remobjects / pascalscript

pascalscript
Other
447 stars 178 forks source link

Param with type "array of const" doesn't work #241

Open zedxxx opened 3 years ago

zedxxx commented 3 years ago

I want use in script this Delphi function: function Format_P(const Format: string; const Args: array of const): string;

If I use PascalScript sources from stable branch then all works fine, but when I switch to the master branch Args receives some garbage instead of actual values. My Delphi version is 10.3.3.

This bug can be easily reproduced with the test:

program FormatTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  SysUtils,
  uPSUtils,
  uPSRuntime,
  uPSCompiler;

function Format_P(const Format: string; const Args: array of const): string;
begin
  Result := SysUtils.Format(Format, Args);
  Writeln(Result); // for debug only
end;

function ScriptOnUses(Sender: TPSPascalCompiler; const AName: TbtString): Boolean;
begin
  if AName = 'SYSTEM' then begin
    Sender.AddDelphiFunction(
      'function Format_P(const Format: string; const Args: array of const): string'
    );
    Result := True;
  end else begin
    Result := False;
  end;
end;

procedure ExecuteScript(const AScript: AnsiString);
var
  I: Integer;
  VCompiler: TPSPascalCompiler;
  VExec: TPSExec;
  VData: AnsiString;
begin
  VCompiler := TPSPascalCompiler.Create;
  try
    VCompiler.OnUses := ScriptOnUses;
    if not VCompiler.Compile(AScript) then begin
      for I := 0 to VCompiler.MsgCount - 1 do begin
        Writeln(VCompiler.Msg[I].MessageToString);
      end;
      raise Exception.Create('Compile filed!');
    end;

    VCompiler.GetOutput(VData);
  finally
    VCompiler.Free;
  end;

  VExec := TPSExec.Create;
  try
    VExec.RegisterDelphiFunction(@Format_P, 'Format_P', cdRegister);

    if not VExec.LoadData(VData) then begin
      raise Exception.Create('Exec filed!');
    end;

    VExec.RunScript;
  finally
    VExec.Free;
  end;
end;

const
  VScript = 'begin Format_P(''a=%d b=%d'', [1, 2]); end.';
begin
  try
    ExecuteScript(AnsiString(VScript));
  except
    on E: Exception do begin
      Writeln(E.ClassName, ': ', E.Message);
    end;
  end;

  Writeln('Press ENTER to exit...');
  Readln;
end.

Test result:

zedxxx commented 3 years ago

I found that it stopped working after this commit: https://github.com/remobjects/pascalscript/commit/86a057c8686143ce0443be6995d6515c5c9b705c

@Vizit0r can you look into this?

Vizit0r commented 3 years ago

@zedxxx on my latest connit, which i already push to my rep, and awaiting for @carlokok approval to merge with main code - all works fine, checked it right now. a=1 b=2 Press ENTER to exit...

carlokok commented 3 years ago

@Vizit0r which branch/pr?

Vizit0r commented 3 years ago

@carlokok look at the "main" thread - https://github.com/remobjects/pascalscript/pull/225 or i miss something and it does not requested as merge?

zedxxx commented 3 years ago

@Vizit0r I tested your fork and can confirm that it fixes this bug.