FoxInterpreterSymbols.Mod 41 KB

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