Changeset 221
- Timestamp:
- Nov 24, 2020, 6:19:17 PM (4 years ago)
- Location:
- branches/interpreter2
- Files:
-
- 3 added
- 7 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
branches/interpreter2/Forms/UFormMain.lfm
r213 r221 13 13 OnDestroy = FormDestroy 14 14 OnShow = FormShow 15 LCLVersion = '2.0. 2.0'15 LCLVersion = '2.0.10.0' 16 16 object PanelMessages: TPanel 17 17 Left = 0 … … 48 48 end 49 49 object MainMenu1: TMainMenu 50 left = 79051 top = 75350 Left = 790 51 Top = 753 52 52 object MenuItemFile: TMenuItem 53 53 Caption = 'File' … … 82 82 end 83 83 object ActionList1: TActionList 84 left = 90185 top = 75984 Left = 901 85 Top = 759 86 86 object AGeneratePascal: TAction 87 87 Caption = 'Generate Pascal' -
branches/interpreter2/Forms/UFormMain.pas
r213 r221 70 70 uses 71 71 UParser, UExecutor, UGeneratorPascal, UGeneratorPhp, UFormMessages, UFormSource, 72 UGeneratorCSharp, UGeneratorXml, UFormOutput ;72 UGeneratorCSharp, UGeneratorXml, UFormOutput, UParserPascal; 73 73 74 74 { TFormMain } … … 111 111 begin 112 112 FormMessages.Clear; 113 Parser := TParser .Create;113 Parser := TParserPascal.Create; 114 114 Parser.OnError := InterpreterError; 115 115 Parser.Source := FormSource.SynEditSource.Lines.Text; -
branches/interpreter2/UExecutor.pas
r214 r221 138 138 destructor TExecutorFunction.Destroy; 139 139 begin 140 Block.Free;141 inherited Destroy;140 FreeAndNil(Block); 141 inherited; 142 142 end; 143 143 … … 151 151 destructor TExecutorVariable.Destroy; 152 152 begin 153 Value.Free;154 inherited Destroy;153 FreeAndNil(Value); 154 inherited; 155 155 end; 156 156 … … 164 164 destructor TExecutorType.Destroy; 165 165 begin 166 F unctions.Free;167 inherited Destroy;166 FreeAndNil(Functions); 167 inherited; 168 168 end; 169 169 … … 273 273 destructor TExecutorBlock.Destroy; 274 274 begin 275 Variables.Free;276 F unctions.Free;277 Types.Free;278 inherited Destroy;275 FreeAndNil(Variables); 276 FreeAndNil(Functions); 277 FreeAndNil(Types); 278 inherited; 279 279 end; 280 280 … … 513 513 var 514 514 Value: TValue; 515 BoolValue: Boolean; 515 516 begin 516 517 while True do begin 517 518 Value := ExecuteExpression(Block, WhileDo.Expression); 518 519 if Value is TValueBoolean then begin 519 if not TValueBoolean(Value).Value then Break; 520 BoolValue := TValueBoolean(Value).Value; 521 Value.Free; 522 if not BoolValue then Break; 520 523 ExecuteCommand(Block, WhileDo.Command); 521 524 if WhileDo.DoContinue then begin … … 528 531 end; 529 532 end else raise Exception.Create('Expected boolean value.'); 530 Value.Free;531 533 end; 532 534 end; … … 537 539 Value: TValue; 538 540 I: Integer; 541 BoolValue: Boolean; 539 542 begin 540 543 while True do begin … … 552 555 Value := ExecuteExpression(Block, RepeatUntil.Expression); 553 556 if Value is TValueBoolean then begin 554 if TValueBoolean(Value).Value then Break; 557 BoolValue := TValueBoolean(Value).Value; 558 Value.Free; 559 if BoolValue then Break; 555 560 end else raise Exception.Create('Expected boolean value.'); 556 Value.Free;557 561 end; 558 562 end; … … 654 658 ExecuteBlock(Block, FunctionCall.FunctionDef.Block, ExecutorFunction.Block); 655 659 ExecutorVariable := ExecutorFunction.Block.Variables.SearchByVariable(TVariable(FunctionCall.FunctionDef.Block.Variables.SearchByName('Result'))); 656 Result := ExecutorVariable.Value ;660 Result := ExecutorVariable.Value.Clone; 657 661 end; 658 662 end else raise Exception.Create('No executor for ' + FunctionCall.FunctionDef.Name + ' function.'); … … 706 710 raise Exception.Create('Missing operator function ' + FuncName + ' for type ' + Expression.TypeRef.Name); 707 711 708 Result := Expression.TypeRef.ValueClass.Create;709 710 712 SetLength(Params, Expression.Items.Count); 711 713 for I := 0 to Expression.Items.Count - 1 do begin -
branches/interpreter2/UParser.pas
r212 r221 15 15 private 16 16 FOnError: TErrorEvent; 17 Tokenizer: TTokenizer;18 function ParseBeginEnd(Block: TBlock; out BeginEnd: TBeginEnd): Boolean;19 function ParseFunctionCall(Block: TBlock; out FunctionCall: TFunctionCall): Boolean;20 function ParseCommand(Block: TBlock; out Command: TCommand): Boolean;21 function ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean;22 function ParseBlock(ParentBlock: TBlock; out Block: TBlock; ExistingBlock: TBlock = nil): Boolean;23 function ParseBlockVar(Block: TBlock): Boolean;24 function ParseBlockConst(Block: TBlock): Boolean;25 function ParseFunction(Block: TBlock; out Func: TFunction): Boolean;26 function ParseFunctionParameter(Block: TBlock; out Parameter: TFunctionParameter): Boolean;27 function ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean;28 function ParseExpression(Block: TBlock; out Expression: TExpression): Boolean;29 function ParseExpressionOperation(Block: TBlock; out ExpressionOperation: TExpressionOperation): Boolean;30 function ParseExpressionOperand(Block: TBlock; out ExpressionOperand: TExpressionOperand): Boolean;31 function ParseConstantRef(Block: TBlock; out ConstantRef: TConstant): Boolean;32 function ParseConstant(Block: TBlock; out ConstantRef: TConstant): Boolean;33 function ParseVariable(Block: TBlock; out VariableRef: TVariable): Boolean;34 function ParseIfThenElse(Block: TBlock; out IfThenElse: TIfThenElse): Boolean;35 function ParseWhileDo(Block: TBlock; out WhileDo: TWhileDo): Boolean;36 function ParseRepeatUntil(Block: TBlock; out RepeatUntil: TRepeatUntil): Boolean;37 function ParseForToDo(Block: TBlock; out ForToDo: TForToDo): Boolean;38 function ParseBreak(Block: TBlock; out BreakCmd: TBreak): Boolean;39 function ParseContinue(Block: TBlock; out ContinueCmd: TContinue): Boolean;40 17 procedure TokenizerError(Pos: TPoint; Text: string); 41 18 procedure InitSystemBlock(Block: TBlock); 19 protected 20 Tokenizer: TTokenizer; 21 function ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean; virtual; 42 22 public 43 23 Source: string; … … 54 34 55 35 { TParser } 56 57 function TParser.ParseBeginEnd(Block: TBlock; out BeginEnd: TBeginEnd): Boolean;58 var59 Command: TCommand;60 begin61 if Tokenizer.CheckNext('begin', tkKeyword) then begin62 Tokenizer.Expect('begin', tkKeyword);63 BeginEnd := TBeginEnd.Create;64 Result := True;65 while not Tokenizer.CheckNext('end', tkKeyword) do begin66 if ParseCommand(Block, Command) then begin67 Command.Parent := BeginEnd;68 BeginEnd.Commands.Add(Command);69 Tokenizer.Expect(';', tkSpecialSymbol);70 end else begin71 Error('Unexpected token ' + Tokenizer.GetNext.Text);72 Result := False;73 Break;74 end;75 end;76 Tokenizer.Expect('end', tkKeyword);77 end else Result := False;78 end;79 80 function TParser.ParseFunctionCall(Block: TBlock; out FunctionCall: TFunctionCall81 ): Boolean;82 var83 Token: TToken;84 LastPos: TTokenizerPos;85 FunctionDef: TFunction;86 Expression: TExpression;87 I: Integer;88 begin89 LastPos := Tokenizer.Pos;90 Token := Tokenizer.GetNext;91 if Token.Kind = tkIdentifier then begin92 FunctionDef := Block.GetFunction(Token.Text);93 if Assigned(FunctionDef) then begin94 FunctionCall := TFunctionCall.Create;95 FunctionCall.FunctionDef := FunctionDef;96 if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin97 Tokenizer.Expect('(', tkSpecialSymbol);98 for I := 0 to FunctionDef.Params.Count - 1 do begin99 if I > 0 then Tokenizer.Expect(',', tkSpecialSymbol);100 if ParseExpression(Block, Expression) then begin101 if Expression.GetType = TFunctionParameter(FunctionDef.Params[I]).TypeRef then102 FunctionCall.Params.Add(Expression)103 else Error('Function parameter mismatch.');104 end else Error('Expected function parameter.');105 end;106 Tokenizer.Expect(')', tkSpecialSymbol);107 end;108 Result := True;109 end else begin110 Result := False;111 Tokenizer.Pos := LastPos;112 end;113 end else begin114 Result := False;115 Tokenizer.Pos := LastPos;116 end;117 end;118 119 function TParser.ParseCommand(Block: TBlock; out Command: TCommand): Boolean;120 var121 BeginEnd: TBeginEnd;122 FunctionCall: TFunctionCall;123 Assignment: TAssignment;124 IfThenElse: TIfThenElse;125 WhileDo: TWhileDo;126 ForToDo: TForToDo;127 RepeatUntil: TRepeatUntil;128 BreakCmd: TBreak;129 ContinueCmd: TContinue;130 begin131 if ParseIfThenElse(Block, IfThenElse) then begin132 Result := True;133 Command := IfThenElse;134 end else135 if ParseWhileDo(Block, WhileDo) then begin136 Result := True;137 Command := WhileDo;138 end else139 if ParseForToDo(Block, ForToDo) then begin140 Result := True;141 Command := ForToDo;142 end else143 if ParseBeginEnd(Block, BeginEnd) then begin144 Result := True;145 Command := BeginEnd;146 end else147 if ParseFunctionCall(Block, FunctionCall) then begin148 Result := True;149 Command := FunctionCall;150 end else151 if ParseRepeatUntil(Block, RepeatUntil) then begin152 Result := True;153 Command := RepeatUntil;154 end else155 if ParseAssignment(Block, Assignment) then begin156 Result := True;157 Command := Assignment;158 end else159 if ParseBreak(Block, BreakCmd) then begin160 Result := True;161 Command := BreakCmd;162 end else163 if ParseContinue(Block, ContinueCmd) then begin164 Result := True;165 Command := ContinueCmd;166 end else167 Result := False;168 end;169 170 function TParser.ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean;171 var172 Block: TBlock;173 Token: TToken;174 begin175 Result := False;176 Prog := TProgram.Create;177 Prog.SystemBlock.Free;178 Prog.SystemBlock := SystemBlock;179 if Tokenizer.CheckNext('program', tkKeyword) then begin180 Tokenizer.Expect('program', tkKeyword);181 Token := Tokenizer.GetNext;182 if Token.Kind = tkIdentifier then183 Prog.Name := Token.Text;184 Tokenizer.Expect(';', tkSpecialSymbol);185 end;186 if ParseBlock(SystemBlock, Block) then begin187 Result := True;188 Prog.Block.Free;189 Prog.Block := Block;190 Block.Parent := Prog;191 Tokenizer.Expect('.', tkSpecialSymbol);192 end else begin193 FreeAndNil(Prog);194 Error('Expected begin-end block.');195 end;196 end;197 198 function TParser.ParseBlock(ParentBlock: TBlock; out Block: TBlock; ExistingBlock: TBlock = nil): Boolean;199 var200 BeginEnd: TBeginEnd;201 Func: TFunction;202 begin203 Result := False;204 if Assigned(ExistingBlock) then Block := ExistingBlock205 else Block := TBlock.Create;206 Block.ParentBlock := ParentBlock;207 while True do begin208 if ParseBlockVar(Block) then begin209 end else210 if ParseBlockConst(Block) then begin211 end else212 if ParseFunction(Block, Func) then begin213 Block.Functions.Add(Func);214 end else begin215 Break;216 end;217 end;218 if ParseBeginEnd(Block, BeginEnd) then begin219 Result := True;220 Block.BeginEnd.Free;221 Block.BeginEnd := BeginEnd;222 BeginEnd.Parent := Block;223 end else begin224 if not Assigned(ExistingBlock) then Block.Free;225 Block := nil;226 end;227 end;228 229 function TParser.ParseBlockVar(Block: TBlock): Boolean;230 var231 Token: TToken;232 Variable: TVariable;233 TypeRef: TType;234 begin235 if Tokenizer.CheckNext('var', tkKeyword) then begin236 Result := True;237 Tokenizer.Expect('var', tkKeyword);238 while Tokenizer.CheckNextKind(tkIdentifier) do begin239 Token := Tokenizer.GetNext;240 if Token.Kind = tkIdentifier then begin241 Variable := Block.Variables.SearchByName(Token.Text);242 if not Assigned(Variable) then begin243 Variable := TVariable.Create;244 Variable.Name := Token.Text;245 Block.Variables.Add(Variable);246 Tokenizer.Expect(':', tkSpecialSymbol);247 Token := Tokenizer.GetNext;248 if Token.Kind = tkIdentifier then begin249 TypeRef := Block.GetType(Token.Text);250 if Assigned(TypeRef) then begin251 Variable.TypeRef := TypeRef;252 end else Error('Type ' + Token.Text + ' not found.');253 end;254 end else Error('Variable ' + Token.Text + ' redefined.');255 Tokenizer.Expect(';', tkSpecialSymbol);256 end else begin257 Error('Expected variable name but ' + Token.Text + ' found.');258 Break;259 end;260 end;261 end else Result := False;262 end;263 264 function TParser.ParseBlockConst(Block: TBlock): Boolean;265 var266 Token: TToken;267 Constant: TConstant;268 TypeRef: TType;269 begin270 if Tokenizer.CheckNext('const', tkKeyword) then begin271 Result := True;272 Tokenizer.Expect('const', tkKeyword);273 while Tokenizer.CheckNextKind(tkIdentifier) do begin274 Token := Tokenizer.GetNext;275 if Token.Kind = tkIdentifier then begin276 Constant := Block.Constants.SearchByName(Token.Text);277 if not Assigned(Constant) then begin278 Constant := TConstant.Create;279 Constant.Name := Token.Text;280 Block.Constants.Add(Constant);281 Tokenizer.Expect(':', tkSpecialSymbol);282 Token := Tokenizer.GetNext;283 if Token.Kind = tkIdentifier then begin284 TypeRef := Block.GetType(Token.Text);285 if Assigned(TypeRef) then begin286 Constant.TypeRef := TypeRef;287 end else Error('Type ' + Token.Text + ' not found.');288 end;289 Tokenizer.Expect('=', tkSpecialSymbol);290 Token := Tokenizer.GetNext;291 if Token.Kind = tkNumber then begin292 Constant.Value := TValueInteger.Create;293 TValueInteger(Constant.Value).Value := StrToInt(Token.Text);294 end else295 if Token.Kind = tkString then begin296 Constant.Value := TValueString.Create;297 TValueString(Constant.Value).Value := Token.Text;298 end else Error('Expected string or number.');299 end else Error('Constant ' + Token.Text + ' redefined.');300 Tokenizer.Expect(';', tkSpecialSymbol);301 end else begin302 Error('Expected constant name but ' + Token.Text + ' found.');303 Break;304 end;305 end;306 end else Result := False;307 end;308 309 function TParser.ParseFunction(Block: TBlock; out Func: TFunction): Boolean;310 var311 Token: TToken;312 FunctionParameter: TFunctionParameter;313 NewBlock: TBlock;314 TypeRef: TType;315 Variable: TVariable;316 I: Integer;317 begin318 Result := False;319 if Tokenizer.CheckNext('function', tkKeyword) then begin320 Tokenizer.Expect('function', tkKeyword);321 Result := True;322 Func := TFunction.Create;323 Token := Tokenizer.GetNext;324 if Token.Kind = tkIdentifier then begin325 Func.Name := Token.Text;326 if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin327 Tokenizer.Expect('(', tkSpecialSymbol);328 while not Tokenizer.CheckNext(')', tkSpecialSymbol) do begin329 if Func.Params.Count > 0 then Tokenizer.Expect(',', tkSpecialSymbol);330 if ParseFunctionParameter(Block, FunctionParameter) then begin331 Func.Params.Add(FunctionParameter);332 end else Error('Expected function parameter.');333 end;334 Tokenizer.Expect(')', tkSpecialSymbol);335 for I := 0 to Func.Params.Count - 1 do begin336 Variable := TVariable.Create;337 Variable.Name := TFunctionParameter(Func.Params[I]).Name;338 Variable.TypeRef := TFunctionParameter(Func.Params[I]).TypeRef;339 Variable.Internal := True;340 Func.Block.Variables.Add(Variable);341 end;342 end;343 if Tokenizer.CheckNext(':', tkSpecialSymbol) then begin344 Tokenizer.Expect(':', tkSpecialSymbol);345 Token := Tokenizer.GetNext;346 if Token.Kind = tkIdentifier then begin347 TypeRef := Block.GetType(Token.Text);348 if Assigned(TypeRef) then begin349 Func.ResultType := TypeRef;350 Variable := TVariable.Create;351 Variable.Name := 'Result';352 Variable.TypeRef := TypeRef;353 Variable.Internal := True;354 Func.Block.Variables.Add(Variable);355 end else Error('Type ' + Token.Text + ' not found');356 end;357 end;358 Tokenizer.Expect(';', tkSpecialSymbol);359 if ParseBlock(Block, NewBlock, Func.Block) then begin360 Tokenizer.Expect(';', tkSpecialSymbol);361 end else Error('Expected function block');362 end else Error('Expected function name');363 end;364 end;365 366 function TParser.ParseFunctionParameter(Block: TBlock; out Parameter: TFunctionParameter367 ): Boolean;368 var369 Token: TToken;370 TypeRef: TType;371 begin372 Result := True;373 Token := Tokenizer.GetNext;374 if Token.Kind = tkIdentifier then begin375 Parameter := TFunctionParameter.Create;376 Parameter.Name := Token.Text;377 Tokenizer.Expect(':', tkSpecialSymbol);378 Token := Tokenizer.GetNext;379 if Token.Kind = tkIdentifier then begin380 TypeRef := Block.GetType(Token.Text);381 if Assigned(TypeRef) then begin382 Parameter.TypeRef := TypeRef;383 end else Error('Type ' + Token.Text + ' not found');384 end else Error('Expected parameter type');385 end else Error('Expected parameter name');386 end;387 388 function TParser.ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean;389 var390 Token: TToken;391 Variable: TVariable;392 Expression: TExpression;393 LastPos: TTokenizerPos;394 begin395 LastPos := Tokenizer.Pos;396 Result := False;397 Token := Tokenizer.GetNext;398 if Token.Kind = tkIdentifier then begin399 Variable := Block.GetVariable(Token.Text);400 if Assigned(Variable) then begin401 Result := True;402 Assignment := TAssignment.Create;403 Assignment.Variable := Variable;404 Tokenizer.Expect(':=', tkSpecialSymbol);405 if ParseExpression(Block, Expression) then begin406 if Expression.GetType = Variable.TypeRef then begin407 Assignment.Expression.Free;408 Assignment.Expression := Expression;409 Expression.Parent := Assignment;410 end else begin411 Result := False;412 Error('Assignment type mismatch. Expected ' + Variable.TypeRef.Name + ' but got ' + Expression.GetType.Name);413 end;414 end;415 if not Result then Assignment.Free;416 end else Error('Variable ' + Token.Text + ' not defined.');417 end;418 if not Result then Tokenizer.Pos := LastPos;419 end;420 421 function TParser.ParseExpression(Block: TBlock; out Expression: TExpression422 ): Boolean;423 var424 ExpressionOperation: TExpressionOperation;425 ExpressionOperand: TExpressionOperand;426 begin427 Result := False;428 if ParseExpressionOperation(Block, ExpressionOperation) then begin429 Result := True;430 Expression := ExpressionOperation;431 end else432 if ParseExpressionOperand(Block, ExpressionOperand) then begin433 Result := True;434 Expression := ExpressionOperand;435 end;436 end;437 438 function TParser.ParseExpressionOperation(Block: TBlock; out439 ExpressionOperation: TExpressionOperation): Boolean;440 var441 Operand: TExpressionOperand;442 Token: TToken;443 Expression: TExpression;444 LastPos: TTokenizerPos;445 I: Integer;446 ExpectedType: TType;447 begin448 Result := False;449 LastPos := Tokenizer.Pos;450 if ParseExpressionOperand(Block, Operand) then begin451 Token := Tokenizer.GetNext;452 if (Token.Kind = tkSpecialSymbol) and Tokenizer.IsOperator(Token.Text) then begin453 Result := True;454 ExpressionOperation := TExpressionOperation.Create;455 ExpressionOperation.TypeRef := Operand.GetType;456 if Token.Text = '+' then ExpressionOperation.Operation := eoAdd457 else if Token.Text = '-' then ExpressionOperation.Operation := eoSub458 else if Token.Text = '=' then ExpressionOperation.Operation := eoEqual459 else if Token.Text = '<>' then ExpressionOperation.Operation := eoNotEqual460 else Error('Unsupported operator ' + Token.Text);461 ExpressionOperation.FunctionRef := ExpressionOperation.TypeRef.Functions.SearchByName(ExpressionOperation.GetFunctionName);462 if not Assigned(ExpressionOperation.FunctionRef.ResultType) then463 raise Exception.Create('Missing result type for function');464 ExpressionOperation.TypeRef := ExpressionOperation.FunctionRef.ResultType;465 ExpressionOperation.Items.Add(Operand);466 I := 1;467 if ParseExpression(Block, Expression) then begin468 ExpectedType := TFunctionParameter(ExpressionOperation.FunctionRef.Params[I]).TypeRef;469 if Expression.GetType = ExpectedType then470 ExpressionOperation.Items.Add(Expression)471 else Error('Expression operands needs to be same type. Expected ' + ExpectedType.Name + ' but found ' + Expression.GetType.Name);472 end else Error('Missing operand.');473 end else Operand.Free;474 end;475 if not Result then Tokenizer.Pos := LastPos;476 end;477 478 function TParser.ParseExpressionOperand(Block: TBlock; out479 ExpressionOperand: TExpressionOperand): Boolean;480 var481 Variable: TVariable;482 Constant: TConstant;483 FunctionCall: TFunctionCall;484 begin485 Result := False;486 if ParseFunctionCall(Block, FunctionCall) then begin487 Result := True;488 ExpressionOperand := TExpressionOperand.Create;489 ExpressionOperand.FunctionCall := FunctionCall;490 ExpressionOperand.OperandType := otFunctionCall;491 end else492 if ParseConstant(Block, Constant) then begin493 Result := True;494 ExpressionOperand := TExpressionOperand.Create;495 ExpressionOperand.ConstantDirect := Constant;496 ExpressionOperand.OperandType := otConstantDirect;497 end else498 if ParseConstantRef(Block, Constant) then begin499 Result := True;500 ExpressionOperand := TExpressionOperand.Create;501 ExpressionOperand.ConstantRef := Constant;502 ExpressionOperand.OperandType := otConstantRef;503 end else504 if ParseVariable(Block, Variable) then begin505 Result := True;506 ExpressionOperand := TExpressionOperand.Create;507 ExpressionOperand.VariableRef := Variable;508 ExpressionOperand.OperandType := otVariableRef;509 end else Error('Expected expression operand.');510 end;511 512 function TParser.ParseConstantRef(Block: TBlock; out ConstantRef: TConstant513 ): Boolean;514 var515 LastPos: TTokenizerPos;516 Token: TToken;517 begin518 Result := False;519 LastPos := Tokenizer.Pos;520 Token := Tokenizer.GetNext;521 if Token.Kind = tkIdentifier then begin;522 ConstantRef := Block.GetConstant(Token.Text);523 if Assigned(ConstantRef) then begin524 Result := True;525 end;526 end;527 if not Result then Tokenizer.Pos := LastPos;528 end;529 530 function TParser.ParseConstant(Block: TBlock; out ConstantRef: TConstant531 ): Boolean;532 var533 LastPos: TTokenizerPos;534 Token: TToken;535 begin536 Result := False;537 LastPos := Tokenizer.Pos;538 Token := Tokenizer.GetNext;539 if Token.Kind = tkNumber then begin540 Result := True;541 ConstantRef := TConstant.Create;542 ConstantRef.TypeRef := Block.GetType('Integer');543 ConstantRef.Value := TValueInteger.Create;544 TValueInteger(ConstantRef.Value).Value := StrToInt(Token.Text);545 end else546 if Token.Kind = tkString then begin547 Result := True;548 ConstantRef := TConstant.Create;549 ConstantRef.TypeRef := Block.GetType('string');550 ConstantRef.Value := TValueString.Create;551 TValueString(ConstantRef.Value).Value := Token.Text;552 end;553 if not Result then Tokenizer.Pos := LastPos;554 end;555 556 function TParser.ParseVariable(Block: TBlock; out VariableRef: TVariable557 ): Boolean;558 var559 LastPos: TTokenizerPos;560 Token: TToken;561 begin562 Result := False;563 LastPos := Tokenizer.Pos;564 Token := Tokenizer.GetNext;565 if Token.Kind = tkIdentifier then begin;566 VariableRef := Block.GetVariable(Token.Text);567 if Assigned(VariableRef) then begin568 Result := True;569 end;570 end;571 if not Result then Tokenizer.Pos := LastPos;572 end;573 574 function TParser.ParseIfThenElse(Block: TBlock; out IfThenElse: TIfThenElse575 ): Boolean;576 var577 Expression: TExpression;578 Command: TCommand;579 begin580 Result := False;581 if Tokenizer.CheckNext('if', tkKeyword) then begin582 Tokenizer.Expect('if', tkKeyword);583 Result := True;584 IfThenElse := TIfThenElse.Create;585 if ParseExpression(Block, Expression) then begin586 IfThenElse.Expression.Free;587 IfThenElse.Expression := Expression;588 Tokenizer.Expect('then', tkKeyword);589 if ParseCommand(Block, Command) then begin590 IfThenElse.CommandThen.Free;591 IfThenElse.CommandThen := Command;592 Command.Parent := IfThenElse;593 if Tokenizer.CheckNext('else', tkKeyword) then begin594 Tokenizer.Expect('else', tkKeyword);595 if ParseCommand(Block, Command) then begin596 IfThenElse.CommandElse.Free;597 IfThenElse.CommandElse := Command;598 Command.Parent := IfThenElse;599 end else Error('Expected command');600 end;601 end else Error('Expected command');602 end else Error('Expected expression');603 end;604 end;605 606 function TParser.ParseWhileDo(Block: TBlock; out WhileDo: TWhileDo): Boolean;607 var608 Expression: TExpression;609 Command: TCommand;610 begin611 Result := False;612 if Tokenizer.CheckNext('while', tkKeyword) then begin613 Tokenizer.Expect('while', tkKeyword);614 Result := True;615 WhileDo := TWhileDo.Create;616 if ParseExpression(Block, Expression) then begin617 WhileDo.Expression.Free;618 WhileDo.Expression := Expression;619 Tokenizer.Expect('do', tkKeyword);620 if ParseCommand(Block, Command) then begin621 WhileDo.Command.Free;622 WhileDo.Command := Command;623 Command.Parent := WhileDo;624 end else Error('Expected command');625 end else Error('Expected expression');626 end;627 end;628 629 function TParser.ParseRepeatUntil(Block: TBlock; out RepeatUntil: TRepeatUntil630 ): Boolean;631 var632 Expression: TExpression;633 Command: TCommand;634 begin635 Result := False;636 if Tokenizer.CheckNext('repeat', tkKeyword) then begin637 Tokenizer.Expect('repeat', tkKeyword);638 RepeatUntil := TRepeatUntil.Create;639 Result := True;640 while not Tokenizer.CheckNext('until', tkKeyword) do begin641 if ParseCommand(Block, Command) then begin642 RepeatUntil.Commands.Add(Command);643 Command.Parent := RepeatUntil;644 Tokenizer.Expect(';', tkSpecialSymbol);645 end else begin646 Error('Unexpected token ' + Tokenizer.GetNext.Text);647 Result := False;648 Break;649 end;650 end;651 Tokenizer.Expect('until', tkKeyword);652 if ParseExpression(Block, Expression) then begin653 RepeatUntil.Expression.Free;654 RepeatUntil.Expression := Expression;655 end else Error('Expected expression');656 end else Result := False;657 end;658 659 function TParser.ParseForToDo(Block: TBlock; out ForToDo: TForToDo): Boolean;660 var661 Expression: TExpression;662 VariableRef: TVariable;663 Command: TCommand;664 begin665 Result := False;666 if Tokenizer.CheckNext('for', tkKeyword) then begin667 Tokenizer.Expect('for', tkKeyword);668 Result := True;669 ForToDo := TForToDo.Create;670 if ParseVariable(Block, VariableRef) then begin671 ForToDo.VariableRef := VariableRef;672 Tokenizer.Expect(':=', tkSpecialSymbol);673 if ParseExpression(Block, Expression) then begin674 ForToDo.ExpressionFrom.Free;675 ForToDo.ExpressionFrom := Expression;676 Tokenizer.Expect('to', tkKeyword);677 if ParseExpression(Block, Expression) then begin678 ForToDo.ExpressionTo.Free;679 ForToDo.ExpressionTo := Expression;680 Tokenizer.Expect('do', tkKeyword);681 if ParseCommand(Block, Command) then begin682 ForToDo.Command.Free;683 ForToDo.Command := Command;684 Command.Parent := ForToDo;685 end else Error('Expected command.');686 end else Error('Expected expression.');687 end else Error('Expected expression.');688 end else Error('Expected control variable.');689 end;690 end;691 692 function TParser.ParseBreak(Block: TBlock; out BreakCmd: TBreak): Boolean;693 begin694 Result := False;695 if Tokenizer.CheckNext('break', tkKeyword) then begin696 Tokenizer.Expect('break', tkKeyword);697 Result := True;698 BreakCmd := TBreak.Create;699 end;700 end;701 702 function TParser.ParseContinue(Block: TBlock; out ContinueCmd: TContinue703 ): Boolean;704 begin705 Result := False;706 if Tokenizer.CheckNext('continue', tkKeyword) then begin707 Tokenizer.Expect('continue', tkKeyword);708 Result := True;709 ContinueCmd := TContinue.Create;710 end;711 end;712 36 713 37 procedure TParser.TokenizerError(Pos: TPoint; Text: string); … … 807 131 end; 808 132 133 function TParser.ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean; 134 begin 135 end; 136 809 137 procedure TParser.Parse; 810 138 var … … 836 164 begin 837 165 Tokenizer.Free; 838 inherited Destroy;166 inherited; 839 167 end; 840 168 -
branches/interpreter2/USource.pas
r213 r221 154 154 function GetField(Index: Integer): TField; override; 155 155 procedure SetValue(Index: Integer; var Value); override; 156 destructor Destroy; override; 156 157 end; 157 158 … … 484 485 destructor TReturn.Destroy; 485 486 begin 486 Expression.Free;487 inherited Destroy;487 FreeAndNil(Expression); 488 inherited; 488 489 end; 489 490 … … 530 531 destructor TSourceNodes.Destroy; 531 532 begin 532 List.Free;533 inherited Destroy;533 FreeAndNil(List); 534 inherited; 534 535 end; 535 536 … … 588 589 else if Index = 1 then TypeRef := TType(Value) 589 590 else inherited; 591 end; 592 593 destructor TConstant.Destroy; 594 begin 595 FreeAndNil(Value); 596 inherited; 590 597 end; 591 598 … … 722 729 destructor TRepeatUntil.Destroy; 723 730 begin 724 Expression.Free;725 Commands.Free;726 inherited Destroy;731 FreeAndNil(Expression); 732 FreeAndNil(Commands); 733 inherited; 727 734 end; 728 735 … … 801 808 destructor TForToDo.Destroy; 802 809 begin 803 Command.Free;804 ExpressionTo.Free;805 ExpressionFrom.Free;806 inherited Destroy;810 FreeAndNil(Command); 811 FreeAndNil(ExpressionTo); 812 FreeAndNil(ExpressionFrom); 813 inherited; 807 814 end; 808 815 … … 868 875 destructor TExpressionOperand.Destroy; 869 876 begin 870 if Assigned(ConstantDirect) then ConstantDirect.Free; 877 if Assigned(ConstantDirect) then FreeAndNil(ConstantDirect); 878 if Assigned(FunctionCall) then FreeAndNil(FunctionCall); 871 879 end; 872 880 … … 933 941 destructor TFunction.Destroy; 934 942 begin 935 Block.Free;936 Params.Free;937 inherited Destroy;943 FreeAndNil(Block); 944 FreeAndNil(Params); 945 inherited; 938 946 end; 939 947 … … 971 979 destructor TType.Destroy; 972 980 begin 973 F unctions.Free;974 inherited Destroy;981 FreeAndNil(Functions); 982 inherited; 975 983 end; 976 984 … … 1033 1041 destructor TExpressionOperation.Destroy; 1034 1042 begin 1035 Items.Free;1036 inherited Destroy;1043 FreeAndNil(Items); 1044 inherited; 1037 1045 end; 1038 1046 … … 1079 1087 begin 1080 1088 Variable := nil; 1081 Expression.Free;1082 inherited Destroy;1089 FreeAndNil(Expression); 1090 inherited; 1083 1091 end; 1084 1092 … … 1123 1131 destructor TIfThenElse.Destroy; 1124 1132 begin 1125 Expression.Free;1126 CommandThen.Free;1127 CommandElse.Free;1128 inherited Destroy;1133 FreeAndNil(Expression); 1134 FreeAndNil(CommandThen); 1135 FreeAndNil(CommandElse); 1136 inherited; 1129 1137 end; 1130 1138 … … 1165 1173 destructor TWhileDo.Destroy; 1166 1174 begin 1167 Expression.Free;1168 Command.Free;1169 inherited Destroy;1175 FreeAndNil(Expression); 1176 FreeAndNil(Command); 1177 inherited; 1170 1178 end; 1171 1179 … … 1205 1213 destructor TFunctionCall.Destroy; 1206 1214 begin 1207 Params.Free;1208 inherited Destroy;1215 FreeAndNil(Params); 1216 inherited; 1209 1217 end; 1210 1218 … … 1349 1357 destructor TBlock.Destroy; 1350 1358 begin 1351 BeginEnd.Free;1352 Types.Free;1353 Variables.Free;1354 Constants.Free;1355 F unctions.Free;1356 inherited Destroy;1359 FreeAndNil(BeginEnd); 1360 FreeAndNil(Types); 1361 FreeAndNil(Variables); 1362 FreeAndNil(Constants); 1363 FreeAndNil(Functions); 1364 inherited; 1357 1365 end; 1358 1366 … … 1394 1402 destructor TBeginEnd.Destroy; 1395 1403 begin 1396 Commands.Free;1397 inherited Destroy;1404 FreeAndNil(Commands); 1405 inherited; 1398 1406 end; 1399 1407 … … 1439 1447 destructor TProgram.Destroy; 1440 1448 begin 1441 Block.Free;1442 SystemBlock.Free;1443 inherited Destroy;1449 FreeAndNil(Block); 1450 FreeAndNil(SystemBlock); 1451 inherited; 1444 1452 end; 1445 1453 -
branches/interpreter2/interpreter.lpi
r211 r221 25 25 <SearchPaths> 26 26 <IncludeFiles Value="$(ProjOutDir)"/> 27 <OtherUnitFiles Value="Forms "/>27 <OtherUnitFiles Value="Forms;Generators;Parsers"/> 28 28 <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)-$(BuildMode)"/> 29 29 </SearchPaths> … … 72 72 </Item2> 73 73 </RequiredPackages> 74 <Units Count="1 6">74 <Units Count="17"> 75 75 <Unit0> 76 76 <Filename Value="interpreter.lpr"/> … … 98 98 </Unit5> 99 99 <Unit6> 100 <Filename Value="UGenerator Pascal.pas"/>100 <Filename Value="UGenerator.pas"/> 101 101 <IsPartOfProject Value="True"/> 102 102 </Unit6> 103 103 <Unit7> 104 <Filename Value="UGeneratorPhp.pas"/> 105 <IsPartOfProject Value="True"/> 104 <Filename Value="Forms/UFormMessages.pas"/> 105 <IsPartOfProject Value="True"/> 106 <ComponentName Value="FormMessages"/> 107 <HasResources Value="True"/> 108 <ResourceBaseClass Value="Form"/> 106 109 </Unit7> 107 110 <Unit8> 108 <Filename Value="UGenerator.pas"/> 109 <IsPartOfProject Value="True"/> 111 <Filename Value="Forms/UFormSource.pas"/> 112 <IsPartOfProject Value="True"/> 113 <ComponentName Value="FormSource"/> 114 <HasResources Value="True"/> 115 <ResourceBaseClass Value="Form"/> 110 116 </Unit8> 111 117 <Unit9> 112 <Filename Value="U GeneratorCSharp.pas"/>118 <Filename Value="UOptimizer.pas"/> 113 119 <IsPartOfProject Value="True"/> 114 120 </Unit9> 115 121 <Unit10> 116 <Filename Value="Forms/UForm Messages.pas"/>117 <IsPartOfProject Value="True"/> 118 <ComponentName Value="Form Messages"/>122 <Filename Value="Forms/UFormOutput.pas"/> 123 <IsPartOfProject Value="True"/> 124 <ComponentName Value="FormOutput"/> 119 125 <HasResources Value="True"/> 120 126 <ResourceBaseClass Value="Form"/> 121 127 </Unit10> 122 128 <Unit11> 123 <Filename Value="Forms/UForm Source.pas"/>124 <IsPartOfProject Value="True"/> 125 <ComponentName Value="Form Source"/>129 <Filename Value="Forms/UFormMain.pas"/> 130 <IsPartOfProject Value="True"/> 131 <ComponentName Value="FormMain"/> 126 132 <HasResources Value="True"/> 127 133 <ResourceBaseClass Value="Form"/> 128 134 </Unit11> 129 135 <Unit12> 130 <Filename Value=" UOptimizer.pas"/>136 <Filename Value="Generators/UGeneratorCSharp.pas"/> 131 137 <IsPartOfProject Value="True"/> 132 138 </Unit12> 133 139 <Unit13> 134 <Filename Value=" UGeneratorXml.pas"/>140 <Filename Value="Generators/UGeneratorPascal.pas"/> 135 141 <IsPartOfProject Value="True"/> 136 142 </Unit13> 137 143 <Unit14> 138 <Filename Value="Forms/UFormOutput.pas"/> 139 <IsPartOfProject Value="True"/> 140 <ComponentName Value="FormOutput"/> 141 <HasResources Value="True"/> 142 <ResourceBaseClass Value="Form"/> 144 <Filename Value="Generators/UGeneratorPhp.pas"/> 145 <IsPartOfProject Value="True"/> 143 146 </Unit14> 144 147 <Unit15> 145 <Filename Value="Forms/UFormMain.pas"/> 146 <IsPartOfProject Value="True"/> 147 <ComponentName Value="FormMain"/> 148 <HasResources Value="True"/> 149 <ResourceBaseClass Value="Form"/> 148 <Filename Value="Generators/UGeneratorXml.pas"/> 149 <IsPartOfProject Value="True"/> 150 150 </Unit15> 151 <Unit16> 152 <Filename Value="Parsers/UParserPascal.pas"/> 153 <IsPartOfProject Value="True"/> 154 </Unit16> 151 155 </Units> 152 156 </ProjectOptions> … … 158 162 <SearchPaths> 159 163 <IncludeFiles Value="$(ProjOutDir)"/> 160 <OtherUnitFiles Value="Forms "/>164 <OtherUnitFiles Value="Forms;Generators;Parsers"/> 161 165 <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)-$(BuildMode)"/> 162 166 </SearchPaths> -
branches/interpreter2/interpreter.lpr
r209 r221 9 9 Interfaces, SysUtils, // this includes the LCL widgetset 10 10 Forms, UParser, UTokenizer, USource, UExecutor, UInterpreter, 11 UGenerator Pascal, UGeneratorPhp, UGenerator, UGeneratorCSharp, UFormMessages,12 UFormSource, UOptimizer, U GeneratorXml, UFormOutput, UFormMain11 UGenerator, UFormMessages, 12 UFormSource, UOptimizer, UFormOutput, UFormMain, UParserPascal 13 13 { you can add units after this }; 14 14
Note:
See TracChangeset
for help on using the changeset viewer.