aboutsummaryrefslogtreecommitdiff
path: root/nomsu.moon
diff options
context:
space:
mode:
Diffstat (limited to 'nomsu.moon')
-rwxr-xr-xnomsu.moon154
1 files changed, 9 insertions, 145 deletions
diff --git a/nomsu.moon b/nomsu.moon
index 230b4fb..2435920 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -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