aboutsummaryrefslogtreecommitdiffstats
path: root/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.cpp')
-rw-r--r--main.cpp128
1 files changed, 128 insertions, 0 deletions
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..c70c976
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,128 @@
+/**
+ * lisp-compiler: Compiles LISP using LLVM.
+ * Copyright (C) 2022 Clyne Sullivan
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @file main.cpp
+ * @brief Program entry point.
+ */
+
+/*
+
+Current support:
+ - Literals:
+ - Integer
+ - Double (when decimal point is found)
+ - (define name value)
+ - (set! defined-name new-value)
+ - (lambda (...) ...)
+ - (if cond then else)
+ - Calling procedures:
+ - Defined lambdas
+ - Built-in things
+ - Undefined procedures are prototyped
+
+TODO:
+ - Error reporting!
+ - Documentation!
+ - Arithmetic
+ - String literals?
+ - Typed definitions...
+ - See R7RS-small for more...
+
+*/
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+
+#include <cstdio>
+#include <string>
+
+#include "ast.hpp"
+#include "parser.hpp"
+#include "state.hpp"
+
+void compileToObjectFile(CompilerState&);
+int main(int argc, const char *argv[])
+{
+ CompilerState state;
+ Parser parser;
+
+ for (int i = 1; i < argc; ++i)
+ parser.addString(argv[i]);
+
+ auto functype = llvm::FunctionType::get(llvm::Type::getInt32Ty(state.context), {}, false);
+ auto func = llvm::Function::Create(functype, llvm::Function::ExternalLinkage, "main", &state.module);
+ auto block = llvm::BasicBlock::Create(state.context, "entry", func);
+ state.builder.SetInsertPoint(block);
+
+ parser.parse(state);
+
+ state.builder.CreateRet(state.builder.getInt32(0));
+
+ puts("");
+ state.module.print(llvm::errs(), nullptr); // prints everything
+
+ compileToObjectFile(state);
+
+ return 0;
+}
+
+void compileToObjectFile(CompilerState& state)
+{
+ llvm::InitializeAllTargetInfos();
+ llvm::InitializeAllTargets();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmParsers();
+ llvm::InitializeAllAsmPrinters();
+
+ auto TargetTriple = "x86_64-pc-linux-gnu";
+
+ std::string error;
+ auto Target = llvm::TargetRegistry::lookupTarget(TargetTriple, error);
+ if (!error.empty())
+ puts(error.c_str());
+
+ auto CPU = "generic";
+ auto Features = "";
+ llvm::TargetOptions opt;
+ auto RM = llvm::Optional<llvm::Reloc::Model>();
+ auto TargetMachine = Target->createTargetMachine(TargetTriple, CPU, Features, opt, RM);
+
+ std::error_code EC;
+ llvm::raw_fd_ostream dest ("out.o", EC, llvm::sys::fs::OF_None);
+
+ llvm::legacy::PassManager pass;
+
+ if (TargetMachine->addPassesToEmitFile(pass, dest, nullptr, llvm::CGFT_ObjectFile)) {
+ llvm::errs() << "TargetMachine can't emit a file of this type";
+ } else {
+ pass.run(state.module);
+ dest.flush();
+ }
+}
+