From 70ec5254814f9531e5ca2024465d0e01130306b7 Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Wed, 21 Feb 2024 09:28:49 -0600 Subject: Initial commit --- read.lua | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 read.lua (limited to 'read.lua') diff --git a/read.lua b/read.lua new file mode 100644 index 0000000..72bbd4d --- /dev/null +++ b/read.lua @@ -0,0 +1,74 @@ +--- lam.read + +local read = {} + +local types = require "types" +local util = require "util" + +function read.tokenize (str) + --[[ Convert a string of characters into a list of tokens ]] + assert(str, "No program given") + local tbl = {} + local word = "" + local push_word = + function () + if word:len() > 0 then + table.insert(tbl, word) + word = "" + end + end + + for c = 1, #str do + char = string.char(str:byte(c)) + if char == " " or char == "\t" or char == "\n" then + push_word() + elseif char == "(" then + push_word() + table.insert(tbl, "(") + elseif char == ")" then + push_word() + table.insert(tbl, ")") + else + word = word .. char + end + end + push_word() + return tbl +end + +function read.read (str) + -- [[ Read a scheme expression from a string ]] + + local function Atom (token) + local n = tonumber(token) + if n then return n + else return tostring(token) + end + end + + local function read_tokens (tokens) + --[[ Read a list of tokens from `tokenize' ]] + assert(next(tokens), "Unexpected EOF") + token = util.pop(tokens) + if token == "(" then + local L = {} + while tokens[1] ~= ")" do + table.insert(L, read_tokens(tokens)) + end + util.pop(tokens) -- remove ")" + return L + elseif token == ")" then + error("Unexpected ')'") + else + return Atom(token) + end + end + + return read_tokens(read.tokenize(str)) +end + +return setmetatable(read, { __call = + function(_, str) + return read.read(str) + end, +}) -- cgit 1.4.1-21-gabe81