1 | unit Executor;
|
---|
2 |
|
---|
3 | interface
|
---|
4 |
|
---|
5 | uses
|
---|
6 | Classes, SysUtils, Source, Generics.Collections;
|
---|
7 |
|
---|
8 | type
|
---|
9 | TExecutorFunctions = class;
|
---|
10 | TExecutorBlock = class;
|
---|
11 |
|
---|
12 | TExecutorVariableKind = (vkNormal, vkReference);
|
---|
13 |
|
---|
14 | { TExecutorVariable }
|
---|
15 |
|
---|
16 | TExecutorVariable = class
|
---|
17 | private
|
---|
18 | FValue: TValue;
|
---|
19 | function GetValue: TValue;
|
---|
20 | procedure SetValue(AValue: TValue);
|
---|
21 | public
|
---|
22 | Variable: TVariable;
|
---|
23 | Kind: TExecutorVariableKind;
|
---|
24 | RefVariable: TExecutorVariable;
|
---|
25 | constructor Create;
|
---|
26 | destructor Destroy; override;
|
---|
27 | property Value: TValue read GetValue write SetValue;
|
---|
28 | end;
|
---|
29 |
|
---|
30 | { TExecutorVariables }
|
---|
31 |
|
---|
32 | TExecutorVariables = class(TObjectList<TExecutorVariable>)
|
---|
33 | function SearchByVariable(Variable: TVariable): TExecutorVariable;
|
---|
34 | function AddNew(Variable: TVariable): TExecutorVariable;
|
---|
35 | end;
|
---|
36 |
|
---|
37 | { TExecutorType }
|
---|
38 |
|
---|
39 | TExecutorType = class
|
---|
40 | TypeRef: TType;
|
---|
41 | Functions: TExecutorFunctions;
|
---|
42 | constructor Create;
|
---|
43 | destructor Destroy; override;
|
---|
44 | end;
|
---|
45 |
|
---|
46 | { TExecutorTypes }
|
---|
47 |
|
---|
48 | TExecutorTypes = class(TObjectList<TExecutorType>)
|
---|
49 | function SearchByType(TypeRef: TType): TExecutorType;
|
---|
50 | function AddNew(TypeRef: TType): TExecutorType;
|
---|
51 | end;
|
---|
52 |
|
---|
53 | TExecutorFunctionCallback = function(Params: array of TExecutorVariable):
|
---|
54 | TValue of object;
|
---|
55 |
|
---|
56 | { TExecutorFunction }
|
---|
57 |
|
---|
58 | TExecutorFunction = class
|
---|
59 | FunctionDef: TFunction;
|
---|
60 | Block: TExecutorBlock;
|
---|
61 | Callback: TExecutorFunctionCallback;
|
---|
62 | constructor Create;
|
---|
63 | destructor Destroy; override;
|
---|
64 | end;
|
---|
65 |
|
---|
66 | { TExecutorFunctions }
|
---|
67 |
|
---|
68 | TExecutorFunctions = class(TObjectList<TExecutorFunction>)
|
---|
69 | function SearchByFunction(FunctionDef: TFunction): TExecutorFunction;
|
---|
70 | function AddNew(FunctionDef: TFunction): TExecutorFunction;
|
---|
71 | end;
|
---|
72 |
|
---|
73 | { TExecutorProcedure }
|
---|
74 |
|
---|
75 | TExecutorProcedure = class
|
---|
76 | ProcedureDef: TProcedure;
|
---|
77 | Block: TExecutorBlock;
|
---|
78 | Callback: TExecutorFunctionCallback;
|
---|
79 | constructor Create;
|
---|
80 | destructor Destroy; override;
|
---|
81 | end;
|
---|
82 |
|
---|
83 | { TExecutorProcedures }
|
---|
84 |
|
---|
85 | TExecutorProcedures = class(TObjectList<TExecutorProcedure>)
|
---|
86 | function SearchByProcedure(ProcedureDef: TProcedure): TExecutorProcedure;
|
---|
87 | function AddNew(ProcedureDef: TProcedure): TExecutorProcedure;
|
---|
88 | end;
|
---|
89 |
|
---|
90 | { TExecutorBlock }
|
---|
91 |
|
---|
92 | TExecutorBlock = class
|
---|
93 | Parent: TExecutorBlock;
|
---|
94 | Types: TExecutorTypes;
|
---|
95 | Variables: TExecutorVariables;
|
---|
96 | Functions: TExecutorFunctions;
|
---|
97 | Procedures: TExecutorProcedures;
|
---|
98 | function GetFunction(FunctionDef: TFunction): TExecutorFunction;
|
---|
99 | function GetProcedure(ProcedureDef: TProcedure): TExecutorProcedure;
|
---|
100 | function GetType(TypeDef: TType): TExecutorType;
|
---|
101 | function GetVariable(Variable: TVariable): TExecutorVariable;
|
---|
102 | function GetTypeFunction(TypeDef: TType; FunctionDef: TFunction): TExecutorFunction; overload;
|
---|
103 | function GetTypeFunction(TypeDef: TType; FunctionName: string): TExecutorFunction; overload;
|
---|
104 | constructor Create;
|
---|
105 | destructor Destroy; override;
|
---|
106 | end;
|
---|
107 |
|
---|
108 | TOutputEvent = procedure (Text: string) of object;
|
---|
109 | TInputEvent = function: string of object;
|
---|
110 |
|
---|
111 | { TExecutor }
|
---|
112 |
|
---|
113 | TExecutor = class
|
---|
114 | private
|
---|
115 | FOnOutput: TOutputEvent;
|
---|
116 | FOnInput: TInputEvent;
|
---|
117 | SystemBlock: TExecutorBlock;
|
---|
118 | function ExecuteWriteLn(Params: array of TExecutorVariable): TValue;
|
---|
119 | function ExecuteWrite(Params: array of TExecutorVariable): TValue;
|
---|
120 | function ExecuteReadLn(Params: array of TExecutorVariable): TValue;
|
---|
121 | function ExecuteRead(Params: array of TExecutorVariable): TValue;
|
---|
122 | function ExecuteIntToStr(Params: array of TExecutorVariable): TValue;
|
---|
123 | function ExecuteStrToInt(Params: array of TExecutorVariable): TValue;
|
---|
124 | function ExecuteBoolToStr(Params: array of TExecutorVariable): TValue;
|
---|
125 | function ExecuteStrToBool(Params: array of TExecutorVariable): TValue;
|
---|
126 | function ExecuteBooleanAssign(Params: array of TExecutorVariable): TValue;
|
---|
127 | function ExecuteBooleanNot(Params: array of TExecutorVariable): TValue;
|
---|
128 | function ExecuteBooleanEqual(Params: array of TExecutorVariable): TValue;
|
---|
129 | function ExecuteBooleanNotEqual(Params: array of TExecutorVariable): TValue;
|
---|
130 | function ExecuteStringAssign(Params: array of TExecutorVariable): TValue;
|
---|
131 | function ExecuteStringAdd(Params: array of TExecutorVariable): TValue;
|
---|
132 | function ExecuteStringEqual(Params: array of TExecutorVariable): TValue;
|
---|
133 | function ExecuteStringNotEqual(Params: array of TExecutorVariable): TValue;
|
---|
134 | function ExecuteIntegerAssign(Params: array of TExecutorVariable): TValue;
|
---|
135 | function ExecuteIntegerAdd(Params: array of TExecutorVariable): TValue;
|
---|
136 | function ExecuteIntegerSub(Params: array of TExecutorVariable): TValue;
|
---|
137 | function ExecuteIntegerMul(Params: array of TExecutorVariable): TValue;
|
---|
138 | function ExecuteIntegerIntDiv(Params: array of TExecutorVariable): TValue;
|
---|
139 | function ExecuteIntegerMod(Params: array of TExecutorVariable): TValue;
|
---|
140 | function ExecuteIntegerEqual(Params: array of TExecutorVariable): TValue;
|
---|
141 | function ExecuteIntegerNotEqual(Params: array of TExecutorVariable): TValue;
|
---|
142 | function ExecuteIntegerLesser(Params: array of TExecutorVariable): TValue;
|
---|
143 | function ExecuteIntegerHigher(Params: array of TExecutorVariable): TValue;
|
---|
144 | function ExecuteIntegerLesserOrEqual(Params: array of TExecutorVariable): TValue;
|
---|
145 | function ExecuteIntegerHigherOrEqual(Params: array of TExecutorVariable): TValue;
|
---|
146 | function ExecuteIntegerAnd(Params: array of TExecutorVariable): TValue;
|
---|
147 | function ExecuteIntegerOr(Params: array of TExecutorVariable): TValue;
|
---|
148 | function ExecuteIntegerXor(Params: array of TExecutorVariable): TValue;
|
---|
149 | function ExecuteIntegerShr(Params: array of TExecutorVariable): TValue;
|
---|
150 | function ExecuteIntegerShl(Params: array of TExecutorVariable): TValue;
|
---|
151 | procedure InitExecutorBlock(ExecutorBlock: TExecutorBlock; Block: TBlock);
|
---|
152 | public
|
---|
153 | Prog: TProgram;
|
---|
154 | procedure ExecuteProgram(Prog: TProgram);
|
---|
155 | procedure ExecuteBeginEnd(Block: TExecutorBlock; BeginEnd: TBeginEnd);
|
---|
156 | procedure ExecuteCommand(Block: TExecutorBlock; Command: TCommand);
|
---|
157 | procedure ExecuteIfThenElse(Block: TExecutorBlock; IfThenElse: TIfThenElse);
|
---|
158 | procedure ExecuteWhileDo(Block: TExecutorBlock; WhileDo: TWhileDo);
|
---|
159 | procedure ExecuteRepeatUntil(Block: TExecutorBlock; RepeatUntil: TRepeatUntil);
|
---|
160 | procedure ExecuteForToDo(Block: TExecutorBlock; ForToDo: TForToDo);
|
---|
161 | procedure ExecuteContinue(Block: TExecutorBlock; ContinueCmd: TContinue);
|
---|
162 | procedure ExecuteBreak(Block: TExecutorBlock; BreakCmd: TBreak);
|
---|
163 | procedure ExecuteBlock(ParentBlock: TExecutorBlock; Block: TBlock; ExistingBlock: TExecutorBlock = nil);
|
---|
164 | function ExecuteFunctionCall(Block: TExecutorBlock; FunctionCall: TFunctionCall): TValue;
|
---|
165 | procedure ExecuteProcedureCall(Block: TExecutorBlock; ProcedureCall: TProcedureCall);
|
---|
166 | procedure ExecuteAssignment(Block: TExecutorBlock; Assignment: TAssignment);
|
---|
167 | function ExecuteExpression(Block: TExecutorBlock; Expression: TExpression): TValue;
|
---|
168 | function ExecuteExpressionOperation(Block: TExecutorBlock; Expression: TExpressionOperation): TValue;
|
---|
169 | function ExecuteExpressionOperand(Block: TExecutorBlock; Expression: TExpressionOperand): TValue;
|
---|
170 | function ExecuteExpressionBrackets(Block: TExecutorBlock; Expression: TExpressionBrackets): TValue;
|
---|
171 | procedure Run;
|
---|
172 | procedure Output(Text: string);
|
---|
173 | function Input: string;
|
---|
174 | property OnOutput: TOutputEvent read FOnOutput write FOnOutput;
|
---|
175 | property OnInput: TInputEvent read FOnInput write FOnInput;
|
---|
176 | end;
|
---|
177 |
|
---|
178 |
|
---|
179 | implementation
|
---|
180 |
|
---|
181 | uses
|
---|
182 | SourceNode;
|
---|
183 |
|
---|
184 | resourcestring
|
---|
185 | SUnsupportedOperandType = 'Unsupported exception operand type.';
|
---|
186 | SUnsupportedCommandType = 'Unsupported command type.';
|
---|
187 | SExpectedBooleanValue = 'Expected boolean value.';
|
---|
188 |
|
---|
189 | { TExecutorProcedures }
|
---|
190 |
|
---|
191 | function TExecutorProcedures.SearchByProcedure(ProcedureDef: TProcedure
|
---|
192 | ): TExecutorProcedure;
|
---|
193 | var
|
---|
194 | I: Integer;
|
---|
195 | begin
|
---|
196 | I := 0;
|
---|
197 | while (I < Count) and (Items[I].ProcedureDef <> ProcedureDef) do Inc(I);
|
---|
198 | if I < Count then Result := Items[I]
|
---|
199 | else Result := nil;
|
---|
200 | end;
|
---|
201 |
|
---|
202 | function TExecutorProcedures.AddNew(ProcedureDef: TProcedure
|
---|
203 | ): TExecutorProcedure;
|
---|
204 | begin
|
---|
205 | Result := TExecutorProcedure.Create;
|
---|
206 | Result.ProcedureDef := ProcedureDef;
|
---|
207 | Add(Result);
|
---|
208 | end;
|
---|
209 |
|
---|
210 | { TExecutorProcedure }
|
---|
211 |
|
---|
212 | constructor TExecutorProcedure.Create;
|
---|
213 | begin
|
---|
214 | Block := TExecutorBlock.Create;
|
---|
215 | end;
|
---|
216 |
|
---|
217 | destructor TExecutorProcedure.Destroy;
|
---|
218 | begin
|
---|
219 | FreeAndNil(Block);
|
---|
220 | inherited;
|
---|
221 | end;
|
---|
222 |
|
---|
223 | { TExecutorFunction }
|
---|
224 |
|
---|
225 | constructor TExecutorFunction.Create;
|
---|
226 | begin
|
---|
227 | Block := TExecutorBlock.Create;
|
---|
228 | end;
|
---|
229 |
|
---|
230 | destructor TExecutorFunction.Destroy;
|
---|
231 | begin
|
---|
232 | FreeAndNil(Block);
|
---|
233 | inherited;
|
---|
234 | end;
|
---|
235 |
|
---|
236 | { TExecutorVariable }
|
---|
237 |
|
---|
238 | procedure TExecutorVariable.SetValue(AValue: TValue);
|
---|
239 | begin
|
---|
240 | if FValue = AValue then Exit;
|
---|
241 | if Kind = vkNormal then begin
|
---|
242 | FreeAndNil(FValue);
|
---|
243 | FValue := AValue;
|
---|
244 | end else
|
---|
245 | if Kind = vkReference then begin
|
---|
246 | RefVariable.Value := AValue;
|
---|
247 | end;
|
---|
248 | end;
|
---|
249 |
|
---|
250 | function TExecutorVariable.GetValue: TValue;
|
---|
251 | begin
|
---|
252 | if Kind = vkNormal then begin
|
---|
253 | Result := FValue;
|
---|
254 | end else
|
---|
255 | if Kind = vkReference then begin
|
---|
256 | Result := RefVariable.Value;
|
---|
257 | end;
|
---|
258 | end;
|
---|
259 |
|
---|
260 | constructor TExecutorVariable.Create;
|
---|
261 | begin
|
---|
262 | Value := TValue.Create;
|
---|
263 | end;
|
---|
264 |
|
---|
265 | destructor TExecutorVariable.Destroy;
|
---|
266 | begin
|
---|
267 | FreeAndNil(FValue);
|
---|
268 | inherited;
|
---|
269 | end;
|
---|
270 |
|
---|
271 | { TExecutorType }
|
---|
272 |
|
---|
273 | constructor TExecutorType.Create;
|
---|
274 | begin
|
---|
275 | Functions := TExecutorFunctions.Create;
|
---|
276 | end;
|
---|
277 |
|
---|
278 | destructor TExecutorType.Destroy;
|
---|
279 | begin
|
---|
280 | FreeAndNil(Functions);
|
---|
281 | inherited;
|
---|
282 | end;
|
---|
283 |
|
---|
284 | { TExecutorTypes }
|
---|
285 |
|
---|
286 | function TExecutorTypes.SearchByType(TypeRef: TType): TExecutorType;
|
---|
287 | var
|
---|
288 | I: Integer;
|
---|
289 | begin
|
---|
290 | I := 0;
|
---|
291 | while (I < Count) and (Items[I].TypeRef <> TypeRef) do Inc(I);
|
---|
292 | if I < Count then Result := Items[I]
|
---|
293 | else Result := nil;
|
---|
294 | end;
|
---|
295 |
|
---|
296 | function TExecutorTypes.AddNew(TypeRef: TType): TExecutorType;
|
---|
297 | begin
|
---|
298 | Result := TExecutorType.Create;
|
---|
299 | Result.TypeRef := TypeRef;
|
---|
300 | Add(Result);
|
---|
301 | end;
|
---|
302 |
|
---|
303 | { TExecutorFunctions }
|
---|
304 |
|
---|
305 | function TExecutorFunctions.SearchByFunction(FunctionDef: TFunction
|
---|
306 | ): TExecutorFunction;
|
---|
307 | var
|
---|
308 | I: Integer;
|
---|
309 | begin
|
---|
310 | I := 0;
|
---|
311 | while (I < Count) and (Items[I].FunctionDef <> FunctionDef) do Inc(I);
|
---|
312 | if I < Count then Result := Items[I]
|
---|
313 | else Result := nil;
|
---|
314 | end;
|
---|
315 |
|
---|
316 | function TExecutorFunctions.AddNew(FunctionDef: TFunction): TExecutorFunction;
|
---|
317 | begin
|
---|
318 | Result := TExecutorFunction.Create;
|
---|
319 | Result.FunctionDef := FunctionDef;
|
---|
320 | Add(Result);
|
---|
321 | end;
|
---|
322 |
|
---|
323 | { TExecutorVariables }
|
---|
324 |
|
---|
325 | function TExecutorVariables.SearchByVariable(Variable: TVariable): TExecutorVariable;
|
---|
326 | var
|
---|
327 | I: Integer;
|
---|
328 | begin
|
---|
329 | I := 0;
|
---|
330 | while (I < Count) and (Items[I].Variable <> Variable) do Inc(I);
|
---|
331 | if I < Count then Result := Items[I]
|
---|
332 | else Result := nil;
|
---|
333 | end;
|
---|
334 |
|
---|
335 | function TExecutorVariables.AddNew(Variable: TVariable): TExecutorVariable;
|
---|
336 | begin
|
---|
337 | Result := TExecutorVariable.Create;
|
---|
338 | Result.Variable := Variable;
|
---|
339 | Add(Result);
|
---|
340 | end;
|
---|
341 |
|
---|
342 | { TExecutorBlock }
|
---|
343 |
|
---|
344 | function TExecutorBlock.GetFunction(FunctionDef: TFunction): TExecutorFunction;
|
---|
345 | begin
|
---|
346 | Result := Functions.SearchByFunction(FunctionDef);
|
---|
347 | if not Assigned(Result) and Assigned(Parent) then
|
---|
348 | Result := Parent.GetFunction(FunctionDef);
|
---|
349 | end;
|
---|
350 |
|
---|
351 | function TExecutorBlock.GetProcedure(ProcedureDef: TProcedure
|
---|
352 | ): TExecutorProcedure;
|
---|
353 | begin
|
---|
354 | Result := Procedures.SearchByProcedure(ProcedureDef);
|
---|
355 | if not Assigned(Result) and Assigned(Parent) then
|
---|
356 | Result := Parent.GetProcedure(ProcedureDef);
|
---|
357 | end;
|
---|
358 |
|
---|
359 | function TExecutorBlock.GetType(TypeDef: TType): TExecutorType;
|
---|
360 | begin
|
---|
361 | Result := Types.SearchByType(TypeDef);
|
---|
362 | if not Assigned(Result) and Assigned(Parent) then
|
---|
363 | Result := Parent.GetType(TypeDef);
|
---|
364 | end;
|
---|
365 |
|
---|
366 | function TExecutorBlock.GetVariable(Variable: TVariable): TExecutorVariable;
|
---|
367 | begin
|
---|
368 | Result := Variables.SearchByVariable(Variable);
|
---|
369 | if not Assigned(Result) and Assigned(Parent) then
|
---|
370 | Result := Parent.GetVariable(Variable);
|
---|
371 | end;
|
---|
372 |
|
---|
373 | function TExecutorBlock.GetTypeFunction(TypeDef: TType; FunctionDef: TFunction
|
---|
374 | ): TExecutorFunction;
|
---|
375 | var
|
---|
376 | ExecutorType: TExecutorType;
|
---|
377 | begin
|
---|
378 | ExecutorType := GetType(TypeDef);
|
---|
379 | Result := ExecutorType.Functions.SearchByFunction(FunctionDef);
|
---|
380 | end;
|
---|
381 |
|
---|
382 | function TExecutorBlock.GetTypeFunction(TypeDef: TType; FunctionName: string
|
---|
383 | ): TExecutorFunction;
|
---|
384 | begin
|
---|
385 | Result := GetTypeFunction(TypeDef, TypeDef.Functions.SearchByName(FunctionName));
|
---|
386 | end;
|
---|
387 |
|
---|
388 | constructor TExecutorBlock.Create;
|
---|
389 | begin
|
---|
390 | Types := TExecutorTypes.Create;
|
---|
391 | Variables := TExecutorVariables.Create;
|
---|
392 | Functions := TExecutorFunctions.Create;
|
---|
393 | Procedures := TExecutorProcedures.Create;
|
---|
394 | end;
|
---|
395 |
|
---|
396 | destructor TExecutorBlock.Destroy;
|
---|
397 | begin
|
---|
398 | FreeAndNil(Variables);
|
---|
399 | FreeAndNil(Functions);
|
---|
400 | FreeAndNil(Procedures);
|
---|
401 | FreeAndNil(Types);
|
---|
402 | inherited;
|
---|
403 | end;
|
---|
404 |
|
---|
405 | { TExecutor }
|
---|
406 |
|
---|
407 | function TExecutor.ExecuteWriteLn(Params: array of TExecutorVariable): TValue;
|
---|
408 | var
|
---|
409 | I: Integer;
|
---|
410 | Text: string;
|
---|
411 | begin
|
---|
412 | Result := nil;
|
---|
413 | Text := '';
|
---|
414 | for I := 0 to Length(Params) - 1 do
|
---|
415 | Text := Text + TValueString(Params[I].Value).Value;
|
---|
416 | Output(Text + LineEnding);
|
---|
417 | end;
|
---|
418 |
|
---|
419 | function TExecutor.ExecuteWrite(Params: array of TExecutorVariable): TValue;
|
---|
420 | var
|
---|
421 | I: Integer;
|
---|
422 | Text: string;
|
---|
423 | begin
|
---|
424 | Result := nil;
|
---|
425 | Text := '';
|
---|
426 | for I := 0 to Length(Params) - 1 do
|
---|
427 | Text := Text + TValueString(Params[I].Value).Value;
|
---|
428 | Output(Text);
|
---|
429 | end;
|
---|
430 |
|
---|
431 | function TExecutor.ExecuteReadLn(Params: array of TExecutorVariable): TValue;
|
---|
432 | var
|
---|
433 | I: Integer;
|
---|
434 | begin
|
---|
435 | Result := nil;
|
---|
436 | for I := 0 to Length(Params) - 1 do begin
|
---|
437 | TValueString(Params[I].Value).Value := Input;
|
---|
438 | end;
|
---|
439 | Output(LineEnding);
|
---|
440 | end;
|
---|
441 |
|
---|
442 | function TExecutor.ExecuteRead(Params: array of TExecutorVariable): TValue;
|
---|
443 | var
|
---|
444 | I: Integer;
|
---|
445 | begin
|
---|
446 | Result := nil;
|
---|
447 | for I := 0 to Length(Params) - 1 do
|
---|
448 | TValueString(Params[I].Value).Value := Input;
|
---|
449 | end;
|
---|
450 |
|
---|
451 | function TExecutor.ExecuteIntToStr(Params: array of TExecutorVariable): TValue;
|
---|
452 | begin
|
---|
453 | Result := TValueString.Create;
|
---|
454 | TValueString(Result).Value := IntToStr(TValueInteger(Params[0].Value).Value);
|
---|
455 | end;
|
---|
456 |
|
---|
457 | function TExecutor.ExecuteStrToInt(Params: array of TExecutorVariable): TValue;
|
---|
458 | begin
|
---|
459 | Result := TValueInteger.Create;
|
---|
460 | TValueInteger(Result).Value := StrToInt(TValueString(Params[0].Value).Value);
|
---|
461 | end;
|
---|
462 |
|
---|
463 | function TExecutor.ExecuteBoolToStr(Params: array of TExecutorVariable): TValue;
|
---|
464 | begin
|
---|
465 | Result := TValueString.Create;
|
---|
466 | TValueString(Result).Value := BoolToStr(TValueBoolean(Params[0].Value).Value);
|
---|
467 | end;
|
---|
468 |
|
---|
469 | function TExecutor.ExecuteStrToBool(Params: array of TExecutorVariable): TValue;
|
---|
470 | begin
|
---|
471 | Result := TValueBoolean.Create;
|
---|
472 | TValueBoolean(Result).Value := StrToBool(TValueString(Params[0].Value).Value);
|
---|
473 | end;
|
---|
474 |
|
---|
475 | function TExecutor.ExecuteBooleanAssign(Params: array of TExecutorVariable): TValue;
|
---|
476 | begin
|
---|
477 | Result := TValueBoolean.Create;
|
---|
478 | TValueBoolean(Result).Value := TValueBoolean(Params[0].Value).Value;
|
---|
479 | end;
|
---|
480 |
|
---|
481 | function TExecutor.ExecuteBooleanNot(Params: array of TExecutorVariable): TValue;
|
---|
482 | begin
|
---|
483 | Result := TValueBoolean.Create;
|
---|
484 | TValueBoolean(Result).Value := not TValueBoolean(Params[0].Value).Value;
|
---|
485 | end;
|
---|
486 |
|
---|
487 | function TExecutor.ExecuteBooleanEqual(Params: array of TExecutorVariable): TValue;
|
---|
488 | begin
|
---|
489 | Result := TValueBoolean.Create;
|
---|
490 | TValueBoolean(Result).Value := TValueBoolean(Params[0].Value).Value =
|
---|
491 | TValueBoolean(Params[1].Value).Value;
|
---|
492 | end;
|
---|
493 |
|
---|
494 | function TExecutor.ExecuteBooleanNotEqual(Params: array of TExecutorVariable): TValue;
|
---|
495 | begin
|
---|
496 | Result := TValueBoolean.Create;
|
---|
497 | TValueBoolean(Result).Value := TValueBoolean(Params[0].Value).Value <>
|
---|
498 | TValueBoolean(Params[1].Value).Value;
|
---|
499 | end;
|
---|
500 |
|
---|
501 | function TExecutor.ExecuteStringAssign(Params: array of TExecutorVariable): TValue;
|
---|
502 | begin
|
---|
503 | Result := TValueString.Create;
|
---|
504 | TValueString(Result).Value := TValueString(Params[0].Value).Value;
|
---|
505 | end;
|
---|
506 |
|
---|
507 | function TExecutor.ExecuteStringAdd(Params: array of TExecutorVariable): TValue;
|
---|
508 | begin
|
---|
509 | Result := TValueString.Create;
|
---|
510 | TValueString(Result).Value := TValueString(Params[0].Value).Value +
|
---|
511 | TValueString(Params[1].Value).Value;
|
---|
512 | end;
|
---|
513 |
|
---|
514 | function TExecutor.ExecuteStringEqual(Params: array of TExecutorVariable): TValue;
|
---|
515 | begin
|
---|
516 | Result := TValueBoolean.Create;
|
---|
517 | TValueBoolean(Result).Value := TValueString(Params[0].Value).Value =
|
---|
518 | TValueString(Params[1].Value).Value;
|
---|
519 | end;
|
---|
520 |
|
---|
521 | function TExecutor.ExecuteStringNotEqual(Params: array of TExecutorVariable): TValue;
|
---|
522 | begin
|
---|
523 | Result := TValueBoolean.Create;
|
---|
524 | TValueBoolean(Result).Value := TValueString(Params[0].Value).Value <>
|
---|
525 | TValueString(Params[1].Value).Value;
|
---|
526 | end;
|
---|
527 |
|
---|
528 | function TExecutor.ExecuteIntegerAssign(Params: array of TExecutorVariable): TValue;
|
---|
529 | begin
|
---|
530 | Result := TValueInteger.Create;
|
---|
531 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value;
|
---|
532 | end;
|
---|
533 |
|
---|
534 | function TExecutor.ExecuteIntegerAdd(Params: array of TExecutorVariable): TValue;
|
---|
535 | begin
|
---|
536 | Result := TValueInteger.Create;
|
---|
537 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value +
|
---|
538 | TValueInteger(Params[1].Value).Value;
|
---|
539 | end;
|
---|
540 |
|
---|
541 | function TExecutor.ExecuteIntegerSub(Params: array of TExecutorVariable): TValue;
|
---|
542 | begin
|
---|
543 | Result := TValueInteger.Create;
|
---|
544 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value -
|
---|
545 | TValueInteger(Params[1].Value).Value;
|
---|
546 | end;
|
---|
547 |
|
---|
548 | function TExecutor.ExecuteIntegerMul(Params: array of TExecutorVariable): TValue;
|
---|
549 | begin
|
---|
550 | Result := TValueInteger.Create;
|
---|
551 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value *
|
---|
552 | TValueInteger(Params[1].Value).Value;
|
---|
553 | end;
|
---|
554 |
|
---|
555 | function TExecutor.ExecuteIntegerIntDiv(Params: array of TExecutorVariable): TValue;
|
---|
556 | begin
|
---|
557 | Result := TValueInteger.Create;
|
---|
558 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value div
|
---|
559 | TValueInteger(Params[1].Value).Value;
|
---|
560 | end;
|
---|
561 |
|
---|
562 | function TExecutor.ExecuteIntegerMod(Params: array of TExecutorVariable): TValue;
|
---|
563 | begin
|
---|
564 | Result := TValueInteger.Create;
|
---|
565 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value mod
|
---|
566 | TValueInteger(Params[1].Value).Value;
|
---|
567 | end;
|
---|
568 |
|
---|
569 | function TExecutor.ExecuteIntegerEqual(Params: array of TExecutorVariable): TValue;
|
---|
570 | begin
|
---|
571 | Result := TValueBoolean.Create;
|
---|
572 | TValueBoolean(Result).Value := TValueInteger(Params[0].Value).Value =
|
---|
573 | TValueInteger(Params[1].Value).Value;
|
---|
574 | end;
|
---|
575 |
|
---|
576 | function TExecutor.ExecuteIntegerNotEqual(Params: array of TExecutorVariable): TValue;
|
---|
577 | begin
|
---|
578 | Result := TValueBoolean.Create;
|
---|
579 | TValueBoolean(Result).Value := TValueInteger(Params[0].Value).Value <>
|
---|
580 | TValueInteger(Params[1].Value).Value;
|
---|
581 | end;
|
---|
582 |
|
---|
583 | function TExecutor.ExecuteIntegerLesser(Params: array of TExecutorVariable): TValue;
|
---|
584 | begin
|
---|
585 | Result := TValueBoolean.Create;
|
---|
586 | TValueBoolean(Result).Value := TValueInteger(Params[0].Value).Value <
|
---|
587 | TValueInteger(Params[1].Value).Value;
|
---|
588 | end;
|
---|
589 |
|
---|
590 | function TExecutor.ExecuteIntegerHigher(Params: array of TExecutorVariable): TValue;
|
---|
591 | begin
|
---|
592 | Result := TValueBoolean.Create;
|
---|
593 | TValueBoolean(Result).Value := TValueInteger(Params[0].Value).Value >
|
---|
594 | TValueInteger(Params[1].Value).Value;
|
---|
595 | end;
|
---|
596 |
|
---|
597 | function TExecutor.ExecuteIntegerLesserOrEqual(Params: array of TExecutorVariable): TValue;
|
---|
598 | begin
|
---|
599 | Result := TValueBoolean.Create;
|
---|
600 | TValueBoolean(Result).Value := TValueInteger(Params[0].Value).Value <=
|
---|
601 | TValueInteger(Params[1].Value).Value;
|
---|
602 | end;
|
---|
603 |
|
---|
604 | function TExecutor.ExecuteIntegerHigherOrEqual(Params: array of TExecutorVariable): TValue;
|
---|
605 | begin
|
---|
606 | Result := TValueBoolean.Create;
|
---|
607 | TValueBoolean(Result).Value := TValueInteger(Params[0].Value).Value >=
|
---|
608 | TValueInteger(Params[1].Value).Value;
|
---|
609 | end;
|
---|
610 |
|
---|
611 | function TExecutor.ExecuteIntegerAnd(Params: array of TExecutorVariable): TValue;
|
---|
612 | begin
|
---|
613 | Result := TValueInteger.Create;
|
---|
614 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value and
|
---|
615 | TValueInteger(Params[1].Value).Value;
|
---|
616 | end;
|
---|
617 |
|
---|
618 | function TExecutor.ExecuteIntegerOr(Params: array of TExecutorVariable): TValue;
|
---|
619 | begin
|
---|
620 | Result := TValueInteger.Create;
|
---|
621 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value or
|
---|
622 | TValueInteger(Params[1].Value).Value;
|
---|
623 | end;
|
---|
624 |
|
---|
625 | function TExecutor.ExecuteIntegerXor(Params: array of TExecutorVariable): TValue;
|
---|
626 | begin
|
---|
627 | Result := TValueInteger.Create;
|
---|
628 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value xor
|
---|
629 | TValueInteger(Params[1].Value).Value;
|
---|
630 | end;
|
---|
631 |
|
---|
632 | function TExecutor.ExecuteIntegerShr(Params: array of TExecutorVariable): TValue;
|
---|
633 | begin
|
---|
634 | Result := TValueInteger.Create;
|
---|
635 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value shr
|
---|
636 | TValueInteger(Params[1].Value).Value;
|
---|
637 | end;
|
---|
638 |
|
---|
639 | function TExecutor.ExecuteIntegerShl(Params: array of TExecutorVariable): TValue;
|
---|
640 | begin
|
---|
641 | Result := TValueInteger.Create;
|
---|
642 | TValueInteger(Result).Value := TValueInteger(Params[0].Value).Value shl
|
---|
643 | TValueInteger(Params[1].Value).Value;
|
---|
644 | end;
|
---|
645 |
|
---|
646 | procedure TExecutor.InitExecutorBlock(ExecutorBlock: TExecutorBlock; Block: TBlock);
|
---|
647 | var
|
---|
648 | I: Integer;
|
---|
649 | J: Integer;
|
---|
650 | ExecutorFunction: TExecutorFunction;
|
---|
651 | ExecutorProcedure: TExecutorProcedure;
|
---|
652 | ExecutorType: TExecutorType;
|
---|
653 | begin
|
---|
654 | for I := 0 to Block.Types.Count - 1 do begin
|
---|
655 | ExecutorType := ExecutorBlock.Types.AddNew(TType(Block.Types[I]));
|
---|
656 | for J := 0 to ExecutorType.TypeRef.Functions.Count - 1 do begin
|
---|
657 | ExecutorFunction := ExecutorType.Functions.AddNew(TFunction(ExecutorType.TypeRef.Functions[J]));
|
---|
658 | if ExecutorType.TypeRef.Name = 'Boolean' then begin
|
---|
659 | if ExecutorFunction.FunctionDef.Name = '_Assign' then begin
|
---|
660 | ExecutorFunction.Callback := ExecuteBooleanAssign;
|
---|
661 | end else
|
---|
662 | if ExecutorFunction.FunctionDef.Name = '_Equal' then begin
|
---|
663 | ExecutorFunction.Callback := ExecuteBooleanEqual;
|
---|
664 | end;
|
---|
665 | if ExecutorFunction.FunctionDef.Name = '_NotEqual' then begin
|
---|
666 | ExecutorFunction.Callback := ExecuteBooleanNotEqual;
|
---|
667 | end;
|
---|
668 | if ExecutorFunction.FunctionDef.Name = '_Not' then begin
|
---|
669 | ExecutorFunction.Callback := ExecuteBooleanNot;
|
---|
670 | end else
|
---|
671 | end else
|
---|
672 | if ExecutorType.TypeRef.Name = 'string' then begin
|
---|
673 | if ExecutorFunction.FunctionDef.Name = '_Assign' then begin
|
---|
674 | ExecutorFunction.Callback := ExecuteStringAssign;
|
---|
675 | end else
|
---|
676 | if ExecutorFunction.FunctionDef.Name = '_Add' then begin
|
---|
677 | ExecutorFunction.Callback := ExecuteStringAdd;
|
---|
678 | end else
|
---|
679 | if ExecutorFunction.FunctionDef.Name = '_Equal' then begin
|
---|
680 | ExecutorFunction.Callback := ExecuteStringEqual;
|
---|
681 | end;
|
---|
682 | if ExecutorFunction.FunctionDef.Name = '_NotEqual' then begin
|
---|
683 | ExecutorFunction.Callback := ExecuteStringNotEqual;
|
---|
684 | end;
|
---|
685 | end else
|
---|
686 | if ExecutorType.TypeRef.Name = 'Integer' then begin
|
---|
687 | if ExecutorFunction.FunctionDef.Name = '_Assign' then begin
|
---|
688 | ExecutorFunction.Callback := ExecuteIntegerAssign;
|
---|
689 | end else
|
---|
690 | if ExecutorFunction.FunctionDef.Name = '_Add' then begin
|
---|
691 | ExecutorFunction.Callback := ExecuteIntegerAdd;
|
---|
692 | end else
|
---|
693 | if ExecutorFunction.FunctionDef.Name = '_Sub' then begin
|
---|
694 | ExecutorFunction.Callback := ExecuteIntegerSub;
|
---|
695 | end else
|
---|
696 | if ExecutorFunction.FunctionDef.Name = '_Mul' then begin
|
---|
697 | ExecutorFunction.Callback := ExecuteIntegerMul;
|
---|
698 | end else
|
---|
699 | if ExecutorFunction.FunctionDef.Name = '_IntDiv' then begin
|
---|
700 | ExecutorFunction.Callback := ExecuteIntegerIntDiv;
|
---|
701 | end else
|
---|
702 | if ExecutorFunction.FunctionDef.Name = '_IntMod' then begin
|
---|
703 | ExecutorFunction.Callback := ExecuteIntegerMod;
|
---|
704 | end else
|
---|
705 | if ExecutorFunction.FunctionDef.Name = '_Equal' then begin
|
---|
706 | ExecutorFunction.Callback := ExecuteIntegerEqual;
|
---|
707 | end else
|
---|
708 | if ExecutorFunction.FunctionDef.Name = '_NotEqual' then begin
|
---|
709 | ExecutorFunction.Callback := ExecuteIntegerNotEqual;
|
---|
710 | end;
|
---|
711 | if ExecutorFunction.FunctionDef.Name = '_Lesser' then begin
|
---|
712 | ExecutorFunction.Callback := ExecuteIntegerLesser;
|
---|
713 | end else
|
---|
714 | if ExecutorFunction.FunctionDef.Name = '_Higher' then begin
|
---|
715 | ExecutorFunction.Callback := ExecuteIntegerHigher;
|
---|
716 | end;
|
---|
717 | if ExecutorFunction.FunctionDef.Name = '_LesserOrEqual' then begin
|
---|
718 | ExecutorFunction.Callback := ExecuteIntegerLesserOrEqual;
|
---|
719 | end else
|
---|
720 | if ExecutorFunction.FunctionDef.Name = '_HigherOrEqual' then begin
|
---|
721 | ExecutorFunction.Callback := ExecuteIntegerHigherOrEqual;
|
---|
722 | end;
|
---|
723 | if ExecutorFunction.FunctionDef.Name = '_And' then begin
|
---|
724 | ExecutorFunction.Callback := ExecuteIntegerAnd;
|
---|
725 | end;
|
---|
726 | if ExecutorFunction.FunctionDef.Name = '_Or' then begin
|
---|
727 | ExecutorFunction.Callback := ExecuteIntegerOr;
|
---|
728 | end;
|
---|
729 | if ExecutorFunction.FunctionDef.Name = '_Xor' then begin
|
---|
730 | ExecutorFunction.Callback := ExecuteIntegerXor;
|
---|
731 | end;
|
---|
732 | if ExecutorFunction.FunctionDef.Name = '_Shr' then begin
|
---|
733 | ExecutorFunction.Callback := ExecuteIntegerShr;
|
---|
734 | end;
|
---|
735 | if ExecutorFunction.FunctionDef.Name = '_Shl' then begin
|
---|
736 | ExecutorFunction.Callback := ExecuteIntegerShl;
|
---|
737 | end;
|
---|
738 | end;
|
---|
739 | end;
|
---|
740 | end;
|
---|
741 |
|
---|
742 | for I := 0 to Block.Variables.Count - 1 do begin
|
---|
743 | ExecutorBlock.Variables.AddNew(TVariable(Block.Variables[I]));
|
---|
744 | end;
|
---|
745 |
|
---|
746 | for I := 0 to Block.Functions.Count - 1 do begin
|
---|
747 | ExecutorFunction := ExecutorBlock.Functions.AddNew(TFunction(Block.Functions[I]));
|
---|
748 | if ExecutorFunction.FunctionDef.Name = 'IntToStr' then begin
|
---|
749 | ExecutorFunction.Callback := ExecuteIntToStr;
|
---|
750 | end else
|
---|
751 | if ExecutorFunction.FunctionDef.Name = 'StrToInt' then begin
|
---|
752 | ExecutorFunction.Callback := ExecuteStrToInt;
|
---|
753 | end else
|
---|
754 | if ExecutorFunction.FunctionDef.Name = 'BoolToStr' then begin
|
---|
755 | ExecutorFunction.Callback := ExecuteBoolToStr;
|
---|
756 | end else
|
---|
757 | if ExecutorFunction.FunctionDef.Name = 'StrToBool' then begin
|
---|
758 | ExecutorFunction.Callback := ExecuteStrToBool;
|
---|
759 | end;
|
---|
760 | end;
|
---|
761 |
|
---|
762 | for I := 0 to Block.Procedures.Count - 1 do begin
|
---|
763 | ExecutorProcedure := ExecutorBlock.Procedures.AddNew(TProcedure(Block.Procedures[I]));
|
---|
764 | if ExecutorProcedure.ProcedureDef.Name = 'Write' then begin
|
---|
765 | ExecutorProcedure.Callback := ExecuteWrite;
|
---|
766 | end else
|
---|
767 | if ExecutorProcedure.ProcedureDef.Name = 'WriteLn' then begin
|
---|
768 | ExecutorProcedure.Callback := ExecuteWriteLn;
|
---|
769 | end else
|
---|
770 | if ExecutorProcedure.ProcedureDef.Name = 'Read' then begin
|
---|
771 | ExecutorProcedure.Callback := ExecuteRead;
|
---|
772 | end else
|
---|
773 | if ExecutorProcedure.ProcedureDef.Name = 'ReadLn' then begin
|
---|
774 | ExecutorProcedure.Callback := ExecuteReadLn;
|
---|
775 | end;
|
---|
776 | end;
|
---|
777 | end;
|
---|
778 |
|
---|
779 | procedure TExecutor.ExecuteProgram(Prog: TProgram);
|
---|
780 | begin
|
---|
781 | SystemBlock := TExecutorBlock.Create;
|
---|
782 | InitExecutorBlock(SystemBlock, Prog.SystemBlock);
|
---|
783 | ExecuteBlock(SystemBlock, Prog.Block);
|
---|
784 | SystemBlock.Free;
|
---|
785 | end;
|
---|
786 |
|
---|
787 | procedure TExecutor.ExecuteBeginEnd(Block: TExecutorBlock; BeginEnd: TBeginEnd);
|
---|
788 | var
|
---|
789 | I: Integer;
|
---|
790 | begin
|
---|
791 | for I := 0 to BeginEnd.Commands.Count - 1 do
|
---|
792 | ExecuteCommand(Block, BeginEnd.Commands[I]);
|
---|
793 | end;
|
---|
794 |
|
---|
795 | procedure TExecutor.ExecuteCommand(Block: TExecutorBlock; Command: TCommand);
|
---|
796 | begin
|
---|
797 | if Command is TBeginEnd then ExecuteBeginEnd(Block, TBeginEnd(Command))
|
---|
798 | else if Command is TFunctionCall then ExecuteFunctionCall(Block, TFunctionCall(Command))
|
---|
799 | else if Command is TProcedureCall then ExecuteProcedureCall(Block, TProcedureCall(Command))
|
---|
800 | else if Command is TAssignment then ExecuteAssignment(Block, TAssignment(Command))
|
---|
801 | else if Command is TIfThenElse then ExecuteIfThenElse(Block, TIfThenElse(Command))
|
---|
802 | else if Command is TWhileDo then ExecuteWhileDo(Block, TWhileDo(Command))
|
---|
803 | else if Command is TRepeatUntil then ExecuteRepeatUntil(Block, TRepeatUntil(Command))
|
---|
804 | else if Command is TForToDo then ExecuteForToDo(Block, TForToDo(Command))
|
---|
805 | else if Command is TBreak then ExecuteBreak(Block, TBreak(Command))
|
---|
806 | else if Command is TContinue then ExecuteContinue(Block, TContinue(Command))
|
---|
807 | else if Command is TEmptyCommand then
|
---|
808 | else raise Exception.Create(SUnsupportedCommandType);
|
---|
809 | end;
|
---|
810 |
|
---|
811 | procedure TExecutor.ExecuteIfThenElse(Block: TExecutorBlock;
|
---|
812 | IfThenElse: TIfThenElse);
|
---|
813 | var
|
---|
814 | Value: TValue;
|
---|
815 | begin
|
---|
816 | Value := ExecuteExpression(Block, IfThenElse.Expression);
|
---|
817 | if Value is TValueBoolean then begin
|
---|
818 | if TValueBoolean(Value).Value then ExecuteCommand(Block, IfThenElse.CommandThen)
|
---|
819 | else begin
|
---|
820 | if Assigned(IfThenElse.CommandElse) then
|
---|
821 | ExecuteCommand(Block, IfThenElse.CommandElse);
|
---|
822 | end;
|
---|
823 | end else raise Exception.Create(SExpectedBooleanValue);
|
---|
824 | FreeAndNil(Value);
|
---|
825 | end;
|
---|
826 |
|
---|
827 | procedure TExecutor.ExecuteWhileDo(Block: TExecutorBlock; WhileDo: TWhileDo);
|
---|
828 | var
|
---|
829 | Value: TValue;
|
---|
830 | BoolValue: Boolean;
|
---|
831 | begin
|
---|
832 | while True do begin
|
---|
833 | Value := ExecuteExpression(Block, WhileDo.Expression);
|
---|
834 | if Value is TValueBoolean then begin
|
---|
835 | BoolValue := TValueBoolean(Value).Value;
|
---|
836 | FreeAndNil(Value);
|
---|
837 | if not BoolValue then Break;
|
---|
838 | ExecuteCommand(Block, WhileDo.Command);
|
---|
839 | if WhileDo.DoContinue then begin
|
---|
840 | WhileDo.DoContinue := False;
|
---|
841 | Continue;
|
---|
842 | end;
|
---|
843 | if WhileDo.DoBreak then begin
|
---|
844 | WhileDo.DoBreak := False;
|
---|
845 | Break;
|
---|
846 | end;
|
---|
847 | end else raise Exception.Create(SExpectedBooleanValue);
|
---|
848 | end;
|
---|
849 | end;
|
---|
850 |
|
---|
851 | procedure TExecutor.ExecuteRepeatUntil(Block: TExecutorBlock;
|
---|
852 | RepeatUntil: TRepeatUntil);
|
---|
853 | var
|
---|
854 | Value: TValue;
|
---|
855 | I: Integer;
|
---|
856 | BoolValue: Boolean;
|
---|
857 | begin
|
---|
858 | while True do begin
|
---|
859 | for I := 0 to RepeatUntil.Commands.Count - 1 do begin
|
---|
860 | ExecuteCommand(Block, TCommand(RepeatUntil.Commands[I]));
|
---|
861 | if RepeatUntil.DoContinue then begin
|
---|
862 | RepeatUntil.DoContinue := False;
|
---|
863 | Continue;
|
---|
864 | end;
|
---|
865 | if RepeatUntil.DoBreak then begin
|
---|
866 | RepeatUntil.DoBreak := False;
|
---|
867 | Break;
|
---|
868 | end;
|
---|
869 | end;
|
---|
870 | Value := ExecuteExpression(Block, RepeatUntil.Expression);
|
---|
871 | if Value is TValueBoolean then begin
|
---|
872 | BoolValue := TValueBoolean(Value).Value;
|
---|
873 | FreeAndNil(Value);
|
---|
874 | if BoolValue then Break;
|
---|
875 | end else raise Exception.Create(SExpectedBooleanValue);
|
---|
876 | end;
|
---|
877 | end;
|
---|
878 |
|
---|
879 | procedure TExecutor.ExecuteForToDo(Block: TExecutorBlock; ForToDo: TForToDo);
|
---|
880 | var
|
---|
881 | Variable: TExecutorVariable;
|
---|
882 | Limit: TValue;
|
---|
883 | begin
|
---|
884 | Variable := Block.GetVariable(ForToDo.VariableRef);
|
---|
885 | Variable.Value := ExecuteExpression(Block, ForToDo.ExpressionFrom);
|
---|
886 | Limit := ExecuteExpression(Block, ForToDo.ExpressionTo);
|
---|
887 | while True do begin
|
---|
888 | ExecuteCommand(Block, ForToDo.Command);
|
---|
889 | if ForToDo.DoContinue then begin
|
---|
890 | ForToDo.DoContinue := False;
|
---|
891 | Continue;
|
---|
892 | end;
|
---|
893 | if ForToDo.DoBreak then begin
|
---|
894 | ForToDo.DoBreak := False;
|
---|
895 | Break;
|
---|
896 | end;
|
---|
897 | TValueInteger(Variable.Value).Value := TValueInteger(Variable.Value).Value + 1;
|
---|
898 | if TValueInteger(Variable.Value).Value > TValueInteger(Limit).Value then Break;
|
---|
899 | end;
|
---|
900 | Limit.Free;
|
---|
901 | end;
|
---|
902 |
|
---|
903 | procedure TExecutor.ExecuteContinue(Block: TExecutorBlock;
|
---|
904 | ContinueCmd: TContinue);
|
---|
905 | var
|
---|
906 | Node: TSourceNode;
|
---|
907 | begin
|
---|
908 | Node := ContinueCmd.Parent;
|
---|
909 | while Assigned(Node) and not (Node is TLoop) and Assigned(Node.Parent) do
|
---|
910 | Node := Node.Parent;
|
---|
911 |
|
---|
912 | if Node is TLoop then TLoop(Node).DoContinue := True
|
---|
913 | else raise Exception.Create('Break used outside of loop.');
|
---|
914 | end;
|
---|
915 |
|
---|
916 | procedure TExecutor.ExecuteBreak(Block: TExecutorBlock; BreakCmd: TBreak);
|
---|
917 | var
|
---|
918 | Node: TSourceNode;
|
---|
919 | begin
|
---|
920 | Node := BreakCmd.Parent;
|
---|
921 | while Assigned(Node) and not (Node is TLoop) and Assigned(Node.Parent) do
|
---|
922 | Node := Node.Parent;
|
---|
923 |
|
---|
924 | if Node is TLoop then TLoop(Node).DoBreak := True
|
---|
925 | else raise Exception.Create('Break used outside of loop.');
|
---|
926 | end;
|
---|
927 |
|
---|
928 | procedure TExecutor.ExecuteBlock(ParentBlock: TExecutorBlock; Block: TBlock; ExistingBlock: TExecutorBlock = nil);
|
---|
929 | var
|
---|
930 | ExecutorBlock: TExecutorBlock;
|
---|
931 | begin
|
---|
932 | if Assigned(ExistingBlock) then begin
|
---|
933 | ExecutorBlock := ExistingBlock
|
---|
934 | end else begin
|
---|
935 | ExecutorBlock := TExecutorBlock.Create;
|
---|
936 | InitExecutorBlock(ExecutorBlock, Block);
|
---|
937 | end;
|
---|
938 | ExecutorBlock.Parent := ParentBlock;
|
---|
939 | ExecuteBeginEnd(ExecutorBlock, Block.BeginEnd);
|
---|
940 | if not Assigned(ExistingBlock) then ExecutorBlock.Free;
|
---|
941 | end;
|
---|
942 |
|
---|
943 | function TExecutor.ExecuteFunctionCall(Block: TExecutorBlock;
|
---|
944 | FunctionCall: TFunctionCall): TValue;
|
---|
945 | var
|
---|
946 | ExecutorFunction: TExecutorFunction;
|
---|
947 | Params: array of TExecutorVariable;
|
---|
948 | I: Integer;
|
---|
949 | ExecutorVariable: TExecutorVariable;
|
---|
950 | Variable: TVariable;
|
---|
951 | begin
|
---|
952 | Result := nil;
|
---|
953 | ExecutorFunction := Block.GetFunction(FunctionCall.FunctionDef);
|
---|
954 | if Assigned(ExecutorFunction) then begin
|
---|
955 | InitExecutorBlock(ExecutorFunction.Block, FunctionCall.FunctionDef.Block);
|
---|
956 |
|
---|
957 | // Setup variables
|
---|
958 | for I := 0 to FunctionCall.Params.Count - 1 do begin
|
---|
959 | Variable := FunctionCall.FunctionDef.Block.Variables.SearchByName(
|
---|
960 | TFunctionParameter(FunctionCall.FunctionDef.Params[I]).Name);
|
---|
961 | ExecutorVariable := ExecutorFunction.Block.Variables.SearchByVariable(Variable);
|
---|
962 | if FunctionCall.FunctionDef.Params[I].Kind = pkVar then begin
|
---|
963 | ExecutorVariable.Kind := vkReference;
|
---|
964 | Variable := TExpressionOperand(FunctionCall.Params[I]).VariableRef;
|
---|
965 | ExecutorVariable.RefVariable := Block.Variables.SearchByVariable(Variable);
|
---|
966 | end else begin
|
---|
967 | ExecutorVariable.Kind := vkNormal;
|
---|
968 | ExecutorVariable.Value := ExecuteExpression(Block, TExpression(FunctionCall.Params[I]));
|
---|
969 | end;
|
---|
970 | end;
|
---|
971 |
|
---|
972 | if FunctionCall.FunctionDef.InternalName <> '' then begin
|
---|
973 | SetLength(Params, FunctionCall.Params.Count);
|
---|
974 | for I := 0 to FunctionCall.Params.Count - 1 do begin
|
---|
975 | Variable := FunctionCall.FunctionDef.Block.Variables.SearchByName(
|
---|
976 | TFunctionParameter(FunctionCall.FunctionDef.Params[I]).Name);
|
---|
977 | Params[I] := ExecutorFunction.Block.Variables.SearchByVariable(Variable);
|
---|
978 | end;
|
---|
979 | Result := ExecutorFunction.Callback(Params);
|
---|
980 | end else begin
|
---|
981 | ExecuteBlock(Block, FunctionCall.FunctionDef.Block, ExecutorFunction.Block);
|
---|
982 | ExecutorVariable := ExecutorFunction.Block.Variables.SearchByVariable(
|
---|
983 | TVariable(FunctionCall.FunctionDef.Block.Variables.SearchByName('Result')));
|
---|
984 | Result := ExecutorVariable.Value.Clone;
|
---|
985 | end;
|
---|
986 | end else raise Exception.Create('No executor for ' + FunctionCall.FunctionDef.Name + ' function.');
|
---|
987 | end;
|
---|
988 |
|
---|
989 | procedure TExecutor.ExecuteProcedureCall(Block: TExecutorBlock;
|
---|
990 | ProcedureCall: TProcedureCall);
|
---|
991 | var
|
---|
992 | ExecutorProcedure: TExecutorProcedure;
|
---|
993 | Params: array of TExecutorVariable;
|
---|
994 | I: Integer;
|
---|
995 | ExecutorVariable: TExecutorVariable;
|
---|
996 | Variable: TVariable;
|
---|
997 | ProcedureDef: TProcedure;
|
---|
998 | begin
|
---|
999 | ExecutorProcedure := Block.GetProcedure(ProcedureCall.ProcedureDef);
|
---|
1000 | if Assigned(ExecutorProcedure) then begin
|
---|
1001 | ProcedureDef := ProcedureCall.ProcedureDef;
|
---|
1002 | InitExecutorBlock(ExecutorProcedure.Block, ProcedureDef.Block);
|
---|
1003 |
|
---|
1004 | for I := 0 to ProcedureCall.Params.Count - 1 do begin
|
---|
1005 | Variable := ProcedureCall.ProcedureDef.Block.Variables.SearchByName(
|
---|
1006 | TFunctionParameter(ProcedureCall.ProcedureDef.Params[I]).Name);
|
---|
1007 | ExecutorVariable := ExecutorProcedure.Block.Variables.SearchByVariable(Variable);
|
---|
1008 | if ProcedureCall.ProcedureDef.Params[I].Kind = pkVar then begin
|
---|
1009 | ExecutorVariable.Kind := vkReference;
|
---|
1010 | Variable := TExpressionOperand(ProcedureCall.Params[I]).VariableRef;
|
---|
1011 | ExecutorVariable.RefVariable := Block.GetVariable(Variable);
|
---|
1012 | end else begin
|
---|
1013 | ExecutorVariable.Kind := vkNormal;
|
---|
1014 | ExecutorVariable.Value := ExecuteExpression(Block, TExpression(ProcedureCall.Params[I]));
|
---|
1015 | end;
|
---|
1016 | end;
|
---|
1017 |
|
---|
1018 | if ProcedureCall.ProcedureDef.InternalName <> '' then begin
|
---|
1019 | SetLength(Params, ProcedureCall.Params.Count);
|
---|
1020 | for I := 0 to ProcedureCall.Params.Count - 1 do begin
|
---|
1021 | Variable := ProcedureCall.ProcedureDef.Block.Variables.SearchByName(
|
---|
1022 | TFunctionParameter(ProcedureCall.ProcedureDef.Params[I]).Name);
|
---|
1023 | ExecutorVariable := ExecutorProcedure.Block.Variables.SearchByVariable(Variable);
|
---|
1024 | Params[I] := ExecutorVariable;
|
---|
1025 | end;
|
---|
1026 |
|
---|
1027 | ExecutorProcedure.Callback(Params);
|
---|
1028 | end else begin
|
---|
1029 | ExecuteBlock(Block, ProcedureCall.ProcedureDef.Block, ExecutorProcedure.Block);
|
---|
1030 | end;
|
---|
1031 | end else raise Exception.Create('No executor for ' + ProcedureCall.ProcedureDef.Name + ' function.');
|
---|
1032 | end;
|
---|
1033 |
|
---|
1034 | procedure TExecutor.ExecuteAssignment(Block: TExecutorBlock;
|
---|
1035 | Assignment: TAssignment);
|
---|
1036 | var
|
---|
1037 | Value: TValue;
|
---|
1038 | Variable: TExecutorVariable;
|
---|
1039 | ExecutorFunction: TExecutorFunction;
|
---|
1040 | Params: array of TExecutorVariable;
|
---|
1041 | begin
|
---|
1042 | Value := ExecuteExpression(Block, Assignment.Expression);
|
---|
1043 | Variable := Block.GetVariable(Assignment.Variable);
|
---|
1044 | ExecutorFunction := Block.GetTypeFunction(Assignment.Variable.TypeRef, '_Assign');
|
---|
1045 | if Assignment.Variable.TypeRef = Assignment.Expression.GetType then begin
|
---|
1046 | SetLength(Params, 1);
|
---|
1047 | Params[0] := TExecutorVariable.Create;
|
---|
1048 | Params[0].Value := Value;
|
---|
1049 | Variable.Value := ExecutorFunction.Callback(Params);
|
---|
1050 | end else raise Exception('Assignment result type is ' + Variable.Variable.TypeRef.Name +
|
---|
1051 | ' but value is ' + Assignment.Expression.GetType.Name + '.');
|
---|
1052 | FreeAndNil(Value);
|
---|
1053 | end;
|
---|
1054 |
|
---|
1055 | function TExecutor.ExecuteExpression(Block: TExecutorBlock;
|
---|
1056 | Expression: TExpression): TValue;
|
---|
1057 | begin
|
---|
1058 | if Expression is TExpressionOperation then
|
---|
1059 | Result := ExecuteExpressionOperation(Block, TExpressionOperation(Expression))
|
---|
1060 | else
|
---|
1061 | if Expression is TExpressionOperand then
|
---|
1062 | Result := ExecuteExpressionOperand(Block, TExpressionOperand(Expression))
|
---|
1063 | else
|
---|
1064 | if Expression is TExpressionBrackets then
|
---|
1065 | Result := ExecuteExpressionBrackets(Block, TExpressionBrackets(Expression))
|
---|
1066 | else
|
---|
1067 | raise Exception.Create('Unknown expression class.');
|
---|
1068 | end;
|
---|
1069 |
|
---|
1070 | function TExecutor.ExecuteExpressionOperation(Block: TExecutorBlock;
|
---|
1071 | Expression: TExpressionOperation): TValue;
|
---|
1072 | var
|
---|
1073 | I: Integer;
|
---|
1074 | Value: TValue;
|
---|
1075 | ExecutorFunction: TExecutorFunction;
|
---|
1076 | Params: array of TExecutorVariable;
|
---|
1077 | FuncName: string;
|
---|
1078 | begin
|
---|
1079 | FuncName := Expression.GetFunctionName;
|
---|
1080 |
|
---|
1081 | ExecutorFunction := Block.GetTypeFunction(Expression.FunctionRef.ParentType, FuncName);
|
---|
1082 | if not Assigned(ExecutorFunction) then
|
---|
1083 | raise Exception.Create('Missing operator function ' + FuncName + ' for type ' + Expression.TypeRef.Name);
|
---|
1084 |
|
---|
1085 | SetLength(Params, Expression.Items.Count);
|
---|
1086 | for I := 0 to Expression.Items.Count - 1 do begin
|
---|
1087 | Value := ExecuteExpression(Block, TExpression(Expression.Items[I]));
|
---|
1088 | Params[I] := TExecutorVariable.Create;
|
---|
1089 | Params[I].Value := Value;
|
---|
1090 | end;
|
---|
1091 | Result := ExecutorFunction.Callback(Params);
|
---|
1092 | for I := 0 to Expression.Items.Count - 1 do begin
|
---|
1093 | Params[I].Free;
|
---|
1094 | end;
|
---|
1095 | end;
|
---|
1096 |
|
---|
1097 | function TExecutor.ExecuteExpressionOperand(Block: TExecutorBlock;
|
---|
1098 | Expression: TExpressionOperand): TValue;
|
---|
1099 | begin
|
---|
1100 | case Expression.OperandType of
|
---|
1101 | otFunctionCall: Result := ExecuteFunctionCall(Block, Expression.FunctionCall);
|
---|
1102 | otConstantDirect: Result := Expression.ConstantDirect.Value.Clone;
|
---|
1103 | otConstantRef: Result := Expression.ConstantRef.Value.Clone;
|
---|
1104 | otVariableRef: Result := Block.Variables.SearchByVariable(Expression.VariableRef).Value.Clone;
|
---|
1105 | else raise Exception.Create(SUnsupportedOperandType);
|
---|
1106 | end;
|
---|
1107 | end;
|
---|
1108 |
|
---|
1109 | function TExecutor.ExecuteExpressionBrackets(Block: TExecutorBlock;
|
---|
1110 | Expression: TExpressionBrackets): TValue;
|
---|
1111 | begin
|
---|
1112 | Result := ExecuteExpression(Block, Expression.Expression);
|
---|
1113 | end;
|
---|
1114 |
|
---|
1115 | procedure TExecutor.Run;
|
---|
1116 | begin
|
---|
1117 | ExecuteProgram(Prog);
|
---|
1118 | end;
|
---|
1119 |
|
---|
1120 | procedure TExecutor.Output(Text: string);
|
---|
1121 | begin
|
---|
1122 | if Assigned(FOnOutput) then
|
---|
1123 | FOnOutput(Text);
|
---|
1124 | end;
|
---|
1125 |
|
---|
1126 | function TExecutor.Input: string;
|
---|
1127 | begin
|
---|
1128 | if Assigned(FOnInput) then
|
---|
1129 | Result := FOnInput;
|
---|
1130 | end;
|
---|
1131 |
|
---|
1132 | end.
|
---|
1133 |
|
---|