]> git.lizzy.rs Git - metalua.git/blob - src/compiler/frontend.lua
27b0bf83edf84adaf0f25508d7ba3c231e361ea4
[metalua.git] / src / compiler / frontend.lua
1 ----------------------------------------------------------------------
2 -- Metalua:  $Id$
3 --
4 -- Summary: Main source file for Metalua compiler.
5 --
6 ----------------------------------------------------------------------
7 --
8 -- Copyright (c) 2006, Fabien Fleutot <metalua@gmail.com>.
9 --
10 -- This software is released under the MIT Licence, see licence.txt
11 -- for details.
12 --
13 ----------------------------------------------------------------------
14
15 do
16    local level = 0
17    local function trace(e)
18       local name = debug.getinfo(2).name or "?"
19       if e=="call" then 
20          print((": "):rep(level) .. e .. " " .. name)
21          level=level+1
22       elseif e=="return" then 
23          level=level-1 
24          --print(("."):rep(level) .. e .. " " .. name)
25       else
26          --print(("."):rep(level) .. e .. " " .. name)
27       end
28    end
29    --debug.sethook(trace, "cr")
30 end
31
32 mlc.SHOW_METABUGS = false
33 PRINT_AST         = false
34 EXECUTE           = false
35 VERBOSE           = false
36 PRINT_LINE_MAX    = 80
37 UNIX_SHARPBANG    = [[#!/usr/bin/env lua]]..'\n'
38 LONG_NAMES   = { 
39    help      = "-h" ; 
40    ast       = "-a" ; 
41    output    = "-o" ;
42    metabugs  = "-b" ;
43    execute   = "-x" ;
44    sharpbang = "-s" ;
45    verbose   = "-v" }
46
47 USAGE = [[
48 Metalua compiler.
49 Usage: mlc [options] [files]
50 Options:
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
57
58 Options -a, -x, -b can be reversed with +a, +x, +b.
59
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.]]
62
63 local function print_if_verbose(msg)
64    if VERBOSE then printf("  [%3is]: %s", os.clock(), msg) end
65 end
66
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.
72
73 local function compile_file (src_name, dst_name)
74    printf("Compiling %s...", src_name)
75
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
80
81    -- Execute and save:
82    if EXECUTE and dst_name then
83       EXECUTE = false
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)
93       f()
94
95    -- Execute, don't save
96    elseif EXECUTE then
97       EXECUTE = false
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)
102       f()
103    -- Save, don't execute
104    else
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)
110    end
111 end
112
113 -- argument parsing loop
114 local i = 1
115 while i <= #arg do
116    local dst_name
117    local a = arg[i]
118    i=i+1
119    local x = a:sub(1,1)
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)]
125          if not a then 
126             printf("Unknown option %s\n\n%s", arg[i], USAGE)
127             return -1
128          end
129       end
130       for j = 2, #a do
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
142       end
143    else compile_file (a, dst_name) end
144 end
145
146