added function backend
This commit is contained in:
parent
1e60890919
commit
2804fd552b
|
@ -9,22 +9,35 @@ static struct CodegenBackend_t {
|
||||||
const char* name;
|
const char* name;
|
||||||
} CodegenBackend;
|
} CodegenBackend;
|
||||||
|
|
||||||
|
BackendError new_backend_error(BackendErrorKind kind) {
|
||||||
|
return new_backend_impl_error(kind, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
BackendError init_backend(void) {
|
||||||
DEBUG("initializing backend: %s", CodegenBackend.name);
|
DEBUG("initializing backend: %s", CodegenBackend.name);
|
||||||
|
|
||||||
if (CodegenBackend.init_func == NULL) {
|
if (CodegenBackend.init_func == NULL) {
|
||||||
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
||||||
return NoBackend;
|
return new_backend_error(NoBackend);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t code = CodegenBackend.init_func();
|
BackendError code = CodegenBackend.init_func();
|
||||||
|
|
||||||
if (code) {
|
if (code.kind != Success) {
|
||||||
ERROR("failed to initialize backend: %s with code: %ld", CodegenBackend.name, code);
|
ERROR("failed to initialize backend: %s with code: %ld", CodegenBackend.name, code);
|
||||||
return Other;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
return new_backend_error(Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendError deinit_backend(void) {
|
BackendError deinit_backend(void) {
|
||||||
|
@ -32,17 +45,17 @@ BackendError deinit_backend(void) {
|
||||||
|
|
||||||
if (CodegenBackend.deinit_func == NULL) {
|
if (CodegenBackend.deinit_func == NULL) {
|
||||||
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
||||||
return NoBackend;
|
return new_backend_error(NoBackend);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t code = CodegenBackend.deinit_func();
|
BackendError code = CodegenBackend.deinit_func();
|
||||||
|
|
||||||
if (code) {
|
if (code.kind != Success) {
|
||||||
ERROR("failed to undo initialization of backend: %s with code: %ld", CodegenBackend.name, code);
|
ERROR("failed to undo initialization of backend: %s with code: %ld", CodegenBackend.name, code);
|
||||||
return Other;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
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) {
|
BackendError set_backend(const codegen_init init_func, const codegen_deinit deinit_func, const codegen codegen_func, const char* name) {
|
||||||
|
@ -51,7 +64,7 @@ BackendError set_backend(const codegen_init init_func, const codegen_deinit dein
|
||||||
CodegenBackend.codegen_func = codegen_func;
|
CodegenBackend.codegen_func = codegen_func;
|
||||||
CodegenBackend.name = name;
|
CodegenBackend.name = name;
|
||||||
|
|
||||||
return Success;
|
return new_backend_error(Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
BackendError generate_code(const AST_NODE_PTR root, void** output) {
|
BackendError generate_code(const AST_NODE_PTR root, void** output) {
|
||||||
|
@ -59,14 +72,14 @@ BackendError generate_code(const AST_NODE_PTR root, void** output) {
|
||||||
|
|
||||||
if (CodegenBackend.codegen_func == NULL) {
|
if (CodegenBackend.codegen_func == NULL) {
|
||||||
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
ERROR("backend: %s is not properly initialized", CodegenBackend.name);
|
||||||
return NoBackend;
|
return new_backend_error(NoBackend);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t code = CodegenBackend.codegen_func(root, output);
|
BackendError code = CodegenBackend.codegen_func(root, output);
|
||||||
if (code) {
|
if (code.kind) {
|
||||||
ERROR("code generation of backend: %s failed with code: %ld", CodegenBackend.name, code);
|
ERROR("code generation of backend: %s failed with code: %ld", CodegenBackend.name, code);
|
||||||
return Other;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
return new_backend_error(Success);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,28 +4,42 @@
|
||||||
|
|
||||||
#include <ast/ast.h>
|
#include <ast/ast.h>
|
||||||
|
|
||||||
typedef enum BackendError_t {
|
typedef struct BackendImplError_t {
|
||||||
|
// faulty AST node
|
||||||
|
AST_NODE_PTR ast_node;
|
||||||
|
// error message
|
||||||
|
const char* message;
|
||||||
|
} BackendImplError;
|
||||||
|
|
||||||
|
typedef enum BackendErrorKind_t {
|
||||||
Success,
|
Success,
|
||||||
NoBackend,
|
NoBackend,
|
||||||
BackendAlreadySet,
|
BackendAlreadySet,
|
||||||
Other
|
Unimplemented,
|
||||||
|
// some error occurred in the backend implementation
|
||||||
|
Implementation
|
||||||
|
} BackendErrorKind;
|
||||||
|
|
||||||
|
typedef struct BackendError_t {
|
||||||
|
BackendErrorKind kind;
|
||||||
|
BackendImplError impl;
|
||||||
} BackendError;
|
} BackendError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function called by the compiler backend to generate an intermediate format
|
* @brief Function called by the compiler backend to generate an intermediate format
|
||||||
* from AST. Returns a custom container for its intermediate language.
|
* from AST. Returns a custom container for its intermediate language.
|
||||||
*/
|
*/
|
||||||
typedef size_t (*codegen)(const AST_NODE_PTR, void**);
|
typedef BackendError (*codegen)(const AST_NODE_PTR, void**);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the code generation backend.
|
* @brief Initialize the code generation backend.
|
||||||
*/
|
*/
|
||||||
typedef size_t (*codegen_init)(void);
|
typedef BackendError (*codegen_init)(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Undo initialization of code generation backend.
|
* @brief Undo initialization of code generation backend.
|
||||||
*/
|
*/
|
||||||
typedef size_t (*codegen_deinit)(void);
|
typedef BackendError (*codegen_deinit)(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the backend functions to use
|
* @brief Set the backend functions to use
|
||||||
|
@ -65,4 +79,14 @@ BackendError deinit_backend(void);
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
BackendError generate_code(const AST_NODE_PTR root, void** code);
|
BackendError generate_code(const AST_NODE_PTR root, void** code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a new backend error
|
||||||
|
*
|
||||||
|
* @param kind must ne != Implementation
|
||||||
|
* @return BackendError
|
||||||
|
*/
|
||||||
|
BackendError new_backend_error(BackendErrorKind kind);
|
||||||
|
|
||||||
|
BackendError new_backend_impl_error(BackendErrorKind kind, AST_NODE_PTR node, const char* message);
|
||||||
|
|
||||||
#endif // CODEGN_BACKEND_H_
|
#endif // CODEGN_BACKEND_H_
|
||||||
|
|
|
@ -10,7 +10,7 @@ typedef enum LLVMBackendError_t {
|
||||||
UnresolvedImport
|
UnresolvedImport
|
||||||
} LLVMBackendError;
|
} LLVMBackendError;
|
||||||
|
|
||||||
static size_t llvm_backend_codegen(const AST_NODE_PTR, void**) {
|
static BackendError llvm_backend_codegen(const AST_NODE_PTR, void**) {
|
||||||
// we start with a LLVM module
|
// we start with a LLVM module
|
||||||
LLVMContextRef context = LLVMContextCreate();
|
LLVMContextRef context = LLVMContextCreate();
|
||||||
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("gemstone application", context);
|
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("gemstone application", context);
|
||||||
|
@ -20,21 +20,21 @@ static size_t llvm_backend_codegen(const AST_NODE_PTR, void**) {
|
||||||
LLVMDisposeModule(module);
|
LLVMDisposeModule(module);
|
||||||
LLVMContextDispose(context);
|
LLVMContextDispose(context);
|
||||||
|
|
||||||
return Success;
|
return new_backend_error(Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t llvm_backend_codegen_init(void) {
|
static BackendError llvm_backend_codegen_init(void) {
|
||||||
return Success;
|
return new_backend_error(Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t llvm_backend_codegen_deinit(void) {
|
static BackendError llvm_backend_codegen_deinit(void) {
|
||||||
return Success;
|
return new_backend_error(Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
void llvm_backend_init() {
|
void llvm_backend_init() {
|
||||||
BackendError err = set_backend(&llvm_backend_codegen_init, &llvm_backend_codegen_deinit, &llvm_backend_codegen, "LLVM");
|
BackendError err = set_backend(&llvm_backend_codegen_init, &llvm_backend_codegen_deinit, &llvm_backend_codegen, "LLVM");
|
||||||
|
|
||||||
if (err != Success) {
|
if (err.kind != Success) {
|
||||||
PANIC("unable to init llvm backend: %ld", err);
|
PANIC("unable to init llvm backend: %ld", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
|
||||||
|
#include "ast/ast.h"
|
||||||
|
#include <llvm/function/function.h>
|
||||||
|
#include <llvm/types/type.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static enum IO_Qualifier_t io_qualifier_from_string(const char* str) {
|
||||||
|
if (strcmp(str, "in") == 0) {
|
||||||
|
return In;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum IO_Qualifier_t merge_qualifier(enum IO_Qualifier_t a, enum IO_Qualifier_t b) {
|
||||||
|
enum IO_Qualifier_t result = Unspec;
|
||||||
|
|
||||||
|
if (a == In && b == Out) {
|
||||||
|
result = InOut;
|
||||||
|
} else if (a == Out && b == In) {
|
||||||
|
result = InOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum IO_Qualifier_t io_qualifier_from_ast_list(const AST_NODE_PTR node) {
|
||||||
|
// node is expected to be a list
|
||||||
|
if (node->kind != AST_List) {
|
||||||
|
PANIC("Node must be of type AST_List: %s", AST_node_to_string(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum IO_Qualifier_t qualifier = Unspec;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < node->child_count; i++) {
|
||||||
|
|
||||||
|
AST_NODE_PTR qualifier_node = AST_get_node(node, i);
|
||||||
|
|
||||||
|
if (qualifier_node->kind != AST_Qualifyier) {
|
||||||
|
PANIC("Node must be of type AST_Qualifyier: %s", AST_node_to_string(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum IO_Qualifier_t local_qualifier = io_qualifier_from_string(qualifier_node->value);
|
||||||
|
|
||||||
|
if (qualifier == Unspec) {
|
||||||
|
qualifier = local_qualifier;
|
||||||
|
} else {
|
||||||
|
qualifier = merge_qualifier(qualifier, local_qualifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qualifier == Unspec)
|
||||||
|
qualifier = In;
|
||||||
|
|
||||||
|
return qualifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
GemstoneParam param_from_ast(const AST_NODE_PTR node) {
|
||||||
|
GemstoneParam param;
|
||||||
|
|
||||||
|
// node is expected to be a parameter
|
||||||
|
if (node->kind != AST_Parameter) {
|
||||||
|
PANIC("Node must be of type AST_ParamList: %s", AST_node_to_string(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_NODE_PTR qualifier_list = AST_get_node(node, 0);
|
||||||
|
param.qualifier = io_qualifier_from_ast_list(qualifier_list);
|
||||||
|
|
||||||
|
AST_NODE_PTR param_decl = AST_get_node(node, 1);
|
||||||
|
AST_NODE_PTR param_type = AST_get_node(param_decl, 0);
|
||||||
|
param.typename = get_type_from_ast(param_type);
|
||||||
|
param.name = AST_get_node(param_decl, 1)->value;
|
||||||
|
|
||||||
|
return param;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
#ifndef LLVM_FUNCTION_H_
|
||||||
|
#define LLVM_FUNCTION_H_
|
||||||
|
|
||||||
|
#include <ast/ast.h>
|
||||||
|
#include <llvm/types/type.h>
|
||||||
|
|
||||||
|
enum IO_Qualifier_t {
|
||||||
|
Unspec,
|
||||||
|
In,
|
||||||
|
Out,
|
||||||
|
InOut
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct GemstoneParam_t {
|
||||||
|
const char* name;
|
||||||
|
enum IO_Qualifier_t qualifier;
|
||||||
|
GemstoneType typename;
|
||||||
|
} GemstoneParam;
|
||||||
|
|
||||||
|
typedef struct GemstoneFun_t {
|
||||||
|
const char* name;
|
||||||
|
// TODO: add array of parameters
|
||||||
|
} GemstoneFun;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert an AST node into a function parameter struct
|
||||||
|
*
|
||||||
|
* @param node the node starting a function parameter
|
||||||
|
* @return GemstoneParam
|
||||||
|
*/
|
||||||
|
GemstoneParam param_from_ast(const AST_NODE_PTR node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert an AST node into a function
|
||||||
|
*
|
||||||
|
* @param node the node starting a function
|
||||||
|
* @return GemstoneFun
|
||||||
|
*/
|
||||||
|
GemstoneFun fun_from_ast(const AST_NODE_PTR node);
|
||||||
|
|
||||||
|
#endif // LLVM_FUNCTION_H_
|
|
@ -1,52 +1,8 @@
|
||||||
|
|
||||||
#include <ast/ast.h>
|
#include <llvm/types/composite.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/log.h>
|
|
||||||
#include <llvm-c/Core.h>
|
|
||||||
#include <llvm-c/Types.h>
|
|
||||||
|
|
||||||
#define BITS_PER_BYTE 8
|
LLVMTypeRef llvm_type_from_composite(LLVMContextRef context, const CompositeRef composite) {
|
||||||
|
|
||||||
enum Sign_t {
|
|
||||||
Signed,
|
|
||||||
Unsigned
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Precision_t {
|
|
||||||
ATOM = 1,
|
|
||||||
HALF = 2,
|
|
||||||
SINGLE = 4,
|
|
||||||
DOUBLE = 8,
|
|
||||||
QUAD = 16,
|
|
||||||
OCTO = 32
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Primitive_t {
|
|
||||||
Int,
|
|
||||||
Float
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct CompositeType_t {
|
|
||||||
const char* name;
|
|
||||||
enum Sign_t sign;
|
|
||||||
enum Precision_t scale;
|
|
||||||
enum Primitive_t prim;
|
|
||||||
} Composite;
|
|
||||||
|
|
||||||
typedef struct TypeScope_t {
|
|
||||||
// vector of composite data types
|
|
||||||
Composite* composites;
|
|
||||||
size_t composite_len;
|
|
||||||
size_t composite_cap;
|
|
||||||
} TypeScope;
|
|
||||||
|
|
||||||
Composite* get_composite_type(const char* name);
|
|
||||||
|
|
||||||
typedef struct CompositeType_t* COMPOSITE_REF;
|
|
||||||
|
|
||||||
#define INVALID_COMPOSITE NULL
|
|
||||||
|
|
||||||
LLVMTypeRef llvm_type_from_composite(LLVMContextRef context, const COMPOSITE_REF composite) {
|
|
||||||
DEBUG("converting composite to LLVM type...");
|
DEBUG("converting composite to LLVM type...");
|
||||||
|
|
||||||
LLVMTypeRef type = INVALID_COMPOSITE;
|
LLVMTypeRef type = INVALID_COMPOSITE;
|
||||||
|
@ -61,6 +17,7 @@ LLVMTypeRef llvm_type_from_composite(LLVMContextRef context, const COMPOSITE_REF
|
||||||
switch (composite->scale) {
|
switch (composite->scale) {
|
||||||
case HALF:
|
case HALF:
|
||||||
type = LLVMHalfTypeInContext(context);
|
type = LLVMHalfTypeInContext(context);
|
||||||
|
break;
|
||||||
case SINGLE:
|
case SINGLE:
|
||||||
type = LLVMDoubleTypeInContext(context);
|
type = LLVMDoubleTypeInContext(context);
|
||||||
break;
|
break;
|
||||||
|
@ -89,7 +46,7 @@ double get_scale_factor(const char* keyword) {
|
||||||
PANIC("invalid scale factor: %s", keyword);
|
PANIC("invalid scale factor: %s", keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Precision_t collapse_scale_list(const AST_NODE_PTR list) {
|
enum Scale_t collapse_scale_list(const AST_NODE_PTR list) {
|
||||||
double sum = 1.0;
|
double sum = 1.0;
|
||||||
|
|
||||||
for (size_t i = 0; i < list->child_count; i++) {
|
for (size_t i = 0; i < list->child_count; i++) {
|
||||||
|
@ -99,7 +56,7 @@ enum Precision_t collapse_scale_list(const AST_NODE_PTR list) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sum >= 1.0 && sum <= 32) {
|
if (sum >= 1.0 && sum <= 32) {
|
||||||
return (enum Precision_t) sum;
|
return (enum Scale_t) sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
PANIC("invalid combination of scale factors");
|
PANIC("invalid combination of scale factors");
|
||||||
|
@ -115,6 +72,18 @@ enum Sign_t string_to_sign(const char* keyword) {
|
||||||
PANIC("invalid sign: %s", keyword);
|
PANIC("invalid sign: %s", keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum Primitive_t resolve_primitive(const char* typename) {
|
||||||
|
|
||||||
|
if (strcmp(typename, "int") == 0) {
|
||||||
|
return Int;
|
||||||
|
} else if (strcmp(typename, "float") == 0) {
|
||||||
|
return Float;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: implement lookup of ident type
|
||||||
|
return Int;
|
||||||
|
}
|
||||||
|
|
||||||
struct CompositeType_t ast_type_to_composite(AST_NODE_PTR type) {
|
struct CompositeType_t ast_type_to_composite(AST_NODE_PTR type) {
|
||||||
size_t count = type->child_count;
|
size_t count = type->child_count;
|
||||||
|
|
||||||
|
@ -152,8 +121,7 @@ struct CompositeType_t ast_type_to_composite(AST_NODE_PTR type) {
|
||||||
composite.scale = collapse_scale_list(AST_get_node(type, 0));
|
composite.scale = collapse_scale_list(AST_get_node(type, 0));
|
||||||
composite.prim = resolve_primitive(AST_get_node(type, 2)->value);
|
composite.prim = resolve_primitive(AST_get_node(type, 2)->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return composite;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_builtin_types(LLVMContextRef context) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
#ifndef LLVM_TYPE_H_
|
||||||
|
#define LLVM_TYPE_H_
|
||||||
|
|
||||||
|
#include <ast/ast.h>
|
||||||
|
#include <sys/log.h>
|
||||||
|
#include <llvm-c/Core.h>
|
||||||
|
#include <llvm-c/Types.h>
|
||||||
|
|
||||||
|
#define BITS_PER_BYTE 8
|
||||||
|
|
||||||
|
enum Sign_t {
|
||||||
|
Signed,
|
||||||
|
Unsigned
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Scale_t {
|
||||||
|
ATOM = 1,
|
||||||
|
HALF = 2,
|
||||||
|
SINGLE = 4,
|
||||||
|
DOUBLE = 8,
|
||||||
|
QUAD = 16,
|
||||||
|
OCTO = 32
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Primitive_t {
|
||||||
|
Int,
|
||||||
|
Float
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct CompositeType_t {
|
||||||
|
const char* name;
|
||||||
|
enum Sign_t sign;
|
||||||
|
enum Scale_t scale;
|
||||||
|
enum Primitive_t prim;
|
||||||
|
} Composite;
|
||||||
|
|
||||||
|
typedef struct TypeScope_t {
|
||||||
|
// vector of composite data types
|
||||||
|
Composite* composites;
|
||||||
|
size_t composite_len;
|
||||||
|
size_t composite_cap;
|
||||||
|
} TypeScope;
|
||||||
|
|
||||||
|
typedef struct CompositeType_t* CompositeRef;
|
||||||
|
|
||||||
|
#define INVALID_COMPOSITE NULL
|
||||||
|
|
||||||
|
LLVMTypeRef llvm_type_from_composite(LLVMContextRef context, const CompositeRef composite);
|
||||||
|
|
||||||
|
struct CompositeType_t ast_type_to_composite(AST_NODE_PTR type);
|
||||||
|
|
||||||
|
#endif // LLVM_TYPE_H_
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
#include <llvm/types/composite.h>
|
||||||
|
#include <ast/ast.h>
|
||||||
|
#include <llvm/types/type.h>
|
||||||
|
|
||||||
|
GemstoneType get_type_from_ast(const AST_NODE_PTR type_node) {
|
||||||
|
if (type_node->kind != AST_Type) {
|
||||||
|
PANIC("Node must be of type AST_Type: %s", AST_node_to_string(type_node));
|
||||||
|
}
|
||||||
|
|
||||||
|
GemstoneType type;
|
||||||
|
|
||||||
|
if (type_node->child_count > 1) {
|
||||||
|
// must be composite
|
||||||
|
type.kind = TypeComposite;
|
||||||
|
type.specs.composite = ast_type_to_composite(type_node);
|
||||||
|
} else {
|
||||||
|
// either custom type or box
|
||||||
|
// TODO: resolve concrete type from TypeScope
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
|
||||||
|
#ifndef GEMSTONE_TYPE_H_
|
||||||
|
#define GEMSTONE_TYPE_H_
|
||||||
|
|
||||||
|
#include <ast/ast.h>
|
||||||
|
#include <llvm/types/composite.h>
|
||||||
|
|
||||||
|
enum GemstoneTypeKind_t {
|
||||||
|
TypeComposite,
|
||||||
|
TypeReference,
|
||||||
|
TypeBox
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GemstoneType_t;
|
||||||
|
|
||||||
|
typedef struct GemstoneRefType_t {
|
||||||
|
struct GemstoneType_t* type;
|
||||||
|
} GemstoneRefType;
|
||||||
|
|
||||||
|
typedef struct GemstoneType_t {
|
||||||
|
enum GemstoneTypeKind_t kind;
|
||||||
|
union GemstoneTypeSpecs_t {
|
||||||
|
Composite composite;
|
||||||
|
GemstoneRefType reference;
|
||||||
|
} specs;
|
||||||
|
} GemstoneType;
|
||||||
|
|
||||||
|
struct TypeScope_t;
|
||||||
|
|
||||||
|
typedef struct TypeScope_t {
|
||||||
|
// TODO: array of child scopes
|
||||||
|
// TODO: array of types
|
||||||
|
} TypeScope;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert a type declaration into a concrete type.
|
||||||
|
*
|
||||||
|
* @param type A type declaration (either identifier or composite)
|
||||||
|
* @return GemstoneType
|
||||||
|
*/
|
||||||
|
GemstoneType get_type_from_ast(const AST_NODE_PTR type);
|
||||||
|
|
||||||
|
#endif // GEMSTONE_TYPE_H_
|
29
src/main.c
29
src/main.c
|
@ -53,6 +53,24 @@ void setup(void) {
|
||||||
DEBUG("finished starting up gemstone...");
|
DEBUG("finished starting up gemstone...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void run_backend_codegen() {
|
||||||
|
llvm_backend_init();
|
||||||
|
|
||||||
|
BackendError err;
|
||||||
|
err = init_backend();
|
||||||
|
if (err.kind != Success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* code = NULL;
|
||||||
|
err = generate_code(root, &code);
|
||||||
|
if (err.kind != Success) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = deinit_backend();
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
setup();
|
setup();
|
||||||
|
@ -77,16 +95,9 @@ int main(int argc, char *argv[]) {
|
||||||
root = AST_new_node(AST_Module, NULL);
|
root = AST_new_node(AST_Module, NULL);
|
||||||
yyparse();
|
yyparse();
|
||||||
|
|
||||||
llvm_backend_init();
|
run_backend_codegen();
|
||||||
|
|
||||||
init_backend();
|
FILE *output = fopen("test.gv", "w");
|
||||||
|
|
||||||
void* code = NULL;
|
|
||||||
generate_code(root, &code);
|
|
||||||
|
|
||||||
deinit_backend();
|
|
||||||
|
|
||||||
FILE *output = fopen("test.txt", "w");
|
|
||||||
AST_fprint_graphviz(output, root);
|
AST_fprint_graphviz(output, root);
|
||||||
fclose(output);
|
fclose(output);
|
||||||
AST_delete_node(root);
|
AST_delete_node(root);
|
||||||
|
|
Loading…
Reference in New Issue