{$O-}
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls,

  TypInfo,
  PAXCOMP_CONSTANTS,
  PaxCompiler, PaxProgram, PaxRegister, IMPORT_COMMON;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    LoadProgram1: TPaxProgram;
    procedure Compile(const AName: String);
    procedure CreateObjectHandler(Sender: TPaxProgram;
                                  Instance: TObject);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Compile(const AName: String);
var
  PaxCompiler1: TPaxCompiler;
  PaxProgram1: TPaxProgram;
  PaxPascalLanguage1: TPaxPascalLanguage;
begin
  PaxCompiler1 := TPaxCompiler.Create(nil);
  PaxProgram1 := TPaxProgram.Create(nil);
  PaxPascalLanguage1 := TPaxPascalLanguage.Create(nil);
  try
    PaxCompiler1.RegisterLanguage(PaxPascalLanguage1);
    PaxCompiler1.AddModule(AName, 'Pascal');
    PaxCompiler1.AddCodeFromFile(AName, AName  + '.pas');
    if PaxCompiler1.Compile(PaxProgram1) then
    begin
      PaxProgram1.Run;
      PaxProgram1.SaveToFile(AName + '.pcu');
      ShowMessage(AName + '.pcu created');
    end
    else
      writeln(PaxCompiler1.ErrorMessage[0]);
  finally
    PaxCompiler1.Free;
    PaxProgram1.Free;
    PaxPascalLanguage1.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Compile('unit2');
  Compile('MainProg');
  Compile('MainUnit');
end;

procedure TForm1.CreateObjectHandler(Sender: TPaxProgram;
                                     Instance: TObject);
var
  pti: PTypeInfo;
  ptd: PTypeData;
  S: String;
begin
  if Instance is TForm then
  begin
    pti := Instance.ClassInfo;
    ptd := GetTypeData(pti);
    if FileExists(ptd^.UnitName + '.dfm') then
      Sender.LoadDFMFile(Instance, ptd^.UnitName + '.dfm');
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  LoadProgram1 := TPaxProgram.Create(nil);
  LoadProgram1.OnCreateObject := Form1.CreateObjectHandler;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  LoadProgram1.Free;
end;

function LoadDialog: TForm;
begin
  with Form1 do
  try
    LoadProgram1.LoadFromFile('unit2.pcu');
    LoadProgram1.RunInitialization;
    result := TForm(LoadProgram1.CreateScriptObject('TForm2', [nil]));
  except
    result := nil;
  end;
  if result = nil then
    ShowMessage('Error');
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  P: TPaxProgram;
  A: Pointer;
begin
  P := TPaxProgram.Create(nil);
  try
    P.LoadFromFile('MainUnit.pcu');
    P.LoadPCU('unit2.pcu');
    A := P.GetAddressEx('MainUnit.Start');
    if A <> nil then
    asm
      call A
    end;
  finally
    P.Free;
  end;
end;

initialization

RegisterHeader(0, 'function LoadDialog: TForm;', @LoadDialog);

end.
