added type interface
This commit is contained in:
parent
16fcd6c8e2
commit
1e60890919
|
@ -68,6 +68,18 @@ add_custom_command(OUTPUT ${YACC_GENERATED_SOURCE_FILE}
|
||||||
COMMENT "generate C source file for parser"
|
COMMENT "generate C source file for parser"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
|
# ------------------------------------------------ #
|
||||||
|
# LLVM backend #
|
||||||
|
# ------------------------------------------------ #
|
||||||
|
|
||||||
|
# Fetch LLVM link configuration
|
||||||
|
execute_process(COMMAND llvm-config --libs all
|
||||||
|
OUTPUT_VARIABLE LLVM_LIBS)
|
||||||
|
# Strip whitespace from output
|
||||||
|
string(STRIP "${LLVM_LIBS}" LLVM_LIBS)
|
||||||
|
# Link all targets to LLVM
|
||||||
|
link_libraries(${LLVM_LIBS})
|
||||||
|
|
||||||
# ------------------------------------------------ #
|
# ------------------------------------------------ #
|
||||||
# Source #
|
# Source #
|
||||||
# ------------------------------------------------ #
|
# ------------------------------------------------ #
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
#include <codegen/backend.h>
|
||||||
|
#include <sys/log.h>
|
||||||
|
#include <ast/ast.h>
|
||||||
|
#include <llvm/backend.h>
|
||||||
|
#include <llvm-c/Types.h>
|
||||||
|
#include <llvm-c/Core.h>
|
||||||
|
|
||||||
|
typedef enum LLVMBackendError_t {
|
||||||
|
UnresolvedImport
|
||||||
|
} LLVMBackendError;
|
||||||
|
|
||||||
|
static size_t llvm_backend_codegen(const AST_NODE_PTR, void**) {
|
||||||
|
// we start with a LLVM module
|
||||||
|
LLVMContextRef context = LLVMContextCreate();
|
||||||
|
LLVMModuleRef module = LLVMModuleCreateWithNameInContext("gemstone application", context);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LLVMDisposeModule(module);
|
||||||
|
LLVMContextDispose(context);
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t llvm_backend_codegen_init(void) {
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t llvm_backend_codegen_deinit(void) {
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void llvm_backend_init() {
|
||||||
|
BackendError err = set_backend(&llvm_backend_codegen_init, &llvm_backend_codegen_deinit, &llvm_backend_codegen, "LLVM");
|
||||||
|
|
||||||
|
if (err != Success) {
|
||||||
|
PANIC("unable to init llvm backend: %ld", err);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
#ifndef LLVM_CODEGEN_BACKEND_H_
|
||||||
|
#define LLVM_CODEGEN_BACKEND_H_
|
||||||
|
|
||||||
|
void llvm_backend_init(void);
|
||||||
|
|
||||||
|
#endif // LLVM_CODEGEN_BACKEND_H_
|
|
@ -0,0 +1,159 @@
|
||||||
|
|
||||||
|
#include <ast/ast.h>
|
||||||
|
#include <string.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 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...");
|
||||||
|
|
||||||
|
LLVMTypeRef type = INVALID_COMPOSITE;
|
||||||
|
|
||||||
|
if (composite->prim == Int) {
|
||||||
|
DEBUG("generating integer LLVM type...");
|
||||||
|
|
||||||
|
type = LLVMIntTypeInContext(context, composite->scale * BITS_PER_BYTE);
|
||||||
|
} else if (composite->prim == Float && composite->sign == Signed) {
|
||||||
|
DEBUG("generating float LLVM type...");
|
||||||
|
|
||||||
|
switch (composite->scale) {
|
||||||
|
case HALF:
|
||||||
|
type = LLVMHalfTypeInContext(context);
|
||||||
|
case SINGLE:
|
||||||
|
type = LLVMDoubleTypeInContext(context);
|
||||||
|
break;
|
||||||
|
case DOUBLE:
|
||||||
|
type = LLVMDoubleTypeInContext(context);
|
||||||
|
break;
|
||||||
|
case QUAD:
|
||||||
|
type = LLVMFP128TypeInContext(context);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERROR("Floating point of precision: %ld npt supported", composite->scale);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
double get_scale_factor(const char* keyword) {
|
||||||
|
if (strcmp(keyword, "half") == 0 || strcmp(keyword, "short") == 0) {
|
||||||
|
return 0.5;
|
||||||
|
} else if (strcmp(keyword, "double") == 0 || strcmp(keyword, "long") == 0) {
|
||||||
|
return 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PANIC("invalid scale factor: %s", keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Precision_t collapse_scale_list(const AST_NODE_PTR list) {
|
||||||
|
double sum = 1.0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < list->child_count; i++) {
|
||||||
|
AST_NODE_PTR scale = AST_get_node(list, i);
|
||||||
|
|
||||||
|
sum *= get_scale_factor(scale->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sum >= 1.0 && sum <= 32) {
|
||||||
|
return (enum Precision_t) sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
PANIC("invalid combination of scale factors");
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Sign_t string_to_sign(const char* keyword) {
|
||||||
|
if (strcmp(keyword, "signed") == 0) {
|
||||||
|
return Signed;
|
||||||
|
} else if (strcmp(keyword, "signed") == 0) {
|
||||||
|
return Unsigned;
|
||||||
|
}
|
||||||
|
|
||||||
|
PANIC("invalid sign: %s", keyword);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CompositeType_t ast_type_to_composite(AST_NODE_PTR type) {
|
||||||
|
size_t count = type->child_count;
|
||||||
|
|
||||||
|
struct CompositeType_t composite;
|
||||||
|
composite.name = NULL;
|
||||||
|
composite.prim = Int;
|
||||||
|
composite.scale = SINGLE;
|
||||||
|
composite.sign = Signed;
|
||||||
|
|
||||||
|
if (count == 1) {
|
||||||
|
// only other type given
|
||||||
|
composite.prim = resolve_primitive(AST_get_node(type, 0)->value);
|
||||||
|
|
||||||
|
} else if (count == 2) {
|
||||||
|
// either scale and type
|
||||||
|
// or sign and type
|
||||||
|
AST_NODE_PTR first_child = AST_get_node(type, 0);
|
||||||
|
|
||||||
|
switch (first_child->kind) {
|
||||||
|
case AST_List:
|
||||||
|
composite.scale = collapse_scale_list(first_child);
|
||||||
|
break;
|
||||||
|
case AST_Sign:
|
||||||
|
composite.sign = string_to_sign(first_child->value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PANIC("unexpected node kind: %s", AST_node_to_string(first_child));
|
||||||
|
}
|
||||||
|
|
||||||
|
composite.prim = resolve_primitive(AST_get_node(type, 1)->value);
|
||||||
|
|
||||||
|
} else if (count == 3) {
|
||||||
|
// sign, scale and type
|
||||||
|
composite.sign = string_to_sign(AST_get_node(type, 0)->value);
|
||||||
|
composite.scale = collapse_scale_list(AST_get_node(type, 0));
|
||||||
|
composite.prim = resolve_primitive(AST_get_node(type, 2)->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void generate_builtin_types(LLVMContextRef context) {
|
||||||
|
|
||||||
|
}
|
|
@ -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 <llvm/backend.h>
|
||||||
#include <codegen/backend.h>
|
#include <codegen/backend.h>
|
||||||
|
|
||||||
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
||||||
|
@ -76,11 +77,12 @@ 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");
|
llvm_backend_init();
|
||||||
|
|
||||||
init_backend();
|
init_backend();
|
||||||
|
|
||||||
generate_code(root, NULL);
|
void* code = NULL;
|
||||||
|
generate_code(root, &code);
|
||||||
|
|
||||||
deinit_backend();
|
deinit_backend();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue