123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502 |
- MODULE LSC; (*Lola System Compiler, NW 8.1.95 / 25.2.2015 for RISC (LSCX)*)
- IMPORT Texts, Oberon, LSB, LSS;
-
- VAR sym: INTEGER;
- err: BOOLEAN; (*used at end of Unit*)
- top, bot, undef: LSB.Object;
- factor: PROCEDURE (VAR x: LSB.Item); (*to avoid forward references*)
- expression: PROCEDURE (VAR x: LSB.Item);
- Unit: PROCEDURE (VAR locals: LSB.Object);
- W: Texts.Writer;
- PROCEDURE Err(n: INTEGER);
- BEGIN LSS.Mark("type error"); Texts.WriteInt(W, n, 4);
- Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
- END Err;
- PROCEDURE Log(m: LONGINT): LONGINT;
- VAR n: LONGINT;
- BEGIN n := 1;
- WHILE m > 1 DO m := m DIV 2; INC(n) END ;
- RETURN n
- END Log;
- PROCEDURE New(tag: INTEGER; a, b: LSB.Item): LSB.Item;
- VAR z: LSB.Item;
- BEGIN NEW(z); z.tag := tag; z.a := a; z.b := b; z.val := b.val; RETURN z
- END New;
- PROCEDURE NewObj(class: INTEGER): LSB.Object; (*insert at end, before BIT*)
- VAR new, x: LSB.Object;
- BEGIN x := top;
- WHILE (x.next # bot) & (x.next.name # LSS.id) DO x := x.next END ;
- IF x.next = bot THEN
- NEW(new); new.name := LSS.id; new.tag := class; new.next := bot; x.next := new
- ELSE LSS.Mark("mult def"); new := x
- END ;
- RETURN new
- END NewObj;
- PROCEDURE ThisObj(id: LSS.Ident): LSB.Object; (*find object with name = identifier last read*)
- VAR x: LSB.Object;
- BEGIN x := top.next;
- WHILE (x # NIL) & (x.name # id) DO x := x.next END ;
- IF x = NIL THEN LSS.Mark("undef"); x := undef END ;
- RETURN x
- END ThisObj;
- PROCEDURE CheckTypes(x, y, z: LSB.Item); (*z.type = result type*)
- VAR xtyp, ytyp: LSB.Type;
- BEGIN xtyp := x.type; ytyp := y.type; z.type := xtyp; z.size := x.size; z.val := x.val;
- IF xtyp = LSB.bitType THEN z.type := xtyp;
- IF ytyp = LSB.integer THEN (* b + 0 *)
- IF y.val >= 2 THEN Err(20); LSS.Mark("only 0 or 1") END
- ELSIF ytyp = LSB.string THEN (* b + {...} *) Err(21)
- ELSIF ytyp # LSB.bitType THEN Err(22)
- END
- ELSIF xtyp IS LSB.ArrayType THEN
- IF xtyp(LSB.ArrayType).eltyp = LSB.bitType THEN
- IF (ytyp IS LSB.ArrayType) & (xtyp(LSB.ArrayType).eltyp = LSB.bitType) THEN
- IF xtyp.size # ytyp.size THEN Err(33) END (* x + y *)
- ELSIF ytyp = LSB.integer THEN (* w + 5 *)
- IF xtyp.size < Log(y.val) THEN Err(30) END
- ELSIF ytyp = LSB.string THEN (*x + {...} *)
- IF xtyp.size # y.size THEN Err(31) END
- ELSIF ytyp # LSB.bitType THEN Err(34)
- END
- ELSIF (ytyp IS LSB.ArrayType) & (xtyp(LSB.ArrayType).eltyp = ytyp(LSB.ArrayType).eltyp) THEN
- IF (xtyp.size # ytyp.size) THEN Err(40) END
- ELSE Err(41)
- END
- ELSIF xtyp = LSB.string THEN
- IF ytyp = LSB.bitType THEN (* {...} + b *) Err(12)
- ELSIF (ytyp IS LSB.ArrayType) & (ytyp(LSB.ArrayType).eltyp = LSB.bitType) THEN (* {...} + w *)
- IF x.size # ytyp.size THEN Err(13) END
- ELSIF ytyp = LSB.integer THEN (* {...} + 5*)
- IF x.size < Log(y.val) THEN Err(10) END
- ELSIF ytyp = LSB.string THEN (* {...} + {...} *)
- IF x.size # y.size THEN Err(11) END ;
- ELSE Err(14)
- END
- ELSIF xtyp = LSB.integer THEN
- IF (ytyp IS LSB.ArrayType) & (ytyp(LSB.ArrayType).eltyp = LSB.bitType) THEN (* 5 + w *)
- IF Log(x.val) > ytyp.size THEN Err(3); LSS.Mark("const too large") END
- ELSIF ytyp = LSB.bitType THEN (* 5 + b *)
- IF x.val >= 2 THEN Err(2) END
- ELSIF ytyp = LSB.integer THEN (* 5 + 5 *)
- ELSIF ytyp = LSB.string THEN (* 5 + {...} *)
- IF Log(x.val) > y.size THEN Err(12) END
- ELSE Err(4)
- END
- END
- END CheckTypes;
- PROCEDURE selector(VAR x: LSB.Item);
- VAR y, z: LSB.Item; obj: LSB.Object;
- eltyp: LSB.Type; len, kind: LONGINT;
- BEGIN
- WHILE (sym = LSS.lbrak) OR (sym = LSS.period) DO
- IF sym = LSS.lbrak THEN
- eltyp := x.type(LSB.ArrayType).eltyp; LSS.Get(sym); expression(y);
- IF sym = LSS.colon THEN (*range*)
- LSS.Get(sym); expression(z);
- IF (y.tag = LSB.lit) & (z.tag = LSB.lit) THEN
- len := y.val - z.val + 1; y := New(LSB.range, y, z); x := New(LSB.sel, x, y); x.type := LSB.string; x.size := len
- END
- ELSE kind := x.val; x := New(LSB.sel, x, y); x.type := eltyp; x.val := kind
- END ;
- IF sym = LSS.rbrak THEN LSS.Get(sym) ELSE LSS.Mark("rbrak ?") END
- ELSE (*sym = LSS.period*) LSS.Get(sym); factor(y);
- IF (y.tag = LSB.lit) & (y.val >= x.type.len) THEN LSS.Mark("too large") END ;
- eltyp := x.type(LSB.ArrayType).eltyp; kind := x.val; x := New(LSB.sel, x, y); x.type := eltyp; x.val := kind
- END
- END
- END selector;
- PROCEDURE elem(VAR x: LSB.Item; VAR len: LONGINT);
- VAR y, z: LSB.Item; m, n: LONGINT;
- BEGIN expression(x);
- IF (x.type = LSB.integer) OR (x.type = LSB.string) THEN m := x.size ELSE m := x.type.size END ;
- IF sym = LSS.repl THEN
- LSS.Get(sym);
- IF sym = LSS.integer THEN
- NEW(y); y.tag := LSB.lit; n := LSS.val; y.val := n; y.type := LSB.integer; LSS.Get(sym);
- x := New(LSB.repl, x, y)
- END
- ELSE n := 1
- END ;
- len := m*n
- END elem;
- PROCEDURE constructor(VAR x: LSB.Item);
- VAR y: LSB.Item; n, len: LONGINT;
- BEGIN elem(x, len);
- WHILE sym = LSS.comma DO
- LSS.Get(sym); elem(y, n); INC(len, n); x := New(LSB.cons, x, y); x.val := len
- END ;
- x.size := len; x.type := LSB.string;
- IF sym = LSS.rbrace THEN LSS.Get(sym) ELSE LSS.Mark("rbrace ?") END
- END constructor;
- PROCEDURE factor0(VAR x: LSB.Item);
- VAR obj: LSB.Object; y, z: LSB.Item;
- n, len: LONGINT; t: LSB.ArrayType;
- BEGIN
- IF sym = LSS.ident THEN
- x := ThisObj(LSS.id); LSS.Get(sym);
- IF x.tag = LSB.var THEN selector(x)
- ELSIF x.tag = LSB.const THEN n := x.b.val; NEW(x); x.tag := LSB.lit; x.val := n; x.type := LSB.integer
- ELSE LSS.Mark("bad factor")
- END
- ELSIF sym = LSS.lparen THEN
- LSS.Get(sym); expression(x);
- IF sym = LSS.rparen THEN LSS.Get(sym) ELSE LSS.Mark("rparen ?") END
- ELSIF sym = LSS.integer THEN
- NEW(x); x.tag := LSB.lit; x.val := LSS.val; x.type := LSB.integer; LSS.Get(sym);
- IF sym = LSS.apo THEN LSS.Get(sym);
- IF sym = LSS.integer THEN
- len := LSS.val; LSS.Get(sym);
- IF len < Log(x.val) THEN LSS.Mark("value too large") END
- ELSE LSS.Mark("integer ?"); len := 0
- END ;
- x.size := len
- ELSE len := 0
- END ;
- x.size := len
- ELSIF sym = LSS.not THEN
- LSS.Get(sym); factor(x); y := New(LSB.not, NIL, x); y.type := x.type; y.size := x.size; x := y
- ELSIF sym = LSS.lbrace THEN LSS.Get(sym); constructor(x)
- ELSE LSS.Mark("bad factor")
- END
- END factor0;
- PROCEDURE term(VAR x: LSB.Item);
- VAR y, z: LSB.Item; op: INTEGER;
- BEGIN factor(x);
- WHILE (sym >= LSS.times) & (sym <= LSS.and) DO
- IF sym = LSS.and THEN op := LSB.and
- ELSIF sym = LSS.times THEN op := LSB.mul
- ELSIF sym = LSS.div THEN op := LSB.div
- END ;
- LSS.Get(sym); factor(y); z := New(op, x, y); CheckTypes(x, y, z); x := z
- END
- END term;
- PROCEDURE SimpleExpression(VAR x: LSB.Item);
- VAR y, z: LSB.Item; op: INTEGER;
- BEGIN
- IF sym = LSS.minus THEN LSS.Get(sym); term(y);
- IF y.tag = LSB.lit THEN x := y; x.val := -y.val ELSE x := New(LSB.sub, NIL, y); x.type := y.type END
- ELSIF sym = LSS.plus THEN LSS.Get(sym); term(x);
- ELSE term(x)
- END ;
- WHILE (sym >= LSS.plus) & (sym <= LSS.xor) DO
- IF sym = LSS.or THEN op := LSB.or
- ELSIF sym = LSS.xor THEN op := LSB.xor
- ELSIF sym = LSS.plus THEN op := LSB.add
- ELSIF sym = LSS.minus THEN op := LSB.sub
- END ;
- LSS.Get(sym); term(y); z := New(op, x, y); CheckTypes(x, y, z); x := z
- END
- END SimpleExpression;
- PROCEDURE UncondExpression(VAR x: LSB.Item);
- VAR y, z: LSB.Item; rel: INTEGER;
- BEGIN SimpleExpression(x);
- IF (sym >= LSS.eql) & (sym <= LSS.geq) THEN
- IF sym = LSS.eql THEN rel := LSB.eql
- ELSIF sym = LSS.neq THEN rel := LSB.neq
- ELSIF sym = LSS.lss THEN rel := LSB.lss
- ELSIF sym = LSS.geq THEN rel := LSB.geq
- ELSIF sym = LSS.leq THEN rel := LSB.leq
- ELSE rel := LSB.gtr
- END ;
- LSS.Get(sym); SimpleExpression(y); z := New(rel, x, y); CheckTypes(x, y, z); z.type := LSB.bitType; x := z
- END
- END UncondExpression;
- PROCEDURE expression0(VAR x: LSB.Item);
- VAR y, z, w: LSB.Item;
- BEGIN UncondExpression(x);
- IF sym = LSS.then THEN
- IF x.type # LSB.bitType THEN LSS.Mark("Boolean?") END ;
- LSS.Get(sym); expression(y);
- IF sym = LSS.colon THEN
- LSS.Get(sym); expression(z); w := New(LSB.else, y, z); CheckTypes(y, z, w);
- x := New(LSB.then, x, w); x.type := w.type; x.size := w.size
- ELSE LSS.Mark("colon ?")
- END
- END
- END expression0;
- PROCEDURE CheckAssign(x, y: LSB.Item);
- VAR xtyp, ytyp: LSB.Type;
- BEGIN xtyp := x.type; ytyp := y.type;
- IF xtyp # ytyp THEN
- IF xtyp = LSB.bitType THEN
- IF (ytyp # LSB.integer) OR (y.val >= 2) THEN Err(70); END
- ELSIF xtyp IS LSB.ArrayType THEN
- IF xtyp(LSB.ArrayType).eltyp = LSB.bitType THEN
- IF (ytyp IS LSB.ArrayType) & (xtyp(LSB.ArrayType).eltyp = LSB.bitType) THEN (*w := w*)
- IF xtyp.size # ytyp.size THEN Err(71) END (* x + y *)
- ELSIF ytyp = LSB.integer THEN (* w := 5 *)
- IF xtyp.size < Log(y.val) THEN Err(72) END
- ELSIF ytyp = LSB.string THEN (* w := {...} *)
- IF xtyp.size # y.size THEN Err(73) END
- ELSE Err(74)
- END
- ELSE Err(74)
- END
- END
- END
- END CheckAssign;
- PROCEDURE Param(fpar: LSB.Object; VAR apar: LSB.Item);
- VAR y, z: LSB.Item;
- BEGIN expression(y); apar := New(LSB.next, NIL, y); CheckAssign(fpar, y);
- IF fpar.val IN {3, 4} THEN (*OUT or INOUT parameter*)
- IF ~(y.tag IN {3, 7}) THEN (*actual param is expression?*) LSS.Mark("bad actual param")
- ELSIF y.b = NIL THEN y.b := undef
- END
- END
- END Param;
- PROCEDURE Statement;
- VAR x, y, z, apar, npar: LSB.Item;
- unit: LSB.UnitType; fpar: LSB.Object;
- BEGIN
- IF sym < LSS.ident THEN LSS.Mark("bad factor");
- REPEAT LSS.Get(sym) UNTIL sym >= LSS.ident
- END ;
- IF sym = LSS.ident THEN
- x := ThisObj(LSS.id); z := x; LSS.Get(sym); selector(z);
- IF sym = LSS.becomes THEN LSS.Get(sym);
- IF x.val >= 5 THEN LSS.Mark("assignment to read-only") END ;
- IF (x.b # NIL) & ~(x.type IS LSB.ArrayType) THEN LSS.Mark("mult assign") END ;
- expression(y); CheckAssign(z, y); x.b := y; (*tricky*)
- IF z # x THEN x.a := z.b; x.val := 1 (*overwriting clk field x.a *) END
- ELSIF sym = LSS.lparen THEN LSS.Get(sym); (*unit instantiation*)
- IF x.type IS LSB.UnitType THEN
- unit := x.type(LSB.UnitType); fpar := unit.firstobj;
- IF sym # LSS.rparen THEN
- Param(fpar, apar); x.b := apar; fpar := fpar.next;
- WHILE sym # LSS.rparen DO
- IF sym = LSS.comma THEN LSS.Get(sym) END ;
- Param(fpar, npar);
- IF fpar.tag >= 3 THEN fpar := fpar.next; apar.a := npar; apar := npar
- ELSE LSS.Mark("too many params")
- END
- END ;
- IF fpar.val >= 3 THEN LSS.Mark("too few params") END
- END ;
- IF sym = LSS.rparen THEN LSS.Get(sym) ELSE LSS.Mark("rparen ?") END
- ELSE LSS.Mark("not a module")
- END
- ELSE LSS.Mark("bad statement")
- END
- END
- END Statement;
- PROCEDURE StatSequence;
- BEGIN Statement;
- WHILE sym <= LSS.semicolon DO
- IF sym = LSS.semicolon THEN LSS.Get(sym)
- ELSIF sym < LSS.semicolon THEN LSS.Mark("semicolon missing?");
- END ;
- Statement
- END ;
- IF sym = LSS.end THEN LSS.Get(sym) ELSE LSS.Mark("END ?") END
- END StatSequence;
- (*---------------------------------------------------*)
-
- PROCEDURE ConstDeclaration;
- VAR obj: LSB.Object;
- BEGIN
- IF sym = LSS.ident THEN
- obj := NewObj(LSB.const); LSS.Get(sym);
- IF (sym = LSS.becomes) OR (sym = LSS.eql) THEN LSS.Get(sym) ELSE LSS.Mark(":= ?") END ;
- expression(obj.b); obj.type := LSB.integer;
- IF sym = LSS.semicolon THEN LSS.Get(sym) ELSE LSS.Mark("semicolon ?") END
- ELSE LSS.Mark("ident ?")
- END
- END ConstDeclaration;
- PROCEDURE Type0(VAR type: LSB.Type);
- VAR obj: LSB.Object; len, size: LONGINT;
- eltyp: LSB.Type; arrtyp: LSB.ArrayType;
- BEGIN len := 1;
- IF sym = LSS.lbrak THEN (*array*) LSS.Get(sym);
- IF sym = LSS.integer THEN len := LSS.val; LSS.Get(sym)
- ELSIF sym = LSS.ident THEN obj := ThisObj(LSS.id); len := obj.val
- END ;
- IF sym = LSS.rbrak THEN LSS.Get(sym) ELSE LSS.Mark("rbrak ?") END ;
- Type0(eltyp); NEW(arrtyp); size := eltyp.size * len;
- arrtyp.eltyp := eltyp; type := arrtyp; type.len := len; type.size := size
- ELSIF sym = LSS.ident THEN
- obj := ThisObj(LSS.id); LSS.Get(sym);
- IF obj # NIL THEN
- IF obj.tag = LSB.typ THEN type := obj.type ELSE LSS.Mark("not a type"); type := LSB.bitType END
- ELSE LSS.Mark("type ?")
- END
- ELSE type := LSB.bitType; LSS.Mark("ident or [")
- END
- END Type0;
- PROCEDURE TypeDeclaration;
- VAR obj: LSB.Object; utyp: LSB.UnitType;
- BEGIN
- IF sym = LSS.ident THEN
- obj := NewObj(LSB.typ); LSS.Get(sym);
- IF (sym = LSS.becomes) OR (sym = LSS.eql) THEN LSS.Get(sym) ELSE LSS.Mark(":= ?") END ;
- IF sym = LSS.module THEN
- LSS.Get(sym); NEW(utyp); Unit(utyp.firstobj); obj.type := utyp; obj.type.typobj := obj
- ELSE Type0(obj.type)
- END ;
- IF sym = LSS.semicolon THEN LSS.Get(sym) ELSE LSS.Mark("semicolon ?") END
- ELSE LSS.Mark("ident ?")
- END
- END TypeDeclaration;
- PROCEDURE VarList(kind: INTEGER; clk: LSB.Item);
- VAR first, new, obj: LSB.Object; type: LSB.Type;
- BEGIN obj := NIL;
- WHILE sym = LSS.ident DO
- new := NewObj(LSB.var); new.name := LSS.id; new.val := kind; first := new; LSS.Get(sym);
- IF sym = LSS.comma THEN LSS.Get(sym) ELSIF sym = LSS.ident THEN LSS.Mark("comma missing") END ;
- WHILE sym = LSS.ident DO
- new := NewObj(LSB.var); new.name := LSS.id; new.val := kind; LSS.Get(sym);
- IF sym = LSS.comma THEN LSS.Get(sym) ELSIF sym = LSS.ident THEN LSS.Mark("comma missing") END
- END ;
- IF sym = LSS.colon THEN
- LSS.Get(sym); Type0(type); obj := first;
- WHILE obj # bot DO obj.type := type; obj.a := clk; obj := obj.next END
- ELSE LSS.Mark("colon ?")
- END ;
- IF sym = LSS.semicolon THEN LSS.Get(sym)
- ELSIF sym # LSS.rparen THEN LSS.Mark("semicolon or rparen missing")
- END
- END
- END VarList;
- PROCEDURE ParamList;
- VAR kind: INTEGER;
- BEGIN
- IF sym = LSS.in THEN kind := 6 ELSIF sym = LSS.out THEN kind := 3 ELSIF sym = LSS.inout THEN kind := 4 END ;
- LSS.Get(sym); VarList(kind, NIL)
- END ParamList;
- PROCEDURE Traverse(x: LSB.Item);
- BEGIN
- IF x # NIL THEN
- IF x IS LSB.Object THEN
- IF (x.tag = LSB.var) & (x.val >= 2) THEN (*not reg*)
- IF x(LSB.Object).marked THEN (*loop*)
- Texts.WriteString(W, x(LSB.Object).name); Texts.Write(W, " "); err := TRUE
- ELSIF x.b # NIL THEN x(LSB.Object).marked := TRUE; Traverse(x.b)
- END ;
- x(LSB.Object).marked := FALSE
- END
- ELSE Traverse(x.a); Traverse(x.b)
- END
- END
- END Traverse;
- PROCEDURE Unit0(VAR locals: LSB.Object);
- VAR obj, oldtop: LSB.Object; kind: INTEGER; clock: LSB.Item;
- BEGIN oldtop := top.next; top.next := LSB.root; (*top is dummy*)
- IF sym = LSS.lparen THEN LSS.Get(sym) ELSE LSS.Mark("lparen ?") END ;
- WHILE (sym = LSS.in) OR (sym = LSS.out) OR (sym = LSS.inout) DO ParamList END ;
- IF sym = LSS.rparen THEN LSS.Get(sym) ELSE LSS.Mark("rparen ?") END ;
- IF sym = LSS.xor (*arrow*) THEN LSS.Get(sym); locals := top.next
- ELSE
- IF sym = LSS.semicolon THEN LSS.Get(sym) ELSE LSS.Mark("semicolon ?") END ;
- IF sym = LSS.const THEN LSS.Get(sym);
- WHILE sym = LSS.ident DO ConstDeclaration END
- END ;
- IF sym = LSS.type THEN LSS.Get(sym);
- WHILE sym = LSS.ident DO TypeDeclaration END
- END ;
- WHILE (sym = LSS.var) OR (sym = LSS.reg) DO
- IF sym = LSS.var THEN LSS.Get(sym);
- WHILE sym = LSS.ident DO VarList(2, NIL) END
- ELSE (*reg*) kind := 0; LSS.Get(sym);
- IF sym = LSS.lparen THEN (*clock*)
- LSS.Get(sym); expression(clock);
- IF clock.type # LSB.bitType THEN LSS.Mark("clock must be bitType") END ;
- IF (clock IS LSB.Object) & (clock(LSB.Object).name = "clk") THEN kind := 1; clock := NIL END ;
- IF sym = LSS.rparen THEN LSS.Get(sym) ELSE LSS.Mark("rparen ?") END
- ELSE LSS.Mark("lparen expected"); clock := undef
- END ;
- WHILE sym = LSS.ident DO VarList(kind, clock) END
- END
- END ;
- locals := top.next;
- IF sym = LSS.begin THEN LSS.Get(sym); StatSequence END ;
- obj := locals; err := FALSE; (*find unassigned variables*)
- WHILE obj # LSB.root DO
- IF (obj.tag = LSB.var) & (obj.val < 5) THEN
- IF (obj.b = NIL) & (obj.val < 4) THEN Texts.WriteString(W, obj.name); Texts.Write(W, " "); err := TRUE
- ELSIF obj.b = undef THEN obj.b := NIL
- END
- END ;
- obj := obj.next
- END ;
- IF err THEN Texts.WriteString(W, " unassigned"); Texts.WriteLn(W)
- ELSE obj := locals; err := FALSE; (*find combinatorial loops*)
- WHILE obj # LSB.root DO
- IF obj.tag = LSB.var THEN obj.marked := TRUE; Traverse(obj.b); obj.marked := FALSE END ;
- obj := obj.next
- END ;
- IF err THEN Texts.WriteString(W, "in loop"); Texts.WriteLn(W) END
- END
- END ;
- IF err THEN Texts.Append(Oberon.Log, W.buf) END ;
- top.next := oldtop
- END Unit0;
- PROCEDURE Module(T: Texts.Text; pos: LONGINT);
- VAR root: LSB.Object; modname: ARRAY 32 OF CHAR;
- BEGIN Texts.WriteString(W, "compiling Lola: ");
- bot := LSB.root; top.next := bot; LSS.Init(T, pos); LSS.Get(sym);
- IF sym = LSS.module THEN
- LSS.Get(sym);
- IF sym = LSS.ident THEN
- modname := LSS.id; Texts.WriteString(W, LSS.id); LSS.Get(sym);
- Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf);
- ELSE LSS.Mark("ident ?")
- END ;
- Unit(root);
- IF sym = LSS.ident THEN LSS.Get(sym);
- IF LSS.id # modname THEN LSS.Mark("no match") END
- END ;
- IF sym # LSS.period THEN LSS.Mark("period ?") END ;
- IF ~LSS.error THEN LSB.Register(modname, root)
- ELSE Texts.WriteString(W, "compilation failed"); Texts.WriteLn(W); LSB.Register("", LSB.root)
- END
- ELSE LSS.Mark("module ?")
- END ;
- Texts.Append(Oberon.Log, W.buf)
- END Module;
- PROCEDURE Compile*;
- VAR beg, end, time: LONGINT;
- S: Texts.Scanner; T: Texts.Text;
- BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
- IF S.class = Texts.Char THEN
- IF S.c = "*" THEN
- ELSIF S.c = "@" THEN
- Oberon.GetSelection(T, beg, end, time);
- IF time >= 0 THEN Module(T, beg) END
- END
- ELSIF S.class = Texts.Name THEN
- NEW(T); Texts.Open(T, S.s); Module(T, 0)
- END ;
- Texts.Append(Oberon.Log, W.buf)
- END Compile;
- BEGIN Texts.OpenWriter(W);
- Texts.WriteString(W, "Lola compiler; NW 20.2.2015"); Texts.WriteLn(W);
- NEW(top); bot := LSB.root; NEW(undef); undef.tag := 2; undef.type := LSB.bitType;
- factor := factor0; expression := expression0; Unit := Unit0
- END LSC.
|