2
0

CPB.txt 80 KB

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