#!/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