1 -- This utility bootstraps the metalua compiler:
2 -- * The compiler itself is written partly in lua, partly in metalua.
3 -- * This program uses the lua parts of the compiler to compile the metalua parts.
5 -- Usage: bootstrap output=<resulting file> inputdir=<source directory> <src_1> ... <src_n>
10 for _, a in ipairs(arg) do
11 local var, val = a :match "^(.-)=(.*)"
12 if var then cfg[var] = val else table.insert (cfg.inputs, a) end
15 -- metalua.mlc doesn't exist yet; this preload manager loads a mockup which is just
16 -- sufficient to compile the real mlc.mlua
17 package.preload['metalua.mlc'] = function()
19 print "Loading fake metalua.mlc module for compiler bootstrapping"
24 function mlc.function_of_ast (ast)
25 local proto = bytecode.metalua_compile (ast)
26 local dump = bytecode.dump_string (proto)
27 local func = string.undump(dump)
31 function mlc.ast_of_luastring (src)
32 local lx = mlp.lexer:newstream (src)
33 local ast = mlp.chunk (lx)
37 function mlc.function_of_luastring (src)
38 local ast = mlc.ast_of_luastring (src)
39 local func = mlc.function_of_ast(ast)
43 function mlc.function_of_luafile (name)
44 local f = io.open(name, 'r')
45 local src = f:read '*a'
47 return mlc.function_of_luastring (src, "@"..name)
50 -- don't let require() fork a separate process for *.mlua compilations.
51 package.metalua_nopopen = true
54 require 'verbose_require'
55 require 'metalua.base'
56 require 'metalua.bytecode'
58 require 'metalua.package2'
60 local function compile_file (src_filename)
61 print("Compiling "..src_filename.."... ")
62 local src_file = io.open (src_filename, 'r')
63 local src = src_file:read '*a'; src_file:close()
64 local ast = mlc.ast_of_luastring (src)
65 local proto = bytecode.metalua_compile (ast, '@'..src_filename)
66 local dump = bytecode.dump_string (proto)
67 local dst_filename = cfg.output or error "no output file name specified"
68 local dst_file = io.open (dst_filename, 'wb')
71 print("...Wrote "..dst_filename)
75 local sep = package.config:sub(1,1)
76 if not cfg.inputdir :match (sep..'$') then cfg.inputdir = cfg.inputdir..sep end
81 for _, x in ipairs (cfg.inputs) do compile_file (cfg.inputdir..x) end