]> git.lizzy.rs Git - metalua.git/blob - src/lib/metalua/mlc_xcall.lua
mlc_xcall now properly reports parsing errors
[metalua.git] / src / lib / metalua / mlc_xcall.lua
1 -- lua -l mlc_xcall -e 'luafile_to_astfile ("/tmp/tmp12345.lua", "/tmp/tmp54321.ast")'
2 -- lua -l mlc_xcall -e 'lua_to_astfile ("/tmp/tmp54321.ast")'
3
4 mlc_xcall = { }
5
6
7 -- This is the back-end function, called in a separate lua process
8 -- by `mlc_xcall.client_*()' through `os.execute()'.
9 --  * inputs:
10 --     * the name of a lua source file to compile in a separate process
11 --     * the name of a writable file where the resulting ast is dumped
12 --       with `serialize()'.
13 --  * results:
14 --     * an exit status of 0 or -1, depending on whethet compilation
15 --       succeeded;
16 --     * the ast file filled will either the serialized ast, or the
17 --       error message.
18 function mlc_xcall.server (luafilename, astfilename)
19
20    -- We don't want these to be loaded when people only do client-side business
21    require 'metalua.compiler'
22    require 'serialize'
23
24    -- compile the content of luafile name in an AST, serialized in astfilename
25    local status, ast = pcall (mlc.luafile_to_ast, luafilename)
26    local out = io.open (astfilename, 'w')
27    if status then -- success
28       out:write (serialize (ast))
29       out:close ()
30       os.exit (0)
31    else -- failure, `ast' is actually the error message
32       out:write (ast)
33       out:close ()
34       os.exit (-1)
35    end      
36 end
37
38 -- Compile the file whose name is passed as argument, in a separate process,
39 -- communicating through a temporary file.
40 -- returns:
41 --  * true or false, indicating whether the compilation succeeded
42 --  * the ast, or the error message.
43 function mlc_xcall.client_file (luafile)
44
45    -- printf("\n\nmlc_xcall.client_file(%q)\n\n", luafile)
46
47    local tmpfilename = os.tmpname()
48    local cmd = string.format (
49       [=[lua -l metalua.mlc_xcall -e "mlc_xcall.server([[%s]], [[%s]])"]=], 
50       luafile, tmpfilename)
51
52    -- printf("os.execute [[%s]]\n\n", cmd)
53
54    local status = (0 == os.execute (cmd))
55    local result -- ast or error msg
56    if status then 
57       result = (lua_loadfile or loadfile) (tmpfilename) ()
58    else
59       local f = io.open (tmpfilename)
60       result = f :read '*a'
61       f :close()
62    end
63    os.remove(tmpfilename)
64    return status, result
65 end
66
67 -- Compile a source string into an ast, by dumping it in a tmp
68 -- file then calling `mlc_xcall.client_file()'.
69 -- returns: the same as `mlc_xcall.client_file()'.
70 function mlc_xcall.client_literal (luasrc)
71    local srcfilename = os.tmpname()
72    local srcfile, msg = io.open (srcfilename, 'w')
73    if not srcfile then print(msg) end
74    srcfile :write (luasrc)
75    srcfile :close ()
76    local status, ast = mlc_xcall.client_file (srcfilename)
77    os.remove(srcfilename)
78    return status, ast
79 end
80
81 return mlc_xcall