about summary refs log tree commit diff stats
path: root/repl.lua
blob: be739c7b0e831ac07f724f8c5af63f77f5c752b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
--- lam.repl

local m = {}
local read = require("read")
local eval = require("eval")
local pp = require("dump").pp

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("#n")
	else
		print(x)
	end
end

local lam = [[
 @,,,@
<|^ ^|>  l a m
 |   /)   0015
 |I /)))  acdw
 -------------
]]

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)
		io.write(lam)
	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()
		end
		-- read
		local ok, x = xpcall(
			function () return read.read(inport) end,
			function (e)
				local start = e:find(": ")
				return e:sub(start+2)
			end
		)
		if not ok then
			print("(read) not ok: " .. x)
			x = nil
		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 not ok then
				print("(eval) not ok: " .. val)
			elseif out ~= false then
				-- print
				schemeprint(val)
			end
		end
	end
	inport:close()
	stderr:close()
	io.output():close()
end

--------
return m