9a99ede
Branches > main > 9a99ede > files
Allow any number of bindings in let
Commit: 9a99ede12817c70b7815c615b6cbfc89147cfb7f
Parent: a85f72c
2 changed files:
org/faddle/lang/compile.lua view file
@@ -71,6 +71,19 @@ return ret(statement) .. "function(" .. build_fn_args(fn_args) .. ") " .. compile_body(body) .. " end" end +local function build_let_bindings(bindings)+ assert(type(bindings) == "table" and #bindings >= 0 and #bindings % 2 == 0, "Let requires an even number of binding forms")+ local locals = {}+ local i = 1+ while i < #bindings do+ local sym = bindings[i]+ local binding = bindings[i + 1]+ locals[#locals + 1] = munge(sym) .. "=" .. compile(binding) .. ";"+ i = i + 2+ end+ return "do " .. table.concat(locals) .. " end"+end+ -- If I'm just using the same lexical stuff as Lua, how do builtin Lua modules work? -- In Lua you can just say `io`, but I'd like to wrap these libraries in something like `lua.io` -- to make it clear where they're coming from...@@ -83,13 +96,10 @@ local args = rest(form) local bindings = first(args) local body = rest(args)- assert(type(bindings) == "table" and #bindings % 2 == 0, "Let requires an even number of binding forms")- assert(#bindings == 2)- local sym = bindings[1]- local binding = bindings[2] if statement then- return "local " .. munge(sym) .. "=" .. compile(binding) .. ";" .. compile_body(body)+ return build_let_bindings(bindings) .. ";" .. compile_body(body) else+ -- Not sure if this is the best way to go about this :p return "return (function()" .. compile_let(form, not statement) .. " end)()" end endtest.lua view file
@@ -167,10 +167,15 @@ teq(read_eval("((fn [x y z] [x y z]) 1 2 3)"), {1, 2, 3}) teq(read_eval("((fn []))"), nil) teq(read_eval("((fn [] 1 2 3))"), 3)--- TODO still need variable amounts of let bindings!+ teq(read_eval("(let [x 1])"), nil) teq(read_eval("(let [x 2] 1 2 3)"), 3) +teq(read_eval("(let [])"), nil)+teq(read_eval("(let [] 42)"), 42)+teq(read_eval("(let [] 1 2 3)"), 3)+teq(read_eval("(let [x 1 y 2] [x y])"), {1, 2})+ -- Feels like do could be implemented in terms of let or fn idk. -- teq(read_eval("(do)"), nil) -- teq(read_eval("(do 1)"), 1)