added: string constants to backend llvm

This commit is contained in:
Sven Vogel 2024-06-12 00:08:13 +02:00
parent de253a94ab
commit 560e24950e
8 changed files with 94 additions and 9 deletions

View File

@ -106,6 +106,7 @@ TargetConfig* default_target_config() {
config->link_search_paths = g_array_new(FALSE, FALSE, sizeof(char*)); config->link_search_paths = g_array_new(FALSE, FALSE, sizeof(char*));
config->lld_fatal_warnings = FALSE; config->lld_fatal_warnings = FALSE;
config->gsc_fatal_warnings = FALSE; config->gsc_fatal_warnings = FALSE;
config->import_paths = mem_new_g_array(MemoryNamespaceOpt, sizeof(char*));
return config; return config;
} }
@ -208,6 +209,9 @@ TargetConfig* default_target_config_from_args() {
g_array_free(files, TRUE); g_array_free(files, TRUE);
} }
char* default_import_path = mem_strdup(MemoryNamespaceOpt, ".");
g_array_append_val(config->import_paths, default_import_path);
return config; return config;
} }

View File

@ -61,6 +61,7 @@ typedef struct TargetConfig_t {
bool lld_fatal_warnings; bool lld_fatal_warnings;
// treat parser warnings as errors // treat parser warnings as errors
bool gsc_fatal_warnings; bool gsc_fatal_warnings;
GArray* import_paths;
} TargetConfig; } TargetConfig;
/** /**

View File

@ -164,7 +164,35 @@ static void run_backend_codegen(const Module* module, const TargetConfig* target
err = deinit_backend(); err = deinit_backend();
} }
static AST_NODE_PTR compile_module_with_dependencies(ModuleFileStack *unit, ModuleFile* file) { const char* get_absolute_import_path(const TargetConfig* config, const char* import_target_name) {
INFO("resolving absolute path for import target: %s", import_target_name);
for (guint i = 0; i < config->import_paths->len; i++) {
const char* import_directory_path = g_array_index(config->import_paths, char*, i);
char* path = g_build_filename(import_directory_path, import_target_name, NULL);
char* cwd = g_get_current_dir();
char* canonical = g_canonicalize_filename(path, cwd);
const gboolean exists = g_file_test(canonical, G_FILE_TEST_EXISTS);
const gboolean is_dir = g_file_test(canonical, G_FILE_TEST_IS_DIR);
g_free(path);
g_free(cwd);
if (exists && !is_dir) {
INFO("import target found at: %s", canonical);
return canonical;
}
g_free(canonical);
}
// file not found
return NULL;
}
static AST_NODE_PTR compile_module_with_dependencies(ModuleFileStack *unit, ModuleFile* file, const TargetConfig *target) {
AST_NODE_PTR root_module = AST_new_node(empty_location(), AST_Module, NULL); AST_NODE_PTR root_module = AST_new_node(empty_location(), AST_Module, NULL);
if (compile_file_to_ast(root_module, file) == EXIT_SUCCESS) { if (compile_file_to_ast(root_module, file) == EXIT_SUCCESS) {
@ -175,7 +203,12 @@ static AST_NODE_PTR compile_module_with_dependencies(ModuleFileStack *unit, Modu
if (child->kind == AST_Import) { if (child->kind == AST_Import) {
AST_NODE_PTR imported_module = AST_new_node(empty_location(), AST_Module, NULL); AST_NODE_PTR imported_module = AST_new_node(empty_location(), AST_Module, NULL);
ModuleFile *imported_file = push_file(unit, child->value); const char* path = get_absolute_import_path(target, child->value);
if (path == NULL) {
return NULL;
}
ModuleFile *imported_file = push_file(unit, path);
if (compile_file_to_ast(imported_module, imported_file) == EXIT_SUCCESS) { if (compile_file_to_ast(imported_module, imported_file) == EXIT_SUCCESS) {
AST_merge_modules(root_module, i + 1, imported_module); AST_merge_modules(root_module, i + 1, imported_module);
@ -196,7 +229,7 @@ static void build_target(ModuleFileStack *unit, const TargetConfig *target) {
print_message(Info, "Building target: %s", target->name); print_message(Info, "Building target: %s", target->name);
ModuleFile *file = push_file(unit, target->root_module); ModuleFile *file = push_file(unit, target->root_module);
AST_NODE_PTR ast = compile_module_with_dependencies(unit, file); AST_NODE_PTR ast = compile_module_with_dependencies(unit, file, target);
if (ast != NULL) { if (ast != NULL) {
if (setup_target_environment(target) == 0) { if (setup_target_environment(target) == 0) {

View File

@ -5,6 +5,7 @@
#include <llvm/llvm-ir/expr.h> #include <llvm/llvm-ir/expr.h>
#include <llvm/llvm-ir/types.h> #include <llvm/llvm-ir/types.h>
#include <sys/log.h> #include <sys/log.h>
#include <mem/cache.h>
BackendError impl_bitwise_operation(LLVMBackendCompileUnit *unit, BackendError impl_bitwise_operation(LLVMBackendCompileUnit *unit,
LLVMLocalScope *scope, LLVMLocalScope *scope,
@ -394,6 +395,29 @@ BackendError impl_address_of(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope
return SUCCESS; return SUCCESS;
} }
BackendError impl_deref(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
LLVMBuilderRef builder, Dereference* dereference,
LLVMValueRef *llvm_result) {
BackendError err;
LLVMValueRef llvm_pointer = get_variable(scope, dereference->variable->impl.variable->name);
LLVMTypeRef llvm_deref_type = NULL;
err = get_type_impl(unit, scope->func_scope->global_scope, dereference->variable->result, &llvm_deref_type);
if (err.kind != Success) {
return err;
}
LLVMValueRef* index = mem_alloc(MemoryNamespaceLlvm, sizeof(LLVMValueRef));
err = impl_expr(unit, scope, builder, dereference->index, FALSE, index);
if (err.kind != Success) {
return err;
}
*llvm_result = LLVMBuildGEP2(builder, llvm_deref_type, llvm_pointer, index, 1, "expr.deref");
return err;
}
BackendError impl_expr(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope, BackendError impl_expr(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
LLVMBuilderRef builder, Expression *expr, LLVMBuilderRef builder, Expression *expr,
LLVMBool reference, LLVMBool reference,
@ -427,6 +451,10 @@ BackendError impl_expr(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
err = impl_address_of(unit, scope, builder, &expr->impl.addressOf, err = impl_address_of(unit, scope, builder, &expr->impl.addressOf,
llvm_result); llvm_result);
break; break;
case ExpressionKindDereference:
err = impl_deref(unit, scope, builder, &expr->impl.dereference,
llvm_result);
break;
default: default:
err = new_backend_impl_error(Implementation, NULL, "unknown expression"); err = new_backend_impl_error(Implementation, NULL, "unknown expression");
break; break;

View File

@ -5,6 +5,7 @@
#include <llvm/parser.h> #include <llvm/parser.h>
#include <set/types.h> #include <set/types.h>
#include <sys/log.h> #include <sys/log.h>
#include <set/set.h>
#define BASE_BYTES 4 #define BASE_BYTES 4
#define BITS_PER_BYTE 8 #define BITS_PER_BYTE 8
@ -33,6 +34,17 @@ static BackendError get_const_composite_value(CompositeType composite,
llvm_value); llvm_value);
} }
BackendError impl_reference_const(TypeValue* value, LLVMValueRef* llvm_value) {
BackendError err = SUCCESS;
if (value->type->kind == TypeKindReference && compareTypes(value->type, (Type*) &StringLiteralType)) {
// is string literal
*llvm_value = LLVMConstString(value->value, strlen(value->value), FALSE);
} else {
err = new_backend_impl_error(Implementation, value->nodePtr, "reference initializer can only be string literals");
}
return err;
}
BackendError get_const_type_value(LLVMBackendCompileUnit* unit, BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope, LLVMGlobalScope* scope,
TypeValue* gemstone_value, TypeValue* gemstone_value,
@ -58,9 +70,7 @@ BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
llvm_value); llvm_value);
break; break;
case TypeKindReference: case TypeKindReference:
err = err = impl_reference_const(gemstone_value, llvm_value);
new_backend_impl_error(Implementation, gemstone_value->nodePtr,
"reference cannot be constant value");
break; break;
case TypeKindBox: case TypeKindBox:
err = err =

View File

@ -207,6 +207,9 @@ static BackendError build_module(LLVMBackendCompileUnit* unit,
} }
err = impl_functions(unit, global_scope, module->functions); err = impl_functions(unit, global_scope, module->functions);
if (err.kind != Success) {
return err;
}
char* error = NULL; char* error = NULL;
if (LLVMVerifyModule(unit->module, LLVMAbortProcessAction, &error)) { if (LLVMVerifyModule(unit->module, LLVMAbortProcessAction, &error)) {

View File

@ -1292,7 +1292,8 @@ int createDeref(Expression *ParentExpression, AST_NODE_PTR currentNode) {
assert(currentNode->child_count == 2); assert(currentNode->child_count == 2);
Dereference deref; Dereference deref;
deref.nodePtr = currentNode; deref.nodePtr = currentNode;
deref.index = createExpression(AST_get_node(currentNode, 0)); AST_NODE_PTR expression_node = AST_get_node(currentNode, 1);
deref.index = createExpression(expression_node);
//index has to be made //index has to be made
if (deref.index == NULL) { if (deref.index == NULL) {
@ -1323,11 +1324,11 @@ int createDeref(Expression *ParentExpression, AST_NODE_PTR currentNode) {
} }
} }
deref.variable = createExpression(AST_get_node(currentNode, 1)); deref.variable = createExpression(AST_get_node(currentNode, 0));
//variable has to be made //variable has to be made
if (deref.index == NULL) { if (deref.index == NULL) {
print_diagnostic(current_file, &AST_get_node(currentNode, 1)->location, Error, "Invalid index"); print_diagnostic(current_file, &AST_get_node(currentNode, 0)->location, Error, "Invalid index");
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }

View File

@ -7,8 +7,13 @@
#define SEMANTIC_OK 0 #define SEMANTIC_OK 0
#define SEMANTIC_ERROR 1 #define SEMANTIC_ERROR 1
// type of string literal
extern const Type StringLiteralType;
Module * create_set(AST_NODE_PTR rootNodePtr ); Module * create_set(AST_NODE_PTR rootNodePtr );
void delete_set(Module* module); void delete_set(Module* module);
bool compareTypes(Type *leftType, Type *rightType);
#endif #endif