2
0

Meta.txt 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. MODULE Meta;
  2. (* THIS IS TEXT COPY OF BlackBox 1.6-rc System/Mod/Meta.odc *)
  3. (* DO NOT EDIT *)
  4. IMPORT SYSTEM, Kernel;
  5. CONST
  6. (** result codes for object classes, type classes, visibility classes **)
  7. undef* = 0;
  8. (** object classes **)
  9. typObj* = 2; varObj* = 3; procObj* = 4; fieldObj* = 5; modObj* = 6; parObj* = 7;
  10. (** type classes **)
  11. boolTyp* = 1; sCharTyp* = 2; charTyp* = 3;
  12. byteTyp* = 4; sIntTyp* = 5; intTyp* = 6;
  13. sRealTyp* = 7; realTyp* = 8; setTyp* = 9;
  14. longTyp* = 10; anyRecTyp* = 11; anyPtrTyp* = 12;
  15. sysPtrTyp = 13;
  16. procTyp* = 16; recTyp* = 17; arrTyp* = 18; ptrTyp* = 19;
  17. (** record attributes **)
  18. final* = 0; extensible* = 1; limited* = 2; abstract* = 3;
  19. (** visibility **)
  20. hidden* = 1; readOnly* = 2; private = 3; exported* = 4;
  21. value* = 10; in* = 11; out* = 12; var* = 13;
  22. (* scanner modes *)
  23. modScan = 1; globScan = 2; recVarScan = 3; recTypeScan = 4;
  24. TYPE
  25. Name* = ARRAY 256 OF CHAR;
  26. Value* = ABSTRACT RECORD END; (* to be extended once with a single field of any type *)
  27. ArrayPtr = POINTER TO Array;
  28. Item* = RECORD (Value)
  29. obj-: INTEGER; (* typObj, varObj, procObj, fieldObj, modObj, parObj *)
  30. typ-: INTEGER; (* typObj, varObj, fieldObj, parObj: type; else: 0 *)
  31. vis-: INTEGER; (* varObj, procObj, fieldObj, parObj: vis; else: 0 *)
  32. adr-: INTEGER; (* varObj, procObj: adr; fieldObj: offs; parObj: num; else: 0 *)
  33. mod: Kernel.Module; (* static varObj, procObj, modObj: mod; else: NIL *)
  34. desc: Kernel.Type; (* typObj, varObj, fieldObj, parObj: struct; procObj: sig; else: NIL *)
  35. ptr: ArrayPtr; (* # NIL => item valid; dynamic varObj: ptr; else: dummy *)
  36. ext: Kernel.ItemExt (* all method calls forwarded if # NIL *)
  37. END;
  38. Scanner* = RECORD
  39. this-: Item;
  40. eos-: BOOLEAN; (* end of scan *)
  41. mode: INTEGER; (* modScan, globScan, recVarScan, recTypeScan *)
  42. base: INTEGER; (* recVarScan, recTypeScan: base level index *)
  43. vis: INTEGER; (* recVarScan: record vis *)
  44. adr: INTEGER; (* recVarScan: record adr *)
  45. idx: INTEGER; (* globScan, recVarScan, recTypeScan: object index *)
  46. desc: Kernel.Type; (* recVarScan, recTypeScan: record desc *)
  47. mod: Kernel.Module; (* modScan: next mod; globScan, recVarScan: source mod *)
  48. obj: Kernel.Object (* globScan, recVarScan, recTypeScan: actual object *)
  49. END;
  50. LookupFilter* = PROCEDURE (IN path: ARRAY OF CHAR; OUT i: Item; OUT done: BOOLEAN);
  51. FilterHook = POINTER TO RECORD
  52. next: FilterHook;
  53. filter: LookupFilter
  54. END;
  55. Array = EXTENSIBLE RECORD
  56. w0, w1, w2: INTEGER; (* gc header *)
  57. len: ARRAY 16 OF INTEGER (* dynamic array length table *)
  58. END;
  59. SStringPtr = POINTER TO ARRAY [1] OF SHORTCHAR;
  60. StringPtr = POINTER TO ARRAY [1] OF CHAR;
  61. VAR
  62. dummy: ArrayPtr; (* dummy object for item.ptr *)
  63. filterHook: FilterHook;
  64. (* preconditions:
  65. ASSERT(i.ptr # NIL, 20); (* invalid item *)
  66. ASSERT(i.typ >= recTyp, 21); (* wrong type *)
  67. ASSERT(i.obj = varObj, 22); (* wrong object class *)
  68. ASSERT((i.mod = NIL) OR (i.mod.refcnt >= 0), 23); (* unloaded object module *)
  69. ASSERT(i.desc.mod.refcnt >= 0, 24); (* unloaded type module *)
  70. ASSERT(d.id DIV 16 MOD 16 = 1, 25); (* value not extended once *)
  71. ASSERT(d.fields.num = 1, 26); (* not a single value field *)
  72. ASSERT(i.vis = exported, 27); (* write protected destination *)
  73. ASSERT(type.desc.base[t.id DIV 16 MOD 16] = t, 28); (* wrong pointer type *)
  74. ASSERT((i < n) & (d.obj[i].id DIV 16 MOD 16 = exported), 29); (* unexported type *)
  75. ASSERT(type.desc.id DIV 4 MOD 4 < limited, 30); (* limited or abstract type *)
  76. ASSERT(i.ext = NIL, 31); (* unsupported extension *)
  77. *)
  78. PROCEDURE DescOf (IN x: ANYREC): Kernel.Type;
  79. BEGIN
  80. RETURN SYSTEM.VAL(Kernel.Type, SYSTEM.TYP(x))
  81. END DescOf;
  82. PROCEDURE TypOf (struct: Kernel.Type): INTEGER;
  83. BEGIN
  84. IF SYSTEM.VAL(INTEGER, struct) DIV 256 = 0 THEN
  85. RETURN SYSTEM.VAL(INTEGER, struct)
  86. ELSE
  87. RETURN 16 + struct.id MOD 4
  88. END
  89. END TypOf;
  90. PROCEDURE LenOf (IN i: Item): INTEGER;
  91. BEGIN
  92. IF i.desc.size # 0 THEN RETURN i.desc.size
  93. ELSIF i.ptr = dummy THEN RETURN 0
  94. ELSE RETURN i.ptr.len[i.desc.id DIV 16 MOD 16 - 1]
  95. END
  96. END LenOf;
  97. PROCEDURE SizeOf (IN i: Item): INTEGER;
  98. VAR el: Item;
  99. BEGIN
  100. CASE i.typ OF
  101. | anyRecTyp: RETURN 0
  102. | boolTyp, sCharTyp, byteTyp: RETURN 1
  103. | charTyp, sIntTyp: RETURN 2
  104. | longTyp, realTyp: RETURN 8
  105. | recTyp: RETURN i.desc.size
  106. | arrTyp:
  107. el.desc := i.desc.base[0]; el.typ := TypOf(el.desc); el.ptr := i.ptr;
  108. RETURN LenOf(i) * SizeOf(el)
  109. ELSE RETURN 4
  110. END
  111. END SizeOf;
  112. PROCEDURE SignatureOf (IN i: Item): Kernel.Signature;
  113. BEGIN
  114. IF i.obj = procObj THEN
  115. RETURN SYSTEM.VAL(Kernel.Signature, i.desc)
  116. ELSE
  117. RETURN SYSTEM.VAL(Kernel.Signature, i.desc.base[0])
  118. END
  119. END SignatureOf;
  120. PROCEDURE GetName (IN path: ARRAY OF CHAR; OUT name: ARRAY OF CHAR; VAR i: INTEGER);
  121. VAR j: INTEGER; ch: CHAR;
  122. BEGIN
  123. j := 0; ch := path[i];
  124. WHILE (j < LEN(name) - 1) & ((ch >= "0") & (ch <= "9") OR (CAP(ch) >= "A") & (CAP(ch) <= "Z")
  125. OR (ch >= 0C0X) & (ch # "×") & (ch # "÷") & (ch <= 0FFX) OR (ch = "_")) DO
  126. name[j] := ch; INC(i); INC(j); ch := path[i]
  127. END;
  128. IF (ch = 0X) OR (ch = ".") OR (ch = "[") OR (ch = "^") THEN name[j] := 0X
  129. ELSE name[0] := 0X
  130. END
  131. END GetName;
  132. PROCEDURE LegalName (IN name: ARRAY OF CHAR): BOOLEAN;
  133. VAR i: INTEGER; ch: CHAR;
  134. BEGIN
  135. i := 0; ch := name[0];
  136. WHILE (i < LEN(name) - 1) & ((ch >= "0") & (ch <= "9") OR (CAP(ch) >= "A") & (CAP(ch) <= "Z")
  137. OR (ch >= 0C0X) & (ch # "×") & (ch # "÷") & (ch <= 0FFX) OR (ch = "_")) DO
  138. INC(i); ch := name[i]
  139. END;
  140. RETURN (i > 0) & (ch = 0X)
  141. END LegalName;
  142. (* ---------- Item properties ---------- *)
  143. PROCEDURE (VAR i: Item) Valid* (): BOOLEAN, NEW;
  144. BEGIN
  145. IF i.ext # NIL THEN RETURN i.ext.Valid() END;
  146. RETURN (i.ptr # NIL) & ((i.mod = NIL) OR (i.mod.refcnt >= 0)) & ((i.typ < recTyp) OR (i.desc.mod.refcnt >= 0))
  147. END Valid;
  148. PROCEDURE (VAR i: Item) GetTypeName* (OUT mod, type: Name), NEW;
  149. VAR n: Kernel.Name;
  150. BEGIN
  151. ASSERT(i.ext = NIL, 31);
  152. ASSERT(i.ptr # NIL, 20);
  153. ASSERT(i.typ >= recTyp, 21);
  154. ASSERT(i.desc.mod.refcnt >= 0, 24);
  155. mod := i.desc.mod.name$;
  156. Kernel.GetTypeName(i.desc, n);
  157. type := n$
  158. END GetTypeName;
  159. PROCEDURE (VAR i: Item) BaseTyp* (): INTEGER, NEW;
  160. BEGIN
  161. IF i.ext # NIL THEN RETURN i.ext.BaseTyp() END;
  162. ASSERT(i.ptr # NIL, 20);
  163. ASSERT(i.typ IN {arrTyp, recTyp, ptrTyp}, 21);
  164. RETURN TypOf(i.desc.base[0])
  165. END BaseTyp;
  166. PROCEDURE (VAR i: Item) Level* (): INTEGER, NEW;
  167. BEGIN
  168. ASSERT(i.ext = NIL, 31);
  169. ASSERT(i.ptr # NIL, 20);
  170. ASSERT(i.typ IN {recTyp, arrTyp}, 21);
  171. RETURN i.desc.id DIV 16 MOD 16
  172. END Level;
  173. PROCEDURE (VAR i: Item) Attribute* (): INTEGER, NEW;
  174. BEGIN
  175. ASSERT(i.ext = NIL, 31);
  176. ASSERT(i.ptr # NIL, 20);
  177. ASSERT(i.typ = recTyp, 21);
  178. RETURN i.desc.id DIV 4 MOD 4
  179. END Attribute;
  180. PROCEDURE (VAR i: Item) Size* (): INTEGER, NEW;
  181. BEGIN
  182. IF i.ext # NIL THEN RETURN i.ext.Size() END;
  183. ASSERT(i.ptr # NIL, 20);
  184. ASSERT(i.typ # undef, 21);
  185. RETURN SizeOf(i)
  186. END Size;
  187. PROCEDURE (VAR arr: Item) Len* (): INTEGER, NEW;
  188. BEGIN
  189. IF arr.ext # NIL THEN RETURN arr.ext.Len() END;
  190. ASSERT(arr.ptr # NIL, 20);
  191. ASSERT(arr.typ = arrTyp, 21);
  192. RETURN LenOf(arr)
  193. END Len;
  194. (* ---------- Item generation ---------- *)
  195. PROCEDURE SetUndef (VAR i: Item);
  196. BEGIN
  197. i.typ := undef; i.obj := undef; i.vis := undef;
  198. i.adr := undef; i.mod := NIL; i.desc := NIL; i.ptr := NIL; i.ext := NIL;
  199. END SetUndef;
  200. PROCEDURE SetItem (VAR i: Item; obj: Kernel.Object; mod: Kernel.Module);
  201. VAR t: Kernel.Type;
  202. BEGIN
  203. i.obj := obj.id MOD 16;
  204. i.vis := obj.id DIV 16 MOD 16;
  205. IF i.obj = procObj THEN
  206. i.typ := undef; i.desc := SYSTEM.VAL(Kernel.Type, obj.struct);
  207. i.adr := mod.procBase + obj.offs; i.mod := mod
  208. ELSE
  209. i.typ := TypOf(obj.struct); i.desc := obj.struct;
  210. IF i.obj = varObj THEN i.adr := mod.varBase + obj.offs; i.mod := mod
  211. ELSIF i.obj = fieldObj THEN i.adr := obj.offs; i.mod := NIL
  212. ELSE i.adr := undef; i.mod := NIL
  213. END
  214. END;
  215. i.ext := NIL
  216. END SetItem;
  217. PROCEDURE SetMod (VAR i: Item; mod: Kernel.Module);
  218. BEGIN
  219. i.obj := modObj; i.typ := undef; i.vis := undef;
  220. i.adr := undef; i.mod := mod; i.desc := NIL; i.ptr := dummy; i.ext := NIL
  221. END SetMod;
  222. PROCEDURE GetItem* (obj: ANYPTR; OUT i: Item);
  223. BEGIN
  224. ASSERT(obj # NIL, 28);
  225. i.obj := varObj; i.typ := recTyp; i.vis := exported;
  226. i.adr := SYSTEM.ADR(obj^); i.ptr := SYSTEM.VAL(ArrayPtr, obj);
  227. i.mod := NIL; i.desc := Kernel.TypeOf(obj); i.ext := NIL
  228. END GetItem;
  229. PROCEDURE Lookup* (IN name: ARRAY OF CHAR; OUT mod: Item);
  230. VAR m: Kernel.Module; done: BOOLEAN; filter: FilterHook;
  231. BEGIN
  232. done := FALSE; filter := filterHook;
  233. WHILE ~done & (filter # NIL) DO filter.filter(name, mod, done); filter := filter.next END;
  234. IF ~done & LegalName(name) THEN
  235. m := Kernel.ThisMod(name);
  236. IF m # NIL THEN SetMod(mod, m)
  237. ELSE SetUndef(mod)
  238. END
  239. ELSE SetUndef(mod)
  240. END
  241. END Lookup;
  242. PROCEDURE (VAR in: Item) Lookup* (IN name: ARRAY OF CHAR; VAR i: Item), NEW;
  243. VAR obj: Kernel.Object; o, v, lev, j, a: INTEGER; m: Kernel.Module; n: Kernel.Name;
  244. BEGIN
  245. IF in.ext # NIL THEN in.ext.Lookup(name, i); RETURN END;
  246. ASSERT(in.ptr # NIL, 20);
  247. IF LegalName(name) THEN
  248. IF in.obj = modObj THEN
  249. n := SHORT(name$);
  250. obj := Kernel.ThisObject(in.mod, n);
  251. IF obj # NIL THEN
  252. SetItem(i, obj, in.mod); i.ptr := dummy;
  253. IF (i.vis = hidden) OR (i.obj < typObj) THEN SetUndef(i) END
  254. ELSE SetUndef(i)
  255. END
  256. ELSIF in.typ = recTyp THEN
  257. ASSERT(in.desc.mod.refcnt >= 0, 24);
  258. lev := in.desc.id DIV 16 MOD 16; j := 0;
  259. n := SHORT(name$);
  260. REPEAT
  261. obj := Kernel.ThisField(in.desc.base[j], n); INC(j)
  262. UNTIL (obj # NIL) OR (j > lev);
  263. IF obj # NIL THEN
  264. o := in.obj; a := in.adr; v := in.vis; m := in.mod;
  265. SetItem(i, obj, m); i.ptr := in.ptr;
  266. IF i.vis # hidden THEN
  267. IF o = varObj THEN
  268. i.obj := varObj; INC(i.adr, a); i.mod := m;
  269. IF v < i.vis THEN i.vis := v END
  270. END
  271. ELSE SetUndef(i)
  272. END
  273. ELSE SetUndef(i)
  274. END
  275. ELSE HALT(21)
  276. END
  277. ELSE SetUndef(i)
  278. END
  279. END Lookup;
  280. PROCEDURE (VAR i: Item) GetBaseType* (VAR base: Item), NEW;
  281. VAR n: INTEGER;
  282. BEGIN
  283. ASSERT(i.ext = NIL, 31);
  284. ASSERT(i.ptr # NIL, 20);
  285. ASSERT(i.typ IN {arrTyp, recTyp, ptrTyp}, 21); n := 0;
  286. IF i.typ = recTyp THEN n := i.desc.id DIV 16 MOD 16 - 1 END;
  287. IF n >= 0 THEN
  288. base.obj := typObj; base.vis := undef; base.adr := undef;
  289. base.mod := NIL; base.ptr := dummy; base.ext := NIL;
  290. base.desc := i.desc.base[n];
  291. base.typ := TypOf(base.desc)
  292. ELSE
  293. SetUndef(base)
  294. END
  295. END GetBaseType;
  296. PROCEDURE (VAR rec: Item) GetThisBaseType* (level: INTEGER; VAR base: Item), NEW;
  297. BEGIN
  298. ASSERT(rec.ext = NIL, 31);
  299. ASSERT(rec.ptr # NIL, 20);
  300. ASSERT(rec.typ = recTyp, 21);
  301. ASSERT((level >= 0) & (level < 16), 28);
  302. IF level <= rec.desc.id DIV 16 MOD 16 THEN
  303. base.obj := typObj; base.vis := undef; base.adr := undef;
  304. base.mod := NIL; base.ptr := dummy; base.ext := NIL;
  305. base.desc := rec.desc.base[level];
  306. base.typ := TypOf(base.desc)
  307. ELSE
  308. SetUndef(base)
  309. END
  310. END GetThisBaseType;
  311. PROCEDURE (VAR proc: Item) NumParam* (): INTEGER, NEW;
  312. VAR sig: Kernel.Signature;
  313. BEGIN
  314. ASSERT(proc.ext = NIL, 31);
  315. ASSERT(proc.ptr # NIL, 20);
  316. ASSERT((proc.obj = procObj) OR (proc.typ = procTyp), 21);
  317. sig := SignatureOf(proc);
  318. IF sig # NIL THEN RETURN sig.num ELSE RETURN -1 END
  319. END NumParam;
  320. PROCEDURE (VAR proc: Item) GetParam* (n: INTEGER; VAR par: Item), NEW;
  321. VAR sig: Kernel.Signature;
  322. BEGIN
  323. ASSERT(proc.ext = NIL, 31);
  324. ASSERT(proc.ptr # NIL, 20);
  325. ASSERT((proc.obj = procObj) OR (proc.typ = procTyp), 21);
  326. sig := SignatureOf(proc);
  327. IF (sig # NIL) & (n >= 0) & (n < sig.num) THEN
  328. par.obj := parObj; par.adr := n;
  329. par.vis := sig.par[n].id MOD 16;
  330. par.mod := NIL; par.ptr := dummy; par.ext := NIL;
  331. par.desc := sig.par[n].struct; par.typ := TypOf(par.desc)
  332. ELSE
  333. SetUndef(par)
  334. END
  335. END GetParam;
  336. PROCEDURE (VAR proc: Item) GetParamName* (n: INTEGER; OUT name: Name), NEW;
  337. VAR sig: Kernel.Signature; mod: Kernel.Module; nm: Kernel.Name;
  338. BEGIN
  339. ASSERT(proc.ext = NIL, 31);
  340. ASSERT(proc.ptr # NIL, 20);
  341. IF proc.obj = procObj THEN mod := proc.mod
  342. ELSE ASSERT(proc.typ = procTyp, 21); mod := proc.desc.mod
  343. END;
  344. ASSERT(mod.refcnt >= 0, 23);
  345. sig := SignatureOf(proc);
  346. IF (sig # NIL) & (n >= 0) & (n < sig.num) THEN
  347. Kernel.GetObjName(mod, SYSTEM.VAL(Kernel.Object, SYSTEM.ADR(sig.par[n]) - 8), nm);
  348. name := nm$
  349. ELSE
  350. name := ""
  351. END
  352. END GetParamName;
  353. PROCEDURE (VAR proc: Item) GetReturnType* (VAR type: Item), NEW;
  354. VAR sig: Kernel.Signature;
  355. BEGIN
  356. ASSERT(proc.ext = NIL, 31);
  357. ASSERT(proc.ptr # NIL, 20);
  358. ASSERT((proc.obj = procObj) OR (proc.typ = procTyp), 21);
  359. sig := SignatureOf(proc);
  360. IF sig # NIL THEN
  361. type.obj := typObj; type.vis := undef; type.adr := undef;
  362. type.mod := NIL; type.ptr := dummy; type.ext := NIL;
  363. type.desc := sig.retStruct; type.typ := TypOf(type.desc)
  364. ELSE
  365. SetUndef(type)
  366. END
  367. END GetReturnType;
  368. PROCEDURE (VAR rec: Item) Is* (IN type: Value): BOOLEAN, NEW;
  369. VAR d: Kernel.Type;
  370. BEGIN
  371. ASSERT(rec.ext = NIL, 31);
  372. ASSERT(rec.ptr # NIL, 20);
  373. ASSERT(rec.typ = recTyp, 21);
  374. WITH type: Item DO
  375. ASSERT(type.ptr # NIL, 20);
  376. ASSERT(type.typ = recTyp, 21);
  377. d := type.desc
  378. ELSE
  379. d := DescOf(type); (* type of value rec *)
  380. ASSERT(d.id DIV 16 MOD 16 = 1, 25); (* level of type = 1*)
  381. ASSERT(d.fields.num = 1, 26); (* one field in type *)
  382. d := d.fields.obj[0].struct; (* type of field *)
  383. ASSERT(SYSTEM.VAL(INTEGER, d) DIV 256 # 0, 21); (* type is structured *)
  384. IF d.id MOD 4 = 3 THEN d := d.base[0] END (* deref ptr *)
  385. END;
  386. RETURN rec.desc.base[d.id DIV 16 MOD 16] = d (* rec IS d *)
  387. END Is;
  388. PROCEDURE (VAR ptr: Item) Deref* (VAR ref: Item), NEW;
  389. BEGIN
  390. IF ptr.ext # NIL THEN ptr.ext.Deref(ref); RETURN END;
  391. ASSERT(ptr.ptr # NIL, 20);
  392. ASSERT(ptr.typ IN {sysPtrTyp, anyPtrTyp, ptrTyp}, 21);
  393. ASSERT(ptr.obj = varObj, 22);
  394. ASSERT((ptr.mod = NIL) OR (ptr.mod.refcnt >= 0), 23);
  395. SYSTEM.GET(ptr.adr, ref.adr);
  396. IF ref.adr # 0 THEN
  397. IF ptr.typ # ptrTyp THEN ref.typ := recTyp
  398. ELSE ref.desc := ptr.desc.base[0]; ref.typ := TypOf(ref.desc)
  399. END;
  400. ref.obj := varObj; ref.mod := NIL; ref.vis := exported; (* !!! *)
  401. ref.ptr := SYSTEM.VAL(ArrayPtr, ref.adr);
  402. IF ref.typ = recTyp THEN
  403. ref.desc := DescOf(ref.ptr^); (* dynamic type *)
  404. ELSIF ref.typ = arrTyp THEN
  405. ref.adr := SYSTEM.ADR(ref.ptr.len[ref.desc.id DIV 16 MOD 16]); (* descriptor offset *)
  406. ELSE HALT(100)
  407. END
  408. ELSE SetUndef(ref)
  409. END
  410. END Deref;
  411. PROCEDURE (VAR arr: Item) Index* (index: INTEGER; VAR elem: Item), NEW;
  412. BEGIN
  413. IF arr.ext # NIL THEN arr.ext.Index(index, elem); RETURN END;
  414. ASSERT(arr.ptr # NIL, 20);
  415. ASSERT(arr.typ = arrTyp, 21);
  416. ASSERT(arr.obj = varObj, 22);
  417. IF (index >= 0) & (index < LenOf(arr)) THEN
  418. elem.obj := varObj; elem.vis := arr.vis;
  419. elem.mod := arr.mod; elem.ptr := arr.ptr; elem.ext := NIL;
  420. elem.desc := arr.desc.base[0]; elem.typ := TypOf(elem.desc);
  421. elem.adr := arr.adr + index * SizeOf(elem)
  422. ELSE
  423. SetUndef(elem)
  424. END
  425. END Index;
  426. PROCEDURE LookupPath* (IN path: ARRAY OF CHAR; OUT i: Item);
  427. VAR j, n: INTEGER; name: Name; ch: CHAR; done: BOOLEAN; filter: FilterHook;
  428. BEGIN
  429. done := FALSE; filter := filterHook;
  430. WHILE ~done & (filter # NIL) DO filter.filter(path, i, done); filter := filter.next END;
  431. IF ~done THEN
  432. j := 0;
  433. GetName(path, name, j);
  434. Lookup(name, i);
  435. IF (i.obj = modObj) & (path[j] = ".") THEN
  436. INC(j); GetName(path, name, j);
  437. i.Lookup(name, i); ch := path[j]; INC(j);
  438. WHILE (i.obj = varObj) & (ch # 0X) DO
  439. IF i.typ = ptrTyp THEN i.Deref(i) END;
  440. IF ch = "." THEN
  441. GetName(path, name, j);
  442. IF i.typ = recTyp THEN i.Lookup(name, i) ELSE SetUndef(i) END
  443. ELSIF ch = "[" THEN
  444. n := 0; ch := path[j]; INC(j);
  445. WHILE (ch >= "0") & (ch <= "9") DO n := 10 * n + ORD(ch) - ORD("0"); ch := path[j]; INC(j) END;
  446. IF (ch = "]") & (i.typ = arrTyp) THEN i.Index(n, i) ELSE SetUndef(i) END
  447. END;
  448. ch := path[j]; INC(j)
  449. END
  450. END
  451. END
  452. END LookupPath;
  453. (* ---------- Scanner ---------- *)
  454. PROCEDURE (VAR s: Scanner) ConnectToMods*, NEW;
  455. BEGIN
  456. SetUndef(s.this);
  457. s.this.ptr := dummy;
  458. s.mod := Kernel.modList;
  459. s.mode := modScan;
  460. s.eos := FALSE
  461. END ConnectToMods;
  462. PROCEDURE (VAR s: Scanner) ConnectTo* (IN obj: Item), NEW;
  463. BEGIN
  464. ASSERT(obj.ptr # NIL, 20);
  465. SetUndef(s.this); s.vis := obj.vis;
  466. s.this.ptr := obj.ptr; s.mod := obj.mod; s.idx := 0;
  467. IF obj.obj = modObj THEN
  468. ASSERT(s.mod.refcnt >= 0, 23);
  469. s.mode := globScan
  470. ELSIF obj.typ = recTyp THEN
  471. ASSERT(obj.desc.mod.refcnt >= 0, 24);
  472. s.desc := obj.desc; s.base := 0;
  473. IF obj.obj = varObj THEN s.mode := recVarScan; s.adr := obj.adr
  474. ELSE s.mode := recTypeScan
  475. END
  476. ELSE HALT(21)
  477. END;
  478. s.eos := FALSE
  479. END ConnectTo;
  480. PROCEDURE (VAR s: Scanner) Scan*, NEW;
  481. VAR desc: Kernel.Type;
  482. BEGIN
  483. ASSERT(s.this.ptr # NIL, 20);
  484. IF s.mode = modScan THEN
  485. IF s.mod # NIL THEN SetMod(s.this, s.mod); s.mod := s.mod.next
  486. ELSE SetUndef(s.this); s.eos := TRUE
  487. END
  488. ELSIF s.mode = globScan THEN
  489. ASSERT(s.mod.refcnt >= 0, 23);
  490. REPEAT
  491. IF s.idx >= s.mod.export.num THEN SetUndef(s.this); s.eos := TRUE; RETURN END;
  492. s.obj := SYSTEM.VAL(Kernel.Object, SYSTEM.ADR(s.mod.export.obj[s.idx]));
  493. SetItem(s.this, s.obj, s.mod); INC(s.idx)
  494. UNTIL (s.this.obj IN {procObj, varObj, typObj}) & (s.this.vis # hidden)
  495. ELSE
  496. ASSERT(s.desc.mod.refcnt >= 0, 24);
  497. desc := s.desc.base[s.base];
  498. REPEAT
  499. WHILE s.idx >= desc.fields.num DO
  500. IF desc = s.desc THEN SetUndef(s.this); s.eos := TRUE; RETURN END;
  501. INC(s.base); desc := s.desc.base[s.base]; s.idx := 0
  502. END;
  503. s.obj := SYSTEM.VAL(Kernel.Object, SYSTEM.ADR(desc.fields.obj[s.idx]));
  504. SetItem(s.this, s.obj, s.mod); INC(s.idx)
  505. UNTIL s.this.vis # hidden;
  506. IF s.mode = recVarScan THEN
  507. s.this.obj := varObj; INC(s.this.adr, s.adr); s.this.mod := s.mod;
  508. IF s.vis < s.this.vis THEN s.this.vis := s.vis END
  509. END
  510. END
  511. END Scan;
  512. PROCEDURE (VAR s: Scanner) GetObjName* (OUT name: Name), NEW;
  513. VAR mod: Kernel.Module; n: Kernel.Name;
  514. BEGIN
  515. ASSERT(s.this.ptr # NIL, 20);
  516. IF s.mode = modScan THEN
  517. name := s.this.mod.name$ (* mf 24.08.2004 *)
  518. ELSE
  519. IF s.mode = globScan THEN mod := s.mod
  520. ELSE mod := s.desc.base[s.base].mod
  521. END;
  522. ASSERT(mod.refcnt >= 0, 23);
  523. Kernel.GetObjName(mod, s.obj, n);
  524. name := n$;
  525. END
  526. END GetObjName;
  527. PROCEDURE (VAR s: Scanner) Level* (): INTEGER, NEW;
  528. BEGIN
  529. ASSERT(s.this.ptr # NIL, 20);
  530. ASSERT(s.mode >= recVarScan, 22);
  531. RETURN s.base
  532. END Level;
  533. (* ---------- access to item values ---------- *)
  534. PROCEDURE ValToItem (IN x: Value; VAR i: Item);
  535. VAR desc: Kernel.Type;
  536. BEGIN
  537. desc := DescOf(x);
  538. ASSERT(desc.id DIV 16 MOD 16 = 1, 25); (* level of x = 1*)
  539. ASSERT(desc.fields.num = 1, 26); (* one field in x *)
  540. i.desc := desc.fields.obj[0].struct;
  541. i.typ := TypOf(i.desc); i.obj := varObj; i.ext := NIL; i.vis := exported;
  542. i.ptr := dummy; i.adr := SYSTEM.ADR(x)
  543. END ValToItem;
  544. PROCEDURE^ EqualSignature (a, b: Kernel.Signature): BOOLEAN;
  545. PROCEDURE EqualType (a, b: Kernel.Type): BOOLEAN;
  546. BEGIN
  547. LOOP
  548. IF a = b THEN RETURN TRUE END;
  549. IF (SYSTEM.VAL(INTEGER, a) DIV 256 = 0)
  550. OR (SYSTEM.VAL(INTEGER, b) DIV 256 = 0)
  551. OR (a.id MOD 4 # b.id MOD 4) THEN RETURN FALSE END;
  552. CASE a.id MOD 4 OF
  553. | recTyp - 16: RETURN FALSE
  554. | arrTyp - 16: IF (a.size # 0) OR (b.size # 0) THEN RETURN FALSE END
  555. | procTyp - 16: RETURN EqualSignature(SYSTEM.VAL(Kernel.Signature, a.base[0]),
  556. SYSTEM.VAL(Kernel.Signature, b.base[0]))
  557. ELSE (* ptrTyp *)
  558. END;
  559. a := a.base[0]; b := b.base[0]
  560. END
  561. END EqualType;
  562. PROCEDURE EqualSignature (a, b: Kernel.Signature): BOOLEAN;
  563. VAR i: INTEGER;
  564. BEGIN
  565. IF (a.num # b.num) OR ~EqualType(a.retStruct, b.retStruct) THEN RETURN FALSE END;
  566. i := 0;
  567. WHILE i < a.num DO
  568. IF (a.par[i].id MOD 256 # b.par[i].id MOD 256)
  569. OR ~EqualType(a.par[i].struct, b.par[i].struct) THEN RETURN FALSE END;
  570. INC(i)
  571. END;
  572. RETURN TRUE
  573. END EqualSignature;
  574. PROCEDURE Copy (IN a, b: Item; OUT ok: BOOLEAN); (* b := a *)
  575. VAR n: INTEGER; at, bt: Item;
  576. BEGIN
  577. ok := FALSE;
  578. IF a.obj = procObj THEN
  579. IF (b.typ # procTyp)
  580. OR ~EqualSignature(SignatureOf(a), SignatureOf(b)) THEN RETURN END;
  581. SYSTEM.PUT(b.adr, a.adr);
  582. ELSE (* a.obj = varObj *)
  583. IF a.typ # b.typ THEN RETURN END;
  584. IF a.typ >= recTyp THEN
  585. IF a.typ = ptrTyp THEN
  586. at.desc := a.desc.base[0]; at.typ := TypOf(at.desc); at.ptr := dummy; at.ext := NIL;
  587. bt.desc := b.desc.base[0]; bt.typ := TypOf(bt.desc); bt.ptr := dummy; bt.ext := NIL;
  588. SYSTEM.GET(a.adr, n);
  589. IF (at.typ = recTyp) & (n # 0) THEN
  590. SYSTEM.GET(SYSTEM.VAL(INTEGER, n) - 4, at.desc); (* dynamic type *)
  591. at.desc := at.desc.base[bt.desc.id DIV 16 MOD 16] (* projection to b *)
  592. END
  593. ELSE at := a; bt := b
  594. END;
  595. WHILE (at.typ = arrTyp) & (bt.typ = arrTyp) DO
  596. IF LenOf(at) # LenOf(bt) THEN RETURN END;
  597. at.desc := at.desc.base[0]; at.typ := TypOf(at.desc);
  598. bt.desc := bt.desc.base[0]; bt.typ := TypOf(bt.desc)
  599. END;
  600. IF (at.desc # bt.desc) &
  601. ~((at.typ = procTyp) & (bt.typ = procTyp)
  602. & EqualSignature(SignatureOf(at), SignatureOf(bt))) THEN RETURN END
  603. END;
  604. SYSTEM.MOVE(a.adr, b.adr, SizeOf(b))
  605. END;
  606. ok := TRUE
  607. END Copy;
  608. PROCEDURE (VAR proc: Item) Call* (OUT ok: BOOLEAN), NEW;
  609. VAR p: Kernel.Command; sig: Kernel.Signature;
  610. BEGIN
  611. IF proc.ext # NIL THEN proc.ext.Call(ok); RETURN END;
  612. ASSERT(proc.ptr # NIL, 20);
  613. IF proc.obj = procObj THEN
  614. p := SYSTEM.VAL(Kernel.Command, proc.adr)
  615. ELSE ASSERT((proc.obj = varObj) & (proc.typ = procTyp), 22);
  616. SYSTEM.GET(proc.adr, p)
  617. END;
  618. ASSERT((proc.mod = NIL) OR (proc.mod.refcnt >= 0), 23);
  619. sig := SignatureOf(proc);
  620. IF (sig.retStruct = NIL) & (sig.num = 0) & (p # NIL) THEN p(); ok := TRUE
  621. ELSE ok := FALSE
  622. END
  623. END Call;
  624. PROCEDURE PutParam (IN par: Item; sig: Kernel.Signature; p: INTEGER;
  625. VAR data: ARRAY OF INTEGER; VAR n: INTEGER;
  626. OUT ok: BOOLEAN); (* check & assign a parameter *)
  627. VAR mode, fTyp, aTyp, padr, i: INTEGER; fDesc, aDesc: Kernel.Type;
  628. l: LONGINT; s: SHORTINT; b: BYTE;
  629. BEGIN
  630. ok := FALSE;
  631. ASSERT(par.ext = NIL, 31);
  632. ASSERT(par.ptr # NIL, 20);
  633. ASSERT(par.obj = varObj, 22);
  634. ASSERT((par.mod = NIL) OR (par.mod.refcnt >= 0), 23);
  635. mode := sig.par[p].id MOD 16;
  636. IF mode >= out THEN ASSERT(par.vis = exported, 27) END;
  637. fDesc := sig.par[p].struct;
  638. fTyp := TypOf(fDesc);
  639. aDesc := par.desc;
  640. aTyp := TypOf(aDesc);
  641. padr := par.adr;
  642. IF (fTyp = recTyp) OR (fTyp = anyRecTyp) THEN
  643. IF (aTyp # recTyp)
  644. OR (mode = value) & (aDesc # fDesc)
  645. OR (fTyp = recTyp) & (aDesc.base[fDesc.id DIV 16 MOD 16] # fDesc) THEN RETURN END;
  646. data[n] := padr; INC(n);
  647. data[n] := SYSTEM.VAL(INTEGER, aDesc); INC(n)
  648. ELSIF fTyp = arrTyp THEN
  649. data[n] := padr; INC(n);
  650. IF fDesc.size # 0 THEN data[n] := SizeOf(par); INC(n) END;
  651. WHILE (TypOf(fDesc) = arrTyp) & (TypOf(aDesc) = arrTyp) DO
  652. IF aDesc.size # 0 THEN i := aDesc.size (* actual static size *)
  653. ELSE i := par.ptr.len[aDesc.id DIV 16 MOD 16 - 1] (* actual dynamic size *)
  654. END;
  655. IF fDesc.size = 0 THEN data[n] := i; INC(n)
  656. ELSIF fDesc.size # i THEN RETURN
  657. END;
  658. fDesc := fDesc.base[0]; aDesc := aDesc.base[0]
  659. END;
  660. IF fDesc # aDesc THEN RETURN END
  661. ELSIF fTyp >= anyPtrTyp THEN (* pointer *)
  662. IF fTyp = ptrTyp THEN
  663. fDesc := fDesc.base[0]; (* formal base type *)
  664. IF (mode = value) & (TypOf(fDesc) = recTyp) THEN
  665. IF (aTyp # ptrTyp) & (aTyp # anyPtrTyp) THEN RETURN END;
  666. SYSTEM.GET(padr, i); SYSTEM.GET(i - 4, aDesc); (* dynamic record type *)
  667. aDesc := aDesc.base[fDesc.id DIV 16 MOD 16] (* projection *)
  668. ELSE
  669. IF aTyp # ptrTyp THEN RETURN END;
  670. aDesc := aDesc.base[0]; (* actual base type *)
  671. WHILE (TypOf(fDesc) = arrTyp) & (TypOf(aDesc) = arrTyp) DO
  672. IF fDesc.size # aDesc.size THEN RETURN END;
  673. fDesc := fDesc.base[0]; aDesc := aDesc.base[0]
  674. END
  675. END;
  676. IF fDesc # aDesc THEN RETURN END
  677. ELSIF fTyp = anyPtrTyp THEN
  678. IF (aTyp # anyPtrTyp) & ((aTyp # ptrTyp) OR (TypOf(aDesc.base[0]) # recTyp)) THEN RETURN END
  679. ELSIF fTyp = procTyp THEN
  680. IF (aTyp # procTyp) OR (fDesc.size # aDesc.size) THEN RETURN END (* same fingerprint *)
  681. END;
  682. IF mode = value THEN SYSTEM.GET(padr, data[n]); INC(n)
  683. ELSE data[n] := padr; INC(n)
  684. END
  685. ELSE (* basic type *)
  686. IF fTyp # aTyp THEN RETURN END;
  687. IF mode = value THEN
  688. CASE SizeOf(par) OF
  689. | 1: SYSTEM.GET(padr, b); data[n] := b; INC(n)
  690. | 2: SYSTEM.GET(padr, s); data[n] := s; INC(n)
  691. | 4: SYSTEM.GET(padr, i); data[n] := i; INC(n)
  692. | 8: SYSTEM.GET(padr, l); data[n] := SHORT(l); INC(n); data[n] := SHORT(l DIV 100000000L); INC(n)
  693. END
  694. ELSE (* var par *)
  695. data[n] := padr; INC(n)
  696. END
  697. END;
  698. ok := TRUE
  699. END PutParam;
  700. PROCEDURE GetResult (ret: LONGINT; VAR dest: Item; sig: Kernel.Signature;
  701. OUT ok: BOOLEAN); (* assign return value *)
  702. VAR x: Item; i: INTEGER; s: SHORTINT; b: BYTE;
  703. BEGIN
  704. ASSERT(dest.ext = NIL, 31);
  705. ASSERT(dest.ptr # NIL, 20);
  706. ASSERT(dest.obj = varObj, 22);
  707. ASSERT((dest.mod = NIL) OR (dest.mod.refcnt >= 0), 23);
  708. ASSERT(dest.vis = exported, 27);
  709. x.desc := sig.retStruct; x.typ := TypOf(x.desc);
  710. x.obj := varObj; x.ptr := dummy;
  711. CASE TypOf(sig.retStruct) OF
  712. | boolTyp, sCharTyp, byteTyp: b := SHORT(SHORT(SHORT(ret))); x.adr := SYSTEM.ADR(b);
  713. | charTyp, sIntTyp: s := SHORT(SHORT(ret)); x.adr := SYSTEM.ADR(s);
  714. | longTyp, realTyp: x.adr := SYSTEM.ADR(ret);
  715. | intTyp, sRealTyp, setTyp, anyPtrTyp, procTyp, ptrTyp: i := SHORT(ret); x.adr := SYSTEM.ADR(i);
  716. END;
  717. Copy(x, dest, ok)
  718. END GetResult;
  719. PROCEDURE (VAR proc: Item) ParamCall* (IN par: ARRAY OF Item; VAR dest: Item;
  720. OUT ok: BOOLEAN), NEW;
  721. VAR n, p, adr, padr: INTEGER; ret: LONGINT;
  722. data: ARRAY 256 OF INTEGER; sig: Kernel.Signature;
  723. BEGIN
  724. ok := TRUE;
  725. ASSERT(proc.ext = NIL, 31);
  726. ASSERT(proc.ptr # NIL, 20);
  727. IF proc.obj = procObj THEN adr := proc.adr
  728. ELSE ASSERT((proc.obj = varObj) & (proc.typ = procTyp), 22);
  729. SYSTEM.GET(proc.adr, adr);
  730. IF adr = 0 THEN ok := FALSE; RETURN END
  731. END;
  732. ASSERT((proc.mod = NIL) OR (proc.mod.refcnt >= 0), 23);
  733. sig := SignatureOf(proc);
  734. ASSERT((sig # NIL) & (LEN(par) >= sig.num), 32);
  735. n := 0; p := 0;
  736. WHILE ok & (p < sig.num) DO (* check & assign parameters *)
  737. PutParam(par[p], sig, p, data, n, ok);
  738. INC(p)
  739. END;
  740. IF ok THEN
  741. ret := Kernel.Call(adr, sig, data, n);
  742. IF sig.retStruct # NIL THEN GetResult(ret, dest, sig, ok) END
  743. END
  744. END ParamCall;
  745. PROCEDURE (VAR proc: Item) ParamCallVal* (IN par: ARRAY OF POINTER TO Value; VAR dest: Value;
  746. OUT ok: BOOLEAN), NEW;
  747. TYPE IP = POINTER TO Item;
  748. VAR n, p, adr, padr: INTEGER; ret: LONGINT; x: Item;
  749. data: ARRAY 256 OF INTEGER; sig: Kernel.Signature;
  750. BEGIN
  751. ok := TRUE;
  752. ASSERT(proc.ext = NIL, 31);
  753. ASSERT(proc.ptr # NIL, 20);
  754. IF proc.obj = procObj THEN adr := proc.adr
  755. ELSE ASSERT((proc.obj = varObj) & (proc.typ = procTyp), 22);
  756. SYSTEM.GET(proc.adr, adr);
  757. IF adr = 0 THEN ok := FALSE; RETURN END
  758. END;
  759. ASSERT((proc.mod = NIL) OR (proc.mod.refcnt >= 0), 23);
  760. sig := SignatureOf(proc);
  761. ASSERT((sig # NIL) & (LEN(par) >= sig.num), 32);
  762. n := 0; p := 0;
  763. WHILE ok & (p < sig.num) DO (* check & assign parameters *)
  764. IF par[p] IS IP THEN
  765. PutParam(par[p](IP)^, sig, p, data, n, ok)
  766. ELSE
  767. ValToItem(par[p]^, x);
  768. PutParam(x, sig, p, data, n, ok)
  769. END;
  770. INC(p)
  771. END;
  772. IF ok THEN
  773. ret := Kernel.Call(adr, sig, data, n);
  774. IF sig.retStruct # NIL THEN
  775. WITH dest: Item DO
  776. GetResult(ret, dest, sig, ok)
  777. ELSE
  778. ValToItem(dest, x);
  779. GetResult(ret, x, sig, ok)
  780. END
  781. END
  782. END
  783. END ParamCallVal;
  784. PROCEDURE (VAR var: Item) GetVal* (VAR x: Value; OUT ok: BOOLEAN), NEW;
  785. VAR xi: Item;
  786. BEGIN
  787. ASSERT(var.ext = NIL, 31);
  788. ASSERT(var.ptr # NIL, 20);
  789. ASSERT(var.obj IN {varObj, procObj}, 22);
  790. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  791. WITH x: Item DO
  792. ASSERT(x.ptr # NIL, 20);
  793. ASSERT(x.obj = varObj, 22);
  794. ASSERT((x.mod = NIL) OR (x.mod.refcnt >= 0), 23);
  795. ASSERT(x.vis = exported, 27);
  796. Copy(var, x, ok)
  797. ELSE
  798. ValToItem(x, xi); Copy(var, xi, ok)
  799. END
  800. END GetVal;
  801. PROCEDURE (VAR var: Item) PutVal* (IN x: Value; OUT ok: BOOLEAN), NEW;
  802. VAR xi: Item;
  803. BEGIN
  804. ASSERT(var.ext = NIL, 31);
  805. ASSERT(var.ptr # NIL, 20);
  806. ASSERT(var.obj = varObj, 22);
  807. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  808. ASSERT(var.vis = exported, 27);
  809. WITH x: Item DO
  810. ASSERT(x.ptr # NIL, 20);
  811. ASSERT(x.obj IN {varObj, procObj}, 22);
  812. ASSERT((x.mod = NIL) OR (x.mod.refcnt >= 0), 23);
  813. Copy(x, var, ok)
  814. ELSE
  815. ValToItem(x, xi); Copy(xi, var, ok)
  816. END
  817. END PutVal;
  818. PROCEDURE (VAR var: Item) GetStringVal* (OUT x: ARRAY OF CHAR; OUT ok: BOOLEAN), NEW;
  819. VAR i, n: INTEGER; p: StringPtr;
  820. BEGIN
  821. IF var.ext # NIL THEN var.ext.GetStringVal(x, ok); RETURN END;
  822. ASSERT(var.ptr # NIL, 20);
  823. ASSERT((var.typ = arrTyp) & (SYSTEM.VAL(INTEGER, var.desc.base[0]) = charTyp), 21);
  824. ASSERT(var.obj = varObj, 22);
  825. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  826. p := SYSTEM.VAL(StringPtr, var.adr); i := 0; n := LenOf(var);
  827. WHILE (i < n) & (p[i] # 0X) DO INC(i) END;
  828. IF (i < n) & (i < LEN(x)) THEN x := p^$; ok := TRUE
  829. ELSE x := ""; ok := FALSE
  830. END
  831. END GetStringVal;
  832. PROCEDURE (VAR var: Item) GetSStringVal* (OUT x: ARRAY OF SHORTCHAR; OUT ok: BOOLEAN), NEW;
  833. VAR i, n: INTEGER; p: SStringPtr;
  834. BEGIN
  835. IF var.ext # NIL THEN var.ext.GetSStringVal(x, ok); RETURN END;
  836. ASSERT(var.ptr # NIL, 20);
  837. ASSERT((var.typ = arrTyp) & (SYSTEM.VAL(INTEGER, var.desc.base[0]) = sCharTyp), 21);
  838. ASSERT(var.obj = varObj, 22);
  839. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  840. p := SYSTEM.VAL(SStringPtr, var.adr); i := 0; n := LenOf(var);
  841. WHILE (i < n) & (p[i] # 0X) DO INC(i) END;
  842. IF (i < n) & (i < LEN(x)) THEN x := p^$; ok := TRUE
  843. ELSE x := ""; ok := FALSE
  844. END
  845. END GetSStringVal;
  846. PROCEDURE (VAR var: Item) PutStringVal* (IN x: ARRAY OF CHAR; OUT ok: BOOLEAN), NEW;
  847. VAR i: INTEGER; p: StringPtr;
  848. BEGIN
  849. IF var.ext # NIL THEN var.ext.PutStringVal(x, ok); RETURN END;
  850. ASSERT(var.ptr # NIL, 20);
  851. ASSERT((var.typ = arrTyp) & (SYSTEM.VAL(INTEGER, var.desc.base[0]) = charTyp), 21);
  852. ASSERT(var.obj = varObj, 22);
  853. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  854. ASSERT(var.vis = exported, 27);
  855. p := SYSTEM.VAL(StringPtr, var.adr); i := 0;
  856. WHILE (i < LEN(x)) & (x[i] # 0X) DO INC(i) END;
  857. IF (i < LEN(x)) & (i < LenOf(var)) THEN p^ := x$; ok := TRUE
  858. ELSE ok := FALSE
  859. END
  860. END PutStringVal;
  861. PROCEDURE (VAR var: Item) PutSStringVal* (IN x: ARRAY OF SHORTCHAR; OUT ok: BOOLEAN), NEW;
  862. VAR i: INTEGER; p: SStringPtr;
  863. BEGIN
  864. IF var.ext # NIL THEN var.ext.PutSStringVal(x, ok); RETURN END;
  865. ASSERT(var.ptr # NIL, 20);
  866. ASSERT((var.typ = arrTyp) & (SYSTEM.VAL(INTEGER, var.desc.base[0]) = sCharTyp), 21);
  867. ASSERT(var.obj = varObj, 22);
  868. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  869. ASSERT(var.vis = exported, 27);
  870. p := SYSTEM.VAL(SStringPtr, var.adr); i := 0;
  871. WHILE (i < LEN(x)) & (x[i] # 0X) DO INC(i) END;
  872. IF (i < LEN(x)) & (i < LenOf(var)) THEN p^ := x$; ok := TRUE
  873. ELSE ok := FALSE
  874. END
  875. END PutSStringVal;
  876. PROCEDURE (VAR var: Item) PtrVal* (): ANYPTR, NEW;
  877. VAR p: ANYPTR;
  878. BEGIN
  879. IF var.ext # NIL THEN RETURN var.ext.PtrVal() END;
  880. ASSERT(var.ptr # NIL, 20);
  881. ASSERT(var.typ IN {anyPtrTyp, ptrTyp}, 21);
  882. ASSERT(var.obj = varObj, 22);
  883. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  884. SYSTEM.GET(var.adr, p);
  885. RETURN p
  886. END PtrVal;
  887. PROCEDURE (VAR var: Item) PutPtrVal* (x: ANYPTR), NEW;
  888. VAR vt, xt: Kernel.Type;
  889. BEGIN
  890. IF var.ext # NIL THEN var.ext.PutPtrVal(x); RETURN END;
  891. ASSERT(var.ptr # NIL, 20);
  892. ASSERT(var.typ IN {anyPtrTyp, ptrTyp}, 21);
  893. ASSERT(var.obj = varObj, 22);
  894. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  895. ASSERT(var.vis = exported, 27);
  896. IF (x # NIL) & (var.typ = ptrTyp) THEN
  897. vt := var.desc.base[0]; xt := Kernel.TypeOf(x);
  898. ASSERT(xt.base[vt.id DIV 16 MOD 16] = vt, 28); (* xt IS vt *)
  899. END;
  900. SYSTEM.PUT(var.adr, x)
  901. END PutPtrVal;
  902. PROCEDURE (VAR var: Item) IntVal* (): INTEGER, NEW;
  903. VAR sc: SHORTCHAR; ch: CHAR; s: BYTE; i: SHORTINT; x: INTEGER;
  904. BEGIN
  905. IF var.ext # NIL THEN RETURN var.ext.IntVal() END;
  906. ASSERT(var.ptr # NIL, 20);
  907. ASSERT(var.obj = varObj, 22);
  908. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  909. IF var.typ = sCharTyp THEN SYSTEM.GET(var.adr, sc); x := ORD(sc)
  910. ELSIF var.typ = charTyp THEN SYSTEM.GET(var.adr, ch); x := ORD(ch)
  911. ELSIF var.typ = byteTyp THEN SYSTEM.GET(var.adr, s); x := s
  912. ELSIF var.typ = sIntTyp THEN SYSTEM.GET(var.adr, i); x := i
  913. ELSIF var.typ = intTyp THEN SYSTEM.GET(var.adr, x)
  914. ELSE HALT(21)
  915. END;
  916. RETURN x
  917. END IntVal;
  918. PROCEDURE (VAR var: Item) PutIntVal* (x: INTEGER), NEW;
  919. BEGIN
  920. IF var.ext # NIL THEN var.ext.PutIntVal(x); RETURN END;
  921. ASSERT(var.ptr # NIL, 20);
  922. ASSERT(var.obj = varObj, 22);
  923. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  924. ASSERT(var.vis = exported, 27);
  925. IF var.typ = sCharTyp THEN SYSTEM.PUT(var.adr, SHORT(CHR(x)))
  926. ELSIF var.typ = charTyp THEN SYSTEM.PUT(var.adr, CHR(x))
  927. ELSIF var.typ = byteTyp THEN SYSTEM.PUT(var.adr, SHORT(SHORT(x)))
  928. ELSIF var.typ = sIntTyp THEN SYSTEM.PUT(var.adr, SHORT(x))
  929. ELSIF var.typ = intTyp THEN SYSTEM.PUT(var.adr, x)
  930. ELSE HALT(21)
  931. END
  932. END PutIntVal;
  933. PROCEDURE (VAR var: Item) RealVal* (): REAL, NEW;
  934. VAR r: SHORTREAL; x: REAL;
  935. BEGIN
  936. IF var.ext # NIL THEN RETURN var.ext.RealVal() END;
  937. ASSERT(var.ptr # NIL, 20);
  938. ASSERT(var.obj = varObj, 22);
  939. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  940. IF var.typ = sRealTyp THEN SYSTEM.GET(var.adr, r); x := r
  941. ELSIF var.typ = realTyp THEN SYSTEM.GET(var.adr, x)
  942. ELSE HALT(21)
  943. END;
  944. RETURN x
  945. END RealVal;
  946. PROCEDURE (VAR var: Item) PutRealVal* (x: REAL), NEW;
  947. BEGIN
  948. IF var.ext # NIL THEN var.ext.PutRealVal(x); RETURN END;
  949. ASSERT(var.ptr # NIL, 20);
  950. ASSERT(var.obj = varObj, 22);
  951. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  952. ASSERT(var.vis = exported, 27);
  953. IF var.typ = sRealTyp THEN SYSTEM.PUT(var.adr, SHORT(x))
  954. ELSIF var.typ = realTyp THEN SYSTEM.PUT(var.adr, x)
  955. ELSE HALT(21)
  956. END
  957. END PutRealVal;
  958. PROCEDURE (VAR var: Item) LongVal* (): LONGINT, NEW;
  959. VAR x: LONGINT;
  960. BEGIN
  961. IF var.ext # NIL THEN RETURN var.ext.LongVal() END;
  962. ASSERT(var.ptr # NIL, 20);
  963. ASSERT(var.typ = longTyp, 21);
  964. ASSERT(var.obj = varObj, 22);
  965. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  966. SYSTEM.GET(var.adr, x);
  967. RETURN x
  968. END LongVal;
  969. PROCEDURE (VAR var: Item) PutLongVal* (x: LONGINT), NEW;
  970. BEGIN
  971. IF var.ext # NIL THEN var.ext.PutLongVal(x); RETURN END;
  972. ASSERT(var.ptr # NIL, 20);
  973. ASSERT(var.typ = longTyp, 21);
  974. ASSERT(var.obj = varObj, 22);
  975. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  976. ASSERT(var.vis = exported, 27);
  977. SYSTEM.PUT(var.adr, x)
  978. END PutLongVal;
  979. PROCEDURE (VAR var: Item) CharVal* (): CHAR, NEW;
  980. VAR x: CHAR; s: SHORTCHAR;
  981. BEGIN
  982. IF var.ext # NIL THEN RETURN var.ext.CharVal() END;
  983. ASSERT(var.ptr # NIL, 20);
  984. ASSERT(var.obj = varObj, 22);
  985. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  986. IF var.typ = sCharTyp THEN SYSTEM.GET(var.adr, s); x := s
  987. ELSIF var.typ = charTyp THEN SYSTEM.GET(var.adr, x)
  988. ELSE HALT(21)
  989. END;
  990. RETURN x
  991. END CharVal;
  992. PROCEDURE (VAR var: Item) PutCharVal* (x: CHAR), NEW;
  993. BEGIN
  994. IF var.ext # NIL THEN var.ext.PutCharVal(x); RETURN END;
  995. ASSERT(var.ptr # NIL, 20);
  996. ASSERT(var.obj = varObj, 22);
  997. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  998. ASSERT(var.vis = exported, 27);
  999. IF var.typ = sCharTyp THEN SYSTEM.PUT(var.adr, SHORT(x))
  1000. ELSIF var.typ = charTyp THEN SYSTEM.PUT(var.adr, x)
  1001. ELSE HALT(21)
  1002. END
  1003. END PutCharVal;
  1004. PROCEDURE (VAR var: Item) BoolVal* (): BOOLEAN, NEW;
  1005. VAR x: BOOLEAN;
  1006. BEGIN
  1007. IF var.ext # NIL THEN RETURN var.ext.BoolVal() END;
  1008. ASSERT(var.ptr # NIL, 20);
  1009. ASSERT(var.typ = boolTyp, 21);
  1010. ASSERT(var.obj = varObj, 22);
  1011. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  1012. SYSTEM.GET(var.adr, x);
  1013. RETURN x
  1014. END BoolVal;
  1015. PROCEDURE (VAR var: Item) PutBoolVal* (x: BOOLEAN), NEW;
  1016. BEGIN
  1017. IF var.ext # NIL THEN var.ext.PutBoolVal(x); RETURN END;
  1018. ASSERT(var.ptr # NIL, 20);
  1019. ASSERT(var.typ = boolTyp, 21);
  1020. ASSERT(var.obj = varObj, 22);
  1021. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  1022. ASSERT(var.vis = exported, 27);
  1023. SYSTEM.PUT(var.adr, x)
  1024. END PutBoolVal;
  1025. PROCEDURE (VAR var: Item) SetVal* (): SET, NEW;
  1026. VAR x: SET;
  1027. BEGIN
  1028. IF var.ext # NIL THEN RETURN var.ext.SetVal() END;
  1029. ASSERT(var.ptr # NIL, 20);
  1030. ASSERT(var.typ = setTyp, 21);
  1031. ASSERT(var.obj = varObj, 22);
  1032. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  1033. SYSTEM.GET(var.adr, x);
  1034. RETURN x
  1035. END SetVal;
  1036. PROCEDURE (VAR var: Item) PutSetVal* (x: SET), NEW;
  1037. BEGIN
  1038. IF var.ext # NIL THEN var.ext.PutSetVal(x); RETURN END;
  1039. ASSERT(var.ptr # NIL, 20);
  1040. ASSERT(var.typ = setTyp, 21);
  1041. ASSERT(var.obj = varObj, 22);
  1042. ASSERT((var.mod = NIL) OR (var.mod.refcnt >= 0), 23);
  1043. ASSERT(var.vis = exported, 27);
  1044. SYSTEM.PUT(var.adr, x)
  1045. END PutSetVal;
  1046. PROCEDURE (VAR type: Item) New* (): ANYPTR, NEW;
  1047. VAR p: ANYPTR; i, n, id: INTEGER; d: Kernel.Directory; desc: Kernel.Type;
  1048. BEGIN
  1049. ASSERT(type.ext = NIL, 31);
  1050. ASSERT(type.ptr # NIL, 20);
  1051. desc := type.desc;
  1052. IF type.typ = ptrTyp THEN desc := desc.base[0] END;
  1053. ASSERT(TypOf(desc) = recTyp, 21);
  1054. ASSERT(desc.mod.refcnt >= 0, 24);
  1055. i := 0; d := type.desc.mod.export; n := d.num; id := type.desc.id DIV 256;
  1056. WHILE (i < n) & (d.obj[i].id DIV 256 # id) DO INC(i) END;
  1057. ASSERT((i < n) & (d.obj[i].id DIV 16 MOD 16 = exported), 29);
  1058. ASSERT(desc.id DIV 4 MOD 4 < limited, 30);
  1059. Kernel.NewObj(p, desc);
  1060. RETURN p
  1061. END New;
  1062. PROCEDURE (VAR val: Item) Copy* (): ANYPTR, NEW;
  1063. VAR p: ANYPTR; i, n, id: INTEGER; d: Kernel.Directory;
  1064. BEGIN
  1065. ASSERT(val.ext = NIL, 31);
  1066. ASSERT(val.ptr # NIL, 20);
  1067. ASSERT(val.typ = recTyp, 21);
  1068. ASSERT(val.obj = varObj, 22);
  1069. ASSERT(val.desc.mod.refcnt >= 0, 24);
  1070. i := 0; d := val.desc.mod.export; n := d.num; id := val.desc.id DIV 256;
  1071. WHILE (i < n) & (d.obj[i].id DIV 256 # id) DO INC(i) END;
  1072. ASSERT((i < n) & (d.obj[i].id DIV 16 MOD 16 = exported), 29);
  1073. ASSERT(val.desc.id DIV 4 MOD 4 < limited, 30);
  1074. Kernel.NewObj(p, val.desc);
  1075. SYSTEM.MOVE(val.adr, p, val.desc.size);
  1076. RETURN p
  1077. END Copy;
  1078. PROCEDURE (VAR rec: Item) CallWith* (proc: PROCEDURE(VAR rec, par: ANYREC); VAR par: ANYREC), NEW;
  1079. BEGIN
  1080. ASSERT(rec.ext = NIL, 31);
  1081. ASSERT(rec.ptr # NIL, 20);
  1082. ASSERT(rec.typ = recTyp, 21);
  1083. ASSERT(rec.obj = varObj, 22);
  1084. ASSERT((rec.mod = NIL) OR (rec.mod.refcnt >= 0), 23);
  1085. proc(SYSTEM.THISRECORD(rec.adr, SYSTEM.VAL(INTEGER, rec.desc)), par)
  1086. END CallWith;
  1087. PROCEDURE InstallFilter* (filter: LookupFilter);
  1088. VAR h: FilterHook;
  1089. BEGIN
  1090. ASSERT(filter # NIL, 20);
  1091. NEW(h); h.filter := filter; h.next := filterHook; filterHook := h
  1092. END InstallFilter;
  1093. PROCEDURE UninstallFilter* (filter: LookupFilter);
  1094. VAR h, a: FilterHook;
  1095. BEGIN
  1096. ASSERT(filter # NIL, 20);
  1097. h := filterHook; a := NIL;
  1098. WHILE (h # NIL) & (h.filter # filter) DO a := h; h := h.next END;
  1099. IF h # NIL THEN
  1100. IF a = NIL THEN filterHook := h.next ELSE a.next := h.next END
  1101. END
  1102. END UninstallFilter;
  1103. PROCEDURE GetThisItem* (IN attr: ANYREC; OUT i: Item);
  1104. BEGIN
  1105. WITH attr: Kernel.ItemAttr DO
  1106. i.obj := attr.obj; i.vis := attr.vis; i.typ := attr.typ; i.adr := attr.adr;
  1107. i.mod := attr.mod; i.desc := attr.desc; i.ptr := attr.ptr; i.ext := attr.ext;
  1108. IF i.ptr = NIL THEN i.ptr := dummy END
  1109. END
  1110. END GetThisItem;
  1111. BEGIN
  1112. NEW(dummy)
  1113. END Meta.