FoxInterpreter.Mod 46 KB

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