FoxInterpreter.Mod 38 KB

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