| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030 |
- COMPILER M2comp
- (* Step 2 — Coco/R lexer/parser + SymTab semantic analysis (no codegen).
- Lexer/scanner and parser are FULLY generated by Coco/R (CR):
- M2comp.atg --CR--> M2compS (scanner) + M2compP (parser)
- + M2comp (driver from compiler.frm)
- Static checks (SymTab): 200 duplicate, 201 undeclared, 202 name
- mismatch, 210 bad assignment, 211 arithmetic, 212 boolean operand,
- 213 comparison, 214 condition, 215 not a record, 216 unknown field,
- 217 not an array, 218 bad index, 219 not a pointer, 220 FOR misuse,
- 221 not a type, 222 set mismatch, 223 cyclical type, 224 ordinal
- required, 230 unsupported (EXIT outside LOOP, open array outside
- formal), 232 bad RETURN, 233 invalid call. 231 unused (no FORWARD).
- Kowarsch rules kept from step 1: local MODULEs in Wirth form,
- unary minus takes a Factor (3.3), abbreviated arrays (3.1),
- no octal B/C (2.1). "~" never added (2.2); "<>" still accepted. *)
- IMPORT SymTab, AST;
- CHARACTERS
- eol = CHR(13) .
- letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" .
- digit = "0123456789" .
- hexDigit = digit + "ABCDEF" .
- noQuote1 = ANY - "'" - eol .
- noQuote2 = ANY - '"' - eol .
- IGNORE CHR(9) .. CHR(13)
- COMMENTS
- FROM "(*" TO "*)" NESTED
- TOKENS
- ident = letter { letter | digit } .
- integer = digit { digit }
- | digit { digit } CONTEXT("..")
- | digit { hexDigit } "H" .
- real = digit { digit } "." { digit }
- [ "E" [ "+" | "-" ] digit { digit } ] .
- string = "'" { noQuote1 } "'"
- | '"' { noQuote2 } '"' .
- PRODUCTIONS
- (* NOTE: Coco/R numbers tokens by first occurrence; M2comp.mod's Msg
- table is regenerated from M2comp.err on every build (via
- compiler.frm). After grammar edits, rebuild and check that
- the messages still name the right tokens. *)
- M2comp
- = Module "." .
- Module (. VAR m1, m2: SymTab.Name;
- d, bd, bs, rt: AST.Node;
- im: AST.Node; .)
- = (. SymTab.Init; d := NIL; .)
- "MODULE"
- GetIdent<m1>
- ";"
- { Import<im> (. d := AST.Append(d, im); .) }
- Block<bd, bs> (. d := AST.Append(d, bd);
- rt := AST.MkModule(m1, d,
- AST.MkBlock(NIL, bs));
- AST.SetRoot(rt); .)
- GetIdent<m2> (. IF ~SymTab.Equal(m1, m2) THEN
- SemError(202) END;
- SymTab.PrintTable;
- AST.DumpTree(
- AST.GetRoot()); .) .
- Import<VAR n: AST.Node> (. VAR mod: SymTab.Name;
- h: AST.Node;
- m: SymTab.Name; .)
- = (. mod[0] := 0C; .)
- [ "FROM"
- GetIdent<m> (. IF ~SymTab.Enter(m,
- SymTab.KindImport)
- THEN SemError(200) END;
- mod := m; .) ]
- "IMPORT"
- IdentList<h>
- ";" (. n := AST.MkImport(mod, h); .) .
- IdentList<VAR h: AST.Node> (. VAR n: SymTab.Name; .)
- = GetIdent<n> (. IF ~SymTab.Enter(n,
- SymTab.KindImport)
- THEN SemError(200) END;
- h := AST.MkImpName(n); .)
- { ","
- GetIdent<n> (. IF ~SymTab.Enter(n,
- SymTab.KindImport)
- THEN SemError(200) END;
- h := AST.Append(h,
- AST.MkImpName(n)); .) } .
- GetIdent<VAR n: SymTab.Name>
- = ident (. LexName(n); .) .
- Block<VAR d: AST.Node; VAR s: AST.Node>
- (. VAR dn: AST.Node; .)
- = (. d := NIL; s := NIL; .)
- { Declaration<dn> (. d := AST.Append(d, dn); .) }
- [ "BEGIN"
- StatSeq<s> ]
- "END" .
- Declaration<VAR n: AST.Node> (. VAR cn: AST.Node; .)
- = "CONST" (. n := NIL; .)
- { ConstDecl<cn> ";" (. n := AST.Append(n, cn); .) }
- | "TYPE" (. n := NIL; .)
- { TypeDecl<cn> ";" (. n := AST.Append(n, cn); .) }
- | "VAR" (. n := NIL; .)
- { VarDecl<cn> ";" (. n := AST.Append(n, cn); .) }
- | ProcDecl<n>
- ";"
- | ModuleDecl<n>
- ";" .
- ConstDecl<VAR n: AST.Node> (. VAR nm: SymTab.Name;
- t: SymTab.TypeIndex;
- en: AST.Node;
- cv: INTEGER;
- ok: BOOLEAN; .)
- = GetIdent<nm> (. IF ~SymTab.Enter(nm,
- SymTab.KindConst)
- THEN SemError(200) END; .)
- "="
- ConstExpr<t, en> (. SymTab.SetSymType(nm, t);
- ok := SymTab.ConstFold(en,
- cv);
- SymTab.NoteConst(nm, cv,
- ok);
- n := AST.MkConst(nm, en,
- t); .) .
- ConstExpr<VAR t: SymTab.TypeIndex; VAR e: AST.Node>
- (. VAR vD: BOOLEAN; .)
- = Expr<t, vD, e> .
- TypeDecl<VAR n: AST.Node> (. VAR nm: SymTab.Name;
- t0, t1: SymTab.TypeIndex; .)
- = GetIdent<nm> (. IF ~SymTab.Enter(nm,
- SymTab.KindType)
- THEN SemError(200) END;
- t0 := SymTab.NewAlias();
- SymTab.SetSymType(nm, t0); .)
- "="
- Type<t1> (. IF t1 = t0 THEN SemError(223);
- SymTab.SetTarget(t0,
- SymTab.InvalidType)
- ELSE SymTab.SetTarget(t0, t1) END;
- n := AST.MkTypeDecl(nm,
- t1); .) .
- VarDecl<VAR n: AST.Node> (. VAR t: SymTab.TypeIndex;
- h: AST.Node; .)
- = VarIdents<h> ":"
- Type<t> (. IF SymTab.IsOpen(t) THEN
- SemError(230) END;
- AST.SetChainType(h, t);
- SymTab.FixPending(t);
- n := h; .) .
- VarIdents<VAR h: AST.Node> (. VAR nm: SymTab.Name; .)
- = GetIdent<nm> (. IF ~SymTab.EnterPending(nm,
- SymTab.KindVar)
- THEN SemError(200) END;
- h := AST.MkVar(nm,
- SymTab.InvalidType); .)
- { ","
- GetIdent<nm> (. IF ~SymTab.EnterPending(nm,
- SymTab.KindVar)
- THEN SemError(200) END;
- h := AST.Append(h,
- AST.MkVar(nm,
- SymTab.InvalidType)); .) } .
- ProcDecl<VAR n: AST.Node> (. VAR m1, m2: SymTab.Name;
- rt, ret: SymTab.TypeIndex;
- p, bd, bs: AST.Node;
- pn: INTEGER; .)
- = (. ret := SymTab.InvalidType;
- p := NIL; .)
- "PROCEDURE"
- GetIdent<m1> (. IF ~SymTab.EnterProc(m1) THEN
- SemError(200) END;
- pn := SymTab.ProcNum(m1);
- SymTab.OpenProcScope; .)
- [ FormalParams<p> ]
- [ ":"
- QualIdent<rt> (. ret := rt;
- SymTab.SetProcRet(rt);
- IF (rt #
- SymTab.InvalidType)
- & ((SymTab.ClassOf(rt) =
- SymTab.ClArray)
- OR (SymTab.ClassOf(
- rt) =
- SymTab.ClRecord)) THEN
- SemError(230) END; .) ]
- ";"
- Block<bd, bs> (. n := AST.MkProc(m1, ret, p,
- AST.MkBlock(bd, bs));
- n^.num := pn; .)
- GetIdent<m2> (. IF ~SymTab.Equal(m1, m2) THEN
- SemError(202) END;
- SymTab.CloseProc; .) .
- FormalParams<VAR p: AST.Node> (. VAR ps: AST.Node; .)
- = "(" (. p := NIL; .)
- [ FPSection<ps> (. p := AST.Append(p, ps); .)
- { ";" FPSection<ps> (. p := AST.Append(p, ps); .) } ]
- ")" .
- FPSection<VAR p: AST.Node> (. VAR isV: BOOLEAN;
- t: SymTab.TypeIndex; .)
- = (. isV := FALSE; .)
- [ "VAR" (. isV := TRUE; .) ]
- FPIdents<isV, p> ":"
- Type<t> (. IF SymTab.IsOpen(t) & ~isV THEN
- SemError(230)
- ELSIF ~isV
- & (t #
- SymTab.InvalidType)
- & ((SymTab.ClassOf(t) =
- SymTab.ClArray)
- OR (SymTab.ClassOf(t) =
- SymTab.ClRecord)) THEN
- SemError(230) END;
- AST.SetChainType(p, t);
- IF ~SymTab.FixParamPending(t) THEN
- SemError(200) END; .) .
- FPIdents<isV: BOOLEAN; VAR p: AST.Node>
- (. VAR n: SymTab.Name; .)
- = GetIdent<n> (. IF ~SymTab.EnterParamPending(n,
- isV) THEN
- SemError(200) END;
- p := AST.MkParam(n,
- SymTab.InvalidType,
- isV); .)
- { ","
- GetIdent<n> (. IF ~SymTab.EnterParamPending(n,
- isV) THEN
- SemError(200) END;
- p := AST.Append(p,
- AST.MkParam(n,
- SymTab.InvalidType,
- isV)); .) } .
- ModuleDecl<VAR n: AST.Node> (. VAR m1, m2: SymTab.Name;
- d, bd, bs: AST.Node;
- im, en: AST.Node; .)
- = "MODULE" (* local module, Wirth form *)
- (. d := NIL; .)
- GetIdent<m1> (. IF ~SymTab.EnterModule(m1) THEN
- SemError(200) END; .)
- [ Priority ]
- ";"
- { Import<im> (. d := AST.Append(d, im); .) }
- [ Export<en> (. d := AST.Append(d, en); .) ]
- Block<bd, bs> (. d := AST.Append(d, bd);
- n := AST.MkModule(m1, d,
- AST.MkBlock(NIL, bs)); .)
- GetIdent<m2> (. IF ~SymTab.Equal(m1, m2) THEN
- SemError(202) END;
- IF ~SymTab.ExitModule() THEN
- SemError(201) END; .) .
- Priority (. VAR t: SymTab.TypeIndex;
- vD: BOOLEAN;
- en: AST.Node; .)
- = "["
- Expr<t, vD, en>
- "]" .
- Export<VAR n: AST.Node> (. VAR nm: SymTab.Name;
- h: AST.Node; .)
- = "EXPORT"
- [ "QUALIFIED" ]
- GetIdent<nm> (. IF ~SymTab.ModuleAddExp(nm) THEN
- SemError(200) END;
- h := AST.MkImpName(nm); .)
- { ","
- GetIdent<nm> (. IF ~SymTab.ModuleAddExp(nm) THEN
- SemError(200) END;
- h := AST.Append(h,
- AST.MkImpName(nm)); .) }
- ";" (. n := AST.MkExport(h); .) .
- Type<VAR t: SymTab.TypeIndex>
- (. VAR c: CARDINAL;
- e, s: SymTab.TypeIndex;
- los, his: SymTab.BoundsArr;
- fh: AST.Node;
- i: CARDINAL; .)
- = BoundedBase<t>
- | "ARRAY" (* abbreviated form only (3.1);
- nested ARRAY OF ARRAY long form
- flagged in step 4 sizing *)
- (. c := 0; i := 0;
- WHILE i <= 7 DO
- los[i] := 0;
- his[i] := -1;
- INC(i)
- END; .)
- [ IdxList<c, los, his> ]
- "OF"
- Type<e> (. t := SymTab.WrapArrayB(e, los,
- his, c); .)
- | "RECORD" (. t := SymTab.NewRecord(); .)
- FieldSeq<t, fh>
- "END"
- | "SET"
- "OF"
- QualIdent<s> (. IF (s # SymTab.InvalidType)
- & (SymTab.ClassOf(s) #
- SymTab.ClInt)
- & (SymTab.ClassOf(s) #
- SymTab.ClChar)
- & (SymTab.ClassOf(s) #
- SymTab.ClEnum) THEN
- SemError(224) END;
- t := SymTab.NewSet(s); .)
- | "POINTER"
- "TO"
- Type<e> (. t := SymTab.NewPtr(e); .) .
- BoundedBase<VAR t: SymTab.TypeIndex>
- (. VAR t1, t2: SymTab.TypeIndex;
- vD, vD2: BOOLEAN;
- en, en2: AST.Node;
- lo, hi: INTEGER; .)
- = QualIdent<t>
- [ "["
- Expr<t1, vD, en> (. IF (t1 # SymTab.InvalidType)
- & (SymTab.ClassOf(t1) #
- SymTab.ClInt)
- & (SymTab.ClassOf(t1) #
- SymTab.ClChar)
- & (SymTab.ClassOf(t1) #
- SymTab.ClEnum) THEN
- SemError(224) END; .)
- ".."
- Expr<t2, vD2, en2> (. IF (t2 # SymTab.InvalidType)
- & (SymTab.ClassOf(t2) #
- SymTab.ClInt)
- & (SymTab.ClassOf(t2) #
- SymTab.ClChar)
- & (SymTab.ClassOf(t2) #
- SymTab.ClEnum) THEN
- SemError(224) END;
- IF (t1 = SymTab.InvalidType)
- OR (t2 =
- SymTab.InvalidType) THEN
- t := SymTab.NewSub(t1)
- ELSIF SymTab.ConstFold(en,
- lo)
- & SymTab.ConstFold(en2,
- hi) THEN
- t := SymTab.NewSubB(t1,
- lo, hi)
- ELSE
- SemError(230);
- t := SymTab.NewSub(t1)
- END; .)
- "]" ]
- | "["
- Expr<t1, vD, en> (. IF (t1 # SymTab.InvalidType)
- & (SymTab.ClassOf(t1) #
- SymTab.ClInt)
- & (SymTab.ClassOf(t1) #
- SymTab.ClChar)
- & (SymTab.ClassOf(t1) #
- SymTab.ClEnum) THEN
- SemError(224) END; .)
- ".."
- Expr<t2, vD2, en2> (. IF (t2 # SymTab.InvalidType)
- & (SymTab.ClassOf(t2) #
- SymTab.ClInt)
- & (SymTab.ClassOf(t2) #
- SymTab.ClChar)
- & (SymTab.ClassOf(t2) #
- SymTab.ClEnum) THEN
- SemError(224) END;
- IF (t1 = SymTab.InvalidType)
- OR (t2 =
- SymTab.InvalidType) THEN
- t := SymTab.NewSub(t1)
- ELSIF SymTab.ConstFold(en,
- lo)
- & SymTab.ConstFold(en2,
- hi) THEN
- t := SymTab.NewSubB(t1,
- lo, hi)
- ELSE
- SemError(230);
- t := SymTab.NewSub(t1)
- END; .)
- "]" .
- IdxList<VAR c: CARDINAL; VAR los, his: SymTab.BoundsArr>
- (. VAR s: SymTab.TypeIndex;
- lo, hi: INTEGER;
- ok: BOOLEAN; .)
- = IndexType<s, lo, hi, ok> (. c := 1;
- los[0] := lo; his[0] := hi; .)
- { "," IndexType<s, lo, hi, ok> (. IF c <= 7 THEN
- los[c] := lo;
- his[c] := hi
- END;
- INC(c); .) } .
- IndexType<VAR t: SymTab.TypeIndex; VAR lo, hi: INTEGER;
- VAR ok: BOOLEAN> (. VAR t1, t2: SymTab.TypeIndex;
- vD, vD2: BOOLEAN;
- en, en2: AST.Node;
- l2, h2: INTEGER; .)
- = QualIdent<t> (. ok := SymTab.IndexBounds(t,
- lo, hi); .)
- [ "["
- Expr<t1, vD, en> (. IF (t1 # SymTab.InvalidType)
- & (SymTab.ClassOf(t1) #
- SymTab.ClInt)
- & (SymTab.ClassOf(t1) #
- SymTab.ClChar)
- & (SymTab.ClassOf(t1) #
- SymTab.ClEnum) THEN
- SemError(224) END; .)
- ".."
- Expr<t2, vD2, en2> (. IF (t2 # SymTab.InvalidType)
- & (SymTab.ClassOf(t2) #
- SymTab.ClInt)
- & (SymTab.ClassOf(t2) #
- SymTab.ClChar)
- & (SymTab.ClassOf(t2) #
- SymTab.ClEnum) THEN
- SemError(224) END;
- IF (t1 = SymTab.InvalidType)
- OR (t2 =
- SymTab.InvalidType) THEN
- t := SymTab.NewSub(t1)
- ELSIF SymTab.ConstFold(en,
- l2)
- & SymTab.ConstFold(en2,
- h2) THEN
- t := SymTab.NewSubB(t1,
- l2, h2);
- lo := l2; hi := h2;
- ok := TRUE
- ELSE
- t := SymTab.NewSub(t1);
- ok := FALSE
- END; .)
- "]" ]
- (. IF (t # SymTab.InvalidType)
- & ~ok THEN
- SemError(230) END; .)
- | "["
- Expr<t1, vD, en> (. IF (t1 # SymTab.InvalidType)
- & (SymTab.ClassOf(t1) #
- SymTab.ClInt)
- & (SymTab.ClassOf(t1) #
- SymTab.ClChar)
- & (SymTab.ClassOf(t1) #
- SymTab.ClEnum) THEN
- SemError(224) END;
- ok := FALSE; .)
- ".."
- Expr<t2, vD2, en2> (. IF (t2 # SymTab.InvalidType)
- & (SymTab.ClassOf(t2) #
- SymTab.ClInt)
- & (SymTab.ClassOf(t2) #
- SymTab.ClChar)
- & (SymTab.ClassOf(t2) #
- SymTab.ClEnum) THEN
- SemError(224) END;
- IF (t1 = SymTab.InvalidType)
- OR (t2 =
- SymTab.InvalidType) THEN
- t := SymTab.NewSub(t1)
- ELSIF SymTab.ConstFold(en,
- lo)
- & SymTab.ConstFold(en2,
- hi) THEN
- t := SymTab.NewSubB(t1,
- lo, hi);
- ok := TRUE
- ELSE
- SemError(230);
- t := SymTab.NewSub(t1)
- END; .)
- "]" .
- FieldSeq<rt: SymTab.TypeIndex; VAR h: AST.Node>
- (. VAR fn: AST.Node; .)
- = Field<rt, fn> (. h := fn; .)
- { ";"
- Field<rt, fn> (. h := AST.Append(h, fn); .) } .
- Field<rt: SymTab.TypeIndex; VAR n: AST.Node>
- (. VAR et: SymTab.TypeIndex;
- h: AST.Node; .)
- = (. n := NIL; .)
- [ FieldIdents<rt, h> ":"
- Type<et> (. AST.SetChainType(h, et);
- SymTab.FixPendingF(rt, et);
- n := h; .) ] .
- FieldIdents<rt: SymTab.TypeIndex; VAR h: AST.Node>
- (. VAR nm: SymTab.Name; .)
- = GetIdent<nm> (. IF ~SymTab.FieldPending(rt, nm)
- THEN SemError(200) END;
- h := AST.MkMember(nm,
- SymTab.InvalidType); .)
- { ","
- GetIdent<nm> (. IF ~SymTab.FieldPending(rt, nm)
- THEN SemError(200) END;
- h := AST.Append(h,
- AST.MkMember(nm,
- SymTab.InvalidType)); .) } .
- QualIdent<VAR t: SymTab.TypeIndex>
- (. VAR n, m: SymTab.Name;
- modHead: BOOLEAN; .)
- = (. modHead := FALSE; .)
- GetIdent<n> (. IF ~SymTab.Lookup(n) THEN
- SemError(201);
- t := SymTab.InvalidType
- ELSIF SymTab.SymKind(n)
- = SymTab.KindModule THEN
- t := SymTab.InvalidType;
- modHead := TRUE
- ELSIF (SymTab.SymKind(n) #
- SymTab.KindType)
- & (SymTab.SymKind(n) #
- SymTab.KindPredef)
- & (SymTab.SymKind(n) #
- SymTab.KindImport) THEN
- SemError(221);
- t := SymTab.InvalidType
- ELSE t := SymTab.SymType(n) END; .)
- { "."
- GetIdent<m> (. IF modHead THEN
- modHead := FALSE;
- IF SymTab.ExpKind(n, m)
- = SymTab.KindType THEN
- t := SymTab.ExpType(n, m)
- ELSIF SymTab.SelfKind(n, m)
- = SymTab.KindType THEN
- t := SymTab.SelfType(n, m)
- ELSE
- IF SymTab.ExpKind(n, m) < 0 THEN
- IF SymTab.SelfKind(n, m)
- < 0 THEN
- SemError(201)
- ELSE SemError(221)
- END
- ELSE SemError(221)
- END;
- t := SymTab.InvalidType
- END
- ELSIF t #
- SymTab.InvalidType THEN
- SemError(221);
- t := SymTab.InvalidType
- END; .) } .
- StatSeq<VAR s: AST.Node> (. VAR st: AST.Node; .)
- = Stat<st> (. s := st; .)
- { ";"
- Stat<st> (. s := AST.Append(s, st); .) } .
- Stat<VAR s: AST.Node>
- = (. s := NIL; .)
- [ AssignOrCall<s>
- | IfStat<s>
- | WhileStat<s>
- | RepeatStat<s>
- | LoopStat<s>
- | ForStat<s>
- | ReturnStat<s>
- | "EXIT" (. IF ~SymTab.InLoop() THEN
- SemError(230) END;
- s := AST.MkExit(); .) ] .
- AssignOrCall<VAR s: AST.Node> (. VAR dt, et: SymTab.TypeIndex;
- dk, pn: INTEGER;
- ev: BOOLEAN;
- nn: CARDINAL;
- hadP: BOOLEAN;
- dn, en, ah: AST.Node; .)
- = Designator<dt, dk, pn, dn>
- ( ":="
- Expr<et, ev, en> (. IF dt = SymTab.InvalidType THEN
- (* cascade *)
- ELSIF (dk # SymTab.KindVar)
- & (dk # SymTab.KindParam)
- & (dk # SymTab.KindVarPar)
- & (dk # SymTab.KindField) THEN
- SemError(210)
- ELSIF ~SymTab.Assignable(et,
- dt) THEN
- SemError(210) END;
- s := AST.MkAssign(dn, en); .)
- | (. hadP := FALSE; nn := 0;
- ah := NIL;
- IF dk = SymTab.KindProc THEN
- SymTab.CallBeginNum(pn)
- ELSE
- SymTab.CallBeginNum(-1)
- END;
- IF (dk # SymTab.KindProc)
- & (dk # -1) THEN
- SemError(233) END; .)
- [ ActParams<ah, nn> (. hadP := TRUE; .) ]
- (. IF ~SymTab.CallEndNum(nn) THEN
- SemError(233) END;
- s := AST.MkCall(dn, ah, pn); .) ) .
- Designator<VAR t: SymTab.TypeIndex; VAR k: INTEGER;
- VAR pn: INTEGER; VAR dn: AST.Node>
- (. VAR n, m: SymTab.Name;
- it, it2: SymTab.TypeIndex;
- iv, iv2: BOOLEAN;
- ek, sk, p2: INTEGER;
- modHead, wasMod: BOOLEAN;
- en, en2, ih: AST.Node; .)
- = GetIdent<n> (. modHead := FALSE;
- IF ~SymTab.Lookup(n) THEN
- SemError(201);
- t := SymTab.InvalidType;
- k := -1; pn := -1
- ELSIF SymTab.SymKind(n)
- = SymTab.KindModule THEN
- t := SymTab.InvalidType;
- k := SymTab.KindModule;
- pn := -1; modHead := TRUE
- ELSE
- t := SymTab.SymType(n);
- k := SymTab.SymKind(n);
- IF k = SymTab.KindProc THEN
- pn := SymTab.ProcNum(n)
- ELSE pn := -1
- END
- END;
- dn := AST.MkName(n, t);
- dn^.aux := k; .)
- { "." GetIdent<m> (. wasMod := modHead;
- IF modHead THEN
- modHead := FALSE;
- ek := SymTab.ExpKind(n, m);
- sk := SymTab.SelfKind(n, m);
- IF ek = SymTab.KindType THEN
- t := SymTab.ExpType(n,
- m);
- k := SymTab.KindType
- ELSIF sk =
- SymTab.KindType THEN
- t := SymTab.SelfType(n,
- m);
- k := SymTab.KindType
- ELSIF ek =
- SymTab.KindProc THEN
- t := SymTab.ProcRetByNum(
- SymTab.ExpProc(
- n, m));
- k := SymTab.KindProc;
- pn := SymTab.ExpProc(
- n, m)
- ELSIF sk =
- SymTab.KindProc THEN
- p2 := SymTab.SelfProc(
- n, m);
- t := SymTab.ProcRetByNum(
- p2);
- k := SymTab.KindProc;
- pn := p2
- ELSIF ek >= 0 THEN
- t := SymTab.ExpType(n,
- m);
- k := ek; pn := -1
- ELSIF sk >= 0 THEN
- t := SymTab.SelfType(n,
- m);
- k := sk; pn := -1
- ELSE
- SemError(201);
- t := SymTab.InvalidType;
- k := -1; pn := -1
- END
- ELSIF t =
- SymTab.InvalidType THEN
- (* cascade *)
- ELSIF SymTab.ClassOf(t) #
- SymTab.ClRecord THEN
- SemError(215);
- t := SymTab.InvalidType;
- k := -1; pn := -1
- ELSIF ~SymTab.FieldExists(t,
- m) THEN
- SemError(216);
- t := SymTab.InvalidType;
- k := -1; pn := -1
- ELSE
- t := SymTab.FieldType(t,
- m);
- k := SymTab.KindField;
- pn := -1
- END;
- dn := AST.MkField(dn, m, t);
- dn^.aux := k;
- IF wasMod THEN
- dn^.tag := n
- END; .)
- | "[" Expr<it, iv, en> (. IF t = SymTab.InvalidType THEN
- (* cascade *)
- ELSIF SymTab.ClassOf(t) #
- SymTab.ClArray THEN
- SemError(217);
- t := SymTab.InvalidType;
- k := -1; pn := -1
- ELSIF (it #
- SymTab.InvalidType)
- & ~SymTab.IsIntFamily(
- it) THEN
- SemError(218);
- t := SymTab.InvalidType;
- k := -1; pn := -1
- ELSE t := SymTab.ArrayElem(
- t);
- pn := -1
- END;
- ih := en; .)
- { "," Expr<it2, iv2, en2> (. IF t = SymTab.InvalidType THEN
- (* cascade *)
- ELSIF SymTab.ClassOf(t) #
- SymTab.ClArray THEN
- SemError(217);
- t := SymTab.InvalidType;
- k := -1; pn := -1
- ELSIF (it2 #
- SymTab.InvalidType)
- & ~SymTab.IsIntFamily(
- it2) THEN
- SemError(218)
- ELSE t := SymTab.ArrayElem(
- t) END;
- ih := AST.Append(ih, en2); .) }
- "]" (. dn := AST.MkIndex(dn, ih,
- t);
- dn^.aux := k; .)
- | "^" (. IF t = SymTab.InvalidType THEN
- (* cascade *)
- ELSIF SymTab.ClassOf(t) #
- SymTab.ClPtr THEN
- SemError(219);
- t := SymTab.InvalidType;
- k := -1; pn := -1
- ELSE t := SymTab.PtrBase(t);
- pn := -1
- END;
- dn := AST.MkDeref(dn, t);
- dn^.aux := k; .) } .
- ActParams<VAR h: AST.Node; VAR n: CARDINAL>
- (. VAR at: SymTab.TypeIndex;
- av: BOOLEAN;
- ae: AST.Node; .)
- = "(" (. h := NIL; n := 0; .)
- [ Expr<at, av, ae> (. IF ~SymTab.CallActual(at,
- av) THEN
- SemError(233) END;
- h := AST.Append(h, ae);
- n := 1; .)
- { "," Expr<at, av, ae> (. IF ~SymTab.CallActual(at,
- av) THEN
- SemError(233) END;
- h := AST.Append(h, ae);
- INC(n); .) } ]
- ")" .
- IfStat<VAR s: AST.Node> (. VAR t: SymTab.TypeIndex;
- vD: BOOLEAN;
- cn, th, el, p: AST.Node; .)
- = "IF"
- Expr<t, vD, cn> (. IF ~SymTab.BoolCheck(t) THEN
- SemError(214) END; .)
- "THEN"
- StatSeq<th> (. s := AST.MkIf(cn, th, NIL); .)
- { "ELSIF"
- Expr<t, vD, cn> (. IF ~SymTab.BoolCheck(t) THEN
- SemError(214) END; .)
- "THEN"
- StatSeq<th> (. th := AST.MkIf(cn, th, NIL);
- p := s;
- WHILE p^.extra # NIL DO
- p := p^.extra
- END;
- p^.extra := th; .) }
- [ "ELSE"
- StatSeq<el> (. p := s;
- WHILE p^.extra # NIL DO
- p := p^.extra
- END;
- p^.extra := el; .) ]
- "END" .
- WhileStat<VAR s: AST.Node> (. VAR t: SymTab.TypeIndex;
- vD: BOOLEAN;
- cn, bd: AST.Node; .)
- = "WHILE"
- Expr<t, vD, cn> (. IF ~SymTab.BoolCheck(t) THEN
- SemError(214) END; .)
- "DO"
- StatSeq<bd> (. s := AST.MkWhile(cn, bd); .)
- "END" .
- RepeatStat<VAR s: AST.Node> (. VAR t: SymTab.TypeIndex;
- vD: BOOLEAN;
- cn, bd: AST.Node; .)
- = "REPEAT"
- StatSeq<bd>
- "UNTIL"
- Expr<t, vD, cn> (. IF ~SymTab.BoolCheck(t) THEN
- SemError(214) END;
- s := AST.MkRepeat(bd, cn); .) .
- LoopStat<VAR s: AST.Node> (. VAR bd: AST.Node; .)
- = "LOOP" (. SymTab.LoopEnter; .)
- StatSeq<bd>
- "END" (. SymTab.LoopExit;
- s := AST.MkLoop(bd); .) .
- ForStat<VAR s: AST.Node> (. VAR n: SymTab.Name;
- lo, hi, by: SymTab.TypeIndex;
- lv, lv2, lv3: BOOLEAN;
- ln, hn, bn, bd: AST.Node; .)
- = "FOR"
- GetIdent<n> (. IF ~SymTab.Lookup(n) THEN
- SemError(201)
- ELSIF (SymTab.SymKind(n) #
- SymTab.KindVar)
- & (SymTab.SymKind(n) #
- SymTab.KindParam)
- & (SymTab.SymKind(n) #
- SymTab.KindVarPar)
- & (SymTab.SymKind(n) #
- SymTab.KindField) THEN
- SemError(220)
- ELSIF (SymTab.SymType(n) #
- SymTab.InvalidType)
- & ~SymTab.IsIntFamily(
- SymTab.SymType(n)) THEN
- SemError(220) END; .)
- ":="
- Expr<lo, lv, ln> (. IF (lo # SymTab.InvalidType)
- & ~SymTab.IsIntFamily(lo) THEN
- SemError(220) END; .)
- "TO"
- Expr<hi, lv2, hn> (. IF (hi # SymTab.InvalidType)
- & ~SymTab.IsIntFamily(hi) THEN
- SemError(220) END;
- bn := NIL; .)
- [ "BY"
- Expr<by, lv3, bn> (. IF (by # SymTab.InvalidType)
- & ~SymTab.IsIntFamily(by) THEN
- SemError(220) END; .) ]
- "DO"
- StatSeq<bd> (. s := AST.MkFor(n, ln, hn, bn,
- bd); .)
- "END" .
- ReturnStat<VAR s: AST.Node> (. VAR et: SymTab.TypeIndex;
- ev, hasE: BOOLEAN;
- en, e0: AST.Node; .)
- = (. hasE := FALSE; e0 := NIL; .)
- "RETURN"
- [ Expr<et, ev, en> (. hasE := TRUE; e0 := en; .) ]
- (. IF ~SymTab.InProc() THEN SemError(232)
- ELSIF SymTab.InFunction() & ~hasE THEN SemError(232)
- ELSIF ~SymTab.InFunction() & hasE THEN
- SemError(232) END;
- s := AST.MkReturn(e0); .) .
- Expr<VAR t: SymTab.TypeIndex; VAR v: BOOLEAN;
- VAR e: AST.Node>
- (. VAR t2: SymTab.TypeIndex;
- v2: BOOLEAN;
- op: INTEGER;
- e2: AST.Node; .)
- = SimExpr<t, v, e>
- [ Relation<op> SimExpr<t2, v2, e2>
- (. v := FALSE;
- IF op = SymTab.OpIn THEN
- IF SymTab.InCheck(t, t2) THEN
- t := SymTab.BoolType()
- ELSE SemError(222); t := SymTab.InvalidType END
- ELSE
- IF SymTab.RelCheck(t, t2, op) THEN
- t := SymTab.BoolType()
- ELSE SemError(213); t := SymTab.InvalidType END
- END;
- e := AST.MkBin(op, e, e2, t); .) ] .
- Relation<VAR op: INTEGER>
- = "=" (. op := SymTab.OpEq; .)
- | "#" (. op := SymTab.OpNeq1; .)
- | "<>" (. op := SymTab.OpNeq2; .)
- | "<" (. op := SymTab.OpLt; .)
- | "<=" (. op := SymTab.OpLe; .)
- | ">" (. op := SymTab.OpGt; .)
- | ">=" (. op := SymTab.OpGe; .)
- | "IN" (. op := SymTab.OpIn; .) .
- SimExpr<VAR t: SymTab.TypeIndex; VAR v: BOOLEAN;
- VAR e: AST.Node>
- (. VAR t2, res2: SymTab.TypeIndex;
- v2: BOOLEAN;
- op: INTEGER;
- e2: AST.Node; .)
- = ( "+" Term<t, v, e> (. IF ~SymTab.UnaryCheck(t,
- res2) THEN
- SemError(211);
- t := SymTab.InvalidType
- ELSE t := res2 END;
- v := FALSE;
- e := AST.MkUn(AST.opPos,
- e, t); .)
- | "-" Fact<t, v, e> (. IF ~SymTab.UnaryCheck(t,
- res2) THEN
- SemError(211);
- t := SymTab.InvalidType
- ELSE t := res2 END;
- v := FALSE;
- e := AST.MkUn(AST.opNeg,
- e, t); .)
- | Term<t, v, e> )
- { AddOp<op> Term<t2, v2, e2>
- (. v := FALSE;
- IF op = SymTab.OpOr THEN
- IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
- t := SymTab.BoolType()
- ELSE SemError(212); t := SymTab.InvalidType END
- ELSE
- IF SymTab.ArithCheck(t, t2, FALSE, res2) THEN
- t := res2
- ELSE SemError(211); t := SymTab.InvalidType END
- END;
- e := AST.MkBin(op, e, e2, t); .) } .
- AddOp<VAR op: INTEGER>
- = "+" (. op := SymTab.OpAdd; .)
- | "-" (. op := SymTab.OpSub; .)
- | "OR" (. op := SymTab.OpOr; .) .
- Term<VAR t: SymTab.TypeIndex; VAR v: BOOLEAN;
- VAR e: AST.Node>
- (. VAR t2, res2: SymTab.TypeIndex;
- v2: BOOLEAN;
- op: INTEGER;
- e2: AST.Node; .)
- = Fact<t, v, e>
- { MulOp<op> Fact<t2, v2, e2>
- (. v := FALSE;
- IF op = SymTab.OpAnd THEN
- IF SymTab.BoolCheck(t) & SymTab.BoolCheck(t2) THEN
- t := SymTab.BoolType()
- ELSE SemError(212); t := SymTab.InvalidType END
- ELSE
- IF SymTab.ArithCheck(t, t2,
- (op = SymTab.OpDiv) OR (op = SymTab.OpMod),
- res2) THEN t := res2
- ELSE SemError(211); t := SymTab.InvalidType END
- END;
- e := AST.MkBin(op, e, e2, t); .) } .
- MulOp<VAR op: INTEGER>
- = "*" (. op := SymTab.OpTimes; .)
- | "/" (. op := SymTab.OpSlash; .)
- | "DIV" (. op := SymTab.OpDiv; .)
- | "MOD" (. op := SymTab.OpMod; .)
- | "AND" (. op := SymTab.OpAnd; .) .
- Fact<VAR t: SymTab.TypeIndex; VAR v: BOOLEAN;
- VAR e: AST.Node>
- (. VAR s: ARRAY [0 .. 255] OF CHAR;
- t2, et, dt: SymTab.TypeIndex;
- dk, pn: INTEGER;
- nn: CARDINAL;
- hadP, ce, pushed: BOOLEAN;
- ev, v2: BOOLEAN;
- dn, ah, en: AST.Node;
- iv: INTEGER;
- ok: BOOLEAN; .)
- = integer (. LexString(s);
- t := SymTab.IntType();
- v := FALSE;
- ok := AST.ParseInt(s, iv);
- IF ~ok THEN iv := 0 END;
- e := AST.MkInt(iv, t); .)
- | real (. LexString(s);
- t := SymTab.RealType();
- v := FALSE;
- e := AST.MkReal(s, t); .)
- | string (. LexString(s);
- IF SymTab.StrLen(s) <= 3 THEN
- t := SymTab.CharType();
- e := AST.MkChar(
- ORD(s[1]), t)
- ELSE t := SymTab.NewStr();
- e := AST.MkStr(s, t)
- END;
- v := FALSE; .)
- | Designator<dt, dk, pn, dn> (. hadP := FALSE; nn := 0;
- IF dk = SymTab.KindProc THEN
- SymTab.CallBeginNum(pn);
- pushed := TRUE
- ELSE pushed := FALSE
- END; .)
- [ (. IF ~pushed THEN
- SymTab.CallBeginNum(-1);
- pushed := TRUE
- END; .)
- ActParams<ah, nn> (. hadP := TRUE; .) ]
- (. IF pushed THEN
- ce := SymTab.CallEndNum(nn)
- END;
- IF hadP THEN
- v := FALSE;
- IF dk # SymTab.KindProc THEN
- SemError(233);
- t := SymTab.InvalidType
- ELSIF SymTab.ProcRetByNum(
- pn) =
- SymTab.InvalidType THEN
- SemError(233);
- t := SymTab.InvalidType
- ELSIF ~ce THEN
- SemError(233);
- t := SymTab.InvalidType
- ELSE t :=
- SymTab.ProcRetByNum(pn)
- END;
- e := AST.MkCallExpr(dn, ah,
- pn, t)
- ELSE
- IF dk = SymTab.KindProc THEN
- SemError(233);
- t := SymTab.InvalidType;
- v := FALSE;
- e := AST.MkName("?", t)
- ELSE
- t := dt;
- v := (dt #
- SymTab.InvalidType)
- & ((dk =
- SymTab.KindVar)
- OR (dk =
- SymTab.KindParam)
- OR (dk =
- SymTab.KindVarPar)
- OR (dk =
- SymTab.KindField));
- e := dn
- END
- END; .)
- | "(" Expr<et, ev, en> ")" (. t := et; v := FALSE;
- e := en; .)
- | "NOT" Fact<t2, v2, en> (. IF SymTab.BoolCheck(t2) THEN
- t := SymTab.BoolType()
- ELSE SemError(212);
- t := SymTab.InvalidType END;
- v := FALSE;
- e := AST.MkUn(AST.opNot, en,
- t); .) .
- END M2comp.
|