-
Notifications
You must be signed in to change notification settings - Fork 13
/
titanc
executable file
·83 lines (70 loc) · 2.63 KB
/
titanc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env lua
local argparse = require 'argparse'
local checker = require 'titan-compiler.checker'
local parser = require 'titan-compiler.parser'
local driver = require 'titan-compiler.driver'
local p = argparse('titan', 'Titan compiler')
p:argument('module', 'Names of the modules to compile.'):args("+")
p:flag('--print-ast', 'Print the AST.')
p:flag('-v --verbose', 'Be verbose about compiler invocations.')
p:option('-u --lua', 'Path to Lua source tree (to find Lua headers, defaults to "lua-5.3.5/src").')
p:option('-t --tree', 'Root of the source tree, used for looking for source modules (defaults to ".").')
p:option('-l --link', 'Comma-separated list of additional libraries to link into module.')
local args = p:parse()
-- Work like assert, but don't print the stack trace
local function exit(msg)
io.stderr:write(msg, "\n")
os.exit(1)
end
driver.TITAN_SOURCE_PATH = args.tree or driver.TITAN_SOURCE_PATH
driver.LUA_SOURCE_PATH = args.lua or driver.LUA_SOURCE_PATH
local errors = {}
local main_module = nil
local modules = {}
for _, modname in ipairs(args.module) do
local static_deps = {}
local ok, errs = checker.checkimport(modname, driver.defaultloader(static_deps))
modules[modname] = static_deps
if not ok then
table.insert(errors, errs)
else
if #errs > 0 then table.insert(errors, table.concat(errs, "\n")) end
local ast = driver.imported[modname].ast
if ast and checker.has_main(ast) then
if main_module then
table.insert(errors, modname .. ": multiple main functions found (already declared in " .. main_module ..")")
else
main_module = modname
end
end
if args.print_ast and ast then
print(parser.pretty_print_ast(ast))
end
end
end
if #errors > 0 then exit(table.concat(errors, "\n")) end
local libnames = {}
for name, mod in pairs(driver.imported) do
local ok, err, libname = driver.compile_module(name, mod, modules[name], args.verbose)
if not ok then
table.insert(errors, err)
else
libnames[name] = libname
end
end
if main_module then
local ofiles = {}
for _, ofile in pairs(libnames) do
table.insert(ofiles, ofile)
end
driver.compile_program(main_module, ofiles, args.link, args.verbose)
else
for modname, depset in pairs(modules) do
local ofiles = {}
for modname, _ in pairs(depset) do
table.insert(ofiles, libnames[modname])
end
local ok, err = driver.compile_library(modname, ofiles, args.link, args.verbose)
end
end
if #errors > 0 then exit(table.concat(errors, "\n")) end