diff --git a/bin/pallenec b/bin/pallenec index 55f2d0fc..0829503e 100755 --- a/bin/pallenec +++ b/bin/pallenec @@ -1,73 +1,3 @@ #!/usr/bin/env lua - -local argparse = require "argparse" - -local driver = require "pallene.driver" -local print_ir = require "pallene.print_ir" -local util = require "pallene.util" -local C = require "pallene.C" - --- --- Command-line options --- - -local p = argparse("pallenec", "Pallene compiler") -p:argument("source_file", "File to compile") - --- What the compiler should output. -p:mutex( - p:flag("--emit-c", "Generate a .c file instead of an executable"), - p:flag("--emit-lua", "Generate a .lua file instead of an executable"), - p:flag("--compile-c", "Compile a .c file generated by --emit-c"), - p:flag("--print-ir", "Show the intermediate representation for a program") -) - --- Optimization levels for the Pallene and C compiler. (-O0 disables optimizations for both) --- NOTE: *For C compiler only* this option may be overridden using the CFLAGS environment variable. -p:option("-O", "Optimization level") - :args(1):convert(tonumber) - :choices({"0", "1", "2", "3"}) - :default(2) - -p:option("-o --output", "Output file path") - - -local args = p:parse() - -local opt_level = args.O - --- For compilation errors that don't happen inside a source file. --- Inspired by gcc, eg. "gcc: fatal error: no input files". -local compiler_name = arg[0] - -local function compile(in_ext, out_ext) - local ok, errs = driver.compile(compiler_name, opt_level, in_ext, out_ext, args.source_file, - args.output) - if not ok then util.abort(table.concat(errs, "\n")) end -end - - -local function compile_up_to(stop_after) - local filename = args.source_file - local opt_level = args.O - - local input, err = driver.load_input(filename) - if err then util.abort(err) end - - local out, errs = driver.compile_internal(filename, input, stop_after, opt_level) - if not out then util.abort(table.concat(errs, "\n")) end - - return out -end - -local function do_print_ir() - local module = compile_up_to("optimize") - io.stdout:write(print_ir(module)) -end - -if args.emit_c then compile("pln", "c") -elseif args.emit_lua then compile("pln", "lua") -elseif args.compile_c then compile("c" , "so") -elseif args.print_ir then do_print_ir() -else --[[default]] compile("pln", "so") -end +local pallenec = require "pallene.pallenec" +pallenec.main() diff --git a/src/pallene/pallenec.lua b/src/pallene/pallenec.lua new file mode 100644 index 00000000..8821dc1b --- /dev/null +++ b/src/pallene/pallenec.lua @@ -0,0 +1,75 @@ +-- Copyright (c) 2022, The Pallene Developers +-- Pallene is licensed under the MIT license. +-- Please refer to the LICENSE and AUTHORS files for details +-- SPDX-License-Identifier: MIT + +-- PALLENEC SCRIPT +-- =============== +-- This is the main entry point for the pallenec compiler + +local argparse = require "argparse" +local driver = require "pallene.driver" +local print_ir = require "pallene.print_ir" +local util = require "pallene.util" + +local pallenec = {} + +-- For compilation errors that don't happen inside a source file. +-- Inspired by gcc, eg. "gcc: fatal error: no input files". +local compiler_name = arg[0] + +-- Command-line options +local opts +do + local p = argparse("pallenec", "Pallene compiler") + p:argument("source_file", "File to compile") + + -- What the compiler should output. + p:mutex( + p:flag("--emit-c", "Generate a .c file instead of an executable"), + p:flag("--emit-lua", "Generate a .lua file instead of an executable"), + p:flag("--compile-c", "Compile a .c file generated by --emit-c"), + p:flag("--print-ir", "Show the intermediate representation for a program") + ) + + p:option("-O", "Optimization level") + :args(1):convert(tonumber) + :choices({"0", "1", "2", "3"}) + :default(2) + + p:option("-o --output", "Output file path") + + opts = p:parse() +end + +local function compile(in_ext, out_ext) + local ok, errs = driver.compile(compiler_name, opts.O, in_ext, out_ext, opts.source_file, + opts.output) + if not ok then util.abort(table.concat(errs, "\n")) end +end + +local function compile_up_to(stop_after) + local input, err = driver.load_input(opts.source_file) + if err then util.abort(err) end + + local out, errs = driver.compile_internal(opts.source_file, input, stop_after, opts.O) + if not out then util.abort(table.concat(errs, "\n")) end + + return out +end + +local function do_print_ir() + local module = compile_up_to("optimize") + io.stdout:write(print_ir(module)) +end + +function pallenec.main() + if opts.emit_c then compile("pln", "c") + elseif opts.emit_lua then compile("pln", "lua") + elseif opts.compile_c then compile("c" , "so") + elseif opts.print_ir then do_print_ir() + else --[[default]] compile("pln", "so") + end +end + +return pallenec