FoxInterpreter.Mod 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531
  1. MODULE FoxInterpreter; (** AUTHOR ""; PURPOSE ""; *)
  2. IMPORT Scanner := FoxScanner, FoxParser, SyntaxTree := FoxSyntaxTree, Printout := FoxPrintout, Commands, Diagnostics, StringPool, InterpreterSymbols := FoxInterpreterSymbols, D:= Debugging,
  3. Strings, Streams, Modules, PersistentObjects, Basic := FoxBasic, SYSTEM, Machine;
  4. CONST
  5. EnableTrace = FALSE;
  6. MaxIndex = 8;
  7. TYPE
  8. Result*= InterpreterSymbols.Result;
  9. Value*=InterpreterSymbols.Value;
  10. Integer*=InterpreterSymbols.IntegerValue;
  11. Real*=InterpreterSymbols.RealValue;
  12. String*=InterpreterSymbols.StringValue;
  13. Boolean*=InterpreterSymbols.BooleanValue;
  14. Set*=InterpreterSymbols.SetValue;
  15. Range*=InterpreterSymbols.RangeValue;
  16. Char*=InterpreterSymbols.CharValue;
  17. MathArrayValue*= InterpreterSymbols.MathArrayValue;
  18. Scope*=InterpreterSymbols.Scope;
  19. Container*= InterpreterSymbols.Container;
  20. Item*= RECORD
  21. object*: InterpreterSymbols.Item;
  22. in*: InterpreterSymbols.Item;
  23. name*: StringPool.Index;
  24. i*: ARRAY MaxIndex OF LONGINT; (* indices if applicable *)
  25. END;
  26. CommandStatement = OBJECT (SyntaxTree.Statement)
  27. VAR command: Strings.String;
  28. PROCEDURE & InitCommandStatement(s: Strings.String);
  29. BEGIN
  30. command := s
  31. END InitCommandStatement;
  32. END CommandStatement;
  33. Parser*= OBJECT(FoxParser.Parser)
  34. PROCEDURE Statement(statements: SyntaxTree.StatementSequence; outer: SyntaxTree.Statement): BOOLEAN;
  35. VAR statement: SyntaxTree.Statement;
  36. BEGIN
  37. IF (symbol.token = Scanner.Identifier) & (symbol.identifier = StringPool.GetIndex1("CMD")) THEN
  38. statement := Cmd();
  39. statements.AddStatement(statement);
  40. RETURN TRUE
  41. (*
  42. ELSIF (symbol.token = Scanner.Identifier) & (symbol.identifier = StringPool.GetIndex1("CMDS")) THEN
  43. REPEAT
  44. statement := Cmd();
  45. statements.AddStatement(statement);
  46. UNTIL (symbol.token = Scanner.Identifier) & (symbol.identifier = StringPool.GetIndex1("ENDCMDS"))
  47. *)
  48. ELSE
  49. RETURN Statement^(statements, outer);
  50. END;
  51. END Statement;
  52. PROCEDURE Cmd(): SyntaxTree.Statement;
  53. VAR cmd: CommandStatement; string: Strings.String;
  54. BEGIN
  55. NextSymbol;
  56. IF MandatoryString(string) THEN
  57. NEW(cmd, string);
  58. (* TRACE(string^) *)
  59. END;
  60. RETURN cmd;
  61. END Cmd;
  62. END Parser;
  63. Callstack = OBJECT
  64. VAR
  65. data: ARRAY 1024 OF CHAR;
  66. pos: LONGINT;
  67. size: LONGINT;
  68. H: HUGEINT; (* result in register *)
  69. retType: Modules.FieldEntry;
  70. parameters: POINTER TO ARRAY OF Modules.FieldEntry;
  71. pPos: LONGINT;
  72. PROCEDURE & Init;
  73. BEGIN
  74. pos := 1024; size := 0;
  75. END Init;
  76. PROCEDURE Next(s: SIZE): ADDRESS;
  77. BEGIN
  78. DEC(pos, s); INC(size, s);
  79. RETURN ADDRESSOF(data[pos]);
  80. END Next;
  81. PROCEDURE PushH(h: HUGEINT);
  82. VAR p: POINTER {UNSAFE} TO RECORD h: HUGEINT END;
  83. BEGIN
  84. p := Next(SIZEOF(HUGEINT));
  85. p.h := h;
  86. END PushH;
  87. PROCEDURE PushL(i: LONGINT);
  88. VAR p: POINTER {UNSAFE} TO RECORD i: LONGINT END;
  89. BEGIN
  90. p := Next(SIZEOF(LONGINT));
  91. p.i := i;
  92. END PushL;
  93. PROCEDURE PushI(i: INTEGER);
  94. BEGIN
  95. PushL(i);
  96. END PushI;
  97. PROCEDURE PushS(i: SHORTINT);
  98. BEGIN
  99. PushL(i);
  100. END PushS;
  101. PROCEDURE PushC(c: CHAR);
  102. BEGIN
  103. PushL(ORD(c));
  104. END PushC;
  105. PROCEDURE PushR(r: REAL);
  106. VAR p: POINTER {UNSAFE} TO RECORD r: REAL END;
  107. BEGIN
  108. p := Next(SIZEOF(REAL));
  109. p.r := r;
  110. END PushR;
  111. PROCEDURE PushX(x: LONGREAL);
  112. VAR p: POINTER {UNSAFE} TO RECORD x: LONGREAL END;
  113. BEGIN
  114. p := Next(SIZEOF(LONGREAL));
  115. p.x := x;
  116. END PushX;
  117. PROCEDURE PushA(a: ADDRESS);
  118. VAR p: POINTER {UNSAFE} TO RECORD a: ADDRESS END;
  119. BEGIN
  120. p := Next(SIZEOF(ADDRESS));
  121. p.a := a;
  122. END PushA;
  123. PROCEDURE PushSz(s: SIZE);
  124. VAR p: POINTER {UNSAFE} TO RECORD s: SIZE END;
  125. BEGIN
  126. p := Next(SIZEOF(SIZE));
  127. p.s := s;
  128. END PushSz;
  129. PROCEDURE Call(adr: ADDRESS);
  130. VAR esp: ADDRESS; P: Procedure; h: HUGEINT
  131. TYPE
  132. Procedure = PROCEDURE(): HUGEINT;
  133. BEGIN
  134. P := SYSTEM.VAL(Procedure, adr);
  135. esp := Machine.CurrentSP();
  136. Machine.SetSP(esp-size);
  137. SYSTEM.MOVE(ADDRESS OF data[pos], esp-size, size);
  138. H := P();
  139. Machine.SetSP(esp);
  140. END Call;
  141. PROCEDURE ResH(): HUGEINT;
  142. BEGIN
  143. RETURN H;
  144. END ResH;
  145. PROCEDURE ResL(): LONGINT;
  146. BEGIN
  147. RETURN LONGINT(H);
  148. END ResL;
  149. PROCEDURE ResI(): INTEGER;
  150. BEGIN
  151. RETURN INTEGER(H);
  152. END ResI;
  153. PROCEDURE ResS(): SHORTINT;
  154. BEGIN
  155. RETURN SHORTINT(H);
  156. END ResS;
  157. PROCEDURE ResC(): CHAR;
  158. BEGIN
  159. RETURN CHR(H);
  160. END ResC;
  161. PROCEDURE ResSet(): SET;
  162. BEGIN
  163. RETURN SYSTEM.VAL(SET,H);
  164. END ResSet;
  165. PROCEDURE ResSz(): SIZE;
  166. BEGIN
  167. RETURN SYSTEM.VAL(SIZE, H);
  168. END ResSz;
  169. PROCEDURE ResA(): ADDRESS;
  170. BEGIN
  171. RETURN SYSTEM.VAL(ADDRESS, H)
  172. END ResA;
  173. PROCEDURE ResR(): REAL;
  174. BEGIN
  175. RETURN SYSTEM.VAL(REAL, ResL())
  176. END ResR;
  177. PROCEDURE ResX(): LONGREAL;
  178. BEGIN
  179. RETURN SYSTEM.VAL(LONGREAL, ResH())
  180. END ResX;
  181. END Callstack;
  182. Interpreter* = OBJECT (SyntaxTree.Visitor)
  183. VAR
  184. value: BOOLEAN;
  185. item-: Item;
  186. module-: Modules.Module;
  187. typeDesc-: Modules.TypeDesc;
  188. procedureDesc-: Modules.ProcedureEntry;
  189. scope-: Scope;
  190. exit: BOOLEAN;
  191. error-: BOOLEAN;
  192. diagnostics: Diagnostics.Diagnostics;
  193. context-: Commands.Context;
  194. callStack: Callstack;
  195. PROCEDURE & Init*(scope: Scope; diagnostics: Diagnostics.Diagnostics; context: Commands.Context);
  196. BEGIN
  197. IF scope = NIL THEN scope := global END;
  198. SELF.scope := scope;
  199. error := FALSE;
  200. SELF.diagnostics := diagnostics;
  201. SELF.context := context;
  202. NEW(callStack);
  203. END Init;
  204. PROCEDURE SetScope*(s: Scope);
  205. BEGIN
  206. scope := s
  207. END SetScope;
  208. PROCEDURE Reset*;
  209. BEGIN
  210. error := FALSE;
  211. END Reset;
  212. PROCEDURE Error(CONST msg: ARRAY OF CHAR);
  213. BEGIN
  214. IF error THEN RETURN END;
  215. (*! use diagnostics *)
  216. error := TRUE;
  217. IF diagnostics # NIL THEN
  218. diagnostics.Error("",Diagnostics.Invalid, Diagnostics.Invalid, msg);
  219. END;
  220. END Error;
  221. PROCEDURE ErrorSS(CONST msg: ARRAY OF CHAR; id: StringPool.Index);
  222. VAR name: ARRAY 128 OF CHAR; message: ARRAY 256 OF CHAR;
  223. BEGIN
  224. IF error THEN RETURN END;
  225. (*! use diagnostics *)
  226. error := TRUE;
  227. COPY(msg, message);
  228. IF id # 0 THEN Strings.Append(message," "); StringPool.GetString(id, name); Strings.Append(message, name); END;
  229. IF diagnostics # NIL THEN
  230. diagnostics.Error("",Diagnostics.Invalid, Diagnostics.Invalid, message);
  231. END;
  232. END ErrorSS;
  233. (** syntax tree types omitted -- unused *)
  234. (** expressions *)
  235. PROCEDURE VisitSet*(x: SyntaxTree.Set);
  236. VAR s: SET; i: LONGINT; value: Value;
  237. BEGIN
  238. FOR i := 0 TO x.elements.Length()-1 DO
  239. IF GetValue(x.elements.GetExpression(i), value) THEN
  240. IF value IS Integer THEN INCL(s, value(Integer).value)
  241. ELSIF value IS Range THEN s := s + {FIRST(value(Range).value)..LAST(value(Range).value)}
  242. ELSE Error("wrong value type")
  243. END;
  244. END;
  245. END;
  246. NewSet(s)
  247. END VisitSet;
  248. PROCEDURE VisitMathArrayExpression*(x: SyntaxTree.MathArrayExpression);
  249. VAR numberElements, i: LONGINT; a: MathArrayValue;
  250. BEGIN
  251. numberElements := x.elements.Length();
  252. NEW(a, numberElements);
  253. FOR i := 0 TO numberElements-1 DO
  254. Expression(x.elements.GetExpression(i));
  255. a.SetValue(i,item.object(Value));
  256. END;
  257. item.object := a; value := TRUE;
  258. END VisitMathArrayExpression;
  259. PROCEDURE NewInt(i: LONGINT);
  260. VAR v: Integer;
  261. BEGIN
  262. NEW(v, i); item.object := v; value := TRUE
  263. END NewInt;
  264. PROCEDURE NewReal(i: LONGREAL);
  265. VAR v: Real;
  266. BEGIN
  267. NEW(v, i); item.object := v; value := TRUE
  268. END NewReal;
  269. PROCEDURE NewBool(b: BOOLEAN);
  270. VAR v: Boolean;
  271. BEGIN
  272. NEW(v, b); item.object := v; value := TRUE;
  273. END NewBool;
  274. PROCEDURE NewSet(s: SET);
  275. VAR v: Set;
  276. BEGIN
  277. NEW(v, s); item.object := v; value := TRUE;
  278. END NewSet;
  279. PROCEDURE NewString(CONST s: ARRAY OF CHAR);
  280. VAR v: String;
  281. BEGIN
  282. NEW(v, s); item.object := v; value := TRUE;
  283. END NewString;
  284. PROCEDURE NewRange(r: RANGE);
  285. VAR v: Range;
  286. BEGIN
  287. NEW(v, r ); item.object := v; value := TRUE;
  288. END NewRange;
  289. PROCEDURE NewChar(c: CHAR);
  290. VAR v: Char;
  291. BEGIN
  292. NEW(v, c); item.object := v; value := TRUE;
  293. END NewChar;
  294. PROCEDURE VisitUnaryExpression*(x: SyntaxTree.UnaryExpression);
  295. VAR value: Value; i: LONGINT; r: LONGREAL; b: BOOLEAN; operator: LONGINT;
  296. BEGIN
  297. operator := x.operator;
  298. IF ~GetValue(x, value) THEN RETURN END;
  299. IF value IS Integer THEN
  300. i := value(Integer).value;
  301. CASE operator OF
  302. Scanner.Minus: NewInt(-i)
  303. |Scanner.Plus: NewInt(i)
  304. ELSE Error("unary operator not supported")
  305. END;
  306. ELSIF value IS Real THEN
  307. r := value(Real).value;
  308. CASE operator OF
  309. Scanner.Minus: NewReal(-r)
  310. |Scanner.Plus: NewReal(r)
  311. ELSE Error("unary operator not supported")
  312. END;
  313. ELSIF value IS Boolean THEN
  314. b := value(Boolean).value;
  315. CASE operator OF
  316. Scanner.Not: NewBool(~b)
  317. ELSE Error("unary operator not supported")
  318. END;
  319. ELSIF value IS Set THEN
  320. CASE operator OF
  321. Scanner.Minus: NewSet(-value(Set).value)
  322. ELSE Error("unary operator not supported")
  323. END;
  324. ELSE
  325. Error("unary operation not supported");
  326. END;
  327. END VisitUnaryExpression;
  328. PROCEDURE VisitBinaryExpression*(x: SyntaxTree.BinaryExpression);
  329. VAR left, right: Value; operator: LONGINT; li, ri: LONGINT; lr, rr: LONGREAL; lb, rb: BOOLEAN; sl, sr: SET;
  330. BEGIN
  331. operator := x.operator;
  332. IF ~GetValue(x.left, left) OR ~GetValue(x.right, right) THEN RETURN END;
  333. IF (left IS Integer) & (right IS Integer) THEN
  334. li := left(Integer).value; ri := right(Integer).value;
  335. CASE operator OF
  336. |Scanner.Plus: NewInt(li+ri)
  337. |Scanner.Minus: NewInt(li-ri);
  338. |Scanner.Times: NewInt(li * ri);
  339. |Scanner.Div: NewInt(li DIV ri);
  340. |Scanner.Mod: NewInt(li MOD ri);
  341. |Scanner.Equal: NewBool(li = ri);
  342. |Scanner.Unequal: NewBool(li # ri)
  343. |Scanner.Less: NewBool(li < ri)
  344. |Scanner.LessEqual: NewBool(li <= ri)
  345. |Scanner.Greater: NewBool(li > ri)
  346. |Scanner.GreaterEqual: NewBool(li >= ri)
  347. |Scanner.Slash: NewReal(li/ri)
  348. ELSE Error("binary operator not supported")
  349. END;
  350. ELSIF ((left IS Integer) OR (left IS Real)) & ((right IS Integer) OR (right IS Real)) THEN
  351. IF left IS Integer THEN lr := left(Integer).value
  352. ELSE lr := left(Real).value
  353. END;
  354. IF right IS Integer THEN rr := right(Integer).value;
  355. ELSE rr := right(Real).value
  356. END;
  357. CASE operator OF
  358. |Scanner.Plus: NewReal(lr+rr)
  359. |Scanner.Minus: NewReal(lr-rr);
  360. |Scanner.Times: NewReal(lr * rr);
  361. |Scanner.Slash: NewReal(lr / rr);
  362. |Scanner.Equal: NewBool(lr = rr);
  363. |Scanner.Unequal: NewBool(lr # rr)
  364. |Scanner.Less: NewBool(lr < rr)
  365. |Scanner.LessEqual: NewBool(lr <= rr)
  366. |Scanner.Greater: NewBool(lr > rr)
  367. |Scanner.GreaterEqual: NewBool(lr >= rr)
  368. ELSE Error("binary operator not supported")
  369. END;
  370. ELSIF (left IS Boolean) & (right IS Boolean) THEN
  371. lb := left(Boolean).value; rb := right(Boolean).value;
  372. CASE operator OF
  373. |Scanner.Or: NewBool(lb OR rb);
  374. |Scanner.And: NewBool(lb & rb);
  375. |Scanner.Equal: NewBool(lb = rb)
  376. |Scanner.Unequal: NewBool(lb # rb)
  377. ELSE Error("operator not supported")
  378. END;
  379. ELSIF (left IS String) & (right IS String) THEN
  380. CASE operator OF
  381. |Scanner.Equal: NewBool(left(String).value^ = right(String).value^);
  382. |Scanner.Unequal: NewBool(left(String).value^ = right(String).value^);
  383. |Scanner.Less: NewBool(left(String).value^ < right(String).value^);
  384. |Scanner.LessEqual: NewBool(left(String).value^ <= right(String).value^);
  385. |Scanner.Greater: NewBool(left(String).value^ > right(String).value^);
  386. |Scanner.GreaterEqual: NewBool(left(String).value^ >= right(String).value^);
  387. ELSE Error("binary operator not supported")
  388. END
  389. ELSIF (left IS Set) & (right IS Set) THEN
  390. sl := left(Set).value; sr := right(Set).value;
  391. CASE operator OF
  392. |Scanner.Plus: NewSet(sl+sr)
  393. |Scanner.Minus: NewSet(sl-sr);
  394. |Scanner.Times: NewSet(sl * sr);
  395. |Scanner.Slash: NewSet(sl / sr);
  396. |Scanner.Equal: NewBool(sl = sr);
  397. |Scanner.Unequal: NewBool(sl # sr)
  398. |Scanner.Less: NewBool(sl < sr)
  399. |Scanner.LessEqual: NewBool(sl <= sr)
  400. |Scanner.Greater: NewBool(sl > sr)
  401. |Scanner.GreaterEqual: NewBool(sl >= sr)
  402. ELSE Error("binary operator not supported")
  403. END;
  404. ELSIF (left IS Integer) & (right IS Set) THEN
  405. CASE operator OF
  406. Scanner.In: NewBool(left(Integer).value IN right(Set).value)
  407. ELSE Error("binary operator not supported")
  408. END;
  409. ELSE
  410. Error("binary operation not supported");
  411. Printout.Info("binary operation", x);
  412. END;
  413. END VisitBinaryExpression;
  414. PROCEDURE VisitRangeExpression*(x: SyntaxTree.RangeExpression);
  415. VAR first,last,step: LONGINT; value: Integer;
  416. BEGIN
  417. IF ~ExpectInteger(x.first, value) THEN RETURN END;
  418. first := value.value;
  419. IF ~ExpectInteger(x.last, value) THEN RETURN END;
  420. last := value.value;
  421. IF (x.step # NIL) & ExpectInteger(x.step, value) THEN
  422. step := value.value;
  423. ELSE
  424. step := 1
  425. END;
  426. NewRange(first ..last BY step);
  427. END VisitRangeExpression;
  428. PROCEDURE VisitTensorRangeExpression*(x: SyntaxTree.TensorRangeExpression);
  429. BEGIN HALT(100) (* abstract *) END VisitTensorRangeExpression;
  430. PROCEDURE VisitConversion*(x: SyntaxTree.Conversion);
  431. BEGIN HALT(100) (* abstract *) END VisitConversion;
  432. (** designators (expressions) *)
  433. PROCEDURE VisitDesignator*(x: SyntaxTree.Designator);
  434. BEGIN HALT(100) (* abstract *) END VisitDesignator;
  435. (*
  436. PROCEDURE FindInScope(scope: Scope; symbol: StringPool.Index): Value;
  437. VAR item: Value;
  438. BEGIN
  439. REPEAT
  440. item := scope.Find1(symbol);
  441. IF (item = NIL) THEN
  442. scope := scope.outer
  443. ELSE
  444. scope := NIL
  445. END;
  446. UNTIL (scope = NIL);
  447. RETURN item
  448. END FindInScope;
  449. *)
  450. PROCEDURE FindType(CONST types: POINTER TO ARRAY OF Modules.TypeDesc; CONST name: ARRAY OF CHAR): Modules.TypeDesc;
  451. VAR i: LONGINT;
  452. BEGIN
  453. IF types = NIL THEN RETURN NIL END;
  454. FOR i := 0 TO LEN(types)-1 DO
  455. IF types[i].name = name THEN
  456. RETURN types[i];
  457. END;
  458. END;
  459. RETURN NIL;
  460. END FindType;
  461. PROCEDURE FindProc(CONST types: POINTER TO ARRAY OF Modules.ProcedureEntry; CONST name: ARRAY OF CHAR; VAR num: LONGINT): BOOLEAN;
  462. BEGIN
  463. IF types = NIL THEN RETURN FALSE END;
  464. FOR num := 0 TO LEN(types)-1 DO
  465. IF types[num].name^ = name THEN
  466. RETURN TRUE;
  467. END;
  468. END;
  469. RETURN FALSE;
  470. END FindProc;
  471. PROCEDURE FindField(CONST types: POINTER TO ARRAY OF Modules.FieldEntry; CONST name: ARRAY OF CHAR; VAR num: LONGINT): BOOLEAN;
  472. BEGIN
  473. IF types = NIL THEN RETURN FALSE END;
  474. FOR num := 0 TO LEN(types)-1 DO
  475. IF types[num].name^ = name THEN
  476. RETURN TRUE;
  477. END;
  478. END;
  479. RETURN FALSE;
  480. END FindField;
  481. PROCEDURE VisitIdentifierDesignator*(x: SyntaxTree.IdentifierDesignator);
  482. VAR moduleName: Modules.Name; msg: ARRAY 128 OF CHAR; res: LONGINT;
  483. BEGIN
  484. ASSERT(x.left = NIL);
  485. item.name := x.identifier;
  486. (*
  487. item.object := FindInScope(item.scope, item.name);
  488. *)
  489. item.object := scope.FindObject1(item.name, -1, item.in);
  490. IF item.object = NIL THEN
  491. StringPool.GetString(item.name, moduleName);
  492. item.object :=InterpreterSymbols.GetModule(moduleName);
  493. END;
  494. END VisitIdentifierDesignator;
  495. PROCEDURE VisitSelectorDesignator*(x: SyntaxTree.SelectorDesignator);
  496. VAR traverse: BOOLEAN; name: ARRAY 128 OF CHAR; num: LONGINT;
  497. BEGIN
  498. Expression(x.left); traverse := FALSE;
  499. IF error THEN RETURN END;
  500. item.name := x.identifier;
  501. IF (item.object # NIL) THEN
  502. IF item.object IS Result THEN
  503. StringPool.GetString(item.name, name);
  504. item.object := item.object(Result).Find(name);
  505. ELSE
  506. item.in := item.object;
  507. item.object := InterpreterSymbols.FindInObject1(item.object, x.identifier,-1);
  508. END;
  509. ELSE
  510. ErrorSS("invalid selector",item.name);
  511. item.in := NIL;
  512. END;
  513. END VisitSelectorDesignator;
  514. PROCEDURE PushParameters(e: SyntaxTree.ExpressionList);
  515. VAR i: LONGINT; value: Value;
  516. BEGIN
  517. FOR i := 0 TO e.Length()-1 DO
  518. IF GetValue(e.GetExpression(i), value) THEN
  519. callStack.PushL(value(Integer).value);
  520. END;
  521. END;
  522. END PushParameters;
  523. PROCEDURE VisitParameterDesignator*(x: SyntaxTree.ParameterDesignator);
  524. VAR e: SyntaxTree.Expression; proc: InterpreterSymbols.ProcedureResult; i: LONGINT;
  525. adr: ADDRESS; adrValue: Value; any: InterpreterSymbols.AnyValue;
  526. BEGIN
  527. e := x.left;
  528. Expression(e);
  529. IF (item.object # NIL) & (item.object IS InterpreterSymbols.ProcedureResult) THEN
  530. proc := item.object(InterpreterSymbols.ProcedureResult);
  531. (* self pointer *)
  532. proc.Pars();
  533. IF ~(proc.caller IS InterpreterSymbols.ModuleResult) THEN
  534. adrValue := proc.caller.Evaluate();
  535. ASSERT(adrValue.GetAddress(adr));
  536. proc.PushAddress(adr);
  537. END;
  538. (* result pointer *)
  539. IF proc.ReturnsPointer() THEN
  540. NEW(any,NIL);
  541. proc.PushAddress(any.Address());
  542. END;
  543. FOR i := 0 TO x.parameters.Length()-1 DO
  544. e := x.parameters.GetExpression(i);
  545. IF ~proc.Push(Evaluate(e)) THEN Error("wrong parameter"); RETURN END;
  546. END;
  547. IF ~proc.Check() THEN Error("non-matching parameter number"); RETURN END;
  548. item.object := proc.Evaluate();
  549. IF any # NIL THEN item.object := any END;
  550. ELSE
  551. Error("no procedure")
  552. END;
  553. END VisitParameterDesignator;
  554. PROCEDURE VisitArrowDesignator*(x: SyntaxTree.ArrowDesignator);
  555. BEGIN HALT(100) (* abstract *) END VisitArrowDesignator;
  556. PROCEDURE VisitBracketDesignator*(x: SyntaxTree.BracketDesignator);
  557. VAR array: MathArrayValue; i: LONGINT; element: Value; index: Integer; obj: PersistentObjects.Object;
  558. leftValue, rightValue: Value; filter: InterpreterSymbols.ObjectFilter; expression: SyntaxTree.Expression;
  559. attribute, value: ARRAY 128 OF CHAR;
  560. BEGIN
  561. Expression(x.left);
  562. IF (item.object # NIL) & (item.object IS MathArrayValue) THEN
  563. element := item.object(MathArrayValue);
  564. FOR i := 0 TO x.parameters.Length()-1 DO
  565. array := element(MathArrayValue);
  566. IF GetInteger(x.parameters.GetExpression(i), index) THEN
  567. element := array.GetValue(index.value);
  568. END;
  569. END;
  570. item.object := element;
  571. ELSIF (item.object # NIL) THEN
  572. NEW(filter); obj := item.object;
  573. FOR i := 0 TO x.parameters.Length()-1 DO
  574. expression := x.parameters.GetExpression(i);
  575. IF (expression IS SyntaxTree.BinaryExpression) & (expression(SyntaxTree.BinaryExpression).operator = Scanner.Equal) THEN
  576. IF (expression(SyntaxTree.BinaryExpression).left IS SyntaxTree.IdentifierDesignator) &
  577. GetValue(expression(SyntaxTree.BinaryExpression).right, rightValue) THEN
  578. StringPool.GetString(
  579. expression(SyntaxTree.BinaryExpression).left(SyntaxTree.IdentifierDesignator).identifier, attribute);
  580. rightValue(Value).GetString(value);
  581. obj := filter.Filter(obj, attribute, value)
  582. ELSE HALT(200)
  583. END;
  584. ELSE
  585. IF GetValue(expression, leftValue) THEN
  586. IF leftValue IS String THEN
  587. leftValue(Value).GetString(value);
  588. obj := filter.Filter(obj, "name", value);
  589. ELSIF leftValue IS Integer THEN
  590. IF obj IS PersistentObjects.ObjectList THEN
  591. item.object := obj(PersistentObjects.ObjectList).GetElement(leftValue(Integer).value)
  592. ELSIF obj IS Container THEN
  593. item.object := obj(Container).GetItem(leftValue(Integer).value)
  594. ELSE Error("cannot be indexed")
  595. END;
  596. END;
  597. END;
  598. END;
  599. END;
  600. IF obj(Container).symbols.Length() > 0 THEN
  601. item.object := obj(Container).GetItem(0);
  602. ELSE
  603. Error("no such symbol")
  604. END;
  605. END;
  606. END VisitBracketDesignator;
  607. PROCEDURE VisitSymbolDesignator*(x: SyntaxTree.SymbolDesignator);
  608. BEGIN HALT(100) (* abstract *) END VisitSymbolDesignator;
  609. PROCEDURE VisitIndexDesignator*(x: SyntaxTree.IndexDesignator);
  610. BEGIN HALT(100) (* abstract *) END VisitIndexDesignator;
  611. PROCEDURE VisitProcedureCallDesignator*(x: SyntaxTree.ProcedureCallDesignator);
  612. BEGIN HALT(100)
  613. END VisitProcedureCallDesignator;
  614. PROCEDURE VisitBuiltinCallDesignator*(x: SyntaxTree.BuiltinCallDesignator);
  615. BEGIN HALT(100)
  616. END VisitBuiltinCallDesignator;
  617. PROCEDURE VisitTypeGuardDesignator*(x: SyntaxTree.TypeGuardDesignator);
  618. BEGIN HALT(100) (* abstract *) END VisitTypeGuardDesignator;
  619. PROCEDURE VisitDereferenceDesignator*(x: SyntaxTree.DereferenceDesignator);
  620. BEGIN HALT(100) (* abstract *) END VisitDereferenceDesignator;
  621. PROCEDURE VisitSupercallDesignator*(x: SyntaxTree.SupercallDesignator);
  622. BEGIN HALT(100) (* abstract *) END VisitSupercallDesignator;
  623. PROCEDURE VisitSelfDesignator*(x: SyntaxTree.SelfDesignator);
  624. BEGIN HALT(100) (* abstract *) END VisitSelfDesignator;
  625. PROCEDURE VisitResultDesignator*(x: SyntaxTree.ResultDesignator);
  626. BEGIN HALT(100) (* abstract *) END VisitResultDesignator;
  627. (** values *)
  628. PROCEDURE VisitValue*(x: SyntaxTree.Value);
  629. BEGIN HALT(100) (* abstract *) END VisitValue;
  630. PROCEDURE VisitBooleanValue*(x: SyntaxTree.BooleanValue);
  631. BEGIN
  632. NewBool(x.value)
  633. END VisitBooleanValue;
  634. PROCEDURE VisitIntegerValue*(x: SyntaxTree.IntegerValue);
  635. BEGIN
  636. NewInt(x.value)
  637. END VisitIntegerValue;
  638. PROCEDURE VisitCharacterValue*(x: SyntaxTree.CharacterValue);
  639. BEGIN
  640. NewChar(x.value);
  641. END VisitCharacterValue;
  642. PROCEDURE VisitSetValue*(x: SyntaxTree.SetValue);
  643. BEGIN
  644. NewSet(x.value)
  645. END VisitSetValue;
  646. PROCEDURE VisitMathArrayValue*(x: SyntaxTree.MathArrayValue);
  647. BEGIN HALT(100) (* abstract *) END VisitMathArrayValue;
  648. PROCEDURE VisitRealValue*(x: SyntaxTree.RealValue);
  649. BEGIN
  650. NewReal(x.value)
  651. END VisitRealValue;
  652. PROCEDURE VisitComplexValue*(x: SyntaxTree.ComplexValue);
  653. BEGIN HALT(100) (* abstract *) END VisitComplexValue;
  654. PROCEDURE VisitStringValue*(x: SyntaxTree.StringValue);
  655. BEGIN
  656. NewString(x.value^);
  657. END VisitStringValue;
  658. PROCEDURE VisitNilValue*(x: SyntaxTree.NilValue);
  659. BEGIN HALT(100) (* abstract *) END VisitNilValue;
  660. PROCEDURE VisitEnumerationValue*(x: SyntaxTree.EnumerationValue);
  661. BEGIN HALT(100) (* abstract *) END VisitEnumerationValue;
  662. (** symbols *)
  663. PROCEDURE VisitSymbol*(x: SyntaxTree.Symbol);
  664. BEGIN HALT(100) (* abstract *) END VisitSymbol;
  665. PROCEDURE VisitTypeDeclaration*(x: SyntaxTree.TypeDeclaration);
  666. BEGIN HALT(100) (* abstract *) END VisitTypeDeclaration;
  667. PROCEDURE VisitConstant*(x: SyntaxTree.Constant);
  668. BEGIN HALT(100) (* abstract *) END VisitConstant;
  669. PROCEDURE VisitVariable*(x: SyntaxTree.Variable);
  670. BEGIN HALT(100) (* abstract *) END VisitVariable;
  671. PROCEDURE VisitParameter*(x: SyntaxTree.Parameter);
  672. BEGIN HALT(100) (* abstract *) END VisitParameter;
  673. PROCEDURE VisitProcedure*(x: SyntaxTree.Procedure);
  674. BEGIN HALT(100) (* abstract *) END VisitProcedure;
  675. PROCEDURE VisitBuiltin*(x: SyntaxTree.Builtin);
  676. BEGIN HALT(100) (* abstract *) END VisitBuiltin;
  677. PROCEDURE VisitOperator*(x: SyntaxTree.Operator);
  678. BEGIN HALT(100) (* abstract *) END VisitOperator;
  679. PROCEDURE VisitImport*(x: SyntaxTree.Import);
  680. BEGIN HALT(100) (* abstract *) END VisitImport;
  681. (* copy src to value string replacing substrings that are embraced between refSymbols by expression value *)
  682. PROCEDURE TranslateString*(cmd: CHAR; CONST str: ARRAY OF CHAR; VAR dest: Strings.String): BOOLEAN;
  683. CONST
  684. LeftDelimiter = '{'; RightDelimiter = '}';
  685. VAR
  686. position : LONGINT; ch: CHAR;
  687. destination, expMaker: Scanner.StringMaker; destinationWriter, expressionWriter: Streams.Writer; scanner: Scanner.Scanner; parser: Parser;
  688. expression: SyntaxTree.Expression; value: Value; len: LONGINT;
  689. comment: LONGINT;
  690. PROCEDURE Next(VAR ch: CHAR);
  691. BEGIN
  692. IF position = LEN(str) THEN ch := 0X ELSE ch := str[position]; INC(position) END;
  693. END Next;
  694. PROCEDURE EvaluateExpression();
  695. VAR str: Strings.String; reader: Streams.Reader; done: BOOLEAN;
  696. BEGIN
  697. reader := expMaker.GetReader();
  698. NEW(scanner, "", reader, 0, NIL);
  699. NEW(parser, scanner, NIL);
  700. REPEAT
  701. error := FALSE;
  702. expression := parser.Expression();
  703. done := GetValue(expression, value);
  704. UNTIL done OR ~parser.Optional(Scanner.Colon);
  705. IF done THEN value(Value).WriteValue(destinationWriter);
  706. ELSE
  707. destinationWriter.String("#COULD NOT INTERPRETE#");
  708. error := TRUE;
  709. END;
  710. END EvaluateExpression;
  711. BEGIN
  712. error := FALSE;
  713. position := 0;
  714. Next(ch);
  715. NEW(destination,256); destinationWriter := destination.GetWriter();
  716. NEW(expMaker, 256); expressionWriter := expMaker.GetWriter();
  717. comment := 0;
  718. WHILE (ch # 0X) DO
  719. (* copy string literally *)
  720. IF (comment = 0) & (ch = cmd) THEN
  721. Next(ch);
  722. IF ch = LeftDelimiter THEN
  723. Next(ch);
  724. REPEAT
  725. WHILE (ch # 0X) & (ch # RightDelimiter) DO expressionWriter.Char(ch); Next(ch) END;
  726. IF ch = RightDelimiter THEN
  727. Next(ch); IF (ch # cmd) THEN expressionWriter.Char(RightDelimiter) END;
  728. END;
  729. UNTIL (ch=0X) OR (ch = cmd);
  730. IF ch # 0X THEN Next(ch) END;
  731. expressionWriter.Update;
  732. EvaluateExpression();
  733. expMaker.Clear;
  734. ELSE
  735. destinationWriter.Char(cmd);
  736. END;
  737. (* remove comments *)
  738. ELSIF ch = "(" THEN
  739. Next(ch);
  740. IF ch = "*" THEN
  741. INC(comment); Next(ch);
  742. ELSIF comment = 0 THEN
  743. destinationWriter.Char("(");
  744. END;
  745. ELSIF ch="*" THEN
  746. Next(ch);
  747. IF ch = ")" THEN
  748. DEC(comment);
  749. IF comment < 0 THEN comment := 0 END; Next(ch);
  750. ELSIF comment = 0 THEN
  751. destinationWriter.Char("*")
  752. END;
  753. ELSE
  754. IF comment = 0 THEN destinationWriter.Char(ch) END;
  755. Next(ch);
  756. END;
  757. END;
  758. destinationWriter.Update;
  759. dest := destination.GetString(len);
  760. RETURN ~error
  761. END TranslateString;
  762. PROCEDURE VisitCommandStatement(x: CommandStatement);
  763. VAR t: Strings.String; res: LONGINT; msg: ARRAY 128 OF CHAR; i: LONGINT; array: Strings.StringArray; pos: LONGINT;
  764. command: ARRAY 256 OF CHAR; context: Commands.Context;
  765. PROCEDURE CreateContext(paramString : Strings.String; pos: LONGINT) : Commands.Context;
  766. VAR c : Commands.Context; arg : Streams.StringReader; dummy : ARRAY 1 OF CHAR; len: LONGINT;
  767. BEGIN
  768. IF (paramString = NIL) THEN
  769. NEW(arg, 1); dummy := ""; arg.SetRaw(dummy, 0, 1);
  770. ELSE
  771. len := Strings.Length(paramString^)+1 (*+1 to include 0X *);
  772. NEW(arg, len-pos); arg.SetRaw(paramString^, pos, len-pos);
  773. END;
  774. NEW(c, context.in, arg, context.out, context.error, context.caller);
  775. RETURN c;
  776. END CreateContext;
  777. PROCEDURE IsDelimiter(ch : CHAR) : BOOLEAN;
  778. CONST CR = 0DX; LF = 0AX; TAB = 9X;
  779. BEGIN
  780. RETURN (ch = " ") OR (ch = CR) OR (ch = LF) OR (ch = TAB) OR (ch = ";") OR (ch = 0X);
  781. END IsDelimiter;
  782. BEGIN
  783. IF SELF.context = NIL THEN
  784. context := Commands.GetContext();
  785. ELSE
  786. context := SELF.context
  787. END;
  788. IF TranslateString("?", x.command^, t) THEN END;
  789. array := Strings.Split(t^, "~");
  790. FOR i := 0 TO LEN(array)-1 DO
  791. Strings.TrimWS(array[i]^);
  792. IF (array[i]^ # "") THEN
  793. (* extract command *)
  794. pos := 0;
  795. WHILE ~IsDelimiter(array[i][pos]) DO command[pos] := array[i][pos]; INC(pos); END;
  796. command[pos] := 0X;
  797. IF pos # 0 THEN
  798. context := CreateContext(array[i], pos);
  799. Commands.Activate(command, context, {Commands.Wait, Commands.InheritContext}, res, msg);
  800. IF res # 0 THEN
  801. context.out.String("Interpreter: "); context.error.String(command); context.error.String(" failed"); context.error.Ln
  802. END;
  803. END;
  804. END;
  805. END;
  806. IF res # 0 THEN Error(msg) END;
  807. END VisitCommandStatement;
  808. (** statements *)
  809. PROCEDURE VisitStatement*(x: SyntaxTree.Statement);
  810. BEGIN
  811. IF x IS CommandStatement THEN
  812. VisitCommandStatement(x(CommandStatement));
  813. ELSE HALT(100)
  814. END;
  815. END VisitStatement;
  816. PROCEDURE VisitProcedureCallStatement*(x: SyntaxTree.ProcedureCallStatement);
  817. BEGIN x.call.Accept(SELF) END VisitProcedureCallStatement;
  818. PROCEDURE LoadValue;
  819. BEGIN
  820. IF (item.object # NIL) & (item.object IS Result) THEN
  821. item.object := item.object(Result).Evaluate();
  822. ELSE
  823. ErrorSS("could not load value", item.name);
  824. END;
  825. END LoadValue;
  826. PROCEDURE GetValue*(x: SyntaxTree.Expression; VAR w: Value): BOOLEAN;
  827. BEGIN
  828. IF error THEN RETURN FALSE END;
  829. Expression(x);
  830. LoadValue();
  831. IF item.object # NIL THEN
  832. w := item.object(Value);
  833. END;
  834. RETURN ~error
  835. END GetValue;
  836. PROCEDURE Evaluate(x: SyntaxTree.Expression): Value;
  837. VAR w: Value;
  838. BEGIN
  839. IF GetValue(x, w) THEN RETURN w ELSE RETURN NIL END;
  840. END Evaluate;
  841. PROCEDURE GetInteger(x: SyntaxTree.Expression; VAR i: Integer): BOOLEAN;
  842. VAR v: Value;
  843. BEGIN
  844. IF GetValue(x, v) & (v IS Integer) THEN i := v(Integer); RETURN TRUE ELSE RETURN FALSE END;
  845. END GetInteger;
  846. PROCEDURE ExpectInteger(x: SyntaxTree.Expression; VAR i: Integer): BOOLEAN;
  847. BEGIN IF ~GetInteger(x, i) THEN Error("invalid value - must be integer"); RETURN FALSE ELSE RETURN TRUE END;
  848. END ExpectInteger;
  849. PROCEDURE GetBoolean(x: SyntaxTree.Expression; VAR i: Boolean): BOOLEAN;
  850. VAR v: Value;
  851. BEGIN
  852. IF GetValue(x, v) & (v IS Boolean) THEN i := v(Boolean); RETURN TRUE ELSE RETURN FALSE END;
  853. END GetBoolean;
  854. PROCEDURE ExpectBoolean(x: SyntaxTree.Expression; VAR b: Boolean): BOOLEAN;
  855. BEGIN IF ~GetBoolean(x, b) THEN Error("invalid value - must be boolean"); RETURN FALSE ELSE RETURN TRUE END;
  856. END ExpectBoolean;
  857. PROCEDURE PutValue(x: SyntaxTree.Designator; v: Value);
  858. BEGIN
  859. x.Accept(SELF);
  860. IF (item.object # NIL) & item.object(Result).SetV(v) THEN
  861. ELSIF (item.in # NIL) & (item.name # 0) & (item.in IS Container) THEN
  862. item.in(Container).Enter1(v, item.name);
  863. END;
  864. END PutValue;
  865. PROCEDURE VisitAssignment*(x: SyntaxTree.Assignment);
  866. VAR value: Value;
  867. BEGIN
  868. IF GetValue(x.right, value) THEN
  869. PutValue(x.left, value);
  870. END;
  871. END VisitAssignment;
  872. PROCEDURE IfPart(ifPart: SyntaxTree.IfPart): BOOLEAN;
  873. VAR value: Boolean;
  874. BEGIN
  875. IF ExpectBoolean(ifPart.condition,value) THEN
  876. IF value(Boolean).value THEN
  877. StatementSequence(ifPart.statements);
  878. RETURN TRUE
  879. END;
  880. END;
  881. RETURN FALSE
  882. END IfPart;
  883. PROCEDURE VisitIfStatement*(x: SyntaxTree.IfStatement);
  884. VAR i: LONGINT; elsif: SyntaxTree.IfPart;
  885. BEGIN
  886. IF IfPart(x.ifPart) THEN RETURN END;
  887. FOR i := 0 TO x.ElsifParts()-1 DO
  888. elsif := x.GetElsifPart(i);
  889. IF IfPart(elsif) THEN RETURN END;
  890. END;
  891. IF x.elsePart # NIL THEN
  892. StatementSequence(x.elsePart)
  893. END;
  894. END VisitIfStatement;
  895. PROCEDURE VisitWithStatement*(x: SyntaxTree.WithStatement);
  896. BEGIN HALT(100) (* abstract *) END VisitWithStatement;
  897. PROCEDURE CasePart(x: SyntaxTree.CasePart; b: SyntaxTree.BinaryExpression): BOOLEAN;
  898. VAR i: LONGINT; value: Value;
  899. BEGIN
  900. FOR i := 0 TO x.elements.Length()-1 DO
  901. b.SetRight(x.elements.GetExpression(i));
  902. IF GetValue(b, value) & (value IS Boolean) THEN
  903. IF value(Boolean).value THEN StatementSequence(x.statements); RETURN TRUE END;
  904. ELSE Error("invalid non-boolean value")
  905. END
  906. END;
  907. RETURN FALSE
  908. END CasePart;
  909. PROCEDURE VisitCaseStatement*(x: SyntaxTree.CaseStatement);
  910. VAR binary: SyntaxTree.BinaryExpression; i: LONGINT;
  911. BEGIN
  912. binary := SyntaxTree.NewBinaryExpression(0, x.variable, x.variable, Scanner.Equal);
  913. FOR i := 0 TO x.CaseParts()-1 DO
  914. IF CasePart(x.GetCasePart(i), binary) THEN RETURN END;
  915. END;
  916. IF x.elsePart # NIL THEN
  917. StatementSequence(x.elsePart)
  918. END;
  919. END VisitCaseStatement;
  920. PROCEDURE VisitWhileStatement*(x: SyntaxTree.WhileStatement);
  921. VAR value: Boolean;
  922. BEGIN
  923. WHILE ExpectBoolean(x.condition, value) & value.value DO
  924. StatementSequence(x.statements);
  925. END;
  926. END VisitWhileStatement;
  927. PROCEDURE VisitRepeatStatement*(x: SyntaxTree.RepeatStatement);
  928. VAR value: Boolean;
  929. BEGIN
  930. REPEAT
  931. StatementSequence(x.statements);
  932. UNTIL ~ExpectBoolean(x.condition, value) OR value.value
  933. END VisitRepeatStatement;
  934. PROCEDURE VisitForStatement*(x: SyntaxTree.ForStatement);
  935. VAR fromV, toV, byV: Integer; from, to, by,i: LONGINT; int: Integer;
  936. BEGIN
  937. IF ExpectInteger(x.from, fromV) & ExpectInteger(x.to, toV) THEN
  938. from := fromV.value;
  939. to := toV.value;
  940. Expression(x.variable);
  941. NEW(int, from);
  942. PutValue(x.variable, int);
  943. i := from;
  944. WHILE i <= to DO
  945. int.value := i;
  946. StatementSequence(x.statements);
  947. INC(i);
  948. END;
  949. END;
  950. END VisitForStatement;
  951. PROCEDURE VisitLoopStatement*(x: SyntaxTree.LoopStatement);
  952. VAR prevExit: BOOLEAN;
  953. BEGIN
  954. prevExit := exit;
  955. exit := FALSE;
  956. LOOP
  957. StatementSequence(x.statements);
  958. IF exit THEN EXIT END;
  959. END;
  960. exit := prevExit
  961. END VisitLoopStatement;
  962. PROCEDURE VisitExitStatement*(x: SyntaxTree.ExitStatement);
  963. BEGIN
  964. exit := TRUE
  965. END VisitExitStatement;
  966. PROCEDURE VisitReturnStatement*(x: SyntaxTree.ReturnStatement);
  967. BEGIN HALT(100) (* abstract *) END VisitReturnStatement;
  968. PROCEDURE VisitAwaitStatement*(x: SyntaxTree.AwaitStatement);
  969. BEGIN HALT(100) (* abstract *) END VisitAwaitStatement;
  970. PROCEDURE VisitStatementBlock*(x: SyntaxTree.StatementBlock);
  971. BEGIN
  972. StatementSequence(x.statements)
  973. END VisitStatementBlock;
  974. PROCEDURE VisitCode*(x: SyntaxTree.Code);
  975. BEGIN HALT(100) (* abstract *) END VisitCode;
  976. PROCEDURE Expression(x: SyntaxTree.Expression);
  977. BEGIN
  978. value := FALSE;
  979. x.Accept(SELF);
  980. END Expression;
  981. PROCEDURE Statement(x: SyntaxTree.Statement);
  982. BEGIN
  983. item.object := NIL;
  984. x.Accept(SELF);
  985. END Statement;
  986. PROCEDURE StatementSequence*(x: SyntaxTree.StatementSequence);
  987. VAR i: LONGINT;
  988. BEGIN
  989. FOR i := 0 TO x.Length()-1 DO
  990. Statement(x.GetStatement(i));
  991. END;
  992. END StatementSequence;
  993. END Interpreter;
  994. Resolver*= OBJECT
  995. VAR
  996. interpreter: Interpreter;
  997. content: PersistentObjects.Content;
  998. resolved: Basic.HashTable;
  999. current: Scope;
  1000. changed: BOOLEAN;
  1001. PROCEDURE & InitResolver*;
  1002. BEGIN
  1003. NEW(content); NEW(resolved,64); NEW(interpreter, NIL, NIL, NIL);
  1004. END InitResolver;
  1005. PROCEDURE Traverse(CONST name: ARRAY OF CHAR; array: BOOLEAN);
  1006. VAR index: LONGINT; success: BOOLEAN;
  1007. BEGIN
  1008. IF array THEN index := 0 ELSE index := -1 END;
  1009. REPEAT
  1010. success := FALSE;
  1011. content.success := FALSE;
  1012. current.object.Get(name, index, content);
  1013. IF content.success & (content.class = PersistentObjects.Class.Object) THEN
  1014. success := content.object # NIL;
  1015. IF content.object # NIL THEN
  1016. DoResolve(current.Enter(content.object)); (* content object can be overwritten as sideeffect! *)
  1017. END;
  1018. END;
  1019. INC(index);
  1020. UNTIL ~array OR ~success
  1021. END Traverse;
  1022. PROCEDURE DoResolve*(scope: Scope);
  1023. VAR translation: PersistentObjects.Interpretation; prev: Scope; str: Strings.String;
  1024. BEGIN
  1025. IF (scope.object # NIL) & ~resolved.Has(scope.object) THEN
  1026. prev := current;
  1027. current := scope;
  1028. resolved.Put(scope.object, SELF);
  1029. interpreter.Init(scope, NIL, NIL);
  1030. translation := scope.object.firstTranslation;
  1031. WHILE translation # NIL DO
  1032. IF EnableTrace THEN D.String("resolve "); D.String(translation.name^); D.String(":"); D.String(translation.str^); END;
  1033. IF interpreter.TranslateString("?", translation.str^, str) THEN
  1034. IF EnableTrace THEN D.String(":"); D.Str(str^); END;
  1035. scope.object.Get(translation.name^, -1, content);
  1036. IF ~content.Equals(str^) THEN
  1037. changed := TRUE;
  1038. content.SetAsString(str^);
  1039. END;
  1040. scope.object.Set(translation.name^, -1, content);
  1041. ELSE
  1042. IF EnableTrace THEN D.String(":could not resolve"); END;
  1043. END;
  1044. IF EnableTrace THEN D.Ln; END;
  1045. translation := translation.next
  1046. END;
  1047. scope.object.Enumerate(Traverse);
  1048. current := prev;
  1049. END;
  1050. END DoResolve;
  1051. PROCEDURE Resolve*(scope: Scope);
  1052. BEGIN
  1053. REPEAT
  1054. changed := FALSE;
  1055. resolved.Clear();
  1056. DoResolve(scope);
  1057. UNTIL ~changed;
  1058. END Resolve;
  1059. END Resolver;
  1060. VAR global-: Scope;
  1061. PROCEDURE Statements*(context: Commands.Context);
  1062. VAR scanner: Scanner.Scanner; parser: Parser; diagnostics: Diagnostics.StreamDiagnostics;
  1063. seq: SyntaxTree.StatementSequence; interpreter: Interpreter;
  1064. BEGIN
  1065. NEW(diagnostics, context.error);
  1066. scanner := Scanner.NewScanner("",context.arg,0,diagnostics);
  1067. NEW(parser, scanner, diagnostics);
  1068. seq := parser.StatementSequence(NIL);
  1069. NEW(interpreter, global, diagnostics,context); interpreter.StatementSequence(seq);
  1070. END Statements;
  1071. PROCEDURE Expression*(context: Commands.Context);
  1072. VAR scanner: Scanner.Scanner; parser: Parser; diagnostics: Diagnostics.StreamDiagnostics;
  1073. interpreter: Interpreter; value: Value; expression: SyntaxTree.Expression;
  1074. BEGIN
  1075. NEW(diagnostics, context.error);
  1076. scanner := Scanner.NewScanner("",context.arg,0,diagnostics);
  1077. NEW(parser, scanner, diagnostics);
  1078. expression := parser.Expression();
  1079. NEW(interpreter, global, diagnostics,NIL);
  1080. IF interpreter.GetValue(expression, value) THEN
  1081. value(Value).WriteValue(context.out); context.out.Ln
  1082. ELSE
  1083. context.error.String("could not evaluate expression"); context.error.Ln
  1084. END;
  1085. END Expression;
  1086. PROCEDURE TranslateString*(context: Commands.Context);
  1087. VAR dest: Strings.String; testString: ARRAY 256 OF CHAR; interpreter: Interpreter; streamDiagnostics: Diagnostics.StreamDiagnostics;
  1088. BEGIN
  1089. NEW(streamDiagnostics, context.error);
  1090. NEW(interpreter, global, streamDiagnostics,NIL);
  1091. WHILE context.arg.GetString(testString) DO
  1092. IF interpreter.TranslateString("?", testString, dest) THEN
  1093. context.out.String("RESULT: ");
  1094. context.out.String(dest^);
  1095. context.out.Ln;
  1096. ELSE
  1097. context.error.String("could not translate: ");
  1098. context.error.String(dest^);
  1099. context.error.Ln;
  1100. END;
  1101. END;
  1102. END TranslateString;
  1103. PROCEDURE InitGlobalScope;
  1104. VAR container: Container;
  1105. BEGIN
  1106. NEW(container);
  1107. NEW(global, NIL, container);
  1108. END InitGlobalScope;
  1109. BEGIN
  1110. InitGlobalScope;
  1111. END FoxInterpreter.
  1112. SystemTools.Free FoxInterpreter FoxInterpreterSymbols ~
  1113. FoxInterpreter.Expression
  1114. Test.c.b;
  1115. ~
  1116. FoxInterpreter.Expression
  1117. Test.Test(5);
  1118. ~
  1119. FoxInterpreter.Statements
  1120. a := Test.c.b;
  1121. Test.c.b := Test.c.b + 1;
  1122. ~
  1123. FoxInterpreter.Expression
  1124. a;
  1125. ~
  1126. FoxInterpreter.Expression
  1127. Test.c.b;
  1128. ~
  1129. FoxInterpreter.Statements
  1130. Test.Test(123)
  1131. ~
  1132. FoxInterpreter.Statements
  1133. FOR i := 1 TO 100 DO
  1134. CASE i MOD 10 OF
  1135. 1: suffix := "st"
  1136. |2: suffix := "nd"
  1137. |3: suffix := "rd"
  1138. ELSE suffix := "th"
  1139. END;
  1140. IF i MOD 9 = 0 THEN
  1141. CMD SystemTools.Show This is the ?{i}?{suffix} run. ;
  1142. CMD SystemTools.Ln;
  1143. END;
  1144. END;
  1145. ~
  1146. FoxInterpreter.Expression
  1147. i MOD 10 ~
  1148. FoxInterpreter.Statements
  1149. o := Test.TestO();
  1150. ~
  1151. FoxInterpreter.Statements
  1152. s := {0..10, 15};
  1153. a := 10;
  1154. b := 10..20;
  1155. c := {a,b};
  1156. x := 10;
  1157. y := 20;
  1158. z := x;
  1159. z := x + y;
  1160. b := x = y;
  1161. nb := x # y;
  1162. FOR i := 0 TO 3 DO
  1163. a := i;
  1164. IF i<2 THEN
  1165. a := 200+i;
  1166. END;
  1167. CASE i OF
  1168. 0: a := 2000;
  1169. |2: HALT(100)
  1170. END;
  1171. END;
  1172. ~
  1173. TRACE(x);
  1174. FOR i := 0 TO 100 DO
  1175. x[i] := i
  1176. END;
  1177. ~
  1178. FoxInterpreter.TranslateString
  1179. "This is a string ?{15+2*20*a:32}? oha."
  1180. "The rest of this string will be evaluated ?{3+5 = 20}?"
  1181. "?{ 100*15"
  1182. "a set in a evaluated expression ?{{1,2,4}}?"
  1183. ~
  1184. FoxInterpreter.Statements
  1185. a := [[1,2,3],[4,5,6],[7,8,9]];
  1186. FOR i := 0 TO 2 DO
  1187. FOR j := 0 TO 2 DO
  1188. CMD \+"SystemTools.Show ?{a[i,j]}? ;"+\
  1189. END;
  1190. CMD \+"SystemTools.Ln;"+\
  1191. END;
  1192. CMD \+"SystemTools.Show ?{a}? "+\
  1193. ~
  1194. SystemTools.FreeDownTo FoxInterpreter FoxInterpreterSymbols ~
  1195. FoxInterpreter.Statements
  1196. version := 02000302H;
  1197. a := [
  1198. (* development , version base, TL300, CN, SingleSensor, Version *)
  1199. [FALSE, "TLxDev", FALSE, FALSE, FALSE, version],
  1200. [FALSE, "TL400", FALSE, FALSE, FALSE, version],
  1201. [FALSE, "TL300", TRUE, FALSE, TRUE, version],
  1202. [FALSE, "TL300CN", TRUE, TRUE, FALSE, version],
  1203. [FALSE, "TL300USsu", TRUE, FALSE, TRUE, version],
  1204. [FALSE, "TL300USrt", TRUE, FALSE, FALSE, version]
  1205. ];
  1206. FOR i := 0 TO 5 DO
  1207. major := a[i,5] DIV 1000000H MOD 100H;
  1208. minor := a[i,5] DIV 10000H MOD 100H;
  1209. release := a[i,5] DIV 100H MOD 100H;
  1210. internal := a[i,5] MOD 100H;
  1211. CMD \+"
  1212. SystemTools.Show Building ?{a[i,1]}? Version ?{major}?.?{minor}?.?{release}?.?{internal}? ~
  1213. SystemTools.Ln ~
  1214. FSTools.CreateFile -c -r TLHostConst.Mod
  1215. MODULE TLHostConst;
  1216. (**
  1217. purpose: GUI Configuration Controller. Sets basics for differentiation of different product lines.
  1218. author: Felix Friedrich
  1219. *)
  1220. CONST
  1221. Development*=?{a[i,0]}?;
  1222. VersionBase*="?{a[i,1]}? ";
  1223. TL300*=?{a[i,2]}?;
  1224. CN*=?{a[i,3]}?;
  1225. SingleSensor*=?{a[i,4]}?;
  1226. Version* = ?{a[i,5]}?;
  1227. END TLHostConst.
  1228. ~
  1229. Compiler.Compile --objectFile=Generic Runtime.Mod Trace.Mod A2/Win32.MiniKernel.Mod A2/Win32.WatchdogServer.Mod ~
  1230. StaticLinker.Link
  1231. --fileFormat=PE32
  1232. --fileName=A2Watchdog.exe
  1233. --extension=Gof
  1234. --displacement=401000H
  1235. Runtime Trace MiniKernel WatchdogServer ~
  1236. SystemTools.Show Create ramdisk and format with FAT file system... ~ SystemTools.Ln ~
  1237. VirtualDisks.InstallRamdisk RAMDISK 240000 ~
  1238. Partitions.WriteMBR RAMDISK#0 OBEMBR.Bin ~
  1239. Partitions.Create RAMDISK#1 12 1000 ~
  1240. Partitions.Format RAMDISK#1 FatFS ~
  1241. FSTools.Mount WINAOS FatFS RAMDISK#1 ~
  1242. SystemTools.Ln ~ SystemTools.Show Create WinAOS directory structure... ~
  1243. FSTools.CreateDirectory WINAOS:/TL ~
  1244. FSTools.CreateDirectory WINAOS:/TL/obj ~
  1245. FSTools.CreateDirectory WINAOS:/TL/source ~
  1246. FSTools.CreateDirectory WINAOS:/TL/data ~
  1247. FSTools.CreateDirectory WINAOS:/TL/skins ~
  1248. FSTools.CreateDirectory WINAOS:/TL/fonts ~
  1249. FSTools.CreateDirectory WINAOS:/TL/work ~
  1250. SystemTools.Show Done. ~ SystemTools.Ln ~
  1251. SystemTools.Ln ~ SystemTools.Show Create build directory and build WinAos... ~ SystemTools.Ln ~
  1252. Release.Build
  1253. -f=TL/TLHost.Tool --path="WINAOS:/TL/obj/" --build --zip WinAosMini ~
  1254. SystemTools.Ln ~ SystemTools.Show Extracting data ... ~ SystemTools.Ln ~
  1255. ZipTool.ExtractAll --prefix=WINAOS:/TL/data/ --sourcePath=WINAOS:/TL/obj/ --overwrite -d --silent
  1256. Kernel.zip System.zip Drivers.zip
  1257. ApplicationsMini.zip Compiler.zip GuiApplicationsMini.zip TL.zip
  1258. ~
  1259. SystemTools.Ln ~ SystemTools.Show Removing object files from data folder... ~ SystemTools.Ln ~
  1260. FSTools.DeleteFiles --silent WINAOS:/TL/data/*.Obw ~
  1261. SystemTools.Ln ~ SystemTools.Show Extracting fonts ... ~ SystemTools.Ln ~
  1262. ZipTool.ExtractAll --prefix=WINAOS:/TL/fonts/ --sourcePath=WINAOS:/TL/obj/ --overwrite -d --silent
  1263. ScreenFonts.zip TrueTypeFonts.zip
  1264. ~
  1265. SystemTools.Ln ~ SystemTools.Show Delete ZIP archives from obj folder... ~ SystemTools.Ln ~
  1266. FSTools.DeleteFiles --silent WINAOS:/TL/obj/*.zip ~
  1267. SystemTools.Ln ~ SystemTools.Show Copy skins ... ~ SystemTools.Ln ~
  1268. FSTools.CopyFiles -o ../../source/*.skin => WINAOS:/TL/skins/*.skin ~
  1269. SystemTools.Ln ~ SystemTools.Show Delete some large files that are not stricly required... ~ SystemTools.Ln ~
  1270. FSTools.DeleteFiles
  1271. WINAOS:/TL/data/UnicodeData.txt
  1272. WINAOS:/TL/data/Setup.Text
  1273. WINAOS:/TL/data/BootManager.Text
  1274. ~
  1275. SystemTools.Ln ~ SystemTools.Show Delete some files from data folder... ~ SystemTools.Ln ~
  1276. FSTools.DeleteFiles WINAOS:/TL/data/*.Bin ~
  1277. FSTools.DeleteFiles
  1278. WINAOS:/TL/data/TestContext.xml
  1279. WINAOS:/TL/data/Release.Auto.dsk
  1280. WINAOS:/TL/data/AosDefault.Pal
  1281. WINAOS:/TL/data/OBL.Text
  1282. WINAOS:/TL/data/License.Text
  1283. WINAOS:/TL/data/bluebottle.xsl
  1284. WINAOS:/TL/data/WMPerfMonAlerts.XML
  1285. WINAOS:/TL/data/config.txt
  1286. WINAOS:/TL/data/WMPerfMon.Text
  1287. WINAOS:/TL/obj/CompileCommand.Tool
  1288. ~
  1289. FSTools.CopyFiles WINAOS:/TL/data/ZeroSkin.zip => WINAOS:/TL/skins/ZeroSkin.zip ~
  1290. FSTools.CopyFiles A2Watchdog.exe => WINAOS:/TL/A2Watchdog.exe ~
  1291. FSTools.DeleteFiles WINAOS:/TL/data/ZeroSkin.zip ~
  1292. SystemTools.Show Linking aos.exe ... ~ SystemTools.Ln ~
  1293. PELinker.Link --path=WINAOS:/TL/obj/ --destination=WINAOS:/TL/tl.exe Win32.Aos.Link ~
  1294. FSTools.CreateFile -c -r WINAOS:/TL/aos.ini
  1295. [Configuration]
  1296. Paths.Search = work;obj;source;data;skins;fonts;c:/windows/fonts/
  1297. Paths.Work = work
  1298. Oberon = OberonExternal.Text
  1299. Boot = Traps.Install
  1300. Boot1 = FileTrapWriter.Install
  1301. Boot2 = Display.Install --fullscreen --bits16 --noMouseCursor
  1302. Boot3 = WindowManager.Install --noMouseCursor --bgColor=0F2EFFH
  1303. Boot4 = Clipboard.Install
  1304. Boot6 = HotKeys.Open
  1305. Boot7 = TLC.EnableTrace
  1306. Boot8 = TLC.SetClientTraceLog tltrace
  1307. Boot9 = TLHost.Boot
  1308. Trace = File
  1309. ~
  1310. FSTools.CreateFile -c -r WINAOS:/TL/TL.bat
  1311. A2Watchdog tl.exe
  1312. ~
  1313. FSTools.DeleteFiles TL.zip ~
  1314. SystemTools.Ln ~ SystemTools.Show Creating archive TL.zip... ~
  1315. FSTools.Enumerate -s WINAOS:/TL/*.*
  1316. ZipTool.Add --silent -r TL.zip <#filename#>
  1317. ~
  1318. FSTools.CloseFiles TL.zip ~
  1319. SystemTools.Show Done ~ SystemTools.Ln ~
  1320. FSTools.Unmount WINAOS ~
  1321. VirtualDisks.Uninstall RAMDISK ~
  1322. FSTools.CopyFiles -o TL.zip => ?{a[i,1]}?_?{major}?_?{minor}?_?{release}?_?{internal}?.zip ~
  1323. "+\;
  1324. END;
  1325. ~