1 ----------------------------------------------------------------------
4 -- Summary: Main source file for Metalua compiler.
6 ----------------------------------------------------------------------
8 -- Copyright (c) 2006, Fabien Fleutot <metalua@gmail.com>.
10 -- This software is released under the MIT Licence, see licence.txt
13 ----------------------------------------------------------------------
17 local function trace(e)
18 local name = debug.getinfo(2).name or "?"
20 print((": "):rep(level) .. e .. " " .. name)
22 elseif e=="return" then
24 --print(("."):rep(level) .. e .. " " .. name)
26 --print(("."):rep(level) .. e .. " " .. name)
29 --debug.sethook(trace, "cr")
32 mlc.SHOW_METABUGS = false
37 UNIX_SHARPBANG = [[#!/usr/bin/env lua]]..'\n'
49 Usage: mlc [options] [files]
51 --help, -h: display this help
52 --ast, -a: print the AST resulting from file compilation
53 --output, -o: set the name of the next compiled file
54 --execute, -x: run the function instead of saving it
55 --metabugs, -b: undocumented
56 --verbose, -v: verbose
58 Options -a, -x, -b can be reversed with +a, +x, +b.
60 Options are taken into account only for the files that appear after them,
61 e.g. mlc foo.lua -x bar.lua will compile both files, but only execute bar.luac.]]
63 local function print_if_verbose(msg)
64 if VERBOSE then printf(" [%3is]: %s", os.clock(), msg) end
67 -- Compilation of a file:
68 -- [src_name] is the name of the input file;
69 -- [dst_name] is the optional name of the output file; if nil, an appropriate
70 -- name is built from [src_name]
71 -- What to do with the file is decided by the global variables.
73 local function compile_file (src_name, dst_name)
74 printf("Compiling %s...", src_name)
76 print_if_verbose "Build AST"
77 local ast = mlc.ast_of_luafile (src_name)
78 if not ast then error "Can't open or parse file" end
79 if PRINT_AST then table.print(ast, PRINT_LINE_MAX, "nohash") end
82 if EXECUTE and dst_name then
84 dst_name = src_name .. (src_name:match ".*%.lua" and "c" or ".luac")
85 print_if_verbose "Build binary dump"
86 local bin = mlc.bin_of_ast (ast, src_name)
87 if not ast then error "Invalid parse tree" end
88 print_if_verbose "Write dump in file"
89 mlc.luacfile_of_bin (bin, dst_name)
90 printf("...Wrote %s; execute it:", dst_name)
91 print_if_verbose "Build function from dump"
92 local f = mlc.function_of_bin (bin)
95 -- Execute, don't save
98 print_if_verbose "Build function"
99 local f = mlc.function_of_ast(ast)
100 if not f then error "Invalid parse tree" end
101 printf("...Execute it:", dst_name)
103 -- Save, don't execute
105 dst_name = dst_name or
106 src_name .. (src_name:match ".*%.lua" and "c" or ".luac")
107 print_if_verbose "Build dump and write to file"
108 mlc.luacfile_of_ast(ast, dst_name)
109 printf("...Wrote %s.", dst_name)
113 -- argument parsing loop
120 if x == "-" or x == "+" then
121 local bool = (x=="-")
122 if bool and a[1]=="-" then
123 -- double-dash: read long option
124 a = LONG_NAMES [a:sub(2)]
126 printf("Unknown option %s\n\n%s", arg[i], USAGE)
131 local opt = a:sub (j, j)
132 if opt == "h" then print (USAGE); return 0
133 elseif opt == "a" then PRINT_AST = bool
134 elseif opt == "o" then dst_name = arg[i]; i=i+1
135 elseif opt == "b" then mlc.SHOW_METABUGS = bool
136 elseif opt == "x" then EXECUTE = bool
137 elseif opt == "v" then VERBOSE = bool
138 elseif opt == "s" then
139 if bool then UNIX_SHARPBANG = arg[i]; i=i+1
140 else UNIX_SHARPBANG = nil end
141 else error ("Unknown option -"..opt) end
143 else compile_file (a, dst_name) end