diff --git a/lua_obj.lua b/lua_obj.lua index eca0bf1..569752a 100644 --- a/lua_obj.lua +++ b/lua_obj.lua @@ -150,13 +150,17 @@ do _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 = { ... } + if type(self.source) == 'string' then + local filename, start, stop = self.source:match("^(.-)[(%d+):(%d+)]$") + if start or stop then + self.source = Source(filename, tonumber(start), tonumber(stop)) + else + self.source = Source(self.source, 1, #self) + end + end end, __base = _base_0, __name = "Code" diff --git a/lua_obj.moon b/lua_obj.moon index 6ee1970..c315bdc 100644 --- a/lua_obj.moon +++ b/lua_obj.moon @@ -62,10 +62,13 @@ Source = immutable {"filename","start","stop"}, { class Code new: (@source, ...)=> + @bits = {...} if type(@source) == 'string' filename,start,stop = @source\match("^(.-)[(%d+):(%d+)]$") - @source = Source(filename, tonumber(start), tonumber(stop)) - @bits = {...} + if start or stop + @source = Source(filename, tonumber(start), tonumber(stop)) + else + @source = Source(@source, 1, #self) clone: => cls = @__class diff --git a/nomsu.lua b/nomsu.lua index 9a55d6a..6013467 100644 --- a/nomsu.lua +++ b/nomsu.lua @@ -61,7 +61,16 @@ local line_counter = re.compile([[ lines <- {| line (%nl line)* |} LINE_STARTS = setmetatable({ }, { __mode = "k", __index = function(self, k) - local line_starts = line_counter:match(tostring(k)) + if type(k) ~= 'string' then + k = tostring(k) + do + local v = rawget(self, k) + if v then + return v + end + end + end + local line_starts = line_counter:match(k) self[k] = line_starts return line_starts end @@ -203,7 +212,7 @@ end local NomsuCompiler do local _class_0 - local stub_defs, stub_pattern, var_pattern + local _nomsu_chunk_counter, stub_defs, stub_pattern, var_pattern local _base_0 = { define_action = function(self, signature, source, fn) if type(fn) ~= 'function' then @@ -330,11 +339,14 @@ do assert(tree, "In file " .. tostring(colored.blue(filename)) .. " failed to parse:\n" .. tostring(colored.onyellow(colored.black(nomsu_code)))) return tree end, - run = function(self, nomsu_code, source) - if type(source) == 'string' then - source = Source(source, 1, #nomsu_code) + run = function(self, nomsu_code) + if type(nomsu_code) == 'string' then + _nomsu_chunk_counter = _nomsu_chunk_counter + 1 + local filename = ".nom" + nomsu_code = Nomsu(filename, nomsu_code) + FILE_CACHE[filename] = nomsu_code end - if nomsu_code == "" then + if #nomsu_code == 0 then return nil end local tree = self:parse(nomsu_code, source) @@ -367,14 +379,14 @@ do local lua_filename = filename:gsub("%.nom$", ".lua") local file = FILE_CACHE[lua_filename] if file then - return self:run_lua(file, lua_filename) + return self:run_lua(file) end end local file = file or FILE_CACHE[filename] if not file then error("File does not exist: " .. tostring(filename), 0) end - return self:run(file, filename) + return self:run(file) else return error("Invalid filetype for " .. tostring(filename), 0) end @@ -1226,6 +1238,7 @@ do }) _base_0.__class = _class_0 local self = _class_0 + _nomsu_chunk_counter = 0 self.unescape_string = function(self, str) return Cs(((P("\\\\") / "\\") + (P("\\\"") / '"') + NOMSU_DEFS.escaped_char + P(1)) ^ 0):match(str) end @@ -1353,7 +1366,7 @@ if arg and debug_getinfo(2).func ~= require then else local retval, code if args.input == '-' then - retval, code = nomsu:run(io.read('a'), 'stdin') + retval, code = nomsu:run(io.read('a')) else retval, code = nomsu:run_file(args.input) end @@ -1367,7 +1380,7 @@ if arg and debug_getinfo(2).func ~= require then end end if args.flags["-i"] then - nomsu:run('use "core"', "stdin") + nomsu:run('use "core"') while true do io.write(colored.bright(colored.yellow(">> "))) local buff = "" @@ -1384,9 +1397,7 @@ if arg and debug_getinfo(2).func ~= require then break end local ret - ok, ret = pcall(function() - return nomsu:run(buff, "stdin") - end) + ok, ret = pcall(nomsu.run, nomsu, buff) if ok and ret ~= nil then print("= " .. repr(ret)) elseif not ok then diff --git a/nomsu.moon b/nomsu.moon index d9c3252..e10a8c3 100755 --- a/nomsu.moon +++ b/nomsu.moon @@ -41,6 +41,7 @@ debug_getinfo = debug.getinfo -- Re-implement nomsu-to-lua comment translation export FILE_CACHE +-- FILE_CACHE is a map from filename (string) -> file contents (Lua or Nomsu object) FILE_CACHE = setmetatable {}, { __index: (filename)=> file = io.open(filename) @@ -62,10 +63,16 @@ line_counter = re.compile([[ ]], nl:P("\r")^-1 * P("\n")) -- Mapping from line number -> character offset export LINE_STARTS +-- LINE_STARTS is a mapping from strings to a table that maps line number to character positions LINE_STARTS = setmetatable {}, { __mode:"k" __index: (k)=> - line_starts = line_counter\match(tostring(k)) + -- Implicitly convert Lua and Nomsu objects to strings + if type(k) != 'string' + k = tostring(k) + if v = rawget(self, k) + return v + line_starts = line_counter\match(k) self[k] = line_starts return line_starts } @@ -297,10 +304,14 @@ class NomsuCompiler assert tree, "In file #{colored.blue filename} failed to parse:\n#{colored.onyellow colored.black nomsu_code}" return tree - run: (nomsu_code, source)=> - if type(source) == 'string' - source = Source(source,1,#nomsu_code) - if nomsu_code == "" then return nil + _nomsu_chunk_counter = 0 + run: (nomsu_code)=> + if type(nomsu_code) == 'string' + _nomsu_chunk_counter += 1 + filename = ".nom" + nomsu_code = Nomsu(filename, nomsu_code) + FILE_CACHE[filename] = nomsu_code + if #nomsu_code == 0 then return nil tree = @parse(nomsu_code, source) assert tree, "Failed to parse: #{nomsu_code}" assert tree.type == "File", "Attempt to run non-file: #{tree.type}" @@ -328,11 +339,11 @@ class NomsuCompiler lua_filename = filename\gsub("%.nom$", ".lua") file = FILE_CACHE[lua_filename] if file - return @run_lua(file, lua_filename) + return @run_lua(file) file = file or FILE_CACHE[filename] if not file error("File does not exist: #{filename}", 0) - return @run(file, filename) + return @run(file) else error("Invalid filetype for #{filename}", 0) @@ -939,7 +950,7 @@ if arg and debug_getinfo(2).func != require else local retval, code if args.input == '-' - retval, code = nomsu\run(io.read('a'), 'stdin') + retval, code = nomsu\run(io.read('a')) else retval, code = nomsu\run_file(args.input) if compiled_output @@ -951,7 +962,7 @@ if arg and debug_getinfo(2).func != require if args.flags["-i"] -- REPL - nomsu\run('use "core"', "stdin") + nomsu\run('use "core"') while true io.write(colored.bright colored.yellow ">> ") buff = "" @@ -964,7 +975,7 @@ if arg and debug_getinfo(2).func != require io.write(colored.dim colored.yellow ".. ") if #buff == 0 break - ok, ret = pcall(-> nomsu\run(buff, "stdin")) + ok, ret = pcall(nomsu.run, nomsu, buff) if ok and ret != nil print "= "..repr(ret) elseif not ok