]> git.lizzy.rs Git - metalua.git/blob - src/build-utils/bootstrap.lua
fixes suggested by D. M.
[metalua.git] / src / build-utils / bootstrap.lua
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.
4 --
5 -- Usage: bootstrap output=<resulting file> inputdir=<source directory> <src_1> ... <src_n>
6 --
7
8
9 cfg = { inputs = { } }
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
13 end
14
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()
18
19    print "Loading fake metalua.mlc module for compiler bootstrapping"
20
21    mlc = { } 
22    mlc.metabugs = false
23
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) 
28       return func
29    end
30    
31    function mlc.ast_of_luastring (src)
32       local  lx  = mlp.lexer:newstream (src)
33       local  ast = mlp.chunk (lx)
34       return ast
35    end
36    
37    function mlc.function_of_luastring (src)
38       local  ast  = mlc.ast_of_luastring (src)
39       local  func = mlc.function_of_ast(ast)
40       return func
41    end
42
43    function mlc.function_of_luafile (name)
44       local f   = io.open(name, 'r')
45       local src = f:read '*a'
46       f:close()
47       return mlc.function_of_luastring (src, "@"..name)
48    end
49
50    -- don't let require() fork a separate process for *.mlua compilations.
51    package.metalua_nopopen = true
52 end
53
54 require 'verbose_require'
55 require 'metalua.base'
56 require 'metalua.bytecode'
57 require 'metalua.mlp'
58 require 'metalua.package2'
59
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')
69    dst_file:write(dump)
70    dst_file:close()
71    print("...Wrote "..dst_filename)
72 end
73
74 if cfg.inputdir then
75    local sep = package.config:sub(1,1)
76    if not cfg.inputdir :match (sep..'$') then cfg.inputdir = cfg.inputdir..sep end
77 else
78    cfg.inputdir=""
79 end
80
81 for _, x in ipairs (cfg.inputs) do compile_file (cfg.inputdir..x) end
82