home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 10
/
Fresh_Fish_10_2352.bin
/
new
/
dev
/
obero
/
oberon
/
projectoberonsrc
/
obh.mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1994-10-17
|
18KB
|
496 lines
Syntax10.Scn.Fnt
MODULE OBH; (*NW 7.6.87 / 11.7.93*)
IMPORT OBS, OBT, OBC;
CONST
(*instruction format prefixes*)
F6 = 4EH; F7 = 0CEH; F9 = 3EH; F11 = 0BEH;
(*object and item modes*)
Var = 1; VarX = 2; Ind = 3; IndX = 4; RegI = 5;
RegX = 6; Abs = 7; Con = 8; Stk = 9; Stk0 = 10; Coc = 11; Reg = 12;
Fld = 13; LProc = 15; CProc = 17; IProc = 18; Mod = 19;
(*structure forms*)
Undef = 0; Byte = 1; 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;
TYPE LabelRange* = RECORD low*, high*: INTEGER; label*: INTEGER END ;
VAR clrchk*, stkchk*: BOOLEAN;
lengcode: ARRAY 18 OF INTEGER;
PROCEDURE setCC(VAR x: OBT.Item; cc: LONGINT);
BEGIN
x.typ := OBT.booltyp; x.mode := Coc; x.a0 := cc; x.a1 := 0; x.a2 := 0
END setCC;
PROCEDURE AdjustSP*(n: LONGINT);
BEGIN (*ADJSPB n*)
IF n <= 127 THEN OBC.PutF3(-5A84H); OBC.PutByte(n)
ELSE OBC.PutF3(-5A83H); OBC.PutWord(n)
END
END AdjustSP;
PROCEDURE move(L: INTEGER; VAR x, y: OBT.Item);
BEGIN
IF (y.mode = Con) & (y.a0 <= 7) & (y.a0 >= -8) THEN OBC.PutF2(L+5CH, y.a0, x) (*MOVQi*)
ELSE OBC.PutF4(L+14H, x, y) (*MOVi*)
END
END move;
PROCEDURE load(VAR x: OBT.Item);
VAR y: OBT.Item;
BEGIN IF x.mode # Reg THEN y := x; OBC.GetReg(x); move(lengcode[x.typ.form], x, y) END
END load;
PROCEDURE moveBW(VAR x, y: OBT.Item);
BEGIN
IF (y.mode = Con) & (y.a0 <= 7) & (y.a0 >= -8) THEN OBC.PutF2(5DH, y.a0, x)
ELSE OBC.Put(F7, 10H, x, y) (*MOVXBW*)
END
END moveBW;
PROCEDURE moveBD(VAR x, y: OBT.Item);
BEGIN
IF (y.mode = Con) & (y.a0 <= 7) & (y.a0 >= -8) THEN OBC.PutF2(5FH, y.a0, x)
ELSE OBC.Put(F7, 1CH, x, y) (*MOVXBD*)
END
END moveBD;
PROCEDURE moveWD(VAR x, y: OBT.Item);
BEGIN
IF (y.mode = Con) & (y.a0 <= 7) & (y.a0 >= -8) THEN OBC.PutF2(5FH, y.a0, x)
ELSE OBC.Put(F7, 1DH, x, y) (*MOVXWD*)
END
END moveWD;
PROCEDURE Leng(VAR x: OBT.Item; L: LONGINT);
VAR y: OBT.Item;
BEGIN
IF L <= 7 THEN OBC.PutF2(5FH, L, x) (*MOVQD*)
ELSE y.mode := Con; y.a0 := L; y.typ := OBT.linttyp; OBC.PutF4(17H, x, y)
END
END Leng;
PROCEDURE MoveBlock(VAR x, y: OBT.Item; s: LONGINT; param: BOOLEAN);
VAR L: INTEGER; z: OBT.Item;
BEGIN
IF s > 0 THEN
IF param THEN s := (s+3) DIV 4 * 4; AdjustSP(s) END ;
IF s <= 16 THEN
OBC.Put(F7, 0, x, y); OBC.PutDisp(s-1) (*MOVMB*)
ELSE
z.mode := Reg; z.a0 := 1; OBC.PutF4(27H, z, y); (*ADDR y,R1*)
z.a0 := 2; OBC.PutF4(27H, z, x); z.a0 := 0; (*ADDR x,R2*)
IF s MOD 4 = 0 THEN L := 3; s := s DIV 4
ELSIF s MOD 2 = 0 THEN L := 1; s := s DIV 2
ELSE L := 0
END ;
Leng(z, s);
OBC.PutF1(14); OBC.PutByte(L); OBC.PutByte(0) (*MOVS*)
END
END
END MoveBlock;
PROCEDURE DynArrBnd(ftyp, atyp: OBT.Struct; lev: INTEGER; adr: LONGINT; varpar: BOOLEAN);
VAR f: INTEGER; x, y, z: OBT.Item;
BEGIN (* ftyp.form = DynArr *)
x.mode := Stk; y.mode := Var;
IF varpar & (ftyp.BaseTyp.form = Byte) THEN
IF atyp.form # DynArr THEN
IF (atyp.form # Array) OR (atyp.BaseTyp.size > 1) THEN OBS.Mark(-1) END ;
Leng(x, atyp.size)
ELSE y.lev := lev; y.a0 := adr + atyp.adr; y.typ := OBT.linttyp;
atyp := atyp.BaseTyp;
IF atyp.form # DynArr THEN
IF atyp.size > 1 THEN
OBS.Mark(-1); z.mode := Con; z.typ := OBT.linttyp; z.a0 := atyp.size;
load(y); OBC.Put(F7, 23H, y, z); (* MULD z, Ry *)
z.mode := Con; z.typ := OBT.linttyp; z.a0 := atyp.size
END
ELSE OBS.Mark(-1); load(y); OBC.PutF2(0FH, 1, y);
REPEAT z.mode := Var; z.lev := lev; z.a0 := atyp.adr + adr; z.typ := OBT.linttyp;
load(z); OBC.Put(F7, 23H, y, z); (* MULD Rz, Ry *)
atyp := atyp.BaseTyp
UNTIL atyp.form # DynArr;
IF atyp.size > 1 THEN
z.mode := Con; z.typ := OBT.linttyp; z.a0 := atyp.size;
OBC.Put(F7, 23H, y, z) (* MULD z, Ry *)
END
END ;
OBC.PutF4(17H, x, y) (* MOVD apdynarrlen, TOS *)
END
ELSE
LOOP f := atyp.form;
IF f = Array THEN Leng(x, atyp.size DIV atyp.BaseTyp.size)
ELSIF f = DynArr THEN y.lev := lev; y.a0 := atyp.adr + adr; OBC.PutF4(17H, x, y)
ELSE OBS.Mark(66); EXIT
END ;
ftyp := ftyp.BaseTyp; atyp := atyp.BaseTyp;
IF ftyp.form # DynArr THEN
IF ftyp # atyp THEN
IF ~varpar & (ftyp.form = Pointer) & (atyp.form = Pointer) THEN
ftyp := ftyp.BaseTyp; atyp := atyp.BaseTyp;
IF (ftyp.form = Record) & (atyp.form = Record) THEN
WHILE (ftyp # atyp) & (atyp # NIL) DO atyp := atyp.BaseTyp END ;
IF atyp = NIL THEN OBS.Mark(113) END
ELSE OBS.Mark(67)
END
ELSE OBS.Mark(67)
END
END ;
EXIT
END
END
END
END DynArrBnd;
PROCEDURE Trap*(n: INTEGER);
BEGIN OBC.PutF1(0F2H); OBC.PutByte(n) (*BPT n*)
END Trap;
PROCEDURE CompareParLists*(x, y: OBT.Object);
VAR xt, yt: OBT.Struct;
BEGIN
WHILE x # NIL DO
IF y # NIL THEN
xt := x.typ; yt := y.typ;
WHILE (xt.form = DynArr) & (yt.form = DynArr) DO
xt := xt.BaseTyp; yt := yt.BaseTyp
END ;
IF x.mode # y.mode THEN OBS.Mark(115)
ELSIF xt # yt THEN
IF (xt.form = ProcTyp) & (yt.form = ProcTyp) THEN
CompareParLists(xt.link, yt.link)
ELSE OBS.Mark(115)
END
END ;
y := y.next
ELSE OBS.Mark(116)
END ;
x := x.next
END ;
IF (y # NIL) & (y.mode <= Ind) & (y.a0 > 0) THEN OBS.Mark(117) END
END CompareParLists;
PROCEDURE Assign*(VAR x, y: OBT.Item; param: BOOLEAN);
VAR f, g, L, u: INTEGER; s, vsz: LONGINT;
p, q: OBT.Struct;
tag, tdes: OBT.Item;
BEGIN f := x.typ.form; g := y.typ.form;
IF x.mode = Con THEN OBS.Mark(56)
ELSIF (x.mode IN {Var, VarX}) & (x.lev < 0) THEN OBS.Mark(-3)
END ;
CASE f OF
Undef, String:
| Byte: IF g IN {Undef, Byte, Char, SInt} THEN
IF param THEN moveBD(x, y) ELSE move(0, x, y) END
ELSE OBS.Mark(113)
END
| Bool: IF param THEN u := 3 ELSE u := 0 END ;
IF y.mode = Coc THEN
IF (y.a1 = 0) & (y.a2 = 0) THEN OBC.PutF2(u+3CH, y.a0, x)
ELSE
IF ODD(y.a0) THEN OBC.PutF0(y.a0-1) ELSE OBC.PutF0(y.a0+1) END ;
OBC.PutWord(y.a2); y.a2 := OBC.pc-2;
OBC.FixLink(y.a1); OBC.PutF2(u+5CH, 1, x);
OBC.PutF0(14); L := OBC.pc; OBC.PutWord(0);
OBC.FixLink(y.a2); OBC.PutF2(u+5CH, 0, x); OBC.fixup(L)
END
ELSIF g = Bool THEN
IF y.mode = Con THEN OBC.PutF2(u+5CH, y.a0, x)
ELSIF param THEN OBC.Put(F7, 18H, x, y) (*MOVZBD*)
ELSE OBC.PutF4(14H, x, y)
END
ELSE OBS.Mark(113)
END
| Char, SInt:
IF g = f THEN
IF param THEN moveBD(x, y) ELSE move(0, x, y) END
ELSE OBS.Mark(113)
END
| Int: IF g = Int THEN
IF param THEN moveWD(x, y) ELSE move(1, x, y) END
ELSIF g = SInt THEN
IF param THEN moveBD(x, y) ELSE moveBW(x, y) END
ELSE OBS.Mark(113)
END
| LInt: IF g = LInt THEN move(3, x, y)
ELSIF g = Int THEN moveWD(x, y)
ELSIF g = SInt THEN moveBD(x, y)
ELSE OBS.Mark(113)
END
| Real: IF g = Real THEN OBC.Put(F11, 5, x, y)
ELSIF (SInt <= g) & (g <= LInt) THEN OBC.Put(F9, lengcode[g]+4, x, y)
ELSE OBS.Mark(113)
END
| LReal:IF g = LReal THEN OBC.Put(F11, 4, x, y)
ELSIF g = Real THEN OBC.Put(F9, 1BH, x, y)
ELSIF (SInt <= g) & (g <= LInt) THEN OBC.Put(F9, lengcode[g], x, y)
ELSE OBS.Mark(113)
END
| Set: IF g = f THEN move(3, x, y) ELSE OBS.Mark(113) END
| Pointer:
IF x.typ = y.typ THEN move(3, x, y)
ELSIF g = NilTyp THEN OBC.PutF2(5FH, 0, x)
ELSIF g = Pointer THEN
p := x.typ.BaseTyp; q := y.typ.BaseTyp;
IF (p.form = Record) & (q.form = Record) THEN
WHILE (q # p) & (q # NIL) DO q := q.BaseTyp END ;
IF q # NIL THEN move(3, x, y) ELSE OBS.Mark(113) END
ELSE OBS.Mark(113)
END
ELSE OBS.Mark(113)
END
| Array: s := x.typ.size;
IF x.typ = y.typ THEN MoveBlock(x, y, s, param)
ELSIF (g = String) & (x.typ.BaseTyp.form = Char) THEN
s := y.a1; vsz := x.typ.size; (*check length of string*)
IF s > vsz THEN OBS.Mark(114) END ;
IF param THEN
vsz := (vsz+3) DIV 4