Changeset 203 for branches/interpreter2


Ignore:
Timestamp:
Apr 17, 2020, 10:16:25 PM (5 years ago)
Author:
chronos
Message:
  • Added: Simple pascal code generator.
Location:
branches/interpreter2
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter2/Test.pas

    r202 r203  
    3030  for I := 0 to 5 do begin
    3131    WriteLn(IntToStr(I));   
    32   end;
     32  end; 
    3333   
    3434  // Begin-End
  • branches/interpreter2/UExecutor.pas

    r202 r203  
    1010type
    1111  TExecutorFunctions = class;
     12
     13  { TExecutorVariable }
    1214
    1315  TExecutorVariable = class
    1416    Variable: TVariable;
    1517    Value: TValue;
     18    constructor Create;
     19    destructor Destroy; override;
    1620  end;
    1721
     
    99103    procedure ExecuteWhileDo(Block: TExecutorBlock; WhileDo: TWhileDo);
    100104    procedure ExecuteForToDo(Block: TExecutorBlock; ForToDo: TForToDo);
    101     procedure ExecuteBlock(ParentBlock: TExecutorBlock;Block: TBlock);
     105    procedure ExecuteBlock(ParentBlock: TExecutorBlock; Block: TBlock);
    102106    function ExecuteFunctionCall(Block: TExecutorBlock; FunctionCall: TFunctionCall): TValue;
    103107    procedure ExecuteAssignment(Block: TExecutorBlock; Assignment: TAssignment);
     
    112116
    113117implementation
     118
     119{ TExecutorVariable }
     120
     121constructor TExecutorVariable.Create;
     122begin
     123  Value := TValue.Create;
     124end;
     125
     126destructor TExecutorVariable.Destroy;
     127begin
     128  Value.Free;
     129  inherited Destroy;
     130end;
    114131
    115132{ TExecutorType }
     
    429446      else ExecuteCommand(Block, IfThenElse.CommandElse);
    430447  end else raise Exception.Create('Expected boolean value.');
     448  Value.Free;
    431449end;
    432450
     
    441459      ExecuteCommand(Block, WhileDo.Command);
    442460    end else raise Exception.Create('Expected boolean value.');
     461    Value.Free;
    443462  end;
    444463end;
     
    446465procedure TExecutor.ExecuteForToDo(Block: TExecutorBlock; ForToDo: TForToDo);
    447466var
    448   Value: TValue;
    449467  Variable: TExecutorVariable;
    450468  Limit: TValue;
    451469begin
    452470  Variable := Block.GetVariable(ForToDo.VariableRef);
     471  Variable.Value.Free;
    453472  Variable.Value := ExecuteExpression(Block, ForToDo.ExpressionFrom);
    454473  Limit := ExecuteExpression(Block, ForToDo.ExpressionTo);
     
    458477    if TValueInteger(Variable.Value).Value > TValueInteger(Limit).Value then Break;
    459478  end;
     479  Limit.Free;
    460480end;
    461481
     
    486506    end;
    487507    Result := ExecutorFunction.Callback(Params);
     508    for I := 0 to FunctionCall.Params.Count - 1 do begin
     509      Params[I].Free;
     510    end;
    488511  end else raise Exception.Create('No executor for ' + FunctionCall.FunctionDef.Name + ' function.');
    489512end;
     
    503526    SetLength(Params, 1);
    504527    Params[0] := Value;
     528    Variable.Value.Free;
    505529    Variable.Value := ExecutorFunction.Callback(Params);
    506530  end else raise Exception('Assignment result type is ' + Variable.Variable.TypeRef.Name +
    507531    ' but value is ' + Assignment.Expression.GetType.Name + '.');
     532  Value.Free;
    508533end;
    509534
     
    543568  end;
    544569  Result := ExecutorFunction.Callback(Params);
     570  for I := 0 to Expression.Items.Count - 1 do begin
     571    Params[I].Free;
     572  end;
    545573end;
    546574
     
    548576  Expression: TExpressionOperand): TValue;
    549577begin
    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;
    559585end;
    560586
  • branches/interpreter2/UFormMain.lfm

    r202 r203  
    563563    end
    564564  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
    565574  object SynFreePascalSyn1: TSynFreePascalSyn
    566575    Enabled = False
  • branches/interpreter2/UFormMain.pas

    r202 r203  
    1616    ButtonCompile: TButton;
    1717    ButtonRun: TButton;
     18    ButtonGenerate: TButton;
    1819    Label1: TLabel;
    1920    Label2: TLabel;
     
    2324    SynFreePascalSyn1: TSynFreePascalSyn;
    2425    procedure ButtonCompileClick(Sender: TObject);
     26    procedure ButtonGenerateClick(Sender: TObject);
    2527    procedure ButtonRunClick(Sender: TObject);
    2628    procedure FormActivate(Sender: TObject);
     
    4749
    4850uses
    49   UParser, UExecutor;
     51  UParser, UExecutor, UGenerator;
    5052
    5153{ TFormMain }
     
    105107end;
    106108
     109procedure TFormMain.ButtonGenerateClick(Sender: TObject);
     110var
     111  Generator: TGenerator;
     112begin
     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;
     122end;
     123
    107124procedure TFormMain.InterpreterError(Pos: TPoint; Text: string);
    108125begin
  • branches/interpreter2/UParser.pas

    r202 r203  
    2727    function ParseExpressionOperation(Block: TBlock; out ExpressionOperation: TExpressionOperation): Boolean;
    2828    function ParseExpressionOperand(Block: TBlock; out ExpressionOperand: TExpressionOperand): Boolean;
     29    function ParseConstantRef(Block: TBlock; out ConstantRef: TConstant): Boolean;
    2930    function ParseConstant(Block: TBlock; out ConstantRef: TConstant): Boolean;
    3031    function ParseVariable(Block: TBlock; out VariableRef: TVariable): Boolean;
     
    342343          else Error('Expression operands needs to be same type.');
    343344      end else Error('Missing operand.');
    344     end;
     345    end else Operand.Free;
    345346  end;
    346347  if not Result then Tokenizer.Pos := LastPos;
     
    364365    Result := True;
    365366    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;
    366373    ExpressionOperand.ConstantRef := Constant;
    367     ExpressionOperand.OperandType := otConstant;
     374    ExpressionOperand.OperandType := otConstantRef;
    368375  end else
    369376  if ParseVariable(Block, Variable) then begin
     
    371378    ExpressionOperand := TExpressionOperand.Create;
    372379    ExpressionOperand.VariableRef := Variable;
    373     ExpressionOperand.OperandType := otVariable;
     380    ExpressionOperand.OperandType := otVariableRef;
    374381  end else Error('Expected expression operand.');
    375382end;
    376383
    377 function TParser.ParseConstant(Block: TBlock; out ConstantRef: TConstant
     384function TParser.ParseConstantRef(Block: TBlock; out ConstantRef: TConstant
    378385  ): Boolean;
    379386var
     
    389396      Result := True;
    390397    end;
    391   end else
     398  end;
     399  if not Result then Tokenizer.Pos := LastPos;
     400end;
     401
     402function TParser.ParseConstant(Block: TBlock; out ConstantRef: TConstant
     403  ): Boolean;
     404var
     405  LastPos: TTokenizerPos;
     406  Token: TToken;
     407begin
     408  Result := False;
     409  LastPos := Tokenizer.Pos;
     410  Token := Tokenizer.GetNext;
    392411  if Token.Kind = tkNumber then begin
    393412    Result := True;
    394     ConstantRef := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count));
     413    ConstantRef := TConstant.Create;
    395414    ConstantRef.TypeRef := Block.GetType('Integer');
    396415    ConstantRef.Value := TValueInteger.Create;
     
    399418  if Token.Kind = tkString then begin
    400419    Result := True;
    401     ConstantRef := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count));
     420    ConstantRef := TConstant.Create;
    402421    ConstantRef.TypeRef := Block.GetType('string');
    403422    ConstantRef.Value := TValueString.Create;
  • branches/interpreter2/USource.pas

    r202 r203  
    1212  TFunctions = class;
    1313
     14  { TValue }
     15
    1416  TValue = class
    15   end;
     17    function Clone: TValue; virtual;
     18  end;
     19
     20  { TValueString }
    1621
    1722  TValueString = class(TValue)
    1823    Value: string;
    19   end;
     24    function Clone: TValue; override;
     25  end;
     26
     27  { TValueInteger }
    2028
    2129  TValueInteger = class(TValue)
    2230    Value: Integer;
    23   end;
     31    function Clone: TValue; override;
     32  end;
     33
     34  { TValueBoolean }
    2435
    2536  TValueBoolean = class(TValue)
    2637    Value: Boolean;
     38    function Clone: TValue; override;
    2739  end;
    2840
     
    140152  end;
    141153
    142   TExpressionOperandType = (otVariable, otConstant, otFunctionCall);
     154  TExpressionOperandType = (otVariableRef, otConstantRef, otConstantDirect, otFunctionCall);
    143155
    144156  { TExpressionOperand }
     
    148160    VariableRef: TVariable;
    149161    ConstantRef: TConstant;
     162    ConstantDirect: TConstant;
    150163    FunctionCall: TFunctionCall;
    151164    function GetType: TType; override;
     165    constructor Create;
     166    destructor Destroy; override;
    152167  end;
    153168
     
    225240implementation
    226241
     242{ TValueBoolean }
     243
     244function TValueBoolean.Clone: TValue;
     245begin
     246  Result := TValueBoolean.Create;
     247  TValueBoolean(Result).Value := Value;
     248end;
     249
     250{ TValueInteger }
     251
     252function TValueInteger.Clone: TValue;
     253begin
     254  Result := TValueInteger.Create;
     255  TValueInteger(Result).Value := Value;
     256end;
     257
     258{ TValueString }
     259
     260function TValueString.Clone: TValue;
     261begin
     262  Result := TValueString.Create;
     263  TValueString(Result).Value := Value;
     264end;
     265
     266{ TValue }
     267
     268function TValue.Clone: TValue;
     269begin
     270  Result := nil;
     271end;
     272
    227273{ TForToDo }
    228274
     
    254300begin
    255301  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
    258305  else raise Exception.Create('Unsupported operand type');
     306end;
     307
     308constructor TExpressionOperand.Create;
     309begin
     310end;
     311
     312destructor TExpressionOperand.Destroy;
     313begin
     314  if Assigned(ConstantDirect) then ConstantDirect.Free;
    259315end;
    260316
  • branches/interpreter2/interpreter.lpi

    r202 r203  
    7171      </Item2>
    7272    </RequiredPackages>
    73     <Units Count="7">
     73    <Units Count="8">
    7474      <Unit0>
    7575        <Filename Value="interpreter.lpr"/>
     
    103103        <IsPartOfProject Value="True"/>
    104104      </Unit6>
     105      <Unit7>
     106        <Filename Value="UGenerator.pas"/>
     107        <IsPartOfProject Value="True"/>
     108      </Unit7>
    105109    </Units>
    106110  </ProjectOptions>
  • branches/interpreter2/interpreter.lpr

    r201 r203  
    88  {$ENDIF}{$ENDIF}
    99  Interfaces, SysUtils, // this includes the LCL widgetset
    10   Forms, UFormMain, UParser, UTokenizer, USource, UExecutor, UInterpreter
     10  Forms, UFormMain, UParser, UTokenizer, USource, UExecutor, UInterpreter, UGenerator
    1111  { you can add units after this };
    1212
Note: See TracChangeset for help on using the changeset viewer.