FoxInterpreter.Mod 45 KB

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