unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, PaxCompiler, PaxProgram, PaxRegister;
type
  TForm1 = class(TForm)
    PaxCompiler1: TPaxCompiler;
    PaxPascalLanguage1: TPaxPascalLanguage;
    PaxProgram1: TPaxProgram;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    Y: Integer;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// declare procedural type that conforms to a script-defined procedure
type
  TProcP = procedure (X: Integer); stdcall;

procedure TForm1.Button1Click(Sender: TObject);
var
  H_Y, H_P: Integer;
  I: Integer;
  P: Pointer;
begin
{$O-}
  PaxCompiler1.Reset;
  PaxCompiler1.RegisterLanguage(PaxPascalLanguage1);

  H_Y := PaxCompiler1.RegisterVariable(0, 'Y', _typeINTEGER, @Y);

  PaxCompiler1.AddModule('1', PaxPascalLanguage1.LanguageName);
  PaxCompiler1.AddCode('1', 'procedure P(X: Integer); stdcall;');
  PaxCompiler1.AddCode('1', 'begin');
  PaxCompiler1.AddCode('1', '  Y := Y + X;');
  PaxCompiler1.AddCode('1', 'end;');
  PaxCompiler1.AddCode('1', 'begin');
  PaxCompiler1.AddCode('1', 'end.');

  if PaxCompiler1.Compile(PaxProgram1) then
  begin
    H_P := PaxCompiler1.GetHandle(0, 'P', true);
    P := PaxProgram1.GetAddress(H_P); // get address of script-defind procedure

    TProcP(P)(10); // call it
    ShowMessage(IntToStr(Y));

    TProcP(P)(20); // call it
    ShowMessage(IntToStr(Y));
  end
  else
    for I:=0 to PaxCompiler1.ErrorCount do
      ShowMessage(PaxCompiler1.ErrorMessage[I]);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Y := 0;
end;

end.
