| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511 |
- IMPLEMENTATION MODULE M3GL; (*NW 19.5.83 / 25.6.85*)
- FROM FileSystem IMPORT
- File, Response, Lookup, WriteChar, WriteWord, SetOpen, Close, Delete;
- FROM M3DL IMPORT WordSize,
- ObjPtr, StrPtr, ParPtr, PDPtr, ObjClass, StrForm, ConstValue, KeyPtr,
- cardtyp, inttyp, booltyp, chartyp, realtyp, dbltyp, bitstyp, notyp,
- stringtyp, addrtyp, wordtyp, undftyp;
- FROM M2S IMPORT IdBuf, Mark, id, CloseScanner;
- CONST MaxCard = 177777B; MaxInt = 32767; MinInt = -32767;
- StrTabLength = 2000; StackDepth = 16;
- CodeLength = 12000; RelTabLength = 1000; ProcTabLength = 128;
- VAR sp: INTEGER; (*expression stack pointer*)
- relx: CARDINAL; (*relocation table index*)
- datasize: INTEGER; (*of global data*)
- exp: CARDINAL; (*side effect of clog*)
- strx: CARDINAL; (*string table index*)
- StrTab: ARRAY [0..StrTabLength-1] OF CHAR;
- code: ARRAY [0..CodeLength-1] OF CHAR;
- RelTab: ARRAY [0..RelTabLength-1] OF CARDINAL;
- ProcTab: ARRAY [0..ProcTabLength-1] OF CARDINAL;
- PROCEDURE ROR(s: BITSET; n: CARDINAL): BITSET;
- (*rotate s right by n*) CODE 275B
- END ROR;
-
- PROCEDURE COM(s: BITSET): BITSET;
- (* {0..15} - s *) CODE 323B
- END COM;
- PROCEDURE MSK(n: CARDINAL): BITSET;
- (* {0 .. n-1} *) CODE 326B
- END MSK;
- PROCEDURE err(n: CARDINAL);
- BEGIN Mark(n)
- END err;
- PROCEDURE PutWord(n: CARDINAL);
- BEGIN code[pc] := CHAR(n DIV 400B);
- code[pc+1] := CHAR(n MOD 400B); pc := pc+2
- END PutWord;
- PROCEDURE PutByte(n: CARDINAL);
- BEGIN code[pc] := CHAR(n); pc := pc+1
- END PutByte;
- PROCEDURE PutOp(n: CARDINAL; s: INTEGER);
- BEGIN code[pc] := CHAR(n); pc := pc+1; sp := sp + s;
- IF sp > StackDepth THEN err(215) END
- END PutOp;
- PROCEDURE PutOpZ(n: CARDINAL);
- BEGIN code[pc] := CHAR(n); pc := pc+1
- END PutOpZ;
- PROCEDURE PutOpU(n: CARDINAL);
- BEGIN code[pc] := CHAR(n); pc := pc+1; sp := sp + 1;
- IF sp > StackDepth THEN err(215) END
- END PutOpU;
- PROCEDURE PutOpD(n: CARDINAL);
- BEGIN code[pc] := CHAR(n); pc := pc+1; sp := sp - 1
- END PutOpD;
- PROCEDURE PutOpArg(m, n: CARDINAL; s: INTEGER); (*LGW, LLW, SGW, SLW, CLL*)
- BEGIN sp := sp + s;
- IF sp > StackDepth THEN err(215) END;
- IF n < 10H THEN code[pc] := CHAR(m+n); pc := pc+1
- ELSIF n < 100H THEN code[pc] := CHAR(m); code[pc+1] := CHAR(n); pc := pc+2
- ELSE err(211)
- END
- END PutOpArg;
- PROCEDURE PutOpArg1(m, n: CARDINAL; s: INTEGER); (*LSW, SSW*)
- BEGIN sp := sp + s;
- IF sp > StackDepth THEN err(215) END ;
- IF n < 10H THEN code[pc] := CHAR(m+n); pc := pc+1
- ELSIF n < 100H THEN code[pc] := CHAR(m+40B); code[pc+1] := CHAR(n); pc := pc+2
- ELSE err(211)
- END
- END PutOpArg1;
- PROCEDURE fixupByte(loc: CARDINAL);
- BEGIN code[loc] := CHAR(pc - loc)
- END fixupByte;
- PROCEDURE fixup(loc: CARDINAL);
- BEGIN
- code[loc] := CHAR((pc-loc) DIV 400B); code[loc+1] := CHAR((pc-loc) MOD 400B)
- END fixup;
- PROCEDURE fixupC(loc: CARDINAL);
- BEGIN
- IF loc+2 < pc THEN
- code[loc] := CHAR((pc-loc) DIV 400B); code[loc+1] := CHAR((pc-loc) MOD 400B)
- ELSE pc := pc-3
- END
- END fixupC;
- PROCEDURE reloc;
- BEGIN
- IF relx < RelTabLength THEN RelTab[relx] := pc; relx := relx + 1
- ELSE err(224)
- END
- END reloc;
- PROCEDURE PutLit(n: CARDINAL);
- BEGIN
- IF n < 10H THEN PutOpU(n) (*LIn*)
- ELSIF n < 100H THEN PutOpU(20B); PutByte(n) (*LIB*)
- ELSIF n = 177777B THEN PutOpU(325B) (*LIN*)
- ELSE PutOpU(22B); PutWord(n) (*LIW*)
- END
- END PutLit;
- PROCEDURE PutLd(obj: ObjPtr; size: INTEGER);
- VAR m, L: CARDINAL; a: INTEGER;
- BEGIN (*obj^.class = Var*)
- m := obj^.vmod; L := obj^.vlev; a := obj^.vadr;
- IF m = 0 THEN
- IF L = 0 THEN
- IF size # 2 THEN PutOpArg(100B,a,1) (*LGW*)
- ELSE PutOp(101B, 2); PutByte(a) (*LGD*)
- END
- ELSIF L = curLev THEN
- IF size # 2 THEN PutOpArg(40B,a,1) (*LLW*)
- ELSE PutOp(41B, 2); PutByte(a) (*LLD*)
- END
- ELSE
- IF L+1 = curLev THEN PutOpU(351B) (*GB1*)
- ELSE PutOpU(350B); PutByte(curLev-L)
- END ;
- IF size # 2 THEN PutOpArg1(140B,a,0) (*LSW*)
- ELSE PutOpU(201B); PutByte(a) (*LSD*)
- END
- END
- ELSE
- IF size # 2 THEN PutOpU(42B) (*LEW*) ELSE PutOp(43B,2) (*LED*) END ;
- reloc; PutByte(m); PutByte(a)
- END
- END PutLd;
- PROCEDURE PutSto(obj: ObjPtr; size: INTEGER);
- VAR m, L: CARDINAL; a: INTEGER;
- BEGIN (*obj^.class = Var*)
- IF size <= 2 THEN
- m := obj^.vmod; L := obj^.vlev; a := obj^.vadr;
- IF m = 0 THEN
- IF L = 0 THEN
- IF size = 1 THEN PutOpArg(120B,a,-1) (*SGW*)
- ELSE PutOp(121B,-2); PutByte(a) (*SGD*)
- END
- ELSIF L = curLev THEN
- IF size = 1 THEN PutOpArg(60B,a,-1) (*SLW*)
- ELSE PutOp(61B,-2); PutByte(a) (*SLD*)
- END
- ELSE err(213)
- END
- ELSE
- IF size = 1 THEN PutOpD(62B) (*SEW*) ELSE PutOp(63B,-2) (*SED*) END ;
- reloc; PutByte(m); PutByte(a)
- END
- ELSE PutLit(size); PutOp(340B,-3) (*MOV*)
- END
- END PutSto;
- PROCEDURE AllocString(s: CARDINAL; VAR adr, length: CARDINAL);
- VAR L: CARDINAL;
- BEGIN L := ORD(IdBuf[s]); length := L - 1;
- IF strx + L >= StrTabLength THEN err(225); strx := 0 END ;
- adr := strx DIV 2; (*word address*)
- WHILE L > 1 DO
- s := s+1; StrTab[strx] := IdBuf[s]; strx := strx + 1; L := L-1
- END ;
- StrTab[strx] := 0C; strx := strx + 1;
- IF ODD(strx) THEN strx := strx + 1 END
- END AllocString;
- PROCEDURE loadStrAdr(adr: CARDINAL);
- BEGIN
- IF adr <= 377B THEN
- PutOpU(204B); PutByte(adr) (*LSTA adr*)
- ELSE PutOpU(102B); PutLit(adr); PutOpD(270B) (*LGW2 LIW adr UADD*)
- END
- END loadStrAdr;
- PROCEDURE load(VAR x: Item);
- VAR s: INTEGER;
- BEGIN s := x.typ^.size;
- CASE x.mode OF
- conMd: CASE x.typ^.form OF
- Undef, Range, Array, Record, ProcTyp: |
- Bool, Char, Card, Int, Enum, Set, Pointer, Opaque:
- PutLit(x.val.C); x.mode := cldMd |
- Double, Real: PutOp(23B,2); PutWord(x.val.D0); PutWord(x.val.D1) |
- String: loadStrAdr(x.val.D0)
- END |
- typMd: err(101) |
- varMd: IF x.var^.param = {1} THEN (*var par*)
- PutLd(x.var, 1);
- IF s = 1 THEN PutOpZ(140B) (*LSW0*)
- ELSIF s = 2 THEN PutOpU(202B) (*LSD0*)
- END
- ELSE PutLd(x.var, s)
- END |
- fldMd: IF x.off <= 255 THEN
- IF s = 1 THEN PutOpArg1(140B, x.off,0) (*LSW0*)
- ELSIF s = 2 THEN PutOpU(201B); PutByte(x.off)
- ELSE PutOpZ(26B); PutByte(x.off) (*LSA*)
- END
- ELSE PutOpU(22B); PutWord(x.off); PutOpD(270B); (*LIW UADD*)
- IF s = 1 THEN PutOpZ(140B) (*LSW0*)
- ELSIF s = 2 THEN PutOpU(202B) (*LSD0*)
- END
- END |
- procMd, codMd: err(102) |
- expMd, cldMd: |
- adrMd: IF s = 1 THEN PutOpZ(140B) (*LSW0*)
- ELSIF s = 2 THEN PutOpU(202B) (*LSD0*)
- END |
- inxMd: IF s = 1 THEN
- IF x.typ = chartyp THEN PutOpD(205B) (*LXB*)
- ELSE PutOpD(206B) (*LXW*)
- END
- ELSIF s = 2 THEN PutOpZ(207B) (*LXD*)
- ELSE PutOpD(270B) (*UADD*)
- END
- END ;
- IF x.mode # cldMd THEN x.mode := expMd END
- END load;
- PROCEDURE loadAdr(VAR x: Item);
- BEGIN
- CASE x.mode OF
- conMd: err(103) |
- typMd: err(104) |
- varMd: IF (x.typ^.size > 2) OR (x.var^.param = {1}) OR
- (x.typ^.form = Array) & x.typ^.dyn THEN PutLd(x.var, 1)
- ELSE
- IF x.var^.vmod = 0 THEN
- IF x.var^.vlev = 0 THEN PutOpU(25B) (*LGA*)
- ELSIF x.var^.vlev = curLev THEN PutOpU(24B) (*LLA*)
- ELSE
- IF x.var^.vlev + 1 = curLev THEN PutOpU(351B) (*GB1*)
- ELSE PutOpU(350B); PutByte(curLev - x.var^.vlev)
- END ;
- PutOpZ(26B) (*LSA*)
- END
- ELSE PutOpU(27B); reloc; PutByte(x.var^.vmod) (*LEA*)
- END ;
- PutByte(x.var^.vadr)
- END |
- fldMd: IF x.off <= 255 THEN
- PutOpZ(26B); PutByte(x.off) (*LSA*)
- ELSE PutOpU(22B); PutWord(x.off); PutOpD(270B) (*LIW UADD*)
- END |
- procMd, codMd: err(105) |
- expMd, cldMd: err(106) |
- adrMd: |
- inxMd: IF x.typ^.size = 2 THEN
- PutLit(1); PutOpD(276B) (*SHL*)
- END ;
- PutOpD(270B); (*UADD*)
- IF x.typ = chartyp THEN err(212) END
- END ;
- x.mode := adrMd
- END loadAdr;
- PROCEDURE load2(VAR x, y: Item);
- BEGIN
- IF x.mode = conMd THEN load(y); load(x) ELSE load(x); load(y) END
- END load2;
- PROCEDURE loadLim(v: ObjPtr); (*index limit for dynamic arrays*)
- VAR L: CARDINAL; a: INTEGER;
- BEGIN a := v^.vadr + 1; L := v^.vlev;
- IF L = curLev THEN PutOpArg(40B,a,1) (*LLW*)
- ELSE
- IF L+1 = curLev THEN PutOpU(351B) (*GB1*)
- ELSE PutOpU(350B); PutByte(curLev-L)
- END ;
- PutOpArg1(140B,a,0) (*LSW*)
- END
- END loadLim;
- PROCEDURE SRTest(VAR x: Item);
- BEGIN
- IF (x.typ # NIL) & (x.typ^.form = Range) THEN x.typ := x.typ^.RBaseTyp END
- END SRTest;
- PROCEDURE GenItem(VAR x: Item; y, scope: ObjPtr);
- BEGIN
- IF y # NIL THEN
- x.typ := y^.typ;
- CASE y^.class OF
- Const: x.mode := conMd; x.val := y^.conval;
- IF (x.typ = stringtyp) & (x.val.D0 = 177777B) THEN
- AllocString(x.val.D2, x.val.D0, x.val.D1);
- (*imported string*) y^.conval.D0 := x.val.D0
- END |
- Typ: x.mode := typMd |
- Var: x.mode := varMd; x.var := y |
- Field: IF curLev = 0 THEN PutOpArg(100B, scope^.withadr, 1) (*LGW*)
- ELSE PutOpArg(40B, scope^.withadr, 1) (*LLW*)
- END ;
- x.mode := fldMd; x.off := y^.offset |
- Proc: x.mode := procMd; x.proc := y; x.typ := undftyp |
- Code: x.mode := codMd; x.cod := y; x.typ := undftyp |
- Module: x.mode := varMd; err(107) |
- Temp:
- END
- ELSE err(50); x.typ := undftyp; x.mode := expMd
- END
- END GenItem;
- PROCEDURE clog(x: CARDINAL): CARDINAL;
- BEGIN exp := 0;
- IF x > 0 THEN
- WHILE NOT ODD(x) DO
- x := x DIV 2; exp := exp + 1
- END
- END ;
- RETURN x
- END clog;
- PROCEDURE GenIndex(VAR x, y: Item);
- VAR i,m,n,sz: INTEGER; inxtyp, eltyp: StrPtr;
- BEGIN SRTest(y); (*x.mode = adrMd*)
- IF x.typ^.form = Array THEN
- eltyp := x.typ^.ElemTyp;
- IF x.typ^.dyn THEN load(y);
- IF y.typ = inttyp THEN PutOpZ(307B) (*CHKS*)
- ELSIF y.typ # cardtyp THEN err(109)
- END ;
- IF rngchk THEN loadLim(x.var); PutOpD(306B) END ; (*CHKZ*)
- IF eltyp^.size > 2 THEN
- IF clog(eltyp^.size) = 1 THEN
- PutLit(exp); PutOpD(276B) (*SHL*)
- ELSE PutLit(eltyp^.size); PutOpD(272B) (*UMUL*)
- END
- END ;
- x.mode := inxMd
- ELSE
- WITH x.typ^.IndexTyp^ DO
- inxtyp := RBaseTyp; m := min; n := max
- END ;
- IF y.mode = conMd THEN
- i := y.val.I;
- IF inxtyp # y.typ THEN
- IF (i < 0) OR (inxtyp = cardtyp) & (y.typ # inttyp) OR
- (inxtyp = inttyp) & (y.typ # cardtyp) THEN err(109)
- END
- END ;
- IF (m <= i) & (i <= n) THEN i := i - m
- ELSE err(108); i := m
- END ;
- sz := eltyp^.size * i;
- IF (sz < 400B) & (eltyp^.form # Char) THEN
- x.mode := fldMd; x.off := sz
- ELSE PutLit(sz); x.mode := inxMd
- END
- ELSE load(y);
- IF inxtyp # y.typ THEN
- IF (inxtyp = cardtyp) & (y.typ = inttyp) OR
- (inxtyp = inttyp) & (y.typ = cardtyp) THEN PutOpZ(307B)
- ELSE err(109)
- END
- END ;
- IF m # 0 THEN
- PutLit(CARDINAL(m)); PutOpD(331B) (*ISUB*)
- END ;
- IF rngchk THEN PutLit(n-m); PutOpD(306B) END ; (*CHKZ*)
- IF eltyp^.size > 2 THEN
- IF clog(eltyp^.size) = 1 THEN
- PutLit(exp); PutOpD(276B) (*SHL*)
- ELSE PutLit(eltyp^.size); PutOpD(272B) (*UMUL*)
- END
- END ;
- x.mode := inxMd
- END
- END ;
- x.typ := eltyp
- ELSE err(109)
- END
- END GenIndex;
- PROCEDURE GenField(VAR x: Item; f: ObjPtr);
- BEGIN (*x.typ^.form = Record*)
- IF (f # NIL) & (f^.class = Field) THEN
- IF x.mode = fldMd THEN x.off := x.off + f^.offset
- ELSE loadAdr(x); x.off := f^.offset
- END ;
- x.typ := f^.typ
- ELSIF (f # NIL) & (f^.class = Const) THEN
- x.mode := conMd; x.typ := f^.typ; x.val := f^.conval
- ELSE err(110); x.typ := undftyp; x.mode := fldMd; x.off := 0
- END ;
- x.mode := fldMd
- END GenField;
- PROCEDURE GenWith(VAR x: Item; adr: INTEGER);
- BEGIN (* WITH clause *) loadAdr(x);
- IF curLev = 0 THEN PutOpArg(120B, adr, -1) (*SGW*)
- ELSE PutOpArg(60B, adr, -1) (*SLW*)
- END
- END GenWith;
- PROCEDURE GenDeRef(VAR x: Item);
- BEGIN
- IF x.typ^.form = Pointer THEN
- load(x); x.typ := x.typ^.PBaseTyp
- ELSIF x.typ = addrtyp THEN load(x); x.typ := wordtyp
- ELSE err(111)
- END ;
- x.mode := adrMd
- END GenDeRef;
- PROCEDURE GenNeg(VAR x: Item);
- VAR f: StrForm;
- BEGIN SRTest(x); f := x.typ^.form;
- IF x.mode = conMd THEN
- IF (f = Int) OR (f = Card) & (x.val.C <= MaxInt) THEN
- IF x.val.I >= MinInt THEN
- x.val.I := -(INTEGER(x.val.C)); x.typ := inttyp
- ELSE err(201)
- END
- ELSIF f = Real THEN x.val.R := - x.val.R
- ELSE err(112)
- END
- ELSE load(x);
- IF f = Int THEN PutOpZ(317B) (*NEG*)
- ELSIF f = Card THEN PutOpZ(307B); PutOpZ(317B)
- ELSIF f = Real THEN PutOpZ(236B) (*FNEG*)
- ELSE err(112)
- END
- END
- END GenNeg;
- PROCEDURE GenNot(VAR x: Item);
- BEGIN
- IF x.typ^.form = Bool THEN
- IF x.mode = conMd THEN x.val.B := NOT x.val.B
- ELSE load(x); PutOpZ(327B) (*NOT*)
- END
- ELSE err(113)
- END
- END GenNot;
- PROCEDURE GenAnd(VAR x: Item);
- BEGIN
- IF x.typ^.form = Bool THEN
- load(x); PutOpD(37B); x.val.C := pc; PutByte(0) (*ANDJP*)
- ELSE err(122)
- END ;
- x.mode := expMd
- END GenAnd;
- PROCEDURE GenOr(VAR x: Item);
- BEGIN
- IF x.typ^.form = Bool THEN
- load(x); PutOpD(36B); x.val.C := pc; PutByte(0) (*ORJP*)
- ELSE err(125)
- END ;
- x.mode := expMd
- END GenOr;
- PROCEDURE GenIn(VAR x, y: Item);
- VAR f: StrForm;
- BEGIN SRTest(x); f := x.typ^.form;
- IF ((Bool <= f) & (f <= Int) OR (f = Enum)) & (y.typ^.form = Set) THEN
- y.typ := y.typ^.SBaseTyp;
- IF y.typ^.form = Range THEN y.typ := y.typ^.RBaseTyp END ;
- IF (x.typ = y.typ) OR (x.typ = inttyp) & (y.typ = cardtyp) THEN
- IF (x.mode = conMd) & (y.mode = conMd) THEN
- IF x.val.C < WordSize THEN x.val.B := x.val.C IN y.val.S
- ELSE x.val.B := FALSE; err(202)
- END
- ELSE load2(x, y); PutOpD(324B) (*IN*)
- END
- ELSE err(114); x.mode := expMd
- END
- ELSE err(115); x.mode := expMd
- END ;
- x.typ := booltyp
- END GenIn;
- PROCEDURE GenSet(VAR x, e1, e2: Item);
- VAR s: StrPtr; n: CARDINAL;
- BEGIN x.mode := expMd; SRTest(e1); SRTest(e2);
- (*x.typ^.form = Set*) s := x.typ^.SBaseTyp;
- IF s^.form = Range THEN s := s^.RBaseTyp END ;
- IF (e1.typ = s) & (e2.typ = s) THEN
- IF (e1.mode = conMd) & (e2.mode = conMd) THEN
- x.mode := conMd;
- IF (e2.val.C < WordSize) & (e1.val.C <= e2.val.C + 1) THEN
- n := e2.val.C + 1 - e1.val.C;
- IF n < 16 THEN x.val.S := ROR(MSK(n), e1.val.C)
- ELSE x.val.S := {0..15}
- END
- ELSE err(202)
- END
- ELSE err(214)
- END ;
- ELSE err(116)
- END
- END GenSet;
- PROCEDURE GenSingSet(VAR x, e: Item);
- VAR s: StrPtr;
- BEGIN x.mode := expMd; SRTest(e);
- (*x.typ^.form = Set*) s := x.typ^.SBaseTyp;
- IF s^.form = Range THEN s := s^.RBaseTyp END ;
- IF e.typ = s THEN
- IF e.mode = conMd THEN x.mode := conMd;
- IF e.val.C < WordSize THEN x.val.S := ROR({0}, e.val.C)
- ELSE err(202)
- END
- ELSE load(e); PutOpZ(335B) (*BIT*)
- END
- ELSE err(116)
- END
- END GenSingSet;
- PROCEDURE GenOp(op: CARDINAL; VAR x, y: Item);
- VAR f,g: StrForm;
- BEGIN SRTest(x); SRTest(y); f := x.typ^.form;
- IF x.typ # y.typ THEN g := y.typ^.form;
- IF (f = Int) & (g = Card) & (y.mode = conMd)
- & (y.val.C <= MaxInt) THEN y.typ := x.typ
- ELSIF (f = Card) & (g = Int) & ((x.mode = conMd) OR (x.mode = cldMd))
- & (x.val.C <= MaxInt) THEN x.typ := y.typ; f := Int
- ELSIF (x.typ = addrtyp) & (g = Pointer) THEN f := Pointer
- ELSIF ((f # Pointer) OR (y.typ # addrtyp)) &
- ((f # Card) OR (g # Card)) THEN err(117)
- END
- END ;
- IF (x.mode = conMd) & (y.mode = conMd) THEN
- CASE op OF
- 1: IF f = Card THEN
- IF (x.val.C = 0) OR (y.val.C <= MaxCard DIV x.val.C) THEN
- x.val.C := x.val.C * y.val.C
- ELSE err(203)
- END
- ELSIF f = Int THEN
- IF (x.val.I = 0) OR (ABS(y.val.I) <= MaxInt DIV ABS(x.val.I)) THEN
- x.val.I := x.val.I * y.val.I
- ELSE err(203)
- END
- ELSIF f = Real THEN
- IF (ABS(x.val.R) <= 1.0) OR
- (ABS(y.val.R) <= MAX(REAL)/ABS(x.val.R)) THEN
- x.val.R := x.val.R * y.val.R
- ELSE err(203)
- END
- ELSIF f = Set THEN x.val.S := x.val.S * y.val.S
- ELSE err(118)
- END |
- 2,3: IF f = Card THEN
- IF y.val.C > 0 THEN x.val.C := x.val.C DIV y.val.C
- ELSE err(205)
- END
- ELSIF f = Int THEN
- IF y.val.I # 0 THEN x.val.I := x.val.I DIV y.val.I
- ELSE err(205)
- END
- ELSIF (f = Real) & (op = 2) THEN
- IF (y.val.R >= 1.0) OR
- (ABS(x.val.R) <= ABS(y.val.R) * MAX(REAL)) THEN
- x.val.R := x.val.R / y.val.R
- ELSE err(204)
- END
- ELSIF (f = Set) & (op = 2) THEN x.val.S := x.val.S / y.val.S
- ELSE err(120)
- END |
- 4: IF f = Card THEN
- IF y.val.C > 0 THEN x.val.C := x.val.C MOD y.val.C
- ELSE err(205)
- END
- ELSIF f = Int THEN
- IF (x.val.I >= 0) & (y.val.I > 0) THEN
- x.val.I := x.val.I MOD y.val.I
- ELSE err(205)
- END
- ELSE err(121)
- END |
- 5: IF f = Bool THEN x.val.B := x.val.B & y.val.B
- ELSE err(122)
- END |
- 6: IF f = Card THEN
- IF y.val.C <= MaxCard - x.val.C THEN
- x.val.C := x.val.C + y.val.C
- ELSE err(206)
- END
- ELSIF f = Int THEN
- IF (x.val.I >= 0) & (y.val.I <= MaxInt - x.val.I) OR
- (x.val.I < 0) & (y.val.I >= MinInt - x.val.I) THEN
- x.val.I := x.val.I + y.val.I
- ELSE err(206)
- END
- ELSIF f = Real THEN
- IF (x.val.R >= 0.0) & (y.val.R <= MAX(REAL) - x.val.R) OR
- (x.val.R < 0.0) & (y.val.R >= MIN(REAL) - x.val.R) THEN
- x.val.R := x.val.R + y.val.R
- ELSE err(206)
- END
- ELSIF f = Set THEN x.val.S := x.val.S + y.val.S
- ELSE err(123)
- END |
- 7: IF f = Card THEN
- IF y.val.C <= x.val.C THEN x.val.C := x.val.C - y.val.C
- ELSIF y.val.C - x.val.C <= MaxInt THEN
- x.val.I := -INTEGER(y.val.C - x.val.C); x.typ := inttyp
- ELSE err(207)
- END
- ELSIF f = Int THEN
- IF (x.val.I >= 0) &
- ((y.val.I >= 0) OR (x.val.I <= MaxInt + y.val.I)) OR
- (x.val.I < 0) &
- ((y.val.I < 0) OR (x.val.I >= MinInt + y.val.I)) THEN
- x.val.I := x.val.I - y.val.I
- ELSE err(207)
- END
- ELSIF f = Real THEN
- IF (x.val.R >= 0.0) &
- ((y.val.R >= 0.0) OR (x.val.R <= MAX(REAL) + y.val.R)) THEN
- x.val.R := x.val.R - y.val.R
- ELSIF (x.val.R < 0.0) &
- ((y.val.R < 0.0) OR (x.val.R >= MIN(REAL) + y.val.R)) THEN
- x.val.R := x.val.R - y.val.R
- ELSE err(207)
- END
- ELSIF f = Set THEN x.val.S := x.val.S - y.val.S
- ELSE err(124)
- END |
- 8: IF f = Bool THEN x.val.B := x.val.B OR y.val.B
- ELSE err(125)
- END |
- 9: IF f = Card THEN x.val.B := x.val.C = y.val.C
- ELSIF f = Int THEN x.val.B := x.val.I = y.val.I
- ELSIF f = Real THEN x.val.B := x.val.R = y.val.R
- ELSIF f = Bool THEN x.val.B := x.val.B = y.val.B
- ELSIF f = Set THEN x.val.B := x.val.S = y.val.S
- ELSIF f = Char THEN x.val.B := x.val.Ch = y.val.Ch
- ELSE err(126)
- END ;
- x.typ := booltyp |
- 10: IF f = Card THEN x.val.B := x.val.C # y.val.C
- ELSIF f = Int THEN x.val.B := x.val.I # y.val.I
- ELSIF f = Real THEN x.val.B := x.val.R # y.val.R
- ELSIF f = Bool THEN x.val.B := x.val.B # y.val.B
- ELSIF f = Set THEN x.val.B := x.val.S # y.val.S
- ELSIF f = Char THEN x.val.B := x.val.Ch # y.val.Ch
- ELSE err(126)
- END ;
- x.typ := booltyp |
- 11: IF f = Card THEN x.val.B := x.val.C < y.val.C
- ELSIF f = Int THEN x.val.B := x.val.I < y.val.I
- ELSIF f = Real THEN x.val.B := x.val.R < y.val.R
- ELSIF f = Bool THEN x.val.B := x.val.B < y.val.B
- ELSIF f = Char THEN x.val.B := x.val.Ch < y.val.Ch
- ELSE err(126)
- END ;
- x.typ := booltyp |
- 12: IF f = Card THEN x.val.B := x.val.C <= y.val.C
- ELSIF f = Int THEN x.val.B := x.val.I <= y.val.I
- ELSIF f = Real THEN x.val.B := x.val.R <= y.val.R
- ELSIF f = Bool THEN x.val.B := x.val.B <= y.val.B
- ELSIF f = Set THEN x.val.B := x.val.S <= y.val.S
- ELSIF f = Char THEN x.val.B := x.val.Ch <= y.val.Ch
- ELSE err(126)
- END ;
- x.typ := booltyp |
- 13: IF f = Card THEN x.val.B := x.val.C > y.val.C
- ELSIF f = Int THEN x.val.B := x.val.I > y.val.I
- ELSIF f = Real THEN x.val.B := x.val.R > y.val.R
- ELSIF f = Bool THEN x.val.B := x.val.B > y.val.B
- ELSIF f = Char THEN x.val.B := x.val.Ch > y.val.Ch
- ELSE err(126)
- END ;
- x.typ := booltyp |
- 14: IF f = Card THEN x.val.B := x.val.C >= y.val.C
- ELSIF f = Int THEN x.val.B := x.val.I >= y.val.I
- ELSIF f = Real THEN x.val.B := x.val.R >= y.val.R
- ELSIF f = Bool THEN x.val.B := x.val.B >= y.val.B
- ELSIF f = Set THEN x.val.B := y.val.S >= x.val.S
- ELSIF f = Char THEN x.val.B := x.val.Ch >= y.val.Ch
- ELSE err(126)
- END ;
- x.typ := booltyp
- END
- ELSE
- CASE op OF
- 1: IF f = Card THEN
- IF (x.mode = conMd) & (clog(x.val.C) = 1) THEN
- load(y); PutLit(exp); PutOpD(276B); x.mode := expMd
- ELSIF (y.mode = conMd) & (clog(y.val.C) = 1) THEN
- load(x); PutLit(exp); PutOpD(276B) (*SHL*)
- ELSE load2(x, y); PutOpD(272B) (*UMUL*)
- END
- ELSIF f = Int THEN
- IF (x.mode = conMd) & (clog(x.val.C) = 1) THEN
- load(y); PutLit(exp); PutOpD(276B); x.mode := expMd
- ELSIF (y.mode = conMd) & (clog(y.val.C) = 1) THEN
- load(x); PutLit(exp); PutOpD(276B) (*SHL*)
- ELSE load2(x, y); PutOpD(332B) (*IMUL*)
- END
- ELSE load2(x, y);
- IF f = Double THEN err(216)
- ELSIF f = Real THEN PutOp(232B,-2) (*FMUL*)
- ELSIF f = Set THEN PutOpD(322B) (*AND*)
- ELSIF f # Undef THEN err(118)
- END
- END |
- 2: load(y);
- IF f = Card THEN PutOpD(273B) (*UDIV*)
- ELSIF f = Int THEN PutOpD(333B) (*IDIV*)
- ELSIF f = Real THEN PutOp(233B,-2) (*FDIV*)
- ELSIF f = Set THEN PutOpD(321B) (*XOR*)
- ELSIF f # Undef THEN err(119)
- END |
- 3: IF f = Card THEN (*DIV*)
- IF (y.mode = conMd) & (clog(y.val.C) = 1) THEN
- PutLit(exp); PutOpD(277B) (*SHR*)
- ELSE load(y); PutOpD(273B) (*UDIV*)
- END
- ELSE load(y);
- IF f = Int THEN PutOpD(333B) (*IDIV*)
- ELSIF f = Double THEN err(216)
- ELSIF f # Undef THEN err(120)
- END
- END |
- 4: IF f = Card THEN
- IF (y.mode = conMd) & (clog(y.val.C) = 1) THEN
- PutLit(CARDINAL(COM(MSK(WordSize-exp))));
- PutOpD(322B) (*AND*)
- ELSE load(y); PutOpD(274B) (*UMOD*)
- END
- ELSE load(y);
- IF f = Int THEN PutOpZ(307B); PutOpD(274B)
- ELSIF f # Undef THEN err(121)
- END
- END |
- 5: load(y);
- IF f = Bool THEN fixupByte(x.val.C)
- ELSIF f # Undef THEN err(122)
- END |
- 6: load2(x, y);
- IF f = Card THEN PutOpD(270B) (*UADD*)
- ELSIF f = Int THEN PutOpD(330B) (*IADD*)
- ELSIF f = Real THEN PutOp(230B,-2) (*FADD*)
- ELSIF f = Set THEN PutOpD(320B) (*OR*)
- ELSIF f = Double THEN PutOp(210B,-2) (*DADD*)
- ELSIF f # Undef THEN err(123)
- END |
- 7: load(y);
- IF f = Card THEN PutOpD(271B) (*USUB*)
- ELSIF f = Int THEN PutOpD(331B) (*ISUB*)
- ELSIF f = Real THEN PutOp(231B,-2) (*FSUB*)
- ELSIF f = Set THEN PutOpZ(323B); PutOpD(322B) (*COM AND*)
- ELSIF f = Double THEN PutOp(211B,-2) (*DSUB*)
- ELSIF f # Undef THEN err(124)
- END |
- 8: load(y);
- IF f = Bool THEN fixupByte(x.val.C)
- ELSIF f # Undef THEN err(125)
- END |
- 9: load(y); x.typ := booltyp;
- IF (f <= Int) OR (f = Enum) OR (f = Pointer) OR
- (f = Set) OR (f = Opaque) THEN PutOpD(310B) (*EQL*)
- ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(310B)
- ELSE err(126)
- END |
- 10: load(y); x.typ := booltyp;
- IF (f <= Int) OR (f = Enum) OR (f = Pointer) OR
- (f = Set) OR (f = Opaque) THEN PutOpD(311B) (*NEQ*)
- ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(311B)
- ELSE err(126)
- END |
- 11: load(y); x.typ := booltyp;
- IF (f <= Card) OR (f = Enum) THEN PutOpD(252B) (*ULSS*)
- ELSIF f = Int THEN PutOpD(312B) (*ILSS*)
- ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(312B)
- ELSE err(126)
- END |
- 12: load(y); x.typ := booltyp;
- IF (f <= Card) OR (f = Enum) THEN PutOpD(253B) (*ULEQ*)
- ELSIF f = Int THEN PutOpD(313B) (*ILEQ*)
- ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(313B)
- ELSIF f = Set THEN (*COM AND LI0 EQL*)
- PutOpZ(323B); PutOpZ(322B); PutOpZ(0); PutOpD(310B)
- ELSE err(126)
- END |
- 13: load(y); x.typ := booltyp;
- IF (f <= Card) OR (f = Enum) THEN PutOpD(254B) (*UGTR*)
- ELSIF f = Int THEN PutOpD(314B) (*IGTR*)
- ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(314B)
- ELSE err(126)
- END |
- 14: load(y); x.typ := booltyp;
- IF (f <= Card) OR (f = Enum) THEN PutOpD(255B) (*UGEQ*)
- ELSIF f = Int THEN PutOpD(315B) (*IGEQ*)
- ELSIF (f = Real) OR (f = Double) THEN PutOp(234B,-3); PutOpZ(315B)
- ELSIF f = Set THEN (*COM OR LIN EQL*)
- PutOpZ(323B); PutOpZ(320B); PutOpZ(325B); PutOpD(310B)
- ELSE err(126)
- END
- END
- END
- END GenOp;
- PROCEDURE CheckAssComp(xt: StrPtr; VAR y: Item;
- param: BOOLEAN; VAR sz: INTEGER);
- VAR f,g: StrForm; xp, yp: ParPtr; vsz: INTEGER;
- BEGIN sz := xt^.size;
- IF (y.mode = procMd) & (xt^.form = ProcTyp) THEN
- (*procedure to proc. variable; check compatibility*)
- IF y.proc^.pd^.lev > 0 THEN err(127)
- ELSIF xt^.resTyp # y.proc^.typ THEN err(128)
- ELSE xp := xt^.firstPar; yp := y.proc^.firstParam;
- WHILE xp # NIL DO
- IF yp # NIL THEN
- IF (xp^.varpar # yp^.varpar) OR ((xp^.typ # yp^.typ) &
- ((xp^.typ^.form # Array) OR NOT xp^.typ^.dyn OR
- (yp^.typ^.form # Array) OR NOT yp^.typ^.dyn OR
- (xp^.typ^.ElemTyp # yp^.typ^.ElemTyp))) THEN err(129)
- END ;
- yp := yp^.next
- ELSE err(130)
- END ;
- xp := xp^.next
- END ;
- IF yp # NIL THEN err(131) END ;
- (*generate procedure descriptor*)
- PutOpU(22B) (*LIW*); reloc; PutByte(y.proc^.pmod); PutByte(y.proc^.pd^.num)
- END
- ELSE SRTest(y);
- IF xt^.form = Range THEN xt := xt^.RBaseTyp END ;
- IF y.typ = NIL THEN err(117)
- ELSIF (xt = y.typ) & ~((xt^.form = Array) & xt^.dyn) THEN load(y)
- ELSE
- f := xt^.form; g := y.typ^.form;
- IF (f = Card) & (g = Int) THEN
- IF y.mode = conMd THEN load(y);
- IF y.val.I < 0 THEN err(132) END
- ELSE load(y);
- IF rngchk THEN PutOpZ(307B) END (*CHKS*)
- END
- ELSIF (f = Int) & (g = Card) THEN
- IF y.mode = conMd THEN load(y);
- IF y.val.C > MaxInt THEN err(208) END
- ELSE load(y);
- IF rngchk THEN PutOpZ(307B) END (*CHKS*)
- END
- ELSIF (f = Pointer) & (y.typ = addrtyp)
- OR (g = Pointer) & (xt = addrtyp) THEN load(y)
- ELSIF f = Array THEN
- IF xt^.dyn THEN (*dynamic array parameter*)
- IF ~param THEN err(143)
- ELSIF (g = Array) & (xt^.ElemTyp = y.typ^.ElemTyp) THEN
- IF y.typ^.dyn THEN PutLd(y.var, 2)
- ELSE loadAdr(y); PutLit(y.typ^.IndexTyp^.max - y.typ^.IndexTyp^.min)
- END
- ELSIF xt^.ElemTyp = chartyp THEN
- IF g = String THEN
- load(y); PutLit(y.val.D1 - 1)
- ELSIF (g = Char) & (y.mode = conMd) THEN
- loadStrAdr(strx DIV 2); StrTab[strx] := y.val.Ch;
- StrTab[strx+1] := 0C; strx := strx+2; PutLit(0)
- ELSE err(133)
- END
- ELSIF xt^.ElemTyp = wordtyp THEN
- loadAdr(y); PutLit(y.typ^.size-1)
- ELSE err(133)
- END
- ELSIF xt^.ElemTyp = chartyp THEN
- IF g = String THEN (*string to array variable*)
- load(y); sz := y.val.D1; (*check length of string*)
- vsz := xt^.IndexTyp^.max - xt^.IndexTyp^.min + 1;
- IF sz < vsz THEN sz := sz+1 (*include 0C terminator*)
- ELSIF sz > vsz THEN err(146)
- END ;
- sz := (sz+1) DIV 2;
- IF param THEN
- IF vsz <= 2 THEN PutOpZ(140B) (*LSW0*)
- ELSIF vsz <= 4 THEN PutOpU(202B) (*LSD0*)
- END
- ELSIF sz = 1 THEN PutOpZ(140B) (*LSW0*)
- ELSIF sz = 2 THEN PutOpU(202B) (*LSD0*)
- END
- ELSIF g = Char THEN err(200)
- ELSE err(133)
- END
- ELSE err(133)
- END
- ELSIF param & (xt = wordtyp) & (y.typ^.size = 1) THEN load(y)
- ELSIF (f # Card) OR (g # Card) THEN err(133)
- ELSE load(y)
- END
- END
- END ;
- END CheckAssComp;
- PROCEDURE PrepAss(VAR x: Item);
- VAR L: CARDINAL;
- BEGIN
- IF (x.mode = conMd) OR (x.mode = procMd) THEN err(134) END ;
- IF x.typ^.size <= 2 THEN
- IF x.mode = varMd THEN
- IF x.var^.param = {1} THEN (*var par*)
- loadAdr(x); x.mode := adrMd
- ELSE L := x.var^.vlev;
- IF (L > 0) & (L < curLev) THEN
- IF L+1 = curLev THEN PutOpU(351B) (*GB1*)
- ELSE PutOpU(350B); PutByte(curLev-L) (*GB *)
- END ;
- x.mode := fldMd; x.off := x.var^.vadr
- END
- END
- END
- ELSE
- IF x.mode = varMd THEN
- IF x.var^.param = {1} THEN PutLd(x.var, 1) ELSE loadAdr(x) END
- ELSIF x.mode = inxMd THEN PutOpD(270B) (*UADD*)
- ELSIF x.mode = fldMd THEN PutOpZ(26B) (*LSA*); PutByte(x.off)
- END ;
- x.mode := adrMd
- END
- END PrepAss;
- PROCEDURE GenAssign(VAR x, y: Item);
- VAR s: INTEGER;
- BEGIN CheckAssComp(x.typ, y, FALSE, s);
- IF rngchk & (x.typ^.form = Range) THEN
- WITH x.typ^ DO
- IF min = 0 THEN PutLit(max); PutOpD(306B) (*CHKZ*)
- ELSE PutLit(CARDINAL(min)); PutLit(CARDINAL(max));
- IF min < 0 THEN PutOp(305B, -2) (*CHK*)
- ELSE PutOp(245B, -2) (*UCHK*)
- END
- END
- END
- END ;
- IF x.mode = varMd THEN
- PutSto(x.var, s)
- ELSIF x.mode = fldMd THEN
- IF s = 1 THEN PutOpArg1(160B, x.off, -2) (*SSW*)
- ELSIF s = 2 THEN PutOp(221B,-3); PutByte(x.off) (*SSD*)
- ELSE PutLit(s); PutOp(340B,-3) (*MOV*)
- END
- ELSIF x.mode = inxMd THEN
- IF s = 1 THEN (*SXB SXW*)
- IF x.typ = chartyp THEN PutOp(225B,-3) ELSE PutOp(226B,-3) END
- ELSIF s = 2 THEN PutOp(227B,-4) (*SXD*)
- ELSE PutLit(s); PutOp(340B,-3) (*MOV*)
- END
- ELSIF x.mode = adrMd THEN
- IF s = 1 THEN PutOp(160B,-2) (*SSW0*)
- ELSIF s = 2 THEN PutOp(222B,-3) (*SSD0*)
- ELSE PutLit(s); PutOp(340B,-3) (*MOV*)
- END
- ELSE err(134)
- END
- END GenAssign;
- PROCEDURE GenFJ(VAR loc: CARDINAL);
- BEGIN PutOpZ(31B); loc := pc; PutWord(0) (*JP*)
- END GenFJ;
- PROCEDURE GenCFJ(VAR x: Item; VAR loc: CARDINAL);
- BEGIN
- IF x.typ^.form = Bool THEN load(x) ELSE err(135) END ;
- PutOpD(30B); loc := pc; PutWord(0) (*JPC*)
- END GenCFJ;
- PROCEDURE GenBJ(loc: CARDINAL);
- BEGIN
- IF pc < loc+377B THEN PutOpZ(35B); PutByte(pc-loc) (*JPB*)
- ELSE PutOpZ(31B); PutWord(CARDINAL(-INTEGER(pc-loc)))
- END
- END GenBJ;
- PROCEDURE GenCBJ(VAR x: Item; loc: CARDINAL);
- BEGIN
- IF x.typ^.form = Bool THEN load(x) ELSE err(135) END ;
- IF pc < loc+377B THEN PutOpD(34B); PutByte(pc-loc)
- ELSE PutOpD(30B); PutWord(CARDINAL(-INTEGER(pc-loc)))
- END
- END GenCBJ;
- PROCEDURE PrepCall(VAR x: Item; VAR fpar: ParPtr);
- BEGIN x.sp := sp;
- IF x.mode = procMd THEN
- fpar := x.proc^.firstParam;
- IF sp > 0 THEN PutOpZ(262B); (*STORE*) sp := 0 END
- ELSIF x.mode = codMd THEN fpar := x.cod^.firstArg
- ELSIF x.typ^.form = ProcTyp THEN
- fpar := x.typ^.firstPar; load(x);
- IF sp > 1 THEN PutOpZ(263B); sp := 0 (*STOFV*)
- ELSE PutOpD(264B) (*STOT*)
- END
- ELSE err(136); fpar := NIL; x.typ := undftyp
- END
- END PrepCall;
- PROCEDURE GenParam(VAR ap: Item; fp: ParPtr);
- VAR sz: INTEGER; ftyp, inxtyp: StrPtr;
- BEGIN ftyp := fp^.typ;
- IF fp^.varpar THEN
- IF (ftyp^.form = Array) & ftyp^.dyn &
- (ap.typ^.form = Array) & (ap.typ^.ElemTyp = ftyp^.ElemTyp) THEN
- IF ap.typ^.dyn THEN PutLd(ap.var, 2)
- ELSE loadAdr(ap); inxtyp := ap.typ^.IndexTyp;
- PutLit(inxtyp^.max - inxtyp^.min)
- END
- ELSIF (ap.typ = ftyp) OR
- (ftyp = wordtyp) & (ap.typ^.size = 1) OR
- (ftyp = addrtyp) & (ap.typ^.form = Pointer) THEN loadAdr(ap)
- ELSIF (ftyp^.form = Array) & ftyp^.dyn & (ftyp^.ElemTyp = wordtyp) THEN
- IF (ap.typ^.form = Array) & ap.typ^.dyn THEN PutLd(ap.var, 2)
- ELSE loadAdr(ap); PutLit(ap.typ^.size-1)
- END
- ELSE err(137)
- END
- ELSE CheckAssComp(ftyp, ap, TRUE, sz)
- END
- END GenParam;
- PROCEDURE adjustStack(VAR x: Item);
- BEGIN (*after procedure call*)
- IF (x.typ = NIL) OR (x.typ = notyp) THEN sp := 0
- ELSE sp := x.sp;
- IF sp > 0 THEN
- IF x.typ^.size = 2 THEN PutOp(261B, 2) (*LODFD*)
- ELSE PutOpU(260B) (*LODFW*)
- END
- ELSE sp := x.typ^.size
- END
- END
- END adjustStack;
- PROCEDURE GenCall(VAR x: Item);
- VAR i, L: CARDINAL; pd: PDPtr;
- BEGIN
- IF x.mode = procMd THEN
- pd := x.proc^.pd; L := pd^.lev;
- IF x.proc^.pmod = 0 THEN
- IF (L = 0) OR (L = curLev) THEN PutOpArg(360B, pd^.num, 0) (*CL*) ELSE
- IF pd^.lev + 1 = curLev THEN PutOpU(351B) (*GB1*)
- ELSE PutOpU(350B); PutByte(curLev - pd^.lev)
- END ;
- PutOpD(356B); PutByte(pd^.num) (*CI*)
- END
- ELSE PutOpZ(355B); reloc; PutByte(x.proc^.pmod); PutByte(pd^.num) (*CX*)
- END ;
- x.typ := x.proc^.typ; adjustStack(x)
- ELSIF x.mode = codMd THEN
- x.typ := x.cod^.typ; sp := INTEGER(x.typ^.size) + x.sp;
- L := x.cod^.length; i := 0;
- WHILE i < L DO
- PutByte(CARDINAL(x.cod^.cd^.cod[i])); i := i+1
- END
- ELSIF x.mode = expMd THEN
- PutOpZ(357B); PutOpZ(266B); (*CF DECS*)
- x.typ := x.typ^.resTyp; adjustStack(x)
- END ;
- x.mode := expMd
- END GenCall;
- PROCEDURE unstack(par: ParPtr);
- VAR a, s: INTEGER; tp: StrPtr;
- BEGIN (*unstack parameters in reverse order when entering procedure*)
- IF par # NIL THEN
- unstack(par^.next); tp := par^.typ;
- IF par^.varpar THEN
- IF (tp^.form = Array) & tp^.dyn THEN
- PutOpZ(61B); PutByte(par^.name) (*SLD*)
- ELSE PutOpArg(60B, par^.name, 0) (*SLW*)
- END
- ELSE s := tp^.size; a := par^.name;
- IF s = 1 THEN PutOpArg(60B, a, 0)
- ELSIF (tp^.form = Array) & tp^.dyn THEN
- PutOpZ(61B); PutByte(a); PutOpZ(41B); PutByte(a); (*SLD a, LLD a*)
- IF tp^.ElemTyp = chartyp THEN PutOpZ(1); PutOpZ(277B) END ;
- PutOpZ(26B); PutByte(1); (*LSA 1*)
- IF tp^.ElemTyp^.size > 1 THEN
- PutLit(tp^.ElemTyp^.size); PutOpD(272B) (*LIT s, UMUL*)
- END ;
- PutOpZ(267B); PutByte(a) (*PCOP a*)
- ELSIF s = 2 THEN PutOpZ(61B); PutByte(a) (*SLD*)
- ELSE PutLit(s); PutOpD(267B); PutByte(a) (*PCOP a*)
- END
- END
- END
- END unstack;
- PROCEDURE GenEnter(VAR L: CARDINAL; proc: ObjPtr);
- BEGIN
- IF ODD(pc) THEN PutOpZ(336B) (*NOP*) END ;
- ProcTab[proc^.pd^.num] := pc;
- PutOpZ(353B) (*ENTR*); L := pc; PutByte(0);
- IF curPrio > 0 THEN PutOpZ(250B); PutByte(curPrio) END ;
- unstack(proc^.firstParam)
- END GenEnter;
- PROCEDURE GenEnterMod(mod: ObjPtr);
- BEGIN
- IF ODD(pc) THEN PutOpZ(336B) (*NOP*) END ;
- ProcTab[mod^.modno] := pc;
- IF curPrio > 0 THEN PutOpZ(250B); PutByte(curPrio) END
- END GenEnterMod;
- PROCEDURE FixupEnter(L: CARDINAL; size: INTEGER);
- BEGIN code[L] := CHAR(size-4)
- END FixupEnter;
- PROCEDURE GenReturn;
- BEGIN
- IF curPrio > 0 THEN PutOpZ(251B) END ;
- PutOpZ(354B) (*RTN*)
- END GenReturn;
- PROCEDURE GenResult(VAR x: Item; proc: ObjPtr);
- VAR sz: INTEGER;
- BEGIN CheckAssComp(proc^.typ, x, FALSE, sz); sp := 0
- END GenResult;
- PROCEDURE GenCase1(VAR x: Item; VAR L0: CARDINAL);
- VAR f: StrForm;
- BEGIN load(x); L0 := pc+1; f := x.typ^.form;
- IF (f <= Int) OR (f = Enum) OR (f = Range) THEN
- PutOpD(302B); PutWord(0) (*ENTC*)
- ELSE err(140)
- END
- END GenCase1;
- PROCEDURE GenCase2;
- BEGIN PutOpZ(303B) (*EXC*)
- END GenCase2;
- PROCEDURE GenCase3(L0, L1, n: CARDINAL; VAR tab: ARRAY OF LabelRange);
- VAR i: CARDINAL; j, lim: INTEGER;
- BEGIN fixup(L0);
- IF n > 0 THEN
- PutWord(CARDINAL(tab[0].low)); PutWord(CARDINAL(tab[n-1].high))
- ELSE PutWord(1); PutWord(0)
- END ;
- PutWord(177777B-pc+L1+1);
- i := 0; j := tab[0].low;
- WHILE i < n DO
- lim := tab[i].high;
- IF lim - j + INTEGER(pc) < CodeLength THEN
- WHILE j < tab[i].low DO
- PutWord(177777B-pc+L1+1); j := j+1 (*else*)
- END ;
- WHILE j <= lim DO
- PutWord(177777B-pc+ tab[i].label +1); j := j+1
- END
- ELSE err(217)
- END ;
- i := i+1
- END
- END GenCase3;
- PROCEDURE GenFor1(VAR v, e1: Item);
- VAR f: StrForm; s: INTEGER;
- BEGIN SRTest(v); f := v.typ^.form;
- IF (f <= Int) OR (f = Enum) THEN
- SRTest(e1); CheckAssComp(v.typ, e1, FALSE, s)
- ELSE err(142)
- END
- END GenFor1;
- PROCEDURE GenFor2(VAR v, e2: Item);
- BEGIN SRTest(e2); load(e2);
- IF v.typ # e2.typ THEN
- IF (v.typ = inttyp) & (e2.typ = cardtyp) THEN
- IF e2.mode = conMd THEN
- IF e2.val.C > MaxInt THEN err(208) END
- ELSE PutOpZ(307B)
- END
- ELSIF (v.typ = cardtyp) & (e2.typ = inttyp) THEN
- IF e2.mode = conMd THEN
- IF e2.val.I < 0 THEN err(132) END
- ELSE PutOpZ(307B)
- END
- ELSE err(117)
- END
- END
- END GenFor2;
- PROCEDURE GenFor3(VAR e3: Item; VAR L0, L1: CARDINAL);
- BEGIN PutOp(300B,-3); (*FOR1*)
- IF e3.val.I > 0 THEN PutByte(0)
- ELSIF e3.val.I < 0 THEN PutByte(1)
- ELSE err(141)
- END ;
- L0 := pc; PutWord(0); L1 := pc
- END GenFor3;
- PROCEDURE GenFor4(VAR e3: Item; L0, L1: CARDINAL);
- BEGIN PutOpZ(301B); PutByte(e3.val.C); PutWord(177777B-pc+L1+1); fixup(L0)
- END GenFor4;
- PROCEDURE GenTrap(n: CARDINAL);
- BEGIN PutLit(n); PutOpD(304B) (*TRAP*)
- END GenTrap;
- PROCEDURE GenStParam(VAR p, x: Item; fctno, parno: CARDINAL);
- VAR f: StrForm; ii: INTEGER;
- BEGIN
- IF parno = 0 THEN (*first parameter*)
- CASE fctno OF
- 0,1: |
- 2: (*ABS*) SRTest(x);
- IF x.typ = inttyp THEN load(x); PutOpZ(316B)
- ELSIF x.typ = realtyp THEN load(x); PutOpZ(235B)
- ELSE err(144)
- END |
- 3: (*CAP*) SRTest(x);
- IF x.typ = chartyp THEN load(x); PutLit(137B); PutOpD(322B)
- ELSE err(144); x.typ := chartyp
- END |
- 4: (*FLOAT*) SRTest(x);
- IF x.typ = cardtyp THEN load(x); PutOpU(237B); PutByte(0)
- ELSE err(144)
- END ;
- x.typ := realtyp |
- 5: (*ODD*) SRTest(x);
- IF (x.typ = cardtyp) OR (x.typ = inttyp) THEN
- load(x); PutOpU(1); PutOpD(322B)
- ELSE err(144)
- END ;
- x.typ := booltyp |
- 6: (*ORD*) SRTest(x);
- IF (x.typ^.form <= Card) OR (x.typ^.form = Enum) THEN load(x)
- ELSE err(144)
- END ;
- x.typ := cardtyp |
- 7: (*TRUNC*)
- IF x.typ = realtyp THEN load(x); PutOpD(237B); PutByte(2)
- ELSE err(144)
- END ;
- x.typ := cardtyp |
- 8: (*SIZE, TSIZE*)
- IF (x.mode = typMd) OR (x.mode = varMd) THEN x.val.I := x.typ^.size
- ELSE err(145); x.val.I := 1
- END ;
- x.mode := conMd; x.typ := cardtyp |
- 9: |
- 10: (*ADR*) loadAdr(x); x.mode := expMd; x.typ := addrtyp |
- 11: (*MIN*)
- IF x.mode = typMd THEN x.mode := conMd;
- CASE x.typ^.form OF
- Bool: x.val.B := FALSE |
- Char: x.val.Ch := 0C |
- Int: x.val.C := 100000B |
- Card: x.val.C := 0 |
- Real: x.val.D0 := 177777B; x.val.D1 := 177777B |
- Double: x.val.D0 := 100000B; x.val.D1 := 0 |
- Enum: x.val.C := 0 |
- Range: x.val.I := x.typ^.min; x.typ := x.typ^.RBaseTyp
- ELSE err(144)
- END
- ELSE err(145)
- END |
- 12: (*MAX*)
- IF x.mode = typMd THEN x.mode := conMd;
- CASE x.typ^.form OF
- Bool: x.val.B := TRUE |
- Char: x.val.Ch := 377C |
- Int: x.val.I := 77777B |
- Card: x.val.C := 177777B |
- Real: x.val.D0 := 77777B; x.val.D1 := 177777B |
- Double: x.val.D0 := 77777B; x.val.D1 := 177777B |
- Enum: x.val.C := x.typ^.NofConst - 1 |
- Range: x.val.I := x.typ^.max; x.typ := x.typ^.RBaseTyp
- ELSE err(144)
- END
- ELSE err(145)
- END |
- 13: (*HIGH*)
- IF (x.mode = varMd) & (x.typ^.form = Array) THEN
- IF x.typ^.dyn THEN loadLim(x.var); x.mode := expMd
- ELSE x.mode := conMd; x.val.I := x.typ^.IndexTyp^.max
- END
- ELSE err(144)
- END ;
- x.typ := cardtyp |
- 14: (*CHR*) SRTest(x);
- IF (x.typ = cardtyp) OR (x.typ = inttyp) THEN load(x)
- ELSE err(144)
- END ;
- x.typ := chartyp |
- 15,16: (*INC, DEC*) f := x.typ^.form;
- IF (f <= Int) OR (f = Range) OR (f = Enum) THEN
- (*INC/DEC: adr COPT LSW0 LI1 UADD/IADD SSW0*)
- SRTest(x); loadAdr(x); PutOpU(265B); PutOpZ(140B)
- ELSE err(144)
- END |
- 17,18: (*INCL EXCL*)
- IF x.typ^.form = Set THEN (*adr COPT LSW0*)
- x.typ := x.typ^.SBaseTyp; loadAdr(x); PutOpU(265B); PutOpZ(140B)
- ELSE err(144); x.typ := cardtyp
- END |
- 19: (*VAL*)
- IF x.mode = typMd THEN f := x.typ^.form;
- IF (f # Enum) & (f > Int) THEN err(144) END
- END |
- 20: (*LONG*) SRTest(x);
- IF x.typ = cardtyp THEN load(x) ELSE err(144) END
- END ;
- p := x
- ELSIF parno = 1 THEN (*second parameter*)
- IF (fctno = 15) OR (fctno = 16) THEN (*INC/DEC*)
- SRTest(x); CheckAssComp(p.typ, x, FALSE, ii)
- ELSIF fctno = 17 THEN (*INCL: n BIT OR SSW0*)
- SRTest(p); SRTest(x);
- IF (x.typ = p.typ) OR (p.typ = cardtyp) & (x.typ = inttyp) THEN
- load(x); PutOpZ(335B); PutOpD(320B); PutOp(160B,-2)
- ELSE err(144)
- END ;
- p.typ := notyp
- ELSIF fctno = 18 THEN (*EXCL: n BIT COM AND SSW0*)
- SRTest(p); SRTest(x);
- IF (x.typ = p.typ) OR (p.typ = cardtyp) & (x.typ = inttyp) THEN
- load(x); PutOpZ(335B); PutOpZ(323B); PutOpD(322B); PutOp(160B,-2)
- ELSE err(144)
- END ;
- p.typ := notyp
- ELSIF fctno = 19 THEN (*VAL*)
- IF x.typ^.size > 1 THEN err(144) END ;
- x.typ := p.typ; p := x
- ELSIF fctno = 20 THEN SRTest(x); (*LONG*)
- IF x.typ = cardtyp THEN load(x) ELSE err(144) END ;
- p.typ := dbltyp
- ELSE err(64)
- END
- ELSE err(64)
- END
- END GenStParam;
- PROCEDURE GenStFct(VAR p: Item; fctno, parno: CARDINAL);
- BEGIN
- IF parno < 1 THEN err(65)
- ELSIF fctno = 15 THEN (*INC*)
- IF parno = 1 THEN PutOpU(1) END ;
- IF p.typ^.form = Int THEN PutOpD(330B) ELSE PutOpD(270B) END ;
- PutOp(160B,-2); p.typ := notyp
- ELSIF fctno = 16 THEN (*DEC*)
- IF parno = 1 THEN PutOpU(1) END ;
- IF p.typ^.form = Int THEN PutOpD(331B) ELSE PutOpD(271B) END ;
- PutOp(160B,-2); p.typ := notyp
- ELSIF (fctno > 16) & (parno < 2) THEN err(65)
- END
- END GenStFct;
- PROCEDURE CheckStack;
- CONST CodeLimit = CodeLength - RelTabLength;
- BEGIN sp := 0;
- IF pc > CodeLimit THEN err(226); CloseScanner; HALT END
- END CheckStack;
- PROCEDURE scanlist1(obj: ObjPtr);
- (*generate code to allocate dataspace and set indirect adresses*)
- VAR s: INTEGER;
- BEGIN
- WHILE obj # NIL DO
- IF (obj^.class = Var) & (obj^.param = {}) & (obj^.typ^.size > 2) THEN
- s := obj^.typ^.size;
- IF curLev = 0 THEN
- IF obj^.vmod = 0 THEN
- datasize := datasize + s; PutOpU(265B); PutOpArg(120B, obj^.vadr,-1);
- IF s < 400B THEN PutOpZ(26B); PutByte(s)
- ELSE PutLit(s); PutOpD(270B) (*UADD*)
- END
- END
- ELSE
- PutLit(s); PutOpZ(352B); PutOpArg(60B, obj^.vadr,-1)
- END
- ELSIF obj^.class = Module THEN
- scanlist1(obj^.firstObj)
- END ;
- obj := obj^.next
- END
- END scanlist1;
- PROCEDURE scanlist2(obj: ObjPtr);
- BEGIN (*generate code for initialization calls of modules*)
- WHILE obj # NIL DO
- IF obj^.class = Module THEN
- scanlist2(obj^.firstObj); PutOpArg(360B, obj^.modno, 0) (*CL*)
- END ;
- obj := obj^.next
- END
- END scanlist2;
- PROCEDURE GenEndDecl(ancestor: ObjPtr; modno: CARDINAL);
- VAR s: CARDINAL; obj: ObjPtr;
- BEGIN
- IF ancestor^.class = Proc THEN obj := ancestor^.firstLocal
- ELSE obj := ancestor^.firstObj
- END ;
- scanlist1(obj);
- IF curLev = 0 THEN (*main*)
- PutOpZ(122B); (*SGW2*) s := 1; (*initialize imports*)
- WHILE s < modno DO
- PutOpZ(355B); reloc; PutByte(s); PutByte(0); s := s+1
- END
- END ;
- scanlist2(obj); sp := 0
- END GenEndDecl;
- PROCEDURE OutCodeFile(VAR name: ARRAY OF CHAR; stamp: KeyPtr;
- adr: INTEGER; pno, id, modn: CARDINAL; mods: ObjPtr);
- VAR i,pcw: CARDINAL;
- out: File;
- PROCEDURE W(n: CARDINAL);
- BEGIN WriteWord(out, n)
- END W;
- PROCEDURE WriteNameAndKey(id: CARDINAL; stamp: KeyPtr);
- VAR k,L: CARDINAL;
- BEGIN L := CARDINAL(IdBuf[id])-1; k := id+L;
- WHILE id < k DO id := id+1; WriteChar(out, IdBuf[id]) END ;
- IF ODD(L) THEN WriteChar(out, 0C) END ;
- WHILE L < 15 DO W(0); L := L+2 END ;
- W(stamp^.k0); W(stamp^.k1); W(stamp^.k2)
- END WriteNameAndKey;
- BEGIN PutOpZ(354B);
- IF ODD(pc) THEN PutOpZ(336B) END ;
- code[7] := CHAR(adr); pcw := pc DIV 2;
- Lookup(out, name, TRUE);
- IF out.res = done THEN
- (*version and header blocks*)
- W(200B); W(1); W(4);
- W(201B); W(14); WriteNameAndKey(id, stamp);
- W(CARDINAL(adr)+CARDINAL(datasize)+(strx DIV 2)); W(pno+pcw); W(0);
- IF modn > 1 THEN (*imports*)
- W(202B); W((modn-1)*11); mods := mods^.next^.next;
- REPEAT
- WriteNameAndKey(mods^.name, mods^.key); mods := mods^.next
- UNTIL mods = NIL
- END ;
- (*data and string blocks*)
- W(204B); W(3); W(1); W(0); W(0);
- IF strx > 0 THEN
- W(204B); W(strx DIV 2 +1); W(adr+datasize);
- FOR i := 0 TO strx-1 DO WriteChar(out, StrTab[i]) END
- END ;
- (*code blocks*)
- W(203B); W(pno+1); W(0);
- FOR i := 0 TO pno-1 DO W(ProcTab[i] + 2*pno) END ;
- W(203B); W(pcw+1); W(pno);
- FOR i := 0 TO pc-1 DO WriteChar(out, code[i]) END ;
- (*relocation block*)
- IF relx > 0 THEN
- W(205B); W(relx);
- FOR i := 0 TO relx-1 DO W(RelTab[i] + 2*pno) END
- END ;
- SetOpen(out);
- IF out.res # done THEN err(223); Delete(out) ELSE Close(out) END
- ELSE err(222)
- END
- END OutCodeFile;
- PROCEDURE InitGenerator;
- BEGIN pc := 0; sp := 0; ProcTab[0] := 0;
- strx := 0; datasize := 0; relx := 0;
- (*LGA 1, TS, JPFC 2, RTN, LGA 0*)
- PutOpZ(25B); PutByte(1); PutOpZ(224B); PutOpZ(32B); PutByte(2);
- PutOpZ(354B); PutOpZ(25B); PutByte(0)
- END InitGenerator;
- BEGIN
- END M3GL.
|