1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251 |
- MODULE Dev0CPB;
- (* THIS IS TEXT COPY OF CPB.odc *)
- (* DO NOT EDIT *)
- (**
- project = "BlackBox"
- organization = "www.oberon.ch"
- contributors = "Oberon microsystems, Robert Campbell"
- version = "System/Rsrc/About"
- copyright = "System/Rsrc/About"
- license = "Docu/BB-License"
- references = "ftp://ftp.inf.ethz.ch/pub/software/Oberon/OberonV4/Docu/OP2.Paper.ps"
- changes = ""
- issues = ""
- **)
- IMPORT DevCPT := Dev0CPT, DevCPM := Dev0CPM;
- CONST
- (* symbol values or ops *)
- 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; ash = 17; msk = 18; len = 19;
- conv = 20; abs = 21; cap = 22; odd = 23; not = 33;
- (*SYSTEM*)
- adr = 24; cc = 25; bit = 26; lsh = 27; rot = 28; val = 29;
- min = 34; max = 35; typfn = 36; size = 37;
-
- (* object modes *)
- Var = 1; VarPar = 2; Con = 3; Fld = 4; Typ = 5; LProc = 6; XProc = 7;
- SProc = 8; CProc = 9; IProc = 10; Mod = 11; Head = 12; TProc = 13;
- (* Structure forms *)
- Undef = 0; Byte = 1; Bool = 2; Char8 = 3; Int8 = 4; Int16 = 5; Int32 = 6;
- Real32 = 7; Real64 = 8; Set = 9; String8 = 10; NilTyp = 11; NoTyp = 12;
- Pointer = 13; ProcTyp = 14; Comp = 15;
- Char16 = 16; String16 = 17; Int64 = 18;
- intSet = {Int8..Int32, Int64}; realSet = {Real32, Real64}; charSet = {Char8, Char16};
- (* composite structure forms *)
- Basic = 1; Array = 2; DynArr = 3; Record = 4;
- (* nodes classes *)
- Nvar = 0; Nvarpar = 1; Nfield = 2; Nderef = 3; Nindex = 4; Nguard = 5; Neguard = 6;
- Nconst = 7; Ntype = 8; Nproc = 9; Nupto = 10; Nmop = 11; Ndop = 12; Ncall = 13;
- Ninittd = 14; Nif = 15; Ncaselse = 16; Ncasedo = 17; Nenter = 18; Nassign = 19;
- Nifelse = 20; Ncase = 21; Nwhile = 22; Nrepeat = 23; Nloop = 24; Nexit = 25;
- Nreturn = 26; Nwith = 27; Ntrap = 28;
- (*function number*)
- assign = 0;
- haltfn = 0; newfn = 1; absfn = 2; capfn = 3; ordfn = 4;
- entierfn = 5; oddfn = 6; minfn = 7; maxfn = 8; chrfn = 9;
- shortfn = 10; longfn = 11; sizefn = 12; incfn = 13; decfn = 14;
- inclfn = 15; exclfn = 16; lenfn = 17; copyfn = 18; ashfn = 19; assertfn = 32;
- lchrfn = 33; lentierfcn = 34; bitsfn = 37; bytesfn = 38;
-
- (*SYSTEM function number*)
- adrfn = 20; ccfn = 21; lshfn = 22; rotfn = 23;
- getfn = 24; putfn = 25; getrfn = 26; putrfn = 27;
- bitfn = 28; valfn = 29; sysnewfn = 30; movefn = 31;
- thisrecfn = 45; thisarrfn = 46;
- (* COM function number *)
- validfn = 40; iidfn = 41; queryfn = 42;
-
- (* module visibility of objects *)
- internal = 0; external = 1; externalR = 2; inPar = 3; outPar = 4;
- (* procedure flags (conval.setval) *)
- hasBody = 1; isRedef = 2; slNeeded = 3; imVar = 4;
-
- (* attribute flags (attr.adr, struct.attribute, proc.conval.setval)*)
- newAttr = 16; absAttr = 17; limAttr = 18; empAttr = 19; extAttr = 20;
-
- (* case statement flags (conval.setval) *)
- useTable = 1; useTree = 2;
-
- (* sysflags *)
- nilBit = 1; inBit = 2; outBit = 4; newBit = 8; iidBit = 16; interface = 10; jint = -11; jstr = -13;
- AssertTrap = 0; (* default trap number *)
- covarOut = FALSE;
-
-
- VAR
- typSize*: PROCEDURE(typ: DevCPT.Struct);
- zero, one, two, dummy, quot: DevCPT.Const;
- PROCEDURE err(n: SHORTINT);
- BEGIN DevCPM.err(n)
- END err;
-
- PROCEDURE NewLeaf*(obj: DevCPT.Object): DevCPT.Node;
- VAR node: DevCPT.Node; typ: DevCPT.Struct;
- BEGIN
- typ := obj.typ;
- CASE obj.mode OF
- Var:
- node := DevCPT.NewNode(Nvar); node.readonly := (obj.vis = externalR) & (obj.mnolev < 0)
- | VarPar:
- node := DevCPT.NewNode(Nvarpar); node.readonly := obj.vis = inPar;
- | Con:
- node := DevCPT.NewNode(Nconst); node.conval := DevCPT.NewConst();
- node.conval^ := obj.conval^ (* string is not copied, only its ref *)
- | Typ:
- node := DevCPT.NewNode(Ntype)
- | LProc..IProc, TProc:
- node := DevCPT.NewNode(Nproc)
- ELSE err(127); node := DevCPT.NewNode(Nvar); typ := DevCPT.notyp
- END ;
- node.obj := obj; node.typ := typ;
- RETURN node
- END NewLeaf;
-
- PROCEDURE Construct*(class: BYTE; VAR x: DevCPT.Node; y: DevCPT.Node);
- VAR node: DevCPT.Node;
- BEGIN
- node := DevCPT.NewNode(class); node.typ := DevCPT.notyp;
- node.left := x; node.right := y; x := node
- END Construct;
-
- PROCEDURE Link*(VAR x, last: DevCPT.Node; y: DevCPT.Node);
- BEGIN
- IF x = NIL THEN x := y ELSE last.link := y END ;
- WHILE y.link # NIL DO y := y.link END ;
- last := y
- END Link;
-
- PROCEDURE BoolToInt(b: BOOLEAN): INTEGER;
- BEGIN
- IF b THEN RETURN 1 ELSE RETURN 0 END
- END BoolToInt;
-
- PROCEDURE IntToBool(i: INTEGER): BOOLEAN;
- BEGIN
- IF i = 0 THEN RETURN FALSE ELSE RETURN TRUE END
- END IntToBool;
-
- PROCEDURE NewBoolConst*(boolval: BOOLEAN): DevCPT.Node;
- VAR x: DevCPT.Node;
- BEGIN
- x := DevCPT.NewNode(Nconst); x.typ := DevCPT.booltyp;
- x.conval := DevCPT.NewConst(); x.conval.intval := BoolToInt(boolval); RETURN x
- END NewBoolConst;
-
- PROCEDURE OptIf*(VAR x: DevCPT.Node); (* x.link = NIL *)
- VAR if, pred: DevCPT.Node;
- BEGIN
- if := x.left;
- WHILE if.left.class = Nconst DO
- IF IntToBool(if.left.conval.intval) THEN x := if.right; RETURN
- ELSIF if.link = NIL THEN x := x.right; RETURN
- ELSE if := if.link; x.left := if
- END
- END ;
- pred := if; if := if.link;
- WHILE if # NIL DO
- IF if.left.class = Nconst THEN
- IF IntToBool(if.left.conval.intval) THEN
- pred.link := NIL; x.right := if.right; RETURN
- ELSE if := if.link; pred.link := if
- END
- ELSE pred := if; if := if.link
- END
- END
- END OptIf;
- PROCEDURE Nil*(): DevCPT.Node;
- VAR x: DevCPT.Node;
- BEGIN
- x := DevCPT.NewNode(Nconst); x.typ := DevCPT.niltyp;
- x.conval := DevCPT.NewConst(); x.conval.intval := 0; RETURN x
- END Nil;
- PROCEDURE EmptySet*(): DevCPT.Node;
- VAR x: DevCPT.Node;
- BEGIN
- x := DevCPT.NewNode(Nconst); x.typ := DevCPT.settyp;
- x.conval := DevCPT.NewConst(); x.conval.setval := {}; RETURN x
- END EmptySet;
-
- PROCEDURE MarkAsUsed (node: DevCPT.Node);
- VAR c: BYTE;
- BEGIN
- c := node.class;
- WHILE (c = Nfield) OR (c = Nindex) OR (c = Nguard) OR (c = Neguard) DO node := node.left; c := node.class END;
- IF (c = Nvar) & (node.obj.mnolev > 0) THEN node.obj.used := TRUE END
- END MarkAsUsed;
-
-
- PROCEDURE GetTempVar* (name: ARRAY OF SHORTCHAR; typ: DevCPT.Struct; VAR obj: DevCPT.Object);
- VAR n: DevCPT.Name; o: DevCPT.Object;
- BEGIN
- n := "@@ "; DevCPT.Insert(n, obj); obj.name^ := name$; (* avoid err 1 *)
- obj.mode := Var; obj.typ := typ;
- o := DevCPT.topScope.scope;
- IF o = NIL THEN DevCPT.topScope.scope := obj
- ELSE
- WHILE o.link # NIL DO o := o.link END;
- o.link := obj
- END
- END GetTempVar;
- (* ---------- constant operations ---------- *)
-
- PROCEDURE Log (x: DevCPT.Node): INTEGER;
- VAR val, exp: INTEGER;
- BEGIN
- exp := 0;
- IF x.typ.form = Int64 THEN
- RETURN -1
- ELSE
- val := x.conval.intval;
- IF val > 0 THEN
- WHILE ~ODD(val) DO val := val DIV 2; INC(exp) END
- END;
- IF val # 1 THEN exp := -1 END
- END;
- RETURN exp
- END Log;
- PROCEDURE Floor (x: REAL): REAL;
- VAR y: REAL;
- BEGIN
- IF ABS(x) > 9007199254740992.0 (* 2^53 *) THEN RETURN x
- ELSIF (x >= MAX(INTEGER) + 1.0) OR (x < MIN(INTEGER)) THEN
- y := Floor(x / (MAX(INTEGER) + 1.0)) * (MAX(INTEGER) + 1.0);
- RETURN SHORT(ENTIER(x - y)) + y
- ELSE RETURN SHORT(ENTIER(x))
- END
- END Floor;
- PROCEDURE SetToInt (s: SET): INTEGER;
- VAR x, i: INTEGER;
- BEGIN
- i := 31; x := 0;
- IF 31 IN s THEN x := -1 END;
- WHILE i > 0 DO
- x := x * 2; DEC(i);
- IF i IN s THEN INC(x) END
- END;
- RETURN x
- END SetToInt;
- PROCEDURE IntToSet (x: INTEGER): SET;
- VAR i: INTEGER; s: SET;
- BEGIN
- i := 0; s := {};
- WHILE i < 32 DO
- IF ODD(x) THEN INCL(s, i) END;
- x := x DIV 2; INC(i)
- END;
- RETURN s
- END IntToSet;
- PROCEDURE GetConstType (x: DevCPT.Const; form: INTEGER; errno: SHORTINT; VAR typ: DevCPT.Struct);
- CONST MAXL = 9223372036854775808.0; (* 2^63 *)
- BEGIN
- IF (form IN intSet + charSet) & (x.realval + x.intval >= MIN(INTEGER))
- & (x.realval + x.intval <= MAX(INTEGER)) THEN
- x.intval := SHORT(ENTIER(x.realval + x.intval)); x.realval := 0
- END;
- IF form IN intSet THEN
- IF x.realval = 0 THEN typ := DevCPT.int32typ
- ELSIF (x.intval >= -MAXL - x.realval) & (x.intval < MAXL - x.realval) THEN typ := DevCPT.int64typ
- ELSE err(errno); x.intval := 1; x.realval := 0; typ := DevCPT.int32typ
- END
- ELSIF form IN realSet THEN (* SR *)
- typ := DevCPT.real64typ
- ELSIF form IN charSet THEN
- IF x.intval <= 255 THEN typ := DevCPT.char8typ
- ELSE typ := DevCPT.char16typ
- END
- ELSE typ := DevCPT.undftyp
- END
- END GetConstType;
-
- PROCEDURE CheckConstType (x: DevCPT.Const; form: INTEGER; errno: SHORTINT);
- VAR type: DevCPT.Struct;
- BEGIN
- GetConstType(x, form, errno, type);
- IF ~DevCPT.Includes(form, type.form)
- & ((form # Int8) OR (x.realval # 0) OR (x.intval < -128) OR (x.intval > 127))
- & ((form # Int16) OR (x.realval # 0) OR (x.intval < -32768) OR (x.intval > 32767))
- & ((form # Real32) OR (ABS(x.realval) > DevCPM.MaxReal32) & (ABS(x.realval) # DevCPM.InfReal)) THEN
- err(errno); x.intval := 1; x.realval := 0
- END
- (*
- IF (form IN intSet + charSet) & (x.realval + x.intval >= MIN(INTEGER))
- & (x.realval + x.intval <= MAX(INTEGER)) THEN
- x.intval := SHORT(ENTIER(x.realval + x.intval)); x.realval := 0
- END;
- IF (form = Int64) & ((x.intval < -MAXL - x.realval) OR (x.intval >= MAXL - x.realval))
- OR (form = Int32) & (x.realval # 0)
- OR (form = Int16) & ((x.realval # 0) OR (x.intval < -32768) OR (x.intval > 32767))
- OR (form = Int8) & ((x.realval # 0) OR (x.intval < -128) OR (x.intval > 127))
- OR (form = Char16) & ((x.realval # 0) OR (x.intval < 0) OR (x.intval > 65535))
- OR (form = Char8) & ((x.realval # 0) OR (x.intval < 0) OR (x.intval > 255))
- OR (form = Real32) & (ABS(x.realval) > DevCPM.MaxReal32) & (ABS(x.realval) # DevCPM.InfReal) THEN
- err(errno); x.intval := 1; x.realval := 0
- END
- *)
- END CheckConstType;
-
- PROCEDURE ConvConst (x: DevCPT.Const; from, to: INTEGER);
- VAR sr: SHORTREAL;
- BEGIN
- IF from = Set THEN
- x.intval := SetToInt(x.setval); x.realval := 0; x.setval := {};
- ELSIF from IN intSet + charSet THEN
- IF to = Set THEN CheckConstType(x, Int32, 203); x.setval := IntToSet(x.intval)
- ELSIF to IN intSet THEN CheckConstType(x, to, 203)
- ELSIF to IN realSet THEN x.realval := x.realval + x.intval; x.intval := DevCPM.ConstNotAlloc
- ELSE (*to IN charSet*) CheckConstType(x, to, 220)
- END
- ELSIF from IN realSet THEN
- IF to IN realSet THEN CheckConstType(x, to, 203);
- IF to = Real32 THEN sr := SHORT(x.realval); x.realval := sr END (* reduce precision *)
- ELSE x.realval := Floor(x.realval); x.intval := 0; CheckConstType(x, to, 203)
- END
- END
- END ConvConst;
-
- PROCEDURE Prepare (x: DevCPT.Const);
- VAR r: REAL;
- BEGIN
- x.realval := x.realval + x.intval DIV 32768 * 32768;
- x.intval := x.intval MOD 32768;
- r := Floor(x.realval / 4096) * 4096;
- x.intval := x.intval + SHORT(ENTIER(x.realval - r));
- x.realval := r
- (* ABS(x.intval) < 2^15 & ABS(x.realval) MOD 2^12 = 0 *)
- END Prepare;
-
- PROCEDURE AddConst (x, y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := x + y *)
- BEGIN
- IF type.form IN intSet THEN
- Prepare(x); Prepare(y);
- z.intval := x.intval + y.intval; z.realval := x.realval + y.realval
- ELSIF type.form IN realSet THEN
- IF (ABS(x.realval) = DevCPM.InfReal) & (x.realval = - y.realval) THEN err(212)
- ELSE z.realval := x.realval + y.realval
- END
- ELSE HALT(100)
- END;
- GetConstType(z, type.form, 206, type)
- END AddConst;
-
- PROCEDURE NegateConst (y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := - y *)
- BEGIN
- IF type.form IN intSet THEN Prepare(y); z.intval := -y.intval; z.realval := -y.realval
- ELSIF type.form IN realSet THEN z.realval := -y.realval
- ELSE HALT(100)
- END;
- GetConstType(z, type.form, 207, type)
- END NegateConst;
-
- PROCEDURE SubConst (x, y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := x - y *)
- BEGIN
- IF type.form IN intSet THEN
- Prepare(x); Prepare(y);
- z.intval := x.intval - y.intval; z.realval := x.realval - y.realval
- ELSIF type.form IN realSet THEN
- IF (ABS(x.realval) = DevCPM.InfReal) & (x.realval = y.realval) THEN err(212)
- ELSE z.realval := x.realval - y.realval
- END
- ELSE HALT(100)
- END;
- GetConstType(z, type.form, 207, type)
- END SubConst;
-
- PROCEDURE MulConst (x, y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := x * y *)
- BEGIN
- IF type.form IN intSet THEN
- Prepare(x); Prepare(y);
- z.realval := x.realval * y.realval + x.intval * y.realval + x.realval * y.intval;
- z.intval := x.intval * y.intval
- ELSIF type.form IN realSet THEN
- IF (ABS(x.realval) = DevCPM.InfReal) & ( y.realval = 0.0) THEN err(212)
- ELSIF (ABS(y.realval) = DevCPM.InfReal) & (x.realval = 0.0) THEN err(212)
- ELSE z.realval := x.realval * y.realval
- END
- ELSE HALT(100)
- END;
- GetConstType(z, type.form, 204, type)
- END MulConst;
-
- PROCEDURE DivConst (x, y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := x / y *)
- BEGIN
- IF type.form IN realSet THEN
- IF (x.realval = 0.0) & (y.realval = 0.0) THEN err(212)
- ELSIF (ABS(x.realval) = DevCPM.InfReal) & (ABS(y.realval) = DevCPM.InfReal) THEN err(212)
- ELSE z.realval := x.realval / y.realval
- END
- ELSE HALT(100)
- END;
- GetConstType(z, type.form, 204, type)
- END DivConst;
-
- PROCEDURE DivModConst (x, y: DevCPT.Const; div: BOOLEAN; VAR type: DevCPT.Struct);
- (* x := x DIV y | x MOD y *)
- BEGIN
- IF type.form IN intSet THEN
- IF y.realval + y.intval # 0 THEN
- Prepare(x); Prepare(y);
- quot.realval := Floor((x.realval + x.intval) / (y.realval + y.intval));
- quot.intval := 0; Prepare(quot);
- x.realval := x.realval - quot.realval * y.realval - quot.realval * y.intval - quot.intval * y.realval;
- x.intval := x.intval - quot.intval * y.intval;
- IF y.realval + y.intval > 0 THEN
- WHILE x.realval + x.intval > 0 DO SubConst(x, y, x, type); INC(quot.intval) END;
- WHILE x.realval + x.intval < 0 DO AddConst(x, y, x, type); DEC(quot.intval) END
- ELSE
- WHILE x.realval + x.intval < 0 DO SubConst(x, y, x, type); INC(quot.intval) END;
- WHILE x.realval + x.intval > 0 DO AddConst(x, y, x, type); DEC(quot.intval) END
- END;
- IF div THEN x.realval := quot.realval; x.intval := quot.intval END;
- GetConstType(x, type.form, 204, type)
- ELSE err(205)
- END
- ELSE HALT(100)
- END
- END DivModConst;
-
- PROCEDURE EqualConst (x, y: DevCPT.Const; form: INTEGER): BOOLEAN; (* x = y *)
- VAR res: BOOLEAN;
- BEGIN
- CASE form OF
- | Undef: res := TRUE
- | Bool, Byte, Char8..Int32, Char16: res := x.intval = y.intval
- | Int64: Prepare(x); Prepare(y); res := (x.realval - y.realval) + (x.intval - y.intval) = 0
- | Real32, Real64: res := x.realval = y.realval
- | Set: res := x.setval = y.setval
- | String8, String16, Comp (* guid *): res := x.ext^ = y.ext^
- | NilTyp, Pointer, ProcTyp: res := x.intval = y.intval
- END;
- RETURN res
- END EqualConst;
-
- PROCEDURE LessConst (x, y: DevCPT.Const; form: INTEGER): BOOLEAN; (* x < y *)
- VAR res: BOOLEAN;
- BEGIN
- CASE form OF
- | Undef: res := TRUE
- | Byte, Char8..Int32, Char16: res := x.intval < y.intval
- | Int64: Prepare(x); Prepare(y); res := (x.realval - y.realval) + (x.intval - y.intval) < 0
- | Real32, Real64: res := x.realval < y.realval
- | String8, String16: res := x.ext^ < y.ext^
- | Bool, Set, NilTyp, Pointer, ProcTyp, Comp: err(108)
- END;
- RETURN res
- END LessConst;
-
- PROCEDURE IsNegConst (x: DevCPT.Const; form: INTEGER): BOOLEAN; (* x < 0 OR x = (-0.0) *)
- VAR res: BOOLEAN;
- BEGIN
- CASE form OF
- | Int8..Int32: res := x.intval < 0
- | Int64: Prepare(x); res := x.realval + x.intval < 0
- | Real32, Real64: res := (x.realval <= 0.) & (1. / x.realval <= 0.)
- END;
- RETURN res
- END IsNegConst;
- PROCEDURE NewIntConst*(intval: INTEGER): DevCPT.Node;
- VAR x: DevCPT.Node;
- BEGIN
- x := DevCPT.NewNode(Nconst); x.conval := DevCPT.NewConst();
- x.conval.intval := intval; x.conval.realval := 0; x.typ := DevCPT.int32typ; RETURN x
- END NewIntConst;
-
- PROCEDURE NewLargeIntConst* (intval: INTEGER; realval: REAL): DevCPT.Node;
- VAR x: DevCPT.Node;
- BEGIN
- x := DevCPT.NewNode(Nconst); x.conval := DevCPT.NewConst();
- x.conval.intval := intval; x.conval.realval := realval; x.typ := DevCPT.int64typ; RETURN x
- END NewLargeIntConst;
-
- PROCEDURE NewRealConst*(realval: REAL; typ: DevCPT.Struct): DevCPT.Node;
- VAR x: DevCPT.Node;
- BEGIN
- x := DevCPT.NewNode(Nconst); x.conval := DevCPT.NewConst();
- x.conval.realval := realval; x.conval.intval := DevCPM.ConstNotAlloc;
- IF typ = NIL THEN typ := DevCPT.real64typ END;
- x.typ := typ;
- RETURN x
- END NewRealConst;
-
- PROCEDURE NewString*(str: DevCPT.String; lstr: POINTER TO ARRAY OF CHAR; len: INTEGER): DevCPT.Node;
- VAR i, j, c: INTEGER; x: DevCPT.Node; ext: DevCPT.ConstExt;
- BEGIN
- x := DevCPT.NewNode(Nconst); x.conval := DevCPT.NewConst();
- IF lstr # NIL THEN
- x.typ := DevCPT.string16typ;
- NEW(ext, 3 * len); i := 0; j := 0;
- REPEAT c := ORD(lstr[i]); INC(i); DevCPM.PutUtf8(ext^, c, j) UNTIL c = 0;
- x.conval.ext := ext
- ELSE
- x.typ := DevCPT.string8typ; x.conval.ext := str
- END;
- x.conval.intval := DevCPM.ConstNotAlloc; x.conval.intval2 := len;
- RETURN x
- END NewString;
-
- PROCEDURE CharToString8(n: DevCPT.Node);
- VAR ch: SHORTCHAR;
- BEGIN
- n.typ := DevCPT.string8typ; ch := SHORT(CHR(n.conval.intval)); NEW(n.conval.ext, 2);
- IF ch = 0X THEN n.conval.intval2 := 1 ELSE n.conval.intval2 := 2; n.conval.ext[1] := 0X END ;
- n.conval.ext[0] := ch; n.conval.intval := DevCPM.ConstNotAlloc; n.obj := NIL
- END CharToString8;
-
- PROCEDURE CharToString16 (n: DevCPT.Node);
- VAR ch, ch1: SHORTCHAR; i: INTEGER;
- BEGIN
- n.typ := DevCPT.string16typ; NEW(n.conval.ext, 4);
- IF n.conval.intval = 0 THEN
- n.conval.ext[0] := 0X; n.conval.intval2 := 1
- ELSE
- i := 0; DevCPM.PutUtf8(n.conval.ext^, n.conval.intval, i);
- n.conval.ext[i] := 0X; n.conval.intval2 := 2
- END;
- n.conval.intval := DevCPM.ConstNotAlloc; n.obj := NIL
- END CharToString16;
-
- PROCEDURE String8ToString16 (n: DevCPT.Node);
- VAR i, j, x: INTEGER; ext, new: DevCPT.ConstExt;
- BEGIN
- n.typ := DevCPT.string16typ; ext := n.conval.ext;
- NEW(new, 2 * n.conval.intval2); i := 0; j := 0;
- REPEAT x := ORD(ext[i]); INC(i); DevCPM.PutUtf8(new^, x, j) UNTIL x = 0;
- n.conval.ext := new; n.obj := NIL
- END String8ToString16;
-
- PROCEDURE String16ToString8 (n: DevCPT.Node);
- VAR i, j, x: INTEGER; ext, new: DevCPT.ConstExt;
- BEGIN
- n.typ := DevCPT.string8typ; ext := n.conval.ext;
- NEW(new, n.conval.intval2); i := 0; j := 0;
- REPEAT DevCPM.GetUtf8(ext^, x, i); new[j] := SHORT(CHR(x MOD 256)); INC(j) UNTIL x = 0;
- n.conval.ext := new; n.obj := NIL
- END String16ToString8;
-
- PROCEDURE StringToGuid (VAR n: DevCPT.Node);
- BEGIN
- ASSERT((n.class = Nconst) & (n.typ.form = String8));
- IF ~DevCPM.ValidGuid(n.conval.ext^) THEN err(165) END;
- n.typ := DevCPT.guidtyp
- END StringToGuid;
-
- PROCEDURE CheckString (n: DevCPT.Node; typ: DevCPT.Struct; e: SHORTINT);
- VAR ntyp: DevCPT.Struct;
- BEGIN
- ntyp := n.typ;
- IF (typ = DevCPT.guidtyp) & (n.class = Nconst) & (ntyp.form = String8) THEN StringToGuid(n)
- ELSIF (typ.comp IN {Array, DynArr}) & (typ.BaseTyp.form = Char8) OR (typ.form = String8) THEN
- IF (n.class = Nconst) & (ntyp.form = Char8) THEN CharToString8(n)
- ELSIF (ntyp.comp IN {Array, DynArr}) & (ntyp.BaseTyp.form = Char8) OR (ntyp.form = String8) THEN (* ok *)
- ELSE err(e)
- END
- ELSIF (typ.comp IN {Array, DynArr}) & (typ.BaseTyp.form = Char16) OR (typ.form = String16) THEN
- IF (n.class = Nconst) & (ntyp.form IN charSet) THEN CharToString16(n)
- ELSIF (n.class = Nconst) & (ntyp.form = String8) THEN String8ToString16(n)
- ELSIF (ntyp.comp IN {Array, DynArr}) & (ntyp.BaseTyp.form = Char16) OR (ntyp.form = String16) THEN
- (* ok *)
- ELSE err(e)
- END
- ELSE err(e)
- END
- END CheckString;
-
-
- PROCEDURE BindNodes(class: BYTE; typ: DevCPT.Struct; VAR x: DevCPT.Node; y: DevCPT.Node);
- VAR node: DevCPT.Node;
- BEGIN
- node := DevCPT.NewNode(class); node.typ := typ;
- node.left := x; node.right := y; x := node
- END BindNodes;
- PROCEDURE NotVar(x: DevCPT.Node): BOOLEAN;
- BEGIN
- RETURN (x.class >= Nconst) & ((x.class # Nmop) OR (x.subcl # val) OR (x.left.class >= Nconst))
- OR (x.typ.form IN {String8, String16})
- END NotVar;
- PROCEDURE Convert(VAR x: DevCPT.Node; typ: DevCPT.Struct);
- VAR node: DevCPT.Node; f, g: SHORTINT; k: INTEGER; r: REAL;
- BEGIN f := x.typ.form; g := typ.form;
- IF x.class = Nconst THEN
- IF g = String8 THEN
- IF f = String16 THEN String16ToString8(x)
- ELSIF f IN charSet THEN CharToString8(x)
- ELSE typ := DevCPT.undftyp
- END
- ELSIF g = String16 THEN
- IF f = String8 THEN String8ToString16(x)
- ELSIF f IN charSet THEN CharToString16(x)
- ELSE typ := DevCPT.undftyp
- END
- ELSE ConvConst(x.conval, f, g)
- END;
- x.obj := NIL
- ELSIF (x.class = Nmop) & (x.subcl = conv) & (DevCPT.Includes(f, x.left.typ.form) OR DevCPT.Includes(f, g))
- THEN
- (* don't create new node *)
- IF x.left.typ.form = typ.form THEN (* and suppress existing node *) x := x.left END
- ELSE
- IF (x.class = Ndop) & (x.typ.form IN {String8, String16}) THEN (* propagate to leaf nodes *)
- Convert(x.left, typ); Convert(x.right, typ)
- ELSE
- node := DevCPT.NewNode(Nmop); node.subcl := conv; node.left := x; x := node;
- END
- END;
- x.typ := typ
- END Convert;
- PROCEDURE Promote (VAR left, right: DevCPT.Node; op: INTEGER); (* check expression compatibility *)
- VAR f, g: INTEGER; new: DevCPT.Struct;
- BEGIN
- f := left.typ.form; g := right.typ.form; new := left.typ;
- IF f IN intSet + realSet THEN
- IF g IN intSet + realSet THEN
- IF (f = Real32) & (right.class = Nconst) & (g IN realSet) & (left.class # Nconst)
- (* & ((ABS(right.conval.realval) <= DevCPM.MaxReal32)
- OR (ABS(right.conval.realval) = DevCPM.InfReal)) *)
- OR (g = Real32) & (left.class = Nconst) & (f IN realSet) & (right.class # Nconst)
- (* & ((ABS(left.conval.realval) <= DevCPM.MaxReal32)
- OR (ABS(left.conval.realval) = DevCPM.InfReal)) *) THEN
- new := DevCPT.real32typ (* SR *)
- ELSIF (f = Real64) OR (g = Real64) THEN new := DevCPT.real64typ
- ELSIF (f = Real32) OR (g = Real32) THEN new := DevCPT.real32typ (* SR *)
- ELSIF op = slash THEN new := DevCPT.real64typ
- ELSIF (f = Int64) OR (g = Int64) THEN new := DevCPT.int64typ
- ELSE new := DevCPT.int32typ
- END
- ELSE err(100)
- END
- ELSIF (left.typ = DevCPT.guidtyp) OR (right.typ = DevCPT.guidtyp) THEN
- IF f = String8 THEN StringToGuid(left) END;
- IF g = String8 THEN StringToGuid(right) END;
- IF left.typ # right.typ THEN err(100) END;
- f := Comp
- ELSIF f IN charSet + {String8, String16} THEN
- IF g IN charSet + {String8, String16} THEN
- IF (f = String16) OR (g = String16) OR (f = Char16) & (g = String8) OR (f = String8) & (g = Char16) THEN
- new := DevCPT.string16typ
- ELSIF (f = Char16) OR (g = Char16) THEN new := DevCPT.char16typ
- ELSIF (f = String8) OR (g = String8) THEN new := DevCPT.string8typ
- ELSIF op = plus THEN
- IF (f = Char16) OR (g = Char16) THEN new := DevCPT.string16typ
- ELSE new := DevCPT.string8typ
- END
- END;
- IF (new.form IN {String8, String16})
- & ((f IN charSet) & (left.class # Nconst) OR (g IN charSet) & (right.class # Nconst))
- THEN
- err(100)
- END
- ELSE err(100)
- END
- ELSIF (f IN {NilTyp, Pointer, ProcTyp}) & (g IN {NilTyp, Pointer, ProcTyp}) THEN
- IF ~DevCPT.SameType(left.typ, right.typ) & (f # NilTyp) & (g # NilTyp)
- & ~((f = Pointer) & (g = Pointer)
- & (DevCPT.Extends(left.typ, right.typ) OR DevCPT.Extends(right.typ, left.typ))) THEN err(100) END
- ELSIF f # g THEN err(100)
- END;
- IF ~(f IN {NilTyp, Pointer, ProcTyp, Comp}) THEN
- IF g # new.form THEN Convert(right, new) END;
- IF f # new.form THEN Convert(left, new) END
- END
- END Promote;
- PROCEDURE CheckParameters* (fp, ap: DevCPT.Object; checkNames: BOOLEAN); (* checks par list match *)
- VAR ft, at: DevCPT.Struct;
- BEGIN
- WHILE fp # NIL DO
- IF ap # NIL THEN
- ft := fp.typ; at := ap.typ;
- IF fp.ptyp # NIL THEN ft := fp.ptyp END; (* get original formal type *)
- IF ap.ptyp # NIL THEN at := ap.ptyp END; (* get original formal type *)
- IF ~DevCPT.EqualType(ft, at)
- OR (fp.mode # ap.mode) OR (fp.sysflag # ap.sysflag) OR (fp.vis # ap.vis)
- OR checkNames & (fp.name^ # ap.name^) THEN err(115) END ;
- ap := ap.link
- ELSE err(116)
- END;
- fp := fp.link
- END;
- IF ap # NIL THEN err(116) END
- END CheckParameters;
- PROCEDURE CheckNewParamPair* (newPar, iidPar: DevCPT.Node);
- VAR ityp, ntyp: DevCPT.Struct;
- BEGIN
- ntyp := newPar.typ.BaseTyp;
- IF (newPar.class = Nvarpar) & ODD(newPar.obj.sysflag DIV newBit) THEN
- IF (iidPar.class = Nvarpar) & ODD(iidPar.obj.sysflag DIV iidBit) & (iidPar.obj.mnolev = newPar.obj.mnolev)
- THEN (* ok *)
- ELSE err(168)
- END
- ELSIF ntyp.extlev = 0 THEN (* ok *)
- ELSIF (iidPar.class = Nconst) & (iidPar.obj # NIL) & (iidPar.obj.mode = Typ) THEN
- IF ~DevCPT.Extends(iidPar.obj.typ, ntyp) THEN err(168) END
- ELSE err(168)
- END
- END CheckNewParamPair;
-
- PROCEDURE DeRef*(VAR x: DevCPT.Node);
- VAR strobj, bstrobj: DevCPT.Object; typ, btyp: DevCPT.Struct;
- BEGIN
- typ := x.typ;
- IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(78)
- ELSIF typ.form = Pointer THEN
- btyp := typ.BaseTyp; strobj := typ.strobj; bstrobj := btyp.strobj;
- IF (strobj # NIL) & (strobj.name # DevCPT.null) & (bstrobj # NIL) & (bstrobj.name # DevCPT.null) THEN
- btyp.pbused := TRUE
- END ;
- BindNodes(Nderef, btyp, x, NIL); x.subcl := 0
- ELSE err(84)
- END
- END DeRef;
- PROCEDURE StrDeref*(VAR x: DevCPT.Node);
- VAR typ, btyp: DevCPT.Struct;
- BEGIN
- typ := x.typ;
- IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(78)
- ELSIF ((typ.comp IN {Array, DynArr}) & (typ.BaseTyp.form IN charSet)) OR (typ.sysflag = jstr) THEN
- IF (typ.BaseTyp # NIL) & (typ.BaseTyp.form = Char8) THEN btyp := DevCPT.string8typ
- ELSE btyp := DevCPT.string16typ
- END;
- BindNodes(Nderef, btyp, x, NIL); x.subcl := 1
- ELSE err(90)
- END
- END StrDeref;
- PROCEDURE Index*(VAR x: DevCPT.Node; y: DevCPT.Node);
- VAR f: SHORTINT; typ: DevCPT.Struct;
- BEGIN
- f := y.typ.form;
- IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(79)
- ELSIF ~(f IN intSet) OR (y.class IN {Nproc, Ntype}) THEN err(80); y.typ := DevCPT.int32typ END ;
- IF f = Int64 THEN Convert(y, DevCPT.int32typ) END;
- IF x.typ.comp = Array THEN typ := x.typ.BaseTyp;
- IF (y.class = Nconst) & ((y.conval.intval < 0) OR (y.conval.intval >= x.typ.n)) THEN err(81) END
- ELSIF x.typ.comp = DynArr THEN typ := x.typ.BaseTyp;
- IF (y.class = Nconst) & (y.conval.intval < 0) THEN err(81) END
- ELSE err(82); typ := DevCPT.undftyp
- END ;
- BindNodes(Nindex, typ, x, y); x.readonly := x.left.readonly
- END Index;
-
- PROCEDURE Field*(VAR x: DevCPT.Node; y: DevCPT.Object);
- BEGIN (*x.typ.comp = Record*)
- IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(77) END ;
- IF (y # NIL) & (y.mode IN {Fld, TProc}) THEN
- BindNodes(Nfield, y.typ, x, NIL); x.obj := y;
- x.readonly := x.left.readonly OR ((y.vis = externalR) & (y.mnolev < 0))
- ELSE err(83); x.typ := DevCPT.undftyp
- END
- END Field;
-
- PROCEDURE TypTest*(VAR x: DevCPT.Node; obj: DevCPT.Object; guard: BOOLEAN);
- PROCEDURE GTT(t0, t1: DevCPT.Struct);
- VAR node: DevCPT.Node;
- BEGIN
- IF (t0 # NIL) & DevCPT.SameType(t0, t1) & (guard OR (x.class # Nguard)) THEN
- IF ~guard THEN x := NewBoolConst(TRUE) END
- ELSIF (t0 = NIL) OR DevCPT.Extends(t1, t0) OR (t0.sysflag = jint) OR (t1.sysflag = jint)
- OR (t1.comp = DynArr) & (DevCPM.java IN DevCPM.options) THEN
- IF guard THEN BindNodes(Nguard, NIL, x, NIL); x.readonly := x.left.readonly
- ELSE node := DevCPT.NewNode(Nmop); node.subcl := is; node.left := x; node.obj := obj; x := node
- END
- ELSE err(85)
- END
- END GTT;
- BEGIN
- IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(112)
- ELSIF x.typ.form = Pointer THEN
- IF x.typ = DevCPT.sysptrtyp THEN
- IF obj.typ.form = Pointer THEN GTT(NIL, obj.typ.BaseTyp)
- ELSE err(86)
- END
- ELSIF x.typ.BaseTyp.comp # Record THEN err(85)
- ELSIF obj.typ.form = Pointer THEN GTT(x.typ.BaseTyp, obj.typ.BaseTyp)
- ELSE err(86)
- END
- ELSIF (x.typ.comp = Record) & (x.class = Nvarpar) & (x.obj.vis # outPar) & (obj.typ.comp = Record) THEN
- GTT(x.typ, obj.typ)
- ELSE err(87)
- END ;
- IF guard THEN x.typ := obj.typ ELSE x.typ := DevCPT.booltyp END
- END TypTest;
-
- PROCEDURE In*(VAR x: DevCPT.Node; y: DevCPT.Node);
- VAR f: SHORTINT; k: INTEGER;
- BEGIN f := x.typ.form;
- IF (x.class = Ntype) OR (x.class = Nproc) OR (y.class = Ntype) OR (y.class = Nproc) THEN err(126)
- ELSIF (f IN intSet) & (y.typ.form = Set) THEN
- IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
- IF x.class = Nconst THEN
- k := x.conval.intval;
- IF (k < 0) OR (k > DevCPM.MaxSet) THEN err(202)
- ELSIF y.class = Nconst THEN x.conval.intval := BoolToInt(k IN y.conval.setval); x.obj := NIL
- ELSE BindNodes(Ndop, DevCPT.booltyp, x, y); x.subcl := in
- END
- ELSE BindNodes(Ndop, DevCPT.booltyp, x, y); x.subcl := in
- END
- ELSE err(92)
- END ;
- x.typ := DevCPT.booltyp
- END In;
- PROCEDURE MOp*(op: BYTE; VAR x: DevCPT.Node);
- VAR f: SHORTINT; typ: DevCPT.Struct; z: DevCPT.Node;
-
- PROCEDURE NewOp(op: BYTE; typ: DevCPT.Struct; z: DevCPT.Node): DevCPT.Node;
- VAR node: DevCPT.Node;
- BEGIN
- node := DevCPT.NewNode(Nmop); node.subcl := op; node.typ := typ;
- node.left := z; RETURN node
- END NewOp;
- BEGIN z := x;
- IF ((z.class = Ntype) OR (z.class = Nproc)) & (op # adr) & (op # typfn) & (op # size) THEN err(126) (* !!! *)
- ELSE
- typ := z.typ; f := typ.form;
- CASE op OF
- | not:
- IF f = Bool THEN
- IF z.class = Nconst THEN
- z.conval.intval := BoolToInt(~IntToBool(z.conval.intval)); z.obj := NIL
- ELSE z := NewOp(op, typ, z)
- END
- ELSE err(98)
- END
- | plus:
- IF ~(f IN intSet + realSet) THEN err(96) END
- | minus:
- IF f IN intSet + realSet + {Set} THEN
- IF z.class = Nconst THEN
- IF f = Set THEN z.conval.setval := -z.conval.setval
- ELSE NegateConst(z.conval, z.conval, z.typ)
- END;
- z.obj := NIL
- ELSE
- IF f < Int32 THEN Convert(z, DevCPT.int32typ) END;
- z := NewOp(op, z.typ, z)
- END
- ELSE err(97)
- END
- | abs:
- IF f IN intSet + realSet THEN
- IF z.class = Nconst THEN
- IF IsNegConst(z.conval, f) THEN NegateConst(z.conval, z.conval, z.typ) END;
- z.obj := NIL
- ELSE
- IF f < Int32 THEN Convert(z, DevCPT.int32typ) END;
- z := NewOp(op, z.typ, z)
- END
- ELSE err(111)
- END
- | cap:
- IF f IN charSet THEN
- IF z.class = Nconst THEN
- IF ODD(z.conval.intval DIV 32) THEN DEC(z.conval.intval, 32) END;
- z.obj := NIL
- ELSE z := NewOp(op, typ, z)
- END
- ELSE err(111); z.typ := DevCPT.char8typ
- END
- | odd:
- IF f IN intSet THEN
- IF z.class = Nconst THEN
- DivModConst(z.conval, two, FALSE, z.typ); (* z MOD 2 *)
- z.obj := NIL
- ELSE z := NewOp(op, typ, z)
- END
- ELSE err(111)
- END ;
- z.typ := DevCPT.booltyp
- | adr: (*ADR*)
- IF z.class = Nproc THEN
- IF z.obj.mnolev > 0 THEN err(73)
- ELSIF z.obj.mode = LProc THEN z.obj.mode := XProc
- END;
- z := NewOp(op, typ, z)
- ELSIF z.class = Ntype THEN
- IF z.obj.typ.untagged THEN err(111) END;
- z := NewOp(op, typ, z)
- ELSIF (z.class < Nconst) OR (z.class = Nconst) & (f IN {String8, String16}) THEN
- z := NewOp(op, typ, z)
- ELSE err(127)
- END ;
- z.typ := DevCPT.int32typ
- | typfn, size: (*TYP, SIZE*)
- z := NewOp(op, typ, z);
- z.typ := DevCPT.int32typ
- | cc: (*SYSTEM.CC*)
- IF (f IN intSet) & (z.class = Nconst) THEN
- IF (0 <= z.conval.intval) & (z.conval.intval <= DevCPM.MaxCC) & (z.conval.realval = 0) THEN
- z := NewOp(op, typ, z)
- ELSE err(219)
- END
- ELSE err(69)
- END;
- z.typ := DevCPT.booltyp
- END
- END;
- x := z
- END MOp;
-
- PROCEDURE ConstOp(op: SHORTINT; x, y: DevCPT.Node);
- VAR f: SHORTINT; i, j: INTEGER; xval, yval: DevCPT.Const; ext: DevCPT.ConstExt; t: DevCPT.Struct;
- BEGIN
- f := x.typ.form;
- IF f = y.typ.form THEN
- xval := x.conval; yval := y.conval;
- CASE op OF
- | times:
- IF f IN intSet + realSet THEN MulConst(xval, yval, xval, x.typ)
- ELSIF f = Set THEN xval.setval := xval.setval * yval.setval
- ELSIF f # Undef THEN err(101)
- END
- | slash:
- IF f IN realSet THEN DivConst(xval, yval, xval, x.typ)
- ELSIF f = Set THEN xval.setval := xval.setval / yval.setval
- ELSIF f # Undef THEN err(102)
- END
- | div:
- IF f IN intSet THEN DivModConst(xval, yval, TRUE, x.typ)
- ELSIF f # Undef THEN err(103)
- END
- | mod:
- IF f IN intSet THEN DivModConst(xval, yval, FALSE, x.typ)
- ELSIF f # Undef THEN err(104)
- END
- | and:
- IF f = Bool THEN xval.intval := BoolToInt(IntToBool(xval.intval) & IntToBool(yval.intval))
- ELSE err(94)
- END
- | plus:
- IF f IN intSet + realSet THEN AddConst(xval, yval, xval, x.typ)
- ELSIF f = Set THEN xval.setval := xval.setval + yval.setval
- ELSIF (f IN {String8, String16}) & (xval.ext # NIL) & (yval.ext # NIL) THEN
- NEW(ext, LEN(xval.ext^) + LEN(yval.ext^));
- i := 0; WHILE xval.ext[i] # 0X DO ext[i] := xval.ext[i]; INC(i) END;
- j := 0; WHILE yval.ext[j] # 0X DO ext[i] := yval.ext[j]; INC(i); INC(j) END;
- ext[i] := 0X; xval.ext := ext; INC(xval.intval2, yval.intval2 - 1)
- ELSIF f # Undef THEN err(105)
- END
- | minus:
- IF f IN intSet + realSet THEN SubConst(xval, yval, xval, x.typ)
- ELSIF f = Set THEN xval.setval := xval.setval - yval.setval
- ELSIF f # Undef THEN err(106)
- END
- | min:
- IF f IN intSet + realSet THEN
- IF LessConst(yval, xval, f) THEN xval^ := yval^ END
- ELSIF f # Undef THEN err(111)
- END
- | max:
- IF f IN intSet + realSet THEN
- IF LessConst(xval, yval, f) THEN xval^ := yval^ END
- ELSIF f # Undef THEN err(111)
- END
- | or:
- IF f = Bool THEN xval.intval := BoolToInt(IntToBool(xval.intval) OR IntToBool(yval.intval))
- ELSE err(95)
- END
- | eql: xval.intval := BoolToInt(EqualConst(xval, yval, f)); x.typ := DevCPT.booltyp
- | neq: xval.intval := BoolToInt(~EqualConst(xval, yval, f)); x.typ := DevCPT.booltyp
- | lss: xval.intval := BoolToInt(LessConst(xval, yval, f)); x.typ := DevCPT.booltyp
- | leq: xval.intval := BoolToInt(~LessConst(yval, xval, f)); x.typ := DevCPT.booltyp
- | gtr: xval.intval := BoolToInt(LessConst(yval, xval, f)); x.typ := DevCPT.booltyp
- | geq: xval.intval := BoolToInt(~LessConst(xval, yval, f)); x.typ := DevCPT.booltyp
- END
- ELSE err(100)
- END;
- x.obj := NIL
- END ConstOp;
-
- PROCEDURE Op*(op: BYTE; VAR x: DevCPT.Node; y: DevCPT.Node);
- VAR f, g: SHORTINT; t, z: DevCPT.Node; typ: DevCPT.Struct; do: BOOLEAN; val: INTEGER;
- PROCEDURE NewOp(op: BYTE; typ: DevCPT.Struct; VAR x: DevCPT.Node; y: DevCPT.Node);
- VAR node: DevCPT.Node;
- BEGIN
- node := DevCPT.NewNode(Ndop); node.subcl := op; node.typ := typ;
- node.left := x; node.right := y; x := node
- END NewOp;
- BEGIN z := x;
- IF (z.class = Ntype) OR (z.class = Nproc) OR (y.class = Ntype) OR (y.class = Nproc) THEN err(126)
- ELSE
- Promote(z, y, op);
- IF (z.class = Nconst) & (y.class = Nconst) THEN ConstOp(op, z, y)
- ELSE
- typ := z.typ; f := typ.form; g := y.typ.form;
- CASE op OF
- | times:
- do := TRUE;
- IF f IN intSet THEN
- IF z.class = Nconst THEN
- IF EqualConst(z.conval, one, f) THEN do := FALSE; z := y
- ELSIF EqualConst(z.conval, zero, f) THEN do := FALSE
- ELSE val := Log(z);
- IF val >= 0 THEN
- t := y; y := z; z := t;
- op := ash; y.typ := DevCPT.int32typ; y.conval.intval := val; y.obj := NIL
- END
- END
- ELSIF y.class = Nconst THEN
- IF EqualConst(y.conval, one, f) THEN do := FALSE
- ELSIF EqualConst(y.conval, zero, f) THEN do := FALSE; z := y
- ELSE val := Log(y);
- IF val >= 0 THEN
- op := ash; y.typ := DevCPT.int32typ; y.conval.intval := val; y.obj := NIL
- END
- END
- END
- ELSIF ~(f IN {Undef, Real32..Set}) THEN err(105); typ := DevCPT.undftyp
- END ;
- IF do THEN NewOp(op, typ, z, y) END;
- | slash:
- IF f IN realSet THEN (* OK *)
- ELSIF (f # Set) & (f # Undef) THEN err(102); typ := DevCPT.undftyp
- END ;
- NewOp(op, typ, z, y)
- | div:
- do := TRUE;
- IF f IN intSet THEN
- IF y.class = Nconst THEN
- IF EqualConst(y.conval, zero, f) THEN err(205)
- ELSIF EqualConst(y.conval, one, f) THEN do := FALSE
- ELSE val := Log(y);
- IF val >= 0 THEN
- op := ash; y.typ := DevCPT.int32typ; y.conval.intval := -val; y.obj := NIL
- END
- END
- END
- ELSIF f # Undef THEN err(103); typ := DevCPT.undftyp
- END ;
- IF do THEN NewOp(op, typ, z, y) END;
- | mod:
- IF f IN intSet THEN
- IF y.class = Nconst THEN
- IF EqualConst(y.conval, zero, f) THEN err(205)
- ELSE val := Log(y);
- IF val >= 0 THEN
- op := msk; y.conval.intval := ASH(-1, val); y.obj := NIL
- END
- END
- END
- ELSIF f # Undef THEN err(104); typ := DevCPT.undftyp
- END ;
- NewOp(op, typ, z, y);
- | and:
- IF f = Bool THEN
- IF z.class = Nconst THEN
- IF IntToBool(z.conval.intval) THEN z := y END
- ELSIF (y.class = Nconst) & IntToBool(y.conval.intval) THEN (* optimize z & TRUE -> z *)
- ELSE NewOp(op, typ, z, y)
- END
- ELSIF f # Undef THEN err(94); z.typ := DevCPT.undftyp
- END
- | plus:
- IF ~(f IN {Undef, Int8..Set, Int64, String8, String16}) THEN err(105); typ := DevCPT.undftyp END;
- do := TRUE;
- IF f IN intSet THEN
- IF (z.class = Nconst) & EqualConst(z.conval, zero, f) THEN do := FALSE; z := y END ;
- IF (y.class = Nconst) & EqualConst(y.conval, zero, f) THEN do := FALSE END
- ELSIF f IN {String8, String16} THEN
- IF (z.class = Nconst) & (z.conval.intval2 = 1) THEN do := FALSE; z := y END ;
- IF (y.class = Nconst) & (y.conval.intval2 = 1) THEN do := FALSE END;
- IF do THEN
- IF z.class = Ndop THEN
- t := z; WHILE t.right.class = Ndop DO t := t.right END;
- IF (t.right.class = Nconst) & (y.class = Nconst) THEN
- ConstOp(op, t.right, y); do := FALSE
- ELSIF (t.right.class = Nconst) & (y.class = Ndop) & (y.left.class = Nconst) THEN
- ConstOp(op, t.right, y.left); y.left := t.right; t.right := y; do := FALSE
- ELSE
- NewOp(op, typ, t.right, y); do := FALSE
- END
- ELSE
- IF (z.class = Nconst) & (y.class = Ndop) & (y.left.class = Nconst) THEN
- ConstOp(op, z, y.left); y.left := z; z := y; do := FALSE
- END
- END
- END
- END ;
- IF do THEN NewOp(op, typ, z, y) END;
- | minus:
- IF ~(f IN {Undef, Int8..Set, Int64}) THEN err(106); typ := DevCPT.undftyp END;
- IF ~(f IN intSet) OR (y.class # Nconst) OR ~EqualConst(y.conval, zero, f) THEN NewOp(op, typ, z, y)
- END;
- | min, max:
- IF ~(f IN {Undef} + intSet + realSet + charSet) THEN err(111); typ := DevCPT.undftyp END;
- NewOp(op, typ, z, y);
- | or:
- IF f = Bool THEN
- IF z.class = Nconst THEN
- IF ~IntToBool(z.conval.intval) THEN z := y END
- ELSIF (y.class = Nconst) & ~IntToBool(y.conval.intval) THEN (* optimize z OR FALSE -> z *)
- ELSE NewOp(op, typ, z, y)
- END
- ELSIF f # Undef THEN err(95); z.typ := DevCPT.undftyp
- END
- | eql, neq, lss, leq, gtr, geq:
- IF f IN {String8, String16} THEN
- IF (f = String16) & (z.class = Nmop) & (z.subcl = conv) & (y.class = Nmop) & (y.subcl = conv) THEN
- z := z.left; y := y.left (* remove LONG on both sides *)
- ELSIF (z.class = Nconst) & (z.conval.intval2 = 1) & (y.class = Nderef) THEN (* y$ = "" -> y[0] = 0X *)
- y := y.left; Index(y, NewIntConst(0)); z.typ := y.typ; z.conval.intval := 0
- ELSIF (y.class = Nconst) & (y.conval.intval2 = 1) & (z.class = Nderef) THEN (* z$ = "" -> z[0] = 0X *)
- z := z.left; Index(z, NewIntConst(0)); y.typ := z.typ; y.conval.intval := 0
- END;
- typ := DevCPT.booltyp
- ELSIF (f IN {Undef, Char8..Real64, Char16, Int64})
- OR (op <= neq) & ((f IN {Bool, Set, NilTyp, Pointer, ProcTyp}) OR (typ = DevCPT.guidtyp)) THEN
- typ := DevCPT.booltyp
- ELSE err(107); typ := DevCPT.undftyp
- END;
- NewOp(op, typ, z, y)
- END
- END
- END;
- x := z
- END Op;
- PROCEDURE SetRange*(VAR x: DevCPT.Node; y: DevCPT.Node);
- VAR k, l: INTEGER;
- BEGIN
- IF (x.class = Ntype) OR (x.class = Nproc) OR (y.class = Ntype) OR (y.class = Nproc) THEN err(126)
- ELSIF (x.typ.form IN intSet) & (y.typ.form IN intSet) THEN
- IF x.typ.form = Int64 THEN Convert(x, DevCPT.int32typ) END;
- IF y.typ.form = Int64 THEN Convert(y, DevCPT.int32typ) END;
- IF x.class = Nconst THEN
- k := x.conval.intval;
- IF (0 > k) OR (k > DevCPM.MaxSet) OR (x.conval.realval # 0) THEN err(202) END
- END ;
- IF y.class = Nconst THEN
- l := y.conval.intval;
- IF (0 > l) OR (l > DevCPM.MaxSet) OR (y.conval.realval # 0) THEN err(202) END
- END ;
- IF (x.class = Nconst) & (y.class = Nconst) THEN
- IF k <= l THEN
- x.conval.setval := {k..l}
- ELSE err(201); x.conval.setval := {l..k}
- END ;
- x.obj := NIL
- ELSE BindNodes(Nupto, DevCPT.settyp, x, y)
- END
- ELSE err(93)
- END ;
- x.typ := DevCPT.settyp
- END SetRange;
- PROCEDURE SetElem*(VAR x: DevCPT.Node);
- VAR k: INTEGER;
- BEGIN
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126) END;
- IF x.typ.form IN intSet THEN
- IF x.typ.form = Int64 THEN Convert(x, DevCPT.int32typ) END;
- IF x.class = Nconst THEN
- k := x.conval.intval;
- IF (0 <= k) & (k <= DevCPM.MaxSet) & (x.conval.realval = 0) THEN x.conval.setval := {k}
- ELSE err(202)
- END ;
- x.obj := NIL
- ELSE BindNodes(Nmop, DevCPT.settyp, x, NIL); x.subcl := bit
- END ;
- ELSE err(93)
- END;
- x.typ := DevCPT.settyp
- END SetElem;
-
- PROCEDURE CheckAssign* (x: DevCPT.Struct; VAR ynode: DevCPT.Node);
- (* x := y, checks assignment compatibility *)
- VAR f, g: SHORTINT; y, b: DevCPT.Struct;
- BEGIN
- y := ynode.typ; f := x.form; g := y.form;
- IF (ynode.class = Ntype) OR (ynode.class = Nproc) & (f # ProcTyp) THEN err(126) END ;
- CASE f OF
- | Undef, String8, String16, Byte:
- | Bool, Set:
- IF g # f THEN err(113) END
- | Int8, Int16, Int32, Int64, Real32, Real64: (* SR *)
- IF (g IN intSet) OR (g IN realSet) & (f IN realSet) THEN
- IF ynode.class = Nconst THEN Convert(ynode, x)
- ELSIF ~DevCPT.Includes(f, g) THEN err(113)
- END
- ELSE err(113)
- END
- (*
- IF ~(g IN intSet + realSet) OR ~DevCPT.Includes(f, g) & (~(g IN intSet) OR (ynode.class # Nconst)) THEN
- err(113)
- ELSIF ynode.class = Nconst THEN Convert(ynode, x)
- END
- *)
- | Char8, Char16:
- IF ~(g IN charSet) OR ~DevCPT.Includes(f, g) THEN err(113)
- ELSIF ynode.class = Nconst THEN Convert(ynode, x)
- END
- | Pointer:
- b := x.BaseTyp;
- IF DevCPT.Extends(y, x)
- OR (g = NilTyp)
- OR (g = Pointer)
- & ((x = DevCPT.sysptrtyp) OR (DevCPM.java IN DevCPM.options) & (x = DevCPT.anyptrtyp))
- THEN (* ok *)
- ELSIF (b.comp = DynArr) & b.untagged THEN (* pointer to untagged open array *)
- IF ynode.class = Nconst THEN CheckString(ynode, b, 113)
- ELSIF ~(y.comp IN {Array, DynArr}) OR ~DevCPT.EqualType(b.BaseTyp, y.BaseTyp) THEN err(113)
- END
- ELSIF b.untagged & (ynode.class = Nmop) & (ynode.subcl = adr) THEN (* p := ADR(r) *)
- IF (b.comp = DynArr) & (ynode.left.class = Nconst) THEN CheckString(ynode.left, b, 113)
- ELSIF ~DevCPT.Extends(ynode.left.typ, b) THEN err(113)
- END
- ELSIF (b.sysflag = jstr) & ((g = String16) OR (ynode.class = Nconst) & (g IN {Char8, Char16, String8}))
- THEN
- IF g # String16 THEN Convert(ynode, DevCPT.string16typ) END
- ELSE err(113)
- END
- | ProcTyp:
- IF DevCPT.EqualType(x, y) OR (g = NilTyp) THEN (* ok *)
- ELSIF (ynode.class = Nproc) & (ynode.obj.mode IN {XProc, IProc, LProc}) THEN
- IF ynode.obj.mode = LProc THEN
- IF ynode.obj.mnolev = 0 THEN ynode.obj.mode := XProc ELSE err(73) END
- END;
- IF (x.sysflag = 0) & (ynode.obj.sysflag >= 0) OR (x.sysflag = ynode.obj.sysflag) THEN
- IF DevCPT.EqualType(x.BaseTyp, ynode.obj.typ) THEN CheckParameters(x.link, ynode.obj.link, FALSE)
- ELSE err(117)
- END
- ELSE err(113)
- END
- ELSE err(113)
- END
- | NoTyp, NilTyp: err(113)
- | Comp:
- x.pvused := TRUE; (* idfp of y guarantees assignment compatibility with x *)
- IF x.comp = Record THEN
- IF ~DevCPT.EqualType(x, y) OR (x.attribute # 0) THEN err(113) END
- ELSIF g IN {Char8, Char16, String8, String16} THEN
- IF (x.BaseTyp.form = Char16) & (g = String8) THEN Convert(ynode, DevCPT.string16typ)
- ELSE CheckString(ynode, x, 113);
- END;
- IF (x # DevCPT.guidtyp) & (x.comp = Array) & (ynode.class = Nconst) & (ynode.conval.intval2 > x.n) THEN
- err(114)
- END
- ELSIF (x.comp = Array) & DevCPT.EqualType(x, y) THEN (* ok *)
- ELSE err(113)
- END
- END
- END CheckAssign;
-
- PROCEDURE AssignString (VAR x: DevCPT.Node; str: DevCPT.Node); (* x := str or x[0] := 0X *)
- BEGIN
- ASSERT((str.class = Nconst) & (str.typ.form IN {String8, String16}));
- IF (x.typ.comp IN {Array, DynArr}) & (str.conval.intval2 = 1) THEN (* x := "" -> x[0] := 0X *)
- Index(x, NewIntConst(0));
- str.typ := x.typ; str.conval.intval := 0;
- END;
- BindNodes(Nassign, DevCPT.notyp, x, str); x.subcl := assign
- END AssignString;
-
- PROCEDURE CheckLeaf(x: DevCPT.Node; dynArrToo: BOOLEAN);
- BEGIN
- IF (x.class = Nmop) & (x.subcl = val) THEN x := x.left END ;
- IF x.class = Nguard THEN x := x.left END ; (* skip last (and unique) guard *)
- IF (x.class = Nvar) & (dynArrToo OR (x.typ.comp # DynArr)) THEN x.obj.leaf := FALSE END
- END CheckLeaf;
-
- PROCEDURE CheckOldType (x: DevCPT.Node);
- BEGIN
- IF ~(DevCPM.oberon IN DevCPM.options)
- & ((x.typ = DevCPT.lreal64typ) OR (x.typ = DevCPT.lint64typ) OR (x.typ = DevCPT.lchar16typ)) THEN
- err(198)
- END
- END CheckOldType;
-
- PROCEDURE StPar0*(VAR par0: DevCPT.Node; fctno: SHORTINT); (* par0: first param of standard proc *)
- VAR f: SHORTINT; typ: DevCPT.Struct; x, t: DevCPT.Node;
- BEGIN x := par0; f := x.typ.form;
- CASE fctno OF
- haltfn: (*HALT*)
- IF (f IN intSet - {Int64}) & (x.class = Nconst) THEN
- IF (DevCPM.MinHaltNr <= x.conval.intval) & (x.conval.intval <= DevCPM.MaxHaltNr) THEN
- BindNodes(Ntrap, DevCPT.notyp, x, x)
- ELSE err(218)
- END
- ELSIF (DevCPM.java IN DevCPM.options)
- & ((x.class = Ntype) OR (x.class = Nvar))
- & (x.typ.form = Pointer)
- THEN
- BindNodes(Ntrap, DevCPT.notyp, x, x)
- ELSE err(69)
- END ;
- x.typ := DevCPT.notyp
- | newfn: (*NEW*)
- typ := DevCPT.notyp;
- IF NotVar(x) THEN err(112)
- ELSIF f = Pointer THEN
- IF DevCPM.NEWusingAdr THEN CheckLeaf(x, TRUE) END ;
- IF x.readonly THEN err(76)
- ELSIF (x.typ.BaseTyp.attribute = absAttr)
- OR (x.typ.BaseTyp.attribute = limAttr) & (x.typ.BaseTyp.mno # 0) THEN err(193)
- ELSIF (x.obj # NIL) & ODD(x.obj.sysflag DIV newBit) THEN err(167)
- END ;
- MarkAsUsed(x);
- f := x.typ.BaseTyp.comp;
- IF f IN {Record, DynArr, Array} THEN
- IF f = DynArr THEN typ := x.typ.BaseTyp END ;
- BindNodes(Nassign, DevCPT.notyp, x, NIL); x.subcl := newfn
- ELSE err(111)
- END
- ELSE err(111)
- END ;
- x.typ := typ
- | absfn: (*ABS*)
- MOp(abs, x)
- | capfn: (*CAP*)
- MOp(cap, x)
- | ordfn: (*ORD*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f = Char8 THEN Convert(x, DevCPT.int16typ)
- ELSIF f = Char16 THEN Convert(x, DevCPT.int32typ)
- ELSIF f = Set THEN Convert(x, DevCPT.int32typ)
- ELSE err(111)
- END
- | bitsfn: (*BITS*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN {Int8, Int16, Int32} THEN Convert(x, DevCPT.settyp)
- ELSE err(111)
- END
- | entierfn: (*ENTIER*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN realSet THEN Convert(x, DevCPT.int64typ)
- ELSE err(111)
- END ;
- x.typ := DevCPT.int64typ
- | lentierfcn: (* LENTIER *)
- IF ~(DevCPM.oberon IN DevCPM.options) THEN err(199) END;
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN realSet THEN Convert(x, DevCPT.int64typ)
- ELSE err(111)
- END ;
- x.typ := DevCPT.int64typ
- | oddfn: (*ODD*)
- MOp(odd, x)
- | minfn: (*MIN*)
- IF x.class = Ntype THEN
- CheckOldType(x);
- CASE f OF
- Bool: x := NewBoolConst(FALSE)
- | Char8: x := NewIntConst(0); x.typ := DevCPT.char8typ
- | Char16: x := NewIntConst(0); x.typ := DevCPT.char8typ
- | Int8: x := NewIntConst(-128)
- | Int16: x := NewIntConst(-32768)
- | Int32: x := NewIntConst(-2147483648)
- | Int64: x := NewLargeIntConst(0, -9223372036854775808.0E0) (* -2^63 *)
- | Set: x := NewIntConst(0) (*; x.typ := DevCPT.int16typ *)
- | Real32: x := NewRealConst(DevCPM.MinReal32, DevCPT.real64typ)
- | Real64: x := NewRealConst(DevCPM.MinReal64, DevCPT.real64typ)
- ELSE err(111)
- END;
- x.hint := 1
- ELSIF ~(f IN intSet + realSet + charSet) THEN err(111)
- END
- | maxfn: (*MAX*)
- IF x.class = Ntype THEN
- CheckOldType(x);
- CASE f OF
- Bool: x := NewBoolConst(TRUE)
- | Char8: x := NewIntConst(0FFH); x.typ := DevCPT.char8typ
- | Char16: x := NewIntConst(0FFFFH); x.typ := DevCPT.char16typ
- | Int8: x := NewIntConst(127)
- | Int16: x := NewIntConst(32767)
- | Int32: x := NewIntConst(2147483647)
- | Int64: x := NewLargeIntConst(-1, 9223372036854775808.0E0) (* 2^63 - 1 *)
- | Set: x := NewIntConst(31) (*; x.typ := DevCPT.int16typ *)
- | Real32: x := NewRealConst(DevCPM.MaxReal32, DevCPT.real64typ)
- | Real64: x := NewRealConst(DevCPM.MaxReal64, DevCPT.real64typ)
- ELSE err(111)
- END;
- x.hint := 1
- ELSIF ~(f IN intSet + realSet + charSet) THEN err(111)
- END
- | chrfn: (*CHR*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN {Undef, Int8..Int32, Int64} THEN Convert(x, DevCPT.char16typ)
- ELSE err(111); x.typ := DevCPT.char16typ
- END
- | lchrfn: (* LCHR *)
- IF ~(DevCPM.oberon IN DevCPM.options) THEN err(199) END;
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN {Undef, Int8..Int32, Int64} THEN Convert(x, DevCPT.char16typ)
- ELSE err(111); x.typ := DevCPT.char16typ
- END
- | shortfn: (*SHORT*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSE
- IF (x.typ.comp IN {Array, DynArr}) & (x.typ.BaseTyp.form IN charSet) THEN StrDeref(x); f := x.typ.form
- END;
- IF f = Int16 THEN Convert(x, DevCPT.int8typ)
- ELSIF f = Int32 THEN Convert(x, DevCPT.int16typ)
- ELSIF f = Int64 THEN Convert(x, DevCPT.int32typ)
- ELSIF f = Real64 THEN Convert(x, DevCPT.real32typ)
- ELSIF f = Char16 THEN Convert(x, DevCPT.char8typ)
- ELSIF f = String16 THEN Convert(x, DevCPT.string8typ)
- ELSE err(111)
- END
- END
- | longfn: (*LONG*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSE
- IF (x.typ.comp IN {Array, DynArr}) & (x.typ.BaseTyp.form IN charSet) THEN StrDeref(x); f := x.typ.form
- END;
- IF f = Int8 THEN Convert(x, DevCPT.int16typ)
- ELSIF f = Int16 THEN Convert(x, DevCPT.int32typ)
- ELSIF f = Int32 THEN Convert(x, DevCPT.int64typ)
- ELSIF f = Real32 THEN Convert(x, DevCPT.real64typ)
- ELSIF f = Char8 THEN Convert(x, DevCPT.char16typ)
- ELSIF f = String8 THEN Convert(x, DevCPT.string16typ)
- ELSE err(111)
- END
- END
- | incfn, decfn: (*INC, DEC*)
- IF NotVar(x) THEN err(112)
- ELSIF ~(f IN intSet) THEN err(111)
- ELSIF x.readonly THEN err(76)
- END;
- MarkAsUsed(x)
- | inclfn, exclfn: (*INCL, EXCL*)
- IF NotVar(x) THEN err(112)
- ELSIF f # Set THEN err(111); x.typ := DevCPT.settyp
- ELSIF x.readonly THEN err(76)
- END;
- MarkAsUsed(x)
- | lenfn: (*LEN*)
- IF (* (x.class = Ntype) OR *) (x.class = Nproc) THEN err(126) (* !!! *)
- (* ELSIF x.typ.sysflag = jstr THEN StrDeref(x) *)
- ELSE
- IF x.typ.form = Pointer THEN DeRef(x) END;
- IF x.class = Nconst THEN
- IF x.typ.form = Char8 THEN CharToString8(x)
- ELSIF x.typ.form = Char16 THEN CharToString16(x)
- END
- END;
- IF ~(x.typ.comp IN {DynArr, Array}) & ~(x.typ.form IN {String8, String16}) THEN err(131) END
- END
- | copyfn: (*COPY*)
- IF ~(DevCPM.oberon IN DevCPM.options) THEN err(199) END;
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126) END
- | ashfn: (*ASH*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN intSet THEN
- IF f < Int32 THEN Convert(x, DevCPT.int32typ) END
- ELSE err(111); x.typ := DevCPT.int32typ
- END
- | adrfn: (*ADR*)
- IF x.class = Ntype THEN CheckOldType(x) END;
- CheckLeaf(x, FALSE); MOp(adr, x)
- | typfn: (*TYP*)
- CheckLeaf(x, FALSE);
- IF x.class = Ntype THEN
- CheckOldType(x);
- IF x.typ.form = Pointer THEN x := NewLeaf(x.typ.BaseTyp.strobj) END;
- IF x.typ.comp # Record THEN err(111) END;
- MOp(adr, x)
- ELSE
- IF x.typ.form = Pointer THEN DeRef(x) END;
- IF x.typ.comp # Record THEN err(111) END;
- MOp(typfn, x)
- END
- | sizefn: (*SIZE*)
- IF x.class # Ntype THEN err(110); x := NewIntConst(1)
- ELSIF (f IN {Byte..Set, Pointer, ProcTyp, Char16, Int64}) OR (x.typ.comp IN {Array, Record}) THEN
- CheckOldType(x); x.typ.pvused := TRUE;
- IF typSize # NIL THEN
- typSize(x.typ); x := NewIntConst(x.typ.size)
- ELSE
- MOp(size, x)
- END
- ELSE err(111); x := NewIntConst(1)
- END
- | thisrecfn, (*THISRECORD*)
- thisarrfn: (*THISARRAY*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN {Int8, Int16} THEN Convert(x, DevCPT.int32typ)
- ELSIF f # Int32 THEN err(111)
- END
- | ccfn: (*SYSTEM.CC*)
- MOp(cc, x)
- | lshfn, rotfn: (*SYSTEM.LSH, SYSTEM.ROT*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF ~(f IN intSet + charSet + {Byte, Set}) THEN err(111)
- END
- | getfn, putfn, bitfn, movefn: (*SYSTEM.GET, SYSTEM.PUT, SYSTEM.BIT, SYSTEM.MOVE*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF (x.class = Nconst) & (f IN {Int8, Int16}) THEN Convert(x, DevCPT.int32typ)
- ELSIF ~(f IN {Int32, Pointer}) THEN err(111); x.typ := DevCPT.int32typ
- END
- | getrfn, putrfn: (*SYSTEM.GETREG, SYSTEM.PUTREG*)
- IF (f IN intSet) & (x.class = Nconst) THEN
- IF (x.conval.intval < DevCPM.MinRegNr) OR (x.conval.intval > DevCPM.MaxRegNr) THEN err(220)
- END
- ELSE err(69)
- END
- | valfn: (*SYSTEM.VAL*)
- IF x.class # Ntype THEN err(110)
- ELSIF (f IN {Undef, String8, String16, NoTyp, NilTyp}) (* OR (x.typ.comp = DynArr) *) THEN err(111)
- ELSE CheckOldType(x)
- END
- | assertfn: (*ASSERT*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126); x := NewBoolConst(FALSE)
- ELSIF f # Bool THEN err(120); x := NewBoolConst(FALSE)
- ELSE MOp(not, x)
- END
- | validfn: (* VALID *)
- IF (x.class = Nvarpar) & ODD(x.obj.sysflag DIV nilBit) THEN
- MOp(adr, x); x.typ := DevCPT.sysptrtyp; Op(neq, x, Nil())
- ELSE err(111)
- END;
- x.typ := DevCPT.booltyp
- | iidfn: (* COM.IID *)
- IF (x.class = Nconst) & (f = String8) THEN StringToGuid(x)
- ELSE
- typ := x.typ;
- IF typ.form = Pointer THEN typ := typ.BaseTyp END;
- IF (typ.sysflag = interface) & (typ.ext # NIL) & (typ.strobj # NIL) THEN
- IF x.obj # typ.strobj THEN x := NewLeaf(typ.strobj) END
- ELSE err(111)
- END;
- x.class := Nconst; x.typ := DevCPT.guidtyp
- END
- | queryfn: (* COM.QUERY *)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f # Pointer THEN err(111)
- END
- END ;
- par0 := x
- END StPar0;
- PROCEDURE StPar1*(VAR par0: DevCPT.Node; x: DevCPT.Node; fctno: BYTE);
- (* x: second parameter of standard proc *)
- VAR f, n, L, i: INTEGER; typ, tp1: DevCPT.Struct; p, t: DevCPT.Node;
-
- PROCEDURE NewOp(class, subcl: BYTE; left, right: DevCPT.Node): DevCPT.Node;
- VAR node: DevCPT.Node;
- BEGIN
- node := DevCPT.NewNode(class); node.subcl := subcl;
- node.left := left; node.right := right; RETURN node
- END NewOp;
-
- BEGIN p := par0; f := x.typ.form;
- CASE fctno OF
- incfn, decfn: (*INC DEC*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126); p.typ := DevCPT.notyp
- ELSE
- IF f # p.typ.form THEN
- IF f IN intSet THEN Convert(x, p.typ)
- ELSE err(111)
- END
- END ;
- p := NewOp(Nassign, fctno, p, x);
- p.typ := DevCPT.notyp
- END
- | inclfn, exclfn: (*INCL, EXCL*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN intSet THEN
- IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
- IF (x.class = Nconst) & ((0 > x.conval.intval) OR (x.conval.intval > DevCPM.MaxSet)) THEN err(202)
- END ;
- p := NewOp(Nassign, fctno, p, x)
- ELSE err(111)
- END ;
- p.typ := DevCPT.notyp
- | lenfn: (*LEN*)
- IF ~(f IN intSet) OR (x.class # Nconst) THEN err(69)
- ELSE
- IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
- L := SHORT(x.conval.intval); typ := p.typ;
- WHILE (L > 0) & (typ.comp IN {DynArr, Array}) DO typ := typ.BaseTyp; DEC(L) END ;
- IF (L # 0) OR ~(typ.comp IN {DynArr, Array}) THEN err(132)
- ELSE x.obj := NIL;
- IF typ.comp = DynArr THEN
- WHILE p.class = Nindex DO
- p := p.left; INC(x.conval.intval) (* possible side effect ignored *)
- END;
- p := NewOp(Ndop, len, p, x); p.typ := DevCPT.int32typ
- ELSE p := x; p.conval.intval := typ.n; p.typ := DevCPT.int32typ
- END
- END
- END
- | copyfn: (*COPY*)
- IF NotVar(x) THEN err(112)
- ELSIF x.readonly THEN err(76)
- ELSE
- CheckString(p, x.typ, 111); t := x; x := p; p := t;
- IF (x.class = Nconst) & (x.typ.form IN {String8, String16}) THEN AssignString(p, x)
- ELSE p := NewOp(Nassign, copyfn, p, x)
- END
- END ;
- p.typ := DevCPT.notyp; MarkAsUsed(x)
- | ashfn: (*ASH*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN intSet THEN
- IF (x.class = Nconst) & ((x.conval.intval > 64) OR (x.conval.intval < -64)) THEN err(208)
- ELSIF (p.class = Nconst) & (x.class = Nconst) THEN
- n := x.conval.intval;
- IF n > 0 THEN
- WHILE n > 0 DO MulConst(p.conval, two, p.conval, p.typ); DEC(n) END
- ELSE
- WHILE n < 0 DO DivModConst(p.conval, two, TRUE, p.typ); INC(n) END
- END;
- p.obj := NIL
- ELSE
- IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
- typ := p.typ; p := NewOp(Ndop, ash, p, x); p.typ := typ
- END
- ELSE err(111)
- END
- | minfn: (*MIN*)
- IF p.class # Ntype THEN Op(min, p, x) ELSE err(64) END
- | maxfn: (*MAX*)
- IF p.class # Ntype THEN Op(max, p, x) ELSE err(64) END
- | newfn: (*NEW(p, x...)*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF p.typ.comp = DynArr THEN
- IF f IN intSet THEN
- IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
- IF (x.class = Nconst) & (x.conval.intval <= 0)
- & (~(DevCPM.java IN DevCPM.options) OR (x.conval.intval < 0))THEN err(63) END
- ELSE err(111)
- END ;
- p.right := x; p.typ := p.typ.BaseTyp
- ELSIF (p.left # NIL) & (p.left.typ.form = Pointer) THEN
- typ := p.left.typ;
- WHILE (typ # DevCPT.undftyp) & (typ.BaseTyp # NIL) DO typ := typ.BaseTyp END;
- IF typ.sysflag = interface THEN
- typ := x.typ;
- WHILE (typ # DevCPT.undftyp) & (typ.BaseTyp # NIL) DO typ := typ.BaseTyp END;
- IF (f = Pointer) & (typ.sysflag = interface) THEN
- p.right := x
- ELSE err(169)
- END
- ELSE err(64)
- END
- ELSE err(111)
- END
- | thisrecfn, (*THISRECORD*)
- thisarrfn: (*THISARRAY*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN {Int8, Int16, Int32} THEN
- IF f < Int32 THEN Convert(x, DevCPT.int32typ) END;
- p := NewOp(Ndop, fctno, p, x); p.typ := DevCPT.undftyp
- ELSE err(111)
- END
- | lshfn, rotfn: (*SYSTEM.LSH, SYSTEM.ROT*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF ~(f IN intSet) THEN err(111)
- ELSE
- IF fctno = lshfn THEN p := NewOp(Ndop, lsh, p, x) ELSE p := NewOp(Ndop, rot, p, x) END ;
- p.typ := p.left.typ
- END
- | getfn, putfn, getrfn, putrfn: (*SYSTEM.GET, SYSTEM.PUT, SYSTEM.GETREG, SYSTEM.PUTREG*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN {Undef..Set, NilTyp, Pointer, ProcTyp, Char16, Int64} THEN
- IF (fctno = getfn) OR (fctno = getrfn) THEN
- IF NotVar(x) THEN err(112) END ;
- t := x; x := p; p := t
- END ;
- p := NewOp(Nassign, fctno, p, x)
- ELSE err(111)
- END ;
- p.typ := DevCPT.notyp
- | bitfn: (*SYSTEM.BIT*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN intSet THEN
- p := NewOp(Ndop, bit, p, x)
- ELSE err(111)
- END ;
- p.typ := DevCPT.booltyp
- | valfn: (*SYSTEM.VAL*) (* type is changed without considering the byte ordering on the target machine *)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF x.typ.comp = DynArr THEN
- IF x.typ.untagged & ((p.typ.comp # DynArr) OR p.typ.untagged) THEN (* ok *)
- ELSIF (p.typ.comp = DynArr) & (x.typ.n = p.typ.n) THEN
- typ := x.typ;
- WHILE typ.comp = DynArr DO typ := typ.BaseTyp END;
- tp1 := p.typ;
- WHILE tp1.comp = DynArr DO tp1 := tp1.BaseTyp END;
- IF typ.size # tp1.size THEN err(115) END
- ELSE err(115)
- END
- ELSIF p.typ.comp = DynArr THEN err(115)
- ELSIF (x.class = Nconst) & (f = String8) & (p.typ.form = Int32) & (x.conval.intval2 <= 5) THEN
- i := 0; n := 0;
- WHILE i < x.conval.intval2 - 1 DO n := 256 * n + ORD(x.conval.ext[i]); INC(i) END;
- x := NewIntConst(n)
- ELSIF (f IN {Undef, NoTyp, NilTyp}) OR (f IN {String8, String16}) & ~(DevCPM.java IN DevCPM.options) THEN err(111)
- END ;
- IF (x.class = Nconst) & (x.typ = p.typ) THEN (* ok *)
- ELSIF (x.class >= Nconst) OR ((f IN realSet) # (p.typ.form IN realSet))
- OR (DevCPM.options * {DevCPM.java, DevCPM.allSysVal} # {}) THEN
- t := DevCPT.NewNode(Nmop); t.subcl := val; t.left := x; x := t
- ELSE x.readonly := FALSE
- END ;
- x.typ := p.typ; p := x
- | movefn: (*SYSTEM.MOVE*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF (x.class = Nconst) & (f IN {Int8, Int16}) THEN Convert(x, DevCPT.int32typ)
- ELSIF ~(f IN {Int32, Pointer}) THEN err(111); x.typ := DevCPT.int32typ
- END ;
- p.link := x
- | assertfn: (*ASSERT*)
- IF (f IN intSet - {Int64}) & (x.class = Nconst) THEN
- IF (DevCPM.MinHaltNr <= x.conval.intval) & (x.conval.intval <= DevCPM.MaxHaltNr) THEN
- BindNodes(Ntrap, DevCPT.notyp, x, x);
- Construct(Nif, p, x); Construct(Nifelse, p, NIL); OptIf(p);
- ELSE err(218)
- END
- ELSIF
- (DevCPM.java IN DevCPM.options) & ((x.class = Ntype) OR (x.class = Nvar)) & (x.typ.form = Pointer)
- THEN
- BindNodes(Ntrap, DevCPT.notyp, x, x);
- Construct(Nif, p, x); Construct(Nifelse, p, NIL); OptIf(p);
- ELSE err(69)
- END;
- IF p = NIL THEN (* ASSERT(TRUE) *)
- ELSIF p.class = Ntrap THEN err(99)
- ELSE p.subcl := assertfn
- END
- | queryfn: (* COM.QUERY *)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF x.typ # DevCPT.guidtyp THEN err(111); x.typ := DevCPT.guidtyp
- END;
- p.link := x
- ELSE err(64)
- END ;
- par0 := p
- END StPar1;
- PROCEDURE StParN*(VAR par0: DevCPT.Node; x: DevCPT.Node; fctno, n: SHORTINT);
- (* x: n+1-th param of standard proc *)
- VAR node: DevCPT.Node; f: SHORTINT; p: DevCPT.Node; typ: DevCPT.Struct;
- BEGIN p := par0; f := x.typ.form;
- IF fctno = newfn THEN (*NEW(p, ..., x...*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF p.typ.comp # DynArr THEN err(64)
- ELSIF f IN intSet THEN
- IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
- IF (x.class = Nconst) & (x.conval.intval <= 0) THEN err(63) END;
- node := p.right; WHILE node.link # NIL DO node := node.link END;
- node.link := x; p.typ := p.typ.BaseTyp
- ELSE err(111)
- END
- ELSIF (fctno = movefn) & (n = 2) THEN (*SYSTEM.MOVE*)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF f IN intSet THEN
- node := DevCPT.NewNode(Nassign); node.subcl := movefn; node.right := p;
- node.left := p.link; p.link := x; p := node
- ELSE err(111)
- END ;
- p.typ := DevCPT.notyp
- ELSIF (fctno = queryfn) & (n = 2) THEN (* COM.QUERY *)
- IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
- ELSIF (x.class < Nconst) & (f = Pointer) & (x.typ.sysflag = interface) THEN
- IF ~DevCPT.Extends(p.typ, x.typ) THEN err(164) END;
- IF x.readonly THEN err(76) END;
- CheckNewParamPair(x, p.link);
- MarkAsUsed(x);
- node := DevCPT.NewNode(Ndop); node.subcl := queryfn;
- node.left := p; node.right := p.link; p.link := NIL; node.right.link := x; p := node
- ELSE err(111)
- END;
- p.typ := DevCPT.booltyp
- ELSE err(64)
- END ;
- par0 := p
- END StParN;
- PROCEDURE StFct*(VAR par0: DevCPT.Node; fctno: BYTE; parno: SHORTINT);
- VAR dim: SHORTINT; x, p: DevCPT.Node;
- BEGIN p := par0;
- IF fctno <= ashfn THEN
- IF (fctno = newfn) & (p.typ # DevCPT.notyp) THEN
- IF p.typ.comp = DynArr THEN err(65) END ;
- p.typ := DevCPT.notyp
- ELSIF (fctno = minfn) OR (fctno = maxfn) THEN
- IF (parno < 1) OR (parno = 1) & (p.hint # 1) THEN err(65) END;
- p.hint := 0
- ELSIF fctno <= sizefn THEN (* 1 param *)
- IF parno < 1 THEN err(65) END
- ELSE (* more than 1 param *)
- IF ((fctno = incfn) OR (fctno = decfn)) & (parno = 1) THEN (*INC, DEC*)
- BindNodes(Nassign, DevCPT.notyp, p, NewIntConst(1)); p.subcl := fctno; p.right.typ := p.left.typ
- ELSIF (fctno = lenfn) & (parno = 1) THEN (*LEN*)
- IF p.typ.form IN {String8, String16} THEN
- IF p.class = Nconst THEN p := NewIntConst(p.conval.intval2 - 1)
- ELSIF (p.class = Ndop) & (p.subcl = plus) THEN (* propagate to leaf nodes *)
- StFct(p.left, lenfn, 1); StFct(p.right, lenfn, 1); p.typ := DevCPT.int32typ
- ELSE
- WHILE (p.class = Nmop) & (p.subcl = conv) DO p := p.left END;
- IF DevCPM.errors = 0 THEN ASSERT(p.class = Nderef) END;
- BindNodes(Ndop, DevCPT.int32typ, p, NewIntConst(0)); p.subcl := len
- END
- ELSIF p.typ.comp = DynArr THEN dim := 0;
- WHILE p.class = Nindex DO p := p.left; INC(dim) END ; (* possible side effect ignored *)
- BindNodes(Ndop, DevCPT.int32typ, p, NewIntConst(dim)); p.subcl := len
- ELSE
- p := NewIntConst(p.typ.n)
- END
- ELSIF parno < 2 THEN err(65)
- END
- END
- ELSIF fctno = assertfn THEN
- IF parno = 1 THEN x := NIL;
- BindNodes(Ntrap, DevCPT.notyp, x, NewIntConst(AssertTrap));
- Construct(Nif, p, x); Construct(Nifelse, p, NIL); OptIf(p);
- IF p = NIL THEN (* ASSERT(TRUE) *)
- ELSIF p.class = Ntrap THEN err(99)
- ELSE p.subcl := assertfn
- END
- ELSIF parno < 1 THEN err(65)
- END
- ELSIF (fctno >= lchrfn) & (fctno <= bytesfn) THEN
- IF parno < 1 THEN err(65) END
- ELSIF fctno < validfn THEN (*SYSTEM*)
- IF (parno < 1) OR
- (fctno > ccfn) & (parno < 2) OR
- (fctno = movefn) & (parno < 3) THEN err(65)
- END
- ELSIF (fctno = thisrecfn) OR (fctno = thisarrfn) THEN
- IF parno < 2 THEN err(65) END
- ELSE (* COM *)
- IF fctno = queryfn THEN
- IF parno < 3 THEN err(65) END
- ELSE
- IF parno < 1 THEN err(65) END
- END
- END ;
- par0 := p
- END StFct;
-
- PROCEDURE DynArrParCheck (ftyp: DevCPT.Struct; VAR ap: DevCPT.Node; fvarpar: BOOLEAN);
- (* check array compatibility *)
- VAR atyp: DevCPT.Struct;
- BEGIN (* ftyp.comp = DynArr *)
- atyp := ap.typ;
- IF atyp.form IN {Char8, Char16, String8, String16} THEN
- IF ~fvarpar & (ftyp.BaseTyp.form = Char16) & (atyp.form = String8) THEN Convert(ap, DevCPT.string16typ)
- ELSE CheckString(ap, ftyp, 67)
- END
- ELSE
- WHILE (ftyp.comp = DynArr) & ((atyp.comp IN {Array, DynArr}) OR (atyp.form IN {String8, String16})) DO
- ftyp := ftyp.BaseTyp; atyp := atyp.BaseTyp
- END;
- IF ftyp.comp = DynArr THEN err(67)
- ELSIF ~fvarpar & (ftyp.form = Pointer) & DevCPT.Extends(atyp, ftyp) THEN (* ok *)
- ELSIF ~DevCPT.EqualType(ftyp, atyp) THEN err(66)
- END
- END
- END DynArrParCheck;
- PROCEDURE PrepCall*(VAR x: DevCPT.Node; VAR fpar: DevCPT.Object);
- BEGIN
- IF (x.obj # NIL) & (x.obj.mode IN {LProc, XProc, TProc, CProc}) THEN
- fpar := x.obj.link;
- IF x.obj.mode = TProc THEN
- IF fpar.typ.form = Pointer THEN
- IF x.left.class = Nderef THEN x.left := x.left.left (*undo DeRef*) ELSE err(71) END
- END;
- fpar := fpar.link
- END
- ELSIF (x.class # Ntype) & (x.typ # NIL) & (x.typ.form = ProcTyp) THEN
- fpar := x.typ.link
- ELSE err(121); fpar := NIL; x.typ := DevCPT.undftyp
- END
- END PrepCall;
- PROCEDURE Param* (VAR ap: DevCPT.Node; fp: DevCPT.Object); (* checks parameter compatibilty *)
- VAR at, ft: DevCPT.Struct;
- BEGIN
- at := ap.typ; ft := fp.typ;
- IF fp.ptyp # NIL THEN ft := fp.ptyp END; (* get original formal type *)
- IF ft.form # Undef THEN
- IF (ap.class = Ntype) OR (ap.class = Nproc) & (ft.form # ProcTyp) THEN err(126) END;
- IF fp.mode = VarPar THEN
- IF ODD(fp.sysflag DIV nilBit) & (at = DevCPT.niltyp) THEN (* ok *)
- ELSIF (ft.comp = Record) & ~ft.untagged & (ap.class = Ndop) & (ap.subcl = thisrecfn) THEN (* ok *)
- ELSIF (ft.comp = DynArr) & ~ft.untagged & (ft.n = 0) & (ap.class = Ndop) & (ap.subcl = thisarrfn) THEN
- (* ok *)
- ELSE
- IF fp.vis = inPar THEN
- IF (ft = DevCPT.guidtyp) & (ap.class = Nconst) & (at.form = String8) THEN
- StringToGuid(ap); at := ap.typ
- (*
- ELSIF ((at.form IN charSet + {String8, String16}) OR (at = DevCPT.guidtyp))
- & ((ap.class = Nderef) OR (ap.class = Nconst)) THEN (* ok *)
- ELSIF NotVar(ap) THEN err(122)
- *)
- END;
- IF ~NotVar(ap) THEN CheckLeaf(ap, FALSE) END
- ELSE
- IF NotVar(ap) THEN err(122)
- ELSIF ap.readonly THEN err(76)
- ELSIF (ap.obj # NIL) & ODD(ap.obj.sysflag DIV newBit) & ~ODD(fp.sysflag DIV newBit) THEN
- err(167)
- ELSE MarkAsUsed(ap); CheckLeaf(ap, FALSE)
- END
- END;
- IF ft.comp = DynArr THEN DynArrParCheck(ft, ap, fp.vis # inPar)
- ELSIF ODD(fp.sysflag DIV newBit) THEN
- IF ~DevCPT.Extends(at, ft) THEN err(123) END
- ELSIF (ft = DevCPT.sysptrtyp) & (at.form = Pointer) THEN (* ok *)
- ELSIF (fp.vis # outPar) & (ft.comp = Record) & DevCPT.Extends(at, ft) THEN (* ok *)
- ELSIF covarOut & (fp.vis = outPar) & (ft.form = Pointer) & DevCPT.Extends(ft, at) THEN (* ok *)
- ELSIF fp.vis = inPar THEN CheckAssign(ft, ap)
- ELSIF ~DevCPT.EqualType(ft, at) THEN err(123)
- END
- END
- ELSIF ft.comp = DynArr THEN DynArrParCheck(ft, ap, FALSE)
- ELSE CheckAssign(ft, ap)
- END
- END
- END Param;
-
- PROCEDURE StaticLink*(dlev: BYTE; var: BOOLEAN);
- VAR scope: DevCPT.Object;
- BEGIN
- scope := DevCPT.topScope;
- WHILE dlev > 0 DO DEC(dlev);
- INCL(scope.link.conval.setval, slNeeded);
- scope := scope.left
- END;
- IF var THEN INCL(scope.link.conval.setval, imVar) END (* !!! *)
- END StaticLink;
- PROCEDURE Call*(VAR x: DevCPT.Node; apar: DevCPT.Node; fp: DevCPT.Object);
- VAR typ: DevCPT.Struct; p: DevCPT.Node; lev: BYTE;
- BEGIN
- IF x.class = Nproc THEN typ := x.typ;
- lev := x.obj.mnolev;
- IF lev > 0 THEN StaticLink(SHORT(SHORT(DevCPT.topScope.mnolev-lev)), FALSE) END ; (* !!! *)
- IF x.obj.mode = IProc THEN err(121) END
- ELSIF (x.class = Nfield) & (x.obj.mode = TProc) THEN typ := x.typ;
- x.class := Nproc; p := x.left; x.left := NIL; p.link := apar; apar := p; fp := x.obj.link
- ELSE typ := x.typ.BaseTyp
- END ;
- BindNodes(Ncall, typ, x, apar); x.obj := fp
- END Call;
- PROCEDURE Enter*(VAR procdec: DevCPT.Node; stat: DevCPT.Node; proc: DevCPT.Object);
- VAR x: DevCPT.Node;
- BEGIN
- x := DevCPT.NewNode(Nenter); x.typ := DevCPT.notyp; x.obj := proc;
- x.left := procdec; x.right := stat; procdec := x
- END Enter;
-
- PROCEDURE Return*(VAR x: DevCPT.Node; proc: DevCPT.Object);
- VAR node: DevCPT.Node;
- BEGIN
- IF proc = NIL THEN (* return from module *)
- IF x # NIL THEN err(124) END
- ELSE
- IF x # NIL THEN CheckAssign(proc.typ, x)
- ELSIF proc.typ # DevCPT.notyp THEN err(124)
- END
- END ;
- node := DevCPT.NewNode(Nreturn); node.typ := DevCPT.notyp; node.obj := proc; node.left := x; x := node
- END Return;
- PROCEDURE Assign*(VAR x: DevCPT.Node; y: DevCPT.Node);
- VAR z: DevCPT.Node;
- BEGIN
- IF (x.class >= Nconst) OR (x.typ.form IN {String8, String16}) THEN err(56) END ;
- CheckAssign(x.typ, y);
- IF x.readonly THEN err(76)
- ELSIF (x.obj # NIL) & ODD(x.obj.sysflag DIV newBit) THEN err(167)
- END ;
- MarkAsUsed(x);
- IF (y.class = Nconst) & (y.typ.form IN {String8, String16}) & (x.typ.form # Pointer) THEN AssignString(x, y)
- ELSE BindNodes(Nassign, DevCPT.notyp, x, y); x.subcl := assign
- END
- END Assign;
-
- PROCEDURE Inittd*(VAR inittd, last: DevCPT.Node; typ: DevCPT.Struct);
- VAR node: DevCPT.Node;
- BEGIN
- node := DevCPT.NewNode(Ninittd); node.typ := typ;
- node.conval := DevCPT.NewConst(); node.conval.intval := typ.txtpos;
- IF inittd = NIL THEN inittd := node ELSE last.link := node END ;
- last := node
- END Inittd;
-
- (* handling of temporary variables for string operations *)
-
- PROCEDURE Overlap (left, right: DevCPT.Node): BOOLEAN;
- BEGIN
- IF right.class = Nconst THEN
- RETURN FALSE
- ELSIF (right.class = Ndop) & (right.subcl = plus) THEN
- RETURN Overlap(left, right.left) OR Overlap(left, right.right)
- ELSE
- WHILE right.class = Nmop DO right := right.left END;
- IF right.class = Nderef THEN right := right.left END;
- IF left.typ.BaseTyp # right.typ.BaseTyp THEN RETURN FALSE END;
- LOOP
- IF left.class = Nvarpar THEN
- WHILE (right.class = Nindex) OR (right.class = Nfield) OR (right.class = Nguard) DO
- right := right.left
- END;
- RETURN (right.class # Nvar) OR (right.obj.mnolev < left.obj.mnolev)
- ELSIF right.class = Nvarpar THEN
- WHILE (left.class = Nindex) OR (left.class = Nfield) OR (left.class = Nguard) DO left := left.left END;
- RETURN (left.class # Nvar) OR (left.obj.mnolev < right.obj.mnolev)
- ELSIF (left.class = Nvar) & (right.class = Nvar) THEN
- RETURN left.obj = right.obj
- ELSIF (left.class = Nderef) & (right.class = Nderef) THEN
- RETURN TRUE
- ELSIF (left.class = Nindex) & (right.class = Nindex) THEN
- IF (left.right.class = Nconst) & (right.right.class = Nconst)
- & (left.right.conval.intval # right.right.conval.intval) THEN RETURN FALSE END;
- left := left.left; right := right.left
- ELSIF (left.class = Nfield) & (right.class = Nfield) THEN
- IF left.obj # right.obj THEN RETURN FALSE END;
- left := left.left; right := right.left;
- WHILE left.class = Nguard DO left := left.left END;
- WHILE right.class = Nguard DO right := right.left END
- ELSE
- RETURN FALSE
- END
- END
- END
- END Overlap;
- PROCEDURE GetStaticLength (n: DevCPT.Node; OUT length: INTEGER);
- VAR x: INTEGER;
- BEGIN
- IF n.class = Nconst THEN
- length := n.conval.intval2 - 1
- ELSIF (n.class = Ndop) & (n.subcl = plus) THEN
- GetStaticLength(n.left, length); GetStaticLength(n.right, x);
- IF (length >= 0) & (x >= 0) THEN length := length + x ELSE length := -1 END
- ELSE
- WHILE (n.class = Nmop) & (n.subcl = conv) DO n := n.left END;
- IF (n.class = Nderef) & (n.subcl = 1) THEN n := n.left END;
- IF n.typ.comp = Array THEN
- length := n.typ.n - 1
- ELSIF n.typ.comp = DynArr THEN
- length := -1
- ELSE (* error case *)
- length := 4
- END
- END
- END GetStaticLength;
- PROCEDURE GetMaxLength (n: DevCPT.Node; VAR stat, last: DevCPT.Node; OUT length: DevCPT.Node);
- VAR x: DevCPT.Node; d: INTEGER; obj: DevCPT.Object;
- BEGIN
- IF n.class = Nconst THEN
- length := NewIntConst(n.conval.intval2 - 1)
- ELSIF (n.class = Ndop) & (n.subcl = plus) THEN
- GetMaxLength(n.left, stat, last, length); GetMaxLength(n.right, stat, last, x);
- IF (length.class = Nconst) & (x.class = Nconst) THEN ConstOp(plus, length, x)
- ELSE BindNodes(Ndop, length.typ, length, x); length.subcl := plus
- END
- ELSE
- WHILE (n.class = Nmop) & (n.subcl = conv) DO n := n.left END;
- IF (n.class = Nderef) & (n.subcl = 1) THEN n := n.left END;
- IF n.typ.comp = Array THEN
- length := NewIntConst(n.typ.n - 1)
- ELSIF n.typ.comp = DynArr THEN
- d := 0;
- WHILE n.class = Nindex DO n := n.left; INC(d) END;
- ASSERT((n.class = Nderef) OR (n.class = Nvar) OR (n.class = Nvarpar));
- IF (n.class = Nderef) & (n.left.class # Nvar) & (n.left.class # Nvarpar) THEN
- GetTempVar("@tmp", n.left.typ, obj);
- x := NewLeaf(obj); Assign(x, n.left); Link(stat, last, x);
- n.left := NewLeaf(obj); (* tree is manipulated here *)
- n := NewLeaf(obj); DeRef(n)
- END;
- IF n.typ.untagged & (n.typ.comp = DynArr) & (n.typ.BaseTyp.form IN {Char8, Char16}) THEN
- StrDeref(n);
- BindNodes(Ndop, DevCPT.int32typ, n, NewIntConst(d)); n.subcl := len;
- BindNodes(Ndop, DevCPT.int32typ, n, NewIntConst(1)); n.subcl := plus
- ELSE
- BindNodes(Ndop, DevCPT.int32typ, n, NewIntConst(d)); n.subcl := len;
- END;
- length := n
- ELSE (* error case *)
- length := NewIntConst(4)
- END
- END
- END GetMaxLength;
- PROCEDURE CheckBuffering* (
- VAR n: DevCPT.Node; left: DevCPT.Node; par: DevCPT.Object; VAR stat, last: DevCPT.Node
- );
- VAR length, x: DevCPT.Node; obj: DevCPT.Object; typ: DevCPT.Struct; len, xlen: INTEGER;
- BEGIN
- IF (n.typ.form IN {String8, String16}) & ~(DevCPM.java IN DevCPM.options)
- & ((n.class = Ndop) & (n.subcl = plus) & ((left = NIL) OR Overlap(left, n.right))
- OR (n.class = Nmop) & (n.subcl = conv) & (left = NIL)
- OR (par # NIL) & (par.vis = inPar) & (par.typ.comp = Array)) THEN
- IF (par # NIL) & (par.typ.comp = Array) THEN
- len := par.typ.n - 1
- ELSE
- IF left # NIL THEN GetStaticLength(left, len) ELSE len := -1 END;
- GetStaticLength(n, xlen);
- IF (len = -1) OR (xlen # -1) & (xlen < len) THEN len := xlen END
- END;
- IF len # -1 THEN
- typ := DevCPT.NewStr(Comp, Array); typ.n := len + 1; typ.BaseTyp := n.typ.BaseTyp;
- GetTempVar("@str", typ, obj);
- x := NewLeaf(obj); Assign(x, n); Link(stat, last, x);
- n := NewLeaf(obj)
- ELSE
- IF left # NIL THEN GetMaxLength(left, stat, last, length)
- ELSE GetMaxLength(n, stat, last, length)
- END;
- typ := DevCPT.NewStr(Pointer, Basic);
- typ.BaseTyp := DevCPT.NewStr(Comp, DynArr); typ.BaseTyp.BaseTyp := n.typ.BaseTyp;
- GetTempVar("@ptr", typ, obj);
- x := NewLeaf(obj); Construct(Nassign, x, length); x.subcl := newfn; Link(stat, last, x);
- x := NewLeaf(obj); DeRef(x); Assign(x, n); Link(stat, last, x);
- n := NewLeaf(obj); DeRef(n)
- END;
- StrDeref(n)
- ELSIF (n.typ.form = Pointer) & (n.typ.sysflag = interface) & (left = NIL)
- & ((par # NIL) OR (n.class = Ncall))
- & ((n.class # Nvar) OR (n.obj.mnolev <= 0)) THEN
- GetTempVar("@cip", DevCPT.punktyp, obj);
- x := NewLeaf(obj); Assign(x, n); Link(stat, last, x);
- n := NewLeaf(obj)
- END
- END CheckBuffering;
-
- PROCEDURE CheckVarParBuffering* (VAR n: DevCPT.Node; VAR stat, last: DevCPT.Node);
- VAR x: DevCPT.Node; obj: DevCPT.Object;
- BEGIN
- IF (n.class # Nvar) OR (n.obj.mnolev <= 0) THEN
- GetTempVar("@ptr", n.typ, obj);
- x := NewLeaf(obj); Assign(x, n); Link(stat, last, x);
- n := NewLeaf(obj)
- END
- END CheckVarParBuffering;
-
- (* case optimization *)
- PROCEDURE Evaluate (n: DevCPT.Node; VAR min, max, num, dist: INTEGER; VAR head: DevCPT.Node);
- VAR a: INTEGER;
- BEGIN
- IF n.left # NIL THEN
- a := MIN(INTEGER); Evaluate(n.left, min, a, num, dist, head);
- IF n.conval.intval - a > dist THEN dist := n.conval.intval - a; head := n END
- ELSIF n.conval.intval < min THEN
- min := n.conval.intval
- END;
- IF n.right # NIL THEN
- a := MAX(INTEGER); Evaluate(n.right, a, max, num, dist, head);
- IF a - n.conval.intval2 > dist THEN dist := a - n.conval.intval2; head := n END
- ELSIF n.conval.intval2 > max THEN
- max := n.conval.intval2
- END;
- INC(num);
- IF n.conval.intval < n.conval.intval2 THEN
- INC(num);
- IF n.conval.intval2 - n.conval.intval > dist THEN dist := n.conval.intval2 - n.conval.intval; head := n END
- END
- END Evaluate;
-
- PROCEDURE Rebuild (VAR root: DevCPT.Node; head: DevCPT.Node);
- VAR n: DevCPT.Node;
- BEGIN
- IF root # head THEN
- IF head.conval.intval2 < root.conval.intval THEN
- Rebuild(root.left, head);
- root.left := head.right; head.right := root; root := head
- ELSE
- Rebuild(root.right, head);
- root.right := head.left; head.left := root; root := head
- END
- END
- END Rebuild;
-
- PROCEDURE OptimizeCase* (VAR n: DevCPT.Node);
- VAR min, max, num, dist, limit: INTEGER; head: DevCPT.Node;
- BEGIN
- IF n # NIL THEN
- min := MAX(INTEGER); max := MIN(INTEGER); num := 0; dist := 0; head := n;
- Evaluate(n, min, max, num, dist, head);
- limit := 6 * num;
- IF limit < 100 THEN limit := 100 END;
- IF (num > 4) & ((min > MAX(INTEGER) - limit) OR (max < min + limit)) THEN
- INCL(n.conval.setval, useTable)
- ELSE
- IF num > 4 THEN Rebuild(n, head) END;
- INCL(n.conval.setval, useTree);
- OptimizeCase(n.left);
- OptimizeCase(n.right)
- END
- END
- END OptimizeCase;
- (*
- PROCEDURE ShowTree (n: DevCPT.Node; opts: SET);
- BEGIN
- IF n # NIL THEN
- IF opts = {} THEN opts := n.conval.setval END;
- IF useTable IN opts THEN
- IF n.left # NIL THEN ShowTree(n.left, opts); DevCPM.LogW(",") END;
- DevCPM.LogWNum(n.conval.intval, 1);
- IF n.conval.intval2 > n.conval.intval THEN DevCPM.LogW("-"); DevCPM.LogWNum(n.conval.intval2, 1)
- END;
- IF n.right # NIL THEN DevCPM.LogW(","); ShowTree(n.right, opts) END
- ELSIF useTree IN opts THEN
- DevCPM.LogW("("); ShowTree(n.left, {}); DevCPM.LogW("|"); DevCPM.LogWNum(n.conval.intval, 1);
- IF n.conval.intval2 > n.conval.intval THEN DevCPM.LogW("-"); DevCPM.LogWNum(n.conval.intval2, 1)
- END;
- DevCPM.LogW("|"); ShowTree(n.right, {}); DevCPM.LogW(")")
- ELSE
- ShowTree(n.left, opts); DevCPM.LogW(" "); DevCPM.LogWNum(n.conval.intval, 1);
- IF n.conval.intval2 > n.conval.intval THEN DevCPM.LogW("-"); DevCPM.LogWNum(n.conval.intval2, 1)
- END;
- DevCPM.LogW(" "); ShowTree(n.right, opts)
- END
- END
- END ShowTree;
- *)
- BEGIN
- zero := DevCPT.NewConst(); zero.intval := 0; zero.realval := 0;
- one := DevCPT.NewConst(); one.intval := 1; one.realval := 0;
- two := DevCPT.NewConst(); two.intval := 2; two.realval := 0;
- dummy := DevCPT.NewConst();
- quot := DevCPT.NewConst()
- END Dev0CPB.
|