require 'metalua.compiler'
require 'metalua.clopts'
-require 'serialize'
+require 'metalua.mlc_xcall'
AST_COMPILE_ERROR_NUMBER = -1
RUNTIME_ERROR_NUMBER = -3
-{ extension 'match' }
-function spring_pcall (f, arg, name)
- local pattern =
- [=[lua -l metalua.compiler -l serialize -e ]=]..
- [=["print (serialize (%s ([[%s]], [[%s]])))"]=]
- local cmd = string.format (pattern, f, arg, name)
- --print ("Running the following process: " .. cmd)
- local fd = io.popen (cmd)
- local ast_src = fd:read '*a'
- fd:close()
- --print (data)
- local ast_builder, msg = lua_loadstring(ast_src)
- if not ast_builder then
- error ("can't compile data: "..msg)
- print (ast_src)
- end
- local ast = ast_builder()
- return true, ast
-end
-
local chunks = { }
local runargs = { }
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]
if not name then name = '@'..x end
local f, msg = io.open(x, "rb")
- if not f then error(msg) end
+ if not f then error("While trying to open file '"..x.."': "..msg) end
x = f:read'*a'
f:close()
lua_loadstring = loadstring
local lua_loadstring = loadstring
+lua_loadfile = loadfile
+local lua_loadfile = loadfile
function loadstring(str, name)
if type(str) ~= 'string' then error 'string expected' end
if not f then error(msg) end
return f()
end
-
-
--- /dev/null
+-- 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")'
+
+mlc_xcall = { }
+
+function mlc_xcall.server (luafilename, astfilename)
+
+ -- We don't want these to be loaded when people only do client-side business
+ require 'metalua.compiler'
+ require 'serialize'
+
+ -- compile the content of luafile name in an AST, serialized in astfilename
+ local ast = mlc.luafile_to_ast (luafilename)
+ local out = io.open (astfilename, 'w')
+ out:write (serialize (ast))
+ out:close ()
+end
+
+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 :gsub ([[\]], [[\\]]),
+ tmpfilename :gsub([[\]], [[\\]]))
+
+ --printf("os.execute [[%s]]\n\n", cmd)
+
+ local ret = os.execute (cmd)
+ if ret~=0 then error "xcall failure. FIXME: transmit failure and backtrace" end
+ local ast = (lua_loadfile or loadfile) (tmpfilename) ()
+ os.remove(tmpfilename)
+ return true, ast
+end
+
+function mlc_xcall.client_literal (luasrc)
+ local srcfilename = os.tmpname()
+ local srcfile, msg = io.open (srcfilename, 'w')
+ if not srcfile then print(msg) end
+ srcfile :write (luasrc)
+ srcfile :close ()
+ local status, ast = mlc_xcall.client_file (srcfilename)
+ os.remove(srcfilename)
+ return status, ast
+end
+
+return mlc_xcall
\ No newline at end of file
local luastring = file:read '*a'
file:close()
return mlc.function_of_luastring (luastring, name)
- else
+ else
file:close()
- return spring_load (filename_or_msg)
+ require 'metalua.mlc_xcall'
+ local status, ast = mlc_xcall.client_file (filename_or_msg)
+ return mlc.function_of_ast(ast)
end
end