99 lines
2.8 KiB
C
99 lines
2.8 KiB
C
|
|
#include "set/types.h"
|
|
|
|
#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 new_backend_error(BackendErrorKind kind) {
|
|
BackendError error;
|
|
error.kind = kind;
|
|
error.impl.ast_node = NULL;
|
|
error.impl.message = NULL;
|
|
|
|
return error;
|
|
}
|
|
|
|
BackendError new_backend_impl_error(BackendErrorKind kind, AST_NODE_PTR node,
|
|
const char* message) {
|
|
BackendError error;
|
|
error.kind = kind;
|
|
error.impl.ast_node = node;
|
|
error.impl.message = message;
|
|
|
|
return error;
|
|
}
|
|
|
|
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 new_backend_error(NoBackend);
|
|
}
|
|
|
|
BackendError code = CodegenBackend.init_func();
|
|
|
|
if (code.kind != Success) {
|
|
ERROR("failed to initialize backend: %s with code: %ld",
|
|
CodegenBackend.name, code);
|
|
return code;
|
|
}
|
|
|
|
return new_backend_error(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 new_backend_error(NoBackend);
|
|
}
|
|
|
|
BackendError code = CodegenBackend.deinit_func();
|
|
|
|
if (code.kind != Success) {
|
|
ERROR("failed to undo initialization of backend: %s with code: %ld",
|
|
CodegenBackend.name, code);
|
|
return code;
|
|
}
|
|
|
|
return new_backend_error(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 new_backend_error(Success);
|
|
}
|
|
|
|
BackendError generate_code(const Module* root, const TargetConfig* target) {
|
|
DEBUG("generating code with backend: %s", CodegenBackend.name);
|
|
|
|
if (CodegenBackend.codegen_func == NULL) {
|
|
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
|
return new_backend_error(NoBackend);
|
|
}
|
|
|
|
BackendError code = CodegenBackend.codegen_func(root, target);
|
|
if (code.kind) {
|
|
ERROR("code generation of backend: %s failed with code: %ld `%s`",
|
|
CodegenBackend.name, code, code.impl.message);
|
|
return code;
|
|
}
|
|
|
|
return new_backend_error(Success);
|
|
}
|