unit fMain; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, uPSCompiler, uPSRuntime, uPSDisassembly, uPSPreprocessor, uPSUtils, Menus, uPSC_comobj, uPSR_comobj; type TMainForm = class(TForm) Memo1: TMemo; Memo2: TMemo; Splitter1: TSplitter; MainMenu1: TMainMenu; Toosl1: TMenuItem; Compile1: TMenuItem; CompilewithTimer1: TMenuItem; File1: TMenuItem; Exit1: TMenuItem; N1: TMenuItem; SaveAs1: TMenuItem; Save1: TMenuItem; Open1: TMenuItem; New1: TMenuItem; OpenDialog1: TOpenDialog; SaveDialog1: TSaveDialog; N2: TMenuItem; Stop1: TMenuItem; N3: TMenuItem; CompileandDisassemble1: TMenuItem; procedure Compile1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Exit1Click(Sender: TObject); procedure New1Click(Sender: TObject); procedure Open1Click(Sender: TObject); procedure Save1Click(Sender: TObject); procedure SaveAs1Click(Sender: TObject); procedure Memo1Change(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure Stop1Click(Sender: TObject); procedure CompileandDisassemble1Click(Sender: TObject); procedure CompilewithTimer1Click(Sender: TObject); private fn: string; changed: Boolean; function SaveTest: Boolean; public { Public declarations } end; var MainForm: TMainForm; implementation uses uPSC_dll, uPSR_dll, uPSDebugger, uPSR_std, uPSC_std, uPSR_stdctrls, uPSC_stdctrls, uPSR_forms, uPSC_forms, uPSC_graphics, uPSC_controls, uPSC_classes, uPSR_graphics, uPSR_controls, uPSR_classes, fDwin; {$R *.DFM} var Imp: TPSRuntimeClassImporter; function StringLoadFile(const Filename: string): string; var Stream: TStream; begin Stream := TFileStream.Create(Filename, fmOpenread or fmSharedenywrite); try SetLength(Result, Stream.Size); Stream.Read(Result[1], Length(Result)); finally Stream.Free; end; end; function OnNeedFile(Sender: TPSPreProcessor; const callingfilename: AnsiString; var FileName, Output: AnsiString): Boolean; var s: string; begin s := ExtractFilePath(callingfilename); if s = '' then s := ExtractFilePath(Paramstr(0)); Filename := s + Filename; if FileExists(Filename) then begin Output := StringLoadFile(Filename); Result := True; end else Result := False; end; function MyOnUses(Sender: TPSPascalCompiler; const Name: AnsiString): Boolean; begin if Name = 'SYSTEM' then begin TPSPascalCompiler(Sender).AddFunction('procedure Writeln(s: string);'); TPSPascalCompiler(Sender).AddFunction('function Readln(question: string): string;'); Sender.AddDelphiFunction('function ImportTest(S1: string; s2: Longint; s3: Byte; s4: word; var s5: string): string;'); Sender.AddConstantN('NaN', 'extended').Value.textended := 0.0 / 0.0; Sender.AddConstantN('Infinity', 'extended').Value.textended := 1.0 / 0.0; Sender.AddConstantN('NegInfinity', 'extended').Value.textended := - 1.0 / 0.0; SIRegister_Std(Sender); SIRegister_Classes(Sender, True); SIRegister_Graphics(Sender, True); SIRegister_Controls(Sender); SIRegister_stdctrls(Sender); SIRegister_Forms(Sender); SIRegister_ComObj(Sender); AddImportedClassVariable(Sender, 'Memo1', 'TMemo'); AddImportedClassVariable(Sender, 'Memo2', 'TMemo'); AddImportedClassVariable(Sender, 'Self', 'TForm'); AddImportedClassVariable(Sender, 'Application', 'TApplication'); Result := True; end else begin TPSPascalCompiler(Sender).MakeError('', ecUnknownIdentifier, ''); Result := False; end; end; function MyWriteln(Caller: TPSExec; p: TIFExternalProcRec; Global, Stack: TPSStack): Boolean; var PStart: Cardinal; begin if Global = nil then begin result := false; exit; end; PStart := Stack.Count - 1; MainForm.Memo2.Lines.Add(Stack.GetString(PStart)); Result := True; end; function MyReadln(Caller: TPSExec; p: TIFExternalProcRec; Global, Stack: TPSStack): Boolean; var PStart: Cardinal; begin if Global = nil then begin result := false; exit; end; PStart := Stack.Count - 2; Stack.SetString(PStart + 1, InputBox(MainForm.Caption, Stack.GetString(PStart), '')); Result := True; end; function ImportTest(S1: string; s2: Longint; s3: Byte; s4: word; var s5: string): string; begin Result := s1 + ' ' + IntToStr(s2) + ' ' + IntToStr(s3) + ' ' + IntToStr(s4) + ' - OK!'; S5 := s5 + ' '+ result + ' - OK2!'; end; var IgnoreRunline: Boolean = False; I: Integer; procedure RunLine(Sender: TPSExec); begin if IgnoreRunline then Exit; i := (i + 1) mod 15; Sender.GetVar(''); if i = 0 then Application.ProcessMessages; end; function MyExportCheck(Sender: TPSPascalCompiler; Proc: TPSInternalProcedure; const ProcDecl: AnsiString): Boolean; begin Result := True; end; procedure TMainForm.Compile1Click(Sender: TObject); var x1: TPSPascalCompiler; x2: TPSDebugExec; xpre: TPSPreProcessor; s, d: AnsiString; procedure Outputtxt(const s: string); begin Memo2.Lines.Add(s); end; procedure OutputMsgs; var l: Longint; b: Boolean; begin b := False; for l := 0 to x1.MsgCount - 1 do begin Outputtxt(x1.Msg[l].MessageToString); if (not b) and (x1.Msg[l] is TPSPascalCompilerError) then begin b := True; Memo1.SelStart := X1.Msg[l].Pos; end; end; end; begin if tag <> 0 then exit; Memo2.Clear; xpre := TPSPreProcessor.Create; try xpre.OnNeedFile := OnNeedFile; xpre.MainFileName := fn; xpre.MainFile := Memo1.Text; xpre.PreProcess(xpre.MainFileName, s); x1 := TPSPascalCompiler.Create; x1.OnExportCheck := MyExportCheck; x1.OnUses := MyOnUses; x1.OnExternalProc := DllExternalProc; x1.AllowNoEnd := true; if x1.Compile(s) then begin Outputtxt('Successfully compiled'); xpre.AdjustMessages(x1); OutputMsgs; if not x1.GetOutput(s) then begin x1.Free; Outputtxt('[Error] : Could not get data'); exit; end; x1.GetDebugOutput(d); x1.Free; x2 := TPSDebugExec.Create; try RegisterDLLRuntime(x2); RegisterClassLibraryRuntime(x2, Imp); RIRegister_ComObj(x2); tag := longint(x2); if sender <> nil then x2.OnRunLine := RunLine; x2.RegisterFunctionName('WRITELN', MyWriteln, nil, nil); x2.RegisterFunctionName('READLN', MyReadln, nil, nil); x2.RegisterDelphiFunction(@ImportTest, 'IMPORTTEST', cdRegister); if not x2.LoadData(s) then begin Outputtxt('[Error] : Could not load data: '+TIFErrorToString(x2.ExceptionCode, x2.ExceptionString)); tag := 0; exit; end; x2.LoadDebugData(d); SetVariantToClass(x2.GetVarNo(x2.GetVar('MEMO1')), Memo1); SetVariantToClass(x2.GetVarNo(x2.GetVar('MEMO2')), Memo2); SetVariantToClass(x2.GetVarNo(x2.GetVar('SELF')), Self); SetVariantToClass(x2.GetVarNo(x2.GetVar('APPLICATION')), Application); x2.RunScript; if x2.ExceptionCode <> erNoError then Outputtxt('[Runtime Error] : ' + TIFErrorToString(x2.ExceptionCode, x2.ExceptionString) + ' in ' + IntToStr(x2.ExceptionProcNo) + ' at ' + IntToSTr(x2.ExceptionPos)) else OutputTxt('Successfully executed'); finally tag := 0; x2.Free; end; end else begin Outputtxt('Failed when compiling'); xpre.AdjustMessages(x1); OutputMsgs; x1.Free; end; finally Xpre.Free; end; end; procedure TMainForm.FormCreate(Sender: TObject); begin Caption := 'RemObjects Pascal Script'; fn := ''; changed := False; Memo1.Lines.Text := 'Program Test;'#13#10'Begin'#13#10'End.'; end; procedure TMainForm.Exit1Click(Sender: TObject); begin Close; end; procedure TMainForm.New1Click(Sender: TObject); begin if not SaveTest then exit; Memo1.Lines.Text := 'Program Test;'#13#10'Begin'#13#10'End.'; Memo2.Lines.Clear; fn := ''; end; function TMainForm.SaveTest: Boolean; begin if changed then begin case MessageDlg('File is not saved, save now?', mtWarning, mbYesNoCancel, 0) of mrYes: begin Save1Click(nil); Result := not changed; end; mrNo: Result := True; else Result := False; end; end else Result := True; end; procedure TMainForm.Open1Click(Sender: TObject); begin if not SaveTest then exit; if OpenDialog1.Execute then begin Memo1.Lines.LoadFromFile(OpenDialog1.FileName); changed := False; Memo2.Lines.Clear; fn := OpenDialog1.FileName; end; end; procedure TMainForm.Save1Click(Sender: TObject); begin if fn = '' then begin Saveas1Click(nil); end else begin Memo1.Lines.SaveToFile(fn); changed := False; end; end; procedure TMainForm.SaveAs1Click(Sender: TObject); begin SaveDialog1.FileName := ''; if SaveDialog1.Execute then begin fn := SaveDialog1.FileName; Memo1.Lines.SaveToFile(fn); changed := False; end; end; procedure TMainForm.Memo1Change(Sender: TObject); begin changed := True; end; procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin CanClose := SaveTest; end; procedure TMainForm.Stop1Click(Sender: TObject); begin if tag <> 0 then TPSExec(tag).Stop; end; procedure TMainForm.CompileandDisassemble1Click(Sender: TObject); var x1: TPSPascalCompiler; xpre: TPSPreProcessor; s: AnsiString; s2: string; procedure OutputMsgs; var l: Integer; b: Boolean; begin b := False; for l := 0 to x1.MsgCount - 1 do begin Memo2.Lines.Add(x1.Msg[l].MessageToString); if (not b) and (x1.Msg[l] is TPSPascalCompilerError) then begin b := True; Memo1.SelStart := X1.Msg[l].Pos; end; end; end; begin if tag <> 0 then exit; Memo2.Clear; xpre := TPSPreProcessor.Create; try xpre.OnNeedFile := OnNeedFile; xpre.MainFileName := fn; xpre.MainFile := Memo1.Text; xpre.PreProcess(xpre.MainFileName, s); x1 := TPSPascalCompiler.Create; x1.OnExternalProc := DllExternalProc; x1.OnUses := MyOnUses; if x1.Compile(s) then begin Memo2.Lines.Add('Successfully compiled'); xpre.AdjustMessages(x1); OutputMsgs; if not x1.GetOutput(s) then begin x1.Free; Memo2.Lines.Add('[Error] : Could not get data'); exit; end; x1.Free; IFPS3DataToText(s, s2); dwin.Memo1.Text := s2; dwin.showmodal; end else begin Memo2.Lines.Add('Failed when compiling'); xpre.AdjustMessages(x1); OutputMsgs; x1.Free; end; finally xPre.Free; end; end; procedure TMainForm.CompilewithTimer1Click(Sender: TObject); var Freq, Time1, Time2: Comp; begin if not QueryPerformanceFrequency(TLargeInteger((@Freq)^)) then begin ShowMessage('Your computer does not support Performance Timers!'); exit; end; QueryPerformanceCounter(TLargeInteger((@Time1)^)); IgnoreRunline := True; try Compile1Click(nil); except end; IgnoreRunline := False; QueryPerformanceCounter(TLargeInteger((@Time2)^)); Memo2.Lines.Add('Time: ' + Sysutils.FloatToStr((Time2 - Time1) / Freq) + ' sec'); end; initialization Imp := TPSRuntimeClassImporter.Create; RIRegister_Std(Imp); RIRegister_Classes(Imp, True); RIRegister_Graphics(Imp, True); RIRegister_Controls(Imp); RIRegister_stdctrls(imp); RIRegister_Forms(Imp); finalization Imp.Free; end.