DIRECTORY
M2D USING [StrForm, ObjPtr, ConstPtr, VarPtr, ProcPtr, CodePtr, FieldPtr, StrPtr, EnumPtr, RangePtr, SetPtr, PointerPtr, ProcTypPtr, ArrayPtr, RecordPtr, ParPtr, WordSize, Proc, undftyp, notyp, inttyp, cardtyp, dbltyp, realtyp, bitstyp, chartyp, stringtyp, UNION],
M2F USING [GenStParam, GenStFct],
M2G USING [LabelTabPtr, LabelTable, NofCases, GenItem, GenSingSet, GenSet, GenTrap, GenIndex, GenField, GenDeRef, PrepCall, GenCall, GenParam],
M2H USING [ItemPtr, Item, LoadAdr, Load, LoadStk, GenIn, GenOp, GenNeg, GenNot, GenAnd, GenOr],
M2I USING [pc, AllocString],
M2S USING [Symbol, sym, numtyp, intval, dblval, realval, id, GetSym, KeepId, Mark],
M2T USING [Scope, LastObj, NewScope, NewObj, NewStr, NewPar, CloseScope, ParamLink, Find, FindExport, FindField],
M2Q;
MaxInt:
CARDINAL = 77777B;
EnumTypSize : CARDINAL = 1;
SetTypSize: CARDINAL = 1;
PointerTypSize: CARDINAL = 1;
ProcTypSize: CARDINAL = 1;
DynArrDesSize: CARDINAL = 2;
dummyContxt: M2D.ProcPtr ← NEW [M2D.Proc ← [cell: 2]];
err: PROC [n: CARDINAL] = { M2S.Mark [n] };
CheckSym:
PROC [s: M2S.Symbol, n:
CARDINAL] =
{ IF M2S.sym = s THEN M2S.GetSym ELSE M2S.Mark [n] };
qualident:
PROC
RETURNS [obj: M2D.ObjPtr] =
{ -- sym = ident --
obj ← M2T.Find [M2S.id];
M2S.GetSym;
WHILE (M2S.sym = period)
AND (obj #
NIL)
AND (obj^.class = Module)
DO
M2S.GetSym;
IF M2S.sym = ident
THEN
{ obj ← M2T.FindExport [M2S.id, NARROW [obj^.ext]]; M2S.GetSym }
ELSE err [10]
ENDLOOP };
CheckComp:
PROC [t0, t1: M2D.StrPtr] =
{ IF (t0 # t1) AND ((t0 # M2D.inttyp) OR (t1 # M2D.cardtyp)) THEN err [61] };
CaseLabelList:
PUBLIC
PROC [Ltyp: M2D.StrPtr, n:
CARDINAL, tab: M2G.LabelTabPtr]
RETURNS [N:
CARDINAL] =
{ x: M2H.ItemPtr ← NEW [M2H.Item];
y: M2H.ItemPtr ← NEW [M2H.Item];
f: M2D.StrForm ← Ltyp^.form;
IF f = Range
THEN
{ range: M2D.RangePtr ← NARROW [Ltyp^.ext]; Ltyp ← range^.BaseTyp }
ELSE
IF (f > Int) AND (f # Enum) THEN err [38];
DO ConstExpression [x]; CheckComp [Ltyp, x.typ];
IF M2S.sym = ellipsis
THEN
{ M2S.GetSym; ConstExpression [y]; CheckComp [Ltyp, y.typ] }
ELSE y^ ← x^;
enter label range into ordered table --
IF n < M2G.NofCases
THEN { i:
CARDINAL ← n;
DO
IF i = 0 THEN EXIT;
IF tab[i-1].low <= y.val.I
THEN
{ IF tab[i-1].high >= x.val.I THEN err [62];
EXIT };
tab[i] ← tab[i-1]; i ← i-1
ENDLOOP;
tab[i].low ← x.val.I; tab[i].high ← y.val.I; tab[i].label ← M2I.pc;
n ← n + 1 }
ELSE err [92];
IF M2S.sym = comma THEN M2S.GetSym
ELSE
IF (M2S.sym >= lparen) AND (M2S.sym <= ident) THEN err [11]
ELSE EXIT
ENDLOOP;
N ← n };
FieldListSequence:
PROC [adr:
CARDINAL]
RETURNS [maxAdr:
CARDINAL] =
{fld0, fld1, tagfldtyp: M2D.ObjPtr; typ: M2D.StrPtr;
VariantPart:
PROC =
{ tabPtr: M2G.LabelTabPtr ← NEW [M2G.LabelTable];
lastadr:
CARDINAL; N:
CARDINAL;
maxAdr ← adr; N ← 0;
DO
IF M2S.sym < bar
THEN
{ N ← CaseLabelList [typ, N, tabPtr]; CheckSym [colon, 13];
lastadr ← FieldListSequence [adr];
IF lastadr > maxAdr THEN maxAdr ← lastadr };
IF M2S.sym = bar THEN M2S.GetSym ELSE EXIT
ENDLOOP;
IF M2S.sym = else
THEN
{ M2S.GetSym; lastadr ← FieldListSequence [adr];
IF lastadr > maxAdr THEN maxAdr ← lastadr }};
typ ← M2D.undftyp;
IF (M2S.sym = ident)
OR (M2S.sym = case)
THEN
DO
IF M2S.sym = ident
THEN
{ fld0 ← M2T.LastObj []; fld1 ← fld0;
DO
IF M2S.sym = ident
THEN
{ fld1 ← M2T.NewObj [M2S.id, Field]; M2S.KeepId; M2S.GetSym }
ELSE err [10];
IF M2S.sym = comma THEN M2S.GetSym
ELSE IF M2S.sym = ident THEN err [11]
ELSE EXIT
ENDLOOP;
CheckSym [colon, 13]; typ ← Type [];
WHILE fld0 # fld1
DO fld0 ← fld0^.next;
{ field: M2D.FieldPtr ← NARROW [fld0^.ext];
fld0^.typ ← typ; field^.offset ← adr };
adr ← adr + typ^.size
ENDLOOP }
ELSE
IF M2S.sym = case
THEN
{ M2S.GetSym; fld1 ← NIL; tagfldtyp ← NIL;
IF M2S.sym = ident
THEN
{ fld1 ← M2T.NewObj [M2S.id, Field]; M2S.KeepId; M2S.GetSym };
CheckSym [colon, 13];
IF M2S.sym = ident THEN tagfldtyp ← qualident [] ELSE err [10];
IF (tagfldtyp # NIL) AND (tagfldtyp^.class = Typ) THEN typ ← tagfldtyp^.typ
ELSE err [52];
IF fld1 #
NIL
THEN
{ field: M2D.FieldPtr ← NARROW [fld1^.ext];
field^.offset ← adr; fld1^.typ ← typ; adr ← adr + typ^.size };
CheckSym [of, 23]; VariantPart; adr ← maxAdr;
CheckSym [end, 20] };
IF M2S.sym = semicolon THEN M2S.GetSym
ELSE IF M2S.sym = ident THEN err [12]
ELSE EXIT
ENDLOOP;
maxAdr ← adr };
SubRange:
PROC
RETURNS [typ: M2D.StrPtr] =
{ x: M2H.ItemPtr ← NEW [M2H.Item];
y: M2H.ItemPtr ← NEW [M2H.Item];
f: M2D.StrForm; range: M2D.RangePtr ← NIL;
typ ← M2T.NewStr [Range]; range ← NARROW [typ^.ext];
ConstExpression [x]; f ← x^.typ^.form;
IF (f <= Int) OR (f = Enum) THEN range^.min ← x^.val.I ELSE err [82];
CheckSym [ellipsis, 21]; ConstExpression [y]; CheckComp [x^.typ, y^.typ];
IF (y^.typ = M2D.cardtyp) AND (y^.val.C > MaxInt) THEN err [95];
range^.max ← y^.val.I;
IF range^.min > range^.max THEN err [63];
range^.BaseTyp ← x^.typ; typ^.size ← x^.typ^.size };
SimpleType:
PROC
RETURNS [typ: M2D.StrPtr] =
{ obj: M2D.ObjPtr; typ0: M2D.StrPtr; n: CARDINAL;
range: M2D.RangePtr ← NIL; enum: M2D.EnumPtr ← NIL;
typ ← M2D.undftyp;
IF M2S.sym = ident
THEN { obj ← qualident [];
IF (obj # NIL) AND (obj^.class = Typ) THEN typ ← obj^.typ ELSE err [52];
IF M2S.sym = lbrak
THEN { M2S.GetSym;
typ0 ← typ; typ ← SubRange []; range ← NARROW [typ^.ext];
IF range^.BaseTyp # typ0
THEN
IF (typ0 = M2D.inttyp)
AND(range^.BaseTyp = M2D.cardtyp)
THEN
range^.BaseTyp ← M2D.inttyp
ELSE err [61];
IF M2S.sym = rbrak THEN M2S.GetSym
ELSE
{ err [16]; IF M2S.sym = rparen THEN M2S.GetSym }}}
ELSE
IF M2S.sym = lparen
THEN { M2S.GetSym;
typ ← M2T.NewStr [Enum]; enum ← NARROW [typ^.ext];
obj ← NIL; n ← 0;
DO const: M2D.ConstPtr ←
NIL;
IF M2S.sym = ident
THEN
{ obj ← M2T.NewObj [M2S.id, Const]; M2S.KeepId;
const ← NARROW [obj^.ext]; const^.conval.C ← n;
n ← n + 1; obj^.typ ← typ;
M2S.GetSym }
ELSE err [10];
IF M2S.sym = comma THEN M2S.GetSym
ELSE IF M2S.sym = ident THEN err [11]
ELSE EXIT
ENDLOOP;
enum^.NofConst ← n; typ^.size ← EnumTypSize;
CheckSym [rparen, 15] }
ELSE
IF M2S.sym = lbrak
THEN
{ M2S.GetSym; typ ← SubRange [];
IF M2S.sym = rbrak THEN M2S.GetSym
ELSE { err [16];
IF M2S.sym = rparen THEN M2S.GetSym }}
ELSE err [32] };
FormalType:
PUBLIC
PROC
RETURNS [typ: M2D.StrPtr] =
{ objtyp: M2D.ObjPtr; array: M2D.ArrayPtr ← NIL;
typ ← M2D.undftyp;
IF M2S.sym = array
THEN { M2S.GetSym;
typ ← M2T.NewStr [Array]; array ← NARROW [typ^.ext];
typ^.strobj ← NIL; typ^.size ← DynArrDesSize; array^.dyn ← TRUE;
CheckSym [of, 23];
IF M2S.sym = ident
THEN { objtyp ← qualident [];
IF (objtyp #
NIL)
AND (objtyp^.class = Typ)
THEN
array^.ElemTyp ← objtyp^.typ
ELSE err [52] }
ELSE err [10] }
ELSE
IF M2S.sym = ident
THEN
{ objtyp ← qualident [];
IF (objtyp #
NIL)
AND (objtyp^.class = Typ)
THEN
typ ← objtyp^.typ
ELSE err [52] }
ELSE err [10] };
FormalTypeList:
PROC [proctyp: M2D.ProcTypPtr] =
{ obj: M2D.ObjPtr; partyp: M2D.StrPtr; isvar: BOOLEAN;
IF (M2S.sym = ident)
OR (M2S.sym = var)
OR (M2S.sym = array)
THEN
DO
IF M2S.sym = var THEN { M2S.GetSym; isvar ← TRUE }
ELSE isvar ← FALSE;
partyp ← FormalType []; M2T.NewPar [partyp, isvar];
IF M2S.sym = comma THEN M2S.GetSym
ELSE IF M2S.sym = ident THEN err [11]
ELSE EXIT
ENDLOOP;
CheckSym [rparen, 15]; proctyp^.firstPar ← M2T.ParamLink [];
IF M2S.sym = colon
THEN
{ M2S.GetSym; proctyp^.resTyp ← M2D.undftyp;
IF M2S.sym = ident
THEN { obj ← qualident [];
IF (obj # NIL) AND (obj^.class = Typ) THEN proctyp^.resTyp ← obj^.typ
ELSE err [52] }
ELSE err [10] }
ELSE proctyp^.resTyp ← M2D.notyp };
ArrayType:
PROC
RETURNS [typ: M2D.StrPtr] =
{ a, b: INTEGER; array: M2D.ArrayPtr ← NIL;
typ ← M2T.NewStr [Array]; array ← NARROW [typ^.ext];
array^.dyn ← FALSE; a ← 0;
array^.IndexTyp ← SimpleType [];
IF array^.IndexTyp^.form = Range
THEN
{ range: M2D.RangePtr ← NARROW [array^.IndexTyp^.ext];
a ← range^.min; b ← range^.max }
ELSE { err [94]; b ← 0 };
IF M2S.sym = of THEN { M2S.GetSym; array^.ElemTyp ← Type [] }
ELSE
IF M2S.sym = comma THEN { M2S.GetSym; array^.ElemTyp ← ArrayType [] }
ELSE { err [23]; array^.ElemTyp ← M2D.undftyp };
a ← b-a+1; b ← array^.ElemTyp^.size;
IF array^.ElemTyp^.form = Char THEN {}
ELSE
IF MaxInt / b >= a THEN a ← a*b
ELSE { err [210]; a ← 1 };
typ^.size ← a };
OpaqueType:
PUBLIC
PROC
RETURNS [typ: M2D.StrPtr] =
{ typ ← M2T.NewStr [Opaque]; typ^.size ← PointerTypSize };
Type:
PUBLIC
PROC
RETURNS [typ: M2D.StrPtr] =
{ obj: M2D.ObjPtr; btyp: M2D.StrPtr;
IF M2S.sym < lparen
THEN { err [33];
DO M2S.GetSym;
IF M2S.sym >= lparen THEN EXIT
ENDLOOP };
IF M2S.sym = array THEN { M2S.GetSym; typ ← ArrayType [] }
ELSE
IF M2S.sym = record
THEN
{ record: M2D.RecordPtr ← NIL; M2S.GetSym;
typ ← M2T.NewStr [Record]; record ← NARROW [typ^.ext];
obj ← M2T.NewScope [Typ]; -- header --
typ^.size ← FieldListSequence [0];
record^.firstFld ← obj^.next;
CheckSym [end, 20];
M2T.CloseScope }
ELSE
IF M2S.sym = set
THEN
{ set: M2D.SetPtr ← NIL; M2S.GetSym; CheckSym [of, 23];
typ ← M2T.NewStr [Set]; set ← NARROW [typ^.ext];
set^.BaseTyp ← SimpleType []; btyp ← set^.BaseTyp;
IF btyp^.form = Enum
THEN
{ enum: M2D.EnumPtr ← NARROW [btyp^.ext];
IF enum^.NofConst > M2D.WordSize THEN err [209] }
ELSE
IF btyp^.form = Range
THEN
{ range: M2D.RangePtr ← NARROW [btyp^.ext];
IF (range^.min < 0) OR (range^.max >= M2D.WordSize) THEN err [209] }
ELSE err [60];
typ^.size ← SetTypSize }
ELSE
IF M2S.sym = pointer
THEN
{ pointer: M2D.PointerPtr ← NIL; M2S.GetSym;
typ ← M2T.NewStr [Pointer]; pointer ← NARROW [typ^.ext];
pointer^.BaseId ← 0; typ^.size ← PointerTypSize;
CheckSym [to, 24];
IF M2S.sym = ident
THEN { obj ← qualident [];
IF obj =
NIL
THEN
{ pointer^.BaseTyp ← M2D.undftyp; pointer^.BaseId ← M2S.id;
M2S.KeepId-- forward ref --}
ELSE
IF obj^.class = Typ THEN pointer^.BaseTyp ← obj^.typ ELSE err [52] }
ELSE pointer^.BaseTyp ← Type [] }
ELSE
IF M2S.sym = procedure
THEN
{ proctyp: M2D.ProcTypPtr; M2S.GetSym;
typ ← M2T.NewStr [ProcTyp]; proctyp ← NARROW[typ^.ext];
typ^.size ← ProcTypSize;
IF M2S.sym = lparen THEN { M2S.GetSym; FormalTypeList [proctyp] }
ELSE proctyp^.resTyp ← NIL }
ELSE typ ← SimpleType [];
IF (M2S.sym < semicolon)
OR (M2S.sym > else)
THEN { err [34];
WHILE (M2S.sym < ident)
OR (M2S.sym > else)
AND (M2S.sym < begin)
DO
M2S.GetSym
ENDLOOP }};
Selector:
PUBLIC
PROC [x: M2H.ItemPtr, obj: M2D.ObjPtr] =
{ y: M2H.ItemPtr ← NEW [M2H.Item ← [contxt: x^.contxt]];
M2G.GenItem [x, obj, M2T.Scope];
DO
IF M2S.sym = lbrak
THEN { M2S.GetSym;
DO
M2H.LoadAdr [x]; Expression [y]; M2G.GenIndex [x, y];
IF M2S.sym = comma THEN M2S.GetSym ELSE EXIT
ENDLOOP;
CheckSym [rbrak, 16] }
ELSE
IF M2S.sym = period
THEN { M2S.GetSym;
IF M2S.sym = ident
THEN
{
IF (x^.typ #
NIL)
AND (x^.typ^.form = Record)
THEN
{ obj ← M2T.FindField [M2S.id, NARROW[x^.typ^.ext]];
M2G.GenField [x, obj] }
ELSE err [57];
M2S.GetSym }
ELSE err [10] }
ELSE IF M2S.sym = arrow THEN { M2S.GetSym; M2G.GenDeRef [x] }
ELSE EXIT
ENDLOOP };
FormalParameters:
PUBLIC
PROC [proc: M2D.ProcPtr] =
{ isvar: BOOLEAN; par, par0: M2D.ObjPtr; typ0: M2D.StrPtr;
proc^.cell ← 0; proc^.adr ← 0;
IF (M2S.sym = ident)
OR (M2S.sym = var)
THEN
DO par0 ← M2T.LastObj []; isvar ←
FALSE;
IF M2S.sym = var THEN { M2S.GetSym; isvar ← TRUE };
DO
IF M2S.sym = ident
THEN
{ par ← M2T.NewObj [M2S.id, Var]; M2S.KeepId; M2S.GetSym }
ELSE err [10];
IF M2S.sym = comma THEN M2S.GetSym
ELSE IF M2S.sym = ident THEN err [11]
ELSE IF M2S.sym = var THEN { err [11]; M2S.GetSym }
ELSE EXIT
ENDLOOP;
CheckSym [colon, 13];
typ0 ← FormalType []; par0 ← par0^.next;
WHILE par0 #
NIL
DO
var0: M2D.VarPtr ← NARROW [par0^.ext];
par0^.typ ← typ0; var0^.mod ← 0;
var0^.lev ← proc^.lev; var0^.varpar ← isvar;
IF proc^.cell >= 14 THEN { err [99]; proc^.cell ← 0 };
var0^.cell ← proc^.cell; proc^.cell ← proc^.cell + 1;
IF typ0^.form = Array
THEN
{ array: M2D.ArrayPtr ← NARROW [typ0^.ext];
IF array^.dyn
THEN
{ IF proc^.cell >= 14 THEN { err [99]; proc^.cell ← 0 };
proc^.cell ← proc^.cell + 1 } -- size
ELSE IF NOT isvar THEN proc^.adr ← proc^.adr + typ0^.size }
ELSE
IF (typ0^.form = Record)
AND
NOT isvar
THEN
proc^.adr ← proc^.adr + typ0^.size;
par0 ← par0^.next
ENDLOOP;
IF M2S.sym = semicolon THEN M2S.GetSym
ELSE IF M2S.sym = ident THEN err [12]
ELSE EXIT
ENDLOOP;
CheckSym [rparen, 15] };
ActualParameters:
PUBLIC
PROC [x: M2H.ItemPtr] =
{ apar: M2H.ItemPtr ← NEW [M2H.Item ← [contxt: x^.contxt]];
fpar: M2D.ParPtr ← M2G.PrepCall [x];
IF M2S.sym # rparen
THEN
DO Expression [apar];
IF fpar #
NIL
THEN { M2G.GenParam [apar, fpar];
x^.expRegs ← M2D.UNION [x^.expRegs, apar^.expRegs]; fpar ← fpar^.next }
ELSE err [64];
IF M2S.sym = comma THEN M2S.GetSym
ELSE IF (M2S.sym >= lparen) AND (M2S.sym <= ident) THEN err [11]
ELSE EXIT
ENDLOOP;
IF fpar = NIL THEN M2G.GenCall [x] ELSE err [65] };
StandProcCall:
PUBLIC
PROC [p: M2H.ItemPtr] =
{ code: M2D.CodePtr ← NARROW [p^.obj^.ext];
m: CARDINAL ← code^.num; n: CARDINAL;
x: M2H.ItemPtr ← NEW [M2H.Item ← [contxt: p^.contxt]];
IF m = 1
THEN
{ M2G.GenTrap [10]; p^.typ ← M2D.notyp }
ELSE { CheckSym [lparen, 22]; n ← 0;
DO Expression [x]; M2F.GenStParam [p, x, m, n]; n ← n + 1;
IF M2S.sym = comma THEN M2S.GetSym
ELSE IF M2S.sym # ident THEN EXIT
ENDLOOP;
CheckSym [rparen, 15];
M2F.GenStFct [p, m, n] }};
Element:
PROC [x: M2H.ItemPtr] =
{ e1: M2H.ItemPtr ← NEW [M2H.Item ← [contxt: x^.contxt]];
e2: M2H.ItemPtr ← NEW [M2H.Item ← [contxt: x^.contxt]];
Expression [e1];
IF M2S.sym = ellipsis
THEN { M2S.GetSym;
IF e1^.mode = conMd
THEN { Expression [e2];
IF e2^.mode # conMd THEN err [90] }
ELSE { M2H.Load [e1]; Expression [e2] };
M2G.GenSet [x, e1, e2] }
ELSE M2G.GenSingSet [x, e1] };
Sets:
PROC [x: M2H.ItemPtr, styp: M2D.StrPtr] =
{ y: M2H.ItemPtr ← NEW [M2H.Item ← [contxt: x^.contxt]];
x^.typ ← styp; y^.typ ← styp;
IF M2S.sym # rbrace
THEN { Element [x];
DO
IF M2S.sym = comma THEN M2S.GetSym
ELSE
IF (M2S.sym >= lparen) AND (M2S.sym <= ident) THEN err [11]
ELSE EXIT;
M2H.Load [x];
Element [y]; M2H.Load [y];
M2H.GenOp [plus, x, y]
ENDLOOP }
ELSE { x^.mode ← conMd; x^.val.S ← ALL [FALSE] };
CheckSym [rbrace, 17] };
Factor:
PROC [x: M2H.ItemPtr] =
{ obj: M2D.ObjPtr; xt: M2D.StrPtr;
IF M2S.sym < lparen
THEN { err [31];
DO M2S.GetSym;
IF M2S.sym >= lparen THEN EXIT
ENDLOOP };
IF M2S.sym = ident
THEN { obj ← qualident [];
IF M2S.sym = lbrace
THEN { M2S.GetSym;
IF (obj #
NIL)
AND (obj^.class = Typ)
AND (obj^.typ^.form = Set)
THEN
Sets [x, obj^.typ]
ELSE { err [52]; Sets [x, M2D.bitstyp] }}
ELSE { Selector [x, obj];
IF x^.mode = codMd
THEN
{ code: M2D.CodePtr ← NARROW [x^.obj^.ext];
IF code^.num > 0 THEN StandProcCall [x] }
ELSE
IF M2S.sym = lparen
THEN { M2S.GetSym;
IF x^.mode = typMd
THEN
-- type transfer function --
{ xt ← x^.typ; Expression [x]; M2H.Load [x];
IF xt^.size # x.typ^.size THEN err [81];
x^.typ ← xt }
ELSE ActualParameters [x];
CheckSym [rparen, 15] }}}
ELSE
IF M2S.sym = number
THEN
{ M2S.GetSym; x^.mode ← conMd;
SELECT M2S.numtyp
FROM
cardint => { x^.typ ← M2D.cardtyp; x^.val.C ← M2S.intval };
longint => { x^.typ ← M2D.dbltyp; x^.val.D ← M2S.dblval };
char => { x^.typ ← M2D.chartyp; x^.val.C ← M2S.intval };
real => { x^.typ ← M2D.realtyp; x^.val.R ← M2S.realval };
longreal => { x^.typ ← M2D.realtyp; x^.val.R ← M2S.realval }
ENDCASE }
ELSE
IF M2S.sym = string
THEN
{ x^.typ ← M2D.stringtyp; x^.mode ← conMd;
[ x^.val.D0, x^.val.D1 ] ← M2I.AllocString [M2S.id];
M2S.GetSym }
ELSE
IF M2S.sym = lparen
THEN
{ M2S.GetSym; Expression [x]; CheckSym [rparen, 15] }
ELSE
IF M2S.sym = lbrace
THEN
{ M2S.GetSym; Sets [x, M2D.bitstyp] }
ELSE
IF M2S.sym = not
THEN
{ M2S.GetSym; Factor [x]; M2H.GenNot [x] }
ELSE { err [31]; x^.typ ← M2D.undftyp; x^.mode ← stkMd }};
Term:
PROC [x: M2H.ItemPtr] =
{ y: M2H.ItemPtr ← NEW [M2H.Item ← [contxt: x^.contxt]];
mulop: M2S.Symbol;
Factor [x];
WHILE (M2S.sym >= times)
AND (M2S.sym <= and)
DO
mulop ← M2S.sym; M2S.GetSym;
IF x^.mode # conMd
THEN
IF x^.typ^.form = Set THEN M2H.Load [x] ELSE M2H.LoadStk [x];
IF mulop = and THEN M2H.GenAnd [x];
Factor [y];
IF y^.mode # conMd
THEN
IF y^.typ^.form = Set THEN M2H.Load [y] ELSE M2H.LoadStk [y];
M2H.GenOp [mulop, x, y]
ENDLOOP };
SimpleExpression:
PROC [x: M2H.ItemPtr] =
{ y: M2H.ItemPtr ← NEW [M2H.Item ← [contxt: x^.contxt]];
addop: M2S.Symbol;
IF M2S.sym = minus THEN { M2S.GetSym; Term [x]; M2H.GenNeg [x] }
ELSE
{ IF M2S.sym = plus THEN M2S.GetSym;
Term [x] };
WHILE (M2S.sym >= plus)
AND (M2S.sym <= or)
DO
addop ← M2S.sym; M2S.GetSym;
IF addop = or
THEN
{ IF x^.mode # conMd THEN M2H.LoadStk [x];
M2H.GenOr [x]; Term [y];
IF y^.mode # conMd THEN M2H.LoadStk [y] }
ELSE { M2H.Load [x]; Term [y]; M2H.Load [y] };
M2H.GenOp [addop, x, y]
ENDLOOP };
Expression:
PUBLIC
PROC [x: M2H.ItemPtr] =
{ y: M2H.ItemPtr ← NEW [M2H.Item ← [contxt: x^.contxt]];
relation: M2S.Symbol;
SimpleExpression [x];
IF (M2S.sym >= eql)
AND (M2S.sym <= geq)
THEN
{ relation ← M2S.sym; M2S.GetSym;
IF x^.mode # conMd
THEN
IF x^.typ^.form = Set THEN M2H.Load [x] ELSE M2H.LoadStk [x];
SimpleExpression [y];
IF y^.mode # conMd THEN M2H.Load [y];
M2H.GenOp [relation, x, y] }
ELSE
IF M2S.sym = in
THEN { M2S.GetSym;
IF x^.mode # conMd THEN M2H.LoadStk [x];
SimpleExpression [y]; M2H.Load [y];
M2H.GenIn [x, y] }};
ConstExpression:
PUBLIC
PROC [x: M2H.ItemPtr] =
{ x^.contxt ← dummyContxt;
Expression [x];
IF x^.mode # conMd THEN
{ err [44]; x^.mode ← conMd; x^.val.C ← 1 }};