FoxInterpreterSymbols.Mod 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454
  1. MODULE FoxInterpreterSymbols; (** AUTHOR ""; PURPOSE ""; *)
  2. IMPORT Strings, Basic := FoxBasic, StringPool, Streams, Commands, PersistentObjects, Modules, Machine, SYSTEM;
  3. CONST
  4. TAB = 09X;
  5. CONST
  6. sfTypeNoType = 0X;
  7. sfTypeBoolean= 01X;
  8. sfTypeChar = 02X;
  9. sfTypeSignedInteger = 03X;
  10. sfTypeUnsignedInteger = 04X;
  11. sfTypeFloat = 05X;
  12. sfTypeComplex = 06X;
  13. sfTypeSet = 07X;
  14. sfTypeByte = 08X;
  15. sfTypeAny = 09X;
  16. sfTypeObject = 0AX;
  17. sfTypeAddress= 0BX;
  18. sfTypeSize = 0CX;
  19. sfTypeRange = 0DX;
  20. sfTypePointerToRecord = 0EX;
  21. sfTypePointerToArray = 0FX;
  22. sfTypeOpenArray = 10X;
  23. sfTypeStaticArray = 11X;
  24. sfTypeRecord = 12X;
  25. TYPE
  26. Item*= PersistentObjects.Object;
  27. Object* = PersistentObjects.Object;
  28. Content* = PersistentObjects.Content;
  29. TYPE
  30. Result*= OBJECT (Item)
  31. PROCEDURE Evaluate*(): Value;
  32. BEGIN
  33. RETURN NIL;
  34. END Evaluate;
  35. PROCEDURE SetV*(v: Value): BOOLEAN;
  36. BEGIN
  37. RETURN FALSE;
  38. END SetV;
  39. PROCEDURE Find*(CONST name: ARRAY OF CHAR): Result;
  40. BEGIN
  41. RETURN NIL;
  42. END Find;
  43. PROCEDURE Address*(): ADDRESS;
  44. BEGIN
  45. RETURN NIL;
  46. END Address;
  47. PROCEDURE Trace*;
  48. BEGIN
  49. END Trace;
  50. END Result;
  51. SymbolResult*=OBJECT(Result)
  52. VAR name: ARRAY 32 OF CHAR;
  53. PROCEDURE InitSymbol(CONST n: ARRAY OF CHAR);
  54. BEGIN
  55. COPY(n, name);
  56. END InitSymbol;
  57. END SymbolResult;
  58. ModuleResult*= OBJECT(SymbolResult)
  59. VAR
  60. self: Modules.TypeDesc;
  61. PROCEDURE & InitModule(CONST name: ARRAY OF CHAR; m: Modules.Module);
  62. BEGIN
  63. InitSymbol(name);
  64. ASSERT(m # NIL);
  65. self := FindType(m.typeInfo, "@Self");
  66. END InitModule;
  67. PROCEDURE Find(CONST name: ARRAY OF CHAR): Result;
  68. VAR num: LONGINT;
  69. proc: ProcedureResult;
  70. field: FieldResult;
  71. BEGIN
  72. IF FindProc(self.procedures, name,num) THEN
  73. NEW(proc, SELF, name, self.procedures[num]);
  74. proc.address := self.procedures[num].address;
  75. RETURN proc
  76. ELSIF FindField(self.fields, name, num) THEN
  77. NEW(field, name, self.fields[num]);
  78. field.address := self.fields[num].offset;
  79. RETURN field;
  80. END;
  81. RETURN NIL;
  82. END Find;
  83. END ModuleResult;
  84. Callstack = OBJECT
  85. VAR
  86. data: ARRAY 1024 OF CHAR;
  87. pos: LONGINT;
  88. size: LONGINT;
  89. H: HUGEINT; (* result in register *)
  90. retType: Modules.FieldEntry;
  91. parameters: POINTER TO ARRAY OF Modules.FieldEntry;
  92. pPos: LONGINT;
  93. PROCEDURE & Init;
  94. BEGIN
  95. pos := 1024; size := 0;
  96. END Init;
  97. PROCEDURE Next(s: SIZE): ADDRESS;
  98. BEGIN
  99. DEC(pos, s); INC(size, s);
  100. RETURN ADDRESSOF(data[pos]);
  101. END Next;
  102. PROCEDURE PushH(h: HUGEINT);
  103. VAR p: POINTER {UNSAFE} TO RECORD h: HUGEINT END;
  104. BEGIN
  105. p := Next(SIZEOF(HUGEINT));
  106. p.h := h;
  107. END PushH;
  108. PROCEDURE PushL(i: LONGINT);
  109. VAR p: POINTER {UNSAFE} TO RECORD i: LONGINT END;
  110. BEGIN
  111. p := Next(SIZEOF(LONGINT));
  112. p.i := i;
  113. END PushL;
  114. PROCEDURE PushI(i: INTEGER);
  115. BEGIN
  116. PushL(i);
  117. END PushI;
  118. PROCEDURE PushS(i: SHORTINT);
  119. BEGIN
  120. PushL(i);
  121. END PushS;
  122. PROCEDURE PushB(b: BOOLEAN);
  123. VAR p: POINTER {UNSAFE} TO RECORD b: BOOLEAN END;
  124. BEGIN
  125. p := Next(SIZEOF(LONGINT));
  126. p.b := b;
  127. END PushB;
  128. PROCEDURE PushC(c: CHAR);
  129. BEGIN
  130. PushL(ORD(c));
  131. END PushC;
  132. PROCEDURE PushSet(set: SET);
  133. VAR p: POINTER {UNSAFE} TO RECORD s:SET END;
  134. BEGIN
  135. p := Next(SIZEOF(SET));
  136. p.s := set;
  137. END PushSet;
  138. PROCEDURE PushR(r: REAL);
  139. VAR p: POINTER {UNSAFE} TO RECORD r: REAL END;
  140. BEGIN
  141. p := Next(SIZEOF(REAL));
  142. p.r := r;
  143. END PushR;
  144. PROCEDURE PushX(x: LONGREAL);
  145. VAR p: POINTER {UNSAFE} TO RECORD x: LONGREAL END;
  146. BEGIN
  147. p := Next(SIZEOF(LONGREAL));
  148. p.x := x;
  149. END PushX;
  150. PROCEDURE PushA(a: ADDRESS);
  151. VAR p: POINTER {UNSAFE} TO RECORD a: ADDRESS END;
  152. BEGIN
  153. p := Next(SIZEOF(ADDRESS));
  154. p.a := a;
  155. END PushA;
  156. PROCEDURE PushSz(s: SIZE);
  157. VAR p: POINTER {UNSAFE} TO RECORD s: SIZE END;
  158. BEGIN
  159. p := Next(SIZEOF(SIZE));
  160. p.s := s;
  161. END PushSz;
  162. PROCEDURE Call(adr: ADDRESS);
  163. VAR esp: ADDRESS; P: Procedure; h: HUGEINT
  164. TYPE
  165. Procedure = PROCEDURE(): HUGEINT;
  166. BEGIN
  167. P := SYSTEM.VAL(Procedure, adr);
  168. esp := Machine.CurrentSP();
  169. Machine.SetSP(esp-size);
  170. IF size > 0 THEN
  171. SYSTEM.MOVE(ADDRESS OF data[pos], esp-size, size);
  172. END;
  173. H := P();
  174. Machine.SetSP(esp);
  175. END Call;
  176. PROCEDURE ResH(): HUGEINT;
  177. BEGIN
  178. RETURN H;
  179. END ResH;
  180. PROCEDURE ResL(): LONGINT;
  181. BEGIN
  182. RETURN LONGINT(H);
  183. END ResL;
  184. PROCEDURE ResI(): INTEGER;
  185. BEGIN
  186. RETURN INTEGER(H);
  187. END ResI;
  188. PROCEDURE ResS(): SHORTINT;
  189. BEGIN
  190. RETURN SHORTINT(H);
  191. END ResS;
  192. PROCEDURE ResC(): CHAR;
  193. BEGIN
  194. RETURN CHR(H);
  195. END ResC;
  196. PROCEDURE ResB(): BOOLEAN;
  197. BEGIN
  198. RETURN SYSTEM.VAL(BOOLEAN, ResC());
  199. END ResB;
  200. PROCEDURE ResSet(): SET;
  201. BEGIN
  202. RETURN SYSTEM.VAL(SET,H);
  203. END ResSet;
  204. PROCEDURE ResSz(): SIZE;
  205. BEGIN
  206. RETURN SYSTEM.VAL(SIZE, H);
  207. END ResSz;
  208. PROCEDURE ResA(): ADDRESS;
  209. BEGIN
  210. RETURN SYSTEM.VAL(ADDRESS, H)
  211. END ResA;
  212. PROCEDURE ResR(): REAL;
  213. BEGIN
  214. RETURN SYSTEM.VAL(REAL, ResL())
  215. END ResR;
  216. PROCEDURE ResX(): LONGREAL;
  217. BEGIN
  218. RETURN SYSTEM.VAL(LONGREAL, ResH())
  219. END ResX;
  220. END Callstack;
  221. ProcedureResult*= OBJECT(SymbolResult)
  222. VAR
  223. proc: Modules.ProcedureEntry;
  224. address: ADDRESS;
  225. stack: Callstack;
  226. index: LONGINT;
  227. caller-: Result;
  228. PROCEDURE ReturnsPointer*(): BOOLEAN;
  229. BEGIN
  230. CASE proc.returnType.class
  231. OF sfTypeAny, sfTypeObject, sfTypePointerToRecord: RETURN TRUE
  232. ELSE RETURN FALSE
  233. END;
  234. END ReturnsPointer;
  235. PROCEDURE & InitProcedure(c: Result; CONST name: ARRAY OF CHAR; CONST p: Modules.ProcedureEntry);
  236. BEGIN
  237. InitSymbol(name); proc := p;
  238. caller := c;
  239. END InitProcedure;
  240. PROCEDURE Pars*();
  241. BEGIN
  242. index := 0;
  243. NEW(stack); (* can optimize this *)
  244. END Pars;
  245. PROCEDURE PushAddress*(adr: ADDRESS); (* for self pointer *)
  246. BEGIN
  247. stack.PushA(adr);
  248. END PushAddress;
  249. PROCEDURE Push*(v: Value): BOOLEAN;
  250. VAR type: Modules.EntryType;
  251. s: SHORTINT; i: INTEGER; l: LONGINT; h: HUGEINT;
  252. r: REAL; x: LONGREAL;
  253. b: BOOLEAN;
  254. set: SET;
  255. BEGIN
  256. IF (proc.parameters = NIL) OR (index >= LEN(proc.parameters)) THEN RETURN FALSE END;
  257. type := proc.parameters[index].type;
  258. INC(index);
  259. CASE type.class OF
  260. sfTypeSignedInteger:
  261. IF v.GetInt(h) THEN
  262. CASE type.size OF
  263. 8: s:= SHORTINT(h); stack.PushS(s);
  264. |16: i:= INTEGER(h); stack.PushI(i);
  265. |32:l := LONGINT(h); stack.PushL(l);
  266. |64:stack.PushH(h);
  267. END;
  268. RETURN TRUE
  269. END;
  270. |sfTypeFloat:
  271. IF v.GetReal(x) THEN
  272. CASE type.size OF
  273. 32: r := REAL(x);stack.PushR(r)
  274. |64: stack.PushX(x)
  275. END;
  276. RETURN TRUE
  277. END;
  278. |sfTypeBoolean:
  279. IF v.GetBoolean(b) THEN
  280. stack.PushB(b);
  281. RETURN TRUE
  282. END;
  283. |sfTypeSet:
  284. IF v.GetSet(set) THEN
  285. stack.PushSet(set);
  286. RETURN TRUE
  287. END;
  288. END;
  289. RETURN FALSE;
  290. END Push;
  291. PROCEDURE Check*(): BOOLEAN;
  292. BEGIN
  293. RETURN (proc.parameters = NIL) & (index = 0) OR (index = LEN(proc.parameters));
  294. END Check;
  295. PROCEDURE Evaluate(): Value;
  296. VAR
  297. type: Modules.EntryType;
  298. int: IntegerValue;
  299. real: RealValue;
  300. bool: BooleanValue;
  301. set: SetValue;
  302. any: AnyValue;
  303. BEGIN
  304. stack.Call(address);
  305. type := proc.returnType;
  306. CASE type.class OF
  307. sfTypeSignedInteger:
  308. CASE type.size OF
  309. 8: NEW(int, stack.ResS());
  310. |16: NEW(int, stack.ResI());
  311. |32: NEW(int, stack.ResL());
  312. |64: NEW(int, SHORT(stack.ResH()));
  313. END;
  314. RETURN int;
  315. |sfTypeFloat:
  316. CASE type.size OF
  317. 32: NEW(real, stack.ResR());
  318. |64: NEW(real, stack.ResX());
  319. END;
  320. RETURN real;
  321. |sfTypeBoolean:
  322. NEW(bool, stack.ResB());
  323. RETURN bool;
  324. |sfTypeSet:
  325. NEW(set, stack.ResSet());
  326. RETURN set;
  327. | sfTypeAny, sfTypeObject, sfTypePointerToRecord: (* pointers are passed as varpars *)
  328. RETURN NIL;
  329. | 0X: RETURN NIL;
  330. END;
  331. RETURN NIL;
  332. END Evaluate;
  333. END ProcedureResult;
  334. FieldResult* = OBJECT (SymbolResult)
  335. VAR field: Modules.FieldEntry;
  336. address: ADDRESS;
  337. PROCEDURE & InitField(CONST name: ARRAY OF CHAR; CONST f: Modules.FieldEntry);
  338. BEGIN
  339. InitSymbol(name); field := f;
  340. END InitField;
  341. PROCEDURE Evaluate(): Value;
  342. VAR l: LONGINT;
  343. int: IntegerValue;
  344. a: ANY;
  345. any: AnyValue;
  346. BEGIN
  347. CASE field.type.class OF
  348. sfTypeSignedInteger:
  349. SYSTEM.GET(address, l);
  350. NEW(int, l);
  351. RETURN int;
  352. | sfTypePointerToRecord, sfTypeAny, sfTypeObject:
  353. SYSTEM.GET(address, a);
  354. NEW(any, a);
  355. RETURN any;
  356. ELSE
  357. HALT(100);
  358. END;
  359. END Evaluate;
  360. PROCEDURE SetV(v: Value): BOOLEAN;
  361. VAR
  362. s: SHORTINT; i: INTEGER; l: LONGINT; h: HUGEINT;
  363. r: REAL; x: LONGREAL;
  364. b: BOOLEAN;
  365. set: SET;
  366. BEGIN
  367. CASE field.type.class OF
  368. sfTypeSignedInteger:
  369. IF v.GetInt(h) THEN
  370. CASE field.type.size OF
  371. 8: s:= SHORTINT(h); SYSTEM.PUT(address, s);
  372. |16: i:= INTEGER(h); SYSTEM.PUT(address, i);
  373. |32:l := LONGINT(h); SYSTEM.PUT(address, l);
  374. |64: SYSTEM.PUT(address, h);
  375. END;
  376. RETURN TRUE
  377. END;
  378. |sfTypeFloat:
  379. IF v.GetReal(x) THEN
  380. CASE field.type.size OF
  381. 32: r := REAL(x); SYSTEM.PUT(address, r);
  382. |64: SYSTEM.PUT(address,x);
  383. END;
  384. RETURN TRUE
  385. END;
  386. |sfTypeBoolean:
  387. IF v.GetBoolean(b) THEN
  388. SYSTEM.PUT(address,b);
  389. RETURN TRUE
  390. END;
  391. |sfTypeSet:
  392. IF v.GetSet(set) THEN
  393. SYSTEM.PUT(address,set);
  394. RETURN TRUE
  395. END;
  396. END;
  397. END SetV;
  398. PROCEDURE Find(CONST name: ARRAY OF CHAR): Result;
  399. VAR type, value: ADDRESS;
  400. VAR typeInfo: Modules.TypeDesc; num: LONGINT;
  401. proc: ProcedureResult; f: FieldResult;
  402. BEGIN
  403. IF (field.type.class = sfTypePointerToRecord)
  404. OR (field.type.class = sfTypeAny)
  405. OR (field.type.class = sfTypeObject)
  406. THEN
  407. SYSTEM.GET(address, value);
  408. SYSTEM.GET(value-SIZEOF(ADDRESS), type); (* type desc *)
  409. RETURN FindInType(SELF, value, type, name);
  410. (*
  411. SYSTEM.GET(type-SIZEOF(ADDRESS), typeInfo); (* type info*)
  412. IF FindProc(typeInfo.procedures, name,num) THEN
  413. NEW(proc, SELF, name, typeInfo.procedures[num]);
  414. proc.address := typeInfo.procedures[num].address;
  415. RETURN proc
  416. ELSIF FindField(typeInfo.fields, name, num) THEN
  417. NEW(f, name, typeInfo.fields[num]);
  418. f.address := value + typeInfo.fields[num].offset;
  419. RETURN f;
  420. ELSE HALT(101);
  421. END;
  422. *)
  423. ELSIF field.type.class = sfTypeRecord THEN
  424. type := field.type.type;
  425. RETURN FindInType(SELF, address, type, name);
  426. (*
  427. SYSTEM.GET(type-SIZEOF(ADDRESS), typeInfo); (* type info*)
  428. IF FindProc(typeInfo.procedures, name,num) THEN
  429. NEW(proc, SELF, name, typeInfo.procedures[num]);
  430. proc.address := typeInfo.procedures[num].address;
  431. RETURN proc
  432. ELSIF FindField(typeInfo.fields, name, num) THEN
  433. NEW(f, name, typeInfo.fields[num]);
  434. f.address := address + typeInfo.fields[num].offset;
  435. RETURN f;
  436. ELSE HALT(101);
  437. END;
  438. *)
  439. ELSE HALT(100);
  440. END;
  441. END Find;
  442. END FieldResult;
  443. (* traverse types and supertypes for first occurence of symbol name *)
  444. PROCEDURE FindInType(scope: Result; address: ADDRESS; type: ADDRESS; CONST name: ARRAY OF CHAR): Result;
  445. VAR tag: ADDRESS; typeInfo: Modules.TypeDesc; i, num: LONGINT;
  446. proc: ProcedureResult; f: FieldResult;
  447. BEGIN
  448. FOR i := 15 TO 0 BY -1 DO
  449. SYSTEM.GET(type-(2+i)*SIZEOF(ADDRESS), tag);
  450. IF tag # NIL THEN
  451. SYSTEM.GET(tag-SIZEOF(ADDRESS), typeInfo);
  452. IF FindProc(typeInfo.procedures, name,num) THEN
  453. NEW(proc, scope, name, typeInfo.procedures[num]);
  454. proc.address := typeInfo.procedures[num].address;
  455. RETURN proc
  456. ELSIF FindField(typeInfo.fields, name, num) THEN
  457. NEW(f, name, typeInfo.fields[num]);
  458. f.address := address + typeInfo.fields[num].offset;
  459. RETURN f;
  460. END;
  461. END;
  462. END;
  463. RETURN NIL;
  464. END FindInType;
  465. TYPE
  466. Value*= OBJECT(Result)
  467. PROCEDURE & InitValue;
  468. BEGIN InitObject
  469. END InitValue;
  470. PROCEDURE Evaluate(): Value;
  471. BEGIN
  472. RETURN SELF;
  473. END Evaluate;
  474. PROCEDURE GetInt*(VAR h: HUGEINT): BOOLEAN;
  475. BEGIN
  476. RETURN FALSE;
  477. END GetInt;
  478. PROCEDURE GetAddress*(VAR a: ADDRESS): BOOLEAN;
  479. BEGIN
  480. RETURN FALSE;
  481. END GetAddress;
  482. PROCEDURE GetReal*(VAR x: LONGREAL): BOOLEAN;
  483. BEGIN
  484. RETURN FALSE;
  485. END GetReal;
  486. PROCEDURE GetBoolean*(VAR x: BOOLEAN): BOOLEAN;
  487. BEGIN
  488. RETURN FALSE;
  489. END GetBoolean;
  490. PROCEDURE GetSet*(VAR x: SET): BOOLEAN;
  491. BEGIN
  492. RETURN FALSE;
  493. END GetSet;
  494. PROCEDURE GetChar*(VAR x: CHAR): BOOLEAN;
  495. BEGIN
  496. RETURN FALSE;
  497. END GetChar;
  498. PROCEDURE GetRange*(VAR x: RANGE): BOOLEAN;
  499. BEGIN
  500. RETURN FALSE;
  501. END GetRange;
  502. PROCEDURE WriteValue*(w: Streams.Writer);
  503. BEGIN
  504. END WriteValue;
  505. PROCEDURE GetString*(VAR w: ARRAY OF CHAR);
  506. VAR stringWriter: Streams.StringWriter;
  507. BEGIN
  508. NEW(stringWriter, 128);
  509. WriteValue(stringWriter); stringWriter.Update;
  510. stringWriter.Get(w);
  511. END GetString;
  512. END Value;
  513. CONST StrValue="value";
  514. TYPE
  515. AnyValue*=OBJECT(Value)
  516. VAR value*:ANY;
  517. PROCEDURE & InitAny*(value: ANY);
  518. BEGIN InitValue; SELF.value := value; type := "AnyValue";
  519. END InitAny;
  520. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  521. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  522. END Enumerate;
  523. PROCEDURE GetAddress(VAR a: ADDRESS): BOOLEAN;
  524. BEGIN
  525. a := value; RETURN TRUE;
  526. END GetAddress;
  527. PROCEDURE WriteValue(w: Streams.Writer);
  528. BEGIN w.Address(value);
  529. END WriteValue;
  530. PROCEDURE Address(): ADDRESS;
  531. BEGIN
  532. RETURN ADDRESSOF(value)
  533. END Address;
  534. PROCEDURE Find(CONST name: ARRAY OF CHAR): Result;
  535. VAR type, v, address: ADDRESS;
  536. VAR typeInfo: Modules.TypeDesc; num: LONGINT;
  537. proc: ProcedureResult; f: FieldResult;
  538. BEGIN
  539. IF value # NIL THEN
  540. address := value;
  541. SYSTEM.GET(address-SIZEOF(ADDRESS), type); (* type desc *)
  542. RETURN FindInType(SELF, address, type, name);
  543. (*
  544. SYSTEM.GET(type-SIZEOF(ADDRESS), typeInfo); (* type info*)
  545. IF FindProc(typeInfo.procedures, name,num) THEN
  546. NEW(proc, SELF, name, typeInfo.procedures[num]);
  547. proc.address := typeInfo.procedures[num].address;
  548. RETURN proc
  549. ELSIF FindField(typeInfo.fields, name, num) THEN
  550. NEW(f, name, typeInfo.fields[num]);
  551. f.address := address + typeInfo.fields[num].offset;
  552. RETURN f;
  553. ELSE HALT(101);
  554. END;
  555. *)
  556. ELSE
  557. RETURN NIL;
  558. END;
  559. END Find;
  560. END AnyValue;
  561. AddressValue*=OBJECT(Value)
  562. VAR value*:ADDRESS;
  563. PROCEDURE & InitAny*(value: ADDRESS);
  564. BEGIN InitValue; SELF.value := value; type := "AnyValue";
  565. END InitAny;
  566. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  567. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  568. END Enumerate;
  569. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  570. VAR int: LONGINT;
  571. BEGIN
  572. IF name = StrValue THEN c.GetInteger(int); value := int;
  573. ELSE Set^(name, index, c);
  574. END;
  575. END Set;
  576. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  577. BEGIN
  578. IF name = StrValue THEN c.SetInteger(value);
  579. ELSE Get^(name, index, c);
  580. END;
  581. END Get;
  582. PROCEDURE GetAddress(VAR a: ADDRESS): BOOLEAN;
  583. BEGIN
  584. a := value; RETURN TRUE;
  585. END GetAddress;
  586. PROCEDURE WriteValue(w: Streams.Writer);
  587. BEGIN w.Address(value);
  588. END WriteValue;
  589. PROCEDURE Address(): ADDRESS;
  590. BEGIN
  591. RETURN ADDRESSOF(value)
  592. END Address;
  593. END AddressValue;
  594. IntegerValue*=OBJECT(Value)
  595. VAR value*: LONGINT;
  596. PROCEDURE & InitInteger*(value: LONGINT);
  597. BEGIN InitValue; SELF.value := value; type := "IntegerValue";
  598. END InitInteger;
  599. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  600. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  601. END Enumerate;
  602. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  603. BEGIN
  604. IF name = StrValue THEN c.GetInteger(value);
  605. ELSE Set^(name, index, c);
  606. END;
  607. END Set;
  608. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  609. BEGIN
  610. IF name = StrValue THEN c.SetInteger(value);
  611. ELSE Get^(name, index, c);
  612. END;
  613. END Get;
  614. PROCEDURE GetInt(VAR v: HUGEINT): BOOLEAN;
  615. BEGIN
  616. v := value; RETURN TRUE;
  617. END GetInt;
  618. PROCEDURE GetReal(VAR x: LONGREAL): BOOLEAN;
  619. BEGIN
  620. x := value; RETURN TRUE;
  621. END GetReal;
  622. PROCEDURE WriteValue(w: Streams.Writer);
  623. BEGIN w.Int(value,0);
  624. END WriteValue;
  625. PROCEDURE Address(): ADDRESS;
  626. BEGIN
  627. RETURN ADDRESSOF(value)
  628. END Address;
  629. END IntegerValue;
  630. RealValue*=OBJECT(Value)
  631. VAR value*: LONGREAL;
  632. PROCEDURE & InitReal*(value: LONGREAL);
  633. BEGIN InitValue; SELF.value := value; type := "RealValue";
  634. END InitReal;
  635. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  636. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  637. END Enumerate;
  638. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  639. BEGIN
  640. IF name = StrValue THEN c.GetFloat(value);
  641. ELSE Set^(name, index, c);
  642. END;
  643. END Set;
  644. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  645. BEGIN
  646. IF name = StrValue THEN c.SetFloat(value);
  647. ELSE Get^(name, index, c);
  648. END;
  649. END Get;
  650. PROCEDURE GetReal(VAR x: LONGREAL): BOOLEAN;
  651. BEGIN
  652. x := value; RETURN TRUE;
  653. END GetReal;
  654. PROCEDURE WriteValue(w: Streams.Writer);
  655. BEGIN w.Float(value,40);
  656. END WriteValue;
  657. PROCEDURE Address(): ADDRESS;
  658. BEGIN
  659. RETURN ADDRESSOF(value)
  660. END Address;
  661. END RealValue;
  662. BooleanValue*=OBJECT(Value)
  663. VAR value*: BOOLEAN;
  664. PROCEDURE & InitBoolean*(value: BOOLEAN);
  665. BEGIN InitValue; SELF.value := value; type := "BooleanValue";
  666. END InitBoolean;
  667. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  668. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  669. END Enumerate;
  670. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  671. BEGIN
  672. IF name = StrValue THEN c.GetBoolean(value);
  673. ELSE Set^(name, index, c);
  674. END;
  675. END Set;
  676. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  677. BEGIN
  678. IF name = StrValue THEN c.SetBoolean(value);
  679. ELSE Get^(name, index, c);
  680. END;
  681. END Get;
  682. PROCEDURE GetBoolean(VAR x: BOOLEAN): BOOLEAN;
  683. BEGIN
  684. x := value; RETURN TRUE;
  685. END GetBoolean;
  686. PROCEDURE WriteValue(w: Streams.Writer);
  687. BEGIN IF value THEN w.String("TRUE") ELSE w.String("FALSE") END
  688. END WriteValue;
  689. PROCEDURE Address(): ADDRESS;
  690. BEGIN
  691. RETURN ADDRESSOF(value)
  692. END Address;
  693. END BooleanValue;
  694. StringValue*=OBJECT(Value)
  695. VAR value*: Strings.String;
  696. PROCEDURE & InitString*(CONST value: ARRAY OF CHAR);
  697. BEGIN InitValue; SELF.value := Strings.NewString(value); type := "StringValue";
  698. END InitString;
  699. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  700. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  701. END Enumerate;
  702. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  703. BEGIN
  704. IF name = StrValue THEN c.GetString(value);
  705. ELSE Set^(name, index, c);
  706. END;
  707. END Set;
  708. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  709. BEGIN
  710. IF name = StrValue THEN c.SetString(value);
  711. ELSE Get^(name, index, c);
  712. END;
  713. END Get;
  714. PROCEDURE WriteValue(w: Streams.Writer);
  715. BEGIN (*w.String('"');*) w.String(value^); (*w.String('"');*)
  716. END WriteValue;
  717. PROCEDURE Address(): ADDRESS;
  718. BEGIN
  719. RETURN value;
  720. END Address;
  721. END StringValue;
  722. SetValue*=OBJECT(Value)
  723. VAR value*: SET;
  724. PROCEDURE & InitSet*(value: SET);
  725. BEGIN InitValue; SELF.value := value; type := "SetValue"
  726. END InitSet;
  727. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  728. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  729. END Enumerate;
  730. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  731. BEGIN
  732. IF name = StrValue THEN c.GetSet(value);
  733. ELSE Set^(name, index, c);
  734. END;
  735. END Set;
  736. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  737. BEGIN
  738. IF name = StrValue THEN c.SetSet(value);
  739. ELSE Get^(name, index, c);
  740. END;
  741. END Get;
  742. PROCEDURE GetSet(VAR x: SET): BOOLEAN;
  743. BEGIN
  744. x:= value; RETURN TRUE;
  745. END GetSet;
  746. PROCEDURE WriteValue(w: Streams.Writer);
  747. BEGIN
  748. w.Set(value)
  749. END WriteValue;
  750. PROCEDURE Address(): ADDRESS;
  751. BEGIN
  752. RETURN ADDRESSOF(value)
  753. END Address;
  754. END SetValue;
  755. RangeValue*=OBJECT(Value)
  756. VAR value*: RANGE;
  757. PROCEDURE & InitRange*(r: RANGE);
  758. BEGIN InitValue; value := r; type := "RangeValue"
  759. END InitRange;
  760. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  761. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  762. END Enumerate;
  763. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  764. BEGIN
  765. IF name = StrValue THEN c.GetRange(value);
  766. ELSE Set^(name, index, c);
  767. END;
  768. END Set;
  769. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  770. BEGIN
  771. IF name = StrValue THEN c.SetRange(value);
  772. ELSE Get^(name, index, c);
  773. END;
  774. END Get;
  775. PROCEDURE GetRange(VAR x: RANGE): BOOLEAN;
  776. BEGIN
  777. x := value; RETURN TRUE;
  778. END GetRange;
  779. PROCEDURE WriteValue(w: Streams.Writer);
  780. BEGIN
  781. w.Int(FIRST(value),0); w.String(" .. "); w.Int(LAST(value),0); IF STEP(value) # 1 THEN w.String(" BY "); w.Int(STEP(value),0) END;
  782. END WriteValue;
  783. PROCEDURE Address(): ADDRESS;
  784. BEGIN
  785. RETURN ADDRESSOF(value)
  786. END Address;
  787. END RangeValue;
  788. CharValue*=OBJECT(Value)
  789. VAR value: CHAR;
  790. PROCEDURE & InitChar*(c: CHAR);
  791. BEGIN InitValue; value := c; type := "CharValue";
  792. END InitChar;
  793. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  794. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  795. END Enumerate;
  796. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  797. BEGIN
  798. IF name = StrValue THEN c.GetChar(value);
  799. ELSE Set^(name, index, c);
  800. END;
  801. END Set;
  802. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  803. BEGIN
  804. IF name = StrValue THEN c.SetChar(value);
  805. ELSE Get^(name, index, c);
  806. END;
  807. END Get;
  808. PROCEDURE GetChar(VAR c: CHAR): BOOLEAN;
  809. BEGIN
  810. c := value; RETURN TRUE;
  811. END GetChar;
  812. PROCEDURE WriteValue(w: Streams.Writer);
  813. BEGIN
  814. w.Hex(ORD(value),2); w.String("X");
  815. END WriteValue;
  816. PROCEDURE Address(): ADDRESS;
  817. BEGIN
  818. RETURN ADDRESSOF(value)
  819. END Address;
  820. END CharValue;
  821. EnumValue*=OBJECT(Value)
  822. VAR value: LONGINT; translation: PersistentObjects.Translation;
  823. PROCEDURE & InitEnumValue*(trans: PersistentObjects.Translation; v: LONGINT);
  824. BEGIN InitValue; value := v; translation := trans; type := "EnumValue";
  825. END InitEnumValue;
  826. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  827. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  828. END Enumerate;
  829. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  830. BEGIN
  831. IF name = StrValue THEN c.GetEnum(translation, value);
  832. ELSE Set^(name, index, c);
  833. END;
  834. END Set;
  835. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  836. BEGIN
  837. IF name = StrValue THEN c.SetEnum(translation, value);
  838. ELSE Get^(name, index, c);
  839. END;
  840. END Get;
  841. PROCEDURE WriteValue(w: Streams.Writer);
  842. VAR str: ARRAY 32 OF CHAR;
  843. BEGIN
  844. IF translation.Name(value, str) THEN w.String(str) ELSE w.String("unknown") END;
  845. END WriteValue;
  846. PROCEDURE Address(): ADDRESS;
  847. BEGIN
  848. RETURN ADDRESSOF(value)
  849. END Address;
  850. END EnumValue;
  851. MathArrayValue*=OBJECT(Value)
  852. VAR values: ARRAY [*] OF Value;
  853. PROCEDURE &InitMathArrayValue*(len: LONGINT);
  854. BEGIN
  855. InitValue;
  856. NEW(values, len);
  857. type := "MathArrayValue";
  858. END InitMathArrayValue;
  859. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  860. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  861. END Enumerate;
  862. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  863. BEGIN
  864. IF name = StrValue THEN values[index] := ContentGetValue(c)
  865. ELSE Set^(name, index, c);
  866. END;
  867. END Set;
  868. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  869. BEGIN
  870. IF name = StrValue THEN c.SetObject(values[index],"Value");
  871. ELSE Get^(name, index, c);
  872. END;
  873. END Get;
  874. PROCEDURE SetValue*(at: LONGINT; value: Value);
  875. BEGIN
  876. values[at] := value;
  877. END SetValue;
  878. PROCEDURE GetValue*(at: LONGINT): Value;
  879. BEGIN
  880. RETURN values[at]
  881. END GetValue;
  882. PROCEDURE WriteValue*(w: Streams.Writer);
  883. VAR i: LONGINT; max: LONGINT;
  884. BEGIN
  885. w.String("[ ");
  886. max := LEN(values,0)-1;
  887. FOR i := 0 TO max DO
  888. values[i].WriteValue(w);
  889. IF i < max THEN
  890. w.String(", ");
  891. END;
  892. END;
  893. w.String("] ");
  894. END WriteValue;
  895. END MathArrayValue;
  896. (* object value represented as ANY wrapped in Value ? *)
  897. Symbol*= OBJECT
  898. VAR
  899. name: StringPool.Index;
  900. item-: Item;
  901. PROCEDURE & InitSymbol(name: StringPool.Index; index: LONGINT);
  902. BEGIN
  903. SELF.name := name; SELF.item := item;
  904. END InitSymbol;
  905. PROCEDURE GetName(VAR name: ARRAY OF CHAR);
  906. BEGIN
  907. StringPool.GetString(SELF.name, name);
  908. END GetName;
  909. END Symbol;
  910. Container* = OBJECT (Item)
  911. VAR
  912. symbols-: Basic.List;
  913. lookup-: Basic.HashTableInt;
  914. (* New scope. Note that it is possible that a scope is registered with an alias *)
  915. PROCEDURE & InitContainer*;
  916. BEGIN
  917. InitObject();
  918. NEW(lookup, 16); NEW(symbols, 16);
  919. type := "Container";
  920. END InitContainer;
  921. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  922. VAR i: LONGINT; symbol: Symbol; o: ANY; name: ARRAY 256 OF CHAR;
  923. BEGIN Enumerate^(enum);
  924. FOR i := 0 TO symbols.Length()-1 DO
  925. o := symbols.Get(i);
  926. symbol := o(Symbol);
  927. symbol.GetName(name);
  928. enum(name, FALSE);
  929. END;
  930. END Enumerate;
  931. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  932. BEGIN
  933. IF FALSE THEN
  934. ELSE Set^(name, index, c);
  935. END;
  936. END Set;
  937. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  938. VAR item: Item;
  939. BEGIN
  940. item := Find(name);
  941. IF item # NIL THEN c.SetObject(item,"Item")
  942. ELSE Get^(name, index, c);
  943. END;
  944. END Get;
  945. PROCEDURE GetItem*(index: LONGINT): Item;
  946. BEGIN
  947. RETURN symbols.Get(index)(Symbol).item
  948. END GetItem;
  949. (* Enter a symbol with its name *)
  950. PROCEDURE Enter1*(item: Item; name: StringPool.Index);
  951. VAR any: ANY; symbol: Symbol;
  952. BEGIN
  953. any := lookup.Get(name);
  954. IF any # NIL THEN
  955. symbol := any(Symbol)
  956. ELSE
  957. NEW(symbol, name, symbols.Length());
  958. symbols.Add(symbol);
  959. lookup.Put(symbol.name, symbol);
  960. END;
  961. symbol.item := item
  962. END Enter1;
  963. (* Enter a symbol with its name *)
  964. PROCEDURE Enter*(item: Item; CONST name: ARRAY OF CHAR);
  965. BEGIN
  966. Enter1(item, StringPool.GetIndex1(name))
  967. END Enter;
  968. PROCEDURE Find1*(id: LONGINT): Item;
  969. VAR any: ANY;
  970. BEGIN
  971. any := lookup.Get(id);
  972. IF any # NIL THEN RETURN any(Symbol).item ELSE RETURN NIL END
  973. END Find1;
  974. (* Find a symbol with name *)
  975. PROCEDURE Find*(CONST name: ARRAY OF CHAR): Item;
  976. BEGIN
  977. RETURN Find1(StringPool.GetIndex1(name))
  978. END Find;
  979. END Container;
  980. Scope* = OBJECT
  981. VAR
  982. outer-: Scope;
  983. object-: Object;
  984. level: LONGINT;
  985. PROCEDURE & InitScope*(outer: Scope; object: Object);
  986. BEGIN
  987. SELF.outer := outer;
  988. IF outer = NIL THEN level := 0 ELSE level := outer.level + 1 END;
  989. ASSERT(object # NIL);
  990. SELF.object := object
  991. END InitScope;
  992. PROCEDURE Enter*(object: Object): Scope;
  993. VAR scope: Scope;
  994. BEGIN
  995. NEW(scope, SELF, object);
  996. RETURN scope
  997. END Enter;
  998. PROCEDURE FindObject*(CONST name: ARRAY OF CHAR; index: LONGINT; VAR in: Object): Object;
  999. VAR object: Object;
  1000. BEGIN
  1001. in := SELF.object;
  1002. object := FindInObject(in, name, index);
  1003. IF (object = NIL) & (outer # NIL) THEN
  1004. object := outer.FindObject(name, index, in)
  1005. END;
  1006. RETURN object
  1007. END FindObject;
  1008. PROCEDURE FindObject1*(name: StringPool.Index; index: LONGINT; VAR in: Object): Object;
  1009. VAR str: ARRAY 256 OF CHAR;
  1010. BEGIN
  1011. StringPool.GetString(name, str);
  1012. RETURN FindObject(str,index, in);
  1013. END FindObject1;
  1014. PROCEDURE Leave*(): Scope;
  1015. BEGIN
  1016. RETURN outer
  1017. END Leave;
  1018. PROCEDURE Dump*(log: Streams.Writer);
  1019. BEGIN
  1020. IF object # NIL THEN object.Dump(log,"scope object") END;
  1021. log.Ln;
  1022. IF outer # NIL THEN outer.Dump(log) END;
  1023. END Dump;
  1024. END Scope;
  1025. PROCEDURE Indent(w: Streams.Writer; level: LONGINT);
  1026. BEGIN
  1027. WHILE level> 0 DO w.Char(TAB); DEC(level) END;
  1028. END Indent;
  1029. PROCEDURE Test*(context: Commands.Context);
  1030. VAR scope, inner: Scope; container: Container; integer: IntegerValue; float: RealValue; string: StringValue;
  1031. BEGIN
  1032. NEW(container);
  1033. container.Enter(integer, "integer");
  1034. container.Enter(float,"float");
  1035. container.Enter(string,"string");
  1036. NEW(scope, NIL, container);
  1037. NEW(container);
  1038. inner := scope.Enter(container);
  1039. scope.Dump(context.out);
  1040. (*scope.Write(context.out);*)
  1041. END Test;
  1042. PROCEDURE ContentGetValue(c: Content): Value;
  1043. VAR o: Object;
  1044. BEGIN
  1045. c.GetObject(o); IF o = NIL THEN RETURN NIL ELSE RETURN o(Value) END;
  1046. END ContentGetValue;
  1047. PROCEDURE NewIntegerValue(value: LONGINT): IntegerValue;
  1048. VAR obj: IntegerValue;
  1049. BEGIN
  1050. NEW(obj, value); RETURN obj
  1051. END NewIntegerValue;
  1052. PROCEDURE NewFloatValue(value: LONGREAL): RealValue;
  1053. VAR obj: RealValue;
  1054. BEGIN
  1055. NEW(obj, value); RETURN obj
  1056. END NewFloatValue;
  1057. PROCEDURE NewBooleanValue(value: BOOLEAN): BooleanValue;
  1058. VAR obj: BooleanValue;
  1059. BEGIN
  1060. NEW(obj, value); RETURN obj
  1061. END NewBooleanValue;
  1062. PROCEDURE NewStringValue(CONST value: ARRAY OF CHAR): StringValue;
  1063. VAR obj: StringValue;
  1064. BEGIN
  1065. NEW(obj, value); RETURN obj
  1066. END NewStringValue;
  1067. PROCEDURE NewNameValue(CONST value: ARRAY OF CHAR): StringValue;
  1068. VAR obj: StringValue;
  1069. BEGIN
  1070. NEW(obj, value); RETURN obj
  1071. END NewNameValue;
  1072. PROCEDURE NewRangeValue(value: RANGE): RangeValue;
  1073. VAR obj: RangeValue;
  1074. BEGIN
  1075. NEW(obj, value); RETURN obj
  1076. END NewRangeValue;
  1077. PROCEDURE NewCharValue(value: CHAR): CharValue;
  1078. VAR obj: CharValue;
  1079. BEGIN
  1080. NEW(obj, value); RETURN obj
  1081. END NewCharValue;
  1082. PROCEDURE NewSetValue(value: SET): SetValue;
  1083. VAR obj: SetValue;
  1084. BEGIN
  1085. NEW(obj, value); RETURN obj
  1086. END NewSetValue;
  1087. PROCEDURE NewEnumValue(translation: PersistentObjects.Translation; value: LONGINT): EnumValue;
  1088. VAR obj: EnumValue;
  1089. BEGIN
  1090. NEW(obj, translation, value);
  1091. END NewEnumValue;
  1092. PROCEDURE FindInObject*(in: Object; CONST name: ARRAY OF CHAR; index: LONGINT): Object;
  1093. VAR content: Content;
  1094. TYPE Class=PersistentObjects.Class;
  1095. BEGIN
  1096. NEW(content);
  1097. in.Get(name, index, content);
  1098. IF content.success THEN
  1099. CASE content.class OF
  1100. |Class.String: RETURN NewStringValue(content.string^);
  1101. |Class.Object: RETURN content.object
  1102. |Class.Name: RETURN NewNameValue(content.name);
  1103. |Class.Boolean: RETURN NewBooleanValue(content.boolean);
  1104. |Class.Integer: RETURN NewIntegerValue(content.integer);
  1105. |Class.Float: RETURN NewFloatValue(content.float);
  1106. |Class.Enum: RETURN NewEnumValue(content.translation,content.integer)
  1107. |Class.Range: RETURN NewRangeValue(content.range)
  1108. |Class.Set: RETURN NewSetValue(content.set)
  1109. |Class.Char: RETURN NewCharValue(content.char)
  1110. END
  1111. END;
  1112. RETURN NIL
  1113. END FindInObject;
  1114. TYPE
  1115. ObjectFilter* = OBJECT
  1116. VAR
  1117. content: Content;
  1118. object: Object;
  1119. found: Container;
  1120. attribute, value: ARRAY 256 OF CHAR;
  1121. PROCEDURE & InitObjectFilter*;
  1122. BEGIN
  1123. NEW(content); NEW(found);
  1124. END InitObjectFilter;
  1125. PROCEDURE AddFiltered(obj: Object);
  1126. BEGIN
  1127. IF obj # NIL THEN
  1128. obj.Get(attribute, -1, content);
  1129. IF content.success & content.Equals(value) THEN
  1130. found.Enter(obj,"any");
  1131. END;
  1132. END;
  1133. END AddFiltered;
  1134. PROCEDURE Enumerate(CONST name: ARRAY OF CHAR; array: BOOLEAN);
  1135. VAR obj: Object; index: LONGINT;
  1136. BEGIN
  1137. object.Get(name,-1, content);
  1138. IF content.success & (content.class = PersistentObjects.Class.Object) THEN
  1139. IF array THEN
  1140. index := 0;
  1141. REPEAT
  1142. object.Get(name, index, content);
  1143. obj := content.object;
  1144. AddFiltered(obj);
  1145. INC(index);
  1146. UNTIL obj = NIL;
  1147. ELSE
  1148. AddFiltered(content.object)
  1149. END;
  1150. END;
  1151. END Enumerate;
  1152. PROCEDURE Filter*(obj: Object; attribute, value: ARRAY OF CHAR): Container;
  1153. BEGIN
  1154. NEW(found);
  1155. object := obj;
  1156. COPY(attribute, SELF.attribute);
  1157. COPY(value, SELF.value);
  1158. obj.Enumerate(Enumerate);
  1159. RETURN found
  1160. END Filter;
  1161. END ObjectFilter;
  1162. PROCEDURE FindType(CONST types: POINTER TO ARRAY OF Modules.TypeDesc; CONST name: ARRAY OF CHAR): Modules.TypeDesc;
  1163. VAR i: LONGINT;
  1164. BEGIN
  1165. IF types = NIL THEN RETURN NIL END;
  1166. FOR i := 0 TO LEN(types)-1 DO
  1167. IF types[i].name = name THEN
  1168. RETURN types[i];
  1169. END;
  1170. END;
  1171. RETURN NIL;
  1172. END FindType;
  1173. PROCEDURE FindField(CONST types: POINTER TO ARRAY OF Modules.FieldEntry; CONST name: ARRAY OF CHAR; VAR num: LONGINT): BOOLEAN;
  1174. BEGIN
  1175. IF types = NIL THEN RETURN FALSE END;
  1176. FOR num := 0 TO LEN(types)-1 DO
  1177. IF types[num].name^ = name THEN
  1178. RETURN TRUE;
  1179. END;
  1180. END;
  1181. RETURN FALSE;
  1182. END FindField;
  1183. PROCEDURE FindProc(CONST types: POINTER TO ARRAY OF Modules.ProcedureEntry; CONST name: ARRAY OF CHAR; VAR num: LONGINT): BOOLEAN;
  1184. BEGIN
  1185. IF types = NIL THEN RETURN FALSE END;
  1186. FOR num := 0 TO LEN(types)-1 DO
  1187. IF types[num].name^ = name THEN
  1188. RETURN TRUE;
  1189. END;
  1190. END;
  1191. RETURN FALSE;
  1192. END FindProc;
  1193. PROCEDURE GetModule*(CONST name: ARRAY OF CHAR): ModuleResult;
  1194. VAR msg: ARRAY 128 OF CHAR; res: LONGINT; mod:ModuleResult; m: Modules.Module;
  1195. BEGIN
  1196. m := Modules.ThisModule(name, res, msg);
  1197. IF m # NIL THEN
  1198. NEW(mod, name, m);
  1199. ELSE
  1200. mod := NIL;
  1201. END;
  1202. RETURN mod;
  1203. END GetModule;
  1204. PROCEDURE FindInObject1*(in: Object; name: StringPool.Index; index: LONGINT): Object;
  1205. VAR str: ARRAY 256 OF CHAR;
  1206. BEGIN
  1207. StringPool.GetString(name, str);
  1208. RETURN FindInObject(in,str,index);
  1209. END FindInObject1;
  1210. END FoxInterpreterSymbols.
  1211. SystemTools.FreeDownTo FoxInterpreterSymbols ~
  1212. FoxInterpreterSymbols.Test ~