3 | 3 |
|
4 | 4 |
table = require "table"
|
5 | 5 |
string = require "string"
|
|
6 |
io = require "io"
|
|
7 |
|
6 | 8 |
require "decoy_util"
|
7 | 9 |
require "decoy_model"
|
8 | 10 |
|
|
13 | 15 |
end
|
14 | 16 |
|
15 | 17 |
Compiler = {}
|
16 | |
Compiler.new = function()
|
|
18 |
Compiler.new = function(outfile)
|
17 | 19 |
local fields = {}
|
18 | 20 |
fields.class = Compiler
|
19 | 21 |
|
|
22 |
local emit = function(s)
|
|
23 |
outfile:write(s)
|
|
24 |
end
|
|
25 |
|
|
26 |
local emit_symbol = function(sym)
|
|
27 |
if sym.class ~= Symbol then error("Not a symbol: " .. depict(sym)) end
|
|
28 |
emit(mangle(depict(sym)))
|
|
29 |
end
|
|
30 |
|
|
31 |
local emit_symbols = function(sexp)
|
|
32 |
while sexp ~= Nil do
|
|
33 |
if sexp.class == Cons then
|
|
34 |
emit_symbol(sexp.head())
|
|
35 |
if sexp.tail() ~= Nil then
|
|
36 |
emit(",")
|
|
37 |
end
|
|
38 |
else
|
|
39 |
error("assertion failed: not a Cons")
|
|
40 |
end
|
|
41 |
sexp = sexp.tail()
|
|
42 |
end
|
|
43 |
end
|
|
44 |
|
20 | 45 |
fields.compile_exprs = function(sexp, inter)
|
21 | |
local exprs = {}
|
22 | |
while sexp.class ~= Nil do
|
|
46 |
while sexp ~= Nil do
|
23 | 47 |
if sexp.class == Cons then
|
24 | 48 |
fields.compile_expr(sexp.head())
|
25 | |
if inter then
|
|
49 |
if sexp.tail() ~= Nil then
|
26 | 50 |
inter()
|
27 | 51 |
end
|
28 | 52 |
else
|
|
64 | 88 |
end
|
65 | 89 |
|
66 | 90 |
fields.compile_import_from = function(ast)
|
67 | |
print("/* import " .. mangle(depict(ast.head())) .. " " .. depict(ast.tail()) .. " */")
|
|
91 |
emit("/* import ")
|
|
92 |
emit(depict(ast.head()))
|
|
93 |
emit(" " .. depict(ast.tail()))
|
|
94 |
emit(" */\n")
|
68 | 95 |
end
|
69 | 96 |
|
70 | 97 |
fields.compile_application = function(ast)
|
71 | |
print(mangle(depict(ast.head())) .. "(")
|
72 | |
fields.compile_exprs(ast.tail(), function() print "," end)
|
73 | |
print(")")
|
|
98 |
emit_symbol(ast.head())
|
|
99 |
emit("(")
|
|
100 |
fields.compile_exprs(ast.tail(), function() emit(",") end)
|
|
101 |
emit(")")
|
74 | 102 |
end
|
75 | 103 |
|
76 | 104 |
fields.compile_literal = function(ast)
|
77 | |
print(depict(ast))
|
|
105 |
emit(depict(ast))
|
78 | 106 |
end
|
79 | 107 |
|
80 | 108 |
fields.compile_define = function(ast, env)
|
81 | |
print(mangle(depict(ast.head())) .. " = ")
|
|
109 |
emit_symbol(ast.head())
|
|
110 |
emit(" = ")
|
82 | 111 |
fields.compile_expr(ast.tail().head(), env)
|
83 | |
print(";")
|
|
112 |
emit(";\n")
|
84 | 113 |
end
|
85 | 114 |
|
86 | 115 |
fields.compile_lambda = function(ast, env)
|
87 | 116 |
local args = ast.head()
|
88 | |
print("function")
|
89 | |
print(depict(args)) -- FIXME mangle each of these
|
90 | |
print("{")
|
|
117 |
emit("function")
|
|
118 |
emit("(")
|
|
119 |
emit_symbols(args)
|
|
120 |
emit(") {")
|
91 | 121 |
local body = ast.tail().head()
|
92 | |
print("return ")
|
|
122 |
emit("return ")
|
93 | 123 |
fields.compile_expr(body, env)
|
94 | |
print(";")
|
95 | |
print("}")
|
|
124 |
emit(";}")
|
96 | 125 |
end
|
97 | 126 |
|
98 | 127 |
fields.compile_lookup = function(ast)
|
99 | |
print(mangle(depict(ast)))
|
|
128 |
emit(mangle(depict(ast)))
|
100 | 129 |
end
|
101 | 130 |
|
102 | 131 |
fields.compile_let_star = function(ast)
|
103 | |
print(depict(ast))
|
|
132 |
emit(depict(ast))
|
104 | 133 |
end
|
105 | 134 |
|
106 | 135 |
return fields
|