2023-01-08 14:24:10 -05:00
|
|
|
// Copyright (C) 2022-2023 Exaloop Inc. <https://exaloop.io>
|
2022-12-04 16:45:21 -08:00
|
|
|
|
2021-09-27 14:02:44 -04:00
|
|
|
#include <algorithm>
|
2021-11-01 19:10:33 -04:00
|
|
|
#include <cstdio>
|
2021-09-27 14:02:44 -04:00
|
|
|
#include <cstdlib>
|
2022-01-18 21:19:52 -08:00
|
|
|
#include <fstream>
|
2023-01-28 22:59:49 -05:00
|
|
|
#include <functional>
|
2021-11-01 19:10:33 -04:00
|
|
|
#include <iostream>
|
2021-11-16 15:40:00 -05:00
|
|
|
#include <sstream>
|
2021-09-27 14:02:44 -04:00
|
|
|
#include <string>
|
|
|
|
#include <unordered_map>
|
|
|
|
#include <vector>
|
|
|
|
|
2021-10-30 14:16:40 -04:00
|
|
|
#include "codon/compiler/compiler.h"
|
2021-11-02 14:59:10 -04:00
|
|
|
#include "codon/compiler/error.h"
|
2021-11-01 19:10:33 -04:00
|
|
|
#include "codon/compiler/jit.h"
|
2021-10-30 14:16:40 -04:00
|
|
|
#include "codon/util/common.h"
|
2023-03-17 11:28:55 -04:00
|
|
|
#include "codon/util/jupyter.h"
|
2021-10-30 14:16:40 -04:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2023-01-29 16:35:57 -05:00
|
|
|
#include "llvm/Support/FileSystem.h"
|
2021-10-30 14:16:40 -04:00
|
|
|
|
2021-09-27 14:02:44 -04:00
|
|
|
namespace {
|
|
|
|
void versMsg(llvm::raw_ostream &out) {
|
2021-09-30 15:55:17 -04:00
|
|
|
out << CODON_VERSION_MAJOR << "." << CODON_VERSION_MINOR << "." << CODON_VERSION_PATCH
|
|
|
|
<< "\n";
|
2021-09-27 14:02:44 -04:00
|
|
|
}
|
|
|
|
|
2022-06-26 17:27:31 -04:00
|
|
|
bool isMacOS() {
|
|
|
|
#ifdef __APPLE__
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
return false;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2021-09-27 14:02:44 -04:00
|
|
|
const std::vector<std::string> &supportedExtensions() {
|
2022-12-04 16:45:21 -08:00
|
|
|
static const std::vector<std::string> extensions = {".codon", ".py", ".seq"};
|
2021-09-27 14:02:44 -04:00
|
|
|
return extensions;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasExtension(const std::string &filename, const std::string &extension) {
|
|
|
|
return filename.size() >= extension.size() &&
|
|
|
|
filename.compare(filename.size() - extension.size(), extension.size(),
|
|
|
|
extension) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string trimExtension(const std::string &filename, const std::string &extension) {
|
|
|
|
if (hasExtension(filename, extension)) {
|
|
|
|
return filename.substr(0, filename.size() - extension.size());
|
|
|
|
} else {
|
|
|
|
return filename;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string makeOutputFilename(const std::string &filename,
|
|
|
|
const std::string &extension) {
|
|
|
|
for (const auto &ext : supportedExtensions()) {
|
|
|
|
if (hasExtension(filename, ext))
|
|
|
|
return trimExtension(filename, ext) + extension;
|
|
|
|
}
|
|
|
|
return filename + extension;
|
|
|
|
}
|
|
|
|
|
2021-11-02 14:59:10 -04:00
|
|
|
void display(const codon::error::ParserErrorInfo &e) {
|
2022-12-04 16:45:21 -08:00
|
|
|
using codon::MessageGroupPos;
|
|
|
|
for (auto &group : e) {
|
|
|
|
for (auto &msg : group) {
|
|
|
|
MessageGroupPos pos = MessageGroupPos::NONE;
|
|
|
|
if (&msg == &group.front()) {
|
|
|
|
pos = MessageGroupPos::HEAD;
|
|
|
|
} else if (&msg == &group.back()) {
|
|
|
|
pos = MessageGroupPos::LAST;
|
|
|
|
} else {
|
|
|
|
pos = MessageGroupPos::MID;
|
|
|
|
}
|
|
|
|
codon::compilationError(msg.getMessage(), msg.getFile(), msg.getLine(),
|
|
|
|
msg.getColumn(), msg.getLength(), msg.getErrorCode(),
|
|
|
|
/*terminate=*/false, pos);
|
|
|
|
}
|
2021-11-02 14:59:10 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-20 11:22:32 -05:00
|
|
|
void initLogFlags(const llvm::cl::opt<std::string> &log) {
|
|
|
|
codon::getLogger().parse(log);
|
|
|
|
if (auto *d = getenv("CODON_DEBUG"))
|
|
|
|
codon::getLogger().parse(std::string(d));
|
|
|
|
}
|
|
|
|
|
2023-01-28 22:59:49 -05:00
|
|
|
enum BuildKind { LLVM, Bitcode, Object, Executable, Library, PyExtension, Detect };
|
2021-09-27 14:02:44 -04:00
|
|
|
enum OptMode { Debug, Release };
|
2022-09-15 15:40:00 -04:00
|
|
|
enum Numerics { C, Python };
|
2021-09-27 14:02:44 -04:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
int docMode(const std::vector<const char *> &args, const std::string &argv0) {
|
|
|
|
llvm::cl::ParseCommandLineOptions(args.size(), args.data());
|
2021-11-01 19:10:33 -04:00
|
|
|
std::vector<std::string> files;
|
|
|
|
for (std::string line; std::getline(std::cin, line);)
|
|
|
|
files.push_back(line);
|
|
|
|
|
|
|
|
auto compiler = std::make_unique<codon::Compiler>(args[0]);
|
2021-11-02 14:59:10 -04:00
|
|
|
bool failed = false;
|
2021-11-03 10:34:33 -04:00
|
|
|
auto result = compiler->docgen(files);
|
|
|
|
llvm::handleAllErrors(result.takeError(),
|
2021-11-02 14:59:10 -04:00
|
|
|
[&failed](const codon::error::ParserErrorInfo &e) {
|
|
|
|
display(e);
|
|
|
|
failed = true;
|
|
|
|
});
|
|
|
|
if (failed)
|
2021-11-01 19:10:33 -04:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
2021-11-03 10:34:33 -04:00
|
|
|
fmt::print("{}\n", *result);
|
2021-09-27 14:02:44 -04:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2023-01-28 22:59:49 -05:00
|
|
|
std::unique_ptr<codon::Compiler> processSource(
|
|
|
|
const std::vector<const char *> &args, bool standalone,
|
|
|
|
std::function<bool()> pyExtension = [] { return false; }) {
|
2021-09-27 14:02:44 -04:00
|
|
|
llvm::cl::opt<std::string> input(llvm::cl::Positional, llvm::cl::desc("<input file>"),
|
|
|
|
llvm::cl::init("-"));
|
2022-02-17 19:03:07 -08:00
|
|
|
auto regs = llvm::cl::getRegisteredOptions();
|
2021-09-27 14:02:44 -04:00
|
|
|
llvm::cl::opt<OptMode> optMode(
|
|
|
|
llvm::cl::desc("optimization mode"),
|
|
|
|
llvm::cl::values(
|
2022-02-17 19:03:07 -08:00
|
|
|
clEnumValN(Debug, regs.find("debug") != regs.end() ? "default" : "debug",
|
2021-09-27 14:02:44 -04:00
|
|
|
"Turn off compiler optimizations and show backtraces"),
|
|
|
|
clEnumValN(Release, "release",
|
|
|
|
"Turn on compiler optimizations and disable debug info")),
|
|
|
|
llvm::cl::init(Debug));
|
|
|
|
llvm::cl::list<std::string> defines(
|
|
|
|
"D", llvm::cl::Prefix,
|
|
|
|
llvm::cl::desc("Add static variable definitions. The syntax is <name>=<value>"));
|
|
|
|
llvm::cl::list<std::string> disabledOpts(
|
|
|
|
"disable-opt", llvm::cl::desc("Disable the specified IR optimization"));
|
2021-10-17 10:30:52 -04:00
|
|
|
llvm::cl::list<std::string> plugins("plugin",
|
|
|
|
llvm::cl::desc("Load specified plugin"));
|
2021-10-30 19:02:12 -04:00
|
|
|
llvm::cl::opt<std::string> log("log", llvm::cl::desc("Enable given log streams"));
|
2022-09-15 15:40:00 -04:00
|
|
|
llvm::cl::opt<Numerics> numerics(
|
|
|
|
"numerics", llvm::cl::desc("numerical semantics"),
|
|
|
|
llvm::cl::values(
|
|
|
|
clEnumValN(C, "c", "C semantics: best performance but deviates from Python"),
|
|
|
|
clEnumValN(Python, "py",
|
|
|
|
"Python semantics: mirrors Python but might disable optimizations "
|
|
|
|
"like vectorization")),
|
|
|
|
llvm::cl::init(C));
|
2021-09-27 14:02:44 -04:00
|
|
|
|
|
|
|
llvm::cl::ParseCommandLineOptions(args.size(), args.data());
|
2022-01-20 11:22:32 -05:00
|
|
|
initLogFlags(log);
|
2021-09-27 14:02:44 -04:00
|
|
|
|
|
|
|
std::unordered_map<std::string, std::string> defmap;
|
|
|
|
for (const auto &define : defines) {
|
|
|
|
auto eq = define.find('=');
|
|
|
|
if (eq == std::string::npos || !eq) {
|
2021-10-04 12:10:59 -05:00
|
|
|
codon::compilationWarning("ignoring malformed definition: " + define);
|
2021-09-27 14:02:44 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto name = define.substr(0, eq);
|
|
|
|
auto value = define.substr(eq + 1);
|
|
|
|
|
|
|
|
if (defmap.find(name) != defmap.end()) {
|
2021-10-04 12:10:59 -05:00
|
|
|
codon::compilationWarning("ignoring duplicate definition: " + define);
|
2021-09-27 14:02:44 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
defmap.emplace(name, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
const bool isDebug = (optMode == OptMode::Debug);
|
|
|
|
std::vector<std::string> disabledOptsVec(disabledOpts);
|
2023-01-28 22:59:49 -05:00
|
|
|
auto compiler = std::make_unique<codon::Compiler>(
|
|
|
|
args[0], isDebug, disabledOptsVec,
|
|
|
|
/*isTest=*/false, (numerics == Numerics::Python), pyExtension());
|
2021-11-11 11:50:00 -05:00
|
|
|
compiler->getLLVMVisitor()->setStandalone(standalone);
|
2021-09-27 14:02:44 -04:00
|
|
|
|
2021-10-30 14:16:40 -04:00
|
|
|
// load plugins
|
2021-10-17 10:30:52 -04:00
|
|
|
for (const auto &plugin : plugins) {
|
2021-11-03 15:04:01 -04:00
|
|
|
bool failed = false;
|
|
|
|
llvm::handleAllErrors(
|
|
|
|
compiler->load(plugin), [&failed](const codon::error::PluginErrorInfo &e) {
|
2022-12-04 16:45:21 -08:00
|
|
|
codon::compilationError(e.getMessage(), /*file=*/"",
|
|
|
|
/*line=*/0, /*col=*/0, /*len*/ 0, /*errorCode*/ -1,
|
2021-11-03 15:04:01 -04:00
|
|
|
/*terminate=*/false);
|
|
|
|
failed = true;
|
|
|
|
});
|
|
|
|
if (failed)
|
2021-10-30 14:16:40 -04:00
|
|
|
return {};
|
2021-09-27 14:02:44 -04:00
|
|
|
}
|
2021-10-16 13:16:57 -04:00
|
|
|
|
2021-11-02 14:59:10 -04:00
|
|
|
bool failed = false;
|
2022-07-26 13:06:00 -07:00
|
|
|
int testFlags = 0;
|
|
|
|
if (auto *tf = getenv("CODON_TEST_FLAGS"))
|
|
|
|
testFlags = std::atoi(tf);
|
|
|
|
llvm::handleAllErrors(compiler->parseFile(input, /*testFlags=*/testFlags, defmap),
|
2021-11-02 14:59:10 -04:00
|
|
|
[&failed](const codon::error::ParserErrorInfo &e) {
|
|
|
|
display(e);
|
|
|
|
failed = true;
|
|
|
|
});
|
|
|
|
if (failed)
|
2021-10-30 14:16:40 -04:00
|
|
|
return {};
|
2021-09-27 14:02:44 -04:00
|
|
|
|
2021-10-30 19:02:12 -04:00
|
|
|
{
|
|
|
|
TIME("compile");
|
2021-11-03 15:04:01 -04:00
|
|
|
llvm::cantFail(compiler->compile());
|
2021-10-30 19:02:12 -04:00
|
|
|
}
|
2021-10-30 14:16:40 -04:00
|
|
|
return compiler;
|
2021-09-27 14:02:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int runMode(const std::vector<const char *> &args) {
|
|
|
|
llvm::cl::list<std::string> libs(
|
|
|
|
"l", llvm::cl::desc("Load and link the specified library"));
|
2022-06-26 17:27:31 -04:00
|
|
|
llvm::cl::list<std::string> progArgs(llvm::cl::ConsumeAfter,
|
|
|
|
llvm::cl::desc("<program arguments>..."));
|
2021-11-11 11:50:00 -05:00
|
|
|
auto compiler = processSource(args, /*standalone=*/false);
|
2021-10-30 14:16:40 -04:00
|
|
|
if (!compiler)
|
2021-09-27 14:02:44 -04:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
std::vector<std::string> libsVec(libs);
|
2022-06-26 17:27:31 -04:00
|
|
|
std::vector<std::string> argsVec(progArgs);
|
2021-10-30 14:16:40 -04:00
|
|
|
argsVec.insert(argsVec.begin(), compiler->getInput());
|
|
|
|
compiler->getLLVMVisitor()->run(argsVec, libsVec);
|
2021-09-27 14:02:44 -04:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2021-11-02 14:59:10 -04:00
|
|
|
namespace {
|
2021-11-06 11:02:19 -04:00
|
|
|
std::string jitExec(codon::jit::JIT *jit, const std::string &code) {
|
2022-03-31 01:22:26 -07:00
|
|
|
auto result = jit->execute(code);
|
2021-11-06 11:02:19 -04:00
|
|
|
if (auto err = result.takeError()) {
|
2021-11-06 12:57:09 -04:00
|
|
|
std::string output;
|
2021-11-06 11:02:19 -04:00
|
|
|
llvm::handleAllErrors(
|
|
|
|
std::move(err), [](const codon::error::ParserErrorInfo &e) { display(e); },
|
2021-11-16 15:40:00 -05:00
|
|
|
[&output](const codon::error::RuntimeErrorInfo &e) {
|
|
|
|
std::stringstream buf;
|
|
|
|
buf << e.getOutput();
|
|
|
|
buf << "\n\033[1mBacktrace:\033[0m\n";
|
|
|
|
for (const auto &line : e.getBacktrace()) {
|
|
|
|
buf << " " << line << "\n";
|
|
|
|
}
|
|
|
|
output = buf.str();
|
|
|
|
});
|
2021-11-06 12:57:09 -04:00
|
|
|
return output;
|
2021-11-06 11:02:19 -04:00
|
|
|
}
|
|
|
|
return *result;
|
2021-11-02 14:59:10 -04:00
|
|
|
}
|
2022-03-19 10:29:41 -04:00
|
|
|
|
|
|
|
void jitLoop(codon::jit::JIT *jit, std::istream &fp) {
|
|
|
|
std::string code;
|
|
|
|
for (std::string line; std::getline(fp, line);) {
|
|
|
|
if (line != "#%%") {
|
|
|
|
code += line + "\n";
|
|
|
|
} else {
|
|
|
|
fmt::print("{}[done]\n", jitExec(jit, code));
|
|
|
|
code = "";
|
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!code.empty())
|
|
|
|
fmt::print("{}[done]\n", jitExec(jit, code));
|
|
|
|
}
|
2021-11-02 14:59:10 -04:00
|
|
|
} // namespace
|
|
|
|
|
2021-11-01 19:10:33 -04:00
|
|
|
int jitMode(const std::vector<const char *> &args) {
|
2022-03-19 10:29:41 -04:00
|
|
|
llvm::cl::opt<std::string> input(llvm::cl::Positional, llvm::cl::desc("<input file>"),
|
|
|
|
llvm::cl::init("-"));
|
2021-11-30 08:44:36 -05:00
|
|
|
llvm::cl::list<std::string> plugins("plugin",
|
|
|
|
llvm::cl::desc("Load specified plugin"));
|
2022-01-20 11:22:32 -05:00
|
|
|
llvm::cl::opt<std::string> log("log", llvm::cl::desc("Enable given log streams"));
|
2021-11-30 08:44:36 -05:00
|
|
|
llvm::cl::ParseCommandLineOptions(args.size(), args.data());
|
2022-01-20 11:22:32 -05:00
|
|
|
initLogFlags(log);
|
2021-11-01 19:10:33 -04:00
|
|
|
codon::jit::JIT jit(args[0]);
|
2021-11-30 08:44:36 -05:00
|
|
|
|
|
|
|
// load plugins
|
|
|
|
for (const auto &plugin : plugins) {
|
|
|
|
bool failed = false;
|
|
|
|
llvm::handleAllErrors(jit.getCompiler()->load(plugin),
|
|
|
|
[&failed](const codon::error::PluginErrorInfo &e) {
|
|
|
|
codon::compilationError(e.getMessage(), /*file=*/"",
|
2022-12-04 16:45:21 -08:00
|
|
|
/*line=*/0, /*col=*/0, /*len=*/0,
|
|
|
|
/*errorCode*/ -1,
|
2021-11-30 08:44:36 -05:00
|
|
|
/*terminate=*/false);
|
|
|
|
failed = true;
|
|
|
|
});
|
|
|
|
if (failed)
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
2021-11-02 14:59:10 -04:00
|
|
|
llvm::cantFail(jit.init());
|
2021-11-01 19:10:33 -04:00
|
|
|
fmt::print(">>> Codon JIT v{} <<<\n", CODON_VERSION);
|
2022-03-19 10:29:41 -04:00
|
|
|
if (input == "-") {
|
|
|
|
jitLoop(&jit, std::cin);
|
|
|
|
} else {
|
|
|
|
std::ifstream fileInput(input);
|
|
|
|
jitLoop(&jit, fileInput);
|
2021-11-01 19:10:33 -04:00
|
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
2021-10-23 10:42:32 -07:00
|
|
|
|
2022-06-22 16:00:40 -04:00
|
|
|
int buildMode(const std::vector<const char *> &args, const std::string &argv0) {
|
2021-09-27 14:02:44 -04:00
|
|
|
llvm::cl::list<std::string> libs(
|
|
|
|
"l", llvm::cl::desc("Link the specified library (only for executables)"));
|
2022-06-22 16:00:40 -04:00
|
|
|
llvm::cl::opt<std::string> lflags("linker-flags",
|
|
|
|
llvm::cl::desc("Pass given flags to linker"));
|
2021-09-27 14:02:44 -04:00
|
|
|
llvm::cl::opt<BuildKind> buildKind(
|
|
|
|
llvm::cl::desc("output type"),
|
2023-01-28 22:59:49 -05:00
|
|
|
llvm::cl::values(
|
|
|
|
clEnumValN(LLVM, "llvm", "Generate LLVM IR"),
|
|
|
|
clEnumValN(Bitcode, "bc", "Generate LLVM bitcode"),
|
|
|
|
clEnumValN(Object, "obj", "Generate native object file"),
|
|
|
|
clEnumValN(Executable, "exe", "Generate executable"),
|
|
|
|
clEnumValN(Library, "lib", "Generate shared library"),
|
|
|
|
clEnumValN(PyExtension, "pyext", "Generate Python extension module"),
|
|
|
|
clEnumValN(Detect, "detect",
|
|
|
|
"Detect output type based on output file extension")),
|
2021-09-27 14:02:44 -04:00
|
|
|
llvm::cl::init(Detect));
|
|
|
|
llvm::cl::opt<std::string> output(
|
|
|
|
"o",
|
|
|
|
llvm::cl::desc(
|
|
|
|
"Write compiled output to specified file. Supported extensions: "
|
|
|
|
"none (executable), .o (object file), .ll (LLVM IR), .bc (LLVM bitcode)"));
|
2023-01-29 16:35:57 -05:00
|
|
|
llvm::cl::opt<std::string> pyModule(
|
|
|
|
"module", llvm::cl::desc("Python extension module name (only applicable when "
|
|
|
|
"building Python extension module)"));
|
2021-09-27 14:02:44 -04:00
|
|
|
|
2023-01-28 22:59:49 -05:00
|
|
|
auto compiler = processSource(args, /*standalone=*/true,
|
|
|
|
[&] { return buildKind == BuildKind::PyExtension; });
|
2021-10-30 14:16:40 -04:00
|
|
|
if (!compiler)
|
2021-09-27 14:02:44 -04:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
std::vector<std::string> libsVec(libs);
|
|
|
|
|
2021-10-30 14:16:40 -04:00
|
|
|
if (output.empty() && compiler->getInput() == "-")
|
2021-10-04 12:10:59 -05:00
|
|
|
codon::compilationError("output file must be specified when reading from stdin");
|
2021-09-27 14:02:44 -04:00
|
|
|
std::string extension;
|
|
|
|
switch (buildKind) {
|
|
|
|
case BuildKind::LLVM:
|
|
|
|
extension = ".ll";
|
|
|
|
break;
|
|
|
|
case BuildKind::Bitcode:
|
|
|
|
extension = ".bc";
|
|
|
|
break;
|
|
|
|
case BuildKind::Object:
|
2023-02-02 16:09:10 -05:00
|
|
|
case BuildKind::PyExtension:
|
2021-09-27 14:02:44 -04:00
|
|
|
extension = ".o";
|
|
|
|
break;
|
2022-06-26 17:27:31 -04:00
|
|
|
case BuildKind::Library:
|
|
|
|
extension = isMacOS() ? ".dylib" : ".so";
|
|
|
|
break;
|
2021-09-27 14:02:44 -04:00
|
|
|
case BuildKind::Executable:
|
|
|
|
case BuildKind::Detect:
|
|
|
|
extension = "";
|
|
|
|
break;
|
|
|
|
default:
|
2022-07-26 13:06:00 -07:00
|
|
|
seqassertn(0, "unknown build kind");
|
2021-09-27 14:02:44 -04:00
|
|
|
}
|
|
|
|
const std::string filename =
|
2021-10-30 14:16:40 -04:00
|
|
|
output.empty() ? makeOutputFilename(compiler->getInput(), extension) : output;
|
2021-09-27 14:02:44 -04:00
|
|
|
switch (buildKind) {
|
|
|
|
case BuildKind::LLVM:
|
2021-10-30 14:16:40 -04:00
|
|
|
compiler->getLLVMVisitor()->writeToLLFile(filename);
|
2021-09-27 14:02:44 -04:00
|
|
|
break;
|
|
|
|
case BuildKind::Bitcode:
|
2021-10-30 14:16:40 -04:00
|
|
|
compiler->getLLVMVisitor()->writeToBitcodeFile(filename);
|
2021-09-27 14:02:44 -04:00
|
|
|
break;
|
|
|
|
case BuildKind::Object:
|
2021-10-30 14:16:40 -04:00
|
|
|
compiler->getLLVMVisitor()->writeToObjectFile(filename);
|
2021-09-27 14:02:44 -04:00
|
|
|
break;
|
|
|
|
case BuildKind::Executable:
|
2022-06-26 17:27:31 -04:00
|
|
|
compiler->getLLVMVisitor()->writeToExecutable(filename, argv0, false, libsVec,
|
|
|
|
lflags);
|
|
|
|
break;
|
|
|
|
case BuildKind::Library:
|
|
|
|
compiler->getLLVMVisitor()->writeToExecutable(filename, argv0, true, libsVec,
|
|
|
|
lflags);
|
2021-09-27 14:02:44 -04:00
|
|
|
break;
|
2023-01-28 22:59:49 -05:00
|
|
|
case BuildKind::PyExtension:
|
2023-02-10 11:28:04 -05:00
|
|
|
compiler->getCache()->pyModule->name =
|
|
|
|
pyModule.empty() ? llvm::sys::path::stem(compiler->getInput()).str() : pyModule;
|
|
|
|
compiler->getLLVMVisitor()->writeToPythonExtension(*compiler->getCache()->pyModule,
|
|
|
|
filename);
|
2023-01-28 22:59:49 -05:00
|
|
|
break;
|
2021-09-27 14:02:44 -04:00
|
|
|
case BuildKind::Detect:
|
2022-06-22 16:00:40 -04:00
|
|
|
compiler->getLLVMVisitor()->compile(filename, argv0, libsVec, lflags);
|
2021-09-27 14:02:44 -04:00
|
|
|
break;
|
|
|
|
default:
|
2022-07-26 13:06:00 -07:00
|
|
|
seqassertn(0, "unknown build kind");
|
2021-09-27 14:02:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2021-11-09 03:47:41 -08:00
|
|
|
int jupyterMode(const std::vector<const char *> &args) {
|
2021-12-06 01:59:32 -08:00
|
|
|
llvm::cl::list<std::string> plugins("plugin",
|
|
|
|
llvm::cl::desc("Load specified plugin"));
|
|
|
|
llvm::cl::opt<std::string> input(llvm::cl::Positional,
|
|
|
|
llvm::cl::desc("<connection file>"),
|
|
|
|
llvm::cl::init("connection.json"));
|
|
|
|
llvm::cl::ParseCommandLineOptions(args.size(), args.data());
|
|
|
|
int code = codon::startJupyterKernel(args[0], plugins, input);
|
2021-11-09 03:47:41 -08:00
|
|
|
return code;
|
|
|
|
}
|
|
|
|
|
2021-09-27 14:02:44 -04:00
|
|
|
void showCommandsAndExit() {
|
2022-06-26 17:27:31 -04:00
|
|
|
codon::compilationError("Available commands: codon <run|build|doc>");
|
2021-09-27 14:02:44 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int otherMode(const std::vector<const char *> &args) {
|
|
|
|
llvm::cl::opt<std::string> input(llvm::cl::Positional, llvm::cl::desc("<mode>"));
|
|
|
|
llvm::cl::extrahelp("\nMODES:\n\n"
|
|
|
|
" run - run a program interactively\n"
|
|
|
|
" build - build a program\n"
|
|
|
|
" doc - generate program documentation\n");
|
|
|
|
llvm::cl::ParseCommandLineOptions(args.size(), args.data());
|
|
|
|
|
|
|
|
if (!input.empty())
|
|
|
|
showCommandsAndExit();
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, const char **argv) {
|
|
|
|
if (argc < 2)
|
|
|
|
showCommandsAndExit();
|
|
|
|
|
|
|
|
llvm::cl::SetVersionPrinter(versMsg);
|
|
|
|
std::vector<const char *> args{argv[0]};
|
|
|
|
for (int i = 2; i < argc; i++)
|
|
|
|
args.push_back(argv[i]);
|
|
|
|
|
|
|
|
std::string mode(argv[1]);
|
|
|
|
std::string argv0 = std::string(args[0]) + " " + mode;
|
|
|
|
if (mode == "run") {
|
|
|
|
args[0] = argv0.data();
|
|
|
|
return runMode(args);
|
|
|
|
}
|
|
|
|
if (mode == "build") {
|
2022-06-22 16:00:40 -04:00
|
|
|
const char *oldArgv0 = args[0];
|
2021-09-27 14:02:44 -04:00
|
|
|
args[0] = argv0.data();
|
2022-06-22 16:00:40 -04:00
|
|
|
return buildMode(args, oldArgv0);
|
2021-09-27 14:02:44 -04:00
|
|
|
}
|
|
|
|
if (mode == "doc") {
|
|
|
|
const char *oldArgv0 = args[0];
|
|
|
|
args[0] = argv0.data();
|
|
|
|
return docMode(args, oldArgv0);
|
|
|
|
}
|
2021-10-23 10:42:32 -07:00
|
|
|
if (mode == "jit") {
|
2021-11-01 19:10:33 -04:00
|
|
|
args[0] = argv0.data();
|
|
|
|
return jitMode(args);
|
2021-10-23 10:42:32 -07:00
|
|
|
}
|
2021-11-09 03:47:41 -08:00
|
|
|
if (mode == "jupyter") {
|
|
|
|
args[0] = argv0.data();
|
|
|
|
return jupyterMode(args);
|
|
|
|
}
|
2021-09-27 14:02:44 -04:00
|
|
|
return otherMode({argv, argv + argc});
|
|
|
|
}
|