From 16f3a189fd9b32f599d1271c772e6d4287f95d20 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 18 Apr 2018 15:28:46 -0700 Subject: More working, shifting towards having Lua and Nomsu objects instead of just strings. --- lua_obj.lua | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 205 insertions(+), 38 deletions(-) (limited to 'lua_obj.lua') diff --git a/lua_obj.lua b/lua_obj.lua index ba8277c..eca0bf1 100644 --- a/lua_obj.lua +++ b/lua_obj.lua @@ -4,23 +4,30 @@ do insert, remove, concat = _obj_0.insert, _obj_0.remove, _obj_0.concat end local immutable = require('immutable') -local Lua, Location -Location = immutable({ +local Lua, Source +Source = immutable({ "filename", "start", "stop" }, { - name = "Location", + name = "Source", __new = function(self, filename, start, stop) - return filename, start, stop or start + if stop then + assert(start <= stop, "Invalid range: " .. tostring(start) .. ", " .. tostring(stop)) + end + return filename, start, stop end, __tostring = function(self) - return "Location(\"" .. tostring(self.filename) .. "\", " .. tostring(self.start) .. ", " .. tostring(self.stop) .. ")" + if self.stop then + return "Source(\"" .. tostring(self.filename) .. "\", " .. tostring(self.start) .. ", " .. tostring(self.stop) .. ")" + else + return "Source(\"" .. tostring(self.filename) .. "\", " .. tostring(self.start) .. ")" + end 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 + return (self.stop or self.start) < (other.stop or other.start) else return self.start < other.start end @@ -28,11 +35,36 @@ Location = immutable({ __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 + return (self.stop or self.start) <= (other.stop or other.start) else return self.start <= other.start end end, + __add = function(self, offset) + if type(self) == 'number' then + offset, self = self, offset + else + assert(type(offset) == 'number', "Cannot add Source and " .. tostring(type(offset))) + end + return Source(self.filename, self.start + offset, self.stop) + end, + sub = function(self, start, stop) + if not self.stop then + assert(not stop, "cannot subscript non-range with range") + assert(start > 0, "cannot subscript non-range with negative index") + return Source(self.filename, self.start + (start or 0)) + else + start = start or 1 + if start < 0 then + start = self.stop + start + 1 + end + stop = stop or -1 + if stop < 0 then + stop = self.stop + stop + 1 + end + return Source(self.filename, self.start + start - 1, self.start + stop - 1) + end + end, get_text = function(self) return FILE_CACHE[self.filename]:sub(self.start, self.stop) end, @@ -61,19 +93,88 @@ Location = immutable({ end end }) +local Code do local _class_0 local _base_0 = { clone = function(self) - local copy = Lua(self.source, { - unpack(self.bits) - }) + local cls = self.__class + local copy = cls(self.source, unpack(self.bits)) copy.is_value = self.is_value for k, v in pairs(self.free_vars) do copy.free_vars[k] = v end return copy end, + __tostring = function(self) + local buff = { } + for i, b in ipairs(self.bits) do + buff[#buff + 1] = tostring(b) + end + local ret = concat(buff, "") + 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, + sub = function(self, start, stop) + local str = tostring(self):sub(start, stop) + local cls = self.__class + return cls(self.source:sub(start - self.source.start + 1, stop - self.source.stop + 1), str) + end, + append = function(self, ...) + local n = select("#", ...) + local bits = self.bits + for i = 1, n do + 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 + bits[i] = bits[i - n] + end + for i = 1, n do + bits[i] = select(i, ...) + end + 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 = Source(filename, tonumber(start), tonumber(stop)) + end + self.bits = { + ... + } + end, + __base = _base_0, + __name = "Code" + }, { + __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 + Code = _class_0 +end +do + local _class_0 + local _parent_0 = Code + local _base_0 = { add_free_vars = function(self, ...) local seen do @@ -150,9 +251,6 @@ do local buff = { } for i, b in ipairs(self.bits) do buff[#buff + 1] = tostring(b) - if i < #self.bits and type(b) ~= 'string' and not b.is_value then - buff[#buff + 1] = "\n" - end end local ret = concat(buff, "") return ret @@ -166,30 +264,33 @@ do end return len end, - __add = function(self, other) - return Lua(nil, self, other) - end, - __concat = function(self, other) - return Lua(nil, self, other) - end, append = function(self, ...) local n = select("#", ...) local bits = self.bits for i = 1, n do - bits[#bits + 1] = select(i, ...) + local bit = select(i, ...) + bits[#bits + 1] = bit + if type(bit) ~= 'string' and not bit.is_value and #self.bits > 0 then + bits[#bits + 1] = "\n" + end end end, prepend = function(self, ...) local n = select("#", ...) local bits = self.bits - for i = #bits + n, n + 1, -1 do - bits[i] = bits[i - n] - end + local insert_index = 1 for i = 1, n do - bits[i] = select(i, ...) + local bit = select(i, ...) + insert(bits, insert_index, bit) + insert_index = insert_index + 1 + if type(bit) ~= 'string' and not bit.is_value and insert_index < #self.bits + 1 then + insert(bits, insert_index, "\n") + insert_index = insert_index + 1 + end end end, - make_offset_table = function(self, lua_chunkname) + make_offset_table = function(self) + local lua_chunkname = tostring(self.source) .. ".lua" local lua_str = tostring(self) local metadata = { nomsu_filename = self.source.filename, @@ -211,7 +312,7 @@ do walk(b) end local lua_stop = lua_offset - local nomsu_src, lua_src = lua.source, Location(lua_chunkname, lua_start, lua_stop) + local nomsu_src, lua_src = lua.source, Source(lua_chunkname, lua_start, lua_stop) metadata.lua_to_nomsu[lua_src] = nomsu_src metadata.nomsu_to_lua[nomsu_src] = lua_src end @@ -229,23 +330,28 @@ do end } _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) _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 - self.bits = { - ... - } + __init = function(self, ...) + _class_0.__parent.__init(self, ...) self.free_vars = { } self.is_value = false end, __base = _base_0, - __name = "Lua" + __name = "Lua", + __parent = _parent_0 }, { - __index = _base_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, ...) @@ -259,9 +365,70 @@ do lua.is_value = true return lua end + if _parent_0.__inherited then + _parent_0.__inherited(_parent_0, _class_0) + end Lua = _class_0 end +local Nomsu +do + local _class_0 + local _parent_0 = Code + local _base_0 = { + __tostring = function(self) + local buff = { } + for i, b in ipairs(self.bits) do + buff[#buff + 1] = tostring(b) + end + local ret = concat(buff, "") + 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 + } + _base_0.__index = _base_0 + setmetatable(_base_0, _parent_0.__base) + _class_0 = setmetatable({ + __init = function(self, ...) + return _class_0.__parent.__init(self, ...) + end, + __base = _base_0, + __name = "Nomsu", + __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 + Nomsu = _class_0 +end return { + Code = Code, + Nomsu = Nomsu, Lua = Lua, - Location = Location + Source = Source } -- cgit v1.2.3