From 4eaaedc486d60fde724abf1af70e21fc2b3e5c49 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Sun, 31 Mar 2024 22:16:37 -0500 Subject: Add rest of quotes to reader --- read.lua | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) 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 local pp = require("pp").pp +-- TODO: +-- - string reading +-- - # syntax +-- - comments +-- - probably more + function m.inport (source, kind) -- KIND can be one of "file", "string"; defaults to "file" -- SOURCE is the name of the file or the string to read, or nil; if nil, @@ -85,6 +91,18 @@ end m.readtable = { ["("] = function (cs) return pop(cs), "open", cs end, [")"] = function (cs) return pop(cs), "close", cs end, + ["'"] = function (cs) return pop(cs), "quote", cs end, + ["`"] = function (cs) return pop(cs), "quote", cs end, + [","] = + function (cs) + pop(cs) -- remove ',' + if cs[1] == "@" then + pop(cs) -- remove '@' + return ",@", "quote", cs + else + return ",", "quote", cs + end + end, } -- Return an iterator over a character table, so you can do: @@ -131,6 +149,24 @@ function m.readchar (port) end end +m.readmacros = { + quote = + function (tok, toktype, port) + local qs = { + ["'"] = "quote", + ["`"] = "quasiquote", + [","] = "unquote", + [",@"] = "unquote-splicing", + } + if not qs[tok] then + error(string.format("Bad quote: '%s'\n", tok)) + end + local Q = {qs[tok]} + table.insert(Q, m.read(port)) + return t.list(Q) + end, +} + function m.read (port) local function read_ahead (tok, toktype) if not tok then error("Unexpected EOF") end @@ -151,6 +187,8 @@ function m.read (port) end elseif toktype == "close" then error("Unexpected ')'") + elseif m.readmacros[toktype] then + return m.readmacros[toktype](tok, toktype, port) else return tok end end -- cgit 1.4.1-21-gabe81