Changeset 203
- Timestamp:
- Apr 17, 2020, 10:16:25 PM (5 years ago)
- Location:
- branches/interpreter2
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/interpreter2/Test.pas
r202 r203 30 30 for I := 0 to 5 do begin 31 31 WriteLn(IntToStr(I)); 32 end; 32 end; 33 33 34 34 // Begin-End -
branches/interpreter2/UExecutor.pas
r202 r203 10 10 type 11 11 TExecutorFunctions = class; 12 13 { TExecutorVariable } 12 14 13 15 TExecutorVariable = class 14 16 Variable: TVariable; 15 17 Value: TValue; 18 constructor Create; 19 destructor Destroy; override; 16 20 end; 17 21 … … 99 103 procedure ExecuteWhileDo(Block: TExecutorBlock; WhileDo: TWhileDo); 100 104 procedure ExecuteForToDo(Block: TExecutorBlock; ForToDo: TForToDo); 101 procedure ExecuteBlock(ParentBlock: TExecutorBlock; Block: TBlock);105 procedure ExecuteBlock(ParentBlock: TExecutorBlock; Block: TBlock); 102 106 function ExecuteFunctionCall(Block: TExecutorBlock; FunctionCall: TFunctionCall): TValue; 103 107 procedure ExecuteAssignment(Block: TExecutorBlock; Assignment: TAssignment); … … 112 116 113 117 implementation 118 119 { TExecutorVariable } 120 121 constructor TExecutorVariable.Create; 122 begin 123 Value := TValue.Create; 124 end; 125 126 destructor TExecutorVariable.Destroy; 127 begin 128 Value.Free; 129 inherited Destroy; 130 end; 114 131 115 132 { TExecutorType } … … 429 446 else ExecuteCommand(Block, IfThenElse.CommandElse); 430 447 end else raise Exception.Create('Expected boolean value.'); 448 Value.Free; 431 449 end; 432 450 … … 441 459 ExecuteCommand(Block, WhileDo.Command); 442 460 end else raise Exception.Create('Expected boolean value.'); 461 Value.Free; 443 462 end; 444 463 end; … … 446 465 procedure TExecutor.ExecuteForToDo(Block: TExecutorBlock; ForToDo: TForToDo); 447 466 var 448 Value: TValue;449 467 Variable: TExecutorVariable; 450 468 Limit: TValue; 451 469 begin 452 470 Variable := Block.GetVariable(ForToDo.VariableRef); 471 Variable.Value.Free; 453 472 Variable.Value := ExecuteExpression(Block, ForToDo.ExpressionFrom); 454 473 Limit := ExecuteExpression(Block, ForToDo.ExpressionTo); … … 458 477 if TValueInteger(Variable.Value).Value > TValueInteger(Limit).Value then Break; 459 478 end; 479 Limit.Free; 460 480 end; 461 481 … … 486 506 end; 487 507 Result := ExecutorFunction.Callback(Params); 508 for I := 0 to FunctionCall.Params.Count - 1 do begin 509 Params[I].Free; 510 end; 488 511 end else raise Exception.Create('No executor for ' + FunctionCall.FunctionDef.Name + ' function.'); 489 512 end; … … 503 526 SetLength(Params, 1); 504 527 Params[0] := Value; 528 Variable.Value.Free; 505 529 Variable.Value := ExecutorFunction.Callback(Params); 506 530 end else raise Exception('Assignment result type is ' + Variable.Variable.TypeRef.Name + 507 531 ' but value is ' + Assignment.Expression.GetType.Name + '.'); 532 Value.Free; 508 533 end; 509 534 … … 543 568 end; 544 569 Result := ExecutorFunction.Callback(Params); 570 for I := 0 to Expression.Items.Count - 1 do begin 571 Params[I].Free; 572 end; 545 573 end; 546 574 … … 548 576 Expression: TExpressionOperand): TValue; 549 577 begin 550 if Assigned(Expression.VariableRef) then begin 551 Result := Block.Variables.SearchByVariable(Expression.VariableRef).Value; 552 end else 553 if Assigned(Expression.ConstantRef) then begin 554 Result := Expression.ConstantRef.Value; 555 end else 556 if Assigned(Expression.FunctionCall) then begin 557 Result := ExecuteFunctionCall(Block, Expression.FunctionCall); 558 end else raise Exception.Create('Unsupported exception operand type.'); 578 case Expression.OperandType of 579 otFunctionCall: Result := ExecuteFunctionCall(Block, Expression.FunctionCall); 580 otConstantDirect: Result := Expression.ConstantDirect.Value.Clone; 581 otConstantRef: Result := Expression.ConstantRef.Value.Clone; 582 otVariableRef: Result := Block.Variables.SearchByVariable(Expression.VariableRef).Value.Clone; 583 else raise Exception.Create('Unsupported exception operand type.'); 584 end; 559 585 end; 560 586 -
branches/interpreter2/UFormMain.lfm
r202 r203 563 563 end 564 564 end 565 object ButtonGenerate: TButton 566 Left = 288 567 Height = 38 568 Top = 18 569 Width = 113 570 Caption = 'Generate' 571 OnClick = ButtonGenerateClick 572 TabOrder = 5 573 end 565 574 object SynFreePascalSyn1: TSynFreePascalSyn 566 575 Enabled = False -
branches/interpreter2/UFormMain.pas
r202 r203 16 16 ButtonCompile: TButton; 17 17 ButtonRun: TButton; 18 ButtonGenerate: TButton; 18 19 Label1: TLabel; 19 20 Label2: TLabel; … … 23 24 SynFreePascalSyn1: TSynFreePascalSyn; 24 25 procedure ButtonCompileClick(Sender: TObject); 26 procedure ButtonGenerateClick(Sender: TObject); 25 27 procedure ButtonRunClick(Sender: TObject); 26 28 procedure FormActivate(Sender: TObject); … … 47 49 48 50 uses 49 UParser, UExecutor ;51 UParser, UExecutor, UGenerator; 50 52 51 53 { TFormMain } … … 105 107 end; 106 108 109 procedure TFormMain.ButtonGenerateClick(Sender: TObject); 110 var 111 Generator: TGenerator; 112 begin 113 ButtonCompile.Click; 114 MemoOutput.Lines.Clear; 115 if Assigned(Prog) then begin 116 Generator := TGenerator.Create; 117 Generator.Prog := Prog; 118 Generator.Generate; 119 MemoOutput.Lines.Text := Generator.Output; 120 Generator.Free; 121 end; 122 end; 123 107 124 procedure TFormMain.InterpreterError(Pos: TPoint; Text: string); 108 125 begin -
branches/interpreter2/UParser.pas
r202 r203 27 27 function ParseExpressionOperation(Block: TBlock; out ExpressionOperation: TExpressionOperation): Boolean; 28 28 function ParseExpressionOperand(Block: TBlock; out ExpressionOperand: TExpressionOperand): Boolean; 29 function ParseConstantRef(Block: TBlock; out ConstantRef: TConstant): Boolean; 29 30 function ParseConstant(Block: TBlock; out ConstantRef: TConstant): Boolean; 30 31 function ParseVariable(Block: TBlock; out VariableRef: TVariable): Boolean; … … 342 343 else Error('Expression operands needs to be same type.'); 343 344 end else Error('Missing operand.'); 344 end ;345 end else Operand.Free; 345 346 end; 346 347 if not Result then Tokenizer.Pos := LastPos; … … 364 365 Result := True; 365 366 ExpressionOperand := TExpressionOperand.Create; 367 ExpressionOperand.ConstantDirect := Constant; 368 ExpressionOperand.OperandType := otConstantDirect; 369 end else 370 if ParseConstantRef(Block, Constant) then begin 371 Result := True; 372 ExpressionOperand := TExpressionOperand.Create; 366 373 ExpressionOperand.ConstantRef := Constant; 367 ExpressionOperand.OperandType := otConstant ;374 ExpressionOperand.OperandType := otConstantRef; 368 375 end else 369 376 if ParseVariable(Block, Variable) then begin … … 371 378 ExpressionOperand := TExpressionOperand.Create; 372 379 ExpressionOperand.VariableRef := Variable; 373 ExpressionOperand.OperandType := otVariable ;380 ExpressionOperand.OperandType := otVariableRef; 374 381 end else Error('Expected expression operand.'); 375 382 end; 376 383 377 function TParser.ParseConstant (Block: TBlock; out ConstantRef: TConstant384 function TParser.ParseConstantRef(Block: TBlock; out ConstantRef: TConstant 378 385 ): Boolean; 379 386 var … … 389 396 Result := True; 390 397 end; 391 end else 398 end; 399 if not Result then Tokenizer.Pos := LastPos; 400 end; 401 402 function TParser.ParseConstant(Block: TBlock; out ConstantRef: TConstant 403 ): Boolean; 404 var 405 LastPos: TTokenizerPos; 406 Token: TToken; 407 begin 408 Result := False; 409 LastPos := Tokenizer.Pos; 410 Token := Tokenizer.GetNext; 392 411 if Token.Kind = tkNumber then begin 393 412 Result := True; 394 ConstantRef := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count));413 ConstantRef := TConstant.Create; 395 414 ConstantRef.TypeRef := Block.GetType('Integer'); 396 415 ConstantRef.Value := TValueInteger.Create; … … 399 418 if Token.Kind = tkString then begin 400 419 Result := True; 401 ConstantRef := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count));420 ConstantRef := TConstant.Create; 402 421 ConstantRef.TypeRef := Block.GetType('string'); 403 422 ConstantRef.Value := TValueString.Create; -
branches/interpreter2/USource.pas
r202 r203 12 12 TFunctions = class; 13 13 14 { TValue } 15 14 16 TValue = class 15 end; 17 function Clone: TValue; virtual; 18 end; 19 20 { TValueString } 16 21 17 22 TValueString = class(TValue) 18 23 Value: string; 19 end; 24 function Clone: TValue; override; 25 end; 26 27 { TValueInteger } 20 28 21 29 TValueInteger = class(TValue) 22 30 Value: Integer; 23 end; 31 function Clone: TValue; override; 32 end; 33 34 { TValueBoolean } 24 35 25 36 TValueBoolean = class(TValue) 26 37 Value: Boolean; 38 function Clone: TValue; override; 27 39 end; 28 40 … … 140 152 end; 141 153 142 TExpressionOperandType = (otVariable , otConstant, otFunctionCall);154 TExpressionOperandType = (otVariableRef, otConstantRef, otConstantDirect, otFunctionCall); 143 155 144 156 { TExpressionOperand } … … 148 160 VariableRef: TVariable; 149 161 ConstantRef: TConstant; 162 ConstantDirect: TConstant; 150 163 FunctionCall: TFunctionCall; 151 164 function GetType: TType; override; 165 constructor Create; 166 destructor Destroy; override; 152 167 end; 153 168 … … 225 240 implementation 226 241 242 { TValueBoolean } 243 244 function TValueBoolean.Clone: TValue; 245 begin 246 Result := TValueBoolean.Create; 247 TValueBoolean(Result).Value := Value; 248 end; 249 250 { TValueInteger } 251 252 function TValueInteger.Clone: TValue; 253 begin 254 Result := TValueInteger.Create; 255 TValueInteger(Result).Value := Value; 256 end; 257 258 { TValueString } 259 260 function TValueString.Clone: TValue; 261 begin 262 Result := TValueString.Create; 263 TValueString(Result).Value := Value; 264 end; 265 266 { TValue } 267 268 function TValue.Clone: TValue; 269 begin 270 Result := nil; 271 end; 272 227 273 { TForToDo } 228 274 … … 254 300 begin 255 301 if OperandType = otFunctionCall then Result := FunctionCall.FunctionDef.ResultType 256 else if OperandType = otConstant then Result := ConstantRef.TypeRef 257 else if OperandType = otVariable then Result := VariableRef.TypeRef 302 else if OperandType = otConstantRef then Result := ConstantRef.TypeRef 303 else if OperandType = otConstantDirect then Result := ConstantDirect.TypeRef 304 else if OperandType = otVariableRef then Result := VariableRef.TypeRef 258 305 else raise Exception.Create('Unsupported operand type'); 306 end; 307 308 constructor TExpressionOperand.Create; 309 begin 310 end; 311 312 destructor TExpressionOperand.Destroy; 313 begin 314 if Assigned(ConstantDirect) then ConstantDirect.Free; 259 315 end; 260 316 -
branches/interpreter2/interpreter.lpi
r202 r203 71 71 </Item2> 72 72 </RequiredPackages> 73 <Units Count=" 7">73 <Units Count="8"> 74 74 <Unit0> 75 75 <Filename Value="interpreter.lpr"/> … … 103 103 <IsPartOfProject Value="True"/> 104 104 </Unit6> 105 <Unit7> 106 <Filename Value="UGenerator.pas"/> 107 <IsPartOfProject Value="True"/> 108 </Unit7> 105 109 </Units> 106 110 </ProjectOptions> -
branches/interpreter2/interpreter.lpr
r201 r203 8 8 {$ENDIF}{$ENDIF} 9 9 Interfaces, SysUtils, // this includes the LCL widgetset 10 Forms, UFormMain, UParser, UTokenizer, USource, UExecutor, UInterpreter 10 Forms, UFormMain, UParser, UTokenizer, USource, UExecutor, UInterpreter, UGenerator 11 11 { you can add units after this }; 12 12
Note:
See TracChangeset
for help on using the changeset viewer.