pascual.atg 31 KB

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