Changeset 222 for branches/interpreter2/Parsers/UParserPascal.pas
- Timestamp:
- Nov 25, 2020, 12:18:45 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/interpreter2/Parsers/UParserPascal.pas
r221 r222 9 9 10 10 type 11 12 { TParserPascal } 13 11 14 TParserPascal = class(TParser) 12 15 protected … … 21 24 function ParseFunctionParameter(Block: TBlock; out Parameter: TFunctionParameter): Boolean; 22 25 function ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean; 23 function ParseExpression(Block: TBlock; out Expression: TExpression): Boolean; 26 function ParseExpression(Block: TBlock; out Expression: TExpression; 27 WithOperation: Boolean = True): Boolean; 24 28 function ParseExpressionOperation(Block: TBlock; out ExpressionOperation: TExpressionOperation): Boolean; 25 29 function ParseExpressionOperand(Block: TBlock; out ExpressionOperand: TExpressionOperand): Boolean; 30 function ParseExpressionBrackets(Block: TBlock; out ExpressionBrackets: TExpressionBrackets): Boolean; 26 31 function ParseConstantRef(Block: TBlock; out ConstantRef: TConstant): Boolean; 27 32 function ParseConstant(Block: TBlock; out ConstantRef: TConstant): Boolean; … … 42 47 Command: TCommand; 43 48 begin 44 if Tokenizer.CheckNext('begin', tkKeyword) then begin 45 Tokenizer.Expect('begin', tkKeyword); 49 if Tokenizer.CheckNextAndRead('begin', tkKeyword) then begin 46 50 BeginEnd := TBeginEnd.Create; 47 51 Result := True; … … 77 81 FunctionCall := TFunctionCall.Create; 78 82 FunctionCall.FunctionDef := FunctionDef; 79 if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin 80 Tokenizer.Expect('(', tkSpecialSymbol); 83 if Tokenizer.CheckNextAndRead('(', tkSpecialSymbol) then begin 81 84 for I := 0 to FunctionDef.Params.Count - 1 do begin 82 85 if I > 0 then Tokenizer.Expect(',', tkSpecialSymbol); … … 160 163 Prog.SystemBlock.Free; 161 164 Prog.SystemBlock := SystemBlock; 162 if Tokenizer.CheckNext('program', tkKeyword) then begin 163 Tokenizer.Expect('program', tkKeyword); 165 if Tokenizer.CheckNextAndRead('program', tkKeyword) then begin 164 166 Token := Tokenizer.GetNext; 165 167 if Token.Kind = tkIdentifier then … … 216 218 TypeRef: TType; 217 219 begin 218 if Tokenizer.CheckNext('var', tkKeyword) then begin 219 Result := True; 220 Tokenizer.Expect('var', tkKeyword); 220 if Tokenizer.CheckNextAndRead('var', tkKeyword) then begin 221 Result := True; 221 222 while Tokenizer.CheckNextKind(tkIdentifier) do begin 222 223 Token := Tokenizer.GetNext; … … 251 252 TypeRef: TType; 252 253 begin 253 if Tokenizer.CheckNext('const', tkKeyword) then begin 254 Result := True; 255 Tokenizer.Expect('const', tkKeyword); 254 if Tokenizer.CheckNextAndRead('const', tkKeyword) then begin 255 Result := True; 256 256 while Tokenizer.CheckNextKind(tkIdentifier) do begin 257 257 Token := Tokenizer.GetNext; … … 300 300 begin 301 301 Result := False; 302 if Tokenizer.CheckNext('function', tkKeyword) then begin 303 Tokenizer.Expect('function', tkKeyword); 302 if Tokenizer.CheckNextAndRead('function', tkKeyword) then begin 304 303 Result := True; 305 304 Func := TFunction.Create; … … 307 306 if Token.Kind = tkIdentifier then begin 308 307 Func.Name := Token.Text; 309 if Tokenizer.CheckNext('(', tkSpecialSymbol) then begin 310 Tokenizer.Expect('(', tkSpecialSymbol); 308 if Tokenizer.CheckNextAndRead('(', tkSpecialSymbol) then begin 311 309 while not Tokenizer.CheckNext(')', tkSpecialSymbol) do begin 312 310 if Func.Params.Count > 0 then Tokenizer.Expect(',', tkSpecialSymbol); … … 324 322 end; 325 323 end; 326 if Tokenizer.CheckNext(':', tkSpecialSymbol) then begin 327 Tokenizer.Expect(':', tkSpecialSymbol); 324 if Tokenizer.CheckNextAndRead(':', tkSpecialSymbol) then begin 328 325 Token := Tokenizer.GetNext; 329 326 if Token.Kind = tkIdentifier then begin … … 402 399 end; 403 400 404 function TParserPascal.ParseExpression(Block: TBlock; out Expression: TExpression 405 ): Boolean;401 function TParserPascal.ParseExpression(Block: TBlock; out Expression: TExpression; 402 WithOperation: Boolean = True): Boolean; 406 403 var 407 404 ExpressionOperation: TExpressionOperation; 408 405 ExpressionOperand: TExpressionOperand; 409 begin 410 Result := False; 411 if ParseExpressionOperation(Block, ExpressionOperation) then begin 406 ExpressionBrackets: TExpressionBrackets; 407 begin 408 Result := False; 409 if WithOperation and ParseExpressionOperation(Block, ExpressionOperation) then begin 412 410 Result := True; 413 411 Expression := ExpressionOperation; 412 end else 413 if ParseExpressionBrackets(Block, ExpressionBrackets) then begin 414 Result := True; 415 Expression := ExpressionBrackets; 414 416 end else 415 417 if ParseExpressionOperand(Block, ExpressionOperand) then begin … … 422 424 ExpressionOperation: TExpressionOperation): Boolean; 423 425 var 424 Operand: TExpressionOperand;425 Token: TToken;426 426 Expression: TExpression; 427 Token: TToken; 427 428 LastPos: TTokenizerPos; 428 429 I: Integer; … … 431 432 Result := False; 432 433 LastPos := Tokenizer.Pos; 433 if ParseExpression Operand(Block, Operand) then begin434 if ParseExpression(Block, Expression, False) then begin 434 435 Token := Tokenizer.GetNext; 435 if (Token.Kind = tkSpecialSymbol) andTokenizer.IsOperator(Token.Text) then begin436 if Tokenizer.IsOperator(Token.Text) then begin 436 437 Result := True; 437 438 ExpressionOperation := TExpressionOperation.Create; 438 ExpressionOperation.TypeRef := Operand.GetType; 439 if Token.Text = '+' then ExpressionOperation.Operation := eoAdd 440 else if Token.Text = '-' then ExpressionOperation.Operation := eoSub 441 else if Token.Text = '=' then ExpressionOperation.Operation := eoEqual 442 else if Token.Text = '<>' then ExpressionOperation.Operation := eoNotEqual 443 else Error('Unsupported operator ' + Token.Text); 439 ExpressionOperation.Items.Add(Expression); 440 ExpressionOperation.TypeRef := Expression.GetType; 441 ExpressionOperation.Operation := GetOperatorByName(Token.Text); 442 if ExpressionOperation.Operation = eoNone then 443 Error('Unsupported operator ' + Token.Text); 444 444 ExpressionOperation.FunctionRef := ExpressionOperation.TypeRef.Functions.SearchByName(ExpressionOperation.GetFunctionName); 445 if not Assigned(ExpressionOperation.FunctionRef.ResultType) then 446 raise Exception.Create('Missing result type for function'); 447 ExpressionOperation.TypeRef := ExpressionOperation.FunctionRef.ResultType; 448 ExpressionOperation.Items.Add(Operand); 449 I := 1; 450 if ParseExpression(Block, Expression) then begin 451 ExpectedType := TFunctionParameter(ExpressionOperation.FunctionRef.Params[I]).TypeRef; 452 if Expression.GetType = ExpectedType then 453 ExpressionOperation.Items.Add(Expression) 454 else Error('Expression operands needs to be same type. Expected ' + ExpectedType.Name + ' but found ' + Expression.GetType.Name); 455 end else Error('Missing operand.'); 456 end else Operand.Free; 445 if Assigned(ExpressionOperation.FunctionRef) then begin 446 if not Assigned(ExpressionOperation.FunctionRef.ResultType) then 447 raise Exception.Create('Missing result type for function'); 448 ExpressionOperation.TypeRef := ExpressionOperation.FunctionRef.ResultType; 449 I := 1; 450 if ParseExpression(Block, Expression) then begin 451 ExpectedType := TFunctionParameter(ExpressionOperation.FunctionRef.Params[I]).TypeRef; 452 if Expression.GetType = ExpectedType then 453 ExpressionOperation.Items.Add(Expression) 454 else Error('Expression operands needs to be same type. Expected ' + ExpectedType.Name + ' but found ' + Expression.GetType.Name); 455 end else Error('Missing operand.'); 456 end else Error('Operator ' + Token.Text + ' not defind for type ' + ExpressionOperation.TypeRef.Name + '.'); 457 end else Expression.Free; 457 458 end; 458 459 if not Result then Tokenizer.Pos := LastPos; … … 490 491 ExpressionOperand.VariableRef := Variable; 491 492 ExpressionOperand.OperandType := otVariableRef; 492 end else Error('Expected expression operand.'); 493 end else 494 Error('Expected expression operand.'); 495 end; 496 497 function TParserPascal.ParseExpressionBrackets(Block: TBlock; out 498 ExpressionBrackets: TExpressionBrackets): Boolean; 499 var 500 Expression: TExpression; 501 begin 502 Result := False; 503 if Tokenizer.CheckNextAndRead('(', tkSpecialSymbol) then begin 504 Result := True; 505 if ParseExpression(Block, Expression) then begin 506 ExpressionBrackets := TExpressionBrackets.Create; 507 ExpressionBrackets.Expression := Expression; 508 end; 509 Tokenizer.Expect(')', tkSpecialSymbol); 510 end; 493 511 end; 494 512 … … 562 580 begin 563 581 Result := False; 564 if Tokenizer.CheckNext('if', tkKeyword) then begin 565 Tokenizer.Expect('if', tkKeyword); 582 if Tokenizer.CheckNextAndRead('if', tkKeyword) then begin 566 583 Result := True; 567 584 IfThenElse := TIfThenElse.Create; … … 574 591 IfThenElse.CommandThen := Command; 575 592 Command.Parent := IfThenElse; 576 if Tokenizer.CheckNext('else', tkKeyword) then begin 577 Tokenizer.Expect('else', tkKeyword); 593 if Tokenizer.CheckNextAndRead('else', tkKeyword) then begin 578 594 if ParseCommand(Block, Command) then begin 579 595 IfThenElse.CommandElse.Free; … … 593 609 begin 594 610 Result := False; 595 if Tokenizer.CheckNext('while', tkKeyword) then begin 596 Tokenizer.Expect('while', tkKeyword); 611 if Tokenizer.CheckNextAndRead('while', tkKeyword) then begin 597 612 Result := True; 598 613 WhileDo := TWhileDo.Create; … … 617 632 begin 618 633 Result := False; 619 if Tokenizer.CheckNext('repeat', tkKeyword) then begin 620 Tokenizer.Expect('repeat', tkKeyword); 634 if Tokenizer.CheckNextAndRead('repeat', tkKeyword) then begin 621 635 RepeatUntil := TRepeatUntil.Create; 622 636 Result := True; … … 647 661 begin 648 662 Result := False; 649 if Tokenizer.CheckNext('for', tkKeyword) then begin 650 Tokenizer.Expect('for', tkKeyword); 663 if Tokenizer.CheckNextAndRead('for', tkKeyword) then begin 651 664 Result := True; 652 665 ForToDo := TForToDo.Create; … … 676 689 begin 677 690 Result := False; 678 if Tokenizer.CheckNext('break', tkKeyword) then begin 679 Tokenizer.Expect('break', tkKeyword); 691 if Tokenizer.CheckNextAndRead('break', tkKeyword) then begin 680 692 Result := True; 681 693 BreakCmd := TBreak.Create; … … 687 699 begin 688 700 Result := False; 689 if Tokenizer.CheckNext('continue', tkKeyword) then begin 690 Tokenizer.Expect('continue', tkKeyword); 701 if Tokenizer.CheckNextAndRead('continue', tkKeyword) then begin 691 702 Result := True; 692 703 ContinueCmd := TContinue.Create;
Note:
See TracChangeset
for help on using the changeset viewer.