aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nomsu.lua216
-rwxr-xr-xnomsu.moon170
2 files changed, 223 insertions, 163 deletions
diff --git a/nomsu.lua b/nomsu.lua
index 2c91540..d8efeeb 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -34,6 +34,7 @@ do
local _obj_0 = require("code_obj")
Nomsu, Lua, Source = _obj_0.Nomsu, _obj_0.Lua, _obj_0.Source
end
+local STDIN, STDOUT, STDERR = "/dev/fd/0", "/dev/fd/1", "/dev/fd/2"
FILE_CACHE = setmetatable({ }, {
__index = function(self, filename)
local file = io.open(filename)
@@ -56,7 +57,7 @@ iterate_single = function(item, prev)
end
local all_files
all_files = function(path)
- if path:match("%.nom$") or path:match("%.lua$") then
+ if path:match("%.nom$") or path:match("%.lua$") or path:match("^/dev/fd/[012]$") then
return iterate_single, path
end
path = path:gsub("\\", "\\\\"):gsub("`", ""):gsub('"', '\\"'):gsub("$", "")
@@ -388,7 +389,7 @@ do
if filename:match("%.lua$") then
local file = assert(FILE_CACHE[filename], "Could not find file: " .. tostring(filename))
ret = self:run_lua(Lua(Source(filename), file))
- elseif filename:match("%.nom$") then
+ elseif filename:match("%.nom$") or filename:match("^/dev/fd/[012]$") then
if not self.skip_precompiled then
local lua_filename = filename:gsub("%.nom$", ".lua")
local file = FILE_CACHE[lua_filename]
@@ -1032,89 +1033,13 @@ OPTIONS
end
return info
end
- local run
- run = function()
- if args.flags["-v"] then
- nomsu.debug = true
- end
- if args.input == "-" then
- args.input = "/dev/fd/0"
- end
- if args.output == nil then
- args.output = "/dev/null"
- elseif args.output == "-" then
- args.output = "/dev/fd/1"
- end
- nomsu.skip_precompiled = not args.flags["-O"]
- if args.input then
- local compile_fn = nil
- if args.output == "/dev/fd/1" and not args.print_file then
- args.print_file = "/dev/null"
- elseif not args.print_file or args.print_file == "-" then
- args.print_file = "/dev/fd/1"
- end
- local print_file = io.open(args.print_file, "w")
- nomsu.environment.print = function(...)
- local N = select("#", ...)
- if N > 0 then
- print_file:write(tostring(select(1, ...)))
- for i = 2, N do
- print_file:write('\t', tostring(select(1, ...)))
- end
- end
- print_file:write('\n')
- return print_file:flush()
- end
- local output_file = io.open(args.output, 'w')
- compile_fn = function(code)
- return output_file:write("local IMMEDIATE = true;\n" .. tostring(code))
- end
- if args.input:match("%.lua$") then
- dofile(args.input)(nomsu, { })
- else
- for input_file in all_files(args.input) do
- if args.flags["-s"] then
- nomsu:parse(io.open(input_file):read("*a"))
- elseif args.flags["-f"] then
- local tree = nomsu:parse(io.open(input_file):read("*a"))
- output_file:write(tostring(tree:as_nomsu()))
- else
- nomsu:run_file(input_file, compile_fn)
- end
- end
- end
- end
- if not args.input or args.flags["-i"] then
- nomsu:run('use "core"')
- while true do
- io.write(colored.bright(colored.yellow(">> ")))
- local buff = ""
- while true do
- local line = io.read("*L")
- if line == "\n" or not line then
- break
- end
- line = line:gsub("\t", " ")
- buff = buff .. line
- io.write(colored.dim(colored.yellow(".. ")))
- end
- if #buff == 0 then
- break
- end
- local ret
- ok, ret = pcall(nomsu.run, nomsu, buff)
- if ok and ret ~= nil then
- print("= " .. repr(ret))
- elseif not ok then
- print(colored.bright(colored.red(ret)))
- end
- end
+ local print_err_msg
+ print_err_msg = function(error_message, stack_offset)
+ if stack_offset == nil then
+ stack_offset = 2
end
- end
- local err_hand
- err_hand = function(error_message)
- print(tostring(colored.red("ERROR:")) .. " " .. tostring(colored.bright(colored.yellow(colored.onred((error_message or ""))))))
- print("stack traceback:")
+ io.stderr:write(tostring(colored.red("ERROR:")) .. " " .. tostring(colored.bright(colored.red((error_message or "")))) .. "\n")
+ io.stderr:write("stack traceback:\n")
ok, to_lua = pcall(function()
return require('moonscript.base').to_lua
end)
@@ -1125,7 +1050,7 @@ OPTIONS
end
local nomsu_source = FILE_CACHE["nomsu.moon"]
local _, line_table = to_lua(nomsu_source)
- local level = 2
+ local level = stack_offset
while true do
local _continue_0 = false
repeat
@@ -1182,15 +1107,132 @@ OPTIONS
end
end
local _from = colored.dim(colored.white("|"))
- print(("%32s %s %s"):format(name, _from, line))
+ io.stderr:write(("%32s %s %s\n"):format(name, _from, line))
_continue_0 = true
until true
if not _continue_0 then
break
end
end
+ return io.stderr:flush()
+ end
+ local run
+ run = function()
+ if args.flags["-v"] then
+ nomsu.debug = true
+ end
+ if args.input == "-" then
+ args.input = STDIN
+ end
+ local output_file
+ if args.output == "-" then
+ output_file = io.stdout
+ elseif args.output then
+ output_file = io.open(args.output, 'w')
+ end
+ local print_file
+ if args.print_file == "-" then
+ print_file = io.stdout
+ elseif args.print_file then
+ print_file = io.open(args.print_file, 'w')
+ elseif output_file == io.stdout then
+ print_file = nil
+ else
+ print_file = io.stdout
+ end
+ nomsu.skip_precompiled = not args.flags["-O"]
+ if args.input then
+ local compile_fn = nil
+ if print_file == nil then
+ nomsu.environment.print = function() end
+ elseif print_file ~= io.stdout then
+ nomsu.environment.print = function(...)
+ local N = select("#", ...)
+ if N > 0 then
+ print_file:write(tostring(select(1, ...)))
+ for i = 2, N do
+ print_file:write('\t', tostring(select(1, ...)))
+ end
+ end
+ print_file:write('\n')
+ return print_file:flush()
+ end
+ end
+ if output_file then
+ compile_fn = function(code)
+ output_file:write("local IMMEDIATE = true;\n" .. tostring(code))
+ return output_file:flush()
+ end
+ end
+ if args.flags["-s"] then
+ for input_file in all_files(args.input) do
+ nomsu:parse(io.open(input_file):read("*a"))
+ end
+ if print_file then
+ print_file:write("Success!\n")
+ print_file:flush()
+ end
+ elseif args.flags["-f"] then
+ for input_file in all_files(args.input) do
+ local tree = nomsu:parse(io.open(input_file):read("*a"))
+ local formatted = tostring(tree:as_nomsu())
+ if output_file then
+ output_file:write(formatted, "\n")
+ output_file:flush()
+ end
+ if print_file then
+ print_file:write(formatted, "\n")
+ print_file:flush()
+ end
+ end
+ elseif args.input == STDIN then
+ nomsu:run(io.input():read("*a"), compile_fn)
+ else
+ nomsu:run_file(args.input, compile_fn)
+ end
+ end
+ if not args.input or args.flags["-i"] then
+ nomsu:run('use "core"')
+ while true do
+ io.write(colored.bright(colored.yellow(">> ")))
+ local buff = ""
+ while true do
+ local line = io.read("*L")
+ if line == "\n" or not line then
+ if #buff > 0 then
+ io.write("\027[1A\027[2K")
+ end
+ break
+ end
+ line = line:gsub("\t", " ")
+ buff = buff .. line
+ io.write(colored.dim(colored.yellow(".. ")))
+ end
+ if #buff == 0 then
+ break
+ end
+ local ret
+ ok, ret = pcall(nomsu.run, nomsu, buff)
+ if ok and ret ~= nil then
+ print("= " .. repr(ret))
+ elseif not ok then
+ print_err_msg(ret)
+ end
+ end
+ end
+ end
+ local err_hand
+ err_hand = function(error_message)
+ print_err_msg(error_message)
return os.exit(false, true)
end
- require('ldt').guard(run)
+ do
+ local ldt = require('ldt')
+ if ldt then
+ ldt.guard(run)
+ else
+ xpcall(run, err_hand)
+ end
+ end
end
return NomsuCompiler
diff --git a/nomsu.moon b/nomsu.moon
index c38417a..ed056dd 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -26,6 +26,7 @@ colored = setmetatable({}, {__index:(_,color)-> ((msg)-> colors[color]..tostring
{:insert, :remove, :concat} = table
debug_getinfo = debug.getinfo
{:Nomsu, :Lua, :Source} = require "code_obj"
+STDIN, STDOUT, STDERR = "/dev/fd/0", "/dev/fd/1", "/dev/fd/2"
-- TODO:
-- consider non-linear codegen, rather than doing thunks for things like comprehensions
@@ -52,7 +53,7 @@ FILE_CACHE = setmetatable {}, {
iterate_single = (item, prev) -> if item == prev then nil else item
all_files = (path)->
-- Sanitize path
- if path\match("%.nom$") or path\match("%.lua$")
+ if path\match("%.nom$") or path\match("%.lua$") or path\match("^/dev/fd/[012]$")
return iterate_single, path
-- TODO: improve sanitization
path = path\gsub("\\","\\\\")\gsub("`","")\gsub('"','\\"')\gsub("$","")
@@ -336,7 +337,7 @@ class NomsuCompiler
if filename\match("%.lua$")
file = assert(FILE_CACHE[filename], "Could not find file: #{filename}")
ret = @run_lua(Lua(Source(filename), file))
- elseif filename\match("%.nom$")
+ elseif filename\match("%.nom$") or filename\match("^/dev/fd/[012]$")
if not @skip_precompiled -- Look for precompiled version
lua_filename = filename\gsub("%.nom$", ".lua")
file = FILE_CACHE[lua_filename]
@@ -727,84 +728,17 @@ OPTIONS
]=]
return info
-
- run = ->
- if args.flags["-v"]
- nomsu.debug = true
-
- if args.input == "-" then args.input = "/dev/fd/0" -- stdin
- if args.output == nil then args.output = "/dev/null"
- elseif args.output == "-" then args.output = "/dev/fd/1" -- stdout
-
- nomsu.skip_precompiled = not args.flags["-O"]
- if args.input
- compile_fn = nil
- if args.output == "/dev/fd/1" and not args.print_file
- args.print_file = "/dev/null"
- elseif not args.print_file or args.print_file == "-"
- args.print_file = "/dev/fd/1" -- stdout
-
- print_file = io.open(args.print_file, "w")
- nomsu.environment.print = (...)->
- N = select("#",...)
- if N > 0
- print_file\write(tostring(select(1,...)))
- for i=2,N
- print_file\write('\t',tostring(select(1,...)))
- print_file\write('\n')
- print_file\flush!
-
- output_file = io.open(args.output, 'w')
- compile_fn = (code)->
- output_file\write("local IMMEDIATE = true;\n"..tostring(code))
-
- if args.input\match("%.lua$")
- dofile(args.input)(nomsu, {})
- else
- for input_file in all_files(args.input)
- -- Check syntax:
- if args.flags["-s"]
- nomsu\parse(io.open(input_file)\read("*a"))
- elseif args.flags["-f"]
- tree = nomsu\parse(io.open(input_file)\read("*a"))
- output_file\write(tostring(tree\as_nomsu!))
- else
- nomsu\run_file(input_file, compile_fn)
-
- if not args.input or args.flags["-i"]
- -- REPL
- nomsu\run('use "core"')
- while true
- io.write(colored.bright colored.yellow ">> ")
- buff = ""
- while true
- line = io.read("*L")
- if line == "\n" or not line
- break
- line = line\gsub("\t", " ")
- buff ..= line
- io.write(colored.dim colored.yellow ".. ")
- if #buff == 0
- break
- ok, ret = pcall(nomsu.run, nomsu, buff)
- if ok and ret != nil
- print "= "..repr(ret)
- elseif not ok
- print colored.bright colored.red ret
-
- err_hand = (error_message)->
- -- TODO: write properly to stderr
- print("#{colored.red "ERROR:"} #{colored.bright colored.yellow colored.onred (error_message or "")}")
- print("stack traceback:")
+ print_err_msg = (error_message, stack_offset=2)->
+ 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_table = to_lua(nomsu_source)
- level = 2
+ level = stack_offset
while true
-- TODO: reduce duplicate code
calling_fn = debug_getinfo(level)
@@ -841,8 +775,91 @@ OPTIONS
line = colored.blue("#{calling_fn.short_src}:#{calling_fn.currentline}")
name = colored.bright(colored.blue(name or "???"))
_from = colored.dim colored.white "|"
- print(("%32s %s %s")\format(name, _from, line))
+ io.stderr\write(("%32s %s %s\n")\format(name, _from, line))
+ io.stderr\flush!
+
+ run = ->
+ if args.flags["-v"]
+ nomsu.debug = true
+
+ if args.input == "-" then args.input = STDIN
+
+ output_file = if args.output == "-" then io.stdout
+ elseif args.output then io.open(args.output, 'w')
+
+ print_file = if args.print_file == "-" then io.stdout
+ elseif args.print_file then io.open(args.print_file, 'w')
+ elseif output_file == io.stdout then nil
+ else io.stdout
+
+ nomsu.skip_precompiled = not args.flags["-O"]
+ if args.input
+ compile_fn = nil
+ if print_file == nil
+ nomsu.environment.print = ->
+ elseif print_file != io.stdout
+ nomsu.environment.print = (...)->
+ N = select("#",...)
+ if N > 0
+ print_file\write(tostring(select(1,...)))
+ for i=2,N
+ print_file\write('\t',tostring(select(1,...)))
+ print_file\write('\n')
+ print_file\flush!
+
+ if output_file
+ compile_fn = (code)->
+ output_file\write("local IMMEDIATE = true;\n"..tostring(code))
+ output_file\flush!
+ if args.flags["-s"]
+ -- Check syntax:
+ for input_file in all_files(args.input)
+ nomsu\parse(io.open(input_file)\read("*a"))
+ if print_file
+ print_file\write("Success!\n")
+ print_file\flush!
+ elseif args.flags["-f"]
+ -- Auto-format
+ for input_file in all_files(args.input)
+ tree = nomsu\parse(io.open(input_file)\read("*a"))
+ formatted = tostring(tree\as_nomsu!)
+ if output_file
+ output_file\write(formatted, "\n")
+ output_file\flush!
+ if print_file
+ print_file\write(formatted, "\n")
+ print_file\flush!
+ elseif args.input == STDIN
+ nomsu\run(io.input!\read("*a"), compile_fn)
+ else
+ nomsu\run_file(args.input, compile_fn)
+
+ if not args.input or args.flags["-i"]
+ -- REPL
+ nomsu\run('use "core"')
+ while true
+ io.write(colored.bright colored.yellow ">> ")
+ buff = ""
+ while true
+ line = io.read("*L")
+ if line == "\n" or not line
+ if #buff > 0
+ io.write("\027[1A\027[2K")
+ break -- Run buffer
+ line = line\gsub("\t", " ")
+ buff ..= line
+ io.write(colored.dim colored.yellow ".. ")
+ if #buff == 0
+ break -- Exit
+ ok, ret = pcall(nomsu.run, nomsu, buff)
+ if ok and ret != nil
+ print "= "..repr(ret)
+ 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
@@ -851,8 +868,9 @@ OPTIONS
--ProFi = require 'ProFi'
--ProFi\start()
- require('ldt').guard run
- --xpcall(run, err_hand)
+ if ldt = require('ldt')
+ ldt.guard run
+ else xpcall(run, err_hand)
--ProFi\stop()
--ProFi\writeReport( 'MyProfilingReport.txt' )