From d2ea9fe8d62228b1bc633285fad94dd9b28841a3 Mon Sep 17 00:00:00 2001 From: Nathan Seymour Date: Thu, 7 Nov 2024 12:45:01 -0600 Subject: [PATCH] refactoring; --- CMakeLists.txt | 3 +- src/calculator/main.cpp | 20 +++++++++- src/calculator/main.h | 11 +++++ src/calculator/ui/Window.h | 20 ++-------- src/compiler/Compiler.cpp | 2 - src/compiler/Compiler.h | 36 ++++++++++------- src/compiler/Program.cpp | 1 - src/compiler/Program.h | 51 ------------------------ src/compiler/std/StandardLibrary.cpp | 25 ++++++++++-- src/compiler/transformer/IRGenerator.cpp | 17 ++++---- src/compiler/transformer/IRGenerator.h | 4 +- src/graphic/ugl/shapes/Line.cpp | 2 +- src/graphic/ugl/shapes/Line.h | 4 +- 13 files changed, 91 insertions(+), 105 deletions(-) create mode 100644 src/calculator/main.h delete mode 100644 src/compiler/Program.cpp delete mode 100644 src/compiler/Program.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ca7d28..c72c067 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,8 +55,6 @@ add_library(unlogic STATIC src/Error.h src/parser/Parser.cpp src/parser/Parser.h - src/compiler/Program.cpp - src/compiler/Program.h src/compiler/transformer/IRGenerator.cpp src/compiler/transformer/IRGenerator.h ) @@ -79,6 +77,7 @@ add_executable(unlogic-calculator src/graphic/ugl/Canvas.h src/graphic/ugl/VertexBuffer.cpp src/graphic/ugl/VertexBuffer.h + src/calculator/main.h ) target_link_libraries(unlogic-calculator PUBLIC unlogic glm::glm ${GTKMM_LIBRARIES}) target_link_directories(unlogic-calculator PUBLIC ${GTKMM_LIBRARY_DIRS}) diff --git a/src/calculator/main.cpp b/src/calculator/main.cpp index c53fb09..3c290d3 100644 --- a/src/calculator/main.cpp +++ b/src/calculator/main.cpp @@ -1,4 +1,6 @@ +#include #include +#include "main.h" #include "compiler/Compiler.h" #include "ui/Window.h" @@ -10,10 +12,24 @@ * - Dispatchers for synchronization */ -int main(int argc, char *argv[]) +void init_compiler_runtime() { unlogic::Compiler::InitializeGlobalCompilerRuntime(); + unlogic::compiler_runtime_avail = true; + unlogic::compiler_runtime_avail.notify_all(); +} + +int main(int argc, char *argv[]) +{ + std::cout << "[MAIN] Initializing compiler runtime..." << std::endl; + std::thread init_thread(init_compiler_runtime); + + std::cout << "[MAIN] Creating application..." << std::endl; auto app = Gtk::Application::create("global.seymour.unlogic"); - return app->make_window_and_run(argc, argv); + int ret = app->make_window_and_run(argc, argv); + + init_thread.join(); + + return ret; } diff --git a/src/calculator/main.h b/src/calculator/main.h new file mode 100644 index 0000000..4c953ad --- /dev/null +++ b/src/calculator/main.h @@ -0,0 +1,11 @@ +#ifndef UNLOGIC_MAIN_H +#define UNLOGIC_MAIN_H + +#include + +namespace unlogic +{ + std::atomic compiler_runtime_avail = false; +} + +#endif //UNLOGIC_MAIN_H diff --git a/src/calculator/ui/Window.h b/src/calculator/ui/Window.h index d078d04..42aa7b3 100644 --- a/src/calculator/ui/Window.h +++ b/src/calculator/ui/Window.h @@ -17,6 +17,8 @@ namespace unlogic class Window : public Gtk::Window { protected: + Glib::Dispatcher event_compilation_finished; + Gtk::Paned divider_; std::shared_ptr source_buffer_; @@ -48,18 +50,10 @@ namespace unlogic void on_source_buffer_changed() { - /* - auto source_text = this->source_buffer_->get_text(); - auto program = parser.Parse(source_text.c_str()); - if(program) - { - Executable executable = Compiler::CompileProgram(std::get(*program)); - executable(); - } - */ } - void CreateUI() + public: + Window() { this->set_title("Unlogic"); this->set_default_size(1000, 500); @@ -93,12 +87,6 @@ namespace unlogic this->canvas_.signal_realize().connect(sigc::mem_fun(*this, &Window::on_renderer_realize)); this->canvas_.signal_render().connect(sigc::mem_fun(*this, &Window::on_renderer_render), false); } - - public: - Window() - { - this->CreateUI(); - } }; } diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp index 0f5fe69..3513808 100644 --- a/src/compiler/Compiler.cpp +++ b/src/compiler/Compiler.cpp @@ -5,5 +5,3 @@ #include "Compiler.h" using namespace unlogic; - -std::atomic Compiler::global_init_complete_ = false; \ No newline at end of file diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h index 1cb1e9c..fec6c37 100644 --- a/src/compiler/Compiler.h +++ b/src/compiler/Compiler.h @@ -21,12 +21,12 @@ #include "parser/Node.h" #include "parser/Parser.h" #include "Library.h" -#include "Program.h" #include "std/StandardLibrary.h" +#include "transformer/IRGenerator.h" namespace unlogic { - class Executable + class Program { friend class Compiler; @@ -34,7 +34,7 @@ namespace unlogic std::unique_ptr jit_; protected: - explicit Executable(std::unique_ptr jit) : jit_(std::move(jit)) + explicit Program(std::unique_ptr jit) : jit_(std::move(jit)) { auto function_ea = this->jit_->lookup("__entry"); if(auto e = function_ea.takeError()) @@ -51,12 +51,11 @@ namespace unlogic return this->function_(); } - Executable() = delete; + Program() = delete; }; class Compiler { - static std::atomic global_init_complete_; std::vector default_libraries_; public: @@ -65,15 +64,10 @@ namespace unlogic llvm::InitializeNativeTarget(); llvm::InitializeNativeTargetAsmPrinter(); llvm::InitializeNativeTargetAsmParser(); - - Compiler::global_init_complete_ = true; - Compiler::global_init_complete_.notify_all(); } - Executable Compile(std::string_view program_text) + Program Compile(std::string_view program_text) { - Compiler::global_init_complete_.wait(false); - // Establish context for build auto ctx = std::make_unique(); @@ -119,16 +113,30 @@ namespace unlogic main.addToLinkOrder(*dylib); } + // Parse program auto body = std::get>(*parser->Parse(program_text)); - Program program(*ctx.get(), std::move(body)); + // Compile program + auto module = std::make_unique("unlogic", *ctx.get()); + + // Create IR generation context + Scope program_scope; + IRGenerationContext ir_ctx = { + .llvm_ctx = *ctx.get(), + .module = std::move(module), + .scope = program_scope, + }; + + // IR Generator + IRGenerator generator(ir_ctx); - auto module = std::move(program.Build()); + // Build program + body->Accept(generator); llvm::orc::ThreadSafeModule tsm(std::move(module), std::move(ctx)); jit->addIRModule(std::move(tsm)); - return Executable(std::move(jit)); + return Program(std::move(jit)); } Compiler() = default; diff --git a/src/compiler/Program.cpp b/src/compiler/Program.cpp deleted file mode 100644 index d976a8f..0000000 --- a/src/compiler/Program.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Program.h" diff --git a/src/compiler/Program.h b/src/compiler/Program.h deleted file mode 100644 index 5abc492..0000000 --- a/src/compiler/Program.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef UNLOGIC_PROGRAM_H -#define UNLOGIC_PROGRAM_H - -#include "transformer/IRGenerator.h" -#include "parser/Node.h" - -namespace unlogic -{ - class Program - { - llvm::LLVMContext &llvm_ctx_; - llvm::IRBuilder<> builder_; - - std::unique_ptr body_; - - public: - std::unique_ptr Build() - { - auto module = std::make_unique("unlogic", this->llvm_ctx_); - - // Create IR generation context - Scope program_scope; - IRGenerationContext ctx = { - .llvm_ctx = this->llvm_ctx_, - .module = std::move(module), - .builder = this->builder_, - .scope = program_scope, - }; - - // IR Generator - IRGenerator generator(ctx); - - // Generate main wrapper function - auto main = std::make_unique("main", std::move(this->body_)); - - // Build program - generator.Visit(main.get()); - - return std::move(module); - } - - Program() = delete; - - Program(llvm::LLVMContext &llvm_ctx, std::unique_ptr body) - : body_(std::move(body)), - llvm_ctx_(llvm_ctx), - builder_(llvm_ctx) {} - }; -} - -#endif //UNLOGIC_PROGRAM_H diff --git a/src/compiler/std/StandardLibrary.cpp b/src/compiler/std/StandardLibrary.cpp index a38468d..b3c00dd 100644 --- a/src/compiler/std/StandardLibrary.cpp +++ b/src/compiler/std/StandardLibrary.cpp @@ -2,6 +2,7 @@ // Created by nathan on 6/18/24. // +#include #include #include "StandardLibrary.h" @@ -9,13 +10,31 @@ using namespace unlogic; extern "C" { - double unlogic_pow(double base, double exponent) { return std::pow(base, exponent); } + double unlogic_std_pow(double base, double exponent) { return std::pow(base, exponent); } + + void unlogic_std_log(char const *message) + { + std::cout << message << std::endl; + } } LibraryDefinition unlogic::stdlib("stdlib", [](unlogic::Library &lib) { - std::array pow_args = { llvm::Type::getDoubleTy(lib.ctx), llvm::Type::getDoubleTy(lib.ctx) }; + // pow + std::array pow_args = { + llvm::Type::getDoubleTy(lib.ctx), + llvm::Type::getDoubleTy(lib.ctx), + }; + llvm::FunctionType *pow_type = llvm::FunctionType::get(llvm::Type::getDoubleTy(lib.ctx), pow_args, false); - lib.AddFunction("pow", pow_type, (void*)unlogic_pow); + lib.AddFunction("pow", pow_type, (void *) unlogic_std_pow); + + // log + std::array log_args = { + llvm::Type::getInt8PtrTy(lib.ctx), + }; + + llvm::FunctionType *log_type = llvm::FunctionType::get(llvm::Type::getVoidTy(lib.ctx), log_args, false); + lib.AddFunction("log", log_type, (void *) unlogic_std_log); }); /* diff --git a/src/compiler/transformer/IRGenerator.cpp b/src/compiler/transformer/IRGenerator.cpp index 3de641f..267c780 100644 --- a/src/compiler/transformer/IRGenerator.cpp +++ b/src/compiler/transformer/IRGenerator.cpp @@ -35,7 +35,7 @@ void unlogic::IRGenerator::Visit(const unlogic::CallNode *node) this->values.pop(); } - llvm::Value *value = ctx.builder.CreateCall(function, argument_values, "calltmp"); + llvm::Value *value = this->builder.CreateCall(function, argument_values, "calltmp"); this->values.push(value); } @@ -49,7 +49,7 @@ void unlogic::IRGenerator::Visit(const unlogic::AdditionNode *node) llvm::Value *rhs = this->values.top(); this->values.pop(); - llvm::Value *value = ctx.builder.CreateFAdd(lhs, rhs, "addtmp"); + llvm::Value *value = this->builder.CreateFAdd(lhs, rhs, "addtmp"); this->values.push(value); } @@ -63,7 +63,7 @@ void unlogic::IRGenerator::Visit(const unlogic::SubtractionNode *node) llvm::Value *rhs = this->values.top(); this->values.pop(); - llvm::Value *value = ctx.builder.CreateFSub(lhs, rhs, "subtmp"); + llvm::Value *value = this->builder.CreateFSub(lhs, rhs, "subtmp"); this->values.push(value); } @@ -77,7 +77,7 @@ void unlogic::IRGenerator::Visit(const unlogic::MultiplicationNode *node) llvm::Value *rhs = this->values.top(); this->values.pop(); - llvm::Value *value = ctx.builder.CreateFMul(lhs, rhs, "multmp"); + llvm::Value *value = this->builder.CreateFMul(lhs, rhs, "multmp"); this->values.push(value); } @@ -91,7 +91,7 @@ void unlogic::IRGenerator::Visit(const unlogic::DivisionNode *node) llvm::Value *rhs = this->values.top(); this->values.pop(); - llvm::Value *value = ctx.builder.CreateFDiv(lhs, rhs, "divtmp"); + llvm::Value *value = this->builder.CreateFDiv(lhs, rhs, "divtmp"); this->values.push(value); } @@ -107,7 +107,7 @@ void unlogic::IRGenerator::Visit(const unlogic::PotentiationNode *node) llvm::Function *pow = ctx.module->getFunction("pow"); - llvm::Value *value = ctx.builder.CreateCall(pow, {lhs, rhs}, "powtmp"); + llvm::Value *value = this->builder.CreateCall(pow, {lhs, rhs}, "powtmp"); this->values.push(value); } @@ -126,7 +126,7 @@ void unlogic::IRGenerator::Visit(const unlogic::FunctionDefinitionNode *node) // Generate function body llvm::BasicBlock *block = llvm::BasicBlock::Create(ctx.llvm_ctx, node->name_, function); - ctx.builder.SetInsertPoint(block); + this->builder.SetInsertPoint(block); ctx.scope.PushLayer(); for(auto &arg : function->args()) @@ -138,7 +138,7 @@ void unlogic::IRGenerator::Visit(const unlogic::FunctionDefinitionNode *node) llvm::Value* return_value = this->values.top(); this->values.pop(); - ctx.builder.CreateRet(return_value); + this->builder.CreateRet(return_value); ctx.scope.PopLayer(); @@ -149,5 +149,4 @@ void unlogic::IRGenerator::Visit(const unlogic::FunctionDefinitionNode *node) void unlogic::IRGenerator::Visit(const unlogic::ScopedBlockNode *node) { - } diff --git a/src/compiler/transformer/IRGenerator.h b/src/compiler/transformer/IRGenerator.h index 7a7f2dc..ff2deb9 100644 --- a/src/compiler/transformer/IRGenerator.h +++ b/src/compiler/transformer/IRGenerator.h @@ -41,13 +41,13 @@ namespace unlogic { llvm::LLVMContext &llvm_ctx; std::unique_ptr module; - llvm::IRBuilder<> &builder; Scope &scope; }; struct IRGenerator : public INodeVisitor { IRGenerationContext &ctx; + llvm::IRBuilder<> builder; std::stack values; void Visit(const NumericLiteralNode *node) override; @@ -62,7 +62,7 @@ namespace unlogic void Visit(const PotentiationNode *node) override; void Visit(const FunctionDefinitionNode *node) override; - IRGenerator(IRGenerationContext &ctx) : ctx(ctx) {} + IRGenerator(IRGenerationContext &ctx) : ctx(ctx), builder(ctx.llvm_ctx) {} }; } diff --git a/src/graphic/ugl/shapes/Line.cpp b/src/graphic/ugl/shapes/Line.cpp index 6a911f8..239afbb 100644 --- a/src/graphic/ugl/shapes/Line.cpp +++ b/src/graphic/ugl/shapes/Line.cpp @@ -30,7 +30,7 @@ std::shared_ptr unlogic::Line::GenerateVertexBuffer() con return std::make_shared(vertices, PrimitiveType::kTriangleStrip); } -void unlogic::Line::SetFunction(const unlogic::Executable &function, const glm::vec2 &domain) +void unlogic::Line::SetFunction(const unlogic::Program &function, const glm::vec2 &domain) { std::size_t point_count = std::ceil((domain.y - domain.x) / this->precision_); this->points_.clear(); diff --git a/src/graphic/ugl/shapes/Line.h b/src/graphic/ugl/shapes/Line.h index 314ba44..e734ff6 100644 --- a/src/graphic/ugl/shapes/Line.h +++ b/src/graphic/ugl/shapes/Line.h @@ -19,11 +19,11 @@ namespace unlogic [[nodiscard]] std::shared_ptr GenerateVertexBuffer() const override; public: - void SetFunction(unlogic::Executable const &function, glm::vec2 const &domain); + void SetFunction(unlogic::Program const &function, glm::vec2 const &domain); void SetPoints(std::vector const &points); - Line(unlogic::Executable const &function, glm::vec2 const &domain) + Line(unlogic::Program const &function, glm::vec2 const &domain) { this->SetFunction(function, domain); }