diff options
Diffstat (limited to 'nomsu.moon')
| -rwxr-xr-x | nomsu.moon | 154 |
1 files changed, 9 insertions, 145 deletions
@@ -21,11 +21,14 @@ colored = setmetatable({}, {__index:(_,color)-> ((msg)-> colors[color]..tostring {:insert, :remove, :concat} = table unpack or= table.unpack {:match, :sub, :rep, :gsub, :format, :byte, :match, :find} = string -debug_getinfo = debug.getinfo {:NomsuCode, :LuaCode, :Source} = require "code_obj" AST = require "nomsu_tree" parse = require("parser") STDIN, STDOUT, STDERR = "/dev/fd/0", "/dev/fd/1", "/dev/fd/2" +-- Mapping from source string (e.g. "@core/metaprogramming.nom[1:100]") to a mapping +-- from lua line number to nomsu line number +export SOURCE_MAP +SOURCE_MAP = {} string.as_lua_id = (str)-> argnum = 0 @@ -147,9 +150,6 @@ with NomsuCompiler .nomsu = NomsuCompiler .parse = (...)=> parse(...) - -- Mapping from source string (e.g. "@core/metaprogramming.nom[1:100]") to a mapping - -- from lua line number to nomsu line number - .source_map = {} -- Discretionary/convenience stuff to_add = { repr:repr, stringify:stringify, utils:utils, lpeg:lpeg, re:re, @@ -347,7 +347,7 @@ with NomsuCompiler "\n") error("Failed to compile generated code:\n#{colored.bright colored.blue colored.onblack line_numbered_lua}\n\n#{err}", 0) source_key = tostring(source or lua.source) - unless @source_map[source_key] + unless SOURCE_MAP[source_key] map = {} offset = 1 source or= lua.source @@ -368,7 +368,7 @@ with NomsuCompiler map[lua_line] or= nomsu_line map[0] = 0 -- Mapping from lua line number to nomsu line numbers - @source_map[source_key] = map + SOURCE_MAP[source_key] = map return run_lua_fn! @@ -798,7 +798,7 @@ with NomsuCompiler -- Command line interface: -- Only run this code if this file was run directly with command line arguments, and not require()'d: -if arg and debug_getinfo(2).func != require +if arg and debug.getinfo(2).func != require parser = re.compile([[ args <- {| (flag ";")* {:inputs: {| ({file} ";")* |} :} {:nomsu_args: {| ("--;" ({[^;]*} ";")*)? |} :} ";"? |} !. flag <- @@ -835,130 +835,6 @@ OPTIONS nomsu = NomsuCompiler nomsu.arg = args.nomsu_args - - ok, to_lua = pcall -> require('moonscript.base').to_lua - if not ok then to_lua = nil - moonscript_line_tables = setmetatable {}, { - __index: (filename)=> - return nil unless to_lua - _, line_table = to_lua(FILE_CACHE[filename]) - self[filename] = line_table - return line_table - } - - debug.getinfo = (thread,f,what)-> - if what == nil - f,what,thread = thread,f,nil - if type(f) == 'number' then f += 1 -- Account for this wrapper function - info = if thread == nil - debug_getinfo(f,what) - else debug_getinfo(thread,f,what) - if not info or not info.func then return info - if info.short_src or info.source or info.linedefine or info.currentline - -- TODO: get name properly - if map = nomsu.source_map[info.source] - if info.currentline - info.currentline = assert(map[info.currentline]) - if info.linedefined - info.linedefined = assert(map[info.linedefined]) - if info.lastlinedefined - info.lastlinedefined = assert(map[info.lastlinedefined]) - --info.short_src = info.source\match('@([^[]*)') - return info - - print_err_msg = (error_message, stack_offset=3)-> - io.stderr\write("#{colored.red "ERROR:"} #{colored.bright colored.red (error_message or "")}\n") - io.stderr\write("stack traceback:\n") - - -- TODO: properly print out the calling site of nomsu code, not just the *called* code - ok, to_lua = pcall -> require('moonscript.base').to_lua - if not ok then to_lua = -> nil - nomsu_source = FILE_CACHE["nomsu.moon"] - LINE_TABLES = setmetatable {}, - __index: (file)=> - _, line_table = to_lua(file) - self[file] = line_table or false - return line_table or false - - get_line = (file, line_no)-> - start = LINE_STARTS[file][line_no] or 1 - stop = (LINE_STARTS[file][line_no+1] or 0) - 1 - return file\sub(start, stop) - - level = stack_offset - while true - -- TODO: reduce duplicate code - calling_fn = debug_getinfo(level) - if not calling_fn then break - if calling_fn.func == run then break - level += 1 - name = calling_fn.name and "function '#{calling_fn.name}'" or nil - if calling_fn.linedefined == 0 then name = "main chunk" - if name == "run_lua_fn" then continue - line = nil - if map = nomsu.source_map[calling_fn.source] - if calling_fn.currentline - calling_fn.currentline = assert(map[calling_fn.currentline]) - if calling_fn.linedefined - calling_fn.linedefined = assert(map[calling_fn.linedefined]) - if calling_fn.lastlinedefined - calling_fn.lastlinedefined = assert(map[calling_fn.lastlinedefined]) - --calling_fn.short_src = calling_fn.source\match('"([^[]*)') - filename,start,stop = calling_fn.source\match('@([^[]*)%[([0-9]+):([0-9]+)]') - assert(filename) - file = FILE_CACHE[filename]\sub(tonumber(start),tonumber(stop)) - err_line = get_line(file, calling_fn.currentline)\sub(1,-2) - offending_statement = colored.bright(colored.red(err_line\match("^[ ]*(.*)"))) - -- TODO: get name properly - name = "action '#{calling_fn.name}'" - line = colored.yellow("#{filename}:#{calling_fn.currentline} in #{name}\n #{offending_statement}") - else - ok, file = pcall ->FILE_CACHE[calling_fn.short_src] - if not ok then file = nil - local line_num - if name == nil - search_level = level - _info = debug.getinfo(search_level) - while _info and (_info.func == pcall or _info.func == xpcall) - search_level += 1 - _info = debug.getinfo(search_level) - if _info - for i=1,999 - varname, val = debug.getlocal(search_level, i) - if not varname then break - if val == calling_fn.func - name = "local '#{varname}'" - if not varname\match("%(") - break - unless name - for i=1,_info.nups - varname, val = debug.getupvalue(_info.func, i) - if not varname then break - if val == calling_fn.func - name = "upvalue '#{varname}'" - if not varname\match("%(") - break - if file and calling_fn.short_src\match(".moon$") and LINE_TABLES[file] - char = LINE_TABLES[file][calling_fn.currentline] - line_num = 1 - for _ in file\sub(1,char)\gmatch("\n") do line_num += 1 - line = colored.cyan("#{calling_fn.short_src}:#{line_num} in #{name or '?'}") - else - line_num = calling_fn.currentline - if calling_fn.short_src == '[C]' - line = colored.green("#{calling_fn.short_src} in #{name or '?'}") - else - line = colored.blue("#{calling_fn.short_src}:#{calling_fn.currentline} in #{name or '?'}") - - if file - err_line = get_line(file, line_num)\sub(1,-2) - offending_statement = colored.bright(colored.red(err_line\match("^[ ]*(.*)$"))) - line ..= "\n "..offending_statement - io.stderr\write(" #{line}\n") - if calling_fn.istailcall - io.stderr\write(" #{colored.dim colored.white " (...tail calls...)"}\n") - - io.stderr\flush! run = -> @@ -1069,19 +945,7 @@ OPTIONS elseif not ok print_err_msg ret - err_hand = (error_message)-> - print_err_msg error_message - os.exit(false, true) - - -- Note: xpcall has a slightly different API in Lua <=5.1 vs. >=5.2, but this works - -- for both APIs - -- TODO: revert back to old error handler - - --require('ProFi')\profile "scratch/profile.txt", (profi)-> - do - ok, ldt = pcall(require,'ldt') - if ok - ldt.guard run - else xpcall(run, err_hand) + run_safely = require "error_handling" + run_safely(run) return NomsuCompiler |
