Ignore:
Timestamp:
Apr 16, 2020, 7:40:38 PM (5 years ago)
Author:
chronos
Message:
  • Fixed: Memory leaks.
Location:
branches/interpreter2
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter2

    • Property svn:ignore set to
      lib
      interpreter
      interpreter.lps
      interpreter.res
      heaptrclog.trc
  • branches/interpreter2/UParser.pas

    r200 r201  
    1616    FOnError: TErrorEvent;
    1717    Tokenizer: TTokenizer;
    18     function ParseBeginEnd(Block: TBlock; var BeginEnd: TBeginEnd): Boolean;
    19     function ParseFunctionCall(Block: TBlock; var FunctionCall: TFunctionCall): Boolean;
    20     function ParseCommand(Block: TBlock; var Command: TCommand): Boolean;
    21     function ParseProgram(SystemBlock: TBlock; var Prog: TProgram): Boolean;
    22     function ParseBlock(ParentBlock: TBlock; var Block: TBlock): Boolean;
    23     function ParseAssignment(Block: TBlock; var Assignment: TAssignment): Boolean;
    24     function ParseExpression(Block: TBlock; var Expression: TExpression): Boolean;
    25     function ParseIfThenElse(Block: TBlock; var IfThenElse: TIfThenElse): Boolean;
    26     function ParseWhileDo(Block: TBlock; var WhileDo: TWhileDo): Boolean;
     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): Boolean;
     23    function ParseVarBlock(Block: TBlock): Boolean;
     24    function ParseConstBlock(Block: TBlock): Boolean;
     25    function ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean;
     26    function ParseExpression(Block: TBlock; out Expression: TExpression): Boolean;
     27    function ParseIfThenElse(Block: TBlock; out IfThenElse: TIfThenElse): Boolean;
     28    function ParseWhileDo(Block: TBlock; out WhileDo: TWhileDo): Boolean;
    2729    procedure TokenizerError(Pos: TPoint; Text: string);
    2830    procedure InitSystemBlock(Block: TBlock);
     
    4244{ TParser }
    4345
    44 function TParser.ParseBeginEnd(Block: TBlock; var BeginEnd: TBeginEnd): Boolean;
     46function TParser.ParseBeginEnd(Block: TBlock; out BeginEnd: TBeginEnd): Boolean;
    4547var
    4648  Command: TCommand;
     
    6466end;
    6567
    66 function TParser.ParseFunctionCall(Block: TBlock; var FunctionCall: TFunctionCall
     68function TParser.ParseFunctionCall(Block: TBlock; out FunctionCall: TFunctionCall
    6769  ): Boolean;
    6870var
     
    9799end;
    98100
    99 function TParser.ParseCommand(Block: TBlock; var Command: TCommand): Boolean;
     101function TParser.ParseCommand(Block: TBlock; out Command: TCommand): Boolean;
    100102var
    101103  BeginEnd: TBeginEnd;
     
    127129end;
    128130
    129 function TParser.ParseProgram(SystemBlock: TBlock; var Prog: TProgram): Boolean;
     131function TParser.ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean;
    130132var
    131133  Block: TBlock;
     
    134136  Result := False;
    135137  Prog := TProgram.Create;
     138  Prog.SystemBlock.Free;
    136139  Prog.SystemBlock := SystemBlock;
    137140  if Tokenizer.CheckNext('program', tkKeyword) then begin
     
    144147  if ParseBlock(SystemBlock, Block) then begin
    145148    Result := True;
     149    Prog.Block.Free;
    146150    Prog.Block := Block;
    147151    Tokenizer.Expect('.', tkSpecialSymbol);
     
    152156end;
    153157
    154 function TParser.ParseBlock(ParentBlock: TBlock; var Block: TBlock): Boolean;
    155 var
    156   Token: TToken;
    157   Variable: TVariable;
    158   Constant: TConstant;
    159 begin
     158function TParser.ParseBlock(ParentBlock: TBlock; out Block: TBlock): Boolean;
     159var
     160  BeginEnd: TBeginEnd;
     161begin
     162  Result := False;
    160163  Block := TBlock.Create;
    161164  Block.Parent := ParentBlock;
     165  ParseVarBlock(Block);
     166  ParseConstBlock(Block);
     167  if ParseBeginEnd(Block, BeginEnd) then begin
     168    Result := True;
     169    Block.BeginEnd.Free;
     170    Block.BeginEnd := BeginEnd;
     171  end else Block.Free;
     172end;
     173
     174function TParser.ParseVarBlock(Block: TBlock): Boolean;
     175var
     176  Token: TToken;
     177  Variable: TVariable;
     178begin
    162179  if Tokenizer.CheckNext('var', tkKeyword) then begin
     180    Result := True;
    163181    Tokenizer.Expect('var', tkKeyword);
    164182    while Tokenizer.CheckNextKind(tkIdentifier) do begin
     
    177195      end;
    178196    end;
    179   end;
     197  end else Result := False;
     198end;
     199
     200function TParser.ParseConstBlock(Block: TBlock): Boolean;
     201var
     202  Token: TToken;
     203  Constant: TConstant;
     204begin
    180205  if Tokenizer.CheckNext('const', tkKeyword) then begin
     206    Result := True;
    181207    Tokenizer.Expect('const', tkKeyword);
    182208    while Tokenizer.CheckNextKind(tkIdentifier) do begin
     
    200226      end;
    201227    end;
    202   end;
    203   Result := ParseBeginEnd(Block, Block.BeginEnd);
    204   //if not Result then Block.Free;
    205 end;
    206 
    207 function TParser.ParseAssignment(Block: TBlock; var Assignment: TAssignment): Boolean;
     228  end else Result := False;
     229end;
     230
     231function TParser.ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean;
    208232var
    209233  Token: TToken;
    210234  Variable: TVariable;
     235  Expression: TExpression;
    211236begin
    212237  Result := False;
     
    220245      Assignment.Variable := Variable;
    221246      Tokenizer.Expect(':=', tkSpecialSymbol);
    222       ParseExpression(Block, Assignment.Expression);
     247      if ParseExpression(Block, Expression) then begin
     248        Assignment.Expression.Free;
     249        Assignment.Expression := Expression;
     250      end;
    223251    end else Error('Variable ' + Token.Text + ' not defined.');
    224252  end;
    225253end;
    226254
    227 function TParser.ParseExpression(Block: TBlock; var Expression: TExpression
     255function TParser.ParseExpression(Block: TBlock; out Expression: TExpression
    228256  ): Boolean;
    229257var
     
    239267      Result := True;
    240268      Expression := TExpression.Create;
    241       Expression.Variable := Variable;
     269      Expression.VariableRef := Variable;
    242270    end else begin
    243271      Constant := Block.Constants.SearchByName(Token.Text);
     
    245273        Result := True;
    246274        Expression := TExpression.Create;
    247         Expression.Constant := Constant;
     275        Expression.ConstantRef := Constant;
    248276      end;
    249277    end;
     
    251279  if Token.Kind = tkNumber then begin
    252280    Result := True;
     281    Constant := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count));
     282    Constant.Value := Token.Text;
    253283    Expression := TExpression.Create;
    254     Expression.Constant := TConstant.Create;
    255     Expression.Constant.Value := Token.Text;
     284    Expression.ConstantRef := Constant;
    256285  end else
    257286  if Token.Kind = tkString then begin
    258287    Result := True;
     288    Constant := Block.Constants.AddNew('_C' + IntToStr(Block.Constants.Count));
     289    Constant.Value := Token.Text;
    259290    Expression := TExpression.Create;
    260     Expression.Constant := TConstant.Create;
    261     Expression.Constant.Value := Token.Text;
    262   end;
    263 end;
    264 
    265 function TParser.ParseIfThenElse(Block: TBlock; var IfThenElse: TIfThenElse
     291    Expression.ConstantRef := Constant;
     292  end;
     293end;
     294
     295function TParser.ParseIfThenElse(Block: TBlock; out IfThenElse: TIfThenElse
    266296  ): Boolean;
    267297var
     
    275305    IfThenElse := TIfThenElse.Create;
    276306    if ParseExpression(Block, Expression) then begin
     307      IfThenElse.Expression.Free;
    277308      IfThenElse.Expression := Expression;
    278309      Tokenizer.Expect('then', tkKeyword);
    279310      if ParseCommand(Block, Command) then begin
     311        IfThenElse.CommandThen.Free;
    280312        IfThenElse.CommandThen := Command;
    281313        if Tokenizer.CheckNext('else', tkKeyword) then begin
    282314          Tokenizer.Expect('else', tkKeyword);
    283315          if ParseCommand(Block, Command) then begin
     316            IfThenElse.CommandElse.Free;
    284317            IfThenElse.CommandElse := Command;
    285318          end else Error('Expected command');
     
    290323end;
    291324
    292 function TParser.ParseWhileDo(Block: TBlock; var WhileDo: TWhileDo): Boolean;
     325function TParser.ParseWhileDo(Block: TBlock; out WhileDo: TWhileDo): Boolean;
    293326var
    294327  Expression: TExpression;
     
    301334    WhileDo := TWhileDo.Create;
    302335    if ParseExpression(Block, Expression) then begin
     336      WhileDo.Expression.Free;
    303337      WhileDo.Expression := Expression;
    304338      Tokenizer.Expect('do', tkKeyword);
    305339      if ParseCommand(Block, Command) then begin
     340        WhileDo.Command.Free;
    306341        WhileDo.Command := Command;
    307342      end else Error('Expected command');
Note: See TracChangeset for help on using the changeset viewer.