about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCase Duckworth2024-03-31 22:16:37 -0500
committerCase Duckworth2024-03-31 22:16:37 -0500
commit4eaaedc486d60fde724abf1af70e21fc2b3e5c49 (patch)
tree491e0e61632cb9595a2dd7ba8dda0c20b2bfc882
parentError on unbound variables (diff)
downloadlam-4eaaedc486d60fde724abf1af70e21fc2b3e5c49.tar.gz
lam-4eaaedc486d60fde724abf1af70e21fc2b3e5c49.zip
Add rest of quotes to reader
-rw-r--r--read.lua38
1 files changed, 38 insertions, 0 deletions
diff --git a/read.lua b/read.lua index a41816f..f8d6b09 100644 --- a/read.lua +++ b/read.lua
@@ -7,6 +7,12 @@ local pop = require("util").pop
7 7
8local pp = require("pp").pp 8local pp = require("pp").pp
9 9
10-- TODO:
11-- - string reading
12-- - # syntax
13-- - comments
14-- - probably more
15
10function m.inport (source, kind) 16function m.inport (source, kind)
11 -- KIND can be one of "file", "string"; defaults to "file" 17 -- KIND can be one of "file", "string"; defaults to "file"
12 -- SOURCE is the name of the file or the string to read, or nil; if nil, 18 -- SOURCE is the name of the file or the string to read, or nil; if nil,
@@ -85,6 +91,18 @@ end
85m.readtable = { 91m.readtable = {
86 ["("] = function (cs) return pop(cs), "open", cs end, 92 ["("] = function (cs) return pop(cs), "open", cs end,
87 [")"] = function (cs) return pop(cs), "close", cs end, 93 [")"] = function (cs) return pop(cs), "close", cs end,
94 ["'"] = function (cs) return pop(cs), "quote", cs end,
95 ["`"] = function (cs) return pop(cs), "quote", cs end,
96 [","] =
97 function (cs)
98 pop(cs) -- remove ','
99 if cs[1] == "@" then
100 pop(cs) -- remove '@'
101 return ",@", "quote", cs
102 else
103 return ",", "quote", cs
104 end
105 end,
88} 106}
89 107
90-- Return an iterator over a character table, so you can do: 108-- Return an iterator over a character table, so you can do:
@@ -131,6 +149,24 @@ function m.readchar (port)
131 end 149 end
132end 150end
133 151
152m.readmacros = {
153 quote =
154 function (tok, toktype, port)
155 local qs = {
156 ["'"] = "quote",
157 ["`"] = "quasiquote",
158 [","] = "unquote",
159 [",@"] = "unquote-splicing",
160 }
161 if not qs[tok] then
162 error(string.format("Bad quote: '%s'\n", tok))
163 end
164 local Q = {qs[tok]}
165 table.insert(Q, m.read(port))
166 return t.list(Q)
167 end,
168}
169
134function m.read (port) 170function m.read (port)
135 local function read_ahead (tok, toktype) 171 local function read_ahead (tok, toktype)
136 if not tok then error("Unexpected EOF") end 172 if not tok then error("Unexpected EOF") end
@@ -151,6 +187,8 @@ function m.read (port)
151 end 187 end
152 elseif toktype == "close" then 188 elseif toktype == "close" then
153 error("Unexpected ')'") 189 error("Unexpected ')'")
190 elseif m.readmacros[toktype] then
191 return m.readmacros[toktype](tok, toktype, port)
154 else return tok 192 else return tok
155 end 193 end
156 end 194 end