unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, PaxCompiler, PaxProgram, PaxRegister;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    H_ShowMessage: Integer;
    H_S: Integer;
    S: AnsiString;
    { Private declarations }
    procedure SaveToStreamHandler(Sender: TPaxProgram; Stream: TStream);
    procedure LoadFromStreamHandler(Sender: TPaxProgram; Stream: TStream);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.SaveToStreamHandler(Sender: TPaxProgram; Stream: TStream);
var
  I: Byte;
begin
  I := 5;
  Stream.Write(I, 1);
  ShowMessage('Saved custom data : ' + IntToStr(I));
end;

procedure TForm1.LoadFromStreamHandler(Sender: TPaxProgram; Stream: TStream);
var
  I: Byte;
begin
  Stream.Read(I, 1);
  ShowMessage('Loaded custom data : ' + IntToStr(I));
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  PaxCompiler1: TPaxCompiler;
  PaxPascalLanguage1: TPaxPascalLanguage;
  PaxProgram1: TPaxProgram;
begin
  PaxCompiler1 := TPaxCompiler.Create(nil);
  PaxPascalLanguage1 := TPaxPascalLanguage.Create(nil);
  PaxProgram1 := TPaxProgram.Create(nil);

  try
    PaxCompiler1.RegisterLanguage(PaxPascalLanguage1);

    // register routine 'ShowMessage'
    H_ShowMessage := PaxCompiler1.RegisterHeader(0, 'procedure ShowMessage(const Msg: string);');

    // register variable 'S'
    H_S := PaxCompiler1.RegisterVariable(0, 'S', _typeSTRING);

    PaxCompiler1.AddModule('1', PaxPascalLanguage1.LanguageName);
    PaxCompiler1.AddCode('1', 'begin');
    PaxCompiler1.AddCode('1', '  ShowMessage(S);');
    PaxCompiler1.AddCode('1', 'end.');

    if PaxCompiler1.Compile(PaxProgram1) then
    begin
      PaxProgram1.OnSaveToStream := SaveToStreamHandler;
      PaxProgram1.SaveToFile('1.bin');
      ShowMessage('Compiled script has been created!');
    end
    else
      for I:=0 to PaxCompiler1.ErrorCount - 1 do
        ShowMessage(PaxCompiler1.ErrorMessage[I]);
  finally
    PaxCompiler1.Free;
    PaxPascalLanguage1.Free;
    PaxProgram1.Free;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  PaxProgram1: TPaxProgram;
begin
  if FileExists('1.bin') and (H_ShowMessage <> 0) and (H_S <> 0) then
  begin
    PaxProgram1 := TPaxProgram.Create(nil);
    try
      PaxProgram1.OnLoadFromStream := LoadFromStreamHandler;
      PaxProgram1.LoadFromFile('1.bin');
      PaxProgram1.SetAddress(H_ShowMessage, @ShowMessage);
      PaxProgram1.SetAddress(H_S, @S);
      PaxProgram1.Run;
    finally
      PaxProgram1.Free;
    end;
  end
  else
    ShowMessage('Press the first button to create compiled script.');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  H_ShowMessage := 0;
  H_S := 0;
  S := 'Hello';
end;

end.
