Changeset 233 for branches/xpascal/Parsers/ParserPascal.pas
- Timestamp:
- Jun 26, 2023, 6:08:23 PM (17 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/xpascal/Parsers/ParserPascal.pas
r230 r233 14 14 function ParseBeginEnd(Block: TBlock; out BeginEnd: TBeginEnd): Boolean; 15 15 function ParseFunctionCall(Block: TBlock; out FunctionCall: TFunctionCall): Boolean; 16 function ParseProcedureCall(Block: TBlock; out ProcedureCall: TProcedureCall): Boolean; 16 17 function ParseCommand(Block: TBlock; out Command: TCommand): Boolean; 17 18 function ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean; override; … … 20 21 function ParseBlockConst(Block: TBlock): Boolean; 21 22 function ParseFunction(Block: TBlock; out Func: TFunction): Boolean; 23 function ParseFunctionParameters(Block: TBlock; out Params: TFunctionParameters): Boolean; 22 24 function ParseFunctionParameter(Block: TBlock; out Parameter: TFunctionParameter): Boolean; 25 function ParseProcedure(Block: TBlock; out Proc: TProcedure): Boolean; 23 26 function ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean; 24 27 function ParseExpression(Block: TBlock; out Expression: TExpression; … … 101 104 end; 102 105 106 function TParserPascal.ParseProcedureCall(Block: TBlock; out 107 ProcedureCall: TProcedureCall): Boolean; 108 var 109 Token: TToken; 110 LastPos: TTokenizerPos; 111 ProcedureDef: TProcedure; 112 Expression: TExpression; 113 I: Integer; 114 begin 115 LastPos := Tokenizer.Pos; 116 Token := Tokenizer.GetNext; 117 if Token.Kind = tkIdentifier then begin 118 ProcedureDef := Block.GetProcedure(Token.Text); 119 if Assigned(ProcedureDef) then begin 120 ProcedureCall := TProcedureCall.Create; 121 ProcedureCall.ProcedureDef := ProcedureDef; 122 if Tokenizer.CheckNextAndRead('(', tkSpecialSymbol) then begin 123 for I := 0 to ProcedureDef.Params.Count - 1 do begin 124 if I > 0 then Tokenizer.Expect(',', tkSpecialSymbol); 125 if ParseExpression(Block, Expression) then begin 126 if Expression.GetType = TFunctionParameter(ProcedureDef.Params[I]).TypeRef then 127 ProcedureCall.Params.Add(Expression) 128 else Error('Function parameter mismatch.'); 129 end else Error('Expected procedure parameter.'); 130 end; 131 Tokenizer.Expect(')', tkSpecialSymbol); 132 end; 133 Result := True; 134 end else begin 135 Result := False; 136 Tokenizer.Pos := LastPos; 137 end; 138 end else begin 139 Result := False; 140 Tokenizer.Pos := LastPos; 141 end; 142 end; 143 103 144 function TParserPascal.ParseCommand(Block: TBlock; out Command: TCommand): Boolean; 104 145 var 105 146 BeginEnd: TBeginEnd; 106 147 FunctionCall: TFunctionCall; 148 ProcedureCall: TProcedureCall; 107 149 Assignment: TAssignment; 108 150 IfThenElse: TIfThenElse; … … 132 174 Result := True; 133 175 Command := FunctionCall; 176 end else 177 if ParseProcedureCall(Block, ProcedureCall) then begin 178 Result := True; 179 Command := ProcedureCall; 134 180 end else 135 181 if ParseRepeatUntil(Block, RepeatUntil) then begin … … 183 229 BeginEnd: TBeginEnd; 184 230 Func: TFunction; 231 Proc: TProcedure; 185 232 begin 186 233 Result := False; … … 195 242 if ParseFunction(Block, Func) then begin 196 243 Block.Functions.Add(Func); 197 end else begin 244 end else 245 if ParseProcedure(Block, Proc) then begin 246 Block.Procedures.Add(Proc); 247 end else 248 begin 198 249 Break; 199 250 end; … … 291 342 var 292 343 Token: TToken; 293 FunctionParameter: TFunctionParameter;294 344 NewBlock: TBlock; 295 345 TypeRef: TType; 296 346 Variable: TVariable; 297 I: Integer;347 FunctionParameters: TFunctionParameters; 298 348 begin 299 349 Result := False; … … 304 354 if Token.Kind = tkIdentifier then begin 305 355 Func.Name := Token.Text; 306 if Tokenizer.CheckNextAndRead('(', tkSpecialSymbol) then begin 307 while not Tokenizer.CheckNext(')', tkSpecialSymbol) do begin 308 if Func.Params.Count > 0 then Tokenizer.Expect(',', tkSpecialSymbol); 309 if ParseFunctionParameter(Block, FunctionParameter) then begin 310 Func.Params.Add(FunctionParameter); 311 end else Error('Expected function parameter.'); 312 end; 313 Tokenizer.Expect(')', tkSpecialSymbol); 314 for I := 0 to Func.Params.Count - 1 do begin 315 Variable := TVariable.Create; 316 Variable.Name := TFunctionParameter(Func.Params[I]).Name; 317 Variable.TypeRef := TFunctionParameter(Func.Params[I]).TypeRef; 318 Variable.Internal := True; 319 Func.Block.Variables.Add(Variable); 320 end; 321 end; 356 Func.Block.ParentBlock := Block; 357 if ParseFunctionParameters(Func.Block, FunctionParameters) then begin 358 Func.Params.Free; 359 Func.Params := FunctionParameters; 360 end; 361 322 362 if Tokenizer.CheckNextAndRead(':', tkSpecialSymbol) then begin 323 363 Token := Tokenizer.GetNext; … … 339 379 end else Error('Expected function block'); 340 380 end else Error('Expected function name'); 381 end; 382 end; 383 384 function TParserPascal.ParseFunctionParameters(Block: TBlock; 385 out Params: TFunctionParameters): Boolean; 386 var 387 FunctionParameter: TFunctionParameter; 388 I: Integer; 389 Variable: TVariable; 390 begin 391 Result := False; 392 Params := TFunctionParameters.Create; 393 if Tokenizer.CheckNextAndRead('(', tkSpecialSymbol) then begin 394 while not Tokenizer.CheckNext(')', tkSpecialSymbol) do begin 395 if Params.Count > 0 then Tokenizer.Expect(',', tkSpecialSymbol); 396 if ParseFunctionParameter(Block, FunctionParameter) then begin 397 Params.Add(FunctionParameter); 398 end else Error('Expected function parameter.'); 399 end; 400 Tokenizer.Expect(')', tkSpecialSymbol); 401 for I := 0 to Params.Count - 1 do begin 402 Variable := TVariable.Create; 403 Variable.Name := Params[I].Name; 404 Variable.TypeRef := Params[I].TypeRef; 405 Variable.Internal := True; 406 Block.Variables.Add(Variable); 407 end; 408 Result := True; 341 409 end; 342 410 end; … … 368 436 end else Error('Expected parameter type'); 369 437 end else Error('Expected parameter name'); 438 end; 439 440 function TParserPascal.ParseProcedure(Block: TBlock; out Proc: TProcedure 441 ): Boolean; 442 var 443 Token: TToken; 444 NewBlock: TBlock; 445 FunctionParameters: TFunctionParameters; 446 begin 447 Result := False; 448 if Tokenizer.CheckNextAndRead('procedure', tkKeyword) then begin 449 Result := True; 450 Proc := TProcedure.Create; 451 Token := Tokenizer.GetNext; 452 if Token.Kind = tkIdentifier then begin 453 Proc.Name := Token.Text; 454 Proc.Block.ParentBlock := Block; 455 if ParseFunctionParameters(Proc.Block, FunctionParameters) then begin 456 Proc.Params.Free; 457 Proc.Params := FunctionParameters; 458 end; 459 460 Tokenizer.Expect(';', tkSpecialSymbol); 461 if ParseBlock(Block, NewBlock, Proc.Block) then begin 462 Tokenizer.Expect(';', tkSpecialSymbol); 463 end else Error('Expected procedure block'); 464 end else Error('Expected procedure name'); 465 end; 370 466 end; 371 467
Note:
See TracChangeset
for help on using the changeset viewer.