FoxInterpreterSymbols.Mod 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  1. MODULE FoxInterpreterSymbols; (** AUTHOR ""; PURPOSE ""; *)
  2. IMPORT Strings, Basic := FoxBasic, StringPool, Streams, Commands, PersistentObjects, Modules, 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, 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. END Find;
  82. END ModuleResult;
  83. ProcedureResult*= OBJECT(SymbolResult)
  84. VAR
  85. proc: Modules.ProcedureEntry;
  86. address: ADDRESS;
  87. PROCEDURE & InitProcedure(CONST name: ARRAY OF CHAR; CONST p: Modules.ProcedureEntry);
  88. BEGIN
  89. InitSymbol(name); proc := p;
  90. END InitProcedure;
  91. END ProcedureResult;
  92. FieldResult = OBJECT (SymbolResult)
  93. VAR field: Modules.FieldEntry;
  94. address: ADDRESS;
  95. PROCEDURE & InitField(CONST name: ARRAY OF CHAR; CONST f: Modules.FieldEntry);
  96. BEGIN
  97. InitSymbol(name); field := f;
  98. END InitField;
  99. PROCEDURE Evaluate(): Value;
  100. VAR l: LONGINT;
  101. int: IntegerValue;
  102. BEGIN
  103. CASE field.type.class OF
  104. sfTypeSignedInteger:
  105. SYSTEM.GET(address, l);
  106. NEW(int, l);
  107. RETURN int
  108. ELSE
  109. HALT(100);
  110. END;
  111. END Evaluate;
  112. PROCEDURE SetV(v: Value): BOOLEAN;
  113. VAR h: HUGEINT; s: SHORTINT; i: INTEGER; l: LONGINT;
  114. BEGIN
  115. CASE field.type.class OF
  116. sfTypeSignedInteger:
  117. IF v.GetInt(h) THEN
  118. CASE field.type.size OF
  119. 8: s:= SHORTINT(h); SYSTEM.PUT(address, s);
  120. |16: i:= INTEGER(h); SYSTEM.PUT(address, i);
  121. |32:l := LONGINT(h); SYSTEM.PUT(address, l);
  122. |64: SYSTEM.PUT(address, h);
  123. END;
  124. RETURN TRUE
  125. END;
  126. END;
  127. END SetV;
  128. PROCEDURE Find(CONST name: ARRAY OF CHAR): Result;
  129. VAR type, value: ADDRESS;
  130. VAR typeInfo: Modules.TypeDesc; num: LONGINT;
  131. proc: ProcedureResult; f: FieldResult;
  132. BEGIN
  133. IF (field.type.class = sfTypePointerToRecord)
  134. OR (field.type.class = sfTypeAny)
  135. OR (field.type.class = sfTypeObject)
  136. THEN
  137. SYSTEM.GET(address, value);
  138. SYSTEM.GET(value-SIZEOF(ADDRESS), type); (* type desc *)
  139. SYSTEM.GET(type-SIZEOF(ADDRESS), typeInfo); (* type info*)
  140. IF FindProc(typeInfo.procedures, name,num) THEN
  141. NEW(proc, name, typeInfo.procedures[num]);
  142. proc.address := typeInfo.procedures[num].address;
  143. RETURN proc
  144. ELSIF FindField(typeInfo.fields, name, num) THEN
  145. NEW(f, name, typeInfo.fields[num]);
  146. f.address := value + typeInfo.fields[num].offset;
  147. RETURN f;
  148. ELSE HALT(101);
  149. END;
  150. ELSIF field.type.class = sfTypeRecord THEN
  151. type := field.type.type;
  152. SYSTEM.GET(type-SIZEOF(ADDRESS), typeInfo); (* type info*)
  153. IF FindProc(typeInfo.procedures, name,num) THEN
  154. NEW(proc, name, typeInfo.procedures[num]);
  155. proc.address := typeInfo.procedures[num].address;
  156. RETURN proc
  157. ELSIF FindField(typeInfo.fields, name, num) THEN
  158. NEW(f, name, typeInfo.fields[num]);
  159. f.address := address + typeInfo.fields[num].offset;
  160. RETURN f;
  161. ELSE HALT(101);
  162. END;
  163. ELSE HALT(100);
  164. END;
  165. END Find;
  166. END FieldResult;
  167. Value*= OBJECT(Result)
  168. PROCEDURE & InitValue;
  169. BEGIN InitObject
  170. END InitValue;
  171. PROCEDURE Evaluate(): Value;
  172. BEGIN
  173. RETURN SELF;
  174. END Evaluate;
  175. PROCEDURE GetInt(VAR h: HUGEINT): BOOLEAN;
  176. BEGIN
  177. RETURN FALSE;
  178. END GetInt;
  179. PROCEDURE GetReal(VAR x: LONGREAL): BOOLEAN;
  180. BEGIN
  181. RETURN FALSE;
  182. END GetReal;
  183. PROCEDURE WriteValue*(w: Streams.Writer);
  184. BEGIN
  185. END WriteValue;
  186. PROCEDURE GetString*(VAR w: ARRAY OF CHAR);
  187. VAR stringWriter: Streams.StringWriter;
  188. BEGIN
  189. NEW(stringWriter, 128);
  190. WriteValue(stringWriter); stringWriter.Update;
  191. stringWriter.Get(w);
  192. END GetString;
  193. END Value;
  194. CONST StrValue="value";
  195. TYPE
  196. AnyValue*=OBJECT(Value)
  197. VAR value*:ADDRESS;
  198. PROCEDURE & InitAny*(value: ADDRESS);
  199. BEGIN InitValue; SELF.value := value; type := "AnyValue";
  200. END InitAny;
  201. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  202. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  203. END Enumerate;
  204. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  205. VAR int: LONGINT;
  206. BEGIN
  207. IF name = StrValue THEN c.GetInteger(int); value := int;
  208. ELSE Set^(name, index, c);
  209. END;
  210. END Set;
  211. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  212. BEGIN
  213. IF name = StrValue THEN c.SetInteger(value);
  214. ELSE Get^(name, index, c);
  215. END;
  216. END Get;
  217. PROCEDURE WriteValue(w: Streams.Writer);
  218. BEGIN w.Int(value,0);
  219. END WriteValue;
  220. PROCEDURE Address(): ADDRESS;
  221. BEGIN
  222. RETURN ADDRESSOF(value)
  223. END Address;
  224. END AnyValue;
  225. IntegerValue*=OBJECT(Value)
  226. VAR value*: LONGINT;
  227. PROCEDURE & InitInteger*(value: LONGINT);
  228. BEGIN InitValue; SELF.value := value; type := "IntegerValue";
  229. END InitInteger;
  230. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  231. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  232. END Enumerate;
  233. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  234. BEGIN
  235. IF name = StrValue THEN c.GetInteger(value);
  236. ELSE Set^(name, index, c);
  237. END;
  238. END Set;
  239. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  240. BEGIN
  241. IF name = StrValue THEN c.SetInteger(value);
  242. ELSE Get^(name, index, c);
  243. END;
  244. END Get;
  245. PROCEDURE GetInt(VAR v: HUGEINT): BOOLEAN;
  246. BEGIN
  247. v := value; RETURN TRUE;
  248. END GetInt;
  249. PROCEDURE WriteValue(w: Streams.Writer);
  250. BEGIN w.Int(value,0);
  251. END WriteValue;
  252. PROCEDURE Address(): ADDRESS;
  253. BEGIN
  254. RETURN ADDRESSOF(value)
  255. END Address;
  256. END IntegerValue;
  257. RealValue*=OBJECT(Value)
  258. VAR value*: LONGREAL;
  259. PROCEDURE & InitReal*(value: LONGREAL);
  260. BEGIN InitValue; SELF.value := value; type := "RealValue";
  261. END InitReal;
  262. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  263. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  264. END Enumerate;
  265. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  266. BEGIN
  267. IF name = StrValue THEN c.GetFloat(value);
  268. ELSE Set^(name, index, c);
  269. END;
  270. END Set;
  271. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  272. BEGIN
  273. IF name = StrValue THEN c.SetFloat(value);
  274. ELSE Get^(name, index, c);
  275. END;
  276. END Get;
  277. PROCEDURE WriteValue(w: Streams.Writer);
  278. BEGIN w.Float(value,40);
  279. END WriteValue;
  280. PROCEDURE Address(): ADDRESS;
  281. BEGIN
  282. RETURN ADDRESSOF(value)
  283. END Address;
  284. END RealValue;
  285. BooleanValue*=OBJECT(Value)
  286. VAR value*: BOOLEAN;
  287. PROCEDURE & InitBoolean*(value: BOOLEAN);
  288. BEGIN InitValue; SELF.value := value; type := "BooleanValue";
  289. END InitBoolean;
  290. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  291. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  292. END Enumerate;
  293. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  294. BEGIN
  295. IF name = StrValue THEN c.GetBoolean(value);
  296. ELSE Set^(name, index, c);
  297. END;
  298. END Set;
  299. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  300. BEGIN
  301. IF name = StrValue THEN c.SetBoolean(value);
  302. ELSE Get^(name, index, c);
  303. END;
  304. END Get;
  305. PROCEDURE WriteValue(w: Streams.Writer);
  306. BEGIN IF value THEN w.String("TRUE") ELSE w.String("FALSE") END
  307. END WriteValue;
  308. PROCEDURE Address(): ADDRESS;
  309. BEGIN
  310. RETURN ADDRESSOF(value)
  311. END Address;
  312. END BooleanValue;
  313. StringValue*=OBJECT(Value)
  314. VAR value*: Strings.String;
  315. PROCEDURE & InitString*(CONST value: ARRAY OF CHAR);
  316. BEGIN InitValue; SELF.value := Strings.NewString(value); type := "StringValue";
  317. END InitString;
  318. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  319. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  320. END Enumerate;
  321. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  322. BEGIN
  323. IF name = StrValue THEN c.GetString(value);
  324. ELSE Set^(name, index, c);
  325. END;
  326. END Set;
  327. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  328. BEGIN
  329. IF name = StrValue THEN c.SetString(value);
  330. ELSE Get^(name, index, c);
  331. END;
  332. END Get;
  333. PROCEDURE WriteValue(w: Streams.Writer);
  334. BEGIN (*w.String('"');*) w.String(value^); (*w.String('"');*)
  335. END WriteValue;
  336. PROCEDURE Address(): ADDRESS;
  337. BEGIN
  338. RETURN value;
  339. END Address;
  340. END StringValue;
  341. SetValue*=OBJECT(Value)
  342. VAR value*: SET;
  343. PROCEDURE & InitSet*(value: SET);
  344. BEGIN InitValue; SELF.value := value; type := "SetValue"
  345. END InitSet;
  346. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  347. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  348. END Enumerate;
  349. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  350. BEGIN
  351. IF name = StrValue THEN c.GetSet(value);
  352. ELSE Set^(name, index, c);
  353. END;
  354. END Set;
  355. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  356. BEGIN
  357. IF name = StrValue THEN c.SetSet(value);
  358. ELSE Get^(name, index, c);
  359. END;
  360. END Get;
  361. PROCEDURE WriteValue(w: Streams.Writer);
  362. BEGIN
  363. w.Set(value)
  364. END WriteValue;
  365. PROCEDURE Address(): ADDRESS;
  366. BEGIN
  367. RETURN ADDRESSOF(value)
  368. END Address;
  369. END SetValue;
  370. RangeValue*=OBJECT(Value)
  371. VAR value*: RANGE;
  372. PROCEDURE & InitRange*(r: RANGE);
  373. BEGIN InitValue; value := r; type := "RangeValue"
  374. END InitRange;
  375. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  376. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  377. END Enumerate;
  378. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  379. BEGIN
  380. IF name = StrValue THEN c.GetRange(value);
  381. ELSE Set^(name, index, c);
  382. END;
  383. END Set;
  384. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  385. BEGIN
  386. IF name = StrValue THEN c.SetRange(value);
  387. ELSE Get^(name, index, c);
  388. END;
  389. END Get;
  390. PROCEDURE WriteValue(w: Streams.Writer);
  391. BEGIN
  392. 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;
  393. END WriteValue;
  394. PROCEDURE Address(): ADDRESS;
  395. BEGIN
  396. RETURN ADDRESSOF(value)
  397. END Address;
  398. END RangeValue;
  399. CharValue*=OBJECT(Value)
  400. VAR value: CHAR;
  401. PROCEDURE & InitChar*(c: CHAR);
  402. BEGIN InitValue; value := c; type := "CharValue";
  403. END InitChar;
  404. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  405. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  406. END Enumerate;
  407. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  408. BEGIN
  409. IF name = StrValue THEN c.GetChar(value);
  410. ELSE Set^(name, index, c);
  411. END;
  412. END Set;
  413. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  414. BEGIN
  415. IF name = StrValue THEN c.SetChar(value);
  416. ELSE Get^(name, index, c);
  417. END;
  418. END Get;
  419. PROCEDURE WriteValue(w: Streams.Writer);
  420. BEGIN
  421. w.Hex(ORD(value),2); w.String("X");
  422. END WriteValue;
  423. PROCEDURE Address(): ADDRESS;
  424. BEGIN
  425. RETURN ADDRESSOF(value)
  426. END Address;
  427. END CharValue;
  428. EnumValue*=OBJECT(Value)
  429. VAR value: LONGINT; translation: PersistentObjects.Translation;
  430. PROCEDURE & InitEnumValue*(trans: PersistentObjects.Translation; v: LONGINT);
  431. BEGIN InitValue; value := v; translation := trans; type := "EnumValue";
  432. END InitEnumValue;
  433. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  434. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  435. END Enumerate;
  436. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  437. BEGIN
  438. IF name = StrValue THEN c.GetEnum(translation, value);
  439. ELSE Set^(name, index, c);
  440. END;
  441. END Set;
  442. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  443. BEGIN
  444. IF name = StrValue THEN c.SetEnum(translation, value);
  445. ELSE Get^(name, index, c);
  446. END;
  447. END Get;
  448. PROCEDURE WriteValue(w: Streams.Writer);
  449. VAR str: ARRAY 32 OF CHAR;
  450. BEGIN
  451. IF translation.Name(value, str) THEN w.String(str) ELSE w.String("unknown") END;
  452. END WriteValue;
  453. PROCEDURE Address(): ADDRESS;
  454. BEGIN
  455. RETURN ADDRESSOF(value)
  456. END Address;
  457. END EnumValue;
  458. MathArrayValue*=OBJECT(Value)
  459. VAR values: ARRAY [*] OF Value;
  460. PROCEDURE &InitMathArrayValue*(len: LONGINT);
  461. BEGIN
  462. InitValue;
  463. NEW(values, len);
  464. type := "MathArrayValue";
  465. END InitMathArrayValue;
  466. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  467. BEGIN Enumerate^(enum); enum(StrValue,FALSE);
  468. END Enumerate;
  469. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  470. BEGIN
  471. IF name = StrValue THEN values[index] := ContentGetValue(c)
  472. ELSE Set^(name, index, c);
  473. END;
  474. END Set;
  475. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  476. BEGIN
  477. IF name = StrValue THEN c.SetObject(values[index],"Value");
  478. ELSE Get^(name, index, c);
  479. END;
  480. END Get;
  481. PROCEDURE SetValue*(at: LONGINT; value: Value);
  482. BEGIN
  483. values[at] := value;
  484. END SetValue;
  485. PROCEDURE GetValue*(at: LONGINT): Value;
  486. BEGIN
  487. RETURN values[at]
  488. END GetValue;
  489. PROCEDURE WriteValue*(w: Streams.Writer);
  490. VAR i: LONGINT; max: LONGINT;
  491. BEGIN
  492. w.String("[ ");
  493. max := LEN(values,0)-1;
  494. FOR i := 0 TO max DO
  495. values[i].WriteValue(w);
  496. IF i < max THEN
  497. w.String(", ");
  498. END;
  499. END;
  500. w.String("] ");
  501. END WriteValue;
  502. END MathArrayValue;
  503. (* object value represented as ANY wrapped in Value ? *)
  504. Symbol*= OBJECT
  505. VAR
  506. name: StringPool.Index;
  507. item-: Item;
  508. PROCEDURE & InitSymbol(name: StringPool.Index; index: LONGINT);
  509. BEGIN
  510. SELF.name := name; SELF.item := item;
  511. END InitSymbol;
  512. PROCEDURE GetName(VAR name: ARRAY OF CHAR);
  513. BEGIN
  514. StringPool.GetString(SELF.name, name);
  515. END GetName;
  516. END Symbol;
  517. Container* = OBJECT (Item)
  518. VAR
  519. symbols-: Basic.List;
  520. lookup-: Basic.HashTableInt;
  521. (* New scope. Note that it is possible that a scope is registered with an alias *)
  522. PROCEDURE & InitContainer*;
  523. BEGIN
  524. InitObject();
  525. NEW(lookup, 16); NEW(symbols, 16);
  526. type := "Container";
  527. END InitContainer;
  528. PROCEDURE Enumerate(enum: PersistentObjects.Enumerator);
  529. VAR i: LONGINT; symbol: Symbol; o: ANY; name: ARRAY 256 OF CHAR;
  530. BEGIN Enumerate^(enum);
  531. FOR i := 0 TO symbols.Length()-1 DO
  532. o := symbols.Get(i);
  533. symbol := o(Symbol);
  534. symbol.GetName(name);
  535. enum(name, FALSE);
  536. END;
  537. END Enumerate;
  538. PROCEDURE Set(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  539. BEGIN
  540. IF FALSE THEN
  541. ELSE Set^(name, index, c);
  542. END;
  543. END Set;
  544. PROCEDURE Get(CONST name: ARRAY OF CHAR; index: LONGINT; c: Content);
  545. VAR item: Item;
  546. BEGIN
  547. item := Find(name);
  548. IF item # NIL THEN c.SetObject(item,"Item")
  549. ELSE Get^(name, index, c);
  550. END;
  551. END Get;
  552. PROCEDURE GetItem*(index: LONGINT): Item;
  553. BEGIN
  554. RETURN symbols.Get(index)(Symbol).item
  555. END GetItem;
  556. (* Enter a symbol with its name *)
  557. PROCEDURE Enter1*(item: Item; name: StringPool.Index);
  558. VAR any: ANY; symbol: Symbol;
  559. BEGIN
  560. any := lookup.Get(name);
  561. IF any # NIL THEN
  562. symbol := any(Symbol)
  563. ELSE
  564. NEW(symbol, name, symbols.Length());
  565. symbols.Add(symbol);
  566. lookup.Put(symbol.name, symbol);
  567. END;
  568. symbol.item := item
  569. END Enter1;
  570. (* Enter a symbol with its name *)
  571. PROCEDURE Enter*(item: Item; CONST name: ARRAY OF CHAR);
  572. BEGIN
  573. Enter1(item, StringPool.GetIndex1(name))
  574. END Enter;
  575. PROCEDURE Find1*(id: LONGINT): Item;
  576. VAR any: ANY;
  577. BEGIN
  578. any := lookup.Get(id);
  579. IF any # NIL THEN RETURN any(Symbol).item ELSE RETURN NIL END
  580. END Find1;
  581. (* Find a symbol with name *)
  582. PROCEDURE Find*(CONST name: ARRAY OF CHAR): Item;
  583. BEGIN
  584. RETURN Find1(StringPool.GetIndex1(name))
  585. END Find;
  586. END Container;
  587. Scope* = OBJECT
  588. VAR
  589. outer-: Scope;
  590. object-: Object;
  591. level: LONGINT;
  592. PROCEDURE & InitScope*(outer: Scope; object: Object);
  593. BEGIN
  594. SELF.outer := outer;
  595. IF outer = NIL THEN level := 0 ELSE level := outer.level + 1 END;
  596. ASSERT(object # NIL);
  597. SELF.object := object
  598. END InitScope;
  599. PROCEDURE Enter*(object: Object): Scope;
  600. VAR scope: Scope;
  601. BEGIN
  602. NEW(scope, SELF, object);
  603. RETURN scope
  604. END Enter;
  605. PROCEDURE FindObject*(CONST name: ARRAY OF CHAR; index: LONGINT; VAR in: Object): Object;
  606. VAR object: Object;
  607. BEGIN
  608. in := SELF.object;
  609. object := FindInObject(in, name, index);
  610. IF (object = NIL) & (outer # NIL) THEN
  611. object := outer.FindObject(name, index, in)
  612. END;
  613. RETURN object
  614. END FindObject;
  615. PROCEDURE FindObject1*(name: StringPool.Index; index: LONGINT; VAR in: Object): Object;
  616. VAR str: ARRAY 256 OF CHAR;
  617. BEGIN
  618. StringPool.GetString(name, str);
  619. RETURN FindObject(str,index, in);
  620. END FindObject1;
  621. PROCEDURE Leave*(): Scope;
  622. BEGIN
  623. RETURN outer
  624. END Leave;
  625. PROCEDURE Dump*(log: Streams.Writer);
  626. BEGIN
  627. IF object # NIL THEN object.Dump(log,"scope object") END;
  628. log.Ln;
  629. IF outer # NIL THEN outer.Dump(log) END;
  630. END Dump;
  631. END Scope;
  632. PROCEDURE Indent(w: Streams.Writer; level: LONGINT);
  633. BEGIN
  634. WHILE level> 0 DO w.Char(TAB); DEC(level) END;
  635. END Indent;
  636. PROCEDURE Test*(context: Commands.Context);
  637. VAR scope, inner: Scope; container: Container; integer: IntegerValue; float: RealValue; string: StringValue;
  638. BEGIN
  639. NEW(container);
  640. container.Enter(integer, "integer");
  641. container.Enter(float,"float");
  642. container.Enter(string,"string");
  643. NEW(scope, NIL, container);
  644. NEW(container);
  645. inner := scope.Enter(container);
  646. scope.Dump(context.out);
  647. (*scope.Write(context.out);*)
  648. END Test;
  649. PROCEDURE ContentGetValue(c: Content): Value;
  650. VAR o: Object;
  651. BEGIN
  652. c.GetObject(o); IF o = NIL THEN RETURN NIL ELSE RETURN o(Value) END;
  653. END ContentGetValue;
  654. PROCEDURE NewIntegerValue(value: LONGINT): IntegerValue;
  655. VAR obj: IntegerValue;
  656. BEGIN
  657. NEW(obj, value); RETURN obj
  658. END NewIntegerValue;
  659. PROCEDURE NewFloatValue(value: LONGREAL): RealValue;
  660. VAR obj: RealValue;
  661. BEGIN
  662. NEW(obj, value); RETURN obj
  663. END NewFloatValue;
  664. PROCEDURE NewBooleanValue(value: BOOLEAN): BooleanValue;
  665. VAR obj: BooleanValue;
  666. BEGIN
  667. NEW(obj, value); RETURN obj
  668. END NewBooleanValue;
  669. PROCEDURE NewStringValue(CONST value: ARRAY OF CHAR): StringValue;
  670. VAR obj: StringValue;
  671. BEGIN
  672. NEW(obj, value); RETURN obj
  673. END NewStringValue;
  674. PROCEDURE NewNameValue(CONST value: ARRAY OF CHAR): StringValue;
  675. VAR obj: StringValue;
  676. BEGIN
  677. NEW(obj, value); RETURN obj
  678. END NewNameValue;
  679. PROCEDURE NewRangeValue(value: RANGE): RangeValue;
  680. VAR obj: RangeValue;
  681. BEGIN
  682. NEW(obj, value); RETURN obj
  683. END NewRangeValue;
  684. PROCEDURE NewCharValue(value: CHAR): CharValue;
  685. VAR obj: CharValue;
  686. BEGIN
  687. NEW(obj, value); RETURN obj
  688. END NewCharValue;
  689. PROCEDURE NewSetValue(value: SET): SetValue;
  690. VAR obj: SetValue;
  691. BEGIN
  692. NEW(obj, value); RETURN obj
  693. END NewSetValue;
  694. PROCEDURE NewEnumValue(translation: PersistentObjects.Translation; value: LONGINT): EnumValue;
  695. VAR obj: EnumValue;
  696. BEGIN
  697. NEW(obj, translation, value);
  698. END NewEnumValue;
  699. PROCEDURE FindInObject*(in: Object; CONST name: ARRAY OF CHAR; index: LONGINT): Object;
  700. VAR content: Content;
  701. TYPE Class=PersistentObjects.Class;
  702. BEGIN
  703. NEW(content);
  704. in.Get(name, index, content);
  705. IF content.success THEN
  706. CASE content.class OF
  707. |Class.String: RETURN NewStringValue(content.string^);
  708. |Class.Object: RETURN content.object
  709. |Class.Name: RETURN NewNameValue(content.name);
  710. |Class.Boolean: RETURN NewBooleanValue(content.boolean);
  711. |Class.Integer: RETURN NewIntegerValue(content.integer);
  712. |Class.Float: RETURN NewFloatValue(content.float);
  713. |Class.Enum: RETURN NewEnumValue(content.translation,content.integer)
  714. |Class.Range: RETURN NewRangeValue(content.range)
  715. |Class.Set: RETURN NewSetValue(content.set)
  716. |Class.Char: RETURN NewCharValue(content.char)
  717. END
  718. END;
  719. RETURN NIL
  720. END FindInObject;
  721. TYPE
  722. ObjectFilter* = OBJECT
  723. VAR
  724. content: Content;
  725. object: Object;
  726. found: Container;
  727. attribute, value: ARRAY 256 OF CHAR;
  728. PROCEDURE & InitObjectFilter*;
  729. BEGIN
  730. NEW(content); NEW(found);
  731. END InitObjectFilter;
  732. PROCEDURE AddFiltered(obj: Object);
  733. BEGIN
  734. IF obj # NIL THEN
  735. obj.Get(attribute, -1, content);
  736. IF content.success & content.Equals(value) THEN
  737. found.Enter(obj,"any");
  738. END;
  739. END;
  740. END AddFiltered;
  741. PROCEDURE Enumerate(CONST name: ARRAY OF CHAR; array: BOOLEAN);
  742. VAR obj: Object; index: LONGINT;
  743. BEGIN
  744. object.Get(name,-1, content);
  745. IF content.success & (content.class = PersistentObjects.Class.Object) THEN
  746. IF array THEN
  747. index := 0;
  748. REPEAT
  749. object.Get(name, index, content);
  750. obj := content.object;
  751. AddFiltered(obj);
  752. INC(index);
  753. UNTIL obj = NIL;
  754. ELSE
  755. AddFiltered(content.object)
  756. END;
  757. END;
  758. END Enumerate;
  759. PROCEDURE Filter*(obj: Object; attribute, value: ARRAY OF CHAR): Container;
  760. BEGIN
  761. NEW(found);
  762. object := obj;
  763. COPY(attribute, SELF.attribute);
  764. COPY(value, SELF.value);
  765. obj.Enumerate(Enumerate);
  766. RETURN found
  767. END Filter;
  768. END ObjectFilter;
  769. PROCEDURE FindType(CONST types: POINTER TO ARRAY OF Modules.TypeDesc; CONST name: ARRAY OF CHAR): Modules.TypeDesc;
  770. VAR i: LONGINT;
  771. BEGIN
  772. IF types = NIL THEN RETURN NIL END;
  773. FOR i := 0 TO LEN(types)-1 DO
  774. IF types[i].name = name THEN
  775. RETURN types[i];
  776. END;
  777. END;
  778. RETURN NIL;
  779. END FindType;
  780. PROCEDURE FindField(CONST types: POINTER TO ARRAY OF Modules.FieldEntry; CONST name: ARRAY OF CHAR; VAR num: LONGINT): BOOLEAN;
  781. BEGIN
  782. IF types = NIL THEN RETURN FALSE END;
  783. FOR num := 0 TO LEN(types)-1 DO
  784. IF types[num].name^ = name THEN
  785. RETURN TRUE;
  786. END;
  787. END;
  788. RETURN FALSE;
  789. END FindField;
  790. PROCEDURE FindProc(CONST types: POINTER TO ARRAY OF Modules.ProcedureEntry; CONST name: ARRAY OF CHAR; VAR num: LONGINT): BOOLEAN;
  791. BEGIN
  792. IF types = NIL THEN RETURN FALSE END;
  793. FOR num := 0 TO LEN(types)-1 DO
  794. IF types[num].name^ = name THEN
  795. RETURN TRUE;
  796. END;
  797. END;
  798. RETURN FALSE;
  799. END FindProc;
  800. PROCEDURE GetModule*(CONST name: ARRAY OF CHAR): ModuleResult;
  801. VAR msg: ARRAY 128 OF CHAR; res: LONGINT; mod:ModuleResult; m: Modules.Module;
  802. BEGIN
  803. m := Modules.ThisModule(name, res, msg);
  804. IF m # NIL THEN
  805. NEW(mod, name, m);
  806. ELSE
  807. mod := NIL;
  808. END;
  809. RETURN mod;
  810. END GetModule;
  811. PROCEDURE FindInObject1*(in: Object; name: StringPool.Index; index: LONGINT): Object;
  812. VAR str: ARRAY 256 OF CHAR;
  813. BEGIN
  814. StringPool.GetString(name, str);
  815. RETURN FindInObject(in,str,index);
  816. END FindInObject1;
  817. END FoxInterpreterSymbols.
  818. SystemTools.FreeDownTo FoxInterpreterSymbols ~
  819. FoxInterpreterSymbols.Test ~