8432b65

Faddle · faddle.git · Tickets

Branches > main > 8432b65 > files

Add compiler

Grahp, 2026-07-17

Commit: 8432b653b28cd9ec957cf18e6ffbe24188b9492d
Parent: d2ef4c4

3 changed files:

org/faddle/lang/compile.lua added (view file)

@@ -0,0 +1,57 @@+local LIST = require("org.faddle.lang.list")+local is_list = LIST.is_list+local cons = LIST.cons+local count = LIST.count+local first = LIST.first+local rest = LIST.rest+local apply = LIST.apply+local empty = LIST.empty+local symbol = require("org.faddle.lang.symbol")+local is_symbol = symbol.is_symbol+local intern = symbol.intern++-- Still bad :p+local FN = intern("fn")++local compile++local function compile_fn(form)+  local args = rest(form)+  local fn_args = first(args)+  local body = rest(args)+  assert(#fn_args == 0)+  assert(count(body) == 1)+  return "function() return " .. compile(first(body)) .. " end"+end++--- Returns a string of Lua source code from the form+compile = function(form)+  if is_list(form) then+    if count(form) == 0 then return "__rt.list()" end+    if first(form) == FN then return compile_fn(form) end+    -- macro expansion :D+    -- rt functions?+  else+    local t = type(form)+    if t == "number" or t == "nil" or t == "boolean" then+      return tostring(form)+    elseif t == "string" then+      return string.format("%q", form)+    else+      error("Cannot compile form of type '" .. t .. "'")+    end+  end+end++local loadfn = loadstring or load++local function execute(lua_source, chunk_name)+  local chunk, err = loadfn("local __rt = require('org.faddle.lang.rt');return " .. lua_source, chunk_name)+  if not chunk then+    error(err)+  else+    return chunk()+  end+end++return {compile = compile, execute = execute}

org/faddle/lang/eval.lua modified (view file)

@@ -10,6 +10,10 @@ local is_symbol = symbol.is_symbol local intern = symbol.intern +local compiler = require("org.faddle.lang.compile")+local compile = compiler.compile+local execute = compiler.execute+ local eval  -- Table of module names -> module tables?@@ -21,16 +25,21 @@ -- And re-defining updates the var and calls its handler or whatever, or calls an update_var() idk, and it also updates the module table local function def(var_name, args, env)   assert(is_symbol(var_name), "def must be called with a symbol")+  assert(modules[env.current_module] ~= nil, "Cannot define var in non-existent module '" .. env.current_module .. "'")   local val = eval(first(args), env)   -- Doesn't add to the return table right now   -- Probably want to munge names so they're easier to use from Lua.   -- I'm not sure whether like 'foo?' and 'is_foo' should be the same symbol or just munged to produce the same thing.-  env[env.current_module][var_name] = val+  print(env.current_module)+  print(var_name)+  print(env.user)+  modules[env.current_module][var_name] = val   return var_name end  local function module(mod_name, env)   if type(mod_name) ~= "string" then error("First argument to module must be a string!") end+  -- Why not?   if package.loaded[mod_name] and not modules[mod_name] then     error("Cannot override already defined Lua module " .. mod_name)   else@@ -50,6 +59,7 @@ local DEF = intern("def") local MODULE = intern("module") local QUOTE = intern("quote")+local FN = intern("fn")  -- Should eventually be in core/boot ofc they're just here now so I can test functions before figuring out modules local temp_functions =@@ -73,8 +83,15 @@ end  -- Not quite sure how to do this...+-- Do tables need to be compiled into Lua?+-- Not simple ones, but others may benefit, I'm not sure. local function eval_table(t, env)-  return t+  local ret = {}+  for k, v in pairs(t) do+    -- Could end up with holes, but that's the user's fault+    ret[eval(k, env)] = eval(v, env)+  end+  return ret end  local function map_eval(lst, env)@@ -114,6 +131,7 @@     if f == QUOTE  then return second(form) end     if f == MODULE then return module(second(form), env) end     if f == DEF    then return def(second(form), rest(rest(form)), env) end+    if f == FN     then return execute(compile(form), "eval_fn") end      form = map_eval(form, env)     return call(first(form), rest(form))

org/faddle/lang/rt.lua added (view file)

@@ -0,0 +1,6 @@++local LIST = require("org.faddle.lang.list")++local list = LIST.list++return {list = list}