Ignore:
Timestamp:
Nov 24, 2020, 6:19:17 PM (4 years ago)
Author:
chronos
Message:
  • Fixed: Resolved remaining memory leaks.
  • Modified: Generators moved to Generators subdirectory.
  • Modified: PascalParser moved to Parsers subdirectory.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter2/UParser.pas

    r212 r221  
    1515  private
    1616    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;
    4017    procedure TokenizerError(Pos: TPoint; Text: string);
    4118    procedure InitSystemBlock(Block: TBlock);
     19  protected
     20    Tokenizer: TTokenizer;
     21    function ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean; virtual;
    4222  public
    4323    Source: string;
     
    5434
    5535{ TParser }
    56 
    57 function TParser.ParseBeginEnd(Block: TBlock; out BeginEnd: TBeginEnd): Boolean;
    58 var
    59   Command: TCommand;
    60 begin
    61   if Tokenizer.CheckNext('begin', tkKeyword) then begin
    62     Tokenizer.Expect('begin', tkKeyword);
    63     BeginEnd := TBeginEnd.Create;
    64     Result := True;
    65     while not Tokenizer.CheckNext('end', tkKeyword) do begin
    66       if ParseCommand(Block, Command) then begin
    67         Command.Parent := BeginEnd;
    68         BeginEnd.Commands.Add(Command);
    69         Tokenizer.Expect(';', tkSpecialSymbol);
    70       end else begin
    71         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: TFunctionCall
    81   ): Boolean;
    82 var
    83   Token: TToken;
    84   LastPos: TTokenizerPos;
    85   FunctionDef: TFunction;
    86   Expression: TExpression;
    87   I: Integer;
    88 begin
    89   LastPos := Tokenizer.Pos;
    90   Token := Tokenizer.GetNext;
    91   if Token.Kind = tkIdentifier then begin
    92     FunctionDef := Block.GetFunction(Token.Text);
    93     if Assigned(FunctionDef) then begin
    94       FunctionCall := TFunctionCall.Create;
    95       FunctionCall.FunctionDef := FunctionDef;
    96       if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin
    97         Tokenizer.Expect('(', tkSpecialSymbol);
    98         for I := 0 to FunctionDef.Params.Count - 1 do begin
    99           if I > 0 then Tokenizer.Expect(',', tkSpecialSymbol);
    100           if ParseExpression(Block, Expression) then begin
    101             if Expression.GetType = TFunctionParameter(FunctionDef.Params[I]).TypeRef then
    102               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 begin
    110       Result := False;
    111       Tokenizer.Pos := LastPos;
    112     end;
    113   end else begin
    114     Result := False;
    115     Tokenizer.Pos := LastPos;
    116   end;
    117 end;
    118 
    119 function TParser.ParseCommand(Block: TBlock; out Command: TCommand): Boolean;
    120 var
    121   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 begin
    131   if ParseIfThenElse(Block, IfThenElse) then begin
    132     Result := True;
    133     Command := IfThenElse;
    134   end else
    135   if ParseWhileDo(Block, WhileDo) then begin
    136     Result := True;
    137     Command := WhileDo;
    138   end else
    139   if ParseForToDo(Block, ForToDo) then begin
    140     Result := True;
    141     Command := ForToDo;
    142   end else
    143   if ParseBeginEnd(Block, BeginEnd) then begin
    144     Result := True;
    145     Command := BeginEnd;
    146   end else
    147   if ParseFunctionCall(Block, FunctionCall) then begin
    148     Result := True;
    149     Command := FunctionCall;
    150   end else
    151   if ParseRepeatUntil(Block, RepeatUntil) then begin
    152     Result := True;
    153     Command := RepeatUntil;
    154   end else
    155   if ParseAssignment(Block, Assignment) then begin
    156     Result := True;
    157     Command := Assignment;
    158   end else
    159   if ParseBreak(Block, BreakCmd) then begin
    160     Result := True;
    161     Command := BreakCmd;
    162   end else
    163   if ParseContinue(Block, ContinueCmd) then begin
    164     Result := True;
    165     Command := ContinueCmd;
    166   end else
    167     Result := False;
    168 end;
    169 
    170 function TParser.ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean;
    171 var
    172   Block: TBlock;
    173   Token: TToken;
    174 begin
    175   Result := False;
    176   Prog := TProgram.Create;
    177   Prog.SystemBlock.Free;
    178   Prog.SystemBlock := SystemBlock;
    179   if Tokenizer.CheckNext('program', tkKeyword) then begin
    180     Tokenizer.Expect('program', tkKeyword);
    181     Token := Tokenizer.GetNext;
    182     if Token.Kind = tkIdentifier then
    183       Prog.Name := Token.Text;
    184     Tokenizer.Expect(';', tkSpecialSymbol);
    185   end;
    186   if ParseBlock(SystemBlock, Block) then begin
    187     Result := True;
    188     Prog.Block.Free;
    189     Prog.Block := Block;
    190     Block.Parent := Prog;
    191     Tokenizer.Expect('.', tkSpecialSymbol);
    192   end else begin
    193     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 var
    200   BeginEnd: TBeginEnd;
    201   Func: TFunction;
    202 begin
    203   Result := False;
    204   if Assigned(ExistingBlock) then Block := ExistingBlock
    205     else Block := TBlock.Create;
    206   Block.ParentBlock := ParentBlock;
    207   while True do begin
    208     if ParseBlockVar(Block) then begin
    209     end else
    210     if ParseBlockConst(Block) then begin
    211     end else
    212     if ParseFunction(Block, Func) then begin
    213       Block.Functions.Add(Func);
    214     end else begin
    215       Break;
    216     end;
    217   end;
    218   if ParseBeginEnd(Block, BeginEnd) then begin
    219     Result := True;
    220     Block.BeginEnd.Free;
    221     Block.BeginEnd := BeginEnd;
    222     BeginEnd.Parent := Block;
    223   end else begin
    224     if not Assigned(ExistingBlock) then Block.Free;
    225     Block := nil;
    226   end;
    227 end;
    228 
    229 function TParser.ParseBlockVar(Block: TBlock): Boolean;
    230 var
    231   Token: TToken;
    232   Variable: TVariable;
    233   TypeRef: TType;
    234 begin
    235   if Tokenizer.CheckNext('var', tkKeyword) then begin
    236     Result := True;
    237     Tokenizer.Expect('var', tkKeyword);
    238     while Tokenizer.CheckNextKind(tkIdentifier) do begin
    239       Token := Tokenizer.GetNext;
    240       if Token.Kind = tkIdentifier then begin
    241         Variable := Block.Variables.SearchByName(Token.Text);
    242         if not Assigned(Variable) then begin
    243           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 begin
    249             TypeRef := Block.GetType(Token.Text);
    250             if Assigned(TypeRef) then begin
    251               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 begin
    257         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 var
    266   Token: TToken;
    267   Constant: TConstant;
    268   TypeRef: TType;
    269 begin
    270   if Tokenizer.CheckNext('const', tkKeyword) then begin
    271     Result := True;
    272     Tokenizer.Expect('const', tkKeyword);
    273     while Tokenizer.CheckNextKind(tkIdentifier) do begin
    274       Token := Tokenizer.GetNext;
    275       if Token.Kind = tkIdentifier then begin
    276         Constant := Block.Constants.SearchByName(Token.Text);
    277         if not Assigned(Constant) then begin
    278           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 begin
    284             TypeRef := Block.GetType(Token.Text);
    285             if Assigned(TypeRef) then begin
    286               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 begin
    292             Constant.Value := TValueInteger.Create;
    293             TValueInteger(Constant.Value).Value := StrToInt(Token.Text);
    294           end else
    295           if Token.Kind = tkString then begin
    296             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 begin
    302         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 var
    311   Token: TToken;
    312   FunctionParameter: TFunctionParameter;
    313   NewBlock: TBlock;
    314   TypeRef: TType;
    315   Variable: TVariable;
    316   I: Integer;
    317 begin
    318   Result := False;
    319   if Tokenizer.CheckNext('function', tkKeyword) then begin
    320     Tokenizer.Expect('function', tkKeyword);
    321     Result := True;
    322     Func := TFunction.Create;
    323     Token := Tokenizer.GetNext;
    324     if Token.Kind = tkIdentifier then begin
    325       Func.Name := Token.Text;
    326       if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin
    327         Tokenizer.Expect('(', tkSpecialSymbol);
    328         while not Tokenizer.CheckNext(')', tkSpecialSymbol) do begin
    329           if Func.Params.Count > 0 then Tokenizer.Expect(',', tkSpecialSymbol);
    330           if ParseFunctionParameter(Block, FunctionParameter) then begin
    331             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 begin
    336           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 begin
    344         Tokenizer.Expect(':', tkSpecialSymbol);
    345         Token := Tokenizer.GetNext;
    346         if Token.Kind = tkIdentifier then begin
    347           TypeRef := Block.GetType(Token.Text);
    348           if Assigned(TypeRef) then begin
    349             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 begin
    360         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: TFunctionParameter
    367   ): Boolean;
    368 var
    369   Token: TToken;
    370   TypeRef: TType;
    371 begin
    372   Result := True;
    373   Token := Tokenizer.GetNext;
    374   if Token.Kind = tkIdentifier then begin
    375     Parameter := TFunctionParameter.Create;
    376     Parameter.Name := Token.Text;
    377     Tokenizer.Expect(':', tkSpecialSymbol);
    378     Token := Tokenizer.GetNext;
    379     if Token.Kind = tkIdentifier then begin
    380       TypeRef := Block.GetType(Token.Text);
    381       if Assigned(TypeRef) then begin
    382         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 var
    390   Token: TToken;
    391   Variable: TVariable;
    392   Expression: TExpression;
    393   LastPos: TTokenizerPos;
    394 begin
    395   LastPos := Tokenizer.Pos;
    396   Result := False;
    397   Token := Tokenizer.GetNext;
    398   if Token.Kind = tkIdentifier then begin
    399     Variable := Block.GetVariable(Token.Text);
    400     if Assigned(Variable) then begin
    401       Result := True;
    402       Assignment := TAssignment.Create;
    403       Assignment.Variable := Variable;
    404       Tokenizer.Expect(':=', tkSpecialSymbol);
    405       if ParseExpression(Block, Expression) then begin
    406         if Expression.GetType = Variable.TypeRef then begin
    407           Assignment.Expression.Free;
    408           Assignment.Expression := Expression;
    409           Expression.Parent := Assignment;
    410         end else begin
    411           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: TExpression
    422   ): Boolean;
    423 var
    424   ExpressionOperation: TExpressionOperation;
    425   ExpressionOperand: TExpressionOperand;
    426 begin
    427   Result := False;
    428   if ParseExpressionOperation(Block, ExpressionOperation) then begin
    429     Result := True;
    430     Expression := ExpressionOperation;
    431   end else
    432   if ParseExpressionOperand(Block, ExpressionOperand) then begin
    433     Result := True;
    434     Expression := ExpressionOperand;
    435   end;
    436 end;
    437 
    438 function TParser.ParseExpressionOperation(Block: TBlock; out
    439   ExpressionOperation: TExpressionOperation): Boolean;
    440 var
    441   Operand: TExpressionOperand;
    442   Token: TToken;
    443   Expression: TExpression;
    444   LastPos: TTokenizerPos;
    445   I: Integer;
    446   ExpectedType: TType;
    447 begin
    448   Result := False;
    449   LastPos := Tokenizer.Pos;
    450   if ParseExpressionOperand(Block, Operand) then begin
    451     Token := Tokenizer.GetNext;
    452     if (Token.Kind = tkSpecialSymbol) and Tokenizer.IsOperator(Token.Text) then begin
    453       Result := True;
    454       ExpressionOperation := TExpressionOperation.Create;
    455       ExpressionOperation.TypeRef := Operand.GetType;
    456       if Token.Text = '+' then ExpressionOperation.Operation := eoAdd
    457       else if Token.Text = '-' then ExpressionOperation.Operation := eoSub
    458       else if Token.Text = '=' then ExpressionOperation.Operation := eoEqual
    459       else if Token.Text = '<>' then ExpressionOperation.Operation := eoNotEqual
    460       else Error('Unsupported operator ' + Token.Text);
    461       ExpressionOperation.FunctionRef := ExpressionOperation.TypeRef.Functions.SearchByName(ExpressionOperation.GetFunctionName);
    462       if not Assigned(ExpressionOperation.FunctionRef.ResultType) then
    463         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 begin
    468         ExpectedType := TFunctionParameter(ExpressionOperation.FunctionRef.Params[I]).TypeRef;
    469         if Expression.GetType = ExpectedType then
    470           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; out
    479   ExpressionOperand: TExpressionOperand): Boolean;
    480 var
    481   Variable: TVariable;
    482   Constant: TConstant;
    483   FunctionCall: TFunctionCall;
    484 begin
    485   Result := False;
    486   if ParseFunctionCall(Block, FunctionCall) then begin
    487     Result := True;
    488     ExpressionOperand := TExpressionOperand.Create;
    489     ExpressionOperand.FunctionCall := FunctionCall;
    490     ExpressionOperand.OperandType := otFunctionCall;
    491   end else
    492   if ParseConstant(Block, Constant) then begin
    493     Result := True;
    494     ExpressionOperand := TExpressionOperand.Create;
    495     ExpressionOperand.ConstantDirect := Constant;
    496     ExpressionOperand.OperandType := otConstantDirect;
    497   end else
    498   if ParseConstantRef(Block, Constant) then begin
    499     Result := True;
    500     ExpressionOperand := TExpressionOperand.Create;
    501     ExpressionOperand.ConstantRef := Constant;
    502     ExpressionOperand.OperandType := otConstantRef;
    503   end else
    504   if ParseVariable(Block, Variable) then begin
    505     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: TConstant
    513   ): Boolean;
    514 var
    515   LastPos: TTokenizerPos;
    516   Token: TToken;
    517 begin
    518   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 begin
    524       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: TConstant
    531   ): Boolean;
    532 var
    533   LastPos: TTokenizerPos;
    534   Token: TToken;
    535 begin
    536   Result := False;
    537   LastPos := Tokenizer.Pos;
    538   Token := Tokenizer.GetNext;
    539   if Token.Kind = tkNumber then begin
    540     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 else
    546   if Token.Kind = tkString then begin
    547     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: TVariable
    557   ): Boolean;
    558 var
    559   LastPos: TTokenizerPos;
    560   Token: TToken;
    561 begin
    562   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 begin
    568       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: TIfThenElse
    575   ): Boolean;
    576 var
    577   Expression: TExpression;
    578   Command: TCommand;
    579 begin
    580   Result := False;
    581   if Tokenizer.CheckNext('if', tkKeyword) then begin
    582     Tokenizer.Expect('if', tkKeyword);
    583     Result := True;
    584     IfThenElse := TIfThenElse.Create;
    585     if ParseExpression(Block, Expression) then begin
    586       IfThenElse.Expression.Free;
    587       IfThenElse.Expression := Expression;
    588       Tokenizer.Expect('then', tkKeyword);
    589       if ParseCommand(Block, Command) then begin
    590         IfThenElse.CommandThen.Free;
    591         IfThenElse.CommandThen := Command;
    592         Command.Parent := IfThenElse;
    593         if Tokenizer.CheckNext('else', tkKeyword) then begin
    594           Tokenizer.Expect('else', tkKeyword);
    595           if ParseCommand(Block, Command) then begin
    596             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 var
    608   Expression: TExpression;
    609   Command: TCommand;
    610 begin
    611   Result := False;
    612   if Tokenizer.CheckNext('while', tkKeyword) then begin
    613     Tokenizer.Expect('while', tkKeyword);
    614     Result := True;
    615     WhileDo := TWhileDo.Create;
    616     if ParseExpression(Block, Expression) then begin
    617       WhileDo.Expression.Free;
    618       WhileDo.Expression := Expression;
    619       Tokenizer.Expect('do', tkKeyword);
    620       if ParseCommand(Block, Command) then begin
    621         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: TRepeatUntil
    630   ): Boolean;
    631 var
    632   Expression: TExpression;
    633   Command: TCommand;
    634 begin
    635   Result := False;
    636   if Tokenizer.CheckNext('repeat', tkKeyword) then begin
    637     Tokenizer.Expect('repeat', tkKeyword);
    638     RepeatUntil := TRepeatUntil.Create;
    639     Result := True;
    640     while not Tokenizer.CheckNext('until', tkKeyword) do begin
    641       if ParseCommand(Block, Command) then begin
    642         RepeatUntil.Commands.Add(Command);
    643         Command.Parent := RepeatUntil;
    644         Tokenizer.Expect(';', tkSpecialSymbol);
    645       end else begin
    646         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 begin
    653       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 var
    661   Expression: TExpression;
    662   VariableRef: TVariable;
    663   Command: TCommand;
    664 begin
    665   Result := False;
    666   if Tokenizer.CheckNext('for', tkKeyword) then begin
    667     Tokenizer.Expect('for', tkKeyword);
    668     Result := True;
    669     ForToDo := TForToDo.Create;
    670     if ParseVariable(Block, VariableRef) then begin
    671       ForToDo.VariableRef := VariableRef;
    672       Tokenizer.Expect(':=', tkSpecialSymbol);
    673       if ParseExpression(Block, Expression) then begin
    674         ForToDo.ExpressionFrom.Free;
    675         ForToDo.ExpressionFrom := Expression;
    676         Tokenizer.Expect('to', tkKeyword);
    677         if ParseExpression(Block, Expression) then begin
    678           ForToDo.ExpressionTo.Free;
    679           ForToDo.ExpressionTo := Expression;
    680           Tokenizer.Expect('do', tkKeyword);
    681           if ParseCommand(Block, Command) then begin
    682             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 begin
    694   Result := False;
    695   if Tokenizer.CheckNext('break', tkKeyword) then begin
    696     Tokenizer.Expect('break', tkKeyword);
    697     Result := True;
    698     BreakCmd := TBreak.Create;
    699   end;
    700 end;
    701 
    702 function TParser.ParseContinue(Block: TBlock; out ContinueCmd: TContinue
    703   ): Boolean;
    704 begin
    705   Result := False;
    706   if Tokenizer.CheckNext('continue', tkKeyword) then begin
    707     Tokenizer.Expect('continue', tkKeyword);
    708     Result := True;
    709     ContinueCmd := TContinue.Create;
    710   end;
    711 end;
    71236
    71337procedure TParser.TokenizerError(Pos: TPoint; Text: string);
     
    807131end;
    808132
     133function TParser.ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean;
     134begin
     135end;
     136
    809137procedure TParser.Parse;
    810138var
     
    836164begin
    837165  Tokenizer.Free;
    838   inherited Destroy;
     166  inherited;
    839167end;
    840168
Note: See TracChangeset for help on using the changeset viewer.