-------------------------------------------------------------------
-- Get ASTs from sources
+ mlc.metabugs = cfg.metabugs
local last_file
for x in values(chunks) do
verb_print("Compiling %s", table.tostring(x))
end
end
+ -- FIXME: canonize/check AST
+
-------------------------------------------------------------------
-- Insert runtime loader
if cfg['no-runtime'] then
table.insert(code, 1, +{require'metalua.runtime'})
end
- -- FIXME: check for failures
- mlc.metabugs = cfg.metabugs
local bytecode = mlc.luacstring_of_ast (code)
code = nil
-------------------------------------------------------------------
-- Insert #!... command
if cfg.sharpbang then
- verb_print ("Adding sharp-bang directive %q", cfg.sharpbang)
- if not cfg.sharpbang:strmatch'^#!' then cfg.sharpbang='#!'..cfg.sharpbang end
- if not cfg.sharpbang:strmatch'\n$' then cfg.sharpbang=cfg.sharpbang..'\n' end
- bytecode = cfg.sharpbang..bytecode
+ local shbang = cfg.sharpbang
+ verb_print ("Adding sharp-bang directive %q", shbang)
+ if not shbang :strmatch'^#!' then shbang = '#!' .. shbang end
+ if not shbang :strmatch'\n$' then shbang = shbang .. '\n' end
+ bytecode = shbang .. bytecode
end
-------------------------------------------------------------------
--- lua -l mlc_xcall -e 'luafile_to_astfile ("/tmp/tmp12345.lua", "/tmp/tmp54321.ast")'
--- lua -l mlc_xcall -e 'lua_to_astfile ("/tmp/tmp54321.ast")'
+--------------------------------------------------------------------------------
+-- Execute an `mlc.ast_of_*()' in a separate lua process.
+-- Communication between processes goes through temporary files,
+-- for the sake of portability.
+--------------------------------------------------------------------------------
mlc_xcall = { }
+--------------------------------------------------------------------------------
+-- Number of lines to remove at the end of a traceback, should it be
+-- dumped due to a compilation error in metabugs mode.
+--------------------------------------------------------------------------------
+local STACK_LINES_TO_CUT = 7
+--------------------------------------------------------------------------------
+-- (Not intended to be called directly by users)
+--
-- This is the back-end function, called in a separate lua process
-- by `mlc_xcall.client_*()' through `os.execute()'.
-- * inputs:
-- * the name of a lua source file to compile in a separate process
-- * the name of a writable file where the resulting ast is dumped
-- with `serialize()'.
+-- * metabugs: if true and an error occurs during compilation,
+-- the compiler's stacktrace is printed, allowing meta-programs
+-- debugging.
-- * results:
-- * an exit status of 0 or -1, depending on whethet compilation
-- succeeded;
-- * the ast file filled will either the serialized ast, or the
-- error message.
-function mlc_xcall.server (luafilename, astfilename)
+--------------------------------------------------------------------------------
+function mlc_xcall.server (luafilename, astfilename, metabugs)
-- We don't want these to be loaded when people only do client-side business
require 'metalua.compiler'
require 'serialize'
+ mlc.metabugs = metabugs
+
-- compile the content of luafile name in an AST, serialized in astfilename
--local status, ast = pcall (mlc.luafile_to_ast, luafilename)
local status, ast
local function compile() return mlc.luafile_to_ast (luafilename) end
- if mlc.metabugs or true then
+ if mlc.metabugs then
print 'mlc_xcall.server/metabugs'
- status, ast = xpcall (compile, debug.traceback)
+ --status, ast = xpcall (compile, debug.traceback)
+ --status, ast = xpcall (compile, debug.traceback)
+ local function tb(msg)
+ local r = debug.traceback(msg)
+
+ -- Cut superfluous end lines
+ local line_re = '\n[^\n]*'
+ local re = "^(.-)" .. (line_re) :rep (STACK_LINES_TO_CUT) .. "$"
+ return r :strmatch (re) or r
+ end
+ --status, ast = xpcall (compile, debug.traceback)
+ status, ast = xpcall (compile, tb)
else status, ast = pcall (compile) end
local out = io.open (astfilename, 'w')
if status then -- success
end
end
+--------------------------------------------------------------------------------
-- Compile the file whose name is passed as argument, in a separate process,
-- communicating through a temporary file.
-- returns:
-- * true or false, indicating whether the compilation succeeded
-- * the ast, or the error message.
+--------------------------------------------------------------------------------
function mlc_xcall.client_file (luafile)
-- printf("\n\nmlc_xcall.client_file(%q)\n\n", luafile)
local tmpfilename = os.tmpname()
local cmd = string.format (
- [=[lua -l metalua.mlc_xcall -e "mlc_xcall.server([[%s]], [[%s]])"]=],
- luafile, tmpfilename)
+ [=[lua -l metalua.mlc_xcall -e "mlc_xcall.server([[%s]], [[%s]], %s)"]=],
+ luafile, tmpfilename, mlc.metabugs and "true" or "false")
-- printf("os.execute [[%s]]\n\n", cmd)
return status, result
end
+--------------------------------------------------------------------------------
-- Compile a source string into an ast, by dumping it in a tmp
-- file then calling `mlc_xcall.client_file()'.
-- returns: the same as `mlc_xcall.client_file()'.
+--------------------------------------------------------------------------------
function mlc_xcall.client_literal (luasrc)
local srcfilename = os.tmpname()
local srcfile, msg = io.open (srcfilename, 'w')