home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1994-10-17 | 18.5 KB | 547 lines |
- Syntax10.Scn.Fnt
- MODULE OBC; (*NW 30.5.87 / 28.3.93*)
- IMPORT Files, OBS, OBT;
- CONST ObjMark = 0F5X; CodeLength = 20000; LinkLength = 250;
- ConstLength = 3500; EntryLength = 96; MaxImps = 32;
- MaxPtrs = 64; MaxRecs = 32; MaxComs = 40; MaxExts = 7;
- (*instruction 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; Typ = 14; LProc = 15; SProc = 16; CProc = 17; IProc = 18; Mod = 19; Head = 20;
- (*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 Argument =
- RECORD form, gen, inx: INTEGER;
- d1, d2: LONGINT
- END ;
- VAR pc*, Pc*, level*: INTEGER;
- wasderef*: OBT.Object;
- typchk*: BOOLEAN;
- RegSet, FRegSet: SET;
- StrOffset: LONGINT;
- conx, nofrecs: INTEGER;
- fixlist0: ARRAY MaxImps OF INTEGER; (*abs adr*)
- fixlist1: ARRAY MaxImps OF INTEGER; (*PC-rel adr*)
- RecTab: ARRAY MaxRecs OF OBT.Struct;
- constant: ARRAY ConstLength OF CHAR;
- code: ARRAY CodeLength OF CHAR;
- PROCEDURE SetStrOffset*(varsize: LONGINT);
- BEGIN StrOffset := -ConstLength - varsize
- END SetStrOffset;
- PROCEDURE GetReg*(VAR x: OBT.Item);
- VAR i: INTEGER;
- BEGIN i := 7; x.mode := Reg;
- LOOP IF ~(i IN RegSet) THEN x.a0 := i; INCL(RegSet,i); EXIT END ;
- IF i = 0 THEN x.a0 := 0; OBS.Mark(215); EXIT ELSE DEC(i) END ;
- END
- END GetReg;
- PROCEDURE GetFReg*(VAR x: OBT.Item);
- VAR i: INTEGER;
- BEGIN i := 6; x.mode := Reg;
- LOOP IF ~(i IN FRegSet) THEN x.a0 := i; INCL(FRegSet,i); EXIT END ;
- IF i = 0 THEN x.a0 := 0; OBS.Mark(216); EXIT ELSE i := i-2 END
- END
- END GetFReg;
- PROCEDURE UsedRegisters*(): SET;
- BEGIN RETURN RegSet
- END UsedRegisters;
- PROCEDURE FreeRegs*(r: SET);
- BEGIN RegSet := r; FRegSet := {}
- END FreeRegs;
- PROCEDURE Release*(VAR x: OBT.Item);
- BEGIN
- IF x.mode = Reg THEN
- IF x.typ.form IN {Real, LReal} THEN EXCL(FRegSet, x.a0) ELSE EXCL(RegSet, x.a0) END
- ELSIF x.mode = RegI THEN EXCL(RegSet, x.a0)
- ELSIF x.mode = RegX THEN EXCL(RegSet, x.a0); EXCL(RegSet, x.a2)
- ELSIF x.mode IN {VarX, IndX} THEN EXCL(RegSet, x.a2)
- END
- END Release;
- PROCEDURE CheckCodeSize*;
- BEGIN
- IF pc > CodeLength - 256 THEN OBS.Mark(210); pc := 4 END
- END CheckCodeSize;
- PROCEDURE AllocString*(VAR s: ARRAY OF CHAR; VAR x: OBT.Item);
- VAR i: INTEGER; ch: CHAR;
- BEGIN (*fill constant table backward*) i := 0;
- REPEAT ch := s[i]; INC(i) UNTIL ch = 0X;
- x.a1 := i;
- IF i <= conx THEN
- REPEAT DEC(i); DEC(conx); constant[conx] := s[i] UNTIL i = 0
- ELSE OBS.Mark(230)
- END ;
- x.a0 := conx
- END AllocString;
- PROCEDURE PutByte*(x: LONGINT);
- BEGIN code[pc] := CHR(x); INC(pc)
- END PutByte;
- PROCEDURE PutWord*(x: LONGINT); (*high byte first*)
- BEGIN code[pc] := CHR(x DIV 100H); INC(pc); code[pc] := CHR(x); INC(pc)
- END PutWord;
- PROCEDURE PutDbl*(x: LONGINT);
- VAR i: INTEGER;
- BEGIN i := -32;
- REPEAT INC(i, 8); code[pc] := CHR(ASH(x, i)); INC(pc) UNTIL i = 0
- END PutDbl;
- PROCEDURE PutF3*(op: INTEGER);
- BEGIN code[pc] := CHR(op); INC(pc); code[pc] := CHR(op DIV 100H); INC(pc)
- END PutF3;
- PROCEDURE PutExtAdr*(mno: INTEGER; pno: LONGINT);
- BEGIN PutWord(pno - 4000H); PutF3(fixlist1[mno]); fixlist1[mno] := pc - 4
- END PutExtAdr;
- PROCEDURE PutDisp*(x: LONGINT);
- BEGIN
- IF x < 0 THEN
- IF x >= -40H THEN code[pc] := CHR(x+80H); INC(pc)
- ELSIF x >= -2000H THEN PutWord(x+0C000H)
- ELSE PutDbl(x)
- END
- ELSIF x < 40H THEN code[pc] := CHR(x); INC(pc)
- ELSIF x < 2000H THEN PutWord(x+8000H)
- ELSE PutDbl(x - 40000000H)
- END
- END PutDisp;
- PROCEDURE PutArg(VAR z: Argument);
- BEGIN
- CASE z.form OF
- 0: IF z.inx = 1 THEN code[pc] := CHR(z.d1); INC(pc)
- ELSIF z.inx = 2 THEN PutWord(z.d1)
- ELSIF z.inx = 4 THEN PutDbl(z.d1)
- ELSIF z.inx = 8 THEN PutDbl(z.d2); PutDbl(z.d1)
- END
- | 1:
- | 2,6: PutDisp(z.d1)
- | 3,7: PutDisp(z.d1); PutDisp(z.d2)
- | 4,8: PutDisp(z.d1 - Pc)
- | 5,9: PutWord(z.d1 - 4000H); PutF3(fixlist0[z.d2]); fixlist0[z.d2] := pc - 4
- END
- END PutArg;
- PROCEDURE Operand(VAR x: OBT.Item; VAR z: Argument);
- PROCEDURE downlevel(VAR gen: INTEGER);
- VAR n, op: INTEGER; b: OBT.Item;
- BEGIN GetReg(b); n := level - x.lev; gen := SHORT(b.a0) + 8;
- op := SHORT(b.a0)*40H - 3FE9H;
- IF n = 1 THEN PutF3(op); PutDisp(8); (*MOVD 8(FP) Rb*)
- ELSE PutF3(op - 4000H); PutDisp(8); PutDisp(8); (*MOVD 8(8(FP)) Rb*)
- WHILE n > 2 DO DEC(n);
- PutF3((SHORT(b.a0)*20H + SHORT(b.a0))*40H + 4017H); PutDisp(8)
- END
- END ;
- END downlevel;
- PROCEDURE index;
- VAR s: LONGINT;
- BEGIN s := x.typ.size;
- IF s = 1 THEN z.gen := 1CH
- ELSIF s = 2 THEN z.gen := 1DH
- ELSIF s = 4 THEN z.gen := 1EH
- ELSIF s = 8 THEN z.gen := 1FH
- ELSE z.gen := 1CH; PutByte(F7); PutByte(x.a2 MOD 4 * 40H + 23H); (*MULD s, r*)
- PutByte(x.a2 DIV 4 + 0A0H); PutWord(0); PutWord(s)
- END
- END index;
- BEGIN
- CASE x.mode OF
- Var: IF x.lev = 0 THEN
- z.gen := 1BH; z.d1 := x.a0; z.form := 4
- ELSIF x.lev < 0 THEN
- z.gen := 15H; z.d1 := x.a0; z.d2 := -x.lev; z.form := 5
- ELSIF x.lev = level THEN
- z.gen := 18H; z.d1 := x.a0; z.form := 2
- ELSIF x.lev+1 = level THEN
- z.gen := 10H; z.d1 := 8; z.d2 := x.a0; z.form := 3
- ELSE downlevel(z.gen); z.d1 := x.a0; z.form := 2
- END
- | Ind: IF x.lev <= 0 THEN OBS.Mark(240)
- ELSIF x.lev = level THEN
- z.gen := 10H; z.d1 := x.a0; z.d2 := x.a1; z.form := 3
- ELSE downlevel(z.gen);
- PutF3((z.gen*20H + z.gen-8)*40H + 17H); PutDisp(x.a0);
- z.d1 := x.a1; z.form := 2
- END
- | RegI: z.gen := SHORT(x.a0)+8; z.d1 := x.a1; z.form := 2
- | VarX: index;
- IF x.lev = 0 THEN
- z.inx := 1BH; z.d1 := x.a0; z.form := 8
- ELSIF x.lev < 0 THEN
- z.inx := 15H; z.d1 := x.a0; z.d2 := -x.lev; z.form := 9
- ELSIF x.lev = level THEN
- z.inx := 18H; z.d1 := x.a0; z.form := 6
- ELSIF x.lev+1 = level THEN
- z.inx := 10H; z.d1 := 8; z.d2 := x.a0; z.form := 7
- ELSE downlevel(z.inx); z.d1 := x.a0; z.form := 6
- END ;
- z.inx := z.inx*8 + SHORT(x.a2)
- | IndX: index;
- IF x.lev <= 0 THEN OBS.Mark(240)
- ELSIF x.lev = level THEN
- z.inx := 10H; z.d1 := x.a0; z.d2 := x.a1; z.form := 7
- ELSE downlevel(z.inx);
- PutF3((z.inx*20H + z.inx-8)*40H + 17H); PutDisp(x.a0);
- z.d1 := x.a1; z.form := 6
- END ;
- z.inx := z.inx * 8 + SHORT(x.a2)
- | RegX: index; z.inx := SHORT((x.a0+8)*8 + x.a2); z.d1 := x.a1; z.form := 6
- | Con: z.form := 0;
- CASE x.typ.form OF
- Undef, Byte, Bool, Char, SInt:
- z.gen := 14H; z.inx := 1; z.d1 := x.a0
- | Int:
- z.gen := 14H; z.inx := 2; z.d1 := x.a0
- | LInt, Real, Set, Pointer, ProcTyp, NilTyp:
- z.gen := 14H; z.inx := 4; z.d1 := x.a0
- | LReal:
- z.gen := 14H; z.inx := 8; z.d1 := x.a0; z.d2 := x.a1
- | String:
- z.form := 4; z.gen := 1BH; z.d1 := x.a0 + StrOffset
- END
- | Reg: z.gen := SHORT(x.a0); z.form := 1
- | Stk: z.gen := 17H; z.form := 1
- | Stk0: z.gen := 19H; z.form := 2; z.d1 := 0
- | Abs: z.gen := 15H; z.form := 2; z.d1 := x.a0
- | Coc, Fld .. Head: OBS.Mark(126); x.mode := Var; z.form := 0
- END
- END Operand;
- PROCEDURE PutF0*(cond: LONGINT);
- BEGIN code[pc] := CHR(cond*10H + 10); INC(pc)
- END PutF0;
- PROCEDURE PutF1*(op: INTEGER);
- BEGIN code[pc] := CHR(op); INC(pc)
- END PutF1;
- PROCEDURE PutF2*(op: INTEGER; short: LONGINT; VAR x: OBT.Item);
- VAR dst: Argument;
- BEGIN Operand(x, dst); Pc := pc;
- code[pc] := CHR(SHORT(short) MOD 2 * 80H + op); INC(pc);
- code[pc] := CHR(dst.gen*8 + SHORT(short) MOD 10H DIV 2);
- INC(pc);
- IF dst.form >= 6 THEN code[pc] := CHR(dst.inx); INC(pc) END ;
- PutArg(dst)
- END PutF2;
- PROCEDURE PutF4*(op: INTEGER; VAR x, y: OBT.Item);
- VAR dst, src: Argument;
- BEGIN Operand(x, dst); Operand(y, src); Pc := pc;
- code[pc] := CHR(dst.gen MOD 4 * 40H + op); INC(pc);
- code[pc] := CHR(src.gen*8 + dst.gen DIV 4); INC(pc);
- IF src.form >= 6 THEN code[pc] := CHR(src.inx); INC(pc) END ;
- IF dst.form >= 6 THEN code[pc] := CHR(dst.inx); INC(pc) END ;
- PutArg(src); PutArg(dst)
- END PutF4;
- PROCEDURE Put*(F, op: INTEGER; VAR x, y: OBT.Item);
- VAR dst, src: Argument;
- BEGIN Operand(x, dst); Operand(y, src); Pc := pc; code[pc] := CHR(F); INC(pc);
- code[pc] := CHR(dst.gen MOD 4 * 40H + op); INC(pc);
- code[pc] := CHR(src.gen*8 + dst.gen DIV 4); INC(pc);
- IF src.form >= 6 THEN code[pc] := CHR(src.inx); INC(pc) END ;
- IF dst.form >= 6 THEN code[pc] := CHR(dst.inx); INC(pc) END ;
- PutArg(src); PutArg(dst)
- END Put;
- PROCEDURE RegisterRecType*(typ: OBT.Struct);
- BEGIN
- IF typ.extlev > MaxExts THEN OBS.Mark(233)
- ELSIF nofrecs < MaxRecs THEN
- RecTab[nofrecs] := typ; INC(nofrecs);
- IF level > 0 THEN DEC(conx, 4); typ.adr := conx + StrOffset END
- ELSE OBS.Mark(223)
- END
- END RegisterRecType;
- PROCEDURE SaveRegisters*(VAR gR, fR: SET; VAR x: OBT.Item);
- VAR i, r, m: INTEGER; t: SET;
- BEGIN t := RegSet;
- IF x.mode IN {Reg, RegI, RegX} THEN EXCL(RegSet, x.a0) END ;
- IF x.mode IN {VarX, IndX, RegX} THEN EXCL(RegSet, x.a2) END ;
- gR := RegSet; fR := FRegSet;
- IF RegSet # {} THEN
- i := 0; r := 1; m := 0;
- REPEAT
- IF i IN RegSet THEN INC(m, r) END ;
- INC(r, r); INC(i)
- UNTIL i = 8;
- PutF1(62H); PutByte(m)
- END ;
- RegSet := t - RegSet; i := 0;
- WHILE FRegSet # {} DO
- IF i IN FRegSet THEN
- PutF1(F11); PutF3(i*800H + 5C4H); EXCL(FRegSet, i)
- END ;
- INC(i, 2)
- END
- END SaveRegisters;
- PROCEDURE RestoreRegisters*(gR, fR: SET; VAR x: OBT.Item);
- VAR i, r, m: INTEGER; y: OBT.Item;
- BEGIN RegSet := gR; FRegSet := fR; i := 8;
- (*set result mode*) x.mode := Reg; x.a0 := 0;
- IF (x.typ.form = Real) OR (x.typ.form = LReal) THEN
- IF 0 IN fR THEN GetFReg(y); Put(F11, 4, y, x); x.a0 := y.a0 END ;
- INCL(FRegSet, 0)
- ELSE
- IF 0 IN gR THEN GetReg(y); PutF4(17H, y, x); x.a0 := y.a0 END ;
- INCL(RegSet, 0)
- END ;
- WHILE fR # {} DO
- DEC(i, 2);
- IF i IN fR THEN
- PutF1(F11); PutF3(i*40H - 47FCH); EXCL(fR, i)
- END
- END ;
- IF gR # {} THEN
- i := 8; r := 1; m := 0;
- REPEAT DEC(i);
- IF i IN gR THEN INC(m, r) END ;
- INC(r, r)
- UNTIL i = 0;
- PutF1(72H); PutF1(m)
- END
- END RestoreRegisters;
- PROCEDURE DynArrAdr*(VAR x, y: OBT.Item); (* x := ADR(y) *)
- VAR l, r: OBT.Item;
- BEGIN
- WHILE y.typ.form = DynArr DO (* index with 0 *)
- IF y.mode = IndX THEN
- l.mode := Var; l.a0 := y.a0 + y.typ.adr; l.lev := y.lev;
- (* l = actual dimension length *)
- r.mode := Reg; r.a0 := y.a2; Put(F7, 23H, r, l) (*MULD len, r*)
- END;
- y.typ := y.typ.BaseTyp
- END;
- IF (y.mode = Var) OR (y.mode = Ind) & (y.a1 = 0) THEN
- y.mode := Var; PutF4(17H, x, y) (* MOVD *)
- ELSE PutF4(27H, x, y); x.a1 := 0 (* ADDR *)
- END
- END DynArrAdr;
- PROCEDURE fixup*(loc: LONGINT); (*enter pc at loc*)
- VAR x: LONGINT;
- BEGIN x := pc - loc + 8001H;
- code[loc] := CHR(x DIV 100H); code[loc+1] := CHR(x)
- END fixup;
- PROCEDURE fixupC*(loc: LONGINT);
- VAR x: LONGINT;
- BEGIN x := pc+1 - loc;
- IF x > 3 THEN
- IF x < 2000H THEN
- code[loc] := CHR(x DIV 100H + 80H); code[loc+1] := CHR(x)
- ELSE OBS.Mark(211)
- END
- ELSE DEC(pc, 3)
- END
- END fixupC;
- PROCEDURE fixupL*(loc: LONGINT);
- VAR x: LONGINT;
- BEGIN x := pc+1 - loc;
- IF x > 5 THEN
- code[loc+2] := CHR(x DIV 100H); code[loc+3] := CHR(x)
- ELSE DEC(pc, 5)
- END
- END fixupL;
- PROCEDURE FixLink*(L: LONGINT);
- VAR L1: LONGINT;
- BEGIN
- WHILE L # 0 DO
- L1 := ORD(code[L])*100H + ORD(code[L+1]);
- fixup(L); L := L1
- END
- END FixLink;
- PROCEDURE FixupWith*(L, val: LONGINT);
- VAR x: LONGINT;
- BEGIN x := val MOD 4000H + 8000H;
- IF ABS(val) >= 2000H THEN OBS.Mark(208) END ;
- code[L] := CHR(x DIV 100H); code[L+1] := CHR(x)
- END FixupWith;
- PROCEDURE FixLinkWith*(L, val: LONGINT);
- VAR L1: LONGINT;
- BEGIN
- WHILE L # 0 DO
- L1 := ORD(code[L])*100H + ORD(code[L+1]);
- FixupWith(L, val+1 - L); L := L1
- END
- END FixLinkWith;
- PROCEDURE FixupImm*(loc: INTEGER; val: LONGINT);
- VAR i: INTEGER;
- BEGIN i := 4;
- REPEAT DEC(i); DEC(loc); code[loc] := CHR(val); val := val DIV 100H UNTIL i = 0
- END FixupImm;
- PROCEDURE MergedLinks*(L0, L1: LONGINT): LONGINT;
- VAR L2, L3: LONGINT;
- BEGIN (*merge chains of the two operands of AND and OR *)
- IF L0 # 0 THEN L2 := L0;
- LOOP L3 := ORD(code[L2])*100H + ORD(code[L2+1]);
- IF L3 = 0 THEN EXIT END ;
- L2 := L3
- END ;
- code[L2] := CHR(L1 DIV 100H); code[L2+1] := CHR(L1);
- RETURN L0
- ELSE RETURN L1
- END
- END MergedLinks;
- PROCEDURE Init*;
- VAR i: INTEGER;
- BEGIN pc := 0; level := 0; conx := ConstLength; nofrecs := 0; RegSet := {}; FRegSet := {}; i := 0;
- REPEAT fixlist0[i] := 0; fixlist1[i] := 0; INC(i) UNTIL i = MaxImps
- END Init;
- PROCEDURE FindPtrs(typ: OBT.Struct; badr: LONGINT;
- VAR ptab: ARRAY OF LONGINT; VAR n: INTEGER);
- (*find all pointers in typ and enter their offsets (+badr) in ptab*)
- VAR fld: OBT.Object; btyp: OBT.Struct;
- i, m, s: LONGINT;
- BEGIN
- IF typ.form = Pointer THEN
- IF n < MaxPtrs THEN ptab[n] := badr; INC(n) ELSE OBS.Mark(222) END
- ELSIF typ.form = Record THEN
- btyp := typ.BaseTyp;
- IF btyp # NIL THEN FindPtrs(btyp, badr, ptab, n) END ;
- fld := typ.link;
- WHILE fld # NIL DO
- IF fld.name # "" THEN FindPtrs(fld.typ, fld.a0 + badr, ptab, n)
- ELSIF n < MaxPtrs THEN ptab[n] := fld.a0 + badr; INC(n)
- ELSE OBS.Mark(222)
- END ;
- fld := fld.next
- END
- ELSIF typ.form = Array THEN
- btyp := typ.BaseTyp; m := typ.size DIV btyp.size;
- WHILE btyp.form = Array DO
- m := btyp.size DIV btyp.BaseTyp.size * m; btyp := btyp.BaseTyp
- END ;
- IF (btyp.form = Pointer) OR (btyp.form = Record) THEN
- i := 0; s := btyp.size;
- WHILE i < m DO FindPtrs(btyp, i*s + badr, ptab, n); INC(i) END
- END
- END
- END FindPtrs;
- PROCEDURE OutCode*(VAR name, progid: ARRAY OF CHAR;
- key: LONGINT; datasize: LONGINT);
- VAR f, i, m, np, L, L1: INTEGER;
- s, s0, refpos: LONGINT;
- nofent, nofcom, nofptrs, comsize: INTEGER;
- obj: OBT.Object;
- typ: OBT.Struct;
- ObjFile: Files.File;
- out: Files.Rider;
- PtrTab: ARRAY MaxPtrs OF LONGINT;
- ComTab: ARRAY MaxComs OF OBT.Object;
- PROCEDURE W(n: INTEGER);
- BEGIN Files.Write(out, CHR(n)); Files.Write(out, CHR(n DIV 100H))
- END W;
- PROCEDURE WriteName(VAR name: ARRAY OF CHAR);
- VAR i: INTEGER; ch: CHAR;
- BEGIN i := 0;
- REPEAT ch := name[i]; Files.Write(out, ch); INC(i) UNTIL ch = 0X
- END WriteName;
- PROCEDURE Collect;
- (*collect commands, and pointers*)
- VAR obj, par: OBT.Object; u: INTEGER;
- BEGIN obj := OBT.topScope.next;
- WHILE obj # NIL DO
- IF obj.mode = LProc THEN
- IF obj.a0 = 0 THEN OBS.Mark(129)
- ELSIF obj.marked & (obj.typ.form = NoTyp) THEN
- par := obj.dsc;
- IF (par = NIL) OR (par.mode > 3) OR (par.a0 < 0) THEN (*command*)
- u := 0;
- WHILE obj.name[u] > 0X DO INC(comsize); INC(u) END ;
- INC(comsize, 3);
- IF nofcom < MaxComs THEN ComTab[nofcom] := obj; INC(nofcom)
- ELSE OBS.Mark(232); nofcom := 0; comsize := 0
- END
- END
- END
- ELSIF obj.mode = Var THEN FindPtrs(obj.typ, obj.a0, PtrTab, nofptrs)
- END ;
- obj := obj.next
- END
- END Collect;
- PROCEDURE OutBaseTypes(typ: OBT.Struct);
- BEGIN
- IF typ.BaseTyp # NIL THEN
- OutBaseTypes(typ.BaseTyp); Files.Write(out, CHR(typ.mno)); Files.WriteLInt(out, typ.adr)
- END
- END OutBaseTypes;
- PROCEDURE OutRefBlk(first: OBT.Object; pc: INTEGER; name: ARRAY OF CHAR);
- VAR obj: OBT.Object;
- BEGIN obj := first;
- WHILE obj # NIL DO
- IF obj.mode IN {LProc, IProc} THEN OutRefBlk(obj.dsc, obj.a2, obj.name) END ;
- obj := obj.next
- END ;
- Files.Write(out, 0F8X); Files.WriteInt(out, pc); Files.WriteString(out, name);
- obj := first;
- WHILE obj # NIL DO
- IF (obj.mode = Var) OR (obj.mode = Ind) THEN
- f := obj.typ.form;
- IF (f IN {Byte .. Set, Pointer})
- OR (f = Array) & (obj.typ.BaseTyp.form = Char) THEN
- Files.Write(out, CHR(obj.mode)); Files.Write(out, CHR(f));
- Files.WriteLInt(out, obj.a0); Files.WriteString(out, obj.name)
- END
- END ;
- obj:= obj.next
- END
- END OutRefBlk;
- BEGIN ObjFile := Files.New(name);
- IF ObjFile # NIL THEN
- Files.Set(out, ObjFile, 0);
- WHILE pc MOD 4 # 0 DO PutF1(0A2H) END ; (*NOP*)
- DEC(conx, conx MOD 4);
- nofcom := 0; comsize := 1; nofptrs := 0;
- WHILE nofptrs < nofrecs DO PtrTab[nofptrs] := RecTab[nofptrs].adr; INC(nofptrs) END ;
- Collect; L := fixlist0[0];
- (*header block*)
- Files.Write(out, ObjMark); Files.Write(out, "0"); Files.WriteLInt(out, refpos);
- Files.WriteInt(out, OBT.nofGmod); Files.WriteInt(out, OBT.entno);
- Files.WriteInt(out, nofptrs); Files.WriteInt(out, comsize);
- Files.WriteInt(out, ConstLength - conx); Files.WriteLInt(out, datasize);
- Files.WriteInt(out, pc); Files.WriteInt(out, nofrecs);
- Files.WriteLInt(out, key); Files.WriteString(out, progid);
- (*import block*)
- i := 0;
- WHILE i < OBT.nofGmod DO
- obj := OBT.GlbMod[i];
- Files.WriteLInt(out, obj.a1); Files.WriteString(out, obj.name); INC(i)
- END ;
- (*entry block*)
- Files.WriteBytes(out, OBT.entry, 2*OBT.entno);
- (*pointer block*) i := 0;
- WHILE i < nofptrs DO
- IF PtrTab[i] < -4000H THEN OBS.Mark(225) END ;
- Files.WriteInt(out, SHORT(PtrTab[i])); INC(i)
- END ;
- (*command block*) i := 0;
- WHILE i < nofcom DO
- obj := ComTab[i]; Files.WriteString(out, obj.name);
- Files.WriteInt(out, SHORT(obj.a0)); INC(i)
- END ;
- Files.Write(out, 0X);
- (*constants block*) i := conx;
- WHILE i < ConstLength DO Files.Write(out, constant[i]); INC(i) END ;
- (*code block*)
- Files.WriteBytes(out, code, pc);
- (*fixups*) i := 0;
- WHILE i < OBT.nofGmod DO
- INC(i); Files.WriteInt(out, fixlist0[i]); Files.WriteInt(out, fixlist1[i])
- END ;
- (*typdesc block*) i := 0;
- WHILE i < nofrecs DO
- typ := RecTab[i]; RecTab[i] := NIL; INC(i);
- s := typ.size + 4; m := 4; s0 := 16;
- WHILE (m > 0) & (s > s0) DO INC(s0, s0); DEC(m) END ;
- IF s > s0 THEN s0 := (s+127) DIV 128 * 128 END ;
- np := 0; FindPtrs(typ, 0, PtrTab, np); s := np*2 + (MaxExts+1)*4;
- Files.WriteInt(out, SHORT(s)); Files.WriteInt(out, SHORT(typ.adr)); (*td size/adr*)
- s := LONG(np)*1000000H + s0; Files.WriteLInt(out, s); (*head of typdesc*)
- Files.Write(out, CHR(typ.extlev)); OutBaseTypes(typ);
- Files.Write(out, CHR(np)); m := 0;
- WHILE m < np DO Files.WriteInt(out, SHORT(PtrTab[m])); INC(m) END
- END ;
- (*ref block*)
- refpos := Files.Pos(out);
- OutRefBlk(OBT.topScope.next, pc, "$$");
- Files.Set(out, ObjFile, 2); Files.WriteLInt(out, refpos);
- IF ~OBS.scanerr THEN Files.Register(ObjFile) END
- ELSE OBS.Mark(153)
- END
- END OutCode;
- BEGIN NEW(wasderef)
- END OBC.
-