FoxInterpreter.Mod 43 KB

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