require 'metalua.compiler'
require 'metalua.clopts'
-
-do
- local mfast = os.getenv 'LUA_NOSPRINGS'
- local has_springs = mfast~='yes' and mfast~='true' and pcall(require, 'springs')
- if has_springs then
- function spring_pcall(...)
- local ring = springs.new()
- ring:dostring (INIT_COMPILATION_RING)
- st, ast = ring:pcall(...)
- ring:close()
- return st, ast
- end
- else
- function spring_pcall(f, ...)
- if type(f)=='string' then f = loadstring("return "..f)() end
- return pcall(f, ...)
- end
- end
-end
+require 'metalua.mlc_xcall'
AST_COMPILE_ERROR_NUMBER = -1
RUNTIME_ERROR_NUMBER = -3
local chunks = { }
local runargs = { }
-local acc_chunk = |kind| function (arg)
- table.insert (chunks, { tag=kind, arg })
-end
+local acc_chunk = |kind| |arg| table.insert (chunks, { tag=kind, arg })
parser = clopts {
-- Chunk loading
{ short = 'A', long = 'print-ast-lineinfo', type = 'boolean',
usage = 'print the AST resulting from file compilation, including lineinfo data'
},
+ { short = 'S', long = 'print-src', type = 'boolean',
+ usage = 'print the AST resulting from file compilation, as re-gerenerated sources'
+ },
{ short = 'b', long = 'metabugs', type = 'boolean',
usage = 'show syntax errors as compile-time execution errors'
},
compiler should be prefixed with an option flag, hinting what must be
done with them: take tham as file names to compile, as library names
to load, as parameters passed to the running program... When option
-flags lack, metalua tries to adopt a "Do What I Mean" approach:
+flags are absent, metalua tries to adopt a "Do What I Mean" approach:
- if no code (no library, no literal expression and no file) is
specified, the first flag-less parameter is taken as a file name to
forbids it.
]]}
-
-INIT_COMPILATION_RING = [[require 'metalua.compiler']]
-
local function main (...)
local cfg = parser(...)
local st, ast
match x with
| `Library{ l } -> st, ast = true, `Call{ `Id 'require', `String{ l } }
- | `Literal{ e } -> st, ast = spring_pcall('mlc.ast_of_luastring', e, 'literal')
+ | `Literal{ e } -> st, ast = mlc_xcall.client_literal (e)
| `File{ f } ->
- st, ast = spring_pcall('mlc.ast_of_luafile', f, '@'..f)
- -- Isolate each file in a separate fenv
+ st, ast = mlc_xcall.client_file (f)
+ -- Isolate each file in a separate fenv
if st then
ast = +{ function (...) -{ast} end (...) }
ast.source = '@'..f -- TODO [EVE]
end
end
if not st then
- printf ("Cannot compile %s: %s", table.tostring(x), ast)
+ printf ("Cannot compile %s: %s", table.tostring(x), ast or "no msg")
os.exit (AST_COMPILE_ERROR_NUMBER)
end
ast.origin = x
end
end
+ -------------------------------------------------------------------
+ -- Source printing
+ if cfg['print-src'] then
+ verb_print "Resulting sources:"
+ require 'metalua.ast_to_string'
+ for x in ivalues(code) do
+ printf("--- Source From %s: ---", table.tostring(x.source, 'nohash'))
+ if x.origin and x.origin.tag=='File' then x=x[1][1][2][1] end
+ print (ast_to_string (x))
+ end
+ end
+
-------------------------------------------------------------------
-- Insert runtime loader
if cfg['no-runtime'] then
-- FIXME: check for failures
runargs = table.icat(cfg.params or { }, runargs)
- local st, msg = pcall(f, unpack (runargs))
+ local function print_traceback (errmsg)
+ return errmsg .. '\n' .. debug.traceback ('',2) .. '\n'
+ end
+ local st, msg = xpcall(|| f(unpack (runargs)), print_traceback)
if not st then
io.stderr:write(msg)
os.exit(RUNTIME_ERROR_NUMBER)
verb_print "Starting REPL loop"
require 'metalua.metaloop'
metaloop.run()
--- print ("*":rep(70))
--- print "*** !!! Interactive loop not implemented !!!"
--- print ("*":rep(70))
end
verb_print "Done"