Changeset 235
- Timestamp:
- Jun 27, 2023, 10:09:21 AM (18 months ago)
- Location:
- branches/xpascal
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/xpascal/Executor.pas
r233 r235 163 163 procedure ExecuteBlock(ParentBlock: TExecutorBlock; Block: TBlock; ExistingBlock: TExecutorBlock = nil); 164 164 function ExecuteFunctionCall(Block: TExecutorBlock; FunctionCall: TFunctionCall): TValue; 165 function ExecuteProcedureCall(Block: TExecutorBlock; ProcedureCall: TProcedureCall): TValue;165 procedure ExecuteProcedureCall(Block: TExecutorBlock; ProcedureCall: TProcedureCall); 166 166 procedure ExecuteAssignment(Block: TExecutorBlock; Assignment: TAssignment); 167 167 function ExecuteExpression(Block: TExecutorBlock; Expression: TExpression): TValue; … … 195 195 begin 196 196 I := 0; 197 while (I < Count) and ( TExecutorProcedure(Items[I]).ProcedureDef <> ProcedureDef) do Inc(I);198 if I < Count then Result := TExecutorProcedure(Items[I])197 while (I < Count) and (Items[I].ProcedureDef <> ProcedureDef) do Inc(I); 198 if I < Count then Result := Items[I] 199 199 else Result := nil; 200 200 end; … … 275 275 begin 276 276 I := 0; 277 while (I < Count) and ( TExecutorType(Items[I]).TypeRef <> TypeRef) do Inc(I);278 if I < Count then Result := TExecutorType(Items[I])277 while (I < Count) and (Items[I].TypeRef <> TypeRef) do Inc(I); 278 if I < Count then Result := Items[I] 279 279 else Result := nil; 280 280 end; … … 295 295 begin 296 296 I := 0; 297 while (I < Count) and ( TExecutorFunction(Items[I]).FunctionDef <> FunctionDef) do Inc(I);298 if I < Count then Result := TExecutorFunction(Items[I])297 while (I < Count) and (Items[I].FunctionDef <> FunctionDef) do Inc(I); 298 if I < Count then Result := Items[I] 299 299 else Result := nil; 300 300 end; … … 314 314 begin 315 315 I := 0; 316 while (I < Count) and ( TExecutorVariable(Items[I]).Variable <> Variable) do Inc(I);317 if I < Count then Result := TExecutorVariable(Items[I])316 while (I < Count) and (Items[I].Variable <> Variable) do Inc(I); 317 if I < Count then Result := Items[I] 318 318 else Result := nil; 319 319 end; … … 634 634 J: Integer; 635 635 ExecutorFunction: TExecutorFunction; 636 ExecutorProcedure: TExecutorProcedure; 636 637 ExecutorType: TExecutorType; 637 638 begin … … 723 724 end; 724 725 end; 725 for I := 0 to Block.Variables.Count - 1 do 726 727 for I := 0 to Block.Variables.Count - 1 do begin 726 728 ExecutorBlock.Variables.AddNew(TVariable(Block.Variables[I])); 729 end; 730 727 731 for I := 0 to Block.Functions.Count - 1 do begin 728 732 ExecutorFunction := ExecutorBlock.Functions.AddNew(TFunction(Block.Functions[I])); 729 if ExecutorFunction.FunctionDef.Name = 'Write' then begin730 ExecutorFunction.Callback := ExecuteWrite;731 end else732 if ExecutorFunction.FunctionDef.Name = 'WriteLn' then begin733 ExecutorFunction.Callback := ExecuteWriteLn;734 end else735 if ExecutorFunction.FunctionDef.Name = 'Read' then begin736 ExecutorFunction.Callback := ExecuteRead;737 end else738 if ExecutorFunction.FunctionDef.Name = 'ReadLn' then begin739 ExecutorFunction.Callback := ExecuteReadLn;740 end else741 733 if ExecutorFunction.FunctionDef.Name = 'IntToStr' then begin 742 734 ExecutorFunction.Callback := ExecuteIntToStr; … … 750 742 if ExecutorFunction.FunctionDef.Name = 'StrToBool' then begin 751 743 ExecutorFunction.Callback := ExecuteStrToBool; 744 end; 745 end; 746 747 for I := 0 to Block.Procedures.Count - 1 do begin 748 ExecutorProcedure := ExecutorBlock.Procedures.AddNew(TProcedure(Block.Procedures[I])); 749 if ExecutorProcedure.ProcedureDef.Name = 'Write' then begin 750 ExecutorProcedure.Callback := ExecuteWrite; 751 end else 752 if ExecutorProcedure.ProcedureDef.Name = 'WriteLn' then begin 753 ExecutorProcedure.Callback := ExecuteWriteLn; 754 end else 755 if ExecutorProcedure.ProcedureDef.Name = 'Read' then begin 756 ExecutorProcedure.Callback := ExecuteRead; 757 end else 758 if ExecutorProcedure.ProcedureDef.Name = 'ReadLn' then begin 759 ExecutorProcedure.Callback := ExecuteReadLn; 752 760 end; 753 761 end; … … 946 954 Result := ExecutorFunction.Callback(Params); 947 955 for I := 0 to FunctionCall.Params.Count - 1 do begin 948 //if FunctionCall.Params[I].949 956 Params[I].Free; 950 957 end; 951 958 end else begin 952 959 InitExecutorBlock(ExecutorFunction.Block, FunctionCall.FunctionDef.Block); 960 961 // Clean variables 953 962 for I := 0 to FunctionCall.Params.Count - 1 do begin 954 Variable := FunctionCall.FunctionDef.Block.Variables.SearchByName(TFunctionParameter(FunctionCall.FunctionDef.Params[I]).Name); 955 ExecutorVariable := ExecutorFunction.Block.Variables.SearchByVariable(Variable); 956 ExecutorVariable.Value.Free; 957 ExecutorVariable.Value := ExecuteExpression(Block, TExpression(FunctionCall.Params[I])); 963 if FunctionCall.FunctionDef.Params[I].Kind = pkVar then begin 964 Variable := TExpressionOperand(FunctionCall.Params[I]).VariableRef; 965 ExecutorVariable := Block.Variables.SearchByVariable(Variable); 966 ExecutorFunction.Block.Variables[I] := ExecutorVariable; 967 end else begin 968 Variable := FunctionCall.FunctionDef.Block.Variables.SearchByName( 969 TFunctionParameter(FunctionCall.FunctionDef.Params[I]).Name); 970 ExecutorVariable := ExecutorFunction.Block.Variables.SearchByVariable(Variable); 971 ExecutorVariable.Value.Free; 972 ExecutorVariable.Value := ExecuteExpression(Block, TExpression(FunctionCall.Params[I])); 973 end; 958 974 end; 975 959 976 ExecuteBlock(Block, FunctionCall.FunctionDef.Block, ExecutorFunction.Block); 960 977 ExecutorVariable := ExecutorFunction.Block.Variables.SearchByVariable(TVariable(FunctionCall.FunctionDef.Block.Variables.SearchByName('Result'))); … … 964 981 end; 965 982 966 functionTExecutor.ExecuteProcedureCall(Block: TExecutorBlock;967 ProcedureCall: TProcedureCall) : TValue;983 procedure TExecutor.ExecuteProcedureCall(Block: TExecutorBlock; 984 ProcedureCall: TProcedureCall); 968 985 var 969 986 ExecutorProcedure: TExecutorProcedure; … … 973 990 Variable: TVariable; 974 991 begin 975 Result := nil;976 992 ExecutorProcedure := Block.GetProcedure(ProcedureCall.ProcedureDef); 977 993 if Assigned(ExecutorProcedure) then begin … … 989 1005 else Params[I].Value := ExecuteExpression(Block, ProcedureCall.Params[I]); 990 1006 end; 991 Result :=ExecutorProcedure.Callback(Params);1007 ExecutorProcedure.Callback(Params); 992 1008 for I := 0 to ProcedureCall.Params.Count - 1 do begin 993 //if FunctionCall.Params[I].994 1009 Params[I].Free; 995 1010 end; 996 1011 end else begin 997 1012 InitExecutorBlock(ExecutorProcedure.Block, ProcedureCall.ProcedureDef.Block); 1013 1014 // Clean variables 998 1015 for I := 0 to ProcedureCall.Params.Count - 1 do begin 999 Variable := ProcedureCall.ProcedureDef.Block.Variables.SearchByName( 1000 TFunctionParameter(ProcedureCall.ProcedureDef.Params[I]).Name); 1001 ExecutorVariable := ExecutorProcedure.Block.Variables.SearchByVariable(Variable); 1002 ExecutorVariable.Value.Free; 1003 ExecutorVariable.Value := ExecuteExpression(Block, TExpression(ProcedureCall.Params[I])); 1016 if ProcedureCall.ProcedureDef.Params[I].Kind = pkVar then begin 1017 Variable := TExpressionOperand(ProcedureCall.Params[I]).VariableRef; 1018 ExecutorVariable := Block.Variables.SearchByVariable(Variable); 1019 ExecutorProcedure.Block.Variables[I].Variable := Variable; 1020 ExecutorProcedure.Block.Variables[I].Value := ExecutorVariable.Value; 1021 end else begin 1022 Variable := ProcedureCall.ProcedureDef.Block.Variables.SearchByName( 1023 TFunctionParameter(ProcedureCall.ProcedureDef.Params[I]).Name); 1024 ExecutorVariable := ExecutorProcedure.Block.Variables.SearchByVariable(Variable); 1025 ExecutorVariable.Value.Free; 1026 ExecutorVariable.Value := ExecuteExpression(Block, TExpression(ProcedureCall.Params[I])); 1027 end; 1004 1028 end; 1029 1005 1030 ExecuteBlock(Block, ProcedureCall.ProcedureDef.Block, ExecutorProcedure.Block); 1006 ExecutorVariable := ExecutorProcedure.Block.Variables.SearchByVariable(1007 TVariable(ProcedureCall.ProcedureDef.Block.Variables.SearchByName('Result')));1008 Result := ExecutorVariable.Value.Clone;1009 1031 end; 1010 1032 end else raise Exception.Create('No executor for ' + ProcedureCall.ProcedureDef.Name + ' function.'); … … 1022 1044 Variable := Block.GetVariable(Assignment.Variable); 1023 1045 ExecutorFunction := Block.GetTypeFunction(Assignment.Variable.TypeRef, '_Assign'); 1024 if Assignment.Variable.TypeRef = Assignment.Expression.GetType then begin ;1046 if Assignment.Variable.TypeRef = Assignment.Expression.GetType then begin 1025 1047 SetLength(Params, 1); 1026 1048 Params[0] := TExecutorFunctionCallbackParam.Create; -
branches/xpascal/Generators/GeneratorPascal.pas
r234 r235 102 102 Indent := Indent + 1; 103 103 for I := 0 to RepeatUntil.Commands.Count - 1 do begin 104 GenerateCommand(Block, TCommand(RepeatUntil.Commands[I]));104 GenerateCommand(Block, RepeatUntil.Commands[I]); 105 105 AddTextLine(';'); 106 106 end; … … 119 119 AddText('('); 120 120 for I := 0 to FunctionCall.Params.Count - 1 do 121 GenerateExpression(Block, TExpression(FunctionCall.Params[I]));121 GenerateExpression(Block, FunctionCall.Params[I]); 122 122 AddText(')'); 123 123 end; … … 133 133 AddText('('); 134 134 for I := 0 to ProcedureCall.Params.Count - 1 do 135 GenerateExpression(Block, TExpression(ProcedureCall.Params[I]));135 GenerateExpression(Block, ProcedureCall.Params[I]); 136 136 AddText(')'); 137 137 end; … … 169 169 AddText(' '); 170 170 end; 171 GenerateExpression(Block, TExpression(Expression.Items[I]));171 GenerateExpression(Block, Expression.Items[I]); 172 172 end; 173 173 end; … … 217 217 if Prog.Name <> '' then AddTextLine('program ' + Prog.Name + ';'); 218 218 AddTextLine('{$mode delphi}'); 219 AddTextLine(''); 219 220 AddTextLine('uses SysUtils;'); 220 221 GenerateBlock(Block, Prog.Block); … … 231 232 AddText('('); 232 233 for I := 0 to FunctionDef.Params.Count - 1 do begin 233 AddText( TFunctionParameter(FunctionDef.Params[I]).Name);234 AddText(FunctionDef.Params[I].Name); 234 235 AddText(': '); 235 AddText( TFunctionParameter(FunctionDef.Params[I]).TypeRef.Name);236 AddText(FunctionDef.Params[I].TypeRef.Name); 236 237 if I > 0 then AddText(', '); 237 238 end; … … 267 268 AddText('('); 268 269 for I := 0 to ProcedureDef.Params.Count - 1 do begin 269 AddText( TFunctionParameter(ProcedureDef.Params[I]).Name);270 AddText(ProcedureDef.Params[I].Name); 270 271 AddText(': '); 271 AddText( TFunctionParameter(ProcedureDef.Params[I]).TypeRef.Name);272 AddText(ProcedureDef.Params[I].TypeRef.Name); 272 273 if I > 0 then AddText(', '); 273 274 end; … … 307 308 VarCount := 0; 308 309 for I := 0 to Block.Variables.Count - 1 do 309 if not TVariable(Block.Variables[I]).Internal then Inc(VarCount);310 if not Block.Variables[I].Internal then Inc(VarCount); 310 311 311 312 if VarCount > 0 then begin … … 313 314 Indent := Indent + 1; 314 315 for I := 0 to Block.Variables.Count - 1 do 315 if not TVariable(Block.Variables[I]).Internal then begin316 Variable := TVariable(Block.Variables[I]);316 if not Block.Variables[I].Internal then begin 317 Variable := Block.Variables[I]; 317 318 AddTextLine(Variable.Name + ': ' + Variable.TypeRef.Name + ';'); 318 319 end; … … 331 332 Indent := Indent + 1; 332 333 for I := 0 to Block.Constants.Count - 1 do begin 333 Constant := TConstant(Block.Constants[I]);334 Constant := Block.Constants[I]; 334 335 AddText(Constant.Name + ': ' + Constant.TypeRef.Name + ' = '); 335 336 GenerateValue(Constant.Value); … … 348 349 Indent := Indent + 1; 349 350 for I := 0 to BeginEnd.Commands.Count - 1 do begin 350 GenerateCommand(Block, TCommand(BeginEnd.Commands[I]));351 GenerateCommand(Block, BeginEnd.Commands[I]); 351 352 AddTextLine(';'); 352 353 end; … … 361 362 begin 362 363 for I := 0 to Block.Functions.Count - 1 do begin 363 GenerateFunction(ParentBlock, TFunction(Block.Functions[I]));364 GenerateFunction(ParentBlock, Block.Functions[I]); 364 365 AddTextLine; 365 366 end; … … 372 373 begin 373 374 for I := 0 to Block.Procedures.Count - 1 do begin 374 GenerateProcedure(ParentBlock, TProcedure(Block.Procedures[I]));375 GenerateProcedure(ParentBlock, Block.Procedures[I]); 375 376 AddTextLine; 376 377 end; -
branches/xpascal/Languages/xpascal.cs.po
r234 r235 37 37 msgid "Cannot parse program." 38 38 msgstr "Nelze analyzovat program." 39 40 #: parserpascal.sexpectedfunctionparameter 41 msgid "Expected function parameter." 42 msgstr "OÄekáván parametr funkce." 43 44 #: parserpascal.sexpectedprocedureparameter 45 msgid "Expected procedure parameter." 46 msgstr "OÄekávánà parametr procedury." 47 48 #: parserpascal.sfunctionparametermismatch 49 msgid "Function parameter mismatch." 50 msgstr "Neshoda parametru funkce." 51 52 #: parserpascal.sunexpectedtoken 53 #, object-pascal-format 54 msgid "Unexpected token %s" 55 msgstr "NeoÄekávány token %s" 39 56 40 57 #: source.sindexerror … … 174 191 msgid "Unsupported tokenizer state." 175 192 msgstr "NepodporovanÃœ stav tokenizeru." 176 -
branches/xpascal/Languages/xpascal.pot
r233 r235 26 26 #: parser.scannotparseprogram 27 27 msgid "Cannot parse program." 28 msgstr "" 29 30 #: parserpascal.sexpectedfunctionparameter 31 msgid "Expected function parameter." 32 msgstr "" 33 34 #: parserpascal.sexpectedprocedureparameter 35 msgid "Expected procedure parameter." 36 msgstr "" 37 38 #: parserpascal.sfunctionparametermismatch 39 msgid "Function parameter mismatch." 40 msgstr "" 41 42 #: parserpascal.sunexpectedtoken 43 #, object-pascal-format 44 msgid "Unexpected token %s" 28 45 msgstr "" 29 46 -
branches/xpascal/Parsers/ParserPascal.pas
r233 r235 44 44 implementation 45 45 46 resourcestring 47 SExpectedFunctionParameter = 'Expected function parameter.'; 48 SExpectedProcedureParameter = 'Expected procedure parameter.'; 49 SFunctionParameterMismatch = 'Function parameter mismatch.'; 50 SUnexpectedToken = 'Unexpected token %s'; 51 46 52 function TParserPascal.ParseBeginEnd(Block: TBlock; out BeginEnd: TBeginEnd): Boolean; 47 53 var … … 57 63 Tokenizer.Expect(';', tkSpecialSymbol); 58 64 end else begin 59 Error( 'Unexpected token ' + Tokenizer.GetNext.Text);65 Error(Format(SUnexpectedToken, [Tokenizer.GetNext.Text])); 60 66 Result := False; 61 67 Break; … … 88 94 if Expression.GetType = TFunctionParameter(FunctionDef.Params[I]).TypeRef then 89 95 FunctionCall.Params.Add(Expression) 90 else Error( 'Function parameter mismatch.');91 end else Error( 'Expected function parameter.');96 else Error(SFunctionParameterMismatch); 97 end else Error(SExpectedFunctionParameter); 92 98 end; 93 99 Tokenizer.Expect(')', tkSpecialSymbol); … … 126 132 if Expression.GetType = TFunctionParameter(ProcedureDef.Params[I]).TypeRef then 127 133 ProcedureCall.Params.Add(Expression) 128 else Error( 'Function parameter mismatch.');129 end else Error( 'Expected procedure parameter.');134 else Error(SFunctionParameterMismatch); 135 end else Error(SExpectedProcedureParameter); 130 136 end; 131 137 Tokenizer.Expect(')', tkSpecialSymbol); … … 396 402 if ParseFunctionParameter(Block, FunctionParameter) then begin 397 403 Params.Add(FunctionParameter); 398 end else Error( 'Expected function parameter.');404 end else Error(SExpectedFunctionParameter); 399 405 end; 400 406 Tokenizer.Expect(')', tkSpecialSymbol); -
branches/xpascal/Tests.pas
r233 r235 155 155 Source.Add(' WriteLn(BoolToStr(IsZero(0)));'); 156 156 Source.Add(' WriteLn(BoolToStr(IsZero(1)));'); 157 Source.Add('end.'); 158 ExpectedOutput := '-1' + LineEnding + '0' + LineEnding; 159 end; 160 with TTestRun(Result.AddNew('function var parameter', TTestRun)) do begin 161 Source.Add('function Test(var A: Integer): Boolean;'); 162 Source.Add('begin'); 163 Source.Add(' A := 10;'); 164 Source.Add(' Result := True;'); 165 Source.Add('end;'); 166 Source.Add(''); 167 Source.Add('var'); 168 Source.Add(' B: Integer;'); 169 Source.Add('begin'); 170 Source.Add(' B := 1;'); 171 Source.Add(' Test(B);'); 172 Source.Add(' WriteLn(IntToStr(B));'); 157 173 Source.Add('end.'); 158 174 ExpectedOutput := '-1' + LineEnding + '0' + LineEnding;
Note:
See TracChangeset
for help on using the changeset viewer.