home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 10
/
Fresh_Fish_10_2352.bin
/
new
/
dev
/
obero
/
oberon
/
projectoberonsrc
/
obp.mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1994-10-17
|
31KB
|
944 lines
Syntax10.Scn.Fnt
MODULE Compiler; (*NW 7.6.87 / 21.8.92 / 14.12.93*)
IMPORT SYSTEM, Texts, TextFrames, Viewers, Oberon, OBS, OBT, OBC, OBE, OBH;
CONST NofCases = 128; ModNameLen = 20; MaxRecs = 32;
RecDescSize = 8; AdrSize = 4; ProcSize = 4; PtrSize = 4;
XParOrg = 12; LParOrg = 8; LDataSize = 2000H;
(*symbol values*)
times = 1; slash = 2; div = 3; mod = 4;
and = 5; plus = 6; minus = 7; or = 8; eql = 9;
neq = 10; lss = 11; leq = 12; gtr = 13; geq = 14;
in = 15; is = 16; arrow = 17; period = 18; comma = 19;
colon = 20; upto = 21; rparen = 22; rbrak = 23; rbrace = 24;
of = 25; then = 26; do = 27; to = 28; lparen = 29;
lbrak = 30; lbrace = 31; not = 32; becomes = 33; number = 34;
nil = 35; string = 36; ident = 37; semicolon = 38; bar = 39;
end = 40; else = 41; elsif = 42; until = 43; if = 44;
case = 45; while = 46; repeat = 47; loop = 48; with = 49;
exit = 50; return = 51; for = 52; by = 53;
array = 54; record = 55; pointer = 56;
begin = 57; const = 58; type = 59; var = 60; procedure = 61;
import = 62; module = 63;
(*object and item modes*)
Var = 1; Ind = 3; Con = 8; Stk = 9; Stk0 = 10; Fld = 13; Typ = 14;
LProc = 15; SProc = 16; CProc = 17; IProc = 18; Mod = 19;
(*structure forms*)
Undef = 0; Bool = 2; Char = 3; SInt = 4; Int = 5; LInt = 6; Real = 7; LReal = 8; Set = 9; String = 10;
NilTyp = 11; NoTyp = 12; Pointer = 13; ProcTyp = 14; Array = 15; DynArr = 16; Record = 17;
intSet = {4 .. 6}; labeltyps = {3 .. 6};
VAR W: Texts.Writer;
sym, nofrecs: INTEGER;
newSF: BOOLEAN;
dsize: LONGINT;
LoopLevel, ExitNo: INTEGER;
LoopExit: ARRAY 16 OF INTEGER;
PROCEDURE^ Type(VAR typ: OBT.Struct);
PROCEDURE^ FormalType(VAR typ: OBT.Struct);
PROCEDURE^ Expression(VAR x: OBT.Item);
PROCEDURE^ Block(VAR dsize: LONGINT);
PROCEDURE CheckSym(s: INTEGER);
BEGIN
IF sym = s THEN OBS.Get(sym) ELSE OBS.Mark(s) END
END CheckSym;
PROCEDURE qualident(VAR x: OBT.Item);
VAR mnolev: INTEGER; obj: OBT.Object;
BEGIN (*sym = ident*)
OBT.Find(obj, mnolev); OBS.Get(sym);
IF (sym = period) & (obj # NIL) & (obj.mode = Mod) THEN
OBS.Get(sym); mnolev := SHORT(-obj.a0);
IF sym = ident THEN
OBT.FindImport(obj, obj); OBS.Get(sym)
ELSE OBS.Mark(10); obj := NIL
END
END ;
x.lev := mnolev; x.obj := obj;
IF obj # NIL THEN
x.mode := obj.mode; x.typ := obj.typ; x.a0 := obj.a0; x.a1 := obj.a1
ELSE OBS.Mark(0); x.mode := Var;
x.typ := OBT.undftyp; x.a0 := 0; x.obj := NIL
END
END qualident;
PROCEDURE ConstExpression(VAR x: OBT.Item);
BEGIN Expression(x);
IF x.mode # Con THEN
OBS.Mark(50); x.mode := Con; x.typ := OBT.inttyp; x.a0 := 1
END
END ConstExpression;
PROCEDURE NewStr(form: INTEGER): OBT.Struct;
VAR typ: OBT.Struct;
BEGIN NEW(typ);
typ.form := form; typ.mno := 0; typ.size := 4; typ.ref := 0;
typ.BaseTyp := OBT.undftyp; typ.strobj := NIL; RETURN typ
END NewStr;
PROCEDURE CheckMark(VAR mk: BOOLEAN);
BEGIN OBS.Get(sym);
IF sym = times THEN
IF OBC.level = 0 THEN mk := TRUE ELSE mk := FALSE; OBS.Mark(47) END ;
OBS.Get(sym)
ELSE mk := FALSE
END
END CheckMark;
PROCEDURE CheckUndefPointerTypes;
VAR obj: OBT.Object;
BEGIN obj := OBT.topScope.next;
WHILE obj # NIL DO
IF obj.mode = Undef THEN OBS.Mark(48) END ;
obj := obj.next
END
END CheckUndefPointerTypes;
PROCEDURE RecordType(VAR typ: OBT.Struct);
VAR adr, size: LONGINT;
fld, fld0, fld1: OBT.Object;
ftyp, btyp: OBT.Struct;
base: OBT.Item;
BEGIN adr := 0; typ := NewStr(Record); typ.BaseTyp := NIL; typ.extlev := 0;
IF sym = lparen THEN
OBS.Get(sym); (*record extension*)
IF sym = ident THEN
qualident(base);
IF (base.mode = Typ) & (base.typ.form = Record) THEN
typ.BaseTyp := base.typ; typ.extlev := base.typ.extlev + 1; adr := base.typ.size
ELSE OBS.Mark(52)
END
ELSE OBS.Mark(10)
END ;
CheckSym(rparen)
END ;
OBT.OpenScope(0); fld := NIL; fld1 := OBT.topScope;
LOOP
IF sym = ident THEN
LOOP
IF sym = ident THEN
IF typ.BaseTyp # NIL THEN
OBT.FindField(typ.BaseTyp, fld0);
IF fld0 # NIL THEN OBS.Mark(1) END
END ;
OBT.Insert(OBS.name, fld); CheckMark(fld.marked); fld.mode := Fld
ELSE OBS.Mark(10)
END ;
IF sym = comma THEN OBS.Get(sym)
ELSIF sym = ident THEN OBS.Mark(19)
ELSE EXIT
END
END ;
CheckSym(colon); Type(ftyp); size := ftyp.size; btyp := ftyp;
WHILE btyp.form = Array DO btyp := btyp.BaseTyp END ;
IF btyp.size >= 4 THEN INC(adr, (-adr) MOD 4)
ELSIF btyp.size = 2 THEN INC(adr, adr MOD 2)
END ;
WHILE fld1.next # NIL DO
fld1 := fld1.next; fld1.typ := ftyp; fld1.a0 := adr; INC(adr, size)
END
END ;
IF sym = semicolon THEN OBS.Get(sym)
ELSIF sym = ident THEN OBS.Mark(38)
ELSE EXIT
END
END ;
typ.size := (-adr) MOD 4 + adr; typ.mno := 0; typ.link := OBT.topScope.next;
CheckUndefPointerTypes; OBT.CloseScope;
IF OBC.level = 0 THEN INC(dsize, (-dsize) MOD 4 + 4); typ.adr := -dsize END ;
OBC.RegisterRecType(typ)
END RecordType;
PROCEDURE ArrayType(VAR typ: OBT.Struct);
VAR x: OBT.Item; f, n: INTEGER;
BEGIN typ := NewStr(Array); ConstExpression(x); f := x.typ.form;
IF f IN intSet THEN
IF x.a0 <= 0 THEN x.a0 := 1; OBS.Mark(63) END
ELSE OBS.Mark(51); x.a0 := 1
END ;
IF sym = of THEN OBS.Get(sym); Type(typ.BaseTyp)
ELSIF sym = comma THEN OBS.Get(sym); ArrayType(typ.BaseTyp)
ELSE OBS.Mark(34)
END ;
typ.size := x.a0 * typ.BaseTyp.size
END ArrayType;
PROCEDURE FormalParameters(VAR resTyp: OBT.Struct; VAR psize: LONGINT);
VAR mode: SHORTINT;
adr, size: LONGINT; res: OBT.Item;
par, par1: OBT.Object; typ: OBT.Struct;
BEGIN par1 := OBT.topScope; adr := 0;
IF (sym = ident) OR (sym = var) THEN
LOOP
IF sym = var THEN OBS.Get(sym); mode := Ind ELSE mode := Var END ;
LOOP
IF sym = ident THEN
OBT.Insert(OBS.name, par); OBS.Get(sym); par.mode := mode
ELSE OBS.Mark(10)
END ;
IF sym = comma THEN OBS.Get(sym)
ELSIF sym = ident THEN OBS.Mark(19)
ELSIF sym = var THEN OBS.Mark(19); OBS.Get(sym)
ELSE EXIT
END
END ;
CheckSym(colon); FormalType(typ);
IF mode = Ind THEN (*VAR param*)
IF typ.form = Record THEN size := RecDescSize
ELSIF typ.form = DynArr THEN size := typ.size
ELSE size := AdrSize
END
ELSE size := (-typ.size) MOD 4 + typ.size
END ;
WHILE par1.next # NIL DO
par1 := par1.next; par1.typ := typ; DEC(adr, size); par1.a0 := adr
END ;
IF sym = semicolon THEN OBS.Get(sym)
ELSIF sym = ident THEN OBS.Mark(38)
ELSE EXIT
END
END
END ;
psize := psize - adr; par := OBT.topScope.next;
WHILE par # NIL DO INC(par.a0, psize); par := par.next END ;
CheckSym(rparen);
IF sym = colon THEN
OBS.Get(sym); resTyp := OBT.undftyp;
IF sym = ident THEN qualident(res);
IF res.mode = Typ THEN
IF (res.typ.form <= ProcTyp) & (res.typ.form # NoTyp) THEN resTyp := res.typ
ELSE OBS.Mark(54)
END
ELSE OBS.Mark(52)
END
ELSE OBS.Mark(10)
END
ELSE resTyp := OBT.notyp
END
END FormalParameters;
PROCEDURE ProcType(VAR typ: OBT.Struct);
VAR psize: LONGINT;
BEGIN typ := NewStr(ProcTyp); typ.size := ProcSize;
IF sym = lparen THEN
OBS.Get(sym); OBT.OpenScope(OBC.level); psize := XParOrg;
FormalParameters(typ.BaseTyp, psize); typ.link := OBT.topScope.next;
OBT.CloseScope
ELSE typ.BaseTyp := OBT.notyp; typ.link := NIL
END
END ProcType;
PROCEDURE HasPtr(typ: OBT.Struct): BOOLEAN;
VAR fld: OBT.Object;
BEGIN
IF typ.form = Pointer THEN RETURN TRUE
ELSIF typ.form = Array THEN RETURN HasPtr(typ.BaseTyp)
ELSIF typ.form = Record THEN
IF (typ.BaseTyp # NIL) & HasPtr(typ.BaseTyp) THEN RETURN TRUE END ;
fld := typ.link;
WHILE fld # NIL DO
IF (fld.name = "") OR HasPtr(fld.typ) THEN RETURN TRUE END ;
fld := fld.next
END
END ;
RETURN FALSE
END HasPtr;
PROCEDURE SetPtrBase(ptyp, btyp: OBT.Struct);
BEGIN
IF (btyp.form = Record) OR (btyp.form = Array) & ~HasPtr(btyp.BaseTyp) THEN
ptyp.BaseTyp := btyp
ELSE ptyp.BaseTyp := OBT.undftyp; OBS.Mark(57)
END
END SetPtrBase;
PROCEDURE Type(VAR typ