git @ Cat's Eye Technologies Decoy / ed77dc7
Introduce is_a() and stop checking `class` field explicitly. Chris Pressey 1 year, 8 months ago
6 changed file(s) with 41 addition(s) and 32 deletion(s). Raw diff Collapse all Expand all
132132
133133 * Interned strings and modules? Hash-consing, even?
134134 * Tracebacks, or at least line/column, or at least "in function..."
135 * isa instead of .class ==
136135
137136 ### Compiler
138137
152151 an "implementation module" written in language X will be used when
153152 the code is compiled to X. But the module defines the semantics.
154153
154 ### Desugar
155
156 * cond -> nested if's
157 * let* -> nested let1's
158
155159 ### Forms
156160
157161 * `if`
3030
3131 local emit_symbols = function(sexp)
3232 while sexp ~= Nil do
33 if sexp.class == Cons then
33 if is_a(sexp, Cons) then
3434 emit_symbol(sexp.head())
3535 if sexp.tail() ~= Nil then
3636 emit(",")
4343 end
4444
4545 fields.compile_expr = function(ast)
46 if ast.class == Cons then
46 if is_a(ast, Cons) then
4747 local head = ast.head()
48 if head.class == Symbol then
48 if is_a(head, Symbol) then
4949 if head.text() == "quote" then
5050 fields.compile_quote(ast.tail())
5151 elseif head.text() == "let*" then
6464 else
6565 error("Can't compile application not in A-normal form: " .. depict(ast))
6666 end
67 elseif ast.class == Symbol then
67 elseif is_a(ast, Symbol) then
6868 fields.compile_lookup(ast)
69 elseif ast.class == String or ast.class == Number or ast.class == Boolean then
69 elseif is_a(ast, String) or is_a(ast, Number) or is_a(ast, Boolean) then
7070 fields.compile_literal(ast)
7171 else
7272 error("Unsupported form for compilation: " .. depict(ast))
7575
7676 fields.compile_exprs = function(sexp, inter)
7777 while sexp ~= Nil do
78 if sexp.class == Cons then
78 if is_a(sexp, Cons) then
7979 fields.compile_expr(sexp.head())
8080 if sexp.tail() ~= Nil then
8181 inter()
115115
116116 fields.compile_bindings = function(sexp)
117117 while sexp ~= Nil do
118 if sexp.class == Cons then
118 if is_a(sexp, Cons) then
119119 local pair = sexp.head()
120120 debug("compiler", depict(pair))
121121 fields.compile_binding(pair.head(), pair.tail().head())
3636
3737 bind_all = function(bindings, env)
3838 local binding, value
39 while bindings.class ~= Nil do
39 while bindings ~= Nil do
4040 binding = bindings.head()
4141 value = eval_expr(binding.tail().head(), env)
4242 env = bind(binding.head(), value, env)
4747
4848 eval_exprs = function(sexp, env)
4949 local exprs = {}
50 while sexp.class ~= Nil do
51 if sexp.class == Cons then
50 while sexp ~= Nil do
51 if is_a(sexp, Cons) then
5252 table.insert(exprs, eval_expr(sexp.head(), env))
5353 else
5454 error("assertion failed: not a Cons")
5959 end
6060
6161 eval_expr = function(ast, env)
62 if ast.class == Cons then
62 if is_a(ast, Cons) then
6363 local head = ast.head()
64 if head.class == Symbol then
64 if is_a(head, Symbol) then
6565 if head.text() == "quote" then
6666 return ast.tail().head()
6767 elseif head.text() == "let*" then
7979 while branch.class ~= Nil do
8080 local b = branch.head()
8181 local test = b.head()
82 if test.class == Symbol and test.text() == "else" then
82 if is_a(test, Symbol) and test.text() == "else" then
8383 return eval_expr(b.tail().head(), env)
8484 else
8585 local result = eval_expr(test, env)
86 if result.class == Boolean and result.value() then
86 if is_a(result, Boolean) and result.value() then
8787 return eval_expr(b.tail().head(), env)
8888 end
8989 end
116116 fn = eval_expr(ast.head(), env)
117117 return fn(eval_exprs(ast.tail(), env))
118118 end
119 elseif ast.class == Symbol then
119 elseif is_a(ast, Symbol) then
120120 local value = env[ast.text()]
121121 if value == nil then
122122 error("Unbound symbol: " .. ast.text())
123123 end
124124 return value
125 elseif ast.class == String or ast.class == Number or ast.class == Boolean then
125 elseif is_a(ast, String) or is_a(ast, Number) or is_a(ast, Boolean) then
126126 return ast
127127 else
128128 error("Unsupported form for evaluation: " .. depict(ast))
8080 local s = ""
8181 if type(sexp) == "function" then
8282 return "<<" .. tostring(sexp) .. ">>"
83 elseif sexp.class == Nil then
83 elseif sexp == Nil then
8484 return "()"
85 elseif sexp.class == Cons then
85 elseif is_a(sexp, Cons) then
8686 s = s .. "("
8787 s = s .. depict(sexp.head())
8888 sexp = sexp.tail()
8989 local done = false
9090 while not done do
91 if sexp.class == Cons then
91 if is_a(sexp, Cons) then
9292 s = s .. " "
9393 s = s .. depict(sexp.head())
9494 sexp = sexp.tail()
101101 end
102102 s = s .. ")"
103103 return s
104 elseif sexp.class == Symbol then
104 elseif is_a(sexp, Symbol) then
105105 return sexp.text()
106 elseif sexp.class == String then
106 elseif is_a(sexp, String) then
107107 return "\"" .. sexp.text() .. "\""
108 elseif sexp.class == Number then
108 elseif is_a(sexp, Number) then
109109 return tostring(sexp.value())
110 elseif sexp.class == Boolean then
110 elseif is_a(sexp, Boolean) then
111111 if sexp.value() then return "#t" else return "#f" end
112112 else
113113 error("Invalid lua representation of s-expression: " .. render(sexp) .. ": " .. type(sexp))
3030 list_p = function(value)
3131 if type(value) == "function" then
3232 return False
33 elseif value.class == Nil then
33 elseif value == Nil then
3434 return True
35 elseif value.class == Cons then
35 elseif is_a(value, Cons) then
3636 return list_p(value.tail())
3737 else
3838 return False
4848 return False
4949 elseif a.class ~= b.class then
5050 return False
51 elseif a.class == Nil then
51 elseif a == Nil then
5252 return True
53 elseif a.class == String or a.class == Symbol then
53 elseif is_a(a, String) or is_a(a, Symbol) then
5454 return Boolean.value(a.text() == b.text())
55 elseif a.class == Number or a.class == Boolean then
55 elseif is_a(a, Number) or is_a(a, Boolean) then
5656 return Boolean.value(a.value() == b.value())
57 elseif a.class == Cons then
57 elseif is_a(a, Cons) then
5858 return equal_p(a.head(), b.head()) and equal_p(a.tail(), b.tail())
5959 else
6060 return False
183183 end
184184
185185 fields.eval_toplevel = function(expr, env, module)
186 if expr.class == Cons then
187 if expr.head().class == Symbol then
186 if is_a(expr, Cons) then
187 if is_a(expr.head(), Symbol) then
188188 if expr.head().text() == "define" then
189189 local name = expr.tail().head()
190190 local dexpr = expr.tail().tail().head()
3737 return tostring(v)
3838 end
3939 end
40
41 is_a = function(obj, class)
42 -- FIXME: for now this is just an equality test
43 return obj.class == class
44 end