diff options
Diffstat (limited to 'load.lua')
-rw-r--r-- | load.lua | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/load.lua b/load.lua new file mode 100644 index 0000000..f798712 --- /dev/null +++ b/load.lua | |||
@@ -0,0 +1,68 @@ | |||
1 | --- lam.load | ||
2 | |||
3 | local m = {} | ||
4 | local core = require("core") | ||
5 | local eval = require("eval") | ||
6 | local port = require("port") | ||
7 | local read = require("read") | ||
8 | local type = require("type") | ||
9 | |||
10 | local function schemeprint (x) | ||
11 | -- possibly a candidate to put in a `write' library | ||
12 | if x == true then print("#t") | ||
13 | elseif x == false then print("#f") | ||
14 | elseif x == nil then return -- print("#<nil>") | ||
15 | else print(x) | ||
16 | end | ||
17 | end | ||
18 | |||
19 | local function handle_error (e) | ||
20 | local start = e:find(": ") | ||
21 | return e:sub(start + 2) | ||
22 | end | ||
23 | |||
24 | function m.load (filename, interactive) | ||
25 | -- interactive = { out = file/handle, prompt = string, } | ||
26 | local inport = port.input_port(filename) | ||
27 | if interactive then | ||
28 | io.output(interactive.out) | ||
29 | io.output():setvbuf("line") | ||
30 | else | ||
31 | io.output():setvbuf("no") | ||
32 | end | ||
33 | repeat | ||
34 | if interactive then | ||
35 | io.stderr:write(interactive.prompt or "") | ||
36 | io.stderr:flush() | ||
37 | end | ||
38 | -- read | ||
39 | local read_ok, form = xpcall( | ||
40 | function () return read.read(inport) end, | ||
41 | handle_error) | ||
42 | if form == port.eof then break end | ||
43 | if not read_ok then | ||
44 | io.stderr:write("error (read): ", form, "\n") | ||
45 | -- when interactive, errors should not be fatal, but | ||
46 | -- they should be in batch mode | ||
47 | inport:flush() -- avoid endless loop | ||
48 | if not interactive then return nil end | ||
49 | else | ||
50 | -- eval | ||
51 | local eval_ok, value = xpcall( | ||
52 | function () | ||
53 | return eval.eval(form, core.environment) | ||
54 | end, | ||
55 | handle_error) | ||
56 | if not eval_ok then | ||
57 | io.stderr:write("error (eval): ", value, "\n") | ||
58 | if not interactive then return nil end | ||
59 | else | ||
60 | |||
61 | if interactive then schemeprint(value) end | ||
62 | end | ||
63 | end | ||
64 | until value == port.eof -- loop | ||
65 | end | ||
66 | |||
67 | -------- | ||
68 | return m | ||