diff --git a/src/codegen/backend.c b/src/codegen/backend.c new file mode 100644 index 0000000..bb9a8e2 --- /dev/null +++ b/src/codegen/backend.c @@ -0,0 +1,86 @@ +// +// Created by servostar on 5/8/24. +// + +#include +#include + +#define TRUE 1 +#define FALSE 0 + +static CodegenResult __new_result(enum CodegenErrorCode code, char* message) { + const CodegenResult result = { + .code = code, + .message = message + }; + return result; +} + +static struct Codegen_Lib_t { + CodegenFunction codegen_function; + InitCodegenBackend init_function; + DeinitCodegenBackend deinit_function; + unsigned char initialized; +} CodegenLib; + +static CodegenResult __unimplemented() { + return __new_result(Unimplemented, "Backend not set"); +} + +static CodegenResult __default_codegen_function(AST_NODE_PTR _ptr, void** _out) { + return __unimplemented(); +} + +static CodegenResult __default_backend_init(void) { + return __unimplemented(); +} + +static CodegenResult __default_backend_deinit(void) { + return __unimplemented(); +} + +static void __deinit(void) { + if (CodegenLib.initialized && CodegenLib.deinit_function) { + CodegenLib.deinit_function(); + } +} + +void CG_init(void) { + CodegenLib.codegen_function = __default_codegen_function; + CodegenLib.init_function = __default_backend_init; + CodegenLib.deinit_function = __default_backend_deinit; + + atexit(__deinit); +} + +void CG_set_codegen_backend(InitCodegenBackend init, DeinitCodegenBackend deinit, CodegenFunction codegen) { + CodegenLib.codegen_function = codegen; + CodegenLib.init_function = init; + CodegenLib.deinit_function = deinit; +} + +CodegenResult CG_codegen(const AST_NODE_PTR ast, void** output) { + if (ast == NULL) { + return __new_result(InvalidAST, "AST is NULL"); + } + + if (output == NULL) { + return __new_result(NoOutputStorage, "Output pointer is NULL"); + } + + if (CodegenLib.codegen_function == NULL) { + return __new_result(NoBackend, "No code generation backend"); + } + + if (!CodegenLib.initialized && CodegenLib.init_function) { + const CodegenResult result = CodegenLib.init_function(); + + if (result.code != Sucess) { + return result; + } + + CodegenLib.initialized = TRUE; + } + + return CodegenLib.codegen_function(ast, output); +} \ No newline at end of file diff --git a/src/codegen/backend.h b/src/codegen/backend.h new file mode 100644 index 0000000..f63191d --- /dev/null +++ b/src/codegen/backend.h @@ -0,0 +1,40 @@ +// +// Created by servostar on 5/8/24. +// + +#ifndef LIB_H +#define LIB_H + +#include + +enum CodegenErrorCode { + Sucess, + Unimplemented, + InvalidAST, + NoBackend, + NoOutputStorage, + Error +}; + +typedef struct CodegenResult_t { + const enum CodegenErrorCode code; + const char* message; +} CodegenResult; + +// parses a syntax tree into intermediate representation +// and creates backend specific data structure +// returns a success code +typedef CodegenResult (*CodegenFunction) (const AST_NODE_PTR, void**); + +typedef CodegenResult (*InitCodegenBackend) (void); + +typedef CodegenResult (*DeinitCodegenBackend) (void); + +void CG_init(void); + +// Should only be called from a backend implementation +void CG_set_codegen_backend(InitCodegenBackend init, DeinitCodegenBackend deinit, CodegenFunction codegen); + +CodegenResult CG_codegen(AST_NODE_PTR, void**); + +#endif //LIB_H diff --git a/src/main.c b/src/main.c index 0b56d88..905d37f 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #define LOG_LEVEL LOG_LEVEL_DEBUG @@ -48,6 +49,8 @@ void setup(void) // actual setup AST_init(); + CG_init(); + GC_init(); DEBUG("finished starting up gemstone...");