about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCase Duckworth2024-04-03 23:34:19 -0500
committerCase Duckworth2024-04-03 23:34:19 -0500
commitf160a00a1472485a3aadff2a73cc201c84e8a87c (patch)
tree06819c7e6e7c2755730208734542881e51020559
parentChange styling some more (diff)
downloadlam-f160a00a1472485a3aadff2a73cc201c84e8a87c.tar.gz
lam-f160a00a1472485a3aadff2a73cc201c84e8a87c.zip
Refactor literals reading and implement number literals
that is, #b, #o, #d, #x
-rw-r--r--read.lua64
1 files changed, 44 insertions, 20 deletions
diff --git a/read.lua b/read.lua index 6b223f8..4fb9b70 100644 --- a/read.lua +++ b/read.lua
@@ -44,7 +44,6 @@ function m.inport (source, kind)
44 tok, toktype, self.line = 44 tok, toktype, self.line =
45 m.scan(self.line)() 45 m.scan(self.line)()
46 if tok ~= nil then 46 if tok ~= nil then
47 print(tok, toktype)
48 return tok, toktype 47 return tok, toktype
49 end 48 end
50 end 49 end
@@ -96,6 +95,37 @@ local function consume_comment (cs)
96 return table.concat(comment), "comment", cs 95 return table.concat(comment), "comment", cs
97end 96end
98 97
98local function idf (x)
99 return function () return x end
100end
101
102local function numf (base)
103 return function (token)
104 local n = tonumber(token:sub(3), base)
105 assert(n, "Can't read number: " .. token)
106 return n
107 end
108end
109
110local literals = {
111 literal = {
112 ["#t"] = idf(true),
113 ["#true"] = idf(true),
114 ["#f"] = idf(false),
115 ["#false"] = idf(false),
116 ["#\\space"] = idf(t.character(" ")),
117 ["#\\tab"] = idf(t.character("\t")),
118 ["#\\newline"] = idf(t.character("\n")),
119 },
120 match = {
121 ["^#b"] = numf(2),
122 ["^#o"] = numf(8),
123 ["^#d"] = numf(10),
124 ["^#x"] = numf(16),
125 ["^#\\"] = function (tok) return t.character(tok:sub(3)) end,
126 }
127}
128
99local function consume_literal (cs) 129local function consume_literal (cs)
100 -- whitespace and parantheses character literals. 130 -- whitespace and parantheses character literals.
101 -- reverse the match test b/c it's already a complement 131 -- reverse the match test b/c it's already a complement
@@ -105,26 +135,20 @@ local function consume_literal (cs)
105 pop(cs) -- discard '#' 135 pop(cs) -- discard '#'
106 local token, value, cs = consume_token(cs) -- todo: vectors #(...) 136 local token, value, cs = consume_token(cs) -- todo: vectors #(...)
107 token = "#" .. token -- put '#' back 137 token = "#" .. token -- put '#' back
108 -- tokens! 138
109 if token == "#t" or token == "#true" then -- booleans 139 if literals.literal[token] then
110 value = true 140 value = literals.literal[token]()
111 elseif token == "#f" or token == "#false" then
112 value = false
113 --[[ To actually *read* nil, I need to change ports from
114 returning `nil' on eof to an `eof' symbol, i think.
115
116 elseif token == "#n" or token == "#nil" then
117 value = nil
118 --]]
119 elseif token == "#\\space" then -- characters
120 value = type.character(" ")
121 elseif token == "#\\newline" then
122 value = type.character("\n")
123 elseif token:match("^#\\") then
124 value = type.character(token:sub(3))
125 else 141 else
126 error("Bad literal notation: " .. token) 142 for re, fn in pairs(literals.match) do
143 if token:match(re) then
144 value = fn(token)
145 end
146 end
127 end 147 end
148 -- TODO : if `nil' is to be a value in lam i'm going to have to figure
149 -- out some kind of 'lam nil' and 'lua nil' or something..
150 assert(value~=nil, "Can't read literal: " .. token)
151
128 return value, "literal", cs 152 return value, "literal", cs
129end 153end
130 154
@@ -208,7 +232,7 @@ m.readmacros = {
208 table.insert(Q, m.read(port)) 232 table.insert(Q, m.read(port))
209 return t.list(Q) 233 return t.list(Q)
210 end, 234 end,
211 comment = function () return nil end, 235 comment = idf(nil),
212} 236}
213 237
214function m.read (port) 238function m.read (port)