diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3d24d30 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/CMakeLists.txt b/CMakeLists.txt index 21726e3..8759ee9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,21 +1,26 @@ cmake_minimum_required(VERSION 3.21) -project(Erythro C) +project(Erythro C CXX) set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include_directories(include) -add_executable(Erythro - include/Data.h - include/Defs.h - src/Assembler.c - src/Delegate.c - src/Dump.c - src/Lexer.c - src/Main.c - src/Parser.c - src/Pointers.c - src/Statements.c - src/Symbols.c - src/Types.c - src/Importer.c) +set(ERYTHRO_SRC + src/Assembler.c + src/Delegate.c + src/Dump.c + src/Lexer.c + src/Main.c + src/Parser.c + src/Pointers.c + src/Statements.c + src/Symbols.c + src/Types.c + src/Importer.c +) + +add_executable(eryc ${ERYTHRO_SRC}) diff --git a/include/codegen/IGenerator.hh b/include/codegen/IGenerator.hh new file mode 100644 index 0000000..411a59e --- /dev/null +++ b/include/codegen/IGenerator.hh @@ -0,0 +1,102 @@ +/*************/ +/*GEMWIRE */ +/* ERYTHRO*/ +/*************/ + +#pragma once + +#include +#include + +//Note(anita): Should I make a virtal register to deal with the translation +// should I also do the samething with the instructions like I did +// with pasm? +class IGenerator { + private: + std::string buffer; + + public: + virtual auto gen_deallocate_all_register() -> void = 0; + virtual auto gen_retrieve_register() -> int = 0; + virtual auto gen_primitive_size(int type) -> int = 0; + + virtual auto gen_align_memory(int type, int offset, int Direction) -> int = 0; + + virtual auto gen_load(int value) -> int = 0; + + virtual auto gen_add(int left, int right) -> int = 0; + virtual auto gen_mul(int left, int right) -> int = 0; + virtual auto gen_sub(int left, int right) -> int = 0; + virtual auto gen_div(int left, int right) -> int = 0; + + virtual auto gen_load_global_variable(SymbolTableEntry* table, int operation) -> int = 0; + virtual auto gen_load_local_variable(SymbolTableEntry* table, int operation) -> int = 0; + + virtual auto gen_str_global_var(SymbolTableEntry* table, int Register) -> int = 0; + virtual auto gen_str_local_var(SymbolTableEntry* table, int Register) -> int = 0; + + virtual auto gen_calculate_offset(int type) -> int = 0; + + virtual auto gen_new_stackframe() -> int = 0; + + virtual auto gen_dereference(int reg, int type) -> int = 0; + virtual auto gen_str_dereference(int reg_1, int reg_2) -> int = 0; + + virtual auto gen_address(SymbolTableEntry* entry) -> int = 0; + virtual auto gen_global_symbol(SymbolTableEntry* entry) -> int = 0; + + virtual auto gen_new_string(char* value) -> int = 0; + virtual auto gen_load_string(int id) -> int = 0; + + virtual auto gen_equal(int left, int right) -> int = 0; + virtual auto gen_if_not_equal(int left, int right) -> int = 0; + virtual auto gen_less_than(int left, int right) -> int = 0; + virtual auto gen_less_equal_than(int left, int right) -> int = 0; + virtual auto gen_greater_than(int left, int right) -> int = 0; + virtual auto gen_greater_equal_than(int left, int right) -> int = 0; + + virtual auto gen_bitwise_and(int left, int right) -> int = 0; + virtual auto gen_bitwise_or(int left, int right) -> int = 0; + virtual auto gen_bitwise_xor(int left, int right) -> int = 0; + + virtual auto gen_negate(int reg) -> int = 0; + virtual auto gen_invert(int reg) -> int = 0; + + virtual auto gen_boolean_not(int reg) -> int = 0; + + virtual auto gen_shift_left(int left, int right) -> int = 0; + virtual auto gen_shift_right(int left, int right) -> int = 0; + + virtual auto gen_boolean_convert(int reg, int operation, int label) -> int = 0; + + virtual auto gen_compare(int operation, int reg_left, int reg_right) -> int = 0; + virtual auto gen_compare_jmp(int operation, int reg_left, int reg_right, int label) -> int = 0; + + virtual auto gen_if(ASTNode* node, int loop_start_lable, int loop_end_label) -> int = 0; + + virtual auto gen_new_label() -> int = 0; + + virtual auto gen_jmp(int label) -> int = 0; + virtual auto gen_label(int label) -> int = 0; + + //Shift left + virtual auto gen_shift_L(int reg, int val) -> int = 0; + + virtual auto gen_return(SymbolTableEntry* entry, int reg) -> int = 0; + + virtual auto gen_call_wrapper(ASTNode* node) -> int = 0; + + virtual auto gen_copy_args(int reg, int pos) -> int = 0; + + virtual auto gen_call(SymbolTableEntry* entry, int args) -> int = 0; + + virtual auto gen_while(ASTNode* node) -> int = 0; + + //Fixme(anita): This is a hack do a proper call to the systems libcs + virtual auto gen_hack_printf(int reg) -> int = 0; + + virtual auto gen_preamble() -> int = 0; + virtual auto gen_function_preamble() -> int = 0; + virtual auto gen_function_epilogue() -> int = 0; +}; + diff --git a/src/Importer.c b/src/Importer.c index 40b7c4f..29f2983 100644 --- a/src/Importer.c +++ b/src/Importer.c @@ -12,13 +12,18 @@ #include #include +#ifdef __APPLE__ +#include +#endif + + /** * The function of the importer is to read in definitions from a file, and store * them into the symbol tables. - * + * * The file to be imported is called a "module", which is Erythro terminology for C-like "headers". * They contain extra metadata that allows for Erythro's enhanced debugging and error logging. - * + * * Modules may also contain metadata about the contents within - allowing for multiple compile-time * sourcesets with different arguments, all parsed at the same time as the source code. * @@ -30,12 +35,12 @@ /** * Read in the information of a module, check that it is valid, and then read the module itself. * Import syntax looks like: - * + * * > import "file" * * The string is appended to the current working directory and is checked. * If the resulting path exists and resolves to a file, then the file's declarations are added to the symbol tables. - * + * * Modules may not contain definitions. Only declarations * TODO: Module metadata as described above. */ @@ -44,7 +49,7 @@ Tokenise(); // Make sure there's a string after the import. - if (CurrentFile->CurrentSymbol.type != LI_STR) + if (CurrentFile->CurrentSymbol.type != LI_STR) Die("Import statement must be followed by a compile-time constant string."); // Read in the string that we know must be there. @@ -53,9 +58,9 @@ // Figure out the working directory char CWD[PATH_MAX]; - if (getcwd(CWD, sizeof(CWD)) == NULL) + if (getcwd(CWD, sizeof(CWD)) == NULL) DieMessage("Unable to find cwd when importing module", Module); - + // Append the module name to the current working directory char* ModulePath = malloc(sizeof(CWD) + sizeof(Module) + 1); strcpy(ModulePath, CWD); @@ -65,7 +70,7 @@ // Stat the file to see if it exists struct stat FileInfo; - if (stat(ModulePath, &FileInfo) != 0) + if (stat(ModulePath, &FileInfo) != 0) DieMessage("Unable to access the imported module", ModulePath); // At this point, the file exists and we have the path. @@ -77,7 +82,7 @@ memset(ModuleData, 0, sizeof(struct FileData)); ModuleData->AllowDefinitions = false; ModuleData->SourceName = ModulePath; - + printf("Swapping to module %s..\n\n", ModulePath); // Parse all relevant data from the module file... @@ -99,4 +104,4 @@ // Tokenise past the string we just parsed Tokenise(); - } \ No newline at end of file + } diff --git a/src/codegen/Codegen.cc b/src/codegen/Codegen.cc new file mode 100644 index 0000000..e69de29