pasta80.atg 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. (* Tags: Pasta80, Pascal80 *)
  2. COMPILER PASCALS $CN
  3. (* This is a Coco/R (Turbo Pascal) version of a Pascal-S compiler.
  4. Jul 4, 1996. Frankie Arzu <farzu@uvg.edu.gt> or <farzu@cs.tamu.edu>
  5. Nov 6, 1997. Slightly revised Pat Terry <cspt@cs.ru.ac.za>
  6. WARNING +++++++++++ Not entirely debugged yet!
  7. Original Pascal-S Code by:
  8. Author : N. Wirth, E.T.H. CH-8092 Zurich, 1.3.76
  9. *)
  10. USES TextFiles, Emulator, SymTab;
  11. TYPE
  12. SYMBOL = (plus, minus, times, idiv, rdiv, imod, andsy, orsy,
  13. eql, neq, gtr, geq, lss, leq);
  14. CONREC =
  15. RECORD CASE TP : TYPES OF
  16. Ints, Chars, Bools : (I : INTEGER);
  17. Reals : (R : REAL)
  18. END;
  19. VAR
  20. Id : ALFA;
  21. ProgName : ALFA;
  22. Level : INTEGER;
  23. Vm : PMachine;
  24. FUNCTION ResultType (A, B : TYPES) : TYPES;
  25. BEGIN
  26. IF (A > Reals) OR (B > Reals)
  27. THEN BEGIN SemError(33); ResultType := NoTyp END
  28. ELSE
  29. IF (A = NoTyp) OR (B = NoTyp)
  30. THEN ResultType := NoTyp
  31. ELSE
  32. IF A = Ints
  33. THEN
  34. IF B = Ints
  35. THEN ResultType := Ints
  36. ELSE BEGIN ResultType := Reals; Vm^.Emit1(Vm_CVIF, 1) END
  37. ELSE
  38. BEGIN ResultType := Reals; IF B = Ints THEN Vm^.Emit1(Vm_CVIF, 0) END
  39. END;
  40. PROCEDURE GetType (VAR Id : ALFA; VAR TP : TYPEREC);
  41. VAR
  42. X : INTEGER;
  43. BEGIN
  44. X := LocId(Id, Level);
  45. IF X <> 0 THEN
  46. WITH Tab[X] DO
  47. IF Obj <> Type1
  48. THEN SemError(29)
  49. ELSE
  50. BEGIN
  51. TP.TP := Typ; TP.Ref := Ref; TP.Size := Adr;
  52. IF TP.TP = NoTyp THEN SemError(30)
  53. END
  54. END;
  55. PROCEDURE EmitArrayIndex (VAR V, X : ITEM);
  56. VAR
  57. A : INTEGER;
  58. BEGIN
  59. IF V.Typ <> Arrays
  60. THEN SemError(28)
  61. ELSE
  62. BEGIN
  63. A := V.Ref;
  64. IF Atab[A].InxTyp <> X.Typ
  65. THEN SemError(26)
  66. ELSE
  67. IF Atab[A].ElSize = 1
  68. THEN Vm^.Emit1(Vm_INDEX1, A)
  69. ELSE Vm^.Emit1(Vm_INDEX, A);
  70. V.Typ := Atab[A].eltyp; V.Ref := Atab[A].ElRef
  71. END
  72. END;
  73. PROCEDURE EmitValParam (VAR X : ITEM; Cp : INTEGER);
  74. BEGIN
  75. IF X.Typ = Tab[Cp].Typ
  76. THEN
  77. BEGIN
  78. IF X.Ref <> Tab[Cp].Ref THEN SemError(36) ELSE
  79. IF X.Typ = Arrays THEN Vm^.Emit1(Vm_LDBLK, Atab[X.Ref].Size) ELSE
  80. IF X.Typ = Records THEN Vm^.Emit1(Vm_LDBLK, Btab[X.Ref].VSize)
  81. END
  82. ELSE
  83. IF (X.Typ = Ints) AND (Tab[Cp].Typ = Reals)
  84. THEN Vm^.Emit1(Vm_CVIF, 0)
  85. ELSE IF X.Typ <> NoTyp THEN SemError(36);
  86. END;
  87. FUNCTION EmitRefParam (VAR X : ITEM; VAR Id : ALFA) : INTEGER;
  88. VAR
  89. K : INTEGER;
  90. BEGIN
  91. K := LocId(Id, Level);
  92. X.Typ := NoTyp;
  93. IF K <> 0 THEN
  94. BEGIN
  95. IF Tab[K].Obj <> Variable THEN SemError(37);
  96. X.Typ := Tab[K].Typ; X.Ref := Tab[K].Ref;
  97. IF Tab[K].Normal
  98. THEN Vm^.Emit2(Vm_LDA, Tab[K].Lev, Tab[K].Adr)
  99. ELSE Vm^.Emit2(Vm_LD, Tab[K].Lev, Tab[K].Adr);
  100. END;
  101. EmitRefParam := K;
  102. END;
  103. FUNCTION LValue (VAR Id : ALFA; VAR X : ITEM) : INTEGER;
  104. VAR
  105. I, F : INTEGER;
  106. BEGIN
  107. I := LocId(Id, Level); LValue := I;
  108. X.Typ := Tab[I].Typ; X.Ref := Tab[I].Ref;
  109. IF Tab[I].Normal THEN F := Vm_LDA ELSE F := Vm_LD;
  110. CASE Tab[I].Obj OF
  111. Konstant, Type1 :
  112. SemError(45);
  113. Variable :
  114. Vm^.Emit2(F, Tab[I].Lev, Tab[I].Adr);
  115. Prozedure :
  116. (* IF Tab[I].Lev = 0 THEN StandProc(Tab[I].Adr) *);
  117. Funktion:
  118. IF Tab[I].Ref = Display[Level]
  119. THEN Vm^.Emit2(F, Tab[I].Lev + 1, 0);
  120. ELSE SemError(45)
  121. END
  122. END;
  123. FUNCTION RValue (VAR X : ITEM; VAR Id : ALFA) : INTEGER;
  124. VAR
  125. I, F : INTEGER;
  126. BEGIN
  127. I := LocId(Id, Level); RValue := I;
  128. WITH Tab[I] DO
  129. CASE Obj OF
  130. Konstant :
  131. BEGIN
  132. X.Typ := Typ; X.Ref := 0;
  133. IF X.Typ = Reals
  134. THEN Vm^.Emit1(Vm_F_LIT, Adr)
  135. ELSE Vm^.Emit1(Vm_I_LIT, Adr)
  136. END;
  137. Variable :
  138. BEGIN
  139. X.Typ := Typ; X.Ref := Ref;
  140. IF X.Typ IN StanTyps
  141. THEN
  142. IF Normal THEN F := Vm_LD ELSE F := Vm_LDI
  143. ELSE
  144. IF Normal THEN F := Vm_LDA ELSE F := Vm_LD;
  145. Vm^.Emit2(F, Lev, Adr)
  146. END;
  147. Type1, Prozedure :
  148. SemError(44);
  149. Funktion :
  150. BEGIN X.Typ := Typ; Vm^.Emit1(Vm_MARK, I) END
  151. END { CASE, WITH }
  152. END;
  153. PROCEDURE IndSelector (I : INTEGER; VAR X : ITEM);
  154. BEGIN
  155. WITH Tab[I] DO
  156. CASE Obj OF
  157. Variable : BEGIN IF X.Typ IN StanTyps THEN Vm^.Emit(Vm_IND) END
  158. END { CASE, WITH }
  159. END;
  160. PROCEDURE IndVar (I : INTEGER; VAR X : ITEM);
  161. VAR
  162. F : INTEGER;
  163. BEGIN
  164. WITH Tab[I] DO
  165. CASE Obj OF
  166. Variable :
  167. BEGIN
  168. X.Typ := Typ; X.Ref := Ref;
  169. IF X.Typ IN StanTyps
  170. THEN IF Normal THEN F := Vm_LD ELSE F := Vm_LDI
  171. ELSE IF Normal THEN F := Vm_LDA ELSE F := Vm_LD;
  172. Vm^.Emit2(F, Lev, Adr)
  173. END;
  174. Type1, Prozedure :
  175. SemError(44);
  176. Funktion :
  177. BEGIN
  178. X.Typ := Typ; (*Vm^.Emit1(Vm_MARK, I);*)
  179. Vm^.Emit1(Vm_CALL, Btab[Tab[I].Ref].PSize - 1);
  180. IF Tab[I].Lev < Level THEN Vm^.Emit2(Vm_DISP, Tab[I].Lev, Level);
  181. END
  182. END
  183. END;
  184. PROCEDURE AssignType (VAR X, Y : ITEM);
  185. BEGIN
  186. IF X.Typ = Y.Typ
  187. THEN
  188. IF X.Typ IN StanTyps
  189. THEN Vm^.Emit(Vm_STO)
  190. ELSE
  191. IF X.Ref <> Y.Ref
  192. THEN SemError(46)
  193. ELSE
  194. IF X.Typ = Arrays
  195. THEN Vm^.Emit1(Vm_STOBLK, Atab[X.Ref].Size)
  196. ELSE Vm^.Emit1(Vm_STOBLK, Btab[X.Ref].VSize)
  197. ELSE
  198. IF (X.Typ = Reals) AND (Y.Typ = Ints)
  199. THEN BEGIN Vm^.Emit1(Vm_CVIF, 0); Vm^.Emit(Vm_STO) END
  200. ELSE IF (X.Typ <> NoTyp) AND (Y.Typ <> NoTyp) THEN SemError(46)
  201. END;
  202. PROCEDURE EmitOp (Op : SYMBOL; VAR X, Y : ITEM);
  203. BEGIN
  204. CASE Op OF
  205. times :
  206. BEGIN
  207. X.Typ := ResultType(X.Typ, Y.Typ);
  208. CASE X.Typ OF
  209. NoTyp : ;
  210. Ints : Vm^.Emit(Vm_I_MUL);
  211. Reals : Vm^.Emit(Vm_F_MUL);
  212. END
  213. END;
  214. rdiv :
  215. BEGIN
  216. IF X.Typ = Ints THEN
  217. BEGIN Vm^.Emit1(Vm_CVIF, 1); X.Typ := Reals END;
  218. IF Y.Typ = Ints THEN
  219. BEGIN Vm^.Emit1(Vm_CVIF, 0); Y.Typ := Reals END;
  220. IF (X.Typ = Reals) AND (Y.Typ = Reals)
  221. THEN Vm^.Emit(Vm_F_DIV)
  222. ELSE
  223. BEGIN
  224. IF (X.Typ <> NoTyp) AND (Y.Typ <> NoTyp) THEN SemError(33);
  225. X.Typ := NoTyp
  226. END
  227. END;
  228. andsy:
  229. BEGIN
  230. IF (X.Typ = Bools) AND (Y.Typ = Bools)
  231. THEN Vm^.Emit(Vm_B_AND)
  232. ELSE
  233. BEGIN
  234. IF (X.Typ <> NoTyp) AND (Y.Typ <> NoTyp) THEN SemError(32);
  235. X.Typ := NoTyp
  236. END
  237. END;
  238. idiv, imod :
  239. BEGIN
  240. IF (X.Typ = Ints) AND (Y.Typ = Ints)
  241. THEN
  242. IF Op = idiv THEN Vm^.Emit(Vm_I_DIV) ELSE Vm^.Emit(Vm_I_MOD)
  243. ELSE
  244. BEGIN
  245. IF (X.Typ <> NoTyp) AND (Y.Typ <> NoTyp) THEN SemError(34);
  246. X.Typ := NoTyp
  247. END
  248. END;
  249. orsy :
  250. BEGIN
  251. IF (X.Typ = Bools) AND (Y.Typ = Bools)
  252. THEN Vm^.Emit(Vm_B_OR)
  253. ELSE
  254. BEGIN
  255. IF (X.Typ <> NoTyp) AND (Y.Typ <> NoTyp) THEN SemError(32);
  256. X.Typ := NoTyp
  257. END;
  258. END;
  259. plus :
  260. BEGIN
  261. X.Typ := ResultType(X.Typ, Y.Typ);
  262. IF (X.Typ = Ints) THEN Vm^.Emit(Vm_I_ADD);
  263. IF (X.Typ = Reals) THEN Vm^.Emit(Vm_F_ADD);
  264. END;
  265. minus :
  266. BEGIN
  267. X.Typ := ResultType(X.Typ, Y.Typ);
  268. IF (X.Typ = Ints) THEN Vm^.Emit(Vm_I_SUB);
  269. IF (X.Typ = Reals) THEN Vm^.Emit(Vm_F_SUB);
  270. END;
  271. eql, neq, lss, leq, gtr, geq :
  272. BEGIN
  273. IF (X.Typ IN [NoTyp, Ints, Bools, Chars]) AND (X.Typ = Y.Typ)
  274. THEN
  275. CASE Op OF
  276. eql : Vm^.Emit(Vm_I_EQ);
  277. neq : Vm^.Emit(Vm_I_NE);
  278. lss : Vm^.Emit(Vm_I_LT);
  279. leq : Vm^.Emit(Vm_I_LE);
  280. gtr : Vm^.Emit(Vm_I_GT);
  281. geq : Vm^.Emit(Vm_I_GE);
  282. END
  283. ELSE
  284. BEGIN
  285. IF X.Typ = Ints
  286. THEN BEGIN X.Typ := Reals; Vm^.Emit1(Vm_CVIF, 1) END
  287. ELSE
  288. IF Y.Typ = Ints THEN
  289. BEGIN Y.Typ := Reals; Vm^.Emit1(Vm_CVIF, 0) END;
  290. IF (X.Typ = Reals) AND (Y.Typ = Reals)
  291. THEN
  292. CASE Op OF
  293. eql : Vm^.Emit(Vm_F_EQ);
  294. neq : Vm^.Emit(Vm_F_NE);
  295. lss : Vm^.Emit(Vm_F_LT);
  296. leq : Vm^.Emit(Vm_F_LE);
  297. gtr : Vm^.Emit(Vm_F_GT);
  298. geq : Vm^.Emit(Vm_F_GE);
  299. END
  300. ELSE SemError(35)
  301. END;
  302. X.Typ := Bools
  303. END
  304. END
  305. END;
  306. IGNORE CASE
  307. IGNORE CHR(1) .. CHR(31)
  308. COMMENTS FROM "(*" TO "*)"
  309. COMMENTS FROM "{" TO "}"
  310. CHARACTERS
  311. digit = "0123456789".
  312. letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
  313. instrn = ANY - "'" - CHR(13).
  314. TOKENS
  315. ident = letter { letter | digit } .
  316. IntNum = digit { digit } | digit { digit } CONTEXT ("..") .
  317. RealNum1 = digit { digit } "." digit { digit } .
  318. RealNum2 = digit { digit } "." digit { digit } "E" ["+"|"-"] digit { digit } .
  319. string = "'" { instrn | "'" "'" } "'" .
  320. PRODUCTIONS
  321. PASCALS
  322. = (. SymTab.ErrorProc := SemError;
  323. Vm := NEW(PMachine, Init);
  324. Level := 1 .)
  325. "PROGRAM" Ident<ProgName>
  326. [ "(" ident {"," ident }
  327. ")"
  328. ]
  329. Block<GetTabPos, FALSE>
  330. SYNC "." (. Vm^.Emit(Vm_HALT);
  331. IF Btab[2].VSize > StackSize THEN SemError(49);
  332. IF ProgName = 'TEST0 ' THEN
  333. BEGIN
  334. PrintTables(ErrorFile);
  335. Vm^.DumpCode(ErrorFile)
  336. END;
  337. Close(ErrorFile);
  338. IF Successful THEN Vm^.Interpret .)
  339. .
  340. Block <Prt : INTEGER; IsFun : BOOLEAN>
  341. (. VAR DX, Prb, X : INTEGER; .)
  342. = (. DX := 5;
  343. IF Level > LMax THEN Fatal(5);
  344. Prb := EnterBlock;
  345. NewDisplay(Prt, Level) .)
  346. [ "(" ParameterList<DX>
  347. ")" ] (. SetProcParams(Prb, GetTabPos, DX) .)
  348. [ ":" Ident<Id> (. IF IsFun THEN
  349. BEGIN
  350. X := LocId(Id, Level);
  351. SetProcType(Prt, X);
  352. END .)
  353. ]
  354. ";"
  355. { ConstDecl
  356. | TypeDecl
  357. | VarDecl<DX>
  358. | ProcDecl
  359. } (. SetProcVarSize(Prb, DX) .)
  360. SYNC
  361. "BEGIN" (. SetProcAddr(Prt, Vm^.LC) .)
  362. Statement
  363. { ";" Statement }
  364. "END"
  365. .
  366. Statement
  367. = AssignCallStat
  368. | CompStat
  369. | IfStat
  370. | WhileStat
  371. | RepeatStat
  372. | ForStat
  373. | StandardProc
  374. .
  375. AssignCallStat (. VAR
  376. X, Y : ITEM;
  377. I : INTEGER; .)
  378. =
  379. Ident<Id> (. I := LValue(Id, X) .)
  380. { Selector<X> }
  381. ( ":=" Expression<Y, TRUE> (. AssignType(X, Y) .)
  382. | (. Vm^.Emit1(Vm_MARK, I) .)
  383. [ ActualParams<I, Btab[Tab[I].Ref].LastPar> ]
  384. (. Vm^.Emit1(Vm_CALL, Btab[Tab[I].Ref].PSize - 1);
  385. IF Tab[I].Lev < Level THEN
  386. Vm^.Emit2(Vm_DISP, Tab[I].Lev, Level) .)
  387. )
  388. .
  389. CompStat
  390. = "BEGIN" Statement { ";" Statement } "END" .
  391. IfStat (. VAR
  392. X : ITEM;
  393. LC1, LC2 : INTEGER; .)
  394. = "IF" Expression<X, TRUE> (. IF NOT (X.Typ IN [Bools, NoTyp]) THEN
  395. SemError(17);
  396. LC1 := Vm^.LC; Vm^.Emit(Vm_CJMP) .)
  397. "THEN" Statement
  398. ( "ELSE" (. LC2 := Vm^.LC; Vm^.Emit(Vm_JMP);
  399. Vm^.Code[LC1].Y := Vm^.LC .)
  400. Statement (. Vm^.Code[LC2].Y := Vm^.LC .)
  401. | (* empty *) (. Vm^.Code[LC1].Y := Vm^.LC .)
  402. )
  403. .
  404. RepeatStat (. VAR
  405. X : ITEM;
  406. LC1 : INTEGER; .)
  407. = "REPEAT" (. LC1 := Vm^.LC .)
  408. Statement { "," Statement }
  409. "UNTIL"
  410. Expression<X, TRUE> (. IF NOT (X.Typ IN [Bools, NoTyp]) THEN
  411. SemError(17);
  412. Vm^.Emit1(Vm_CJMP, LC1) .)
  413. .
  414. WhileStat (. VAR
  415. X : ITEM;
  416. LC1, LC2 : INTEGER; .)
  417. = "WHILE" (. LC1 := Vm^.LC .)
  418. Expression<X, TRUE> (. IF NOT (X.Typ IN [Bools, NoTyp]) THEN
  419. SemError(17);
  420. LC2 := Vm^.LC; Vm^.Emit(Vm_CJMP) .)
  421. "DO"
  422. Statement (. Vm^.Emit1(Vm_JMP, LC1);
  423. Vm^.Code[LC2].Y := Vm^.LC .)
  424. .
  425. ForStat (. VAR
  426. Cvt : TYPES;
  427. X : ITEM;
  428. I, F, LC1, LC2 : INTEGER; .)
  429. = "FOR" Ident<Id> (. I := LocId(Id, Level);
  430. IF I = 0 THEN Cvt := Ints ELSE
  431. IF Tab[I].Obj = Variable THEN
  432. BEGIN
  433. Cvt := Tab[I].Typ;
  434. IF NOT Tab[I].Normal
  435. THEN SemError(37)
  436. ELSE Vm^.Emit2(Vm_LDA, Tab[I].Lev, Tab[I].Adr);
  437. IF NOT (Cvt IN [NoTyp, Ints, Bools, Chars]) THEN SemError(18)
  438. END
  439. ELSE
  440. BEGIN SemError(37); Cvt := Ints END .)
  441. ":=" Expression<X, TRUE> (. IF X.Typ <> Cvt THEN SemError(19) .)
  442. ( "TO" (. F := Vm_FOR1U .)
  443. | "DOWNTO" (. F := Vm_FOR1D .)
  444. )
  445. Expression<X, TRUE> (. IF X.Typ <> Cvt THEN SemError(19);
  446. LC1 := Vm^.LC; Vm^.Emit(F) .)
  447. "DO" (. LC2 := Vm^.LC .)
  448. Statement (. Vm^.Emit1(F + 1, LC2); Vm^.Code[LC1].Y := Vm^.LC .)
  449. .
  450. StandardProc
  451. = "READ" "(" ReadArg {"," ReadArg} ")"
  452. | "READLN" "(" ReadArg {"," ReadArg} ")"
  453. (. Vm^.Emit(Vm_READLN) .)
  454. | "WRITE" "(" WriteArg {"," WriteArg} ")"
  455. | "WRITELN" "(" WriteArg {"," WriteArg} ")"
  456. (. Vm^.Emit(Vm_WRITELN) .)
  457. .
  458. ReadArg (. VAR
  459. I : INTEGER;
  460. X : ITEM; .)
  461. = Ident<Id> (. I := EmitRefParam(X, Id) .)
  462. { Selector<X> } (. IF X.Typ IN [Ints, Reals, Chars, NoTyp]
  463. THEN Vm^.Emit1(Vm_READ, ORD(X.Typ))
  464. ELSE SemError(41) .)
  465. .
  466. WriteArg (. VAR
  467. I, SLen : INTEGER;
  468. X, Y : ITEM;
  469. S : STRING; .)
  470. = StrConst<S> (. I := EnterString(S);
  471. SLen := Length(S) - 2;
  472. Vm^.Emit1(Vm_I_LIT, SLen);
  473. Vm^.Emit1(Vm_S_WRITE, I) .)
  474. | Expression<X, TRUE> (. IF NOT (X.Typ IN StanTyps)
  475. THEN SemError(41) .)
  476. ( ":"
  477. Expression<Y, TRUE> (. IF Y.Typ <> Ints THEN SemError(43) .)
  478. ( ":" (. IF X.Typ <> Reals THEN SemError(42) .)
  479. Expression<Y, TRUE> (. IF Y.Typ <> Ints THEN SemError(43);
  480. Vm^.Emit(Vm_WRITE3) .)
  481. | (* Empty *) (. Vm^.Emit1(Vm_WRITE2, ORD(X.Typ)) .)
  482. )
  483. | (* Empty *) (. Vm^.Emit1(Vm_WRITE1, ORD(X.Typ)) .)
  484. )
  485. .
  486. Selector <VAR V : ITEM> (. VAR
  487. X : ITEM;
  488. A, J : INTEGER; .)
  489. = "." Ident<Id> (. A := GetFieldOfs(V, Id);
  490. IF A <> 0 THEN Vm^.Emit1(Vm_OFS, A) .)
  491. | "["
  492. Expression<X, TRUE> (. EmitArrayIndex(V, X) .)
  493. { ","
  494. Expression<X, TRUE> (. EmitArrayIndex(V, X) .)
  495. }
  496. "]"
  497. .
  498. ActualParams <Cp, LastP : INTEGER>
  499. (. VAR
  500. X : ITEM;
  501. .)
  502. = "(" (. IF Cp >= LastP THEN SemError(39); INC(Cp) .)
  503. Expression<X, Tab[Cp].Normal>
  504. (. IF Tab[Cp].Normal
  505. THEN EmitValParam(X, Cp)
  506. ELSE
  507. IF (X.Typ <> Tab[Cp].Typ) OR (X.Ref <> Tab[Cp].Ref) THEN SemError(36) .)
  508. { "," (. IF Cp >= LastP THEN SemError(39); INC(Cp) .)
  509. Expression<X, Tab[Cp].Normal>
  510. (. IF Tab[Cp].Normal
  511. THEN EmitValParam(X, Cp)
  512. ELSE
  513. IF (X.Typ <> Tab[Cp].Typ) OR (X.Ref <> Tab[Cp].Ref) THEN SemError(36) .)
  514. }
  515. ")"
  516. .
  517. Expression <VAR X : ITEM; Normal : BOOLEAN>
  518. (. VAR
  519. Y : ITEM;
  520. Op : SYMBOL; .)
  521. = SimpExpr<X, Normal>
  522. { RelOp<Op>
  523. SimpExpr<Y, Normal> (. EmitOp(Op, X, Y) .)
  524. }
  525. .
  526. SimpExpr <VAR X : ITEM; Normal : BOOLEAN>
  527. (. VAR
  528. Y : ITEM;
  529. Op : SYMBOL;
  530. Neg : BOOLEAN; .)
  531. = (. Neg := FALSE .)
  532. [ "+" | "-" (. Neg := TRUE .)
  533. ]
  534. Term<X, Normal> (. IF Neg THEN
  535. IF X.Typ > Reals
  536. THEN SemError(33)
  537. ELSE Vm^.Emit(Vm_NEG) .)
  538. { AddOp<Op>
  539. Term<Y, Normal> (. EmitOp(Op, X, Y) .)
  540. }
  541. .
  542. Term <VAR X : ITEM; Normal : BOOLEAN>
  543. (. VAR
  544. Y : ITEM;
  545. Op : SYMBOL; .)
  546. = Factor<X, Normal>
  547. { MultOp<Op>
  548. Factor<Y, Normal> (. EmitOp(Op, X, Y) .)
  549. }
  550. .
  551. Factor <VAR X : ITEM; Normal : BOOLEAN>
  552. (. VAR
  553. CH : CHAR;
  554. I : INTEGER;
  555. RNum : REAL;
  556. INum : INTEGER;
  557. .)
  558. = (. X.Typ := NoTyp; X.Ref := 0 .)
  559. Ident<Id> (. IF NOT Normal
  560. THEN I := EmitRefParam(X, Id)
  561. ELSE I := RValue(X, Id) .)
  562. ( Selector<X> (. IF Normal THEN IndSelector(I, X) .)
  563. { Selector<X> (. IF Normal THEN IndSelector(I, X) .)
  564. }
  565. | ActualParams<I, Btab[Tab[I].Ref].LastPar>
  566. (. Vm^.Emit1(Vm_CALL, Btab[Tab[I].Ref].PSize - 1);
  567. IF Tab[I].Lev < Level THEN
  568. Vm^.Emit2(Vm_DISP, Tab[I].Lev, Level);
  569. .)
  570. | (*empty bug fix pdt (. IF Normal THEN IndVar(I, X) .) *)
  571. )
  572. | RealConst<RNum> (. X.Typ := Reals; X.Ref := 0;
  573. I := EnterReal(RNum);
  574. Vm^.Emit1(Vm_F_LIT, I) .)
  575. | IntConst<INum> (. X.Typ := Ints; X.Ref := 0;
  576. Vm^.Emit1(Vm_I_LIT, INum) .)
  577. | ChrConst<CH> (. X.Typ := Chars; X.Ref := 0;
  578. Vm^.Emit1(Vm_I_LIT, ORD(CH)) .)
  579. | "(" Expression<X, Normal> ")"
  580. | "NOT" Factor<X, Normal> (. IF X.Typ = Bools
  581. THEN Vm^.Emit(Vm_NOT)
  582. ELSE IF X.Typ <> NoTyp THEN SemError(Vm_EXITP) .)
  583. .
  584. RelOp <VAR Op : SYMBOL>
  585. = "=" (. Op := eql .)
  586. | "<>" (. Op := neq .)
  587. | "<" (. Op := lss .)
  588. | "<=" (. Op := leq .)
  589. | ">" (. Op := gtr .)
  590. | ">=" (. Op := geq .)
  591. .
  592. AddOp <VAR Op : SYMBOL>
  593. = "+" (. Op := plus .)
  594. | "-" (. Op := minus .)
  595. | "OR" (. Op := orsy .)
  596. .
  597. MultOp <VAR Op : SYMBOL>
  598. = "DIV" (. Op := idiv .)
  599. | "MOD" (. Op := imod .)
  600. | "AND" (. Op := andsy .)
  601. | "/" (. Op := rdiv .)
  602. | "*" (. Op := times .)
  603. .
  604. ProcDecl (. VAR
  605. T0 : INTEGER;
  606. IsFun : BOOLEAN;
  607. OldLevel : INTEGER; .)
  608. = (
  609. "PROCEDURE" Ident<Id> (. T0 := EnterId(Id, Prozedure, Level); IsFun := FALSE .)
  610. | "FUNCTION" Ident<Id> (. T0 := EnterId(Id, Funktion, Level); IsFun := TRUE .)
  611. ) (. Tab[T0].Normal := TRUE;
  612. OldLevel := Level; Level := Level + 1 .)
  613. Block<T0, IsFun> (. Level := OldLevel .)
  614. ";" (. Vm^.Emit(Vm_EXITP + ORD(IsFun)) .)
  615. .
  616. VarDecl <VAR DX : INTEGER>
  617. (. VAR
  618. T0, T1 : INTEGER;
  619. TP : TYPEREC; .)
  620. = "VAR"
  621. {
  622. Ident<Id> (. T0 := EnterId(Id, Variable, Level); T1 := T0 .)
  623. { "," Ident<Id> (. T1 := EnterId(Id, Variable, Level) .)
  624. }
  625. ":" Typ<TP> (. FixTab(T0, T1, TP, TRUE, DX) .)
  626. ";"
  627. }
  628. .
  629. ArrayTyp <VAR AType : TYPEREC> (. VAR
  630. ElType : TYPEREC;
  631. Low, High : CONREC; .)
  632. = (. AType.TP := Arrays .)
  633. Const<Low> (. IF Low.TP = Reals THEN
  634. BEGIN
  635. SemError(27);
  636. Low.TP := Ints; Low.I := 0
  637. END .)
  638. ".." Const<High> (. IF High.TP = Reals THEN
  639. BEGIN
  640. SemError(27);
  641. High.TP := Ints; High.I := 0
  642. END;
  643. AType.Ref := EnterArray(Low.TP, Low.I, High.I) .)
  644. ( "," ArrayTyp<ElType>
  645. | "]" "OF" Typ<ElType>
  646. ) (. FixArray(AType, ElType) .)
  647. .
  648. Typ <VAR TP : TYPEREC> (. VAR
  649. X : INTEGER;
  650. ElType : TYPEREC;
  651. Offset, T0, T1 : INTEGER; .)
  652. = (. TP.TP := NoTyp; TP.Ref := 0; TP.Size := 0 .)
  653. Ident<Id> (. GetType(Id, TP) .)
  654. | "ARRAY" "[" ArrayTyp<TP>
  655. | "RECORD" (. TP.Ref := EnterBlock; TP.TP := Records;
  656. IF Level = LMax THEN Fatal(5);
  657. Level := Level + 1;
  658. Display[Level] := TP.Ref; Offset := 0 .)
  659. {
  660. Ident<Id> (. T0 := EnterId(Id, Variable, Level); T1 := T0 .)
  661. { "," Ident<Id> (. T1 := EnterId(Id, Variable, Level) .)
  662. }
  663. ":" Typ<ElType> (. FixTab(T0, T1, ElType, TRUE, Offset) .)
  664. ";"
  665. }
  666. "END" (. Btab[TP.Ref].VSize := Offset;
  667. TP.Size := Offset;
  668. Btab[TP.Ref].PSize := 0;
  669. Level := Level - 1 .)
  670. .
  671. ParameterList <VAR DX : INTEGER>
  672. = ParameterItem<DX>
  673. { ";" ParameterItem<DX> }
  674. .
  675. ParameterItem <VAR DX : INTEGER> (. VAR
  676. TP : TYPEREC;
  677. X, T0, T1 : INTEGER;
  678. ValPar : BOOLEAN; .)
  679. =
  680. ("VAR" (. ValPar := FALSE .)
  681. | (. ValPar := TRUE .)
  682. )
  683. Ident<Id> (. T0 := EnterId(Id, Variable, Level); T1 := T0 .)
  684. { "," Ident<Id> (. T1 := EnterId(Id, Variable, Level) .)
  685. }
  686. ":"
  687. Ident<Id> (. GetType(Id, TP);
  688. IF NOT ValPar THEN TP.Size := 1;
  689. FixParam(T0, T1, TP, ValPar, Level, DX) .)
  690. .
  691. ConstDecl (. VAR
  692. T1 : INTEGER;
  693. C : CONREC;
  694. C1 : INTEGER; .)
  695. = "CONST"
  696. { Ident<Id> (. T1 := EnterId(Id, Konstant, Level) .)
  697. "="
  698. Const<C> (. IF C.TP = Reals
  699. THEN C1 := EnterReal(C.R)
  700. ELSE C1 := C.I;
  701. WITH Tab[T1] DO
  702. BEGIN
  703. Typ := C.TP; Ref := 0; Adr := C1
  704. END .)
  705. ";"
  706. }
  707. .
  708. TypeDecl (. VAR
  709. T1 : INTEGER;
  710. TP : TYPEREC; .)
  711. = "TYPE"
  712. { Ident<Id> (. T1 := EnterId(Id, Type1, Level) .)
  713. "="
  714. Typ<TP> (. WITH Tab[T1] DO
  715. BEGIN
  716. Typ := TP.TP; Ref := TP.Ref; Adr := TP.Size
  717. END .)
  718. ";"
  719. }
  720. .
  721. Const <VAR C : CONREC> (. VAR
  722. X, Sign : INTEGER;
  723. CH : CHAR;
  724. INum : INTEGER;
  725. RNum : REAL; .)
  726. = (. C.TP := NoTyp; C.I := 0; Sign := 1 .)
  727. (
  728. ChrConst<CH> (. C.TP := Chars; C.I := ORD(CH) .)
  729. | [ "+" | "-" (. Sign := -1 .)
  730. ]
  731. ( Ident<Id> (. X := LocId(Id, Level);
  732. IF X <> 0 THEN
  733. IF Tab[X].Obj <> Konstant
  734. THEN SemError(25)
  735. ELSE
  736. BEGIN
  737. C.TP := Tab[X].Typ;
  738. IF C.TP = Reals
  739. THEN C.R := Sign * RConst[Tab[X].Adr]
  740. ELSE C.I := Sign * Tab[X].Adr
  741. END .)
  742. | IntConst<INum> (. C.TP := Ints; C.I := Sign * INum .)
  743. | RealConst<RNum> (. C.TP := Reals; C.R := Sign * RNum .)
  744. )
  745. )
  746. .
  747. Ident <VAR Id : ALFA> (. VAR S : STRING; .)
  748. = ident (. LexName(S); FillChar(Id, Alng, ' ');
  749. Move(S[1], Id, ORD(S[0])) .)
  750. .
  751. IntConst <VAR N : INTEGER> (. VAR
  752. S : STRING;
  753. C : INTEGER; .)
  754. = IntNum (. LexString(S); Val(S, N, C) .)
  755. .
  756. RealConst <VAR N : REAL> (. VAR
  757. S : STRING;
  758. C : INTEGER; .)
  759. = RealNum1 (. LexString(S); Val(S, N, C) .)
  760. | RealNum2 (. LexString(S); Val(S, N, C) .)
  761. .
  762. StrConst <VAR S : STRING>
  763. = string (. LexString(S) .)
  764. .
  765. ChrConst <VAR CH : CHAR> (. VAR S : STRING; .)
  766. = string (. LexString(S); CH := S[2] .)
  767. .
  768. END PASCALS.