FoxInterpreter.Mod 42 KB

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