From e31bd01ea5d4e5e852be587830a9632027ac5c65 Mon Sep 17 00:00:00 2001 From: Harrand Date: Thu, 16 May 2024 18:13:43 +0100 Subject: [PATCH] [cpp] skeleton for codegen --- cpp/CMakeLists.txt | 2 ++ cpp/src/codegen.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++ cpp/src/codegen.hpp | 24 ++++++++++++++++++++ cpp/src/psyc_main.cpp | 20 ++++++++++++---- 4 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 cpp/src/codegen.cpp create mode 100644 cpp/src/codegen.hpp diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 0f1f30a..bb08690 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -36,6 +36,8 @@ add_executable(psyc src/ast.hpp src/builtin.cpp src/builtin.hpp + src/codegen.cpp + src/codegen.hpp src/config.hpp src/diag.hpp src/error.hpp diff --git a/cpp/src/codegen.cpp b/cpp/src/codegen.cpp new file mode 100644 index 0000000..4ec9a48 --- /dev/null +++ b/cpp/src/codegen.cpp @@ -0,0 +1,53 @@ +#include "codegen.hpp" +#include "diag.hpp" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/LLVMContext.h" + +#include "llvm/ADT/APInt.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Value.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/TargetParser/Host.h" +#include "llvm/MC/TargetRegistry.h" + +namespace code +{ + std::string output::dump_ir() const + { + if(this->codegen_handle == nullptr) + { + return ""; + } + std::string ir_string; + llvm::raw_string_ostream os{ir_string}; + reinterpret_cast(this->codegen_handle)->print(os, nullptr); + return ir_string; + } + + std::string output::get_output_filename() const + { + return this->module_name + ".o"; + } + + void output::write_to_object_file(std::filesystem::path output_dir) + { + std::string object_filename = (output_dir / this->get_output_filename()).string(); + + diag::error(error_code::nyi, "writing to object file is not yet implemented. i was told to write to \"{}\"", object_filename); + } + + output generate(const semal::output& input, std::string module_name) + { + return + { + .codegen_handle = nullptr, + .module_name = module_name + }; + } +} \ No newline at end of file diff --git a/cpp/src/codegen.hpp b/cpp/src/codegen.hpp new file mode 100644 index 0000000..e4821ae --- /dev/null +++ b/cpp/src/codegen.hpp @@ -0,0 +1,24 @@ +#ifndef PSYC_CODEGEN_HPP +#define PSYC_CODEGEN_HPP +#include "semal.hpp" + +namespace code +{ + struct output + { + void* codegen_handle = nullptr; + std::string module_name; + std::string dump_ir() const; + std::string get_output_filename() const; + void write_to_object_file(std::filesystem::path output_dir); + }; + + output generate(const semal::output& input, std::string module_name = ""); + + struct state + { + std::unordered_map codegend_input_files = {}; + }; +} + +#endif // PSYC_CODEGEN_HPP \ No newline at end of file diff --git a/cpp/src/psyc_main.cpp b/cpp/src/psyc_main.cpp index e66c4b1..f086ef1 100644 --- a/cpp/src/psyc_main.cpp +++ b/cpp/src/psyc_main.cpp @@ -2,9 +2,9 @@ #include "lex.hpp" #include "parse.hpp" #include "semal.hpp" +#include "codegen.hpp" #include "timer.hpp" #include "diag.hpp" -#include "type.hpp" #include #include #include @@ -89,14 +89,24 @@ int main(int argc, char** argv) t.semal = timer::elapsed_millis(); // codegen + timer::start(); + code::state codegen; + for(const auto& [input_file, semantic_output] : semal.analysed_input_files) + { + codegen.codegend_input_files[input_file] = code::generate(semantic_output, input_file.stem().string()); + if(args.should_dump_ir) + { + std::cout << "==========================\n"; + std::cout << "ir for " << input_file << ":\n"; + std::cout << codegen.codegend_input_files[input_file].dump_ir(); + std::cout << "\n==========================\n\n"; + } + } + t.codegen = timer::elapsed_millis(); // link t.print(); - - type ty = type::from_primitive(primitive_type::u8); - ty = ty.pointer_to().pointer_to(qualifier_const); - std::cout << "type: \n" << ty.name(); return 0; }