2
0

CPB.txt 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251
  1. MODULE Dev0CPB;
  2. (* THIS IS TEXT COPY OF CPB.odc *)
  3. (* DO NOT EDIT *)
  4. (**
  5. project = "BlackBox"
  6. organization = "www.oberon.ch"
  7. contributors = "Oberon microsystems, Robert Campbell"
  8. version = "System/Rsrc/About"
  9. copyright = "System/Rsrc/About"
  10. license = "Docu/BB-License"
  11. references = "ftp://ftp.inf.ethz.ch/pub/software/Oberon/OberonV4/Docu/OP2.Paper.ps"
  12. changes = ""
  13. issues = ""
  14. **)
  15. IMPORT DevCPT := Dev0CPT, DevCPM := Dev0CPM;
  16. CONST
  17. (* symbol values or ops *)
  18. times = 1; slash = 2; div = 3; mod = 4;
  19. and = 5; plus = 6; minus = 7; or = 8; eql = 9;
  20. neq = 10; lss = 11; leq = 12; gtr = 13; geq = 14;
  21. in = 15; is = 16; ash = 17; msk = 18; len = 19;
  22. conv = 20; abs = 21; cap = 22; odd = 23; not = 33;
  23. (*SYSTEM*)
  24. adr = 24; cc = 25; bit = 26; lsh = 27; rot = 28; val = 29;
  25. min = 34; max = 35; typfn = 36; size = 37;
  26. (* object modes *)
  27. Var = 1; VarPar = 2; Con = 3; Fld = 4; Typ = 5; LProc = 6; XProc = 7;
  28. SProc = 8; CProc = 9; IProc = 10; Mod = 11; Head = 12; TProc = 13;
  29. (* Structure forms *)
  30. Undef = 0; Byte = 1; Bool = 2; Char8 = 3; Int8 = 4; Int16 = 5; Int32 = 6;
  31. Real32 = 7; Real64 = 8; Set = 9; String8 = 10; NilTyp = 11; NoTyp = 12;
  32. Pointer = 13; ProcTyp = 14; Comp = 15;
  33. Char16 = 16; String16 = 17; Int64 = 18;
  34. intSet = {Int8..Int32, Int64}; realSet = {Real32, Real64}; charSet = {Char8, Char16};
  35. (* composite structure forms *)
  36. Basic = 1; Array = 2; DynArr = 3; Record = 4;
  37. (* nodes classes *)
  38. Nvar = 0; Nvarpar = 1; Nfield = 2; Nderef = 3; Nindex = 4; Nguard = 5; Neguard = 6;
  39. Nconst = 7; Ntype = 8; Nproc = 9; Nupto = 10; Nmop = 11; Ndop = 12; Ncall = 13;
  40. Ninittd = 14; Nif = 15; Ncaselse = 16; Ncasedo = 17; Nenter = 18; Nassign = 19;
  41. Nifelse = 20; Ncase = 21; Nwhile = 22; Nrepeat = 23; Nloop = 24; Nexit = 25;
  42. Nreturn = 26; Nwith = 27; Ntrap = 28;
  43. (*function number*)
  44. assign = 0;
  45. haltfn = 0; newfn = 1; absfn = 2; capfn = 3; ordfn = 4;
  46. entierfn = 5; oddfn = 6; minfn = 7; maxfn = 8; chrfn = 9;
  47. shortfn = 10; longfn = 11; sizefn = 12; incfn = 13; decfn = 14;
  48. inclfn = 15; exclfn = 16; lenfn = 17; copyfn = 18; ashfn = 19; assertfn = 32;
  49. lchrfn = 33; lentierfcn = 34; bitsfn = 37; bytesfn = 38;
  50. (*SYSTEM function number*)
  51. adrfn = 20; ccfn = 21; lshfn = 22; rotfn = 23;
  52. getfn = 24; putfn = 25; getrfn = 26; putrfn = 27;
  53. bitfn = 28; valfn = 29; sysnewfn = 30; movefn = 31;
  54. thisrecfn = 45; thisarrfn = 46;
  55. (* COM function number *)
  56. validfn = 40; iidfn = 41; queryfn = 42;
  57. (* module visibility of objects *)
  58. internal = 0; external = 1; externalR = 2; inPar = 3; outPar = 4;
  59. (* procedure flags (conval.setval) *)
  60. hasBody = 1; isRedef = 2; slNeeded = 3; imVar = 4;
  61. (* attribute flags (attr.adr, struct.attribute, proc.conval.setval)*)
  62. newAttr = 16; absAttr = 17; limAttr = 18; empAttr = 19; extAttr = 20;
  63. (* case statement flags (conval.setval) *)
  64. useTable = 1; useTree = 2;
  65. (* sysflags *)
  66. nilBit = 1; inBit = 2; outBit = 4; newBit = 8; iidBit = 16; interface = 10; jint = -11; jstr = -13;
  67. AssertTrap = 0; (* default trap number *)
  68. covarOut = FALSE;
  69. VAR
  70. typSize*: PROCEDURE(typ: DevCPT.Struct);
  71. zero, one, two, dummy, quot: DevCPT.Const;
  72. PROCEDURE err(n: SHORTINT);
  73. BEGIN DevCPM.err(n)
  74. END err;
  75. PROCEDURE NewLeaf*(obj: DevCPT.Object): DevCPT.Node;
  76. VAR node: DevCPT.Node; typ: DevCPT.Struct;
  77. BEGIN
  78. typ := obj.typ;
  79. CASE obj.mode OF
  80. Var:
  81. node := DevCPT.NewNode(Nvar); node.readonly := (obj.vis = externalR) & (obj.mnolev < 0)
  82. | VarPar:
  83. node := DevCPT.NewNode(Nvarpar); node.readonly := obj.vis = inPar;
  84. | Con:
  85. node := DevCPT.NewNode(Nconst); node.conval := DevCPT.NewConst();
  86. node.conval^ := obj.conval^ (* string is not copied, only its ref *)
  87. | Typ:
  88. node := DevCPT.NewNode(Ntype)
  89. | LProc..IProc, TProc:
  90. node := DevCPT.NewNode(Nproc)
  91. ELSE err(127); node := DevCPT.NewNode(Nvar); typ := DevCPT.notyp
  92. END ;
  93. node.obj := obj; node.typ := typ;
  94. RETURN node
  95. END NewLeaf;
  96. PROCEDURE Construct*(class: BYTE; VAR x: DevCPT.Node; y: DevCPT.Node);
  97. VAR node: DevCPT.Node;
  98. BEGIN
  99. node := DevCPT.NewNode(class); node.typ := DevCPT.notyp;
  100. node.left := x; node.right := y; x := node
  101. END Construct;
  102. PROCEDURE Link*(VAR x, last: DevCPT.Node; y: DevCPT.Node);
  103. BEGIN
  104. IF x = NIL THEN x := y ELSE last.link := y END ;
  105. WHILE y.link # NIL DO y := y.link END ;
  106. last := y
  107. END Link;
  108. PROCEDURE BoolToInt(b: BOOLEAN): INTEGER;
  109. BEGIN
  110. IF b THEN RETURN 1 ELSE RETURN 0 END
  111. END BoolToInt;
  112. PROCEDURE IntToBool(i: INTEGER): BOOLEAN;
  113. BEGIN
  114. IF i = 0 THEN RETURN FALSE ELSE RETURN TRUE END
  115. END IntToBool;
  116. PROCEDURE NewBoolConst*(boolval: BOOLEAN): DevCPT.Node;
  117. VAR x: DevCPT.Node;
  118. BEGIN
  119. x := DevCPT.NewNode(Nconst); x.typ := DevCPT.booltyp;
  120. x.conval := DevCPT.NewConst(); x.conval.intval := BoolToInt(boolval); RETURN x
  121. END NewBoolConst;
  122. PROCEDURE OptIf*(VAR x: DevCPT.Node); (* x.link = NIL *)
  123. VAR if, pred: DevCPT.Node;
  124. BEGIN
  125. if := x.left;
  126. WHILE if.left.class = Nconst DO
  127. IF IntToBool(if.left.conval.intval) THEN x := if.right; RETURN
  128. ELSIF if.link = NIL THEN x := x.right; RETURN
  129. ELSE if := if.link; x.left := if
  130. END
  131. END ;
  132. pred := if; if := if.link;
  133. WHILE if # NIL DO
  134. IF if.left.class = Nconst THEN
  135. IF IntToBool(if.left.conval.intval) THEN
  136. pred.link := NIL; x.right := if.right; RETURN
  137. ELSE if := if.link; pred.link := if
  138. END
  139. ELSE pred := if; if := if.link
  140. END
  141. END
  142. END OptIf;
  143. PROCEDURE Nil*(): DevCPT.Node;
  144. VAR x: DevCPT.Node;
  145. BEGIN
  146. x := DevCPT.NewNode(Nconst); x.typ := DevCPT.niltyp;
  147. x.conval := DevCPT.NewConst(); x.conval.intval := 0; RETURN x
  148. END Nil;
  149. PROCEDURE EmptySet*(): DevCPT.Node;
  150. VAR x: DevCPT.Node;
  151. BEGIN
  152. x := DevCPT.NewNode(Nconst); x.typ := DevCPT.settyp;
  153. x.conval := DevCPT.NewConst(); x.conval.setval := {}; RETURN x
  154. END EmptySet;
  155. PROCEDURE MarkAsUsed (node: DevCPT.Node);
  156. VAR c: BYTE;
  157. BEGIN
  158. c := node.class;
  159. WHILE (c = Nfield) OR (c = Nindex) OR (c = Nguard) OR (c = Neguard) DO node := node.left; c := node.class END;
  160. IF (c = Nvar) & (node.obj.mnolev > 0) THEN node.obj.used := TRUE END
  161. END MarkAsUsed;
  162. PROCEDURE GetTempVar* (name: ARRAY OF SHORTCHAR; typ: DevCPT.Struct; VAR obj: DevCPT.Object);
  163. VAR n: DevCPT.Name; o: DevCPT.Object;
  164. BEGIN
  165. n := "@@ "; DevCPT.Insert(n, obj); obj.name^ := name$; (* avoid err 1 *)
  166. obj.mode := Var; obj.typ := typ;
  167. o := DevCPT.topScope.scope;
  168. IF o = NIL THEN DevCPT.topScope.scope := obj
  169. ELSE
  170. WHILE o.link # NIL DO o := o.link END;
  171. o.link := obj
  172. END
  173. END GetTempVar;
  174. (* ---------- constant operations ---------- *)
  175. PROCEDURE Log (x: DevCPT.Node): INTEGER;
  176. VAR val, exp: INTEGER;
  177. BEGIN
  178. exp := 0;
  179. IF x.typ.form = Int64 THEN
  180. RETURN -1
  181. ELSE
  182. val := x.conval.intval;
  183. IF val > 0 THEN
  184. WHILE ~ODD(val) DO val := val DIV 2; INC(exp) END
  185. END;
  186. IF val # 1 THEN exp := -1 END
  187. END;
  188. RETURN exp
  189. END Log;
  190. PROCEDURE Floor (x: REAL): REAL;
  191. VAR y: REAL;
  192. BEGIN
  193. IF ABS(x) > 9007199254740992.0 (* 2^53 *) THEN RETURN x
  194. ELSIF (x >= MAX(INTEGER) + 1.0) OR (x < MIN(INTEGER)) THEN
  195. y := Floor(x / (MAX(INTEGER) + 1.0)) * (MAX(INTEGER) + 1.0);
  196. RETURN SHORT(ENTIER(x - y)) + y
  197. ELSE RETURN SHORT(ENTIER(x))
  198. END
  199. END Floor;
  200. PROCEDURE SetToInt (s: SET): INTEGER;
  201. VAR x, i: INTEGER;
  202. BEGIN
  203. i := 31; x := 0;
  204. IF 31 IN s THEN x := -1 END;
  205. WHILE i > 0 DO
  206. x := x * 2; DEC(i);
  207. IF i IN s THEN INC(x) END
  208. END;
  209. RETURN x
  210. END SetToInt;
  211. PROCEDURE IntToSet (x: INTEGER): SET;
  212. VAR i: INTEGER; s: SET;
  213. BEGIN
  214. i := 0; s := {};
  215. WHILE i < 32 DO
  216. IF ODD(x) THEN INCL(s, i) END;
  217. x := x DIV 2; INC(i)
  218. END;
  219. RETURN s
  220. END IntToSet;
  221. PROCEDURE GetConstType (x: DevCPT.Const; form: INTEGER; errno: SHORTINT; VAR typ: DevCPT.Struct);
  222. CONST MAXL = 9223372036854775808.0; (* 2^63 *)
  223. BEGIN
  224. IF (form IN intSet + charSet) & (x.realval + x.intval >= MIN(INTEGER))
  225. & (x.realval + x.intval <= MAX(INTEGER)) THEN
  226. x.intval := SHORT(ENTIER(x.realval + x.intval)); x.realval := 0
  227. END;
  228. IF form IN intSet THEN
  229. IF x.realval = 0 THEN typ := DevCPT.int32typ
  230. ELSIF (x.intval >= -MAXL - x.realval) & (x.intval < MAXL - x.realval) THEN typ := DevCPT.int64typ
  231. ELSE err(errno); x.intval := 1; x.realval := 0; typ := DevCPT.int32typ
  232. END
  233. ELSIF form IN realSet THEN (* SR *)
  234. typ := DevCPT.real64typ
  235. ELSIF form IN charSet THEN
  236. IF x.intval <= 255 THEN typ := DevCPT.char8typ
  237. ELSE typ := DevCPT.char16typ
  238. END
  239. ELSE typ := DevCPT.undftyp
  240. END
  241. END GetConstType;
  242. PROCEDURE CheckConstType (x: DevCPT.Const; form: INTEGER; errno: SHORTINT);
  243. VAR type: DevCPT.Struct;
  244. BEGIN
  245. GetConstType(x, form, errno, type);
  246. IF ~DevCPT.Includes(form, type.form)
  247. & ((form # Int8) OR (x.realval # 0) OR (x.intval < -128) OR (x.intval > 127))
  248. & ((form # Int16) OR (x.realval # 0) OR (x.intval < -32768) OR (x.intval > 32767))
  249. & ((form # Real32) OR (ABS(x.realval) > DevCPM.MaxReal32) & (ABS(x.realval) # DevCPM.InfReal)) THEN
  250. err(errno); x.intval := 1; x.realval := 0
  251. END
  252. (*
  253. IF (form IN intSet + charSet) & (x.realval + x.intval >= MIN(INTEGER))
  254. & (x.realval + x.intval <= MAX(INTEGER)) THEN
  255. x.intval := SHORT(ENTIER(x.realval + x.intval)); x.realval := 0
  256. END;
  257. IF (form = Int64) & ((x.intval < -MAXL - x.realval) OR (x.intval >= MAXL - x.realval))
  258. OR (form = Int32) & (x.realval # 0)
  259. OR (form = Int16) & ((x.realval # 0) OR (x.intval < -32768) OR (x.intval > 32767))
  260. OR (form = Int8) & ((x.realval # 0) OR (x.intval < -128) OR (x.intval > 127))
  261. OR (form = Char16) & ((x.realval # 0) OR (x.intval < 0) OR (x.intval > 65535))
  262. OR (form = Char8) & ((x.realval # 0) OR (x.intval < 0) OR (x.intval > 255))
  263. OR (form = Real32) & (ABS(x.realval) > DevCPM.MaxReal32) & (ABS(x.realval) # DevCPM.InfReal) THEN
  264. err(errno); x.intval := 1; x.realval := 0
  265. END
  266. *)
  267. END CheckConstType;
  268. PROCEDURE ConvConst (x: DevCPT.Const; from, to: INTEGER);
  269. VAR sr: SHORTREAL;
  270. BEGIN
  271. IF from = Set THEN
  272. x.intval := SetToInt(x.setval); x.realval := 0; x.setval := {};
  273. ELSIF from IN intSet + charSet THEN
  274. IF to = Set THEN CheckConstType(x, Int32, 203); x.setval := IntToSet(x.intval)
  275. ELSIF to IN intSet THEN CheckConstType(x, to, 203)
  276. ELSIF to IN realSet THEN x.realval := x.realval + x.intval; x.intval := DevCPM.ConstNotAlloc
  277. ELSE (*to IN charSet*) CheckConstType(x, to, 220)
  278. END
  279. ELSIF from IN realSet THEN
  280. IF to IN realSet THEN CheckConstType(x, to, 203);
  281. IF to = Real32 THEN sr := SHORT(x.realval); x.realval := sr END (* reduce precision *)
  282. ELSE x.realval := Floor(x.realval); x.intval := 0; CheckConstType(x, to, 203)
  283. END
  284. END
  285. END ConvConst;
  286. PROCEDURE Prepare (x: DevCPT.Const);
  287. VAR r: REAL;
  288. BEGIN
  289. x.realval := x.realval + x.intval DIV 32768 * 32768;
  290. x.intval := x.intval MOD 32768;
  291. r := Floor(x.realval / 4096) * 4096;
  292. x.intval := x.intval + SHORT(ENTIER(x.realval - r));
  293. x.realval := r
  294. (* ABS(x.intval) < 2^15 & ABS(x.realval) MOD 2^12 = 0 *)
  295. END Prepare;
  296. PROCEDURE AddConst (x, y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := x + y *)
  297. BEGIN
  298. IF type.form IN intSet THEN
  299. Prepare(x); Prepare(y);
  300. z.intval := x.intval + y.intval; z.realval := x.realval + y.realval
  301. ELSIF type.form IN realSet THEN
  302. IF (ABS(x.realval) = DevCPM.InfReal) & (x.realval = - y.realval) THEN err(212)
  303. ELSE z.realval := x.realval + y.realval
  304. END
  305. ELSE HALT(100)
  306. END;
  307. GetConstType(z, type.form, 206, type)
  308. END AddConst;
  309. PROCEDURE NegateConst (y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := - y *)
  310. BEGIN
  311. IF type.form IN intSet THEN Prepare(y); z.intval := -y.intval; z.realval := -y.realval
  312. ELSIF type.form IN realSet THEN z.realval := -y.realval
  313. ELSE HALT(100)
  314. END;
  315. GetConstType(z, type.form, 207, type)
  316. END NegateConst;
  317. PROCEDURE SubConst (x, y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := x - y *)
  318. BEGIN
  319. IF type.form IN intSet THEN
  320. Prepare(x); Prepare(y);
  321. z.intval := x.intval - y.intval; z.realval := x.realval - y.realval
  322. ELSIF type.form IN realSet THEN
  323. IF (ABS(x.realval) = DevCPM.InfReal) & (x.realval = y.realval) THEN err(212)
  324. ELSE z.realval := x.realval - y.realval
  325. END
  326. ELSE HALT(100)
  327. END;
  328. GetConstType(z, type.form, 207, type)
  329. END SubConst;
  330. PROCEDURE MulConst (x, y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := x * y *)
  331. BEGIN
  332. IF type.form IN intSet THEN
  333. Prepare(x); Prepare(y);
  334. z.realval := x.realval * y.realval + x.intval * y.realval + x.realval * y.intval;
  335. z.intval := x.intval * y.intval
  336. ELSIF type.form IN realSet THEN
  337. IF (ABS(x.realval) = DevCPM.InfReal) & ( y.realval = 0.0) THEN err(212)
  338. ELSIF (ABS(y.realval) = DevCPM.InfReal) & (x.realval = 0.0) THEN err(212)
  339. ELSE z.realval := x.realval * y.realval
  340. END
  341. ELSE HALT(100)
  342. END;
  343. GetConstType(z, type.form, 204, type)
  344. END MulConst;
  345. PROCEDURE DivConst (x, y, z: DevCPT.Const; VAR type: DevCPT.Struct); (* z := x / y *)
  346. BEGIN
  347. IF type.form IN realSet THEN
  348. IF (x.realval = 0.0) & (y.realval = 0.0) THEN err(212)
  349. ELSIF (ABS(x.realval) = DevCPM.InfReal) & (ABS(y.realval) = DevCPM.InfReal) THEN err(212)
  350. ELSE z.realval := x.realval / y.realval
  351. END
  352. ELSE HALT(100)
  353. END;
  354. GetConstType(z, type.form, 204, type)
  355. END DivConst;
  356. PROCEDURE DivModConst (x, y: DevCPT.Const; div: BOOLEAN; VAR type: DevCPT.Struct);
  357. (* x := x DIV y | x MOD y *)
  358. BEGIN
  359. IF type.form IN intSet THEN
  360. IF y.realval + y.intval # 0 THEN
  361. Prepare(x); Prepare(y);
  362. quot.realval := Floor((x.realval + x.intval) / (y.realval + y.intval));
  363. quot.intval := 0; Prepare(quot);
  364. x.realval := x.realval - quot.realval * y.realval - quot.realval * y.intval - quot.intval * y.realval;
  365. x.intval := x.intval - quot.intval * y.intval;
  366. IF y.realval + y.intval > 0 THEN
  367. WHILE x.realval + x.intval > 0 DO SubConst(x, y, x, type); INC(quot.intval) END;
  368. WHILE x.realval + x.intval < 0 DO AddConst(x, y, x, type); DEC(quot.intval) END
  369. ELSE
  370. WHILE x.realval + x.intval < 0 DO SubConst(x, y, x, type); INC(quot.intval) END;
  371. WHILE x.realval + x.intval > 0 DO AddConst(x, y, x, type); DEC(quot.intval) END
  372. END;
  373. IF div THEN x.realval := quot.realval; x.intval := quot.intval END;
  374. GetConstType(x, type.form, 204, type)
  375. ELSE err(205)
  376. END
  377. ELSE HALT(100)
  378. END
  379. END DivModConst;
  380. PROCEDURE EqualConst (x, y: DevCPT.Const; form: INTEGER): BOOLEAN; (* x = y *)
  381. VAR res: BOOLEAN;
  382. BEGIN
  383. CASE form OF
  384. | Undef: res := TRUE
  385. | Bool, Byte, Char8..Int32, Char16: res := x.intval = y.intval
  386. | Int64: Prepare(x); Prepare(y); res := (x.realval - y.realval) + (x.intval - y.intval) = 0
  387. | Real32, Real64: res := x.realval = y.realval
  388. | Set: res := x.setval = y.setval
  389. | String8, String16, Comp (* guid *): res := x.ext^ = y.ext^
  390. | NilTyp, Pointer, ProcTyp: res := x.intval = y.intval
  391. END;
  392. RETURN res
  393. END EqualConst;
  394. PROCEDURE LessConst (x, y: DevCPT.Const; form: INTEGER): BOOLEAN; (* x < y *)
  395. VAR res: BOOLEAN;
  396. BEGIN
  397. CASE form OF
  398. | Undef: res := TRUE
  399. | Byte, Char8..Int32, Char16: res := x.intval < y.intval
  400. | Int64: Prepare(x); Prepare(y); res := (x.realval - y.realval) + (x.intval - y.intval) < 0
  401. | Real32, Real64: res := x.realval < y.realval
  402. | String8, String16: res := x.ext^ < y.ext^
  403. | Bool, Set, NilTyp, Pointer, ProcTyp, Comp: err(108)
  404. END;
  405. RETURN res
  406. END LessConst;
  407. PROCEDURE IsNegConst (x: DevCPT.Const; form: INTEGER): BOOLEAN; (* x < 0 OR x = (-0.0) *)
  408. VAR res: BOOLEAN;
  409. BEGIN
  410. CASE form OF
  411. | Int8..Int32: res := x.intval < 0
  412. | Int64: Prepare(x); res := x.realval + x.intval < 0
  413. | Real32, Real64: res := (x.realval <= 0.) & (1. / x.realval <= 0.)
  414. END;
  415. RETURN res
  416. END IsNegConst;
  417. PROCEDURE NewIntConst*(intval: INTEGER): DevCPT.Node;
  418. VAR x: DevCPT.Node;
  419. BEGIN
  420. x := DevCPT.NewNode(Nconst); x.conval := DevCPT.NewConst();
  421. x.conval.intval := intval; x.conval.realval := 0; x.typ := DevCPT.int32typ; RETURN x
  422. END NewIntConst;
  423. PROCEDURE NewLargeIntConst* (intval: INTEGER; realval: REAL): DevCPT.Node;
  424. VAR x: DevCPT.Node;
  425. BEGIN
  426. x := DevCPT.NewNode(Nconst); x.conval := DevCPT.NewConst();
  427. x.conval.intval := intval; x.conval.realval := realval; x.typ := DevCPT.int64typ; RETURN x
  428. END NewLargeIntConst;
  429. PROCEDURE NewRealConst*(realval: REAL; typ: DevCPT.Struct): DevCPT.Node;
  430. VAR x: DevCPT.Node;
  431. BEGIN
  432. x := DevCPT.NewNode(Nconst); x.conval := DevCPT.NewConst();
  433. x.conval.realval := realval; x.conval.intval := DevCPM.ConstNotAlloc;
  434. IF typ = NIL THEN typ := DevCPT.real64typ END;
  435. x.typ := typ;
  436. RETURN x
  437. END NewRealConst;
  438. PROCEDURE NewString*(str: DevCPT.String; lstr: POINTER TO ARRAY OF CHAR; len: INTEGER): DevCPT.Node;
  439. VAR i, j, c: INTEGER; x: DevCPT.Node; ext: DevCPT.ConstExt;
  440. BEGIN
  441. x := DevCPT.NewNode(Nconst); x.conval := DevCPT.NewConst();
  442. IF lstr # NIL THEN
  443. x.typ := DevCPT.string16typ;
  444. NEW(ext, 3 * len); i := 0; j := 0;
  445. REPEAT c := ORD(lstr[i]); INC(i); DevCPM.PutUtf8(ext^, c, j) UNTIL c = 0;
  446. x.conval.ext := ext
  447. ELSE
  448. x.typ := DevCPT.string8typ; x.conval.ext := str
  449. END;
  450. x.conval.intval := DevCPM.ConstNotAlloc; x.conval.intval2 := len;
  451. RETURN x
  452. END NewString;
  453. PROCEDURE CharToString8(n: DevCPT.Node);
  454. VAR ch: SHORTCHAR;
  455. BEGIN
  456. n.typ := DevCPT.string8typ; ch := SHORT(CHR(n.conval.intval)); NEW(n.conval.ext, 2);
  457. IF ch = 0X THEN n.conval.intval2 := 1 ELSE n.conval.intval2 := 2; n.conval.ext[1] := 0X END ;
  458. n.conval.ext[0] := ch; n.conval.intval := DevCPM.ConstNotAlloc; n.obj := NIL
  459. END CharToString8;
  460. PROCEDURE CharToString16 (n: DevCPT.Node);
  461. VAR ch, ch1: SHORTCHAR; i: INTEGER;
  462. BEGIN
  463. n.typ := DevCPT.string16typ; NEW(n.conval.ext, 4);
  464. IF n.conval.intval = 0 THEN
  465. n.conval.ext[0] := 0X; n.conval.intval2 := 1
  466. ELSE
  467. i := 0; DevCPM.PutUtf8(n.conval.ext^, n.conval.intval, i);
  468. n.conval.ext[i] := 0X; n.conval.intval2 := 2
  469. END;
  470. n.conval.intval := DevCPM.ConstNotAlloc; n.obj := NIL
  471. END CharToString16;
  472. PROCEDURE String8ToString16 (n: DevCPT.Node);
  473. VAR i, j, x: INTEGER; ext, new: DevCPT.ConstExt;
  474. BEGIN
  475. n.typ := DevCPT.string16typ; ext := n.conval.ext;
  476. NEW(new, 2 * n.conval.intval2); i := 0; j := 0;
  477. REPEAT x := ORD(ext[i]); INC(i); DevCPM.PutUtf8(new^, x, j) UNTIL x = 0;
  478. n.conval.ext := new; n.obj := NIL
  479. END String8ToString16;
  480. PROCEDURE String16ToString8 (n: DevCPT.Node);
  481. VAR i, j, x: INTEGER; ext, new: DevCPT.ConstExt;
  482. BEGIN
  483. n.typ := DevCPT.string8typ; ext := n.conval.ext;
  484. NEW(new, n.conval.intval2); i := 0; j := 0;
  485. REPEAT DevCPM.GetUtf8(ext^, x, i); new[j] := SHORT(CHR(x MOD 256)); INC(j) UNTIL x = 0;
  486. n.conval.ext := new; n.obj := NIL
  487. END String16ToString8;
  488. PROCEDURE StringToGuid (VAR n: DevCPT.Node);
  489. BEGIN
  490. ASSERT((n.class = Nconst) & (n.typ.form = String8));
  491. IF ~DevCPM.ValidGuid(n.conval.ext^) THEN err(165) END;
  492. n.typ := DevCPT.guidtyp
  493. END StringToGuid;
  494. PROCEDURE CheckString (n: DevCPT.Node; typ: DevCPT.Struct; e: SHORTINT);
  495. VAR ntyp: DevCPT.Struct;
  496. BEGIN
  497. ntyp := n.typ;
  498. IF (typ = DevCPT.guidtyp) & (n.class = Nconst) & (ntyp.form = String8) THEN StringToGuid(n)
  499. ELSIF (typ.comp IN {Array, DynArr}) & (typ.BaseTyp.form = Char8) OR (typ.form = String8) THEN
  500. IF (n.class = Nconst) & (ntyp.form = Char8) THEN CharToString8(n)
  501. ELSIF (ntyp.comp IN {Array, DynArr}) & (ntyp.BaseTyp.form = Char8) OR (ntyp.form = String8) THEN (* ok *)
  502. ELSE err(e)
  503. END
  504. ELSIF (typ.comp IN {Array, DynArr}) & (typ.BaseTyp.form = Char16) OR (typ.form = String16) THEN
  505. IF (n.class = Nconst) & (ntyp.form IN charSet) THEN CharToString16(n)
  506. ELSIF (n.class = Nconst) & (ntyp.form = String8) THEN String8ToString16(n)
  507. ELSIF (ntyp.comp IN {Array, DynArr}) & (ntyp.BaseTyp.form = Char16) OR (ntyp.form = String16) THEN
  508. (* ok *)
  509. ELSE err(e)
  510. END
  511. ELSE err(e)
  512. END
  513. END CheckString;
  514. PROCEDURE BindNodes(class: BYTE; typ: DevCPT.Struct; VAR x: DevCPT.Node; y: DevCPT.Node);
  515. VAR node: DevCPT.Node;
  516. BEGIN
  517. node := DevCPT.NewNode(class); node.typ := typ;
  518. node.left := x; node.right := y; x := node
  519. END BindNodes;
  520. PROCEDURE NotVar(x: DevCPT.Node): BOOLEAN;
  521. BEGIN
  522. RETURN (x.class >= Nconst) & ((x.class # Nmop) OR (x.subcl # val) OR (x.left.class >= Nconst))
  523. OR (x.typ.form IN {String8, String16})
  524. END NotVar;
  525. PROCEDURE Convert(VAR x: DevCPT.Node; typ: DevCPT.Struct);
  526. VAR node: DevCPT.Node; f, g: SHORTINT; k: INTEGER; r: REAL;
  527. BEGIN f := x.typ.form; g := typ.form;
  528. IF x.class = Nconst THEN
  529. IF g = String8 THEN
  530. IF f = String16 THEN String16ToString8(x)
  531. ELSIF f IN charSet THEN CharToString8(x)
  532. ELSE typ := DevCPT.undftyp
  533. END
  534. ELSIF g = String16 THEN
  535. IF f = String8 THEN String8ToString16(x)
  536. ELSIF f IN charSet THEN CharToString16(x)
  537. ELSE typ := DevCPT.undftyp
  538. END
  539. ELSE ConvConst(x.conval, f, g)
  540. END;
  541. x.obj := NIL
  542. ELSIF (x.class = Nmop) & (x.subcl = conv) & (DevCPT.Includes(f, x.left.typ.form) OR DevCPT.Includes(f, g))
  543. THEN
  544. (* don't create new node *)
  545. IF x.left.typ.form = typ.form THEN (* and suppress existing node *) x := x.left END
  546. ELSE
  547. IF (x.class = Ndop) & (x.typ.form IN {String8, String16}) THEN (* propagate to leaf nodes *)
  548. Convert(x.left, typ); Convert(x.right, typ)
  549. ELSE
  550. node := DevCPT.NewNode(Nmop); node.subcl := conv; node.left := x; x := node;
  551. END
  552. END;
  553. x.typ := typ
  554. END Convert;
  555. PROCEDURE Promote (VAR left, right: DevCPT.Node; op: INTEGER); (* check expression compatibility *)
  556. VAR f, g: INTEGER; new: DevCPT.Struct;
  557. BEGIN
  558. f := left.typ.form; g := right.typ.form; new := left.typ;
  559. IF f IN intSet + realSet THEN
  560. IF g IN intSet + realSet THEN
  561. IF (f = Real32) & (right.class = Nconst) & (g IN realSet) & (left.class # Nconst)
  562. (* & ((ABS(right.conval.realval) <= DevCPM.MaxReal32)
  563. OR (ABS(right.conval.realval) = DevCPM.InfReal)) *)
  564. OR (g = Real32) & (left.class = Nconst) & (f IN realSet) & (right.class # Nconst)
  565. (* & ((ABS(left.conval.realval) <= DevCPM.MaxReal32)
  566. OR (ABS(left.conval.realval) = DevCPM.InfReal)) *) THEN
  567. new := DevCPT.real32typ (* SR *)
  568. ELSIF (f = Real64) OR (g = Real64) THEN new := DevCPT.real64typ
  569. ELSIF (f = Real32) OR (g = Real32) THEN new := DevCPT.real32typ (* SR *)
  570. ELSIF op = slash THEN new := DevCPT.real64typ
  571. ELSIF (f = Int64) OR (g = Int64) THEN new := DevCPT.int64typ
  572. ELSE new := DevCPT.int32typ
  573. END
  574. ELSE err(100)
  575. END
  576. ELSIF (left.typ = DevCPT.guidtyp) OR (right.typ = DevCPT.guidtyp) THEN
  577. IF f = String8 THEN StringToGuid(left) END;
  578. IF g = String8 THEN StringToGuid(right) END;
  579. IF left.typ # right.typ THEN err(100) END;
  580. f := Comp
  581. ELSIF f IN charSet + {String8, String16} THEN
  582. IF g IN charSet + {String8, String16} THEN
  583. IF (f = String16) OR (g = String16) OR (f = Char16) & (g = String8) OR (f = String8) & (g = Char16) THEN
  584. new := DevCPT.string16typ
  585. ELSIF (f = Char16) OR (g = Char16) THEN new := DevCPT.char16typ
  586. ELSIF (f = String8) OR (g = String8) THEN new := DevCPT.string8typ
  587. ELSIF op = plus THEN
  588. IF (f = Char16) OR (g = Char16) THEN new := DevCPT.string16typ
  589. ELSE new := DevCPT.string8typ
  590. END
  591. END;
  592. IF (new.form IN {String8, String16})
  593. & ((f IN charSet) & (left.class # Nconst) OR (g IN charSet) & (right.class # Nconst))
  594. THEN
  595. err(100)
  596. END
  597. ELSE err(100)
  598. END
  599. ELSIF (f IN {NilTyp, Pointer, ProcTyp}) & (g IN {NilTyp, Pointer, ProcTyp}) THEN
  600. IF ~DevCPT.SameType(left.typ, right.typ) & (f # NilTyp) & (g # NilTyp)
  601. & ~((f = Pointer) & (g = Pointer)
  602. & (DevCPT.Extends(left.typ, right.typ) OR DevCPT.Extends(right.typ, left.typ))) THEN err(100) END
  603. ELSIF f # g THEN err(100)
  604. END;
  605. IF ~(f IN {NilTyp, Pointer, ProcTyp, Comp}) THEN
  606. IF g # new.form THEN Convert(right, new) END;
  607. IF f # new.form THEN Convert(left, new) END
  608. END
  609. END Promote;
  610. PROCEDURE CheckParameters* (fp, ap: DevCPT.Object; checkNames: BOOLEAN); (* checks par list match *)
  611. VAR ft, at: DevCPT.Struct;
  612. BEGIN
  613. WHILE fp # NIL DO
  614. IF ap # NIL THEN
  615. ft := fp.typ; at := ap.typ;
  616. IF fp.ptyp # NIL THEN ft := fp.ptyp END; (* get original formal type *)
  617. IF ap.ptyp # NIL THEN at := ap.ptyp END; (* get original formal type *)
  618. IF ~DevCPT.EqualType(ft, at)
  619. OR (fp.mode # ap.mode) OR (fp.sysflag # ap.sysflag) OR (fp.vis # ap.vis)
  620. OR checkNames & (fp.name^ # ap.name^) THEN err(115) END ;
  621. ap := ap.link
  622. ELSE err(116)
  623. END;
  624. fp := fp.link
  625. END;
  626. IF ap # NIL THEN err(116) END
  627. END CheckParameters;
  628. PROCEDURE CheckNewParamPair* (newPar, iidPar: DevCPT.Node);
  629. VAR ityp, ntyp: DevCPT.Struct;
  630. BEGIN
  631. ntyp := newPar.typ.BaseTyp;
  632. IF (newPar.class = Nvarpar) & ODD(newPar.obj.sysflag DIV newBit) THEN
  633. IF (iidPar.class = Nvarpar) & ODD(iidPar.obj.sysflag DIV iidBit) & (iidPar.obj.mnolev = newPar.obj.mnolev)
  634. THEN (* ok *)
  635. ELSE err(168)
  636. END
  637. ELSIF ntyp.extlev = 0 THEN (* ok *)
  638. ELSIF (iidPar.class = Nconst) & (iidPar.obj # NIL) & (iidPar.obj.mode = Typ) THEN
  639. IF ~DevCPT.Extends(iidPar.obj.typ, ntyp) THEN err(168) END
  640. ELSE err(168)
  641. END
  642. END CheckNewParamPair;
  643. PROCEDURE DeRef*(VAR x: DevCPT.Node);
  644. VAR strobj, bstrobj: DevCPT.Object; typ, btyp: DevCPT.Struct;
  645. BEGIN
  646. typ := x.typ;
  647. IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(78)
  648. ELSIF typ.form = Pointer THEN
  649. btyp := typ.BaseTyp; strobj := typ.strobj; bstrobj := btyp.strobj;
  650. IF (strobj # NIL) & (strobj.name # DevCPT.null) & (bstrobj # NIL) & (bstrobj.name # DevCPT.null) THEN
  651. btyp.pbused := TRUE
  652. END ;
  653. BindNodes(Nderef, btyp, x, NIL); x.subcl := 0
  654. ELSE err(84)
  655. END
  656. END DeRef;
  657. PROCEDURE StrDeref*(VAR x: DevCPT.Node);
  658. VAR typ, btyp: DevCPT.Struct;
  659. BEGIN
  660. typ := x.typ;
  661. IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(78)
  662. ELSIF ((typ.comp IN {Array, DynArr}) & (typ.BaseTyp.form IN charSet)) OR (typ.sysflag = jstr) THEN
  663. IF (typ.BaseTyp # NIL) & (typ.BaseTyp.form = Char8) THEN btyp := DevCPT.string8typ
  664. ELSE btyp := DevCPT.string16typ
  665. END;
  666. BindNodes(Nderef, btyp, x, NIL); x.subcl := 1
  667. ELSE err(90)
  668. END
  669. END StrDeref;
  670. PROCEDURE Index*(VAR x: DevCPT.Node; y: DevCPT.Node);
  671. VAR f: SHORTINT; typ: DevCPT.Struct;
  672. BEGIN
  673. f := y.typ.form;
  674. IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(79)
  675. ELSIF ~(f IN intSet) OR (y.class IN {Nproc, Ntype}) THEN err(80); y.typ := DevCPT.int32typ END ;
  676. IF f = Int64 THEN Convert(y, DevCPT.int32typ) END;
  677. IF x.typ.comp = Array THEN typ := x.typ.BaseTyp;
  678. IF (y.class = Nconst) & ((y.conval.intval < 0) OR (y.conval.intval >= x.typ.n)) THEN err(81) END
  679. ELSIF x.typ.comp = DynArr THEN typ := x.typ.BaseTyp;
  680. IF (y.class = Nconst) & (y.conval.intval < 0) THEN err(81) END
  681. ELSE err(82); typ := DevCPT.undftyp
  682. END ;
  683. BindNodes(Nindex, typ, x, y); x.readonly := x.left.readonly
  684. END Index;
  685. PROCEDURE Field*(VAR x: DevCPT.Node; y: DevCPT.Object);
  686. BEGIN (*x.typ.comp = Record*)
  687. IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(77) END ;
  688. IF (y # NIL) & (y.mode IN {Fld, TProc}) THEN
  689. BindNodes(Nfield, y.typ, x, NIL); x.obj := y;
  690. x.readonly := x.left.readonly OR ((y.vis = externalR) & (y.mnolev < 0))
  691. ELSE err(83); x.typ := DevCPT.undftyp
  692. END
  693. END Field;
  694. PROCEDURE TypTest*(VAR x: DevCPT.Node; obj: DevCPT.Object; guard: BOOLEAN);
  695. PROCEDURE GTT(t0, t1: DevCPT.Struct);
  696. VAR node: DevCPT.Node;
  697. BEGIN
  698. IF (t0 # NIL) & DevCPT.SameType(t0, t1) & (guard OR (x.class # Nguard)) THEN
  699. IF ~guard THEN x := NewBoolConst(TRUE) END
  700. ELSIF (t0 = NIL) OR DevCPT.Extends(t1, t0) OR (t0.sysflag = jint) OR (t1.sysflag = jint)
  701. OR (t1.comp = DynArr) & (DevCPM.java IN DevCPM.options) THEN
  702. IF guard THEN BindNodes(Nguard, NIL, x, NIL); x.readonly := x.left.readonly
  703. ELSE node := DevCPT.NewNode(Nmop); node.subcl := is; node.left := x; node.obj := obj; x := node
  704. END
  705. ELSE err(85)
  706. END
  707. END GTT;
  708. BEGIN
  709. IF (x.class = Nconst) OR (x.class = Ntype) OR (x.class = Nproc) THEN err(112)
  710. ELSIF x.typ.form = Pointer THEN
  711. IF x.typ = DevCPT.sysptrtyp THEN
  712. IF obj.typ.form = Pointer THEN GTT(NIL, obj.typ.BaseTyp)
  713. ELSE err(86)
  714. END
  715. ELSIF x.typ.BaseTyp.comp # Record THEN err(85)
  716. ELSIF obj.typ.form = Pointer THEN GTT(x.typ.BaseTyp, obj.typ.BaseTyp)
  717. ELSE err(86)
  718. END
  719. ELSIF (x.typ.comp = Record) & (x.class = Nvarpar) & (x.obj.vis # outPar) & (obj.typ.comp = Record) THEN
  720. GTT(x.typ, obj.typ)
  721. ELSE err(87)
  722. END ;
  723. IF guard THEN x.typ := obj.typ ELSE x.typ := DevCPT.booltyp END
  724. END TypTest;
  725. PROCEDURE In*(VAR x: DevCPT.Node; y: DevCPT.Node);
  726. VAR f: SHORTINT; k: INTEGER;
  727. BEGIN f := x.typ.form;
  728. IF (x.class = Ntype) OR (x.class = Nproc) OR (y.class = Ntype) OR (y.class = Nproc) THEN err(126)
  729. ELSIF (f IN intSet) & (y.typ.form = Set) THEN
  730. IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
  731. IF x.class = Nconst THEN
  732. k := x.conval.intval;
  733. IF (k < 0) OR (k > DevCPM.MaxSet) THEN err(202)
  734. ELSIF y.class = Nconst THEN x.conval.intval := BoolToInt(k IN y.conval.setval); x.obj := NIL
  735. ELSE BindNodes(Ndop, DevCPT.booltyp, x, y); x.subcl := in
  736. END
  737. ELSE BindNodes(Ndop, DevCPT.booltyp, x, y); x.subcl := in
  738. END
  739. ELSE err(92)
  740. END ;
  741. x.typ := DevCPT.booltyp
  742. END In;
  743. PROCEDURE MOp*(op: BYTE; VAR x: DevCPT.Node);
  744. VAR f: SHORTINT; typ: DevCPT.Struct; z: DevCPT.Node;
  745. PROCEDURE NewOp(op: BYTE; typ: DevCPT.Struct; z: DevCPT.Node): DevCPT.Node;
  746. VAR node: DevCPT.Node;
  747. BEGIN
  748. node := DevCPT.NewNode(Nmop); node.subcl := op; node.typ := typ;
  749. node.left := z; RETURN node
  750. END NewOp;
  751. BEGIN z := x;
  752. IF ((z.class = Ntype) OR (z.class = Nproc)) & (op # adr) & (op # typfn) & (op # size) THEN err(126) (* !!! *)
  753. ELSE
  754. typ := z.typ; f := typ.form;
  755. CASE op OF
  756. | not:
  757. IF f = Bool THEN
  758. IF z.class = Nconst THEN
  759. z.conval.intval := BoolToInt(~IntToBool(z.conval.intval)); z.obj := NIL
  760. ELSE z := NewOp(op, typ, z)
  761. END
  762. ELSE err(98)
  763. END
  764. | plus:
  765. IF ~(f IN intSet + realSet) THEN err(96) END
  766. | minus:
  767. IF f IN intSet + realSet + {Set} THEN
  768. IF z.class = Nconst THEN
  769. IF f = Set THEN z.conval.setval := -z.conval.setval
  770. ELSE NegateConst(z.conval, z.conval, z.typ)
  771. END;
  772. z.obj := NIL
  773. ELSE
  774. IF f < Int32 THEN Convert(z, DevCPT.int32typ) END;
  775. z := NewOp(op, z.typ, z)
  776. END
  777. ELSE err(97)
  778. END
  779. | abs:
  780. IF f IN intSet + realSet THEN
  781. IF z.class = Nconst THEN
  782. IF IsNegConst(z.conval, f) THEN NegateConst(z.conval, z.conval, z.typ) END;
  783. z.obj := NIL
  784. ELSE
  785. IF f < Int32 THEN Convert(z, DevCPT.int32typ) END;
  786. z := NewOp(op, z.typ, z)
  787. END
  788. ELSE err(111)
  789. END
  790. | cap:
  791. IF f IN charSet THEN
  792. IF z.class = Nconst THEN
  793. IF ODD(z.conval.intval DIV 32) THEN DEC(z.conval.intval, 32) END;
  794. z.obj := NIL
  795. ELSE z := NewOp(op, typ, z)
  796. END
  797. ELSE err(111); z.typ := DevCPT.char8typ
  798. END
  799. | odd:
  800. IF f IN intSet THEN
  801. IF z.class = Nconst THEN
  802. DivModConst(z.conval, two, FALSE, z.typ); (* z MOD 2 *)
  803. z.obj := NIL
  804. ELSE z := NewOp(op, typ, z)
  805. END
  806. ELSE err(111)
  807. END ;
  808. z.typ := DevCPT.booltyp
  809. | adr: (*ADR*)
  810. IF z.class = Nproc THEN
  811. IF z.obj.mnolev > 0 THEN err(73)
  812. ELSIF z.obj.mode = LProc THEN z.obj.mode := XProc
  813. END;
  814. z := NewOp(op, typ, z)
  815. ELSIF z.class = Ntype THEN
  816. IF z.obj.typ.untagged THEN err(111) END;
  817. z := NewOp(op, typ, z)
  818. ELSIF (z.class < Nconst) OR (z.class = Nconst) & (f IN {String8, String16}) THEN
  819. z := NewOp(op, typ, z)
  820. ELSE err(127)
  821. END ;
  822. z.typ := DevCPT.int32typ
  823. | typfn, size: (*TYP, SIZE*)
  824. z := NewOp(op, typ, z);
  825. z.typ := DevCPT.int32typ
  826. | cc: (*SYSTEM.CC*)
  827. IF (f IN intSet) & (z.class = Nconst) THEN
  828. IF (0 <= z.conval.intval) & (z.conval.intval <= DevCPM.MaxCC) & (z.conval.realval = 0) THEN
  829. z := NewOp(op, typ, z)
  830. ELSE err(219)
  831. END
  832. ELSE err(69)
  833. END;
  834. z.typ := DevCPT.booltyp
  835. END
  836. END;
  837. x := z
  838. END MOp;
  839. PROCEDURE ConstOp(op: SHORTINT; x, y: DevCPT.Node);
  840. VAR f: SHORTINT; i, j: INTEGER; xval, yval: DevCPT.Const; ext: DevCPT.ConstExt; t: DevCPT.Struct;
  841. BEGIN
  842. f := x.typ.form;
  843. IF f = y.typ.form THEN
  844. xval := x.conval; yval := y.conval;
  845. CASE op OF
  846. | times:
  847. IF f IN intSet + realSet THEN MulConst(xval, yval, xval, x.typ)
  848. ELSIF f = Set THEN xval.setval := xval.setval * yval.setval
  849. ELSIF f # Undef THEN err(101)
  850. END
  851. | slash:
  852. IF f IN realSet THEN DivConst(xval, yval, xval, x.typ)
  853. ELSIF f = Set THEN xval.setval := xval.setval / yval.setval
  854. ELSIF f # Undef THEN err(102)
  855. END
  856. | div:
  857. IF f IN intSet THEN DivModConst(xval, yval, TRUE, x.typ)
  858. ELSIF f # Undef THEN err(103)
  859. END
  860. | mod:
  861. IF f IN intSet THEN DivModConst(xval, yval, FALSE, x.typ)
  862. ELSIF f # Undef THEN err(104)
  863. END
  864. | and:
  865. IF f = Bool THEN xval.intval := BoolToInt(IntToBool(xval.intval) & IntToBool(yval.intval))
  866. ELSE err(94)
  867. END
  868. | plus:
  869. IF f IN intSet + realSet THEN AddConst(xval, yval, xval, x.typ)
  870. ELSIF f = Set THEN xval.setval := xval.setval + yval.setval
  871. ELSIF (f IN {String8, String16}) & (xval.ext # NIL) & (yval.ext # NIL) THEN
  872. NEW(ext, LEN(xval.ext^) + LEN(yval.ext^));
  873. i := 0; WHILE xval.ext[i] # 0X DO ext[i] := xval.ext[i]; INC(i) END;
  874. j := 0; WHILE yval.ext[j] # 0X DO ext[i] := yval.ext[j]; INC(i); INC(j) END;
  875. ext[i] := 0X; xval.ext := ext; INC(xval.intval2, yval.intval2 - 1)
  876. ELSIF f # Undef THEN err(105)
  877. END
  878. | minus:
  879. IF f IN intSet + realSet THEN SubConst(xval, yval, xval, x.typ)
  880. ELSIF f = Set THEN xval.setval := xval.setval - yval.setval
  881. ELSIF f # Undef THEN err(106)
  882. END
  883. | min:
  884. IF f IN intSet + realSet THEN
  885. IF LessConst(yval, xval, f) THEN xval^ := yval^ END
  886. ELSIF f # Undef THEN err(111)
  887. END
  888. | max:
  889. IF f IN intSet + realSet THEN
  890. IF LessConst(xval, yval, f) THEN xval^ := yval^ END
  891. ELSIF f # Undef THEN err(111)
  892. END
  893. | or:
  894. IF f = Bool THEN xval.intval := BoolToInt(IntToBool(xval.intval) OR IntToBool(yval.intval))
  895. ELSE err(95)
  896. END
  897. | eql: xval.intval := BoolToInt(EqualConst(xval, yval, f)); x.typ := DevCPT.booltyp
  898. | neq: xval.intval := BoolToInt(~EqualConst(xval, yval, f)); x.typ := DevCPT.booltyp
  899. | lss: xval.intval := BoolToInt(LessConst(xval, yval, f)); x.typ := DevCPT.booltyp
  900. | leq: xval.intval := BoolToInt(~LessConst(yval, xval, f)); x.typ := DevCPT.booltyp
  901. | gtr: xval.intval := BoolToInt(LessConst(yval, xval, f)); x.typ := DevCPT.booltyp
  902. | geq: xval.intval := BoolToInt(~LessConst(xval, yval, f)); x.typ := DevCPT.booltyp
  903. END
  904. ELSE err(100)
  905. END;
  906. x.obj := NIL
  907. END ConstOp;
  908. PROCEDURE Op*(op: BYTE; VAR x: DevCPT.Node; y: DevCPT.Node);
  909. VAR f, g: SHORTINT; t, z: DevCPT.Node; typ: DevCPT.Struct; do: BOOLEAN; val: INTEGER;
  910. PROCEDURE NewOp(op: BYTE; typ: DevCPT.Struct; VAR x: DevCPT.Node; y: DevCPT.Node);
  911. VAR node: DevCPT.Node;
  912. BEGIN
  913. node := DevCPT.NewNode(Ndop); node.subcl := op; node.typ := typ;
  914. node.left := x; node.right := y; x := node
  915. END NewOp;
  916. BEGIN z := x;
  917. IF (z.class = Ntype) OR (z.class = Nproc) OR (y.class = Ntype) OR (y.class = Nproc) THEN err(126)
  918. ELSE
  919. Promote(z, y, op);
  920. IF (z.class = Nconst) & (y.class = Nconst) THEN ConstOp(op, z, y)
  921. ELSE
  922. typ := z.typ; f := typ.form; g := y.typ.form;
  923. CASE op OF
  924. | times:
  925. do := TRUE;
  926. IF f IN intSet THEN
  927. IF z.class = Nconst THEN
  928. IF EqualConst(z.conval, one, f) THEN do := FALSE; z := y
  929. ELSIF EqualConst(z.conval, zero, f) THEN do := FALSE
  930. ELSE val := Log(z);
  931. IF val >= 0 THEN
  932. t := y; y := z; z := t;
  933. op := ash; y.typ := DevCPT.int32typ; y.conval.intval := val; y.obj := NIL
  934. END
  935. END
  936. ELSIF y.class = Nconst THEN
  937. IF EqualConst(y.conval, one, f) THEN do := FALSE
  938. ELSIF EqualConst(y.conval, zero, f) THEN do := FALSE; z := y
  939. ELSE val := Log(y);
  940. IF val >= 0 THEN
  941. op := ash; y.typ := DevCPT.int32typ; y.conval.intval := val; y.obj := NIL
  942. END
  943. END
  944. END
  945. ELSIF ~(f IN {Undef, Real32..Set}) THEN err(105); typ := DevCPT.undftyp
  946. END ;
  947. IF do THEN NewOp(op, typ, z, y) END;
  948. | slash:
  949. IF f IN realSet THEN (* OK *)
  950. ELSIF (f # Set) & (f # Undef) THEN err(102); typ := DevCPT.undftyp
  951. END ;
  952. NewOp(op, typ, z, y)
  953. | div:
  954. do := TRUE;
  955. IF f IN intSet THEN
  956. IF y.class = Nconst THEN
  957. IF EqualConst(y.conval, zero, f) THEN err(205)
  958. ELSIF EqualConst(y.conval, one, f) THEN do := FALSE
  959. ELSE val := Log(y);
  960. IF val >= 0 THEN
  961. op := ash; y.typ := DevCPT.int32typ; y.conval.intval := -val; y.obj := NIL
  962. END
  963. END
  964. END
  965. ELSIF f # Undef THEN err(103); typ := DevCPT.undftyp
  966. END ;
  967. IF do THEN NewOp(op, typ, z, y) END;
  968. | mod:
  969. IF f IN intSet THEN
  970. IF y.class = Nconst THEN
  971. IF EqualConst(y.conval, zero, f) THEN err(205)
  972. ELSE val := Log(y);
  973. IF val >= 0 THEN
  974. op := msk; y.conval.intval := ASH(-1, val); y.obj := NIL
  975. END
  976. END
  977. END
  978. ELSIF f # Undef THEN err(104); typ := DevCPT.undftyp
  979. END ;
  980. NewOp(op, typ, z, y);
  981. | and:
  982. IF f = Bool THEN
  983. IF z.class = Nconst THEN
  984. IF IntToBool(z.conval.intval) THEN z := y END
  985. ELSIF (y.class = Nconst) & IntToBool(y.conval.intval) THEN (* optimize z & TRUE -> z *)
  986. ELSE NewOp(op, typ, z, y)
  987. END
  988. ELSIF f # Undef THEN err(94); z.typ := DevCPT.undftyp
  989. END
  990. | plus:
  991. IF ~(f IN {Undef, Int8..Set, Int64, String8, String16}) THEN err(105); typ := DevCPT.undftyp END;
  992. do := TRUE;
  993. IF f IN intSet THEN
  994. IF (z.class = Nconst) & EqualConst(z.conval, zero, f) THEN do := FALSE; z := y END ;
  995. IF (y.class = Nconst) & EqualConst(y.conval, zero, f) THEN do := FALSE END
  996. ELSIF f IN {String8, String16} THEN
  997. IF (z.class = Nconst) & (z.conval.intval2 = 1) THEN do := FALSE; z := y END ;
  998. IF (y.class = Nconst) & (y.conval.intval2 = 1) THEN do := FALSE END;
  999. IF do THEN
  1000. IF z.class = Ndop THEN
  1001. t := z; WHILE t.right.class = Ndop DO t := t.right END;
  1002. IF (t.right.class = Nconst) & (y.class = Nconst) THEN
  1003. ConstOp(op, t.right, y); do := FALSE
  1004. ELSIF (t.right.class = Nconst) & (y.class = Ndop) & (y.left.class = Nconst) THEN
  1005. ConstOp(op, t.right, y.left); y.left := t.right; t.right := y; do := FALSE
  1006. ELSE
  1007. NewOp(op, typ, t.right, y); do := FALSE
  1008. END
  1009. ELSE
  1010. IF (z.class = Nconst) & (y.class = Ndop) & (y.left.class = Nconst) THEN
  1011. ConstOp(op, z, y.left); y.left := z; z := y; do := FALSE
  1012. END
  1013. END
  1014. END
  1015. END ;
  1016. IF do THEN NewOp(op, typ, z, y) END;
  1017. | minus:
  1018. IF ~(f IN {Undef, Int8..Set, Int64}) THEN err(106); typ := DevCPT.undftyp END;
  1019. IF ~(f IN intSet) OR (y.class # Nconst) OR ~EqualConst(y.conval, zero, f) THEN NewOp(op, typ, z, y)
  1020. END;
  1021. | min, max:
  1022. IF ~(f IN {Undef} + intSet + realSet + charSet) THEN err(111); typ := DevCPT.undftyp END;
  1023. NewOp(op, typ, z, y);
  1024. | or:
  1025. IF f = Bool THEN
  1026. IF z.class = Nconst THEN
  1027. IF ~IntToBool(z.conval.intval) THEN z := y END
  1028. ELSIF (y.class = Nconst) & ~IntToBool(y.conval.intval) THEN (* optimize z OR FALSE -> z *)
  1029. ELSE NewOp(op, typ, z, y)
  1030. END
  1031. ELSIF f # Undef THEN err(95); z.typ := DevCPT.undftyp
  1032. END
  1033. | eql, neq, lss, leq, gtr, geq:
  1034. IF f IN {String8, String16} THEN
  1035. IF (f = String16) & (z.class = Nmop) & (z.subcl = conv) & (y.class = Nmop) & (y.subcl = conv) THEN
  1036. z := z.left; y := y.left (* remove LONG on both sides *)
  1037. ELSIF (z.class = Nconst) & (z.conval.intval2 = 1) & (y.class = Nderef) THEN (* y$ = "" -> y[0] = 0X *)
  1038. y := y.left; Index(y, NewIntConst(0)); z.typ := y.typ; z.conval.intval := 0
  1039. ELSIF (y.class = Nconst) & (y.conval.intval2 = 1) & (z.class = Nderef) THEN (* z$ = "" -> z[0] = 0X *)
  1040. z := z.left; Index(z, NewIntConst(0)); y.typ := z.typ; y.conval.intval := 0
  1041. END;
  1042. typ := DevCPT.booltyp
  1043. ELSIF (f IN {Undef, Char8..Real64, Char16, Int64})
  1044. OR (op <= neq) & ((f IN {Bool, Set, NilTyp, Pointer, ProcTyp}) OR (typ = DevCPT.guidtyp)) THEN
  1045. typ := DevCPT.booltyp
  1046. ELSE err(107); typ := DevCPT.undftyp
  1047. END;
  1048. NewOp(op, typ, z, y)
  1049. END
  1050. END
  1051. END;
  1052. x := z
  1053. END Op;
  1054. PROCEDURE SetRange*(VAR x: DevCPT.Node; y: DevCPT.Node);
  1055. VAR k, l: INTEGER;
  1056. BEGIN
  1057. IF (x.class = Ntype) OR (x.class = Nproc) OR (y.class = Ntype) OR (y.class = Nproc) THEN err(126)
  1058. ELSIF (x.typ.form IN intSet) & (y.typ.form IN intSet) THEN
  1059. IF x.typ.form = Int64 THEN Convert(x, DevCPT.int32typ) END;
  1060. IF y.typ.form = Int64 THEN Convert(y, DevCPT.int32typ) END;
  1061. IF x.class = Nconst THEN
  1062. k := x.conval.intval;
  1063. IF (0 > k) OR (k > DevCPM.MaxSet) OR (x.conval.realval # 0) THEN err(202) END
  1064. END ;
  1065. IF y.class = Nconst THEN
  1066. l := y.conval.intval;
  1067. IF (0 > l) OR (l > DevCPM.MaxSet) OR (y.conval.realval # 0) THEN err(202) END
  1068. END ;
  1069. IF (x.class = Nconst) & (y.class = Nconst) THEN
  1070. IF k <= l THEN
  1071. x.conval.setval := {k..l}
  1072. ELSE err(201); x.conval.setval := {l..k}
  1073. END ;
  1074. x.obj := NIL
  1075. ELSE BindNodes(Nupto, DevCPT.settyp, x, y)
  1076. END
  1077. ELSE err(93)
  1078. END ;
  1079. x.typ := DevCPT.settyp
  1080. END SetRange;
  1081. PROCEDURE SetElem*(VAR x: DevCPT.Node);
  1082. VAR k: INTEGER;
  1083. BEGIN
  1084. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126) END;
  1085. IF x.typ.form IN intSet THEN
  1086. IF x.typ.form = Int64 THEN Convert(x, DevCPT.int32typ) END;
  1087. IF x.class = Nconst THEN
  1088. k := x.conval.intval;
  1089. IF (0 <= k) & (k <= DevCPM.MaxSet) & (x.conval.realval = 0) THEN x.conval.setval := {k}
  1090. ELSE err(202)
  1091. END ;
  1092. x.obj := NIL
  1093. ELSE BindNodes(Nmop, DevCPT.settyp, x, NIL); x.subcl := bit
  1094. END ;
  1095. ELSE err(93)
  1096. END;
  1097. x.typ := DevCPT.settyp
  1098. END SetElem;
  1099. PROCEDURE CheckAssign* (x: DevCPT.Struct; VAR ynode: DevCPT.Node);
  1100. (* x := y, checks assignment compatibility *)
  1101. VAR f, g: SHORTINT; y, b: DevCPT.Struct;
  1102. BEGIN
  1103. y := ynode.typ; f := x.form; g := y.form;
  1104. IF (ynode.class = Ntype) OR (ynode.class = Nproc) & (f # ProcTyp) THEN err(126) END ;
  1105. CASE f OF
  1106. | Undef, String8, String16, Byte:
  1107. | Bool, Set:
  1108. IF g # f THEN err(113) END
  1109. | Int8, Int16, Int32, Int64, Real32, Real64: (* SR *)
  1110. IF (g IN intSet) OR (g IN realSet) & (f IN realSet) THEN
  1111. IF ynode.class = Nconst THEN Convert(ynode, x)
  1112. ELSIF ~DevCPT.Includes(f, g) THEN err(113)
  1113. END
  1114. ELSE err(113)
  1115. END
  1116. (*
  1117. IF ~(g IN intSet + realSet) OR ~DevCPT.Includes(f, g) & (~(g IN intSet) OR (ynode.class # Nconst)) THEN
  1118. err(113)
  1119. ELSIF ynode.class = Nconst THEN Convert(ynode, x)
  1120. END
  1121. *)
  1122. | Char8, Char16:
  1123. IF ~(g IN charSet) OR ~DevCPT.Includes(f, g) THEN err(113)
  1124. ELSIF ynode.class = Nconst THEN Convert(ynode, x)
  1125. END
  1126. | Pointer:
  1127. b := x.BaseTyp;
  1128. IF DevCPT.Extends(y, x)
  1129. OR (g = NilTyp)
  1130. OR (g = Pointer)
  1131. & ((x = DevCPT.sysptrtyp) OR (DevCPM.java IN DevCPM.options) & (x = DevCPT.anyptrtyp))
  1132. THEN (* ok *)
  1133. ELSIF (b.comp = DynArr) & b.untagged THEN (* pointer to untagged open array *)
  1134. IF ynode.class = Nconst THEN CheckString(ynode, b, 113)
  1135. ELSIF ~(y.comp IN {Array, DynArr}) OR ~DevCPT.EqualType(b.BaseTyp, y.BaseTyp) THEN err(113)
  1136. END
  1137. ELSIF b.untagged & (ynode.class = Nmop) & (ynode.subcl = adr) THEN (* p := ADR(r) *)
  1138. IF (b.comp = DynArr) & (ynode.left.class = Nconst) THEN CheckString(ynode.left, b, 113)
  1139. ELSIF ~DevCPT.Extends(ynode.left.typ, b) THEN err(113)
  1140. END
  1141. ELSIF (b.sysflag = jstr) & ((g = String16) OR (ynode.class = Nconst) & (g IN {Char8, Char16, String8}))
  1142. THEN
  1143. IF g # String16 THEN Convert(ynode, DevCPT.string16typ) END
  1144. ELSE err(113)
  1145. END
  1146. | ProcTyp:
  1147. IF DevCPT.EqualType(x, y) OR (g = NilTyp) THEN (* ok *)
  1148. ELSIF (ynode.class = Nproc) & (ynode.obj.mode IN {XProc, IProc, LProc}) THEN
  1149. IF ynode.obj.mode = LProc THEN
  1150. IF ynode.obj.mnolev = 0 THEN ynode.obj.mode := XProc ELSE err(73) END
  1151. END;
  1152. IF (x.sysflag = 0) & (ynode.obj.sysflag >= 0) OR (x.sysflag = ynode.obj.sysflag) THEN
  1153. IF DevCPT.EqualType(x.BaseTyp, ynode.obj.typ) THEN CheckParameters(x.link, ynode.obj.link, FALSE)
  1154. ELSE err(117)
  1155. END
  1156. ELSE err(113)
  1157. END
  1158. ELSE err(113)
  1159. END
  1160. | NoTyp, NilTyp: err(113)
  1161. | Comp:
  1162. x.pvused := TRUE; (* idfp of y guarantees assignment compatibility with x *)
  1163. IF x.comp = Record THEN
  1164. IF ~DevCPT.EqualType(x, y) OR (x.attribute # 0) THEN err(113) END
  1165. ELSIF g IN {Char8, Char16, String8, String16} THEN
  1166. IF (x.BaseTyp.form = Char16) & (g = String8) THEN Convert(ynode, DevCPT.string16typ)
  1167. ELSE CheckString(ynode, x, 113);
  1168. END;
  1169. IF (x # DevCPT.guidtyp) & (x.comp = Array) & (ynode.class = Nconst) & (ynode.conval.intval2 > x.n) THEN
  1170. err(114)
  1171. END
  1172. ELSIF (x.comp = Array) & DevCPT.EqualType(x, y) THEN (* ok *)
  1173. ELSE err(113)
  1174. END
  1175. END
  1176. END CheckAssign;
  1177. PROCEDURE AssignString (VAR x: DevCPT.Node; str: DevCPT.Node); (* x := str or x[0] := 0X *)
  1178. BEGIN
  1179. ASSERT((str.class = Nconst) & (str.typ.form IN {String8, String16}));
  1180. IF (x.typ.comp IN {Array, DynArr}) & (str.conval.intval2 = 1) THEN (* x := "" -> x[0] := 0X *)
  1181. Index(x, NewIntConst(0));
  1182. str.typ := x.typ; str.conval.intval := 0;
  1183. END;
  1184. BindNodes(Nassign, DevCPT.notyp, x, str); x.subcl := assign
  1185. END AssignString;
  1186. PROCEDURE CheckLeaf(x: DevCPT.Node; dynArrToo: BOOLEAN);
  1187. BEGIN
  1188. IF (x.class = Nmop) & (x.subcl = val) THEN x := x.left END ;
  1189. IF x.class = Nguard THEN x := x.left END ; (* skip last (and unique) guard *)
  1190. IF (x.class = Nvar) & (dynArrToo OR (x.typ.comp # DynArr)) THEN x.obj.leaf := FALSE END
  1191. END CheckLeaf;
  1192. PROCEDURE CheckOldType (x: DevCPT.Node);
  1193. BEGIN
  1194. IF ~(DevCPM.oberon IN DevCPM.options)
  1195. & ((x.typ = DevCPT.lreal64typ) OR (x.typ = DevCPT.lint64typ) OR (x.typ = DevCPT.lchar16typ)) THEN
  1196. err(198)
  1197. END
  1198. END CheckOldType;
  1199. PROCEDURE StPar0*(VAR par0: DevCPT.Node; fctno: SHORTINT); (* par0: first param of standard proc *)
  1200. VAR f: SHORTINT; typ: DevCPT.Struct; x, t: DevCPT.Node;
  1201. BEGIN x := par0; f := x.typ.form;
  1202. CASE fctno OF
  1203. haltfn: (*HALT*)
  1204. IF (f IN intSet - {Int64}) & (x.class = Nconst) THEN
  1205. IF (DevCPM.MinHaltNr <= x.conval.intval) & (x.conval.intval <= DevCPM.MaxHaltNr) THEN
  1206. BindNodes(Ntrap, DevCPT.notyp, x, x)
  1207. ELSE err(218)
  1208. END
  1209. ELSIF (DevCPM.java IN DevCPM.options)
  1210. & ((x.class = Ntype) OR (x.class = Nvar))
  1211. & (x.typ.form = Pointer)
  1212. THEN
  1213. BindNodes(Ntrap, DevCPT.notyp, x, x)
  1214. ELSE err(69)
  1215. END ;
  1216. x.typ := DevCPT.notyp
  1217. | newfn: (*NEW*)
  1218. typ := DevCPT.notyp;
  1219. IF NotVar(x) THEN err(112)
  1220. ELSIF f = Pointer THEN
  1221. IF DevCPM.NEWusingAdr THEN CheckLeaf(x, TRUE) END ;
  1222. IF x.readonly THEN err(76)
  1223. ELSIF (x.typ.BaseTyp.attribute = absAttr)
  1224. OR (x.typ.BaseTyp.attribute = limAttr) & (x.typ.BaseTyp.mno # 0) THEN err(193)
  1225. ELSIF (x.obj # NIL) & ODD(x.obj.sysflag DIV newBit) THEN err(167)
  1226. END ;
  1227. MarkAsUsed(x);
  1228. f := x.typ.BaseTyp.comp;
  1229. IF f IN {Record, DynArr, Array} THEN
  1230. IF f = DynArr THEN typ := x.typ.BaseTyp END ;
  1231. BindNodes(Nassign, DevCPT.notyp, x, NIL); x.subcl := newfn
  1232. ELSE err(111)
  1233. END
  1234. ELSE err(111)
  1235. END ;
  1236. x.typ := typ
  1237. | absfn: (*ABS*)
  1238. MOp(abs, x)
  1239. | capfn: (*CAP*)
  1240. MOp(cap, x)
  1241. | ordfn: (*ORD*)
  1242. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1243. ELSIF f = Char8 THEN Convert(x, DevCPT.int16typ)
  1244. ELSIF f = Char16 THEN Convert(x, DevCPT.int32typ)
  1245. ELSIF f = Set THEN Convert(x, DevCPT.int32typ)
  1246. ELSE err(111)
  1247. END
  1248. | bitsfn: (*BITS*)
  1249. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1250. ELSIF f IN {Int8, Int16, Int32} THEN Convert(x, DevCPT.settyp)
  1251. ELSE err(111)
  1252. END
  1253. | entierfn: (*ENTIER*)
  1254. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1255. ELSIF f IN realSet THEN Convert(x, DevCPT.int64typ)
  1256. ELSE err(111)
  1257. END ;
  1258. x.typ := DevCPT.int64typ
  1259. | lentierfcn: (* LENTIER *)
  1260. IF ~(DevCPM.oberon IN DevCPM.options) THEN err(199) END;
  1261. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1262. ELSIF f IN realSet THEN Convert(x, DevCPT.int64typ)
  1263. ELSE err(111)
  1264. END ;
  1265. x.typ := DevCPT.int64typ
  1266. | oddfn: (*ODD*)
  1267. MOp(odd, x)
  1268. | minfn: (*MIN*)
  1269. IF x.class = Ntype THEN
  1270. CheckOldType(x);
  1271. CASE f OF
  1272. Bool: x := NewBoolConst(FALSE)
  1273. | Char8: x := NewIntConst(0); x.typ := DevCPT.char8typ
  1274. | Char16: x := NewIntConst(0); x.typ := DevCPT.char8typ
  1275. | Int8: x := NewIntConst(-128)
  1276. | Int16: x := NewIntConst(-32768)
  1277. | Int32: x := NewIntConst(-2147483648)
  1278. | Int64: x := NewLargeIntConst(0, -9223372036854775808.0E0) (* -2^63 *)
  1279. | Set: x := NewIntConst(0) (*; x.typ := DevCPT.int16typ *)
  1280. | Real32: x := NewRealConst(DevCPM.MinReal32, DevCPT.real64typ)
  1281. | Real64: x := NewRealConst(DevCPM.MinReal64, DevCPT.real64typ)
  1282. ELSE err(111)
  1283. END;
  1284. x.hint := 1
  1285. ELSIF ~(f IN intSet + realSet + charSet) THEN err(111)
  1286. END
  1287. | maxfn: (*MAX*)
  1288. IF x.class = Ntype THEN
  1289. CheckOldType(x);
  1290. CASE f OF
  1291. Bool: x := NewBoolConst(TRUE)
  1292. | Char8: x := NewIntConst(0FFH); x.typ := DevCPT.char8typ
  1293. | Char16: x := NewIntConst(0FFFFH); x.typ := DevCPT.char16typ
  1294. | Int8: x := NewIntConst(127)
  1295. | Int16: x := NewIntConst(32767)
  1296. | Int32: x := NewIntConst(2147483647)
  1297. | Int64: x := NewLargeIntConst(-1, 9223372036854775808.0E0) (* 2^63 - 1 *)
  1298. | Set: x := NewIntConst(31) (*; x.typ := DevCPT.int16typ *)
  1299. | Real32: x := NewRealConst(DevCPM.MaxReal32, DevCPT.real64typ)
  1300. | Real64: x := NewRealConst(DevCPM.MaxReal64, DevCPT.real64typ)
  1301. ELSE err(111)
  1302. END;
  1303. x.hint := 1
  1304. ELSIF ~(f IN intSet + realSet + charSet) THEN err(111)
  1305. END
  1306. | chrfn: (*CHR*)
  1307. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1308. ELSIF f IN {Undef, Int8..Int32, Int64} THEN Convert(x, DevCPT.char16typ)
  1309. ELSE err(111); x.typ := DevCPT.char16typ
  1310. END
  1311. | lchrfn: (* LCHR *)
  1312. IF ~(DevCPM.oberon IN DevCPM.options) THEN err(199) END;
  1313. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1314. ELSIF f IN {Undef, Int8..Int32, Int64} THEN Convert(x, DevCPT.char16typ)
  1315. ELSE err(111); x.typ := DevCPT.char16typ
  1316. END
  1317. | shortfn: (*SHORT*)
  1318. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1319. ELSE
  1320. IF (x.typ.comp IN {Array, DynArr}) & (x.typ.BaseTyp.form IN charSet) THEN StrDeref(x); f := x.typ.form
  1321. END;
  1322. IF f = Int16 THEN Convert(x, DevCPT.int8typ)
  1323. ELSIF f = Int32 THEN Convert(x, DevCPT.int16typ)
  1324. ELSIF f = Int64 THEN Convert(x, DevCPT.int32typ)
  1325. ELSIF f = Real64 THEN Convert(x, DevCPT.real32typ)
  1326. ELSIF f = Char16 THEN Convert(x, DevCPT.char8typ)
  1327. ELSIF f = String16 THEN Convert(x, DevCPT.string8typ)
  1328. ELSE err(111)
  1329. END
  1330. END
  1331. | longfn: (*LONG*)
  1332. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1333. ELSE
  1334. IF (x.typ.comp IN {Array, DynArr}) & (x.typ.BaseTyp.form IN charSet) THEN StrDeref(x); f := x.typ.form
  1335. END;
  1336. IF f = Int8 THEN Convert(x, DevCPT.int16typ)
  1337. ELSIF f = Int16 THEN Convert(x, DevCPT.int32typ)
  1338. ELSIF f = Int32 THEN Convert(x, DevCPT.int64typ)
  1339. ELSIF f = Real32 THEN Convert(x, DevCPT.real64typ)
  1340. ELSIF f = Char8 THEN Convert(x, DevCPT.char16typ)
  1341. ELSIF f = String8 THEN Convert(x, DevCPT.string16typ)
  1342. ELSE err(111)
  1343. END
  1344. END
  1345. | incfn, decfn: (*INC, DEC*)
  1346. IF NotVar(x) THEN err(112)
  1347. ELSIF ~(f IN intSet) THEN err(111)
  1348. ELSIF x.readonly THEN err(76)
  1349. END;
  1350. MarkAsUsed(x)
  1351. | inclfn, exclfn: (*INCL, EXCL*)
  1352. IF NotVar(x) THEN err(112)
  1353. ELSIF f # Set THEN err(111); x.typ := DevCPT.settyp
  1354. ELSIF x.readonly THEN err(76)
  1355. END;
  1356. MarkAsUsed(x)
  1357. | lenfn: (*LEN*)
  1358. IF (* (x.class = Ntype) OR *) (x.class = Nproc) THEN err(126) (* !!! *)
  1359. (* ELSIF x.typ.sysflag = jstr THEN StrDeref(x) *)
  1360. ELSE
  1361. IF x.typ.form = Pointer THEN DeRef(x) END;
  1362. IF x.class = Nconst THEN
  1363. IF x.typ.form = Char8 THEN CharToString8(x)
  1364. ELSIF x.typ.form = Char16 THEN CharToString16(x)
  1365. END
  1366. END;
  1367. IF ~(x.typ.comp IN {DynArr, Array}) & ~(x.typ.form IN {String8, String16}) THEN err(131) END
  1368. END
  1369. | copyfn: (*COPY*)
  1370. IF ~(DevCPM.oberon IN DevCPM.options) THEN err(199) END;
  1371. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126) END
  1372. | ashfn: (*ASH*)
  1373. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1374. ELSIF f IN intSet THEN
  1375. IF f < Int32 THEN Convert(x, DevCPT.int32typ) END
  1376. ELSE err(111); x.typ := DevCPT.int32typ
  1377. END
  1378. | adrfn: (*ADR*)
  1379. IF x.class = Ntype THEN CheckOldType(x) END;
  1380. CheckLeaf(x, FALSE); MOp(adr, x)
  1381. | typfn: (*TYP*)
  1382. CheckLeaf(x, FALSE);
  1383. IF x.class = Ntype THEN
  1384. CheckOldType(x);
  1385. IF x.typ.form = Pointer THEN x := NewLeaf(x.typ.BaseTyp.strobj) END;
  1386. IF x.typ.comp # Record THEN err(111) END;
  1387. MOp(adr, x)
  1388. ELSE
  1389. IF x.typ.form = Pointer THEN DeRef(x) END;
  1390. IF x.typ.comp # Record THEN err(111) END;
  1391. MOp(typfn, x)
  1392. END
  1393. | sizefn: (*SIZE*)
  1394. IF x.class # Ntype THEN err(110); x := NewIntConst(1)
  1395. ELSIF (f IN {Byte..Set, Pointer, ProcTyp, Char16, Int64}) OR (x.typ.comp IN {Array, Record}) THEN
  1396. CheckOldType(x); x.typ.pvused := TRUE;
  1397. IF typSize # NIL THEN
  1398. typSize(x.typ); x := NewIntConst(x.typ.size)
  1399. ELSE
  1400. MOp(size, x)
  1401. END
  1402. ELSE err(111); x := NewIntConst(1)
  1403. END
  1404. | thisrecfn, (*THISRECORD*)
  1405. thisarrfn: (*THISARRAY*)
  1406. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1407. ELSIF f IN {Int8, Int16} THEN Convert(x, DevCPT.int32typ)
  1408. ELSIF f # Int32 THEN err(111)
  1409. END
  1410. | ccfn: (*SYSTEM.CC*)
  1411. MOp(cc, x)
  1412. | lshfn, rotfn: (*SYSTEM.LSH, SYSTEM.ROT*)
  1413. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1414. ELSIF ~(f IN intSet + charSet + {Byte, Set}) THEN err(111)
  1415. END
  1416. | getfn, putfn, bitfn, movefn: (*SYSTEM.GET, SYSTEM.PUT, SYSTEM.BIT, SYSTEM.MOVE*)
  1417. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1418. ELSIF (x.class = Nconst) & (f IN {Int8, Int16}) THEN Convert(x, DevCPT.int32typ)
  1419. ELSIF ~(f IN {Int32, Pointer}) THEN err(111); x.typ := DevCPT.int32typ
  1420. END
  1421. | getrfn, putrfn: (*SYSTEM.GETREG, SYSTEM.PUTREG*)
  1422. IF (f IN intSet) & (x.class = Nconst) THEN
  1423. IF (x.conval.intval < DevCPM.MinRegNr) OR (x.conval.intval > DevCPM.MaxRegNr) THEN err(220)
  1424. END
  1425. ELSE err(69)
  1426. END
  1427. | valfn: (*SYSTEM.VAL*)
  1428. IF x.class # Ntype THEN err(110)
  1429. ELSIF (f IN {Undef, String8, String16, NoTyp, NilTyp}) (* OR (x.typ.comp = DynArr) *) THEN err(111)
  1430. ELSE CheckOldType(x)
  1431. END
  1432. | assertfn: (*ASSERT*)
  1433. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126); x := NewBoolConst(FALSE)
  1434. ELSIF f # Bool THEN err(120); x := NewBoolConst(FALSE)
  1435. ELSE MOp(not, x)
  1436. END
  1437. | validfn: (* VALID *)
  1438. IF (x.class = Nvarpar) & ODD(x.obj.sysflag DIV nilBit) THEN
  1439. MOp(adr, x); x.typ := DevCPT.sysptrtyp; Op(neq, x, Nil())
  1440. ELSE err(111)
  1441. END;
  1442. x.typ := DevCPT.booltyp
  1443. | iidfn: (* COM.IID *)
  1444. IF (x.class = Nconst) & (f = String8) THEN StringToGuid(x)
  1445. ELSE
  1446. typ := x.typ;
  1447. IF typ.form = Pointer THEN typ := typ.BaseTyp END;
  1448. IF (typ.sysflag = interface) & (typ.ext # NIL) & (typ.strobj # NIL) THEN
  1449. IF x.obj # typ.strobj THEN x := NewLeaf(typ.strobj) END
  1450. ELSE err(111)
  1451. END;
  1452. x.class := Nconst; x.typ := DevCPT.guidtyp
  1453. END
  1454. | queryfn: (* COM.QUERY *)
  1455. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1456. ELSIF f # Pointer THEN err(111)
  1457. END
  1458. END ;
  1459. par0 := x
  1460. END StPar0;
  1461. PROCEDURE StPar1*(VAR par0: DevCPT.Node; x: DevCPT.Node; fctno: BYTE);
  1462. (* x: second parameter of standard proc *)
  1463. VAR f, n, L, i: INTEGER; typ, tp1: DevCPT.Struct; p, t: DevCPT.Node;
  1464. PROCEDURE NewOp(class, subcl: BYTE; left, right: DevCPT.Node): DevCPT.Node;
  1465. VAR node: DevCPT.Node;
  1466. BEGIN
  1467. node := DevCPT.NewNode(class); node.subcl := subcl;
  1468. node.left := left; node.right := right; RETURN node
  1469. END NewOp;
  1470. BEGIN p := par0; f := x.typ.form;
  1471. CASE fctno OF
  1472. incfn, decfn: (*INC DEC*)
  1473. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126); p.typ := DevCPT.notyp
  1474. ELSE
  1475. IF f # p.typ.form THEN
  1476. IF f IN intSet THEN Convert(x, p.typ)
  1477. ELSE err(111)
  1478. END
  1479. END ;
  1480. p := NewOp(Nassign, fctno, p, x);
  1481. p.typ := DevCPT.notyp
  1482. END
  1483. | inclfn, exclfn: (*INCL, EXCL*)
  1484. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1485. ELSIF f IN intSet THEN
  1486. IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
  1487. IF (x.class = Nconst) & ((0 > x.conval.intval) OR (x.conval.intval > DevCPM.MaxSet)) THEN err(202)
  1488. END ;
  1489. p := NewOp(Nassign, fctno, p, x)
  1490. ELSE err(111)
  1491. END ;
  1492. p.typ := DevCPT.notyp
  1493. | lenfn: (*LEN*)
  1494. IF ~(f IN intSet) OR (x.class # Nconst) THEN err(69)
  1495. ELSE
  1496. IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
  1497. L := SHORT(x.conval.intval); typ := p.typ;
  1498. WHILE (L > 0) & (typ.comp IN {DynArr, Array}) DO typ := typ.BaseTyp; DEC(L) END ;
  1499. IF (L # 0) OR ~(typ.comp IN {DynArr, Array}) THEN err(132)
  1500. ELSE x.obj := NIL;
  1501. IF typ.comp = DynArr THEN
  1502. WHILE p.class = Nindex DO
  1503. p := p.left; INC(x.conval.intval) (* possible side effect ignored *)
  1504. END;
  1505. p := NewOp(Ndop, len, p, x); p.typ := DevCPT.int32typ
  1506. ELSE p := x; p.conval.intval := typ.n; p.typ := DevCPT.int32typ
  1507. END
  1508. END
  1509. END
  1510. | copyfn: (*COPY*)
  1511. IF NotVar(x) THEN err(112)
  1512. ELSIF x.readonly THEN err(76)
  1513. ELSE
  1514. CheckString(p, x.typ, 111); t := x; x := p; p := t;
  1515. IF (x.class = Nconst) & (x.typ.form IN {String8, String16}) THEN AssignString(p, x)
  1516. ELSE p := NewOp(Nassign, copyfn, p, x)
  1517. END
  1518. END ;
  1519. p.typ := DevCPT.notyp; MarkAsUsed(x)
  1520. | ashfn: (*ASH*)
  1521. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1522. ELSIF f IN intSet THEN
  1523. IF (x.class = Nconst) & ((x.conval.intval > 64) OR (x.conval.intval < -64)) THEN err(208)
  1524. ELSIF (p.class = Nconst) & (x.class = Nconst) THEN
  1525. n := x.conval.intval;
  1526. IF n > 0 THEN
  1527. WHILE n > 0 DO MulConst(p.conval, two, p.conval, p.typ); DEC(n) END
  1528. ELSE
  1529. WHILE n < 0 DO DivModConst(p.conval, two, TRUE, p.typ); INC(n) END
  1530. END;
  1531. p.obj := NIL
  1532. ELSE
  1533. IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
  1534. typ := p.typ; p := NewOp(Ndop, ash, p, x); p.typ := typ
  1535. END
  1536. ELSE err(111)
  1537. END
  1538. | minfn: (*MIN*)
  1539. IF p.class # Ntype THEN Op(min, p, x) ELSE err(64) END
  1540. | maxfn: (*MAX*)
  1541. IF p.class # Ntype THEN Op(max, p, x) ELSE err(64) END
  1542. | newfn: (*NEW(p, x...)*)
  1543. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1544. ELSIF p.typ.comp = DynArr THEN
  1545. IF f IN intSet THEN
  1546. IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
  1547. IF (x.class = Nconst) & (x.conval.intval <= 0)
  1548. & (~(DevCPM.java IN DevCPM.options) OR (x.conval.intval < 0))THEN err(63) END
  1549. ELSE err(111)
  1550. END ;
  1551. p.right := x; p.typ := p.typ.BaseTyp
  1552. ELSIF (p.left # NIL) & (p.left.typ.form = Pointer) THEN
  1553. typ := p.left.typ;
  1554. WHILE (typ # DevCPT.undftyp) & (typ.BaseTyp # NIL) DO typ := typ.BaseTyp END;
  1555. IF typ.sysflag = interface THEN
  1556. typ := x.typ;
  1557. WHILE (typ # DevCPT.undftyp) & (typ.BaseTyp # NIL) DO typ := typ.BaseTyp END;
  1558. IF (f = Pointer) & (typ.sysflag = interface) THEN
  1559. p.right := x
  1560. ELSE err(169)
  1561. END
  1562. ELSE err(64)
  1563. END
  1564. ELSE err(111)
  1565. END
  1566. | thisrecfn, (*THISRECORD*)
  1567. thisarrfn: (*THISARRAY*)
  1568. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1569. ELSIF f IN {Int8, Int16, Int32} THEN
  1570. IF f < Int32 THEN Convert(x, DevCPT.int32typ) END;
  1571. p := NewOp(Ndop, fctno, p, x); p.typ := DevCPT.undftyp
  1572. ELSE err(111)
  1573. END
  1574. | lshfn, rotfn: (*SYSTEM.LSH, SYSTEM.ROT*)
  1575. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1576. ELSIF ~(f IN intSet) THEN err(111)
  1577. ELSE
  1578. IF fctno = lshfn THEN p := NewOp(Ndop, lsh, p, x) ELSE p := NewOp(Ndop, rot, p, x) END ;
  1579. p.typ := p.left.typ
  1580. END
  1581. | getfn, putfn, getrfn, putrfn: (*SYSTEM.GET, SYSTEM.PUT, SYSTEM.GETREG, SYSTEM.PUTREG*)
  1582. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1583. ELSIF f IN {Undef..Set, NilTyp, Pointer, ProcTyp, Char16, Int64} THEN
  1584. IF (fctno = getfn) OR (fctno = getrfn) THEN
  1585. IF NotVar(x) THEN err(112) END ;
  1586. t := x; x := p; p := t
  1587. END ;
  1588. p := NewOp(Nassign, fctno, p, x)
  1589. ELSE err(111)
  1590. END ;
  1591. p.typ := DevCPT.notyp
  1592. | bitfn: (*SYSTEM.BIT*)
  1593. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1594. ELSIF f IN intSet THEN
  1595. p := NewOp(Ndop, bit, p, x)
  1596. ELSE err(111)
  1597. END ;
  1598. p.typ := DevCPT.booltyp
  1599. | valfn: (*SYSTEM.VAL*) (* type is changed without considering the byte ordering on the target machine *)
  1600. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1601. ELSIF x.typ.comp = DynArr THEN
  1602. IF x.typ.untagged & ((p.typ.comp # DynArr) OR p.typ.untagged) THEN (* ok *)
  1603. ELSIF (p.typ.comp = DynArr) & (x.typ.n = p.typ.n) THEN
  1604. typ := x.typ;
  1605. WHILE typ.comp = DynArr DO typ := typ.BaseTyp END;
  1606. tp1 := p.typ;
  1607. WHILE tp1.comp = DynArr DO tp1 := tp1.BaseTyp END;
  1608. IF typ.size # tp1.size THEN err(115) END
  1609. ELSE err(115)
  1610. END
  1611. ELSIF p.typ.comp = DynArr THEN err(115)
  1612. ELSIF (x.class = Nconst) & (f = String8) & (p.typ.form = Int32) & (x.conval.intval2 <= 5) THEN
  1613. i := 0; n := 0;
  1614. WHILE i < x.conval.intval2 - 1 DO n := 256 * n + ORD(x.conval.ext[i]); INC(i) END;
  1615. x := NewIntConst(n)
  1616. ELSIF (f IN {Undef, NoTyp, NilTyp}) OR (f IN {String8, String16}) & ~(DevCPM.java IN DevCPM.options) THEN err(111)
  1617. END ;
  1618. IF (x.class = Nconst) & (x.typ = p.typ) THEN (* ok *)
  1619. ELSIF (x.class >= Nconst) OR ((f IN realSet) # (p.typ.form IN realSet))
  1620. OR (DevCPM.options * {DevCPM.java, DevCPM.allSysVal} # {}) THEN
  1621. t := DevCPT.NewNode(Nmop); t.subcl := val; t.left := x; x := t
  1622. ELSE x.readonly := FALSE
  1623. END ;
  1624. x.typ := p.typ; p := x
  1625. | movefn: (*SYSTEM.MOVE*)
  1626. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1627. ELSIF (x.class = Nconst) & (f IN {Int8, Int16}) THEN Convert(x, DevCPT.int32typ)
  1628. ELSIF ~(f IN {Int32, Pointer}) THEN err(111); x.typ := DevCPT.int32typ
  1629. END ;
  1630. p.link := x
  1631. | assertfn: (*ASSERT*)
  1632. IF (f IN intSet - {Int64}) & (x.class = Nconst) THEN
  1633. IF (DevCPM.MinHaltNr <= x.conval.intval) & (x.conval.intval <= DevCPM.MaxHaltNr) THEN
  1634. BindNodes(Ntrap, DevCPT.notyp, x, x);
  1635. Construct(Nif, p, x); Construct(Nifelse, p, NIL); OptIf(p);
  1636. ELSE err(218)
  1637. END
  1638. ELSIF
  1639. (DevCPM.java IN DevCPM.options) & ((x.class = Ntype) OR (x.class = Nvar)) & (x.typ.form = Pointer)
  1640. THEN
  1641. BindNodes(Ntrap, DevCPT.notyp, x, x);
  1642. Construct(Nif, p, x); Construct(Nifelse, p, NIL); OptIf(p);
  1643. ELSE err(69)
  1644. END;
  1645. IF p = NIL THEN (* ASSERT(TRUE) *)
  1646. ELSIF p.class = Ntrap THEN err(99)
  1647. ELSE p.subcl := assertfn
  1648. END
  1649. | queryfn: (* COM.QUERY *)
  1650. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1651. ELSIF x.typ # DevCPT.guidtyp THEN err(111); x.typ := DevCPT.guidtyp
  1652. END;
  1653. p.link := x
  1654. ELSE err(64)
  1655. END ;
  1656. par0 := p
  1657. END StPar1;
  1658. PROCEDURE StParN*(VAR par0: DevCPT.Node; x: DevCPT.Node; fctno, n: SHORTINT);
  1659. (* x: n+1-th param of standard proc *)
  1660. VAR node: DevCPT.Node; f: SHORTINT; p: DevCPT.Node; typ: DevCPT.Struct;
  1661. BEGIN p := par0; f := x.typ.form;
  1662. IF fctno = newfn THEN (*NEW(p, ..., x...*)
  1663. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1664. ELSIF p.typ.comp # DynArr THEN err(64)
  1665. ELSIF f IN intSet THEN
  1666. IF f = Int64 THEN Convert(x, DevCPT.int32typ) END;
  1667. IF (x.class = Nconst) & (x.conval.intval <= 0) THEN err(63) END;
  1668. node := p.right; WHILE node.link # NIL DO node := node.link END;
  1669. node.link := x; p.typ := p.typ.BaseTyp
  1670. ELSE err(111)
  1671. END
  1672. ELSIF (fctno = movefn) & (n = 2) THEN (*SYSTEM.MOVE*)
  1673. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1674. ELSIF f IN intSet THEN
  1675. node := DevCPT.NewNode(Nassign); node.subcl := movefn; node.right := p;
  1676. node.left := p.link; p.link := x; p := node
  1677. ELSE err(111)
  1678. END ;
  1679. p.typ := DevCPT.notyp
  1680. ELSIF (fctno = queryfn) & (n = 2) THEN (* COM.QUERY *)
  1681. IF (x.class = Ntype) OR (x.class = Nproc) THEN err(126)
  1682. ELSIF (x.class < Nconst) & (f = Pointer) & (x.typ.sysflag = interface) THEN
  1683. IF ~DevCPT.Extends(p.typ, x.typ) THEN err(164) END;
  1684. IF x.readonly THEN err(76) END;
  1685. CheckNewParamPair(x, p.link);
  1686. MarkAsUsed(x);
  1687. node := DevCPT.NewNode(Ndop); node.subcl := queryfn;
  1688. node.left := p; node.right := p.link; p.link := NIL; node.right.link := x; p := node
  1689. ELSE err(111)
  1690. END;
  1691. p.typ := DevCPT.booltyp
  1692. ELSE err(64)
  1693. END ;
  1694. par0 := p
  1695. END StParN;
  1696. PROCEDURE StFct*(VAR par0: DevCPT.Node; fctno: BYTE; parno: SHORTINT);
  1697. VAR dim: SHORTINT; x, p: DevCPT.Node;
  1698. BEGIN p := par0;
  1699. IF fctno <= ashfn THEN
  1700. IF (fctno = newfn) & (p.typ # DevCPT.notyp) THEN
  1701. IF p.typ.comp = DynArr THEN err(65) END ;
  1702. p.typ := DevCPT.notyp
  1703. ELSIF (fctno = minfn) OR (fctno = maxfn) THEN
  1704. IF (parno < 1) OR (parno = 1) & (p.hint # 1) THEN err(65) END;
  1705. p.hint := 0
  1706. ELSIF fctno <= sizefn THEN (* 1 param *)
  1707. IF parno < 1 THEN err(65) END
  1708. ELSE (* more than 1 param *)
  1709. IF ((fctno = incfn) OR (fctno = decfn)) & (parno = 1) THEN (*INC, DEC*)
  1710. BindNodes(Nassign, DevCPT.notyp, p, NewIntConst(1)); p.subcl := fctno; p.right.typ := p.left.typ
  1711. ELSIF (fctno = lenfn) & (parno = 1) THEN (*LEN*)
  1712. IF p.typ.form IN {String8, String16} THEN
  1713. IF p.class = Nconst THEN p := NewIntConst(p.conval.intval2 - 1)
  1714. ELSIF (p.class = Ndop) & (p.subcl = plus) THEN (* propagate to leaf nodes *)
  1715. StFct(p.left, lenfn, 1); StFct(p.right, lenfn, 1); p.typ := DevCPT.int32typ
  1716. ELSE
  1717. WHILE (p.class = Nmop) & (p.subcl = conv) DO p := p.left END;
  1718. IF DevCPM.errors = 0 THEN ASSERT(p.class = Nderef) END;
  1719. BindNodes(Ndop, DevCPT.int32typ, p, NewIntConst(0)); p.subcl := len
  1720. END
  1721. ELSIF p.typ.comp = DynArr THEN dim := 0;
  1722. WHILE p.class = Nindex DO p := p.left; INC(dim) END ; (* possible side effect ignored *)
  1723. BindNodes(Ndop, DevCPT.int32typ, p, NewIntConst(dim)); p.subcl := len
  1724. ELSE
  1725. p := NewIntConst(p.typ.n)
  1726. END
  1727. ELSIF parno < 2 THEN err(65)
  1728. END
  1729. END
  1730. ELSIF fctno = assertfn THEN
  1731. IF parno = 1 THEN x := NIL;
  1732. BindNodes(Ntrap, DevCPT.notyp, x, NewIntConst(AssertTrap));
  1733. Construct(Nif, p, x); Construct(Nifelse, p, NIL); OptIf(p);
  1734. IF p = NIL THEN (* ASSERT(TRUE) *)
  1735. ELSIF p.class = Ntrap THEN err(99)
  1736. ELSE p.subcl := assertfn
  1737. END
  1738. ELSIF parno < 1 THEN err(65)
  1739. END
  1740. ELSIF (fctno >= lchrfn) & (fctno <= bytesfn) THEN
  1741. IF parno < 1 THEN err(65) END
  1742. ELSIF fctno < validfn THEN (*SYSTEM*)
  1743. IF (parno < 1) OR
  1744. (fctno > ccfn) & (parno < 2) OR
  1745. (fctno = movefn) & (parno < 3) THEN err(65)
  1746. END
  1747. ELSIF (fctno = thisrecfn) OR (fctno = thisarrfn) THEN
  1748. IF parno < 2 THEN err(65) END
  1749. ELSE (* COM *)
  1750. IF fctno = queryfn THEN
  1751. IF parno < 3 THEN err(65) END
  1752. ELSE
  1753. IF parno < 1 THEN err(65) END
  1754. END
  1755. END ;
  1756. par0 := p
  1757. END StFct;
  1758. PROCEDURE DynArrParCheck (ftyp: DevCPT.Struct; VAR ap: DevCPT.Node; fvarpar: BOOLEAN);
  1759. (* check array compatibility *)
  1760. VAR atyp: DevCPT.Struct;
  1761. BEGIN (* ftyp.comp = DynArr *)
  1762. atyp := ap.typ;
  1763. IF atyp.form IN {Char8, Char16, String8, String16} THEN
  1764. IF ~fvarpar & (ftyp.BaseTyp.form = Char16) & (atyp.form = String8) THEN Convert(ap, DevCPT.string16typ)
  1765. ELSE CheckString(ap, ftyp, 67)
  1766. END
  1767. ELSE
  1768. WHILE (ftyp.comp = DynArr) & ((atyp.comp IN {Array, DynArr}) OR (atyp.form IN {String8, String16})) DO
  1769. ftyp := ftyp.BaseTyp; atyp := atyp.BaseTyp
  1770. END;
  1771. IF ftyp.comp = DynArr THEN err(67)
  1772. ELSIF ~fvarpar & (ftyp.form = Pointer) & DevCPT.Extends(atyp, ftyp) THEN (* ok *)
  1773. ELSIF ~DevCPT.EqualType(ftyp, atyp) THEN err(66)
  1774. END
  1775. END
  1776. END DynArrParCheck;
  1777. PROCEDURE PrepCall*(VAR x: DevCPT.Node; VAR fpar: DevCPT.Object);
  1778. BEGIN
  1779. IF (x.obj # NIL) & (x.obj.mode IN {LProc, XProc, TProc, CProc}) THEN
  1780. fpar := x.obj.link;
  1781. IF x.obj.mode = TProc THEN
  1782. IF fpar.typ.form = Pointer THEN
  1783. IF x.left.class = Nderef THEN x.left := x.left.left (*undo DeRef*) ELSE err(71) END
  1784. END;
  1785. fpar := fpar.link
  1786. END
  1787. ELSIF (x.class # Ntype) & (x.typ # NIL) & (x.typ.form = ProcTyp) THEN
  1788. fpar := x.typ.link
  1789. ELSE err(121); fpar := NIL; x.typ := DevCPT.undftyp
  1790. END
  1791. END PrepCall;
  1792. PROCEDURE Param* (VAR ap: DevCPT.Node; fp: DevCPT.Object); (* checks parameter compatibilty *)
  1793. VAR at, ft: DevCPT.Struct;
  1794. BEGIN
  1795. at := ap.typ; ft := fp.typ;
  1796. IF fp.ptyp # NIL THEN ft := fp.ptyp END; (* get original formal type *)
  1797. IF ft.form # Undef THEN
  1798. IF (ap.class = Ntype) OR (ap.class = Nproc) & (ft.form # ProcTyp) THEN err(126) END;
  1799. IF fp.mode = VarPar THEN
  1800. IF ODD(fp.sysflag DIV nilBit) & (at = DevCPT.niltyp) THEN (* ok *)
  1801. ELSIF (ft.comp = Record) & ~ft.untagged & (ap.class = Ndop) & (ap.subcl = thisrecfn) THEN (* ok *)
  1802. ELSIF (ft.comp = DynArr) & ~ft.untagged & (ft.n = 0) & (ap.class = Ndop) & (ap.subcl = thisarrfn) THEN
  1803. (* ok *)
  1804. ELSE
  1805. IF fp.vis = inPar THEN
  1806. IF (ft = DevCPT.guidtyp) & (ap.class = Nconst) & (at.form = String8) THEN
  1807. StringToGuid(ap); at := ap.typ
  1808. (*
  1809. ELSIF ((at.form IN charSet + {String8, String16}) OR (at = DevCPT.guidtyp))
  1810. & ((ap.class = Nderef) OR (ap.class = Nconst)) THEN (* ok *)
  1811. ELSIF NotVar(ap) THEN err(122)
  1812. *)
  1813. END;
  1814. IF ~NotVar(ap) THEN CheckLeaf(ap, FALSE) END
  1815. ELSE
  1816. IF NotVar(ap) THEN err(122)
  1817. ELSIF ap.readonly THEN err(76)
  1818. ELSIF (ap.obj # NIL) & ODD(ap.obj.sysflag DIV newBit) & ~ODD(fp.sysflag DIV newBit) THEN
  1819. err(167)
  1820. ELSE MarkAsUsed(ap); CheckLeaf(ap, FALSE)
  1821. END
  1822. END;
  1823. IF ft.comp = DynArr THEN DynArrParCheck(ft, ap, fp.vis # inPar)
  1824. ELSIF ODD(fp.sysflag DIV newBit) THEN
  1825. IF ~DevCPT.Extends(at, ft) THEN err(123) END
  1826. ELSIF (ft = DevCPT.sysptrtyp) & (at.form = Pointer) THEN (* ok *)
  1827. ELSIF (fp.vis # outPar) & (ft.comp = Record) & DevCPT.Extends(at, ft) THEN (* ok *)
  1828. ELSIF covarOut & (fp.vis = outPar) & (ft.form = Pointer) & DevCPT.Extends(ft, at) THEN (* ok *)
  1829. ELSIF fp.vis = inPar THEN CheckAssign(ft, ap)
  1830. ELSIF ~DevCPT.EqualType(ft, at) THEN err(123)
  1831. END
  1832. END
  1833. ELSIF ft.comp = DynArr THEN DynArrParCheck(ft, ap, FALSE)
  1834. ELSE CheckAssign(ft, ap)
  1835. END
  1836. END
  1837. END Param;
  1838. PROCEDURE StaticLink*(dlev: BYTE; var: BOOLEAN);
  1839. VAR scope: DevCPT.Object;
  1840. BEGIN
  1841. scope := DevCPT.topScope;
  1842. WHILE dlev > 0 DO DEC(dlev);
  1843. INCL(scope.link.conval.setval, slNeeded);
  1844. scope := scope.left
  1845. END;
  1846. IF var THEN INCL(scope.link.conval.setval, imVar) END (* !!! *)
  1847. END StaticLink;
  1848. PROCEDURE Call*(VAR x: DevCPT.Node; apar: DevCPT.Node; fp: DevCPT.Object);
  1849. VAR typ: DevCPT.Struct; p: DevCPT.Node; lev: BYTE;
  1850. BEGIN
  1851. IF x.class = Nproc THEN typ := x.typ;
  1852. lev := x.obj.mnolev;
  1853. IF lev > 0 THEN StaticLink(SHORT(SHORT(DevCPT.topScope.mnolev-lev)), FALSE) END ; (* !!! *)
  1854. IF x.obj.mode = IProc THEN err(121) END
  1855. ELSIF (x.class = Nfield) & (x.obj.mode = TProc) THEN typ := x.typ;
  1856. x.class := Nproc; p := x.left; x.left := NIL; p.link := apar; apar := p; fp := x.obj.link
  1857. ELSE typ := x.typ.BaseTyp
  1858. END ;
  1859. BindNodes(Ncall, typ, x, apar); x.obj := fp
  1860. END Call;
  1861. PROCEDURE Enter*(VAR procdec: DevCPT.Node; stat: DevCPT.Node; proc: DevCPT.Object);
  1862. VAR x: DevCPT.Node;
  1863. BEGIN
  1864. x := DevCPT.NewNode(Nenter); x.typ := DevCPT.notyp; x.obj := proc;
  1865. x.left := procdec; x.right := stat; procdec := x
  1866. END Enter;
  1867. PROCEDURE Return*(VAR x: DevCPT.Node; proc: DevCPT.Object);
  1868. VAR node: DevCPT.Node;
  1869. BEGIN
  1870. IF proc = NIL THEN (* return from module *)
  1871. IF x # NIL THEN err(124) END
  1872. ELSE
  1873. IF x # NIL THEN CheckAssign(proc.typ, x)
  1874. ELSIF proc.typ # DevCPT.notyp THEN err(124)
  1875. END
  1876. END ;
  1877. node := DevCPT.NewNode(Nreturn); node.typ := DevCPT.notyp; node.obj := proc; node.left := x; x := node
  1878. END Return;
  1879. PROCEDURE Assign*(VAR x: DevCPT.Node; y: DevCPT.Node);
  1880. VAR z: DevCPT.Node;
  1881. BEGIN
  1882. IF (x.class >= Nconst) OR (x.typ.form IN {String8, String16}) THEN err(56) END ;
  1883. CheckAssign(x.typ, y);
  1884. IF x.readonly THEN err(76)
  1885. ELSIF (x.obj # NIL) & ODD(x.obj.sysflag DIV newBit) THEN err(167)
  1886. END ;
  1887. MarkAsUsed(x);
  1888. IF (y.class = Nconst) & (y.typ.form IN {String8, String16}) & (x.typ.form # Pointer) THEN AssignString(x, y)
  1889. ELSE BindNodes(Nassign, DevCPT.notyp, x, y); x.subcl := assign
  1890. END
  1891. END Assign;
  1892. PROCEDURE Inittd*(VAR inittd, last: DevCPT.Node; typ: DevCPT.Struct);
  1893. VAR node: DevCPT.Node;
  1894. BEGIN
  1895. node := DevCPT.NewNode(Ninittd); node.typ := typ;
  1896. node.conval := DevCPT.NewConst(); node.conval.intval := typ.txtpos;
  1897. IF inittd = NIL THEN inittd := node ELSE last.link := node END ;
  1898. last := node
  1899. END Inittd;
  1900. (* handling of temporary variables for string operations *)
  1901. PROCEDURE Overlap (left, right: DevCPT.Node): BOOLEAN;
  1902. BEGIN
  1903. IF right.class = Nconst THEN
  1904. RETURN FALSE
  1905. ELSIF (right.class = Ndop) & (right.subcl = plus) THEN
  1906. RETURN Overlap(left, right.left) OR Overlap(left, right.right)
  1907. ELSE
  1908. WHILE right.class = Nmop DO right := right.left END;
  1909. IF right.class = Nderef THEN right := right.left END;
  1910. IF left.typ.BaseTyp # right.typ.BaseTyp THEN RETURN FALSE END;
  1911. LOOP
  1912. IF left.class = Nvarpar THEN
  1913. WHILE (right.class = Nindex) OR (right.class = Nfield) OR (right.class = Nguard) DO
  1914. right := right.left
  1915. END;
  1916. RETURN (right.class # Nvar) OR (right.obj.mnolev < left.obj.mnolev)
  1917. ELSIF right.class = Nvarpar THEN
  1918. WHILE (left.class = Nindex) OR (left.class = Nfield) OR (left.class = Nguard) DO left := left.left END;
  1919. RETURN (left.class # Nvar) OR (left.obj.mnolev < right.obj.mnolev)
  1920. ELSIF (left.class = Nvar) & (right.class = Nvar) THEN
  1921. RETURN left.obj = right.obj
  1922. ELSIF (left.class = Nderef) & (right.class = Nderef) THEN
  1923. RETURN TRUE
  1924. ELSIF (left.class = Nindex) & (right.class = Nindex) THEN
  1925. IF (left.right.class = Nconst) & (right.right.class = Nconst)
  1926. & (left.right.conval.intval # right.right.conval.intval) THEN RETURN FALSE END;
  1927. left := left.left; right := right.left
  1928. ELSIF (left.class = Nfield) & (right.class = Nfield) THEN
  1929. IF left.obj # right.obj THEN RETURN FALSE END;
  1930. left := left.left; right := right.left;
  1931. WHILE left.class = Nguard DO left := left.left END;
  1932. WHILE right.class = Nguard DO right := right.left END
  1933. ELSE
  1934. RETURN FALSE
  1935. END
  1936. END
  1937. END
  1938. END Overlap;
  1939. PROCEDURE GetStaticLength (n: DevCPT.Node; OUT length: INTEGER);
  1940. VAR x: INTEGER;
  1941. BEGIN
  1942. IF n.class = Nconst THEN
  1943. length := n.conval.intval2 - 1
  1944. ELSIF (n.class = Ndop) & (n.subcl = plus) THEN
  1945. GetStaticLength(n.left, length); GetStaticLength(n.right, x);
  1946. IF (length >= 0) & (x >= 0) THEN length := length + x ELSE length := -1 END
  1947. ELSE
  1948. WHILE (n.class = Nmop) & (n.subcl = conv) DO n := n.left END;
  1949. IF (n.class = Nderef) & (n.subcl = 1) THEN n := n.left END;
  1950. IF n.typ.comp = Array THEN
  1951. length := n.typ.n - 1
  1952. ELSIF n.typ.comp = DynArr THEN
  1953. length := -1
  1954. ELSE (* error case *)
  1955. length := 4
  1956. END
  1957. END
  1958. END GetStaticLength;
  1959. PROCEDURE GetMaxLength (n: DevCPT.Node; VAR stat, last: DevCPT.Node; OUT length: DevCPT.Node);
  1960. VAR x: DevCPT.Node; d: INTEGER; obj: DevCPT.Object;
  1961. BEGIN
  1962. IF n.class = Nconst THEN
  1963. length := NewIntConst(n.conval.intval2 - 1)
  1964. ELSIF (n.class = Ndop) & (n.subcl = plus) THEN
  1965. GetMaxLength(n.left, stat, last, length); GetMaxLength(n.right, stat, last, x);
  1966. IF (length.class = Nconst) & (x.class = Nconst) THEN ConstOp(plus, length, x)
  1967. ELSE BindNodes(Ndop, length.typ, length, x); length.subcl := plus
  1968. END
  1969. ELSE
  1970. WHILE (n.class = Nmop) & (n.subcl = conv) DO n := n.left END;
  1971. IF (n.class = Nderef) & (n.subcl = 1) THEN n := n.left END;
  1972. IF n.typ.comp = Array THEN
  1973. length := NewIntConst(n.typ.n - 1)
  1974. ELSIF n.typ.comp = DynArr THEN
  1975. d := 0;
  1976. WHILE n.class = Nindex DO n := n.left; INC(d) END;
  1977. ASSERT((n.class = Nderef) OR (n.class = Nvar) OR (n.class = Nvarpar));
  1978. IF (n.class = Nderef) & (n.left.class # Nvar) & (n.left.class # Nvarpar) THEN
  1979. GetTempVar("@tmp", n.left.typ, obj);
  1980. x := NewLeaf(obj); Assign(x, n.left); Link(stat, last, x);
  1981. n.left := NewLeaf(obj); (* tree is manipulated here *)
  1982. n := NewLeaf(obj); DeRef(n)
  1983. END;
  1984. IF n.typ.untagged & (n.typ.comp = DynArr) & (n.typ.BaseTyp.form IN {Char8, Char16}) THEN
  1985. StrDeref(n);
  1986. BindNodes(Ndop, DevCPT.int32typ, n, NewIntConst(d)); n.subcl := len;
  1987. BindNodes(Ndop, DevCPT.int32typ, n, NewIntConst(1)); n.subcl := plus
  1988. ELSE
  1989. BindNodes(Ndop, DevCPT.int32typ, n, NewIntConst(d)); n.subcl := len;
  1990. END;
  1991. length := n
  1992. ELSE (* error case *)
  1993. length := NewIntConst(4)
  1994. END
  1995. END
  1996. END GetMaxLength;
  1997. PROCEDURE CheckBuffering* (
  1998. VAR n: DevCPT.Node; left: DevCPT.Node; par: DevCPT.Object; VAR stat, last: DevCPT.Node
  1999. );
  2000. VAR length, x: DevCPT.Node; obj: DevCPT.Object; typ: DevCPT.Struct; len, xlen: INTEGER;
  2001. BEGIN
  2002. IF (n.typ.form IN {String8, String16}) & ~(DevCPM.java IN DevCPM.options)
  2003. & ((n.class = Ndop) & (n.subcl = plus) & ((left = NIL) OR Overlap(left, n.right))
  2004. OR (n.class = Nmop) & (n.subcl = conv) & (left = NIL)
  2005. OR (par # NIL) & (par.vis = inPar) & (par.typ.comp = Array)) THEN
  2006. IF (par # NIL) & (par.typ.comp = Array) THEN
  2007. len := par.typ.n - 1
  2008. ELSE
  2009. IF left # NIL THEN GetStaticLength(left, len) ELSE len := -1 END;
  2010. GetStaticLength(n, xlen);
  2011. IF (len = -1) OR (xlen # -1) & (xlen < len) THEN len := xlen END
  2012. END;
  2013. IF len # -1 THEN
  2014. typ := DevCPT.NewStr(Comp, Array); typ.n := len + 1; typ.BaseTyp := n.typ.BaseTyp;
  2015. GetTempVar("@str", typ, obj);
  2016. x := NewLeaf(obj); Assign(x, n); Link(stat, last, x);
  2017. n := NewLeaf(obj)
  2018. ELSE
  2019. IF left # NIL THEN GetMaxLength(left, stat, last, length)
  2020. ELSE GetMaxLength(n, stat, last, length)
  2021. END;
  2022. typ := DevCPT.NewStr(Pointer, Basic);
  2023. typ.BaseTyp := DevCPT.NewStr(Comp, DynArr); typ.BaseTyp.BaseTyp := n.typ.BaseTyp;
  2024. GetTempVar("@ptr", typ, obj);
  2025. x := NewLeaf(obj); Construct(Nassign, x, length); x.subcl := newfn; Link(stat, last, x);
  2026. x := NewLeaf(obj); DeRef(x); Assign(x, n); Link(stat, last, x);
  2027. n := NewLeaf(obj); DeRef(n)
  2028. END;
  2029. StrDeref(n)
  2030. ELSIF (n.typ.form = Pointer) & (n.typ.sysflag = interface) & (left = NIL)
  2031. & ((par # NIL) OR (n.class = Ncall))
  2032. & ((n.class # Nvar) OR (n.obj.mnolev <= 0)) THEN
  2033. GetTempVar("@cip", DevCPT.punktyp, obj);
  2034. x := NewLeaf(obj); Assign(x, n); Link(stat, last, x);
  2035. n := NewLeaf(obj)
  2036. END
  2037. END CheckBuffering;
  2038. PROCEDURE CheckVarParBuffering* (VAR n: DevCPT.Node; VAR stat, last: DevCPT.Node);
  2039. VAR x: DevCPT.Node; obj: DevCPT.Object;
  2040. BEGIN
  2041. IF (n.class # Nvar) OR (n.obj.mnolev <= 0) THEN
  2042. GetTempVar("@ptr", n.typ, obj);
  2043. x := NewLeaf(obj); Assign(x, n); Link(stat, last, x);
  2044. n := NewLeaf(obj)
  2045. END
  2046. END CheckVarParBuffering;
  2047. (* case optimization *)
  2048. PROCEDURE Evaluate (n: DevCPT.Node; VAR min, max, num, dist: INTEGER; VAR head: DevCPT.Node);
  2049. VAR a: INTEGER;
  2050. BEGIN
  2051. IF n.left # NIL THEN
  2052. a := MIN(INTEGER); Evaluate(n.left, min, a, num, dist, head);
  2053. IF n.conval.intval - a > dist THEN dist := n.conval.intval - a; head := n END
  2054. ELSIF n.conval.intval < min THEN
  2055. min := n.conval.intval
  2056. END;
  2057. IF n.right # NIL THEN
  2058. a := MAX(INTEGER); Evaluate(n.right, a, max, num, dist, head);
  2059. IF a - n.conval.intval2 > dist THEN dist := a - n.conval.intval2; head := n END
  2060. ELSIF n.conval.intval2 > max THEN
  2061. max := n.conval.intval2
  2062. END;
  2063. INC(num);
  2064. IF n.conval.intval < n.conval.intval2 THEN
  2065. INC(num);
  2066. IF n.conval.intval2 - n.conval.intval > dist THEN dist := n.conval.intval2 - n.conval.intval; head := n END
  2067. END
  2068. END Evaluate;
  2069. PROCEDURE Rebuild (VAR root: DevCPT.Node; head: DevCPT.Node);
  2070. VAR n: DevCPT.Node;
  2071. BEGIN
  2072. IF root # head THEN
  2073. IF head.conval.intval2 < root.conval.intval THEN
  2074. Rebuild(root.left, head);
  2075. root.left := head.right; head.right := root; root := head
  2076. ELSE
  2077. Rebuild(root.right, head);
  2078. root.right := head.left; head.left := root; root := head
  2079. END
  2080. END
  2081. END Rebuild;
  2082. PROCEDURE OptimizeCase* (VAR n: DevCPT.Node);
  2083. VAR min, max, num, dist, limit: INTEGER; head: DevCPT.Node;
  2084. BEGIN
  2085. IF n # NIL THEN
  2086. min := MAX(INTEGER); max := MIN(INTEGER); num := 0; dist := 0; head := n;
  2087. Evaluate(n, min, max, num, dist, head);
  2088. limit := 6 * num;
  2089. IF limit < 100 THEN limit := 100 END;
  2090. IF (num > 4) & ((min > MAX(INTEGER) - limit) OR (max < min + limit)) THEN
  2091. INCL(n.conval.setval, useTable)
  2092. ELSE
  2093. IF num > 4 THEN Rebuild(n, head) END;
  2094. INCL(n.conval.setval, useTree);
  2095. OptimizeCase(n.left);
  2096. OptimizeCase(n.right)
  2097. END
  2098. END
  2099. END OptimizeCase;
  2100. (*
  2101. PROCEDURE ShowTree (n: DevCPT.Node; opts: SET);
  2102. BEGIN
  2103. IF n # NIL THEN
  2104. IF opts = {} THEN opts := n.conval.setval END;
  2105. IF useTable IN opts THEN
  2106. IF n.left # NIL THEN ShowTree(n.left, opts); DevCPM.LogW(",") END;
  2107. DevCPM.LogWNum(n.conval.intval, 1);
  2108. IF n.conval.intval2 > n.conval.intval THEN DevCPM.LogW("-"); DevCPM.LogWNum(n.conval.intval2, 1)
  2109. END;
  2110. IF n.right # NIL THEN DevCPM.LogW(","); ShowTree(n.right, opts) END
  2111. ELSIF useTree IN opts THEN
  2112. DevCPM.LogW("("); ShowTree(n.left, {}); DevCPM.LogW("|"); DevCPM.LogWNum(n.conval.intval, 1);
  2113. IF n.conval.intval2 > n.conval.intval THEN DevCPM.LogW("-"); DevCPM.LogWNum(n.conval.intval2, 1)
  2114. END;
  2115. DevCPM.LogW("|"); ShowTree(n.right, {}); DevCPM.LogW(")")
  2116. ELSE
  2117. ShowTree(n.left, opts); DevCPM.LogW(" "); DevCPM.LogWNum(n.conval.intval, 1);
  2118. IF n.conval.intval2 > n.conval.intval THEN DevCPM.LogW("-"); DevCPM.LogWNum(n.conval.intval2, 1)
  2119. END;
  2120. DevCPM.LogW(" "); ShowTree(n.right, opts)
  2121. END
  2122. END
  2123. END ShowTree;
  2124. *)
  2125. BEGIN
  2126. zero := DevCPT.NewConst(); zero.intval := 0; zero.realval := 0;
  2127. one := DevCPT.NewConst(); one.intval := 1; one.realval := 0;
  2128. two := DevCPT.NewConst(); two.intval := 2; two.realval := 0;
  2129. dummy := DevCPT.NewConst();
  2130. quot := DevCPT.NewConst()
  2131. END Dev0CPB.