From bebcbdd000b55fa86df4c3c30b6ec7c85ff2dfab Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Fri, 5 Apr 2024 13:38:22 -0500 Subject: Fix reading from files ... i'm PRETTY sure --- repl.lua | 95 ++++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 53 insertions(+), 42 deletions(-) (limited to 'repl.lua') diff --git a/repl.lua b/repl.lua index be739c7..86bc0af 100644 --- a/repl.lua +++ b/repl.lua @@ -1,9 +1,10 @@ --- lam.repl local m = {} -local read = require("read") -local eval = require("eval") -local pp = require("dump").pp +local _r = require("read") +local read, inport, read_string, eof = + _r.read, _r.inport, _r.read_string, _r.eof +local eval = require("eval").eval local function schemeprint (x) -- if x == nil then return end @@ -12,7 +13,7 @@ local function schemeprint (x) elseif x == false then print("#f") elseif x == nil then - print("#n") + print("#") else print(x) end @@ -26,57 +27,67 @@ local lam = [[ ------------- ]] -function m.repl (prompt, infile, out) - -- PROMPT should be a string, INFILE is a filename, and OUT is either a - -- filename, nil (in which case it will be stdout), or false (which - -- suppresses output) - local inport = read.inport(infile) - if out ~= false then - io.output(out) +local function handle_error (e) + local start = e:find(": ") + return e:sub(start + 2) +end + +function m.read_eval (filename, interactive) + -- interactive = { out = file or handle, prompt = string, } + local inport = inport(filename) + local prompt = interactive and interactive.prompt or "> " + if interactive then + io.output(interactive.out or io.stdout) io.write(lam) + io.output():setvbuf("line") + else + io.output(io.stdout) -- hmmm + io.output():setvbuf("no") end - io.output():setvbuf("line") - if prompt then - stderr = io.open("/dev/stderr", "w") -- Linux-only ! - end - while true do -- loop - if prompt then - stderr:write(prompt) - stderr:flush() + repeat + if interactive then + io.stderr:write(prompt) + io.stderr:flush() end -- read local ok, x = xpcall( - function () return read.read(inport) end, - function (e) - local start = e:find(": ") - return e:sub(start+2) - end + function () + local nxt = read(inport) + return nxt + end, + handle_error ) if not ok then - print("(read) not ok: " .. x) - x = nil + io.stderr:write("(read) not ok: ", x, "\n") + -- in interactive mode, errors should not be fatal. in + -- batch mode, they should be. + if not interactive then return nil end end -- eval - if x then - local ok, val = - xpcall( - function () return eval.eval(x) end, - function (e) - local start = e:find(": ") - return e:sub(start+2) - end - ) + if ok then + local ok, v = xpcall( + function () return eval(x) end, + handle_error + ) if not ok then - print("(eval) not ok: " .. val) - elseif out ~= false then - -- print - schemeprint(val) + io.stderr:write("(eval) not ok: ", v, "\n") + if not interactive then return nil end end + -- print + if ok and interactive then schemeprint(v) end + elseif interactive then + ok = "recover" end - end + until x == eof -- loop inport:close() - stderr:close() - io.output():close() +end + +function m.repl (prompt) + return m.read_eval(nil, { prompt = prompt, }) +end + +function m.load (filename) + return m.read_eval(filename) end -------- -- cgit 1.4.1-21-gabe81