9a99ede

Faddle · faddle.git · Tickets

Branches > main > 9a99ede > files

Allow any number of bindings in let

Grahp, 2026-07-19

Commit: 9a99ede12817c70b7815c615b6cbfc89147cfb7f
Parent: a85f72c

2 changed files:

org/faddle/lang/compile.lua modified (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 end

test.lua modified (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)