WIP: codegen backend #4
7
.editorconfig
Normal file
7
.editorconfig
Normal file
|
@ -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
|
|
@ -1,21 +1,26 @@
|
||||||
cmake_minimum_required(VERSION 3.21)
|
cmake_minimum_required(VERSION 3.21)
|
||||||
project(Erythro C)
|
project(Erythro C CXX)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
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)
|
include_directories(include)
|
||||||
|
|
||||||
add_executable(Erythro
|
set(ERYTHRO_SRC
|
||||||
include/Data.h
|
src/Assembler.c
|
||||||
include/Defs.h
|
src/Delegate.c
|
||||||
src/Assembler.c
|
src/Dump.c
|
||||||
src/Delegate.c
|
src/Lexer.c
|
||||||
src/Dump.c
|
src/Main.c
|
||||||
src/Lexer.c
|
src/Parser.c
|
||||||
src/Main.c
|
src/Pointers.c
|
||||||
src/Parser.c
|
src/Statements.c
|
||||||
src/Pointers.c
|
src/Symbols.c
|
||||||
src/Statements.c
|
src/Types.c
|
||||||
src/Symbols.c
|
src/Importer.c
|
||||||
src/Types.c
|
)
|
||||||
src/Importer.c)
|
|
||||||
|
add_executable(eryc ${ERYTHRO_SRC})
|
||||||
|
|
102
include/codegen/IGenerator.hh
Normal file
102
include/codegen/IGenerator.hh
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*************/
|
||||||
|
/*GEMWIRE */
|
||||||
|
/* ERYTHRO*/
|
||||||
|
/*************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <Defs.h>
|
||||||
|
|
||||||
|
//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;
|
||||||
|
};
|
||||||
|
|
|
@ -12,13 +12,18 @@
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The function of the importer is to read in definitions from a file, and store
|
* The function of the importer is to read in definitions from a file, and store
|
||||||
* them into the symbol tables.
|
* them into the symbol tables.
|
||||||
*
|
*
|
||||||
* The file to be imported is called a "module", which is Erythro terminology for C-like "headers".
|
* 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.
|
* 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
|
* 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.
|
* 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.
|
* Read in the information of a module, check that it is valid, and then read the module itself.
|
||||||
* Import syntax looks like:
|
* Import syntax looks like:
|
||||||
*
|
*
|
||||||
* > import "file"
|
* > import "file"
|
||||||
*
|
*
|
||||||
* The string is appended to the current working directory and is checked.
|
* 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.
|
* 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
|
* Modules may not contain definitions. Only declarations
|
||||||
* TODO: Module metadata as described above.
|
* TODO: Module metadata as described above.
|
||||||
*/
|
*/
|
||||||
|
@ -44,7 +49,7 @@
|
||||||
Tokenise();
|
Tokenise();
|
||||||
|
|
||||||
// Make sure there's a string after the import.
|
// 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.");
|
Die("Import statement must be followed by a compile-time constant string.");
|
||||||
|
|
||||||
// Read in the string that we know must be there.
|
// Read in the string that we know must be there.
|
||||||
|
@ -53,9 +58,9 @@
|
||||||
// Figure out the working directory
|
// Figure out the working directory
|
||||||
char CWD[PATH_MAX];
|
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);
|
DieMessage("Unable to find cwd when importing module", Module);
|
||||||
|
|
||||||
// Append the module name to the current working directory
|
// Append the module name to the current working directory
|
||||||
char* ModulePath = malloc(sizeof(CWD) + sizeof(Module) + 1);
|
char* ModulePath = malloc(sizeof(CWD) + sizeof(Module) + 1);
|
||||||
strcpy(ModulePath, CWD);
|
strcpy(ModulePath, CWD);
|
||||||
|
@ -65,7 +70,7 @@
|
||||||
|
|
||||||
// Stat the file to see if it exists
|
// Stat the file to see if it exists
|
||||||
struct stat FileInfo;
|
struct stat FileInfo;
|
||||||
if (stat(ModulePath, &FileInfo) != 0)
|
if (stat(ModulePath, &FileInfo) != 0)
|
||||||
DieMessage("Unable to access the imported module", ModulePath);
|
DieMessage("Unable to access the imported module", ModulePath);
|
||||||
|
|
||||||
// At this point, the file exists and we have the path.
|
// At this point, the file exists and we have the path.
|
||||||
|
@ -77,7 +82,7 @@
|
||||||
memset(ModuleData, 0, sizeof(struct FileData));
|
memset(ModuleData, 0, sizeof(struct FileData));
|
||||||
ModuleData->AllowDefinitions = false;
|
ModuleData->AllowDefinitions = false;
|
||||||
ModuleData->SourceName = ModulePath;
|
ModuleData->SourceName = ModulePath;
|
||||||
|
|
||||||
printf("Swapping to module %s..\n\n", ModulePath);
|
printf("Swapping to module %s..\n\n", ModulePath);
|
||||||
|
|
||||||
// Parse all relevant data from the module file...
|
// Parse all relevant data from the module file...
|
||||||
|
@ -99,4 +104,4 @@
|
||||||
// Tokenise past the string we just parsed
|
// Tokenise past the string we just parsed
|
||||||
Tokenise();
|
Tokenise();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
0
src/codegen/Codegen.cc
Normal file
0
src/codegen/Codegen.cc
Normal file
Loading…
Reference in New Issue
Block a user