diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index a9a568b..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: CI - -on: - pull_request: - branches: - - "**" - -jobs: - build-and-test: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y wget lsb-release software-properties-common gnupg catch2 - - wget https://apt.llvm.org/llvm.sh - chmod +x llvm.sh - sudo ./llvm.sh 22 - - echo "LLVM_DIR=/usr/lib/llvm-22/lib/cmake/llvm" >> $GITHUB_ENV - - - name: Build and Test - run: | - cmake . - make - ./bin/tests diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 64c1a57..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,74 +0,0 @@ -cmake_minimum_required(VERSION 3.31.6) - -project(alpha) - - -set(CMAKE_CXX_STANDARD 20) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) - -include_directories(${CMAKE_SOURCE_DIR}/src) - -find_package(LLVM REQUIRED CONFIG) - -add_definitions(${LLVM_DEFINITIONS}) -llvm_map_components_to_libnames(llvm_libs - core - support - irreader - codegen - asmprinter - target - native - TargetParser -) - - -file(GLOB_RECURSE ALL_SRC_CPP CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") -list(FILTER ALL_SRC_CPP EXCLUDE REGEX ".*main\\.cpp$") - -file(GLOB_RECURSE ALL_SRC_HPP CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp") - -add_library(alpha_lib STATIC ${ALL_SRC_CPP} ${ALL_SRC_HPP}) - -target_include_directories(alpha_lib PUBLIC - ${CMAKE_SOURCE_DIR}/src - ${LLVM_INCLUDE_DIRS} -) -target_link_libraries(alpha_lib PUBLIC ${llvm_libs}) - -# Main compiler - -add_executable(main src/main.cpp) - -target_link_libraries(main PRIVATE alpha_lib) - -set_target_properties(main PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin -) - -# Tests -find_package(Catch2 3 REQUIRED) - -enable_testing() -file(GLOB_RECURSE ALL_TEST_CPP CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp") - - -add_executable(tests - ${ALL_TEST_CPP} -) - -target_link_libraries(tests PRIVATE - alpha_lib - Catch2::Catch2WithMain -) - -get_target_property(Catch2_INCLUDE_DIR Catch2::Catch2 INTERFACE_INCLUDE_DIRECTORIES) -target_include_directories(tests PRIVATE ${Catch2_INCLUDE_DIR}) - -include(Catch) -catch_discover_tests(tests) - -set_target_properties(tests PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin -) \ No newline at end of file diff --git a/README.md b/README.md index 7caf99d..f65da79 100644 --- a/README.md +++ b/README.md @@ -57,17 +57,6 @@ uint8 b = a + 1; uint8 c = a + b + 1; ``` -## Printing - -Values can be printed to standard out using a print statement, proceeded by the value wanted to print. - -``` -print 1; - -uint8 a = 2; -print a; -``` - ## Examples Examples can be found in the `/examples` folder. @@ -90,7 +79,6 @@ String segments are converted to a list of tokens. Representing the smallest seg | Identifier | `IDENTIFIER` | Variable identifier | | Number | `NUMBER` | Integer | | Return | `RETURN` | Returns a value from a function | -| Print | `PRINT` | Prints a value | ## Syntax Analyser @@ -102,7 +90,6 @@ Combines tokens into statements. | Assignment | `ASSIGNMENT` | Sets a variable to a value | | Return | `RETURN` | Returns a value from a function | | Addition | `ADDITION` | Adds two values and assigns them to an identifier | -| Print | `PRINT` | Prints the value after it | ## `LLVM` Intermediate Representation diff --git a/src/generation/generator.hpp b/src/generation/generator.hpp index 75c95d8..49e42a4 100644 --- a/src/generation/generator.hpp +++ b/src/generation/generator.hpp @@ -21,16 +21,20 @@ #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Instruction.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Program.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" #include #include #include #include #include #include -#include #include #include #include @@ -56,7 +60,9 @@ class Generator { llvm::InitializeNativeTargetAsmParser(); } - std::unique_ptr buildModule(llvm::LLVMContext& context) { + void compile() { + + llvm::LLVMContext context; std::unique_ptr module = std::make_unique("build", context); @@ -358,7 +364,6 @@ class Generator { } builder.store(builder.add(lhs, rhs, outName), outUint.getAlloc()); - break; } case StatementType::PRINT: { const PrintStatement& printStatement = @@ -407,16 +412,8 @@ class Generator { builder.createReturn(returnValue); } - return module; - } - - void print_module(std::unique_ptr module) { std::cout << "-- LLVM IR --" << std::endl; module->print(llvm::outs(), nullptr); - } - - void compile(llvm::LLVMContext& context, - std::unique_ptr module) { auto targetTriple = llvm::Triple(llvm::sys::getDefaultTargetTriple()); module->setTargetTriple(targetTriple); @@ -429,7 +426,7 @@ class Generator { auto CPU = "generic"; auto features = ""; llvm::TargetOptions opt; - std::optional RM = llvm::Reloc::PIC_; + std::optional RM = std::nullopt; llvm::TargetMachine* targetMachine = target->createTargetMachine(targetTriple, CPU, features, opt, RM); diff --git a/src/lexer/lexer.hpp b/src/lexer/lexer.hpp index 20c99fb..b2d6088 100644 --- a/src/lexer/lexer.hpp +++ b/src/lexer/lexer.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include "./string_converter.hpp" @@ -58,7 +59,7 @@ class Lexer { tokens.addReturn(ReturnToken()); } else if (buffer == "print") { tokens.addPrint(PrintToken()); - } else if (buffer.size() != 0) { + } else { tokens.addIdentifier(IdentifierToken(buffer)); } diff --git a/src/main.cpp b/src/main.cpp index 965be31..8b85e2e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,7 +4,6 @@ #include #include -#include #include "./io/file_reader.hpp" #include "./lexer/lexer.hpp" @@ -18,14 +17,6 @@ int main(const int argc, char* argv[]) { return 1; } - bool verbose = false; - - if (argc == 3) { - if (std::string(argv[2]) == "-v") { - verbose = true; - } - } - FileReader fileReader(argv[1]); if (!fileReader.isOpen()) { std::cerr << "Input file failed to open\n"; @@ -34,26 +25,14 @@ int main(const int argc, char* argv[]) { Lexer lexer(fileReader.readAll()); TokenContainer tokens = lexer.makeTokenList(); - if (verbose) { - tokens.print(); - } + tokens.print(); AbstractSyntaxTree ast(tokens); Program program = ast.parse(); - if (verbose) { - program.print(); - } + program.print(); Generator generator(program); generator.init(); - - llvm::LLVMContext context; - std::unique_ptr module = generator.buildModule(context); - - if (verbose) { - generator.print_module(std::move(module)); - } - - generator.compile(context, std::move(module)); + generator.compile(); } \ No newline at end of file diff --git a/src/syntax_analyser/abstract_syntax_tree.cpp b/src/syntax_analyser/abstract_syntax_tree.cpp index 319ced6..afcce01 100644 --- a/src/syntax_analyser/abstract_syntax_tree.cpp +++ b/src/syntax_analyser/abstract_syntax_tree.cpp @@ -118,6 +118,8 @@ std::vector> AbstractSyntaxTree::evaluateOperations( const Token& secondToken = static_cast(tokens[tokensIndex + 1].get()); + std::cout << secondToken.tokenType << "\n"; + if (secondToken.tokenType != TokenType::NUMBER && secondToken.tokenType != TokenType::IDENTIFIER) { throw std::runtime_error( @@ -130,6 +132,9 @@ std::vector> AbstractSyntaxTree::evaluateOperations( std::make_unique(outputIdentifier), std::make_unique( (static_cast(secondToken)).value))); + + std::cout << outputIdentifier << " + " + << (static_cast(secondToken)).value << "\n"; } if (secondToken.tokenType == TokenType::IDENTIFIER) { @@ -155,8 +160,10 @@ Program AbstractSyntaxTree::parse() { const Token& token = this->tokenContainer.view(i); buffer.push_back(token); + std::cout << "Reading " << token.tokenType << std::endl; if (token.tokenType == TokenType::END_OF_LINE) { + std::cout << "Reading end of line\n"; if (buffer[0].get().tokenType == TokenType::PRIMITIVE && buffer[1].get().tokenType == TokenType::IDENTIFIER && buffer[2].get().tokenType == TokenType::OPERATOR) { @@ -239,5 +246,6 @@ Program AbstractSyntaxTree::parse() { buffer.clear(); } } + std::cout << "program size: " << program.size() << "\n"; return program; } \ No newline at end of file diff --git a/src/syntax_analyser/statement/addition/addition.hpp b/src/syntax_analyser/statement/addition/addition.hpp index ef2bcf7..e94c873 100644 --- a/src/syntax_analyser/statement/addition/addition.hpp +++ b/src/syntax_analyser/statement/addition/addition.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "syntax_analyser/statement/statement.hpp" #include "syntax_analyser/statement/value/identifier/identifier.hpp" diff --git a/src/syntax_analyser/statement/print/print.hpp b/src/syntax_analyser/statement/print/print.hpp index 6478fcc..77944b0 100644 --- a/src/syntax_analyser/statement/print/print.hpp +++ b/src/syntax_analyser/statement/print/print.hpp @@ -1,8 +1,8 @@ #pragma once -#include +#include "syntax_analyser/statement/assignment/assignment_type.hpp" #include "syntax_analyser/statement/statement.hpp" -#include "syntax_analyser/statement/value/value.hpp" +#include "syntax_analyser/statement/value/identifier/identifier.hpp" class PrintStatement : public Statement { public: diff --git a/tests/system.cpp b/tests/system.cpp deleted file mode 100644 index b231b0b..0000000 --- a/tests/system.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include - -#include "generation/generator.hpp" -#include "io/file_reader.hpp" -#include -#include -#include -#include -#include -#include -#include - -class CompilerBuildListener : public Catch::EventListenerBase { -public: - using Catch::EventListenerBase::EventListenerBase; - void testRunStarting(const Catch::TestRunInfo& testRunInfo) override { - if (std::filesystem::exists("./bin/main")) { - return; - } - std::cerr << "Compiler not found"; - std::exit(1); - } -}; - -CATCH_REGISTER_LISTENER(CompilerBuildListener) - -std::string exec(std::string cmd) { - std::array buffer; - std::string result; - - std::unique_ptr pipe(popen(cmd.c_str(), "r"), - pclose); - - while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { - result += buffer.data(); - } - return result; -} - -void checkOutput(std::string filePath, std::string expectedOut) {} - -TEST_CASE("Run \"./examples/addition.lang\"", "[system]") { - std::system("./bin/main ./examples/addition.lang"); - int out = std::system("./main.out"); - REQUIRE(out != -1); - REQUIRE(WIFEXITED(out)); - REQUIRE(WEXITSTATUS(out) == 5); -}; - -TEST_CASE("Run \"./examples/integer_primitives.lang\"", "[system]") { - std::system("./bin/main ./examples/integer_primitives.lang"); - int out = std::system("./main.out"); - REQUIRE(out != -1); - REQUIRE(WIFEXITED(out)); - REQUIRE(WEXITSTATUS(out) == 0); -}; - -TEST_CASE("Run \"./examples/print.lang\"", "[system]") { - std::system("./bin/main ./examples/print.lang"); - std::string out = exec("./main.out"); - - REQUIRE(out == "1\n2\n"); -}; - -TEST_CASE("Run \"./examples/transitive_assignment.lang\"", "[system]") { - std::system("./bin/main ./examples/transitive_assignment.lang"); - int out = std::system("./main.out"); - - REQUIRE(out != -1); - REQUIRE(WIFEXITED(out)); - REQUIRE(WEXITSTATUS(out) == 1); -}; - -TEST_CASE("Run \"./examples/variable_declaration.lang\"", "[system]") { - std::system("./bin/main ./examples/variable_declaration.lang"); - int out = std::system("./main.out"); - - REQUIRE(out != -1); - REQUIRE(WIFEXITED(out)); - REQUIRE(WEXITSTATUS(out) == 1); -};