about summary refs log tree commit diff stats
path: root/read.lua
diff options
context:
space:
mode:
authorCase Duckworth2024-04-05 13:38:22 -0500
committerCase Duckworth2024-04-05 13:38:22 -0500
commitbebcbdd000b55fa86df4c3c30b6ec7c85ff2dfab (patch)
tree03557590831641f675a0761c7fa421614651c1ed /read.lua
parentAdd display and newline (diff)
downloadlam-bebcbdd000b55fa86df4c3c30b6ec7c85ff2dfab.tar.gz
lam-bebcbdd000b55fa86df4c3c30b6ec7c85ff2dfab.zip
Fix reading from files ... i'm PRETTY sure
Diffstat (limited to 'read.lua')
-rw-r--r--read.lua56
1 files changed, 31 insertions, 25 deletions
diff --git a/read.lua b/read.lua index 4fb9b70..35f5b57 100644 --- a/read.lua +++ b/read.lua
@@ -7,10 +7,31 @@ local pop = require("util").pop
7 7
8-- TODO: 8-- TODO:
9-- - string reading 9-- - string reading
10-- - # syntax
11-- - comments
12-- - probably more 10-- - probably more
13 11
12m.eof = setmetatable({}, {
13 __type = "EOF",
14 __tostring = function () return "#<eof>" end,
15})
16
17local function inport_next_token (port)
18 local tok, toktype
19 while true do
20 if #port.line == 0 then
21 if port.file then
22 local ln = port.file:read()
23 if ln == nil then return m.eof end
24 port.line = m.tochars(ln)
25 else
26 return nil
27 end
28 end
29 tok, toktype, port.line = m.scan(port.line)()
30 port.line = port.line or {}
31 if tok ~= nil then return tok, toktype end
32 end
33end
34
14function m.inport (source, kind) 35function m.inport (source, kind)
15 -- KIND can be one of "file", "string"; defaults to "file" 36 -- KIND can be one of "file", "string"; defaults to "file"
16 -- SOURCE is the name of the file or the string to read, or nil; if nil, 37 -- SOURCE is the name of the file or the string to read, or nil; if nil,
@@ -18,9 +39,9 @@ function m.inport (source, kind)
18 local f, l 39 local f, l
19 local k = kind or "file" 40 local k = kind or "file"
20 if source then 41 if source then
21 if kind == "file" then 42 if k == "file" then
22 f = io.open(source, "r") 43 f = io.open(source, "r")
23 elseif kind == "string" then 44 elseif k == "string" then
24 l = m.tochars(source) 45 l = m.tochars(source)
25 end 46 end
26 else 47 else
@@ -29,25 +50,10 @@ function m.inport (source, kind)
29 end 50 end
30 local t = { 51 local t = {
31 file = f, 52 file = f,
53 filename = source,
54 kind = kind,
32 line = l or {}, 55 line = l or {},
33 next_token = 56 next_token = inport_next_token,
34 function (self)
35 local tok, toktype
36 while true do
37 if #self.line == 0 and self.file then
38 self.line = m.tochars(
39 self.file:read("*l"))
40 end
41 if not self.line or #self.line == 0 then
42 return nil
43 end
44 tok, toktype, self.line =
45 m.scan(self.line)()
46 if tok ~= nil then
47 return tok, toktype
48 end
49 end
50 end,
51 } 57 }
52 if t.file then t.close = function (self) self.file:close() end; end 58 if t.file then t.close = function (self) self.file:close() end; end
53 local mt = { 59 local mt = {
@@ -232,12 +238,12 @@ m.readmacros = {
232 table.insert(Q, m.read(port)) 238 table.insert(Q, m.read(port))
233 return t.list(Q) 239 return t.list(Q)
234 end, 240 end,
235 comment = idf(nil), 241 comment = idf(nil)
236} 242}
237 243
238function m.read (port) 244function m.read (port)
239 local function read_ahead (tok, toktype) 245 local function read_ahead (tok, toktype)
240 if tok == nil then error("Unexpected EOF") end 246 if tok == m.eof then error("Unexpected EOF") end
241 if toktype == "open" then 247 if toktype == "open" then
242 local L = {} 248 local L = {}
243 while true do 249 while true do
@@ -262,7 +268,7 @@ function m.read (port)
262 end 268 end
263 -- body of read 269 -- body of read
264 local tok1, toktype1 = port:next_token() 270 local tok1, toktype1 = port:next_token()
265 if tok1 == nil then return nil 271 if tok1 == m.eof then return m.eof
266 else return read_ahead(tok1, toktype1) 272 else return read_ahead(tok1, toktype1)
267 end 273 end
268end 274end