Changeset 212 for branches/interpreter2/UParser.pas
- Timestamp:
- Apr 22, 2020, 12:04:22 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/interpreter2/UParser.pas
r211 r212 20 20 function ParseCommand(Block: TBlock; out Command: TCommand): Boolean; 21 21 function ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean; 22 function ParseBlock(ParentBlock: TBlock; out Block: TBlock ): Boolean;22 function ParseBlock(ParentBlock: TBlock; out Block: TBlock; ExistingBlock: TBlock = nil): Boolean; 23 23 function ParseBlockVar(Block: TBlock): Boolean; 24 24 function ParseBlockConst(Block: TBlock): Boolean; 25 function ParseFunction(Block: TBlock; out Func: TFunction): Boolean; 26 function ParseFunctionParameter(Block: TBlock; out Parameter: TFunctionParameter): Boolean; 25 27 function ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean; 26 28 function ParseExpression(Block: TBlock; out Expression: TExpression): Boolean; … … 194 196 end; 195 197 196 function TParser.ParseBlock(ParentBlock: TBlock; out Block: TBlock ): Boolean;198 function TParser.ParseBlock(ParentBlock: TBlock; out Block: TBlock; ExistingBlock: TBlock = nil): Boolean; 197 199 var 198 200 BeginEnd: TBeginEnd; 199 begin 200 Result := False; 201 Block := TBlock.Create; 201 Func: TFunction; 202 begin 203 Result := False; 204 if Assigned(ExistingBlock) then Block := ExistingBlock 205 else Block := TBlock.Create; 202 206 Block.ParentBlock := ParentBlock; 203 ParseBlockVar(Block); 204 ParseBlockConst(Block); 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; 205 218 if ParseBeginEnd(Block, BeginEnd) then begin 206 219 Result := True; … … 208 221 Block.BeginEnd := BeginEnd; 209 222 BeginEnd.Parent := Block; 210 end else Block.Free; 223 end else begin 224 if not Assigned(ExistingBlock) then Block.Free; 225 Block := nil; 226 end; 211 227 end; 212 228 … … 291 307 end; 292 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 293 388 function TParser.ParseAssignment(Block: TBlock; out Assignment: TAssignment): Boolean; 294 389 var … … 315 410 end else begin 316 411 Result := False; 317 Error('Assignment type mismatch. ');412 Error('Assignment type mismatch. Expected ' + Variable.TypeRef.Name + ' but got ' + Expression.GetType.Name); 318 413 end; 319 414 end; … … 348 443 Expression: TExpression; 349 444 LastPos: TTokenizerPos; 445 I: Integer; 446 ExpectedType: TType; 350 447 begin 351 448 Result := False; … … 362 459 else if Token.Text = '<>' then ExpressionOperation.Operation := eoNotEqual 363 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; 364 465 ExpressionOperation.Items.Add(Operand); 466 I := 1; 365 467 if ParseExpression(Block, Expression) then begin 366 if Expression.GetType = Operand.GetType then 468 ExpectedType := TFunctionParameter(ExpressionOperation.FunctionRef.Params[I]).TypeRef; 469 if Expression.GetType = ExpectedType then 367 470 ExpressionOperation.Items.Add(Expression) 368 else Error('Expression operands needs to be same type. ');471 else Error('Expression operands needs to be same type. Expected ' + ExpectedType.Name + ' but found ' + Expression.GetType.Name); 369 472 end else Error('Missing operand.'); 370 473 end else Operand.Free;
Note:
See TracChangeset
for help on using the changeset viewer.