mirror of
https://github.com/Reuh/candran.git
synced 2025-10-27 09:59:29 +00:00
138 lines
3.2 KiB
Lua
138 lines
3.2 KiB
Lua
#!/usr/bin/env lua
|
|
|
|
local candran = require("candran")
|
|
local parse = require("candran.can-parser.parser").parse
|
|
local pp = require("candran.can-parser.pp")
|
|
local util = require("candran.util")
|
|
local argparse = require("argparse")
|
|
|
|
-- Parse args --
|
|
|
|
local parser = argparse()
|
|
:name "canc"
|
|
:description("Candran "..candran.VERSION.." compiler by Reuh.")
|
|
:epilog "For more info, see https://github.com/Reuh/candran"
|
|
|
|
parser:argument("filename", "Candran files to compile. Use - to read from standard input; the output file will then be named stdin.lua by default.")
|
|
:args "+"
|
|
|
|
parser:group("Output options",
|
|
parser:option("-d --destination")
|
|
:description "Where compiled files should be written"
|
|
:argname "directory",
|
|
|
|
parser:option("-o --output")
|
|
:description "Output filename. (default: same name as the input file with a .lua extension)"
|
|
:argname "filename",
|
|
|
|
parser:flag("-p --print")
|
|
:description "Write to the standard output instead of creating files",
|
|
|
|
parser:flag("--preprocess")
|
|
:description "Only run the preprocessor",
|
|
|
|
parser:flag("--compile")
|
|
:description "Only run the compiler",
|
|
|
|
parser:flag("--parse")
|
|
:description "Only parse the file and prints syntax errors to stdout",
|
|
|
|
parser:flag("--ast")
|
|
:description"(for debugging purposes) Only parse the files and dump the AST to stdout"
|
|
)
|
|
|
|
util.cli.addCandranOptions(parser)
|
|
|
|
local args = parser:parse()
|
|
|
|
-- Compile --
|
|
|
|
for _, file in ipairs(args.filename) do
|
|
-- Read
|
|
local dest, input
|
|
if file == "-" then
|
|
dest = args.output or "stdin.lua"
|
|
|
|
input = io.read("*a")
|
|
|
|
args.chunkname = "stdin"
|
|
else
|
|
dest = args.output or (file:gsub("%.can$", "")..".lua")
|
|
|
|
local inputFile, err = io.open(file, "r")
|
|
if not inputFile then
|
|
io.stderr:write("canc: cannot open "..file..": "..err.."\n")
|
|
os.exit(1)
|
|
end
|
|
input = inputFile:read("*a")
|
|
inputFile:close()
|
|
|
|
args.chunkname = file
|
|
end
|
|
|
|
-- Parse-only situations
|
|
if args.parse or args.ast then
|
|
local ast, err = parse(input, args.chunkname)
|
|
if not ast then
|
|
io.stderr:write("canc: "..err.."\n")
|
|
os.exit(1)
|
|
end
|
|
if args.ast then
|
|
pp.dump(ast)
|
|
end
|
|
return
|
|
end
|
|
|
|
-- Compile and output
|
|
local options = util.cli.makeCandranOptions(args)
|
|
|
|
if args.destination then
|
|
dest = args.destination .. "/" .. dest
|
|
end
|
|
|
|
if not args.print then
|
|
print("Compiling "..args.chunkname.." in "..dest)
|
|
end
|
|
|
|
local out = input
|
|
if args.preprocess then
|
|
local r, err = candran.preprocess(out, options)
|
|
if not r then
|
|
io.stderr:write("canc: "..err.."\n")
|
|
os.exit(1)
|
|
end
|
|
out = r
|
|
end
|
|
if args.compile then
|
|
local r, err = candran.compile(out, options)
|
|
if not r then
|
|
io.stderr:write("canc: "..err.."\n")
|
|
os.exit(1)
|
|
end
|
|
out = r
|
|
end
|
|
if args.compile == nil and args.preprocess == nil then
|
|
local r, err = candran.make(input, options)
|
|
if not r then
|
|
io.stderr:write("canc: "..err.."\n")
|
|
os.exit(1)
|
|
end
|
|
out = r
|
|
end
|
|
|
|
if args.print then
|
|
print(out)
|
|
else
|
|
local outFile, err = io.open(dest, "w")
|
|
if not outFile then
|
|
os.execute("mkdir -p "..dest:gsub("[^/]+%.lua$", ""))
|
|
outFile, err = io.open(dest, "w")
|
|
if not outFile then
|
|
io.stderr:write("canc: cannot open "..dest..": "..err)
|
|
os.exit(1)
|
|
end
|
|
end
|
|
outFile:write(out)
|
|
outFile:close()
|
|
end
|
|
end
|