--- /dev/null
+-- This utility bootstraps the metalua compiler:
+-- * The compiler itself is written partly in lua, partly in metalua.
+-- * This program uses the lua parts of the compiler to compile the metalua parts.
+--
+-- Usage: bootstrap output=<resulting file> inputdir=<source directory> <src_1> ... <src_n>
+--
+
+
+cfg = { inputs = { } }
+for _, a in ipairs(arg) do
+ local var, val = a :match "^(.-)=(.*)"
+ if var then cfg[var] = val else table.insert (cfg.inputs, a) end
+end
+
+-- metalua.mlc doesn't exit yet; this preload manager loads a mockup which is just
+-- sufficient to compile the real mlc.mlua
+package.preload['metalua.mlc'] = function()
+
+ print "Loading fake metalua.mlc module for compiler bootstrapping"
+
+ mlc = { }
+ mlc.metabugs = false
+
+ function mlc.function_of_ast (ast)
+ local proto = bytecode.metalua_compile (ast)
+ local dump = bytecode.dump_string (proto)
+ local func = string.undump(dump)
+ return func
+ end
+
+ function mlc.ast_of_luastring (src)
+ local lx = mlp.lexer:newstream (src)
+ local ast = mlp.chunk (lx)
+ return ast
+ end
+
+ function mlc.function_of_luastring (src)
+ local ast = mlc.ast_of_luastring (src)
+ local func = mlc.function_of_ast(ast)
+ return func
+ end
+
+ function mlc.function_of_luafile (name)
+ local f = io.open(name, 'r')
+ local src = f:read '*a'
+ f:close()
+ return mlc.function_of_luastring (src, "@"..name)
+ end
+
+ -- don't let require() fork a separate process for *.mlua compilations.
+ package.metalua_nopopen = true
+end
+
+require 'verbose_require'
+require 'metalua.base'
+require 'metalua.bytecode'
+require 'metalua.mlp'
+require 'metalua.package2'
+
+local function compile_file (src_filename)
+ print("Compiling "..src_filename.."... ")
+ local src_file = io.open (src_filename, 'r')
+ local src = src_file:read '*a'; src_file:close()
+ local ast = mlc.ast_of_luastring (src)
+ local proto = bytecode.metalua_compile (ast, '@'..src_filename)
+ local dump = bytecode.dump_string (proto)
+ local dst_filename = cfg.output or error "no output file name specified"
+ local dst_file = io.open (dst_filename, 'wb')
+ dst_file:write(dump)
+ dst_file:close()
+ print("...Wrote "..dst_filename)
+end
+
+if cfg.inputdir then
+ local sep = package.config:sub(1,1)
+ if not cfg.inputdir :match (sep..'$') then cfg.inputdir = cfg.inputdir..sep end
+else
+ cfg.inputdir=""
+end
+
+for _, x in ipairs (cfg.inputs) do compile_file (cfg.inputdir..x) end
+
--- /dev/null
+-- Compile all files called *.mluam in a directory and its sub-directories,
+-- into their *.luac counterpart.
+--
+-- This script is windows-only, Unices have half-decent shell script languages
+-- which let you do the same with a find and an xargs.
+
+cfg = { }
+for _, a in ipairs(arg) do
+ local var, val = a :match "^(.-)=(.*)"
+ if var then cfg[var] = val end
+end
+
+if not cfg.command or not cfg.directory then
+ error ("Usage: "..arg[0].." command=<metalua command> directory=<library root>")
+end
+
+local f = io.popen ("dir /S /b " .. cfg.directory)
+for src in f:lines() do
+ local base = src:match "^(.+)%.mlua$"
+ if base then
+ local cmd = cfg.command.." "..src.." -o "..base..".luac"
+ print (cmd)
+ os.execute (cmd)
+ end
+end
+
+
BUILD_LIB=${BUILD}/lib
# Where to place the final results
-INSTALL_BIN=/usr/local/bin
-INSTALL_LIB=/usr/local/lib/lua/5.1
+# INSTALL_BIN=/usr/local/bin
+# INSTALL_LIB=/usr/local/lib/lua/5.1
+INSTALL_BIN=~/local/bin
+INSTALL_LIB=~/local/lib/lua
# Where to find Lua executables.
# On many Debian-based systems, those can be installed with "sudo apt-get install lua5.1"
cat > ${INSTALL_BIN}/metalua <<EOF
#!/bin/sh
-export LUA_PATH='?.luac;?.lua;${INSTALL_LIB}/?.luac;${INSTALL_LIB}/?.lua'
-export LUA_MPATH='?.mlua;${INSTALL_LIB}/?.mlua'
-${LUA} ${INSTALL_LIB}/metalua.luac \$*
+METALUA_LIB=${INSTALL_LIB}
+export LUA_PATH="?.luac;?.lua;\\\${METALUA_LIB}/?.luac;\\\${METALUA_LIB}/?.lua"
+export LUA_MPATH="?.mlua;\\\${METALUA_LIB}/?.mlua"
+${LUA} \\\${METALUA_LIB}/metalua.luac \\\$*
EOF
chmod a+x ${INSTALL_BIN}/metalua