Skip to content

Commit fcaaf32

Browse files
committed
new example: a winxed REPL
No copy&paste yet, sorry
1 parent cd3da1b commit fcaaf32

File tree

1 file changed

+252
-0
lines changed

1 file changed

+252
-0
lines changed

examples/winxed_repl.winxed

Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// winxed_repl.winxed
2+
3+
// A Read-Eval-Print Loop for winxed
4+
5+
$include "Guitor.winxhead";
6+
7+
$load "Guitor.pbc";
8+
9+
using namespace Guitor;
10+
11+
//**************************************************************
12+
13+
// Compile the string passed embedded in a local function of a function
14+
// that passes the variables in stotage as lexicals.
15+
// Return the outer function.
16+
17+
function parse_line(compiler, storage, string line)
18+
{
19+
string source = "function aux(__storage) {";
20+
21+
for (string name in storage) {
22+
var data = storage[name];
23+
string type = data[0];
24+
if (type == "var")
25+
source += "volatile ";
26+
source += type + " " + name + " = __storage['" + name + "'][1];";
27+
}
28+
source += "var __result = function() { " + line + "; } ();";
29+
for (string name in storage) {
30+
var data = storage[name];
31+
string type = data[0];
32+
source += "__storage['" + name + "'][1] = " + type + "(" + name + ");";
33+
}
34+
35+
source += " return __result; }";
36+
37+
var pir = compiler.compile(source, "pir":[named("target")] );
38+
var pircomp = compreg("PIR");
39+
var code = pircomp.compile(pir);
40+
41+
var fun = code.all_subs()[0];
42+
var result = fun(storage);
43+
return result;
44+
}
45+
46+
//**************************************************************
47+
48+
// Panel contains the output of the commands executed.
49+
50+
class Panel : ChildWindow
51+
{
52+
var font;
53+
var text;
54+
var height;
55+
function Panel(parent, int x, int y, int width, int height, font)
56+
{
57+
self.font = font;
58+
string text[] = [ "Welcome!" ];
59+
self.text = text;
60+
self.height = height;
61+
self.ChildWindow(parent, x, y, width, height);
62+
self.OnConfigure += function (event) { self.onconfigure(event); };
63+
self.OnExpose += function (event) { self.onexpose(event); };
64+
}
65+
function onconfigure(event)
66+
{
67+
self.height =: event.height();
68+
}
69+
function onexpose(event)
70+
{
71+
self.ClearArea(0, 0, 0, 0, 0);
72+
self.drawall();
73+
}
74+
function add(string str)
75+
{
76+
// Add str to current content, breaking it into lines,
77+
// avoiding to add blank line at end.
78+
var text = self.text;
79+
int pos = 0, npos;
80+
while ((npos = indexof(str, "\n", pos)) >= 0) {
81+
push(text, substr(str, pos, npos - pos));
82+
pos = npos + 1;
83+
}
84+
if (pos < length(str))
85+
push(text, substr(str, pos));
86+
}
87+
function drawall()
88+
{
89+
var text = self.text;
90+
int ntext = elements(text);
91+
int lineheight = self.font.getHeight();
92+
int nlines = self.height / lineheight;
93+
int start = ntext - nlines;
94+
if (start < 0)
95+
start = 0;
96+
for (int i = start, y = lineheight; i < ntext; ++i, y += lineheight)
97+
self.DrawImageString(0, y, text[i]);
98+
}
99+
}
100+
101+
//**************************************************************
102+
103+
// Main application window: contains a Panel and a EditBox
104+
105+
class WinxedRepl : TopLevelWindow
106+
{
107+
var font;
108+
var width;
109+
var height;
110+
var command;
111+
var panel;
112+
var command_y;
113+
var command_height;
114+
var storage;
115+
var compiler;
116+
function WinxedRepl(controller, fontname)
117+
{
118+
var display = controller.display;
119+
var font = display.CreateFont(fontname);
120+
int width = 600, height = 400;
121+
int command_height = font.getHeight();
122+
int command_y = height - command_height - 1;
123+
self.font = font;
124+
self.width = width;
125+
self.height = height;
126+
self.command_height = command_height;
127+
self.command_y = command_y;
128+
self.compiler = load_language("winxed");
129+
130+
// No way to declare variables yet, hardcode a few here:
131+
self.storage = {
132+
"n" : [ "int", 42 ],
133+
"j" : [ "string", "hi"],
134+
"p" : [ "var", null ]
135+
};
136+
137+
self.TopLevelWindow(controller, "Winxed REPL",
138+
0, 0, width, height,
139+
{ "background_color" : display.ParseColor("grey") } );
140+
self.SetWMProtocols(['WM_TAKE_FOCUS', 'WM_DELETE_WINDOW' ]);
141+
var command = new EditBox(self,
142+
1, command_y, width - 2, command_height, font);
143+
self.command = command;
144+
command.Map();
145+
var panel = new Panel(self, 1, 1, width - 2, command_y - 2, font);
146+
self.panel = panel;
147+
panel.Map();
148+
149+
self.OnDestroy += function (event) { self.controller.Quit(); };
150+
self.OnConfigure += function (event) { self.onconfigure(event); };
151+
self.OnClientMessage += function (event) { self.onclientmessage(event); };
152+
command.OnKeyPress += function (event) { self.oncommandkeypress(event); };
153+
}
154+
function onconfigure(event)
155+
{
156+
int width = event.width();
157+
int height = event.height();
158+
int command_y = height - self.command_height - 1;
159+
self.width = width;
160+
self.height = height;
161+
self.command_y = command_y;
162+
var command = self.command;
163+
if (command != null) {
164+
command.ResizeWindow(width - 2, self.command_height);
165+
command.MoveWindow(1, command_y);
166+
}
167+
var panel = self.panel;
168+
if (panel != null) {
169+
panel.ResizeWindow(width - 2, command_y - 2);
170+
}
171+
}
172+
function onclientmessage(event)
173+
{
174+
int type = event.message_type();
175+
if (type == self.display.InternAtom("WM_PROTOCOLS")) {
176+
int data0 = event.message_data(0);
177+
if (data0 == self.display.InternAtom("WM_DELETE_WINDOW"))
178+
self.quit();
179+
else if (data0 == self.display.InternAtom("WM_TAKE_FOCUS")) {
180+
if (self.command != null)
181+
self.command.SetInputFocus(RevertToParent);
182+
self.display.Flush();
183+
}
184+
}
185+
}
186+
187+
function quit()
188+
{
189+
var command = self.command;
190+
var panel = self.panel;
191+
self.command = null;
192+
self.panel = null;
193+
if (command != null)
194+
command.Destroy();
195+
if (panel != null)
196+
panel.Destroy();
197+
self.Destroy();
198+
}
199+
function eval(string str)
200+
{
201+
var panel = self.panel;
202+
self.command.setValue("");
203+
var interp = getinterp();
204+
var savestdout = interp.stdout_handle();
205+
var savestderr = interp.stderr_handle();
206+
var out = new ["StringHandle"];
207+
out.open("REPLout", "w");
208+
interp.stdout_handle(out);
209+
interp.stderr_handle(out);
210+
try {
211+
var result = parse_line(self.compiler, self.storage, str);
212+
interp.stdout_handle(savestdout);
213+
interp.stderr_handle(savestderr);
214+
out.close();
215+
out.open("", "r");
216+
panel.add(out.readall());
217+
if (result != null)
218+
panel.add(result);
219+
}
220+
catch (e) {
221+
interp.stdout_handle(savestdout);
222+
interp.stderr_handle(savestderr);
223+
panel.add(e["message"]);
224+
}
225+
panel.ClearArea(0, 0, 0, 0, 0);
226+
panel.drawall();
227+
}
228+
function oncommandkeypress(event)
229+
{
230+
switch (event.keyname()) {
231+
case "Return":
232+
self.eval(self.command.getValue());
233+
break;
234+
case "Escape":
235+
self.quit();
236+
break;
237+
}
238+
}
239+
}
240+
241+
//**************************************************************
242+
243+
function main()
244+
{
245+
var controller = new Controller();
246+
var repl = new WinxedRepl(controller, "Courier-12");
247+
repl.Map();
248+
controller.MainLoop();
249+
controller.Close();
250+
}
251+
252+
// End

0 commit comments

Comments
 (0)