added backend lib
This commit is contained in:
parent
a3e3e25e18
commit
16fcd6c8e2
|
@ -0,0 +1,72 @@
|
||||||
|
|
||||||
|
#include <codegen/backend.h>
|
||||||
|
#include <sys/log.h>
|
||||||
|
|
||||||
|
static struct CodegenBackend_t {
|
||||||
|
codegen_init init_func;
|
||||||
|
codegen_deinit deinit_func;
|
||||||
|
codegen codegen_func;
|
||||||
|
const char* name;
|
||||||
|
} CodegenBackend;
|
||||||
|
|
||||||
|
BackendError init_backend(void) {
|
||||||
|
DEBUG("initializing backend: %s", CodegenBackend.name);
|
||||||
|
|
||||||
|
if (CodegenBackend.init_func == NULL) {
|
||||||
|
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
||||||
|
return NoBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t code = CodegenBackend.init_func();
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
ERROR("failed to initialize backend: %s with code: %ld", CodegenBackend.name, code);
|
||||||
|
return Other;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError deinit_backend(void) {
|
||||||
|
DEBUG("undoing initializing of backend: %s", CodegenBackend.name);
|
||||||
|
|
||||||
|
if (CodegenBackend.deinit_func == NULL) {
|
||||||
|
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
||||||
|
return NoBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t code = CodegenBackend.deinit_func();
|
||||||
|
|
||||||
|
if (code) {
|
||||||
|
ERROR("failed to undo initialization of backend: %s with code: %ld", CodegenBackend.name, code);
|
||||||
|
return Other;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError set_backend(const codegen_init init_func, const codegen_deinit deinit_func, const codegen codegen_func, const char* name) {
|
||||||
|
CodegenBackend.init_func = init_func;
|
||||||
|
CodegenBackend.deinit_func = deinit_func;
|
||||||
|
CodegenBackend.codegen_func = codegen_func;
|
||||||
|
CodegenBackend.name = name;
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
BackendError generate_code(const AST_NODE_PTR root, void** output) {
|
||||||
|
DEBUG("generating code with backend: %s", CodegenBackend.name);
|
||||||
|
|
||||||
|
if (CodegenBackend.codegen_func == NULL) {
|
||||||
|
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
||||||
|
return NoBackend;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t code = CodegenBackend.codegen_func(root, output);
|
||||||
|
if (code) {
|
||||||
|
ERROR("code generation of backend: %s failed with code: %ld", CodegenBackend.name, code);
|
||||||
|
return Other;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
|
||||||
|
#ifndef CODEGN_BACKEND_H_
|
||||||
|
#define CODEGN_BACKEND_H_
|
||||||
|
|
||||||
|
#include <ast/ast.h>
|
||||||
|
|
||||||
|
typedef enum BackendError_t {
|
||||||
|
Success,
|
||||||
|
NoBackend,
|
||||||
|
BackendAlreadySet,
|
||||||
|
Other
|
||||||
|
} BackendError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function called by the compiler backend to generate an intermediate format
|
||||||
|
* from AST. Returns a custom container for its intermediate language.
|
||||||
|
*/
|
||||||
|
typedef size_t (*codegen)(const AST_NODE_PTR, void**);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the code generation backend.
|
||||||
|
*/
|
||||||
|
typedef size_t (*codegen_init)(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Undo initialization of code generation backend.
|
||||||
|
*/
|
||||||
|
typedef size_t (*codegen_deinit)(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the backend functions to use
|
||||||
|
*
|
||||||
|
* @param init_func the function to call for initializing the backend
|
||||||
|
* @param deinit_func the function to call for undoing the initialization of the backend
|
||||||
|
* @param codegen_func the function to call when generating code
|
||||||
|
* @param name name of the backend
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
[[gnu::nonnull(1), gnu::nonnull(2), gnu::nonnull(3), gnu::nonnull(3)]]
|
||||||
|
BackendError set_backend(const codegen_init init_func, const codegen_deinit deinit_func, const codegen codegen_func, const char* name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Call the initialization function of the backend
|
||||||
|
*
|
||||||
|
* @return BackendError
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
BackendError init_backend(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Call the undo initialization function of the backend
|
||||||
|
*
|
||||||
|
* @return BackendError
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
BackendError deinit_backend(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate intermediate code with the registered backend
|
||||||
|
*
|
||||||
|
* @param root the root node of the AST
|
||||||
|
* @param code output pointer to the intermediate code
|
||||||
|
* @return BackendError
|
||||||
|
*/
|
||||||
|
[[nodiscard]]
|
||||||
|
BackendError generate_code(const AST_NODE_PTR root, void** code);
|
||||||
|
|
||||||
|
#endif // CODEGN_BACKEND_H_
|
|
@ -4,6 +4,7 @@
|
||||||
#include <yacc/parser.tab.h>
|
#include <yacc/parser.tab.h>
|
||||||
#include <sys/col.h>
|
#include <sys/col.h>
|
||||||
#include <lex/util.h>
|
#include <lex/util.h>
|
||||||
|
#include <codegen/backend.h>
|
||||||
|
|
||||||
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
||||||
|
|
||||||
|
@ -75,6 +76,14 @@ int main(int argc, char *argv[]) {
|
||||||
root = AST_new_node(AST_Module, NULL);
|
root = AST_new_node(AST_Module, NULL);
|
||||||
yyparse();
|
yyparse();
|
||||||
|
|
||||||
|
set_backend(NULL, NULL, NULL, "LLVM");
|
||||||
|
|
||||||
|
init_backend();
|
||||||
|
|
||||||
|
generate_code(root, NULL);
|
||||||
|
|
||||||
|
deinit_backend();
|
||||||
|
|
||||||
FILE *output = fopen("test.txt", "w");
|
FILE *output = fopen("test.txt", "w");
|
||||||
AST_fprint_graphviz(output, root);
|
AST_fprint_graphviz(output, root);
|
||||||
fclose(output);
|
fclose(output);
|
||||||
|
|
Loading…
Reference in New Issue