diff --git a/lua_obj.lua b/lua_obj.lua
new file mode 100644
index 0000000..a0ff4db
--- /dev/null
+++ b/lua_obj.lua
@@ -0,0 +1,307 @@
+local insert, remove, concat
+do
+  local _obj_0 = table
+  insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat
+end
+local immutable = require('immutable')
+local Lua, LuaValue, Location
+Location = immutable({
+  "filename",
+  "start",
+  "stop"
+}, {
+  name = "Location",
+  __new = function(self, filename, start, stop)
+    assert(type(filename) == 'string' and type(start) == 'number' and type(stop) == 'number')
+    return filename, start, stop or start
+  end,
+  __tostring = function(self)
+    return "Location(\"" .. tostring(self.filename) .. "\", " .. tostring(self.start) .. ", " .. tostring(self.stop) .. ")"
+  end,
+  __lt = function(self, other)
+    assert(self.filename == other.filename, "Cannot compare sources from different files")
+    if self.start == other.start then
+      return self.stop < other.stop
+    else
+      return self.start < other.start
+    end
+  end,
+  __le = function(self, other)
+    assert(self.filename == other.filename, "Cannot compare sources from different files")
+    if self.start == other.start then
+      return self.stop <= other.stop
+    else
+      return self.start <= other.start
+    end
+  end,
+  get_text = function(self)
+    return FILE_CACHE[self.filename]:sub(self.start, self.stop)
+  end,
+  get_line_number = function(self)
+    local line_starts = LINE_STARTS[FILE_CACHE[self.filename]]
+    local start_line = 1
+    while (line_starts[start_line + 1] or (#src + 1)) <= self.start do
+      start_line = start_line + 1
+    end
+    local stop_line = start_line
+    while (line_starts[stop_line + 1] or (#src + 1)) <= self.stop do
+      stop_line = stop_line + 1
+    end
+    return start_line, stop_line
+  end,
+  get_line = function(self)
+    return tostring(self.filename) .. ":" .. tostring(self:get_line_number())
+  end,
+  get_line_range = function(self)
+    local start_line, stop_line = self:get_line_number()
+    if stop_line == start_line then
+      return tostring(self.filename) .. ":" .. tostring(start_line)
+    else
+      return tostring(self.filename) .. ":" .. tostring(start_line) .. "-" .. tostring(stop_line)
+    end
+  end
+})
+do
+  local _class_0
+  local _base_0 = {
+    is_statement = true,
+    is_value = false,
+    add_free_vars = function(self, free_vars)
+      local seen
+      do
+        local _tbl_0 = { }
+        local _list_0 = self.free_vars
+        for _index_0 = 1, #_list_0 do
+          local v = _list_0[_index_0]
+          local _key_0, _val_0 = {
+            [v] = true
+          }
+          _tbl_0[_key_0] = _val_0
+        end
+        seen = _tbl_0
+      end
+      for _index_0 = 1, #free_vars do
+        local var = free_vars[_index_0]
+        if not (seen[var]) then
+          self.free_vars[#self.free_vars + 1] = var
+          seen[var] = true
+        end
+      end
+    end,
+    as_statements = function(self)
+      return self
+    end,
+    declare_locals = function(self, skip)
+      if skip == nil then
+        skip = { }
+      end
+      if next(skip) == 1 then
+        do
+          local _tbl_0 = { }
+          for _index_0 = 1, #skip do
+            local s = skip[_index_0]
+            local _key_0, _val_0 = {
+              [s] = true
+            }
+            _tbl_0[_key_0] = _val_0
+          end
+          skip = _tbl_0
+        end
+      end
+      if #self.free_vars > 0 then
+        self:prepend("local " .. tostring(concat(self.free_vars, ", ")) .. ";\n")
+      end
+      local _list_0 = self.free_vars
+      for _index_0 = 1, #_list_0 do
+        local var = _list_0[_index_0]
+        skip[var] = true
+      end
+      local _list_1 = self.bits
+      for _index_0 = 1, #_list_1 do
+        local bit = _list_1[_index_0]
+        if type(bit) == Lua then
+          bit:declare_locals(skip)
+        end
+      end
+    end,
+    __tostring = function(self)
+      local buff = { }
+      local _list_0 = self.bits
+      for _index_0 = 1, #_list_0 do
+        local b = _list_0[_index_0]
+        buff[#buff + 1] = tostring(b)
+      end
+      local ret = concat(buff, "")
+      assert(not ret:match(".*table: 0x.*"))
+      return ret
+    end,
+    __len = function(self)
+      local len = 0
+      local _list_0 = self.bits
+      for _index_0 = 1, #_list_0 do
+        local b = _list_0[_index_0]
+        len = len + #b
+      end
+      return len
+    end,
+    append = function(self, ...)
+      local n = select("#", ...)
+      local bits = self.bits
+      for i = 1, n do
+        local x = select(i, ...)
+        assert(type(x) ~= 'table' or getmetatable(x))
+        bits[#bits + 1] = select(i, ...)
+      end
+    end,
+    prepend = function(self, ...)
+      local n = select("#", ...)
+      local bits = self.bits
+      for i = #bits + n, n + 1, -1 do
+        local x = select(i, ...)
+        assert(type(x) ~= 'table' or getmetatable(x))
+        bits[i] = bits[i - n]
+      end
+      for i = 1, n do
+        local x = select(i, ...)
+        assert(type(x) ~= 'table' or getmetatable(x))
+        bits[i] = select(i, ...)
+      end
+    end,
+    make_offset_table = function(self, lua_chunkname)
+      local lua_str = tostring(self)
+      local metadata = {
+        nomsu_filename = self.source.filename,
+        lua_filename = lua_chunkname,
+        lua_file = lua_str,
+        lua_to_nomsu = { },
+        nomsu_to_lua = { }
+      }
+      local lua_offset = 1
+      local walk
+      walk = function(lua)
+        if type(lua) == 'string' then
+          lua_offset = lua_offset + #lua
+        else
+          local lua_start = lua_offset
+          local _list_0 = lua.bits
+          for _index_0 = 1, #_list_0 do
+            local b = _list_0[_index_0]
+            walk(b)
+          end
+          local lua_stop = lua_offset
+          local nomsu_src, lua_src = lua.source, Location(lua_chunkname, lua_start, lua_stop)
+          metadata.lua_to_nomsu[lua_src] = nomsu_src
+          metadata.nomsu_to_lua[nomsu_src] = lua_src
+        end
+      end
+      walk(self)
+      return lua_str, metadata
+    end
+  }
+  _base_0.__index = _base_0
+  _class_0 = setmetatable({
+    __init = function(self, source, ...)
+      self.source = source
+      if type(self.source) == 'string' then
+        local filename, start, stop = self.source:match("^(.-)[(%d+):(%d+)]$")
+        self.source = Location(filename, tonumber(start), tonumber(stop))
+      end
+      for i = 1, select("#", ...) do
+        local x = select(i, ...)
+        assert(type(x) ~= 'table' or getmetatable(x))
+      end
+      self.bits = {
+        ...
+      }
+      self.free_vars = { }
+    end,
+    __base = _base_0,
+    __name = "Lua"
+  }, {
+    __index = _base_0,
+    __call = function(cls, ...)
+      local _self_0 = setmetatable({}, _base_0)
+      cls.__init(_self_0, ...)
+      return _self_0
+    end
+  })
+  _base_0.__class = _class_0
+  Lua = _class_0
+end
+do
+  local _class_0
+  local _parent_0 = Lua
+  local _base_0 = {
+    is_statement = false,
+    is_value = true,
+    __tostring = function(self)
+      local buff = { }
+      local _list_0 = self.bits
+      for _index_0 = 1, #_list_0 do
+        local b = _list_0[_index_0]
+        buff[#buff + 1] = tostring(b)
+      end
+      local ret = concat(buff, "")
+      assert(not ret:match(".*table: 0x.*"))
+      return ret
+    end,
+    as_statements = function(self, prefix, suffix)
+      if prefix == nil then
+        prefix = ""
+      end
+      if suffix == nil then
+        suffix = ";"
+      end
+      local bits = {
+        prefix,
+        unpack(self.bits)
+      }
+      bits[#bits + 1] = suffix
+      return Lua(self.source, unpack(bits))
+    end,
+    parenthesize = function(self)
+      self:prepend("(")
+      return self:append(")")
+    end
+  }
+  _base_0.__index = _base_0
+  setmetatable(_base_0, _parent_0.__base)
+  _class_0 = setmetatable({
+    __init = function(self, source, ...)
+      self.source = source
+      self.bits = {
+        ...
+      }
+    end,
+    __base = _base_0,
+    __name = "LuaValue",
+    __parent = _parent_0
+  }, {
+    __index = function(cls, name)
+      local val = rawget(_base_0, name)
+      if val == nil then
+        local parent = rawget(cls, "__parent")
+        if parent then
+          return parent[name]
+        end
+      else
+        return val
+      end
+    end,
+    __call = function(cls, ...)
+      local _self_0 = setmetatable({}, _base_0)
+      cls.__init(_self_0, ...)
+      return _self_0
+    end
+  })
+  _base_0.__class = _class_0
+  if _parent_0.__inherited then
+    _parent_0.__inherited(_parent_0, _class_0)
+  end
+  LuaValue = _class_0
+end
+return {
+  Lua = Lua,
+  LuaValue = LuaValue,
+  Location = Location
+}