-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathpscmd.pas
139 lines (119 loc) · 2.97 KB
/
pscmd.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
unit pscmd;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, uPSComponent, uPSRuntime, psrt;
type
TRuntimeEvent = procedure(Sender: TPSRuntime) of object;
{ TPSShell }
TPSShell = class(TComponent)
private
FPScript: TPSScript;
FRunning: Boolean;
FPrompt: string;
FOnExec: TRuntimeEvent;
FShellProfile: string;
procedure SetOnCompile(Value: TPSEvent);
public
property OnCompile: TPSEvent write SetOnCompile;
property Prompt: string read FPrompt write FPrompt;
property OnExec: TRuntimeEvent read FOnExec write FOnExec;
property ShellProfile: string read FShellProfile write FShellProfile;
constructor Create(AOwner: TComponent); override;
procedure LoadSourceFile(const AFileName: string);
procedure Execute;
procedure RunLine(const line: string);
procedure Compile(const AOutFile: string);
procedure RunBinary(const AFileName: string);
procedure CmdLoop;
procedure StopLoop;
end;
implementation
{ TPSShell }
procedure TPSShell.SetOnCompile(Value: TPSEvent);
begin
FPScript.OnCompile:=Value;
end;
constructor TPSShell.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FPScript:=TPSScript.Create(Self);
end;
procedure TPSShell.LoadSourceFile(const AFileName: string);
begin
FPScript.Script.LoadFromFile(AFileName);
end;
procedure TPSShell.Execute;
begin
if not FPScript.Compile then
WriteLn('Compile error: '+FPScript.CompilerErrorToStr(0))
else if not FPScript.Execute then
WriteLn('Runtime Error: '+FPScript.ExecErrorToString);
end;
procedure TPSShell.RunLine(const line: string);
begin
FPScript.Script.Clear;
if FileExists(FShellProfile) then
begin
FPScript.Script.LoadFromFile(FShellProfile);
FPScript.Script.Add('');
end;
FPScript.Script.Add('begin');
FPScript.Script.Add(line);
FPScript.Script.Add('end.');
Execute;
end;
procedure TPSShell.Compile(const AOutFile: string);
var
bc: string;
begin
if not FPScript.Compile then
WriteLn('Compile error: '+FPScript.CompilerErrorToStr(0))
else
begin
FPScript.Comp.GetOutput(bc);
with TFileStream.Create(AOutFile, fmCreate) do
try
Write(bc[1], Length(bc));
finally
Free;
end;
end;
end;
procedure TPSShell.RunBinary(const AFileName: string);
var
rt: TPSRuntime;
begin
rt:=TPSRuntime.Create(Nil);
try
if Assigned(FOnExec) then
FOnExec(rt)
else
WriteLn('OnExec not assigned!');
if not rt.LoadFromFile(AFileName) then
WriteLn('Load Error: ',rt.ExecErrorString)
else if not rt.RunProgram then
WriteLn('Runtime Error: ',rt.ExecErrorString);
finally
rt.Free;
end;
end;
procedure TPSShell.CmdLoop;
var
line: string;
begin
FRunning:=True;
repeat
{ TODO : Update these to call events instead to allow for more than just terminal }
Write(FPrompt);
ReadLn(line);
RunLine(line);
until not FRunning;
end;
procedure TPSShell.StopLoop;
begin
FRunning:=False;
if FPScript.Running then
FPScript.Stop;
end;
end.