Ignore:
Timestamp:
Jun 27, 2023, 10:09:21 AM (17 months ago)
Author:
chronos
Message:
  • Modified: Improved function var parameter handling.
  • Modified: Code cleanup.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/xpascal/Executor.pas

    r233 r235  
    163163    procedure ExecuteBlock(ParentBlock: TExecutorBlock; Block: TBlock; ExistingBlock: TExecutorBlock = nil);
    164164    function ExecuteFunctionCall(Block: TExecutorBlock; FunctionCall: TFunctionCall): TValue;
    165     function ExecuteProcedureCall(Block: TExecutorBlock; ProcedureCall: TProcedureCall): TValue;
     165    procedure ExecuteProcedureCall(Block: TExecutorBlock; ProcedureCall: TProcedureCall);
    166166    procedure ExecuteAssignment(Block: TExecutorBlock; Assignment: TAssignment);
    167167    function ExecuteExpression(Block: TExecutorBlock; Expression: TExpression): TValue;
     
    195195begin
    196196  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]
    199199    else Result := nil;
    200200end;
     
    275275begin
    276276  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]
    279279    else Result := nil;
    280280end;
     
    295295begin
    296296  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]
    299299    else Result := nil;
    300300end;
     
    314314begin
    315315  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]
    318318    else Result := nil;
    319319end;
     
    634634  J: Integer;
    635635  ExecutorFunction: TExecutorFunction;
     636  ExecutorProcedure: TExecutorProcedure;
    636637  ExecutorType: TExecutorType;
    637638begin
     
    723724    end;
    724725  end;
    725   for I := 0 to Block.Variables.Count - 1 do
     726
     727  for I := 0 to Block.Variables.Count - 1 do begin
    726728    ExecutorBlock.Variables.AddNew(TVariable(Block.Variables[I]));
     729  end;
     730
    727731  for I := 0 to Block.Functions.Count - 1 do begin
    728732    ExecutorFunction := ExecutorBlock.Functions.AddNew(TFunction(Block.Functions[I]));
    729     if ExecutorFunction.FunctionDef.Name = 'Write' then begin
    730       ExecutorFunction.Callback := ExecuteWrite;
    731     end else
    732     if ExecutorFunction.FunctionDef.Name = 'WriteLn' then begin
    733       ExecutorFunction.Callback := ExecuteWriteLn;
    734     end else
    735     if ExecutorFunction.FunctionDef.Name = 'Read' then begin
    736       ExecutorFunction.Callback := ExecuteRead;
    737     end else
    738     if ExecutorFunction.FunctionDef.Name = 'ReadLn' then begin
    739       ExecutorFunction.Callback := ExecuteReadLn;
    740     end else
    741733    if ExecutorFunction.FunctionDef.Name = 'IntToStr' then begin
    742734      ExecutorFunction.Callback := ExecuteIntToStr;
     
    750742    if ExecutorFunction.FunctionDef.Name = 'StrToBool' then begin
    751743      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;
    752760    end;
    753761  end;
     
    946954      Result := ExecutorFunction.Callback(Params);
    947955      for I := 0 to FunctionCall.Params.Count - 1 do begin
    948         //if FunctionCall.Params[I].
    949956        Params[I].Free;
    950957      end;
    951958    end else begin
    952959      InitExecutorBlock(ExecutorFunction.Block, FunctionCall.FunctionDef.Block);
     960
     961      // Clean variables
    953962      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;
    958974      end;
     975
    959976      ExecuteBlock(Block, FunctionCall.FunctionDef.Block, ExecutorFunction.Block);
    960977      ExecutorVariable := ExecutorFunction.Block.Variables.SearchByVariable(TVariable(FunctionCall.FunctionDef.Block.Variables.SearchByName('Result')));
     
    964981end;
    965982
    966 function TExecutor.ExecuteProcedureCall(Block: TExecutorBlock;
    967   ProcedureCall: TProcedureCall): TValue;
     983procedure TExecutor.ExecuteProcedureCall(Block: TExecutorBlock;
     984  ProcedureCall: TProcedureCall);
    968985var
    969986  ExecutorProcedure: TExecutorProcedure;
     
    973990  Variable: TVariable;
    974991begin
    975   Result := nil;
    976992  ExecutorProcedure := Block.GetProcedure(ProcedureCall.ProcedureDef);
    977993  if Assigned(ExecutorProcedure) then begin
     
    9891005        else Params[I].Value := ExecuteExpression(Block, ProcedureCall.Params[I]);
    9901006      end;
    991       Result := ExecutorProcedure.Callback(Params);
     1007      ExecutorProcedure.Callback(Params);
    9921008      for I := 0 to ProcedureCall.Params.Count - 1 do begin
    993         //if FunctionCall.Params[I].
    9941009        Params[I].Free;
    9951010      end;
    9961011    end else begin
    9971012      InitExecutorBlock(ExecutorProcedure.Block, ProcedureCall.ProcedureDef.Block);
     1013
     1014      // Clean variables
    9981015      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;
    10041028      end;
     1029
    10051030      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;
    10091031    end;
    10101032  end else raise Exception.Create('No executor for ' + ProcedureCall.ProcedureDef.Name + ' function.');
     
    10221044  Variable := Block.GetVariable(Assignment.Variable);
    10231045  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
    10251047    SetLength(Params, 1);
    10261048    Params[0] := TExecutorFunctionCallbackParam.Create;
Note: See TracChangeset for help on using the changeset viewer.