about summary refs log tree commit diff stats
path: root/repl.lua
diff options
context:
space:
mode:
authorCase Duckworth2024-04-05 13:38:22 -0500
committerCase Duckworth2024-04-05 13:38:22 -0500
commitbebcbdd000b55fa86df4c3c30b6ec7c85ff2dfab (patch)
tree03557590831641f675a0761c7fa421614651c1ed /repl.lua
parentAdd display and newline (diff)
downloadlam-bebcbdd000b55fa86df4c3c30b6ec7c85ff2dfab.tar.gz
lam-bebcbdd000b55fa86df4c3c30b6ec7c85ff2dfab.zip
Fix reading from files ... i'm PRETTY sure
Diffstat (limited to 'repl.lua')
-rw-r--r--repl.lua95
1 files changed, 53 insertions, 42 deletions
diff --git a/repl.lua b/repl.lua index be739c7..86bc0af 100644 --- a/repl.lua +++ b/repl.lua
@@ -1,9 +1,10 @@
1--- lam.repl 1--- lam.repl
2 2
3local m = {} 3local m = {}
4local read = require("read") 4local _r = require("read")
5local eval = require("eval") 5local read, inport, read_string, eof =
6local pp = require("dump").pp 6 _r.read, _r.inport, _r.read_string, _r.eof
7local eval = require("eval").eval
7 8
8local function schemeprint (x) 9local function schemeprint (x)
9 -- if x == nil then return end 10 -- if x == nil then return end
@@ -12,7 +13,7 @@ local function schemeprint (x)
12 elseif x == false then 13 elseif x == false then
13 print("#f") 14 print("#f")
14 elseif x == nil then 15 elseif x == nil then
15 print("#n") 16 print("#<nil>")
16 else 17 else
17 print(x) 18 print(x)
18 end 19 end
@@ -26,57 +27,67 @@ local lam = [[
26 ------------- 27 -------------
27]] 28]]
28 29
29function m.repl (prompt, infile, out) 30local function handle_error (e)
30 -- PROMPT should be a string, INFILE is a filename, and OUT is either a 31 local start = e:find(": ")
31 -- filename, nil (in which case it will be stdout), or false (which 32 return e:sub(start + 2)
32 -- suppresses output) 33end
33 local inport = read.inport(infile) 34
34 if out ~= false then 35function m.read_eval (filename, interactive)
35 io.output(out) 36 -- interactive = { out = file or handle, prompt = string, }
37 local inport = inport(filename)
38 local prompt = interactive and interactive.prompt or "> "
39 if interactive then
40 io.output(interactive.out or io.stdout)
36 io.write(lam) 41 io.write(lam)
42 io.output():setvbuf("line")
43 else
44 io.output(io.stdout) -- hmmm
45 io.output():setvbuf("no")
37 end 46 end
38 io.output():setvbuf("line") 47 repeat
39 if prompt then 48 if interactive then
40 stderr = io.open("/dev/stderr", "w") -- Linux-only ! 49 io.stderr:write(prompt)
41 end 50 io.stderr:flush()
42 while true do -- loop
43 if prompt then
44 stderr:write(prompt)
45 stderr:flush()
46 end 51 end
47 -- read 52 -- read
48 local ok, x = xpcall( 53 local ok, x = xpcall(
49 function () return read.read(inport) end, 54 function ()
50 function (e) 55 local nxt = read(inport)
51 local start = e:find(": ") 56 return nxt
52 return e:sub(start+2) 57 end,
53 end 58 handle_error
54 ) 59 )
55 if not ok then 60 if not ok then
56 print("(read) not ok: " .. x) 61 io.stderr:write("(read) not ok: ", x, "\n")
57 x = nil 62 -- in interactive mode, errors should not be fatal. in
63 -- batch mode, they should be.
64 if not interactive then return nil end
58 end 65 end
59 -- eval 66 -- eval
60 if x then 67 if ok then
61 local ok, val = 68 local ok, v = xpcall(
62 xpcall( 69 function () return eval(x) end,
63 function () return eval.eval(x) end, 70 handle_error
64 function (e) 71 )
65 local start = e:find(": ")
66 return e:sub(start+2)
67 end
68 )
69 if not ok then 72 if not ok then
70 print("(eval) not ok: " .. val) 73 io.stderr:write("(eval) not ok: ", v, "\n")
71 elseif out ~= false then 74 if not interactive then return nil end
72 -- print
73 schemeprint(val)
74 end 75 end
76 -- print
77 if ok and interactive then schemeprint(v) end
78 elseif interactive then
79 ok = "recover"
75 end 80 end
76 end 81 until x == eof -- loop
77 inport:close() 82 inport:close()
78 stderr:close() 83end
79 io.output():close() 84
85function m.repl (prompt)
86 return m.read_eval(nil, { prompt = prompt, })
87end
88
89function m.load (filename)
90 return m.read_eval(filename)
80end 91end
81 92
82-------- 93--------