diff options
Diffstat (limited to 'main.cpp')
-rw-r--r-- | main.cpp | 128 |
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(); + } +} + |