aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rwxr-xr-xcompile_lib.sh8
-rw-r--r--nomsu.lua140
-rwxr-xr-xnomsu.moon124
4 files changed, 172 insertions, 102 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..5127086
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+*.nom.lua
+*/*.nom.lua
diff --git a/compile_lib.sh b/compile_lib.sh
new file mode 100755
index 0000000..c38cf87
--- /dev/null
+++ b/compile_lib.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+for file in $(find lib/ -name "*.nom") ; do
+ luafile="$file.lua"
+ if [ ! -e "$luafile" ] || [ "$file" -nt "$luafile" ] ; then
+ echo "Compiling $file into $luafile"
+ ./nomsu.moon -c $file
+ fi
+done
diff --git a/nomsu.lua b/nomsu.lua
index 3b8ad49..6fac8bb 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -745,27 +745,42 @@ do
return lua, nil
end
self:defmacro("lua expr %code", lua_value)
- local _require
- _require = function(self, vars)
- if not self.loaded_files[vars.filename] then
+ local run_file
+ run_file = function(self, vars)
+ if vars.filename:match(".*%.lua") then
+ return dofile(vars.filename)(self, vars)
+ end
+ if vars.filename:match(".*%.nom") then
+ if not self.skip_precompiled then
+ local file = io.open(vars.filename .. ".lua", "r")
+ if file then
+ local contents = file:read('*a')
+ file:close()
+ return load(contents)()(self, vars)
+ end
+ end
local file = io.open(vars.filename)
if not file then
self:error("File does not exist: " .. tostring(vars.filename))
end
- self.loaded_files[vars.filename] = (self:run(file:read('*a'), vars.filename)) or true
+ local contents = file:read('*a')
+ file:close()
+ return self:run(contents, vars.filename)
+ else
+ return self:error("Invalid filetype for " .. tostring(vars.filename))
end
- return self.loaded_files[vars.filename]
end
- self:def("require %filename", _require)
- local run_file
- run_file = function(self, vars)
- local file = io.open(vars.filename)
- if not file then
- self:error("File does not exist: " .. tostring(vars.filename))
+ self:def("run file %filename", run_file)
+ local _require
+ _require = function(self, vars)
+ if not self.loaded_files[vars.filename] then
+ self.loaded_files[vars.filename] = run_file(self, {
+ filename = vars.filename
+ }) or true
end
- return self:run(file:read('*a'), vars.filename)
+ return self.loaded_files[vars.filename]
end
- return self:def("run file %filename", run_file)
+ return self:def("require %filename", _require)
end
}
_base_0.__index = _base_0
@@ -826,51 +841,74 @@ do
end
NomsuCompiler = _class_0
end
-if arg and arg[1] then
- local c = NomsuCompiler()
- local input = io.open(arg[1]):read("*a")
- local _write = c.write
- if arg[2] == "-" then
- c.write = function() end
+if arg then
+ local parser = re.compile([[ args <- {| {:flags: flags? :} ({:input: input :} ";" ("-o;"{:output: output :} ";")?)? |} !.
+ flags <- (({| ({flag} ";")* |}) -> set)
+ flag <- "-c" / "-i" / "-p" / "-f" / "--help" / "-h"
+ input <- "-" / [^;]+
+ output <- "-" / [^;]+
+ ]], {
+ set = utils.set
+ })
+ local args = concat(arg, ";") .. ";"
+ args = parser:match(args) or { }
+ if not args or not args.flags or args.flags["--help"] or args.flags["-h"] then
+ print("Usage: lua nomsu.lua [-c] [-i] [-p] [-f] [--help] [input [-o output]]")
+ os.exit()
end
- local retval, code = c:run(input, arg[1])
- c.write = _write
- if arg[2] then
- local output
- if arg[2] == "-" then
- output = io.output()
+ local c = NomsuCompiler()
+ c.skip_precompiled = args.flags["-f"]
+ if args.input then
+ if args.flags["-c"] and not args.output then
+ args.output = args.input .. ".lua"
+ end
+ local compiled_output = nil
+ if args.flags["-p"] then
+ local _write = c.write
+ c.write = function() end
+ compiled_output = io.output()
+ elseif args.output then
+ compiled_output = io.open(args.output, 'w')
+ end
+ if args.input:match(".*%.lua") then
+ local retval = dofile(args.input)(c, { })
else
- output = io.open(arg[2], 'w')
+ local input
+ if args.input == '-' then
+ input = io.read('*a')
+ else
+ input = io.open(args.input):read("*a")
+ end
+ local retval, code = c:run(input, args.input)
+ if compiled_output then
+ compiled_output:write(code)
+ end
+ end
+ if args.flags["-p"] then
+ c.write = _write
end
- output:write(([[ local NomsuCompiler = require('nomsu');
- local c = NomsuCompiler();
- local run = (function(nomsu, vars)
- %s
- end);
- return run(c, {});
- ]]):format(code))
end
-elseif arg then
- local c = NomsuCompiler()
- c:run('require "lib/core.nom"')
- while true do
- local buff = ""
+ if not args.input or args.flags["-i"] then
+ c:run('require "lib/core.nom"')
while true do
- io.write(">> ")
- local line = io.read("*L")
- if line == "\n" or not line then
+ local buff = ""
+ while true do
+ io.write(">> ")
+ local line = io.read("*L")
+ if line == "\n" or not line then
+ break
+ end
+ buff = buff .. line
+ end
+ if #buff == 0 then
break
end
- buff = buff .. line
- end
- if #buff == 0 then
- break
- end
- local ok, ret = pcall(function()
- return c:run(buff)
- end)
- if ok and ret ~= nil then
- print("= " .. repr(ret))
+ local ok, ret = pcall(function()
+ return c:run(buff)
+ end)
+ if ok and ret ~= nil then
+ print("= " .. repr(ret))
+ end
end
end
end
diff --git a/nomsu.moon b/nomsu.moon
index cfe9aa3..05246db 100755
--- a/nomsu.moon
+++ b/nomsu.moon
@@ -21,7 +21,6 @@ colored = setmetatable({}, {__index:(_,color)-> ((msg)-> colors[color]..msg..col
--pcall = (fn,...)-> true, fn(...)
-- TODO:
--- check robustness/functionality of compiler mode.
-- Maybe get GOTOs working at file scope.
-- use actual variables instead of a vars table
-- consider non-linear codegen, rather than doing thunks for things like comprehensions
@@ -564,66 +563,89 @@ class NomsuCompiler
return lua, nil
@defmacro "lua expr %code", lua_value
- _require = (vars)=>
- if not @loaded_files[vars.filename]
+ run_file = (vars)=>
+ if vars.filename\match(".*%.lua")
+ return dofile(vars.filename)(@, vars)
+ if vars.filename\match(".*%.nom")
+ if not @skip_precompiled -- Look for precompiled version
+ file = io.open(vars.filename..".lua", "r")
+ if file
+ contents = file\read('*a')
+ file\close!
+ return load(contents)!(@, vars)
file = io.open(vars.filename)
if not file
@error "File does not exist: #{vars.filename}"
- @loaded_files[vars.filename] = (@run(file\read('*a'), vars.filename)) or true
+ contents = file\read('*a')
+ file\close!
+ return @run(contents, vars.filename)
+ else
+ @error "Invalid filetype for #{vars.filename}"
+ @def "run file %filename", run_file
+
+ _require = (vars)=>
+ if not @loaded_files[vars.filename]
+ @loaded_files[vars.filename] = run_file(self, {filename:vars.filename}) or true
return @loaded_files[vars.filename]
@def "require %filename", _require
- run_file = (vars)=>
- file = io.open(vars.filename)
- if not file
- @error "File does not exist: #{vars.filename}"
- return @run(file\read('*a'), vars.filename)
- @def "run file %filename", run_file
+if arg
+ parser = re.compile([[
+ args <- {| {:flags: flags? :} ({:input: input :} ";" ("-o;"{:output: output :} ";")?)? |} !.
+ flags <- (({| ({flag} ";")* |}) -> set)
+ flag <- "-c" / "-i" / "-p" / "-f" / "--help" / "-h"
+ input <- "-" / [^;]+
+ output <- "-" / [^;]+
+ ]], {set: utils.set})
+ args = concat(arg, ";")..";"
+ args = parser\match(args) or {}
+ if not args or not args.flags or args.flags["--help"] or args.flags["-h"]
+ print "Usage: lua nomsu.lua [-c] [-i] [-p] [-f] [--help] [input [-o output]]"
+ os.exit!
-if arg and arg[1]
- --ProFi = require 'ProFi'
- --ProFi\start()
- c = NomsuCompiler()
- input = io.open(arg[1])\read("*a")
- -- If run via "./nomsu.moon file.nom -", then silence output and print generated
- -- source code instead.
- _write = c.write
- if arg[2] == "-"
- c.write = ->
- retval, code = c\run(input, arg[1])
- c.write = _write -- put it back
- if arg[2]
- output = if arg[2] == "-"
- io.output()
- else io.open(arg[2], 'w')
- output\write ([[
- local NomsuCompiler = require('nomsu');
- local c = NomsuCompiler();
- local run = (function(nomsu, vars)
- %s
- end);
- return run(c, {});
- ]])\format(code)
- --ProFi\stop()
- --ProFi\writeReport( 'MyProfilingReport.txt' )
-
-elseif arg
- -- REPL:
c = NomsuCompiler()
- c\run('require "lib/core.nom"')
- while true
- buff = ""
+ c.skip_precompiled = args.flags["-f"]
+ if args.input
+ -- Read a file or stdin and output either the printouts or the compiled lua
+ if args.flags["-c"] and not args.output
+ args.output = args.input..".lua"
+ compiled_output = nil
+ if args.flags["-p"]
+ _write = c.write
+ c.write = ->
+ compiled_output = io.output()
+ elseif args.output
+ compiled_output = io.open(args.output, 'w')
+
+ if args.input\match(".*%.lua")
+ retval = dofile(args.input)(c, {})
+ else
+ input = if args.input == '-'
+ io.read('*a')
+ else io.open(args.input)\read("*a")
+ retval, code = c\run(input, args.input)
+ -- Output compile lua code
+ if compiled_output
+ compiled_output\write code
+ if args.flags["-p"]
+ c.write = _write
+
+ if not args.input or args.flags["-i"]
+ -- REPL
+ c\run('require "lib/core.nom"')
while true
- io.write(">> ")
- line = io.read("*L")
- if line == "\n" or not line
+ buff = ""
+ while true
+ io.write(">> ")
+ line = io.read("*L")
+ if line == "\n" or not line
+ break
+ buff ..= line
+ if #buff == 0
break
- buff ..= line
- if #buff == 0
- break
- ok, ret = pcall(-> c\run(buff))
- if ok and ret != nil
- print "= "..repr(ret)
+ ok, ret = pcall(-> c\run(buff))
+ if ok and ret != nil
+ print "= "..repr(ret)
return NomsuCompiler