added codegen backend

This commit is contained in:
Sven Vogel 2024-05-08 10:26:57 +02:00
parent 565d50b639
commit 572f779e70
3 changed files with 129 additions and 0 deletions

86
src/codegen/backend.c Normal file
View File

@ -0,0 +1,86 @@
//
// Created by servostar on 5/8/24.
//
#include <codegen/backend.h>
#include <stdlib.h>
#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);
}

40
src/codegen/backend.h Normal file
View File

@ -0,0 +1,40 @@
//
// Created by servostar on 5/8/24.
//
#ifndef LIB_H
#define LIB_H
#include <ast/ast.h>
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

View File

@ -2,6 +2,7 @@
#include <sys/log.h> #include <sys/log.h>
#include <yacc/parser.tab.h> #include <yacc/parser.tab.h>
#include <ast/ast.h> #include <ast/ast.h>
#include <codegen/backend.h>
#include <gc/gc.h> #include <gc/gc.h>
#define LOG_LEVEL LOG_LEVEL_DEBUG #define LOG_LEVEL LOG_LEVEL_DEBUG
@ -48,6 +49,8 @@ void setup(void)
// actual setup // actual setup
AST_init(); AST_init();
CG_init();
GC_init(); GC_init();
DEBUG("finished starting up gemstone..."); DEBUG("finished starting up gemstone...");