--- lam.repl local m = {} 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 if x == true then print("#t") elseif x == false then print("#f") elseif x == nil then print("#") else print(x) end end local lam = [[ @,,,@ <|^ ^|> l a m | /) 0015 |I /))) acdw ------------- ]] 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():setvbuf("no") end repeat if interactive then io.stderr:write(prompt) io.stderr:flush() end -- read local ok, x = xpcall( function () local nxt = read(inport) return nxt end, handle_error ) if not ok then 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 ok then local ok, v = xpcall( function () return eval(x) end, handle_error ) if not ok then 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 until x == eof -- loop inport:close() end function m.repl (prompt) return m.read_eval(nil, { prompt = prompt, }) end function m.load (filename) return m.read_eval(filename) end -------- return m