diff --git a/lib/src/def.gem b/lib/src/def.gem index 5bd344f..8b57e7e 100644 --- a/lib/src/def.gem +++ b/lib/src/def.gem @@ -8,11 +8,11 @@ # Unsigned integrals -type unsgined half half int: u8 -type unsgined half int: u16 -type unsgined int: u32 -type unsgined double int: u64 -type unsgined double double int: u128 +type unsigned half half int: u8 +type unsigned half int: u16 +type unsigned int: u32 +type unsigned double int: u64 +type unsigned double double int: u128 # Signed integrals diff --git a/lib/src/io.gem b/lib/src/io.gem index bc2c553..1845a9c 100644 --- a/lib/src/io.gem +++ b/lib/src/io.gem @@ -9,7 +9,7 @@ import "def.gem" # platform specific handle to an I/O device -# can a file, buffer, window or something else +# can be a file, buffer, window or something else # NOTE: this reference is not meant to be dereferenced # which can lead to errors and undefined behavior type ptr: handle @@ -37,14 +37,14 @@ fun getStderrHandle(out handle: stderr) # -- Implementation note # On Linux this will use the syscall write # On Windows this will use the WriteFile function -fun writeBytes(in handle: dev, in ref u8: buf, in ref u32: len)(out u32: written) +fun writeBytes(in handle: dev, in ref u8: buf, in u32: len)(out u32: written) # Read atmost `len` bytes to `buf` from the I/O resource specified by `dev` # Returns the number of read bytes in `written` # -- Implementation note # On Linux this will use the syscall read # On Windows this will use the ReadFile function -fun readBytes(in handle: dev, in ref u8: buf, in ref u32: len)(out u32: read) +fun readBytes(in handle: dev, in ref u8: buf, in u32: len)(out u32: read) # Flushes the buffers of the I/O resource specified by `dev` # -- Implementation note diff --git a/lib/src/io/impl.c b/lib/src/io/impl.c index f56c561..4de453b 100644 --- a/lib/src/io/impl.c +++ b/lib/src/io/impl.c @@ -40,6 +40,7 @@ void flush(handle dev) { // Compile for Linux and BSD #include +#include // savely cast a 64-bit pointer down to a 32-bit value // this assumes that 64-bit system will use 32-bit handles diff --git a/lib/src/mem.gem b/lib/src/mem.gem index faecbc4..e199c42 100644 --- a/lib/src/mem.gem +++ b/lib/src/mem.gem @@ -20,8 +20,8 @@ fun heap_realloc(in u32: len, in out ref u8: ptr) fun heap_free(in ref u8: ptr) # Copy `len` bytes from `dst` into `src` -fun copy(in ref u8: dst, in ref u8: src, in u32 len) +fun copy(in ref u8: dst, in ref u8: src, in u32: len) # Fill `len` bytes of `dst` with `byte` -fun fill(in ref u8: dst, in u8: byte, in u32 len) +fun fill(in ref u8: dst, in u8: byte, in u32: len) diff --git a/src/ast/ast.c b/src/ast/ast.c index 22120d1..7da6bf5 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -19,8 +19,7 @@ struct AST_Node_t *AST_new_node(TokenLocation location, enum AST_SyntaxElement_t // init to discrete state node->parent = NULL; - node->children = NULL; - node->child_count = 0; + node->children = mem_new_g_array(MemoryNamespaceAst, sizeof(AST_NODE_PTR)); node->kind = kind; node->value = value; node->location = location; @@ -131,17 +130,6 @@ void AST_push_node(struct AST_Node_t *owner, struct AST_Node_t *child) { assert(owner != NULL); assert(child != NULL); - // if there are no children for now - if (owner->child_count == 0) { - DEBUG("Allocating new children array"); - owner->children = mem_alloc(MemoryNamespaceAst, sizeof(struct AST_Node_t *)); - - } else { - DEBUG("Rellocating old children array"); - const size_t size = sizeof(struct AST_Node_t *) * (owner->child_count + 1); - owner->children = mem_realloc(MemoryNamespaceAst, owner->children, size); - } - if (owner->children == NULL) { PANIC("failed to allocate children array of AST node"); } @@ -158,20 +146,20 @@ void AST_push_node(struct AST_Node_t *owner, struct AST_Node_t *child) { assert(owner->children != NULL); - owner->children[owner->child_count++] = child; + g_array_append_val(owner->children, child); } struct AST_Node_t *AST_get_node(struct AST_Node_t *owner, const size_t idx) { DEBUG("retrvieng node %d from %p", idx, owner); assert(owner != NULL); assert(owner->children != NULL); - assert(idx < owner->child_count); + assert(idx < owner->children->len); if (owner->children == NULL) { PANIC("AST owner node has no children"); } - struct AST_Node_t *child = owner->children[idx]; + AST_NODE_PTR child = g_array_index(owner->children, AST_NODE_PTR, idx); if (child == NULL) { PANIC("child node is NULL"); @@ -183,19 +171,13 @@ struct AST_Node_t *AST_get_node(struct AST_Node_t *owner, const size_t idx) { struct AST_Node_t* AST_remove_child(struct AST_Node_t* owner, const size_t idx) { assert(owner != NULL); assert(owner->children != NULL); - assert(idx < owner->child_count); + assert(idx < owner->children->len); - struct AST_Node_t* child = owner->children[idx]; + AST_NODE_PTR child = g_array_index(owner->children, AST_NODE_PTR, idx); + g_array_remove_index(owner->children, idx); child->parent = NULL; - owner->child_count--; - - // shift back every following element by one - for (size_t i = idx; i < owner->child_count; i++) { - owner->children[i] = owner->children[i + 1]; - } - return child; } @@ -204,8 +186,8 @@ struct AST_Node_t* AST_detach_child(struct AST_Node_t* owner, const struct AST_N assert(child != NULL); assert(owner->children != NULL); - for (size_t i = 0; i < owner->child_count; i++) { - if (owner->children[i] == child) { + for (size_t i = 0; i < owner->children->len; i++) { + if (g_array_index(owner->children, AST_NODE_PTR, i) == child) { return AST_remove_child(owner, i); } } @@ -225,10 +207,10 @@ void AST_delete_node(struct AST_Node_t *node) { } if (node->children != NULL) { - for (size_t i = 0; i < node->child_count; i++) { + for (size_t i = 0; i < AST_get_child_count(node); i++) { // prevent detach of children node - node->children[i]->parent = NULL; - AST_delete_node(node->children[i]); + AST_get_node(node, i)->parent = NULL; + AST_delete_node(AST_get_node(node, i)); } mem_free(node->children); } @@ -246,8 +228,8 @@ static void AST_visit_nodes_recurse2(struct AST_Node_t *root, (for_each)(root, depth); - for (size_t i = 0; i < root->child_count; i++) { - AST_visit_nodes_recurse2(root->children[i], for_each, depth + 1); + for (size_t i = 0; i < root->children->len; i++) { + AST_visit_nodes_recurse2(g_array_index(root->children, AST_NODE_PTR, i), for_each, depth + 1); } } @@ -274,8 +256,8 @@ static void AST_fprint_graphviz_node_definition(FILE* stream, const struct AST_N return; } - for (size_t i = 0; i < node->child_count; i++) { - AST_fprint_graphviz_node_definition(stream, node->children[i]); + for (size_t i = 0; i < node->children->len; i++) { + AST_fprint_graphviz_node_definition(stream, g_array_index(node->children, AST_NODE_PTR, i)); } } @@ -289,9 +271,10 @@ static void AST_fprint_graphviz_node_connection(FILE* stream, const struct AST_N return; } - for (size_t i = 0; i < node->child_count; i++) { - fprintf(stream, "\tnode%p -- node%p\n", (void*) node, (void*) node->children[i]); - AST_fprint_graphviz_node_connection(stream, node->children[i]); + for (size_t i = 0; i < node->children->len; i++) { + AST_NODE_PTR child = g_array_index(node->children, AST_NODE_PTR, i); + fprintf(stream, "\tnode%p -- node%p\n", (void*) node, (void*) child); + AST_fprint_graphviz_node_connection(stream, child); } } @@ -310,7 +293,7 @@ void AST_fprint_graphviz(FILE* stream, const struct AST_Node_t* root) { } AST_NODE_PTR AST_get_node_by_kind(AST_NODE_PTR owner, enum AST_SyntaxElement_t kind) { - for (size_t i = 0; i < owner->child_count; i++) { + for (size_t i = 0; i < owner->children->len; i++) { AST_NODE_PTR child = AST_get_node(owner, i); if (child->kind == kind) { @@ -322,23 +305,31 @@ AST_NODE_PTR AST_get_node_by_kind(AST_NODE_PTR owner, enum AST_SyntaxElement_t k } void AST_merge_modules(AST_NODE_PTR dst, size_t k, AST_NODE_PTR src) { - for (size_t i = 0; i < src->child_count; i++) { - AST_insert_node(dst, k + i, AST_remove_child(src, i)); + assert(dst != NULL); + assert(src != NULL); + + size_t elements = src->children->len; + for (size_t i = 0; i < elements; i++) { + AST_insert_node(dst, k + i, AST_remove_child(src, 0)); } AST_delete_node(src); } void AST_insert_node(AST_NODE_PTR owner, size_t idx, AST_NODE_PTR child) { + assert(owner != NULL); + assert(child != NULL); + DEBUG("Reallocating old children array"); - owner->child_count++; - const size_t size = sizeof(struct AST_Node_t *) * owner->child_count; - owner->children = mem_realloc(MemoryNamespaceAst, owner->children, size); - - // shift back every following element backwards by one - for (size_t i = owner->child_count - 1; i > idx; i--) { - owner->children[i] = owner->children[i - 1]; - } - - owner->children[idx] = child; + g_array_insert_val(owner->children, idx, child); +} + +size_t AST_get_child_count(AST_NODE_PTR node) { + return node->children->len; +} + +AST_NODE_PTR AST_get_last_node(AST_NODE_PTR node) { + assert(node != NULL); + + return g_array_index(node->children, AST_NODE_PTR, node->children->len - 1); } diff --git a/src/ast/ast.h b/src/ast/ast.h index 7f001e5..5c71d2c 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -89,7 +89,7 @@ enum AST_SyntaxElement_t { * - kind: The type of the node. Such as AST_Expr, AST_Add, ... * - value: A string representing an optional value. Can be a integer literal for kind AST_int */ -struct AST_Node_t { +typedef struct AST_Node_t { // parent node that owns this node struct AST_Node_t *parent; @@ -100,12 +100,9 @@ struct AST_Node_t { TokenLocation location; - // number of child nodes ownd by this node - // length of children array - size_t child_count; - // variable amount of child nodes - struct AST_Node_t **children; -}; + // children array + GArray* children; +} AST_Node; /** * Shorthand type for a single AST node @@ -199,6 +196,8 @@ struct AST_Node_t* AST_detach_child(struct AST_Node_t* owner, const struct AST_N [[gnu::nonnull(1)]] struct AST_Node_t *AST_get_node(struct AST_Node_t *owner, size_t idx); +AST_NODE_PTR AST_get_last_node(AST_NODE_PTR node); + /** * @brief Execute a function for every child, grandchild, ... and the supplied node as topmost ancestor * @param root the root to recursively execute a function for @@ -227,4 +226,6 @@ void AST_merge_modules(AST_NODE_PTR dst, size_t i, AST_NODE_PTR src); [[gnu::nonnull(1), gnu::nonnull(3)]] void AST_insert_node(AST_NODE_PTR owner, size_t idx, AST_NODE_PTR child); +size_t AST_get_child_count(AST_NODE_PTR node); + #endif diff --git a/src/codegen/backend.c b/src/codegen/backend.c index 9258284..4710974 100644 --- a/src/codegen/backend.c +++ b/src/codegen/backend.c @@ -11,7 +11,12 @@ static struct CodegenBackend_t { } CodegenBackend; BackendError new_backend_error(BackendErrorKind kind) { - return new_backend_impl_error(kind, NULL, NULL); + 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) { @@ -78,7 +83,7 @@ BackendError generate_code(const Module* root, const TargetConfig* target) { BackendError code = CodegenBackend.codegen_func(root, target); 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 `%s`", CodegenBackend.name, code, code.impl.message); return code; } diff --git a/src/compiler.c b/src/compiler.c index 6f3ec7c..289daf7 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -158,9 +158,12 @@ static void run_backend_codegen(const Module* module, const TargetConfig* target DEBUG("generating code..."); err = generate_code(module, target); if (err.kind != Success) { + print_message(Error, "Backend failed: %s", err.impl.message); return; } + print_message(Info, "Compilation finished successfully"); + err = deinit_backend(); } @@ -194,18 +197,25 @@ const char* get_absolute_import_path(const TargetConfig* config, const char* imp static int compile_module_with_dependencies(ModuleFileStack *unit, ModuleFile* file, const TargetConfig *target, AST_NODE_PTR root_module) { + GHashTable* imports = mem_new_g_hash_table(MemoryNamespaceAst, g_str_hash, g_str_equal); + if (compile_file_to_ast(root_module, file) == EXIT_SUCCESS) { - for (size_t i = 0; i < root_module->child_count; i++) { + for (size_t i = 0; i < AST_get_child_count(root_module); i++) { AST_NODE_PTR child = AST_get_node(root_module, i); if (child->kind == AST_Import) { const char* path = get_absolute_import_path(target, child->value); if (path == NULL) { + print_message(Error, "Cannot resolve path for import: `%s`", child->value); return EXIT_FAILURE; } + if (g_hash_table_contains(imports, path)) { + continue; + } + ModuleFile *imported_file = push_file(unit, path); AST_NODE_PTR imported_module = AST_new_node(empty_location(imported_file), AST_Module, NULL); @@ -214,6 +224,11 @@ static int compile_module_with_dependencies(ModuleFileStack *unit, ModuleFile* f } else { return EXIT_FAILURE; } + + g_hash_table_insert(imports, (gpointer) path, NULL); + + gchar* directory = g_path_get_dirname(path); + g_array_append_val(target->import_paths, directory); } } } else { diff --git a/src/io/files.c b/src/io/files.c index ee8a1f7..dc4d044 100644 --- a/src/io/files.c +++ b/src/io/files.c @@ -42,22 +42,24 @@ ModuleFile *push_file(ModuleFileStack *stack, const char *path) { // lazy init of heap stack if (stack->files == NULL) { - stack->files = g_array_new(FALSE, FALSE, sizeof(ModuleFile)); + stack->files = g_array_new(FALSE, FALSE, sizeof(ModuleFile*)); } - ModuleFile new_file = { - .path = path, - .handle = NULL - }; + ModuleFile* new_file = mem_alloc(MemoryNamespaceStatic, sizeof(ModuleFile)); + new_file->handle = NULL; + new_file->path = path; + new_file->statistics.warning_count = 0; + new_file->statistics.error_count = 0; + new_file->statistics.info_count = 0; g_array_append_val(stack->files, new_file); - return ((ModuleFile *) stack->files->data) + stack->files->len - 1; + return new_file; } void delete_files(ModuleFileStack *stack) { for (size_t i = 0; i < stack->files->len; i++) { - const ModuleFile *file = (ModuleFile *) stack->files->data + i; + const ModuleFile *file = g_array_index(stack->files, ModuleFile*, i); if (file->handle != NULL) { DEBUG("closing file: %s", file->path); @@ -254,7 +256,7 @@ void print_unit_statistics(ModuleFileStack *file_stack) { stats.error_count = 0; for (size_t i = 0; i < file_stack->files->len; i++) { - ModuleFile *file = (ModuleFile *) file_stack->files->data; + ModuleFile* file = g_array_index(file_stack->files, ModuleFile*, i); stats.info_count += file->statistics.warning_count; stats.warning_count += file->statistics.warning_count; diff --git a/src/llvm/llvm-ir/expr.c b/src/llvm/llvm-ir/expr.c index 9341b31..cb73c80 100644 --- a/src/llvm/llvm-ir/expr.c +++ b/src/llvm/llvm-ir/expr.c @@ -340,7 +340,7 @@ BackendError impl_typecast(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope, const LLVMOpcode opcode = LLVMGetCastOpcode(operand, src_signed, target_type, dst_signed); *llvm_result = - LLVMBuildCast(builder, opcode, operand, target_type, "typecast"); + LLVMBuildCast(builder, opcode, operand, target_type, "expr.typecast"); return err; } @@ -352,26 +352,29 @@ BackendError impl_variable_load(LLVMBackendCompileUnit *unit, LLVMLocalScope *sc LLVMValueRef llvm_variable = get_variable(scope, variable->name); + Type* type; + + if (variable->kind == VariableKindDefinition) { + type = variable->impl.definiton.declaration.type; + } else { + type = variable->impl.declaration.type; + } + if (llvm_variable == NULL) { return new_backend_impl_error(Implementation, NULL, "Variable not found"); } - if (reference) { + if (reference || is_parameter(scope, variable->name)) { + // don't load in case variable is parameter? // only reference wanted *llvm_result = llvm_variable; + } else { // no referencing, load value - - Type* type; LLVMTypeRef llvm_type; - if (variable->kind == VariableKindDefinition) { - type = variable->impl.definiton.declaration.type; - } else { - type = variable->impl.declaration.type; - } get_type_impl(unit, scope->func_scope->global_scope, type, &llvm_type); if (LLVMGetTypeKind(LLVMTypeOf(llvm_variable)) == LLVMPointerTypeKind) { @@ -405,7 +408,7 @@ BackendError impl_deref(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope, 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); + err = get_type_impl(unit, scope->func_scope->global_scope, dereference->variable->result->impl.reference, &llvm_deref_type); if (err.kind != Success) { return err; } @@ -416,7 +419,9 @@ BackendError impl_deref(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope, return err; } - *llvm_result = LLVMBuildGEP2(builder, llvm_deref_type, llvm_pointer, index, 1, "expr.deref"); + *llvm_result = LLVMBuildGEP2(builder, llvm_deref_type, llvm_pointer, index, 1, "expr.deref.gep2"); + + *llvm_result = LLVMBuildLoad2(builder, llvm_deref_type, *llvm_result, "expr.deref.load"); return err; } @@ -430,7 +435,7 @@ BackendError impl_expr(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope, switch (expr->kind) { case ExpressionKindConstant: - err = get_const_type_value(unit, scope->func_scope->global_scope, + err = get_const_type_value(unit, builder, scope->func_scope->global_scope, &expr->impl.constant, llvm_result); break; case ExpressionKindTransmute: diff --git a/src/llvm/llvm-ir/func.c b/src/llvm/llvm-ir/func.c index c5a4615..f0d03cc 100644 --- a/src/llvm/llvm-ir/func.c +++ b/src/llvm/llvm-ir/func.c @@ -54,6 +54,24 @@ LLVMValueRef get_variable(const LLVMLocalScope* scope, const char* name) { return global_var; } +LLVMBool is_parameter(const LLVMLocalScope* scope, const char* name) { + if (g_hash_table_contains(scope->vars, name)) { + return FALSE; + } + + if (scope->parent_scope != NULL) { + return is_parameter(scope->parent_scope, name); + } + + LLVMValueRef param = get_parameter(scope->func_scope, name); + if (param != NULL) { + return TRUE; + } + + LLVMValueRef global_var = get_global_variable(scope->func_scope->global_scope, name); + return global_var != NULL; +} + BackendError impl_param_type(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope, Parameter* param, LLVMTypeRef* llvm_type) { @@ -133,8 +151,7 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit, Function* func, const char* name) { BackendError err = SUCCESS; - LLVMValueRef llvm_func = NULL; - err = impl_func_type(unit, global_scope, func, &llvm_func); + LLVMValueRef llvm_func = LLVMGetNamedFunction(unit->module, name); if (err.kind == Success) { // create local function scope @@ -166,19 +183,22 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit, LLVMBasicBlockRef llvm_start_body_block = NULL; LLVMBasicBlockRef llvm_end_body_block = NULL; err = impl_block(unit, builder, func_scope, &llvm_start_body_block, &llvm_end_body_block, func->impl.definition.body); - LLVMPositionBuilderAtEnd(builder, entry); - LLVMBuildBr(builder, llvm_start_body_block); - // insert returning end block - LLVMBasicBlockRef end_block = - LLVMAppendBasicBlockInContext(unit->context, llvm_func, "func.end"); - LLVMPositionBuilderAtEnd(builder, end_block); - LLVMBuildRetVoid(builder); + if (err.kind == Success) { + LLVMPositionBuilderAtEnd(builder, entry); + LLVMBuildBr(builder, llvm_start_body_block); - LLVMPositionBuilderAtEnd(builder, llvm_end_body_block); - LLVMBuildBr(builder, end_block); + // insert returning end block + LLVMBasicBlockRef end_block = + LLVMAppendBasicBlockInContext(unit->context, llvm_func, "func.end"); + LLVMPositionBuilderAtEnd(builder, end_block); + LLVMBuildRetVoid(builder); - LLVMDisposeBuilder(builder); + LLVMPositionBuilderAtEnd(builder, llvm_end_body_block); + LLVMBuildBr(builder, end_block); + + LLVMDisposeBuilder(builder); + } // delete function scope GLib structs g_hash_table_destroy(func_scope->params); @@ -187,6 +207,27 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit, return err; } +BackendError impl_function_types(LLVMBackendCompileUnit* unit, + LLVMGlobalScope* scope, GHashTable* functions) { + DEBUG("implementing functions..."); + GHashTableIter iterator; + g_hash_table_iter_init(&iterator, functions); + + gpointer key = NULL; + gpointer val = NULL; + + BackendError err = SUCCESS; + size_t function_count = 0; + while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) { + Function* func = (Function*) val; + LLVMValueRef llvm_func; + err = impl_func_type(unit, scope, func, &llvm_func); + function_count++; + } + + return err; +} + BackendError impl_functions(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope, GHashTable* functions) { DEBUG("implementing functions..."); @@ -202,10 +243,7 @@ BackendError impl_functions(LLVMBackendCompileUnit* unit, while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) { Function* func = (Function*) val; - if (func->kind == FunctionDeclarationKind) { - LLVMValueRef llvm_func = NULL; - err = impl_func_type(unit, scope, func, &llvm_func); - } else { + if (func->kind != FunctionDeclarationKind) { err = impl_func_def(unit, scope, func, (const char*)key); } diff --git a/src/llvm/llvm-ir/func.h b/src/llvm/llvm-ir/func.h index acae8a6..5ab4621 100644 --- a/src/llvm/llvm-ir/func.h +++ b/src/llvm/llvm-ir/func.h @@ -28,6 +28,12 @@ void delete_local_scope(LLVMLocalScope*); LLVMValueRef get_variable(const LLVMLocalScope* scope, const char* name); +LLVMBool is_parameter(const LLVMLocalScope* scope, const char* name); + +BackendError impl_function_types(LLVMBackendCompileUnit* unit, + LLVMGlobalScope* scope, + GHashTable* variables); + BackendError impl_functions(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope, GHashTable* variables); diff --git a/src/llvm/llvm-ir/stmt.c b/src/llvm/llvm-ir/stmt.c index ccb7438..21dfaf3 100644 --- a/src/llvm/llvm-ir/stmt.c +++ b/src/llvm/llvm-ir/stmt.c @@ -170,6 +170,7 @@ BackendError impl_func_call(LLVMBackendCompileUnit *unit, LLVMValueRef llvm_arg = NULL; err = impl_expr(unit, scope, builder, arg, reference, &llvm_arg); + if (err.kind != Success) { break; } @@ -179,6 +180,7 @@ BackendError impl_func_call(LLVMBackendCompileUnit *unit, if (err.kind == Success) { LLVMValueRef llvm_func = LLVMGetNamedFunction(unit->module, call->function->name); + if (llvm_func == NULL) { return new_backend_impl_error(Implementation, NULL, "no declared function"); } diff --git a/src/llvm/llvm-ir/types.c b/src/llvm/llvm-ir/types.c index e577440..b94a1d9 100644 --- a/src/llvm/llvm-ir/types.c +++ b/src/llvm/llvm-ir/types.c @@ -6,10 +6,15 @@ #include #include #include +#include #define BASE_BYTES 4 #define BITS_PER_BYTE 8 +char* guid() { + return "uuid"; +} + static BackendError get_const_primitive_value(PrimitiveType primitive, LLVMTypeRef llvm_type, const char* value, @@ -34,11 +39,19 @@ static BackendError get_const_composite_value(CompositeType composite, llvm_value); } -BackendError impl_reference_const(TypeValue* value, LLVMValueRef* llvm_value) { +BackendError impl_reference_const(LLVMBackendCompileUnit* unit, LLVMBuilderRef builder, 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); + LLVMValueRef string_value = LLVMConstString(value->value, strlen(value->value), false); + + char* uuid = guid(); + + LLVMValueRef string_global = LLVMAddGlobal(unit->module, LLVMTypeOf(string_value), uuid); + LLVMSetInitializer(string_global, string_value); + LLVMSetGlobalConstant(string_global, true); + + *llvm_value = LLVMGetNamedGlobal(unit->module, uuid); } else { err = new_backend_impl_error(Implementation, value->nodePtr, "reference initializer can only be string literals"); } @@ -46,11 +59,11 @@ BackendError impl_reference_const(TypeValue* value, LLVMValueRef* llvm_value) { } BackendError get_const_type_value(LLVMBackendCompileUnit* unit, + LLVMBuilderRef builder, LLVMGlobalScope* scope, TypeValue* gemstone_value, LLVMValueRef* llvm_value) { - BackendError err = new_backend_impl_error( - Implementation, gemstone_value->nodePtr, "No default value for type"); + BackendError err; LLVMTypeRef llvm_type = NULL; err = get_type_impl(unit, scope, gemstone_value->type, &llvm_type); @@ -70,7 +83,7 @@ BackendError get_const_type_value(LLVMBackendCompileUnit* unit, llvm_value); break; case TypeKindReference: - err = impl_reference_const(gemstone_value, llvm_value); + err = impl_reference_const(unit, builder, gemstone_value, llvm_value); break; case TypeKindBox: err = @@ -164,7 +177,7 @@ BackendError impl_composite_type(LLVMBackendCompileUnit* unit, if (composite->sign == Signed) { err = impl_float_type(unit, composite->scale, llvm_type); } else { - ERROR("unsgined floating point not supported"); + ERROR("unsigned floating point not supported"); err = new_backend_impl_error( Implementation, composite->nodePtr, "unsigned floating-point not supported"); @@ -412,8 +425,7 @@ BackendError get_box_default_value(LLVMBackendCompileUnit* unit, BackendError get_type_default_value(LLVMBackendCompileUnit* unit, LLVMGlobalScope* scope, Type* gemstone_type, LLVMValueRef* llvm_value) { - BackendError err = new_backend_impl_error( - Implementation, gemstone_type->nodePtr, "No default value for type"); + BackendError err; LLVMTypeRef llvm_type = NULL; err = get_type_impl(unit, scope, gemstone_type, &llvm_type); diff --git a/src/llvm/llvm-ir/types.h b/src/llvm/llvm-ir/types.h index 405aa91..d094c07 100644 --- a/src/llvm/llvm-ir/types.h +++ b/src/llvm/llvm-ir/types.h @@ -19,6 +19,7 @@ BackendError get_type_default_value(LLVMBackendCompileUnit* unit, LLVMValueRef* llvm_value); BackendError get_const_type_value(LLVMBackendCompileUnit* unit, + LLVMBuilderRef builder, LLVMGlobalScope* scope, TypeValue* gemstone_value, LLVMValueRef* llvm_value); diff --git a/src/llvm/parser.c b/src/llvm/parser.c index 735c8c1..374b081 100644 --- a/src/llvm/parser.c +++ b/src/llvm/parser.c @@ -91,6 +91,8 @@ BackendError emit_module_to_file(LLVMBackendCompileUnit* unit, err = new_backend_impl_error(Implementation, NULL, "failed to emit code"); LLVMDisposeMessage(error); + } else { + print_message(Info, "Generated code was written to: %s", filename); } g_free((void*) filename); @@ -131,6 +133,8 @@ BackendError export_object(LLVMBackendCompileUnit* unit, const Target* target, llvm_target, target->triple.str, target->cpu.str, target->features.str, target->opt, target->reloc, target->model); + print_message(Info, "Generating code for: %s", target->triple.str); + if (config->print_asm) { err = emit_module_to_file(unit, target_machine, LLVMAssemblyFile, error, config); @@ -206,6 +210,11 @@ static BackendError build_module(LLVMBackendCompileUnit* unit, return err; } + err = impl_function_types(unit, global_scope, module->functions); + if (err.kind != Success) { + return err; + } + err = impl_functions(unit, global_scope, module->functions); if (err.kind != Success) { return err; diff --git a/src/set/set.c b/src/set/set.c index 7ad5163..4649c6c 100644 --- a/src/set/set.c +++ b/src/set/set.c @@ -118,7 +118,7 @@ int merge_scale_list(AST_NODE_PTR scale_list, Scale *scale) { assert(scale_list != NULL); assert(scale != NULL); - for (size_t i = 0; i < scale_list->child_count; i++) { + for (size_t i = 0; i < scale_list->children->len; i++) { double scale_in_list = 1.0; int scale_invalid = scale_factor_from(AST_get_node(scale_list, i)->value, &scale_in_list); @@ -162,12 +162,12 @@ int set_impl_composite_type(AST_NODE_PTR ast_type, CompositeType *composite) { composite->sign = Signed; // check if we have a sign - if (AST_Sign == ast_type->children[0]->kind) { + if (AST_Sign == AST_get_node(ast_type, 0)->kind) { - status = sign_from_string(ast_type->children[0]->value, &composite->sign); + status = sign_from_string(AST_get_node(ast_type, 0)->value, &composite->sign); if (status == SEMANTIC_ERROR) { - ERROR("invalid sign: %s", ast_type->children[0]->value); + ERROR("invalid sign: %s", AST_get_node(ast_type, 0)->value); return SEMANTIC_ERROR; } @@ -177,16 +177,16 @@ int set_impl_composite_type(AST_NODE_PTR ast_type, CompositeType *composite) { composite->scale = 1.0; // check if we have a list of scale factors - if (ast_type->children[scaleNodeOffset]->kind == AST_List) { + if (AST_get_node(ast_type, scaleNodeOffset)->kind == AST_List) { - status = merge_scale_list(ast_type->children[scaleNodeOffset], &composite->scale); + status = merge_scale_list(AST_get_node(ast_type, scaleNodeOffset), &composite->scale); if (status == SEMANTIC_ERROR) { return SEMANTIC_ERROR; } } - AST_NODE_PTR typeKind = ast_type->children[ast_type->child_count - 1]; + AST_NODE_PTR typeKind = AST_get_last_node(ast_type); status = primitive_from_string(typeKind->value, &composite->primitive); @@ -252,7 +252,7 @@ int set_impl_reference_type(AST_NODE_PTR currentNode, Type **type) { int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) { assert(currentNode != NULL); assert(currentNode->kind == AST_Type || currentNode->kind == AST_Reference); - assert(currentNode->child_count > 0); + assert(currentNode->children->len > 0); DEBUG("start Type"); int status; @@ -261,7 +261,7 @@ int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) { return set_impl_reference_type(currentNode, type); } - const char *typekind = currentNode->children[currentNode->child_count - 1]->value; + const char *typekind = AST_get_node(currentNode, currentNode->children->len - 1)->value; //find type in composites if (g_hash_table_contains(declaredComposites, typekind) == TRUE) { @@ -272,7 +272,7 @@ int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) { if (g_hash_table_contains(declaredBoxes, typekind) == TRUE) { *type = g_hash_table_lookup(declaredBoxes, typekind); - if (currentNode->child_count > 1) { + if (currentNode->children->len > 1) { print_diagnostic(¤tNode->location, Error, "Box type cannot modified"); return SEMANTIC_ERROR; } @@ -286,7 +286,7 @@ int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) { // only one child means either composite or primitive // try to implement primitive first // if not successfull continue building a composite - if (currentNode->child_count == 1) { + if (currentNode->children->len == 1) { // type is a primitive new_type->kind = TypeKindPrimitive; @@ -298,7 +298,7 @@ int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) { return SEMANTIC_OK; } - print_diagnostic(¤tNode->children[currentNode->child_count - 1]->location, Error, + print_diagnostic(&AST_get_last_node(currentNode)->location, Error, "Expected either primitive or composite type"); return SEMANTIC_ERROR; } @@ -328,7 +328,7 @@ int addVarToScope(Variable *variable); int createRef(AST_NODE_PTR currentNode, Type **reftype) { assert(currentNode != NULL); - assert(currentNode->child_count == 1); + assert(currentNode->children->len == 1); assert(AST_get_node(currentNode, 0)->kind == AST_Type); Type *type = malloc(sizeof(Type)); @@ -336,7 +336,7 @@ int createRef(AST_NODE_PTR currentNode, Type **reftype) { referenceType->kind = TypeKindReference; referenceType->nodePtr = currentNode; - int signal = set_get_type_impl(currentNode->children[0], &type); + int signal = set_get_type_impl(AST_get_node(currentNode, 0), &type); if (signal) { return SEMANTIC_ERROR; } @@ -349,7 +349,7 @@ int createRef(AST_NODE_PTR currentNode, Type **reftype) { int createDecl(AST_NODE_PTR currentNode, GArray **variables) { DEBUG("create declaration"); - AST_NODE_PTR ident_list = currentNode->children[currentNode->child_count - 1]; + AST_NODE_PTR ident_list = AST_get_last_node(currentNode); *variables = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *)); @@ -359,10 +359,10 @@ int createDecl(AST_NODE_PTR currentNode, GArray **variables) { int status = SEMANTIC_OK; - DEBUG("Child Count: %i", currentNode->child_count); + DEBUG("Child Count: %i", currentNode->children->len); - for (size_t i = 0; i < currentNode->child_count; i++) { - switch (currentNode->children[i]->kind) { + for (size_t i = 0; i < currentNode->children->len; i++) { + switch (AST_get_node(currentNode, i)->kind) { case AST_Storage: DEBUG("fill Qualifier"); decl.qualifier = Qualifier_from_string(AST_get_node(currentNode, i)->value); @@ -377,17 +377,17 @@ int createDecl(AST_NODE_PTR currentNode, GArray **variables) { status = createRef(AST_get_node(currentNode, i), &decl.type); break; default: - PANIC("invalid node type: %ld", currentNode->children[i]->kind); + PANIC("invalid node type: %ld", AST_get_node(currentNode, i)->kind); break; } } - for (size_t i = 0; i < ident_list->child_count; i++) { + for (size_t i = 0; i < ident_list->children->len; i++) { Variable *variable = mem_alloc(MemoryNamespaceSet, sizeof(Variable)); variable->kind = VariableKindDeclaration; variable->nodePtr = currentNode; - variable->name = ident_list->children[i]->value; + variable->name = AST_get_node(ident_list, i)->value; variable->impl.declaration = decl; g_array_append_val(*variables, variable); @@ -409,9 +409,9 @@ int createDef(AST_NODE_PTR currentNode, GArray **variables) { DEBUG("create definition"); - AST_NODE_PTR declaration = currentNode->children[0]; - AST_NODE_PTR expression = currentNode->children[1]; - AST_NODE_PTR ident_list = declaration->children[currentNode->child_count - 1]; + AST_NODE_PTR declaration = AST_get_node(currentNode, 0); + AST_NODE_PTR expression = AST_get_node(currentNode, 1); + AST_NODE_PTR ident_list = AST_get_last_node(declaration); *variables = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *)); @@ -423,17 +423,20 @@ int createDef(AST_NODE_PTR currentNode, GArray **variables) { int status = SEMANTIC_OK; - DEBUG("Child Count: %i", declaration->child_count); - for (size_t i = 0; i < declaration->child_count; i++) { - switch (declaration->children[i]->kind) { + DEBUG("Child Count: %i", declaration->children->len); + for (size_t i = 0; i < declaration->children->len; i++) { + + AST_NODE_PTR child = AST_get_node(declaration, i); + + switch (child->kind) { case AST_Storage: DEBUG("fill Qualifier"); - decl.qualifier = Qualifier_from_string(declaration->children[i]->value); + decl.qualifier = Qualifier_from_string(child->value); break; case AST_Reference: case AST_Type: DEBUG("fill Type"); - status = set_get_type_impl(declaration->children[i], &decl.type); + status = set_get_type_impl(child, &decl.type); if (status == SEMANTIC_ERROR) { return SEMANTIC_ERROR; } @@ -441,7 +444,7 @@ int createDef(AST_NODE_PTR currentNode, GArray **variables) { case AST_IdentList: break; default: - PANIC("invalid node type: %ld", declaration->children[i]->kind); + PANIC("invalid node type: %ld", child->kind); break; } } @@ -453,12 +456,12 @@ int createDef(AST_NODE_PTR currentNode, GArray **variables) { } def.initializer = name; - for (size_t i = 0; i < ident_list->child_count; i++) { + for (size_t i = 0; i < ident_list->children->len; i++) { Variable *variable = mem_alloc(MemoryNamespaceSet, sizeof(Variable)); variable->kind = VariableKindDefinition; variable->nodePtr = currentNode; - variable->name = ident_list->children[i]->value; + variable->name = AST_get_node(ident_list, i)->value; variable->impl.definiton = def; g_array_append_val(*variables, variable); @@ -659,10 +662,10 @@ int createArithOperation(Expression *ParentExpression, AST_NODE_PTR currentNode, ParentExpression->impl.operation.nodePtr = currentNode; ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *)); - assert(expectedChildCount == currentNode->child_count); + assert(expectedChildCount == currentNode->children->len); - for (size_t i = 0; i < currentNode->child_count; i++) { - Expression *expression = createExpression(currentNode->children[i]); + for (size_t i = 0; i < currentNode->children->len; i++) { + Expression *expression = createExpression(AST_get_node(currentNode, i)); if (NULL == expression) { return SEMANTIC_ERROR; @@ -738,8 +741,8 @@ int createRelationalOperation(Expression *ParentExpression, AST_NODE_PTR current ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *)); // fill Operands - for (size_t i = 0; i < currentNode->child_count; i++) { - Expression *expression = createExpression(currentNode->children[i]); + for (size_t i = 0; i < currentNode->children->len; i++) { + Expression *expression = createExpression(AST_get_node(currentNode, i)); if (NULL == expression) { return SEMANTIC_ERROR; @@ -797,8 +800,8 @@ int createBoolOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *)); // fill Operands - for (size_t i = 0; i < currentNode->child_count; i++) { - Expression *expression = createExpression(currentNode->children[i]); + for (size_t i = 0; i < currentNode->children->len; i++) { + Expression *expression = createExpression(AST_get_node(currentNode, i)); if (NULL == expression) { return SEMANTIC_ERROR; } @@ -881,7 +884,7 @@ int createBoolNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNod ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *)); //fill Operand - Expression *expression = createExpression(currentNode->children[0]); + Expression *expression = createExpression(AST_get_node(currentNode, 0)); if (NULL == expression) { return SEMANTIC_ERROR; } @@ -949,8 +952,8 @@ int createBitOperation(Expression *ParentExpression, AST_NODE_PTR currentNode) { ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *)); // fill Operands - for (size_t i = 0; i < currentNode->child_count; i++) { - Expression *expression = createExpression(currentNode->children[i]); + for (size_t i = 0; i < currentNode->children->len; i++) { + Expression *expression = createExpression(AST_get_node(currentNode, i)); if (NULL == expression) { return SEMANTIC_ERROR; @@ -1086,7 +1089,7 @@ int createBitNotOperation(Expression *ParentExpression, AST_NODE_PTR currentNode ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *)); //fill Operand - Expression *expression = createExpression(currentNode->children[0]); + Expression *expression = createExpression(AST_get_node(currentNode, 0)); if (NULL == expression) { return SEMANTIC_ERROR; } @@ -1186,12 +1189,12 @@ GArray *getBoxMember(Type *currentBoxType, GArray *names) { int createBoxAccess(Expression *ParentExpression, AST_NODE_PTR currentNode) { - const char *boxname = currentNode->children[0]->value; + const char *boxname = AST_get_node(currentNode, 0)->value; Variable *boxVariable = NULL; int status = getVariableFromScope(boxname, &boxVariable); if (status == SEMANTIC_ERROR) { - print_diagnostic(¤tNode->children[0]->location, Error, + print_diagnostic(&AST_get_node(currentNode, 0)->location, Error, "Variable of name `%s` does not exist"); return SEMANTIC_ERROR; } @@ -1221,12 +1224,12 @@ int createBoxAccess(Expression *ParentExpression, AST_NODE_PTR currentNode) { //first one is the box itself GArray *names = mem_alloc(MemoryNamespaceSet, sizeof(GArray)); if (currentNode->kind == AST_IdentList) { - for (size_t i = 1; i < currentNode->child_count; i++) { - g_array_append_val(names, currentNode->children[i]->value); + for (size_t i = 1; i < currentNode->children->len; i++) { + g_array_append_val(names, AST_get_node(currentNode, i)->value); } } else if (currentNode->kind == AST_List) { - for (size_t i = 1; i < currentNode->children[1]->child_count; i++) { - g_array_append_val(names, currentNode->children[1]->children[i]->value); + for (size_t i = 1; i < AST_get_node(currentNode, 1)->children->len; i++) { + g_array_append_val(names, AST_get_node(AST_get_node(currentNode, 1), i)->value); } } else { PANIC("current Node is not an Access"); @@ -1243,21 +1246,22 @@ int createTypeCast(Expression *ParentExpression, AST_NODE_PTR currentNode) { DEBUG("create type cast"); ParentExpression->impl.typecast.nodePtr = currentNode; - ParentExpression->impl.typecast.operand = createExpression(currentNode->children[0]); + ParentExpression->impl.typecast.operand = createExpression(AST_get_node(currentNode, 0)); if (ParentExpression->impl.typecast.operand == NULL) { return SEMANTIC_ERROR; } if (ParentExpression->impl.typecast.operand->result->kind != TypeKindComposite - && ParentExpression->impl.typecast.operand->result->kind != TypeKindPrimitive) { + && ParentExpression->impl.typecast.operand->result->kind != TypeKindPrimitive + && ParentExpression->impl.typecast.operand->result->kind != TypeKindReference) { return SEMANTIC_ERROR; } Type *target = mem_alloc(MemoryNamespaceSet, sizeof(Type)); - int status = set_get_type_impl(currentNode->children[1], &target); + int status = set_get_type_impl(AST_get_node(currentNode, 1), &target); if (status) { - print_diagnostic(¤tNode->children[1]->location, Error, "Unknown type"); + print_diagnostic(&AST_get_node(currentNode, 1)->location, Error, "Unknown type"); return SEMANTIC_ERROR; } ParentExpression->impl.typecast.targetType = target; @@ -1267,16 +1271,16 @@ int createTypeCast(Expression *ParentExpression, AST_NODE_PTR currentNode) { int createTransmute(Expression *ParentExpression, AST_NODE_PTR currentNode) { ParentExpression->impl.transmute.nodePtr = currentNode; - ParentExpression->impl.transmute.operand = createExpression(currentNode->children[0]); + ParentExpression->impl.transmute.operand = createExpression(AST_get_node(currentNode, 0)); if (ParentExpression->impl.transmute.operand == NULL) { return SEMANTIC_ERROR; } Type *target = mem_alloc(MemoryNamespaceSet, sizeof(Type)); - int status = set_get_type_impl(currentNode->children[1], &target); + int status = set_get_type_impl(AST_get_node(currentNode, 1), &target); if (status) { - print_diagnostic(¤tNode->children[1]->location, Error, "Unknown type"); + print_diagnostic(&AST_get_node(currentNode, 1)->location, Error, "Unknown type"); return SEMANTIC_ERROR; } @@ -1288,7 +1292,7 @@ int createTransmute(Expression *ParentExpression, AST_NODE_PTR currentNode) { } int createDeref(Expression *ParentExpression, AST_NODE_PTR currentNode) { - assert(currentNode->child_count == 2); + assert(currentNode->children->len == 2); Dereference deref; deref.nodePtr = currentNode; AST_NODE_PTR expression_node = AST_get_node(currentNode, 1); @@ -1301,7 +1305,7 @@ int createDeref(Expression *ParentExpression, AST_NODE_PTR currentNode) { Type *indexType = deref.index->result; //indexType can only be a composite or a primitive if (indexType->kind != TypeKindComposite && indexType->kind != TypeKindPrimitive) { - print_diagnostic(&AST_get_node(currentNode, 1)->location, Error, + print_diagnostic(&expression_node->location, Error, "Index must a primitive int or composite variation"); return SEMANTIC_ERROR; } @@ -1345,7 +1349,7 @@ int createDeref(Expression *ParentExpression, AST_NODE_PTR currentNode) { int createAddressOf(Expression *ParentExpression, AST_NODE_PTR currentNode) { assert(currentNode != NULL); - assert(currentNode->child_count == 1); + assert(currentNode->children->len == 1); AddressOf address_of; address_of.node_ptr = currentNode; @@ -1540,14 +1544,15 @@ int createAssign(Statement *ParentStatement, AST_NODE_PTR currentNode) { DEBUG("create Assign"); Assignment assign; assign.nodePtr = currentNode; - const char *varName = currentNode->children[0]->value; + // TODO: get variable + const char *varName = AST_get_node(currentNode, 0)->value; int status = getVariableFromScope(varName, &assign.variable); if (status) { return SEMANTIC_ERROR; } - assign.value = createExpression(currentNode->children[1]); + assign.value = createExpression(AST_get_node(currentNode, 1)); if (assign.value == NULL) { return SEMANTIC_ERROR; } @@ -1579,7 +1584,7 @@ int fillBlock(Block *block, AST_NODE_PTR currentNode) { GHashTable *lowerScope = g_hash_table_new(g_str_hash, g_str_equal); g_array_append_val(Scope, lowerScope); - for (size_t i = 0; i < currentNode->child_count; i++) { + for (size_t i = 0; i < currentNode->children->len; i++) { int signal = createStatement(block, AST_get_node(currentNode, i)); if (signal) { return SEMANTIC_ERROR; @@ -1600,11 +1605,11 @@ int createWhile(Statement *ParentStatement, AST_NODE_PTR currentNode) { While whileStruct; whileStruct.nodePtr = currentNode; - whileStruct.conditon = createExpression(currentNode->children[0]); + whileStruct.conditon = createExpression(AST_get_node(currentNode, 0)); if (NULL == whileStruct.conditon) { return SEMANTIC_ERROR; } - AST_NODE_PTR statementList = currentNode->children[1]; + AST_NODE_PTR statementList = AST_get_node(currentNode, 1); int signal = fillBlock(&whileStruct.block, statementList); if (signal) { @@ -1619,13 +1624,13 @@ int createIf(Branch *Parentbranch, AST_NODE_PTR currentNode) { If ifbranch; ifbranch.nodePtr = currentNode; - Expression *expression = createExpression(currentNode->children[0]); + Expression *expression = createExpression(AST_get_node(currentNode, 0)); if (NULL == expression) { return SEMANTIC_ERROR; } ifbranch.conditon = expression; - int status = fillBlock(&ifbranch.block, currentNode->children[1]); + int status = fillBlock(&ifbranch.block, AST_get_node(currentNode, 1)); if (status) { return SEMANTIC_ERROR; } @@ -1638,7 +1643,7 @@ int createElse(Branch *Parentbranch, AST_NODE_PTR currentNode) { Else elseBranch; elseBranch.nodePtr = currentNode; - int status = fillBlock(&elseBranch.block, currentNode->children[0]); + int status = fillBlock(&elseBranch.block, AST_get_node(currentNode, 0)); if (status) { return SEMANTIC_ERROR; @@ -1655,12 +1660,12 @@ int createElseIf(Branch *Parentbranch, AST_NODE_PTR currentNode) { Parentbranch->elseIfBranches = mem_new_g_array(MemoryNamespaceSet, sizeof(ElseIf)); } - Expression *expression = createExpression(currentNode->children[0]); + Expression *expression = createExpression(AST_get_node(currentNode, 0)); if (NULL == expression) { return SEMANTIC_ERROR; } elseIfBranch.conditon = expression; - int status = fillBlock(&elseIfBranch.block, currentNode->children[1]); + int status = fillBlock(&elseIfBranch.block, AST_get_node(currentNode, 1)); if (status) { return SEMANTIC_ERROR; @@ -1675,22 +1680,22 @@ int createBranch(Statement *ParentStatement, AST_NODE_PTR currentNode) { branch.elseBranch.block.statemnts = NULL; branch.elseIfBranches = NULL; - for (size_t i = 0; i < currentNode->child_count; i++) { - switch (currentNode->children[i]->kind) { + for (size_t i = 0; i < currentNode->children->len; i++) { + switch (AST_get_node(currentNode, i)->kind) { case AST_If: - if (createIf(&branch, currentNode->children[i])) { + if (createIf(&branch, AST_get_node(currentNode, i))) { return SEMANTIC_ERROR; } break; case AST_IfElse: - if (createElseIf(&branch, currentNode->children[i])) { + if (createElseIf(&branch, AST_get_node(currentNode, i))) { return SEMANTIC_ERROR; } break; case AST_Else: - if (createElse(&branch, currentNode->children[i])) { + if (createElse(&branch, AST_get_node(currentNode, i))) { return SEMANTIC_ERROR; } break; @@ -1708,7 +1713,7 @@ int getFunction(const char *name, Function **function); int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) { assert(currentNode != NULL); - assert(currentNode->child_count == 2); + assert(currentNode->children->len == 2); AST_NODE_PTR argsListNode = AST_get_node(currentNode, 1); AST_NODE_PTR nameNode = AST_get_node(currentNode, 0); @@ -1723,12 +1728,12 @@ int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) { } } if (nameNode->kind == AST_IdentList) { - assert(nameNode->child_count > 1); + assert(nameNode->children->len > 1); //idents.boxname.funname() //only boxname and funname are needed, because the combination is unique - const char *boxName = AST_get_node(nameNode, (nameNode->child_count - 2))->value; - const char *funName = AST_get_node(nameNode, (nameNode->child_count - 1))->value; + const char *boxName = AST_get_node(nameNode, (nameNode->children->len - 2))->value; + const char *funName = AST_get_node(nameNode, (nameNode->children->len - 1))->value; const char *name = g_strjoin("", boxName, ".", funName, NULL); @@ -1750,8 +1755,8 @@ int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) { } size_t count = 0; - for (size_t i = 0; i < argsListNode->child_count; i++) { - count += AST_get_node(argsListNode, i)->child_count; + for (size_t i = 0; i < argsListNode->children->len; i++) { + count += AST_get_node(argsListNode, i)->children->len; } if (count != paramCount) { @@ -1762,14 +1767,16 @@ int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) { GArray *expressions = mem_new_g_array(MemoryNamespaceSet, (sizeof(Expression *))); //exprlists - for (size_t i = 0; i < argsListNode->child_count; i++) { + for (size_t i = 0; i < argsListNode->children->len; i++) { AST_NODE_PTR currentExprList = AST_get_node(argsListNode, i); - for (size_t j = 0; j < currentExprList->child_count; j++) { - Expression *expr = createExpression(AST_get_node(currentExprList, j)); + for (int j = ((int) currentExprList->children->len) -1; j >= 0; j--) { + AST_NODE_PTR expr_node = AST_get_node(currentExprList, j); + Expression *expr = createExpression(expr_node); if (expr == NULL) { return SEMANTIC_ERROR; } + g_array_append_val(expressions, expr); } } @@ -1873,21 +1880,21 @@ int createStatement(Block *Parentblock, AST_NODE_PTR currentNode) { int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) { assert(currentNode->kind == AST_Parameter); DEBUG("start param"); - DEBUG("current node child count: %i", currentNode->child_count); + DEBUG("current node child count: %i", currentNode->children->len); - AST_NODE_PTR paramdecl = currentNode->children[1]; - AST_NODE_PTR ioQualifierList = currentNode->children[0]; + AST_NODE_PTR paramdecl = AST_get_node(currentNode, 1); + AST_NODE_PTR ioQualifierList = AST_get_node(currentNode, 0); ParameterDeclaration decl; decl.nodePtr = paramdecl; - DEBUG("iolistnode child count: %i", ioQualifierList->child_count); - if (ioQualifierList->child_count == 2) { + DEBUG("iolistnode child count: %i", ioQualifierList->children->len); + if (ioQualifierList->children->len == 2) { decl.qualifier = InOut; - } else if (ioQualifierList->child_count == 1) { - if (strcmp(ioQualifierList->children[0]->value, "in") == 0) { + } else if (ioQualifierList->children->len == 1) { + if (strcmp(AST_get_node(ioQualifierList, 0)->value, "in") == 0) { decl.qualifier = In; - } else if (strcmp(ioQualifierList->children[0]->value, "out") == 0) { + } else if (strcmp(AST_get_node(ioQualifierList, 0)->value, "out") == 0) { decl.qualifier = Out; } else { PANIC("IO_Qualifier is not in or out"); @@ -1896,14 +1903,14 @@ int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) { PANIC("IO_Qualifier has not the right amount of children"); } - if (set_get_type_impl(paramdecl->children[0], &(decl.type))) { + if (set_get_type_impl(AST_get_node(paramdecl, 0), &(decl.type))) { return SEMANTIC_ERROR; } Parameter param; param.nodePtr = currentNode; param.kind = ParameterDeclarationKind; param.impl.declaration = decl; - param.name = paramdecl->children[1]->value; + param.name = AST_get_node(paramdecl, 1)->value; DEBUG("param name: %s", param.name); g_array_append_val(Paramlist, param); @@ -1919,7 +1926,7 @@ int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) { paramvar->impl.declaration.type = param.impl.declaration.type; if (g_hash_table_contains(functionParameter, param.name)) { - print_diagnostic(¶m.nodePtr->location, Error, "Names of function parameters must be unique"); + print_diagnostic(¶m.nodePtr->location, Error, "Names of function parameters must be unique: %s", param.name); return SEMANTIC_ERROR; } g_hash_table_insert(functionParameter, (gpointer) param.name, paramvar); @@ -1930,9 +1937,9 @@ int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) { int createFunDef(Function *Parentfunction, AST_NODE_PTR currentNode) { DEBUG("start fundef"); - AST_NODE_PTR nameNode = currentNode->children[0]; - AST_NODE_PTR paramlistlist = currentNode->children[1]; - AST_NODE_PTR statementlist = currentNode->children[2]; + AST_NODE_PTR nameNode = AST_get_node(currentNode, 0); + AST_NODE_PTR paramlistlist = AST_get_node(currentNode, 1); + AST_NODE_PTR statementlist = AST_get_node(currentNode, 2); FunctionDefinition fundef; @@ -1941,15 +1948,15 @@ int createFunDef(Function *Parentfunction, AST_NODE_PTR currentNode) { fundef.body = mem_alloc(MemoryNamespaceSet, sizeof(Block)); fundef.parameter = g_array_new(FALSE, FALSE, sizeof(Parameter)); - DEBUG("paramlistlist child count: %i", paramlistlist->child_count); - for (size_t i = 0; i < paramlistlist->child_count; i++) { + DEBUG("paramlistlist child count: %i", paramlistlist->children->len); + for (size_t i = 0; i < paramlistlist->children->len; i++) { //all parameterlists - AST_NODE_PTR paramlist = paramlistlist->children[i]; - DEBUG("paramlist child count: %i", paramlist->child_count); - for (size_t j = 0; j < paramlist->child_count; j++) { + AST_NODE_PTR paramlist = AST_get_node(paramlistlist, i); + DEBUG("paramlist child count: %i", paramlist->children->len); + for (int j = ((int) paramlist->children->len) - 1; j >= 0; j--) { - DEBUG("param child count: %i", AST_get_node(paramlist, j)->child_count); + DEBUG("param child count: %i", AST_get_node(paramlist, j)->children->len); if (createParam(fundef.parameter, AST_get_node(paramlist, j))) { return SEMANTIC_ERROR; @@ -2039,8 +2046,8 @@ int getFunction(const char *name, Function **function) { int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) { DEBUG("start fundecl"); - AST_NODE_PTR nameNode = currentNode->children[0]; - AST_NODE_PTR paramlistlist = currentNode->children[1]; + AST_NODE_PTR nameNode = AST_get_node(currentNode, 0); + AST_NODE_PTR paramlistlist = AST_get_node(currentNode, 1); FunctionDeclaration fundecl; @@ -2048,14 +2055,14 @@ int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) { fundecl.name = nameNode->value; fundecl.parameter = mem_new_g_array(MemoryNamespaceSet, sizeof(Parameter)); - for (size_t i = 0; i < paramlistlist->child_count; i++) { + for (size_t i = 0; i < paramlistlist->children->len; i++) { //all parameter lists - AST_NODE_PTR paramlist = paramlistlist->children[i]; + AST_NODE_PTR paramlist = AST_get_node(paramlistlist, i); - for (size_t j = 0; j < paramlistlist->child_count; j++) { - - if (createParam(fundecl.parameter, paramlist->children[i])) { + for (int j = ((int) paramlist->children->len) - 1; j >= 0; j--) { + AST_NODE_PTR param = AST_get_node(paramlist, j); + if (createParam(fundecl.parameter, param)) { return SEMANTIC_ERROR; } } @@ -2065,6 +2072,7 @@ int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) { Parentfunction->kind = FunctionDeclarationKind; Parentfunction->impl.declaration = fundecl; Parentfunction->name = fundecl.name; + return SEMANTIC_OK; } @@ -2072,12 +2080,12 @@ int createFunction(Function *function, AST_NODE_PTR currentNode) { assert(currentNode->kind == AST_Fun); functionParameter = g_hash_table_new(g_str_hash, g_str_equal); - if (currentNode->child_count == 2) { + if (currentNode->children->len == 2) { int signal = createFunDecl(function, currentNode); if (signal) { return SEMANTIC_ERROR; } - } else if (currentNode->child_count == 3) { + } else if (currentNode->children->len == 3) { int signal = createFunDef(function, currentNode); if (signal) { return SEMANTIC_ERROR; @@ -2100,15 +2108,15 @@ int createFunction(Function *function, AST_NODE_PTR currentNode) { int createDeclMember(BoxType *ParentBox, AST_NODE_PTR currentNode) { Type *declType = mem_alloc(MemoryNamespaceSet, sizeof(Type)); - int status = set_get_type_impl(currentNode->children[0], &declType); + int status = set_get_type_impl(AST_get_node(currentNode, 0), &declType); if (status) { return SEMANTIC_ERROR; } - AST_NODE_PTR nameList = currentNode->children[1]; - for (size_t i = 0; i < nameList->child_count; i++) { + AST_NODE_PTR nameList = AST_get_node(currentNode, 1); + for (size_t i = 0; i < nameList->children->len; i++) { BoxMember *decl = mem_alloc(MemoryNamespaceSet, sizeof(BoxMember)); - decl->name = nameList->children[i]->value; + decl->name = AST_get_node(nameList, i)->value; decl->nodePtr = currentNode; decl->box = ParentBox; decl->initalizer = NULL; @@ -2122,12 +2130,12 @@ int createDeclMember(BoxType *ParentBox, AST_NODE_PTR currentNode) { } int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode) { - AST_NODE_PTR declNode = currentNode->children[0]; - AST_NODE_PTR expressionNode = currentNode->children[1]; - AST_NODE_PTR nameList = declNode->children[1]; + AST_NODE_PTR declNode = AST_get_node(currentNode, 0); + AST_NODE_PTR expressionNode = AST_get_node(currentNode, 1); + AST_NODE_PTR nameList = AST_get_node(declNode, 1); Type *declType = mem_alloc(MemoryNamespaceSet, sizeof(Type)); - int status = set_get_type_impl(currentNode->children[0], &declType); + int status = set_get_type_impl(AST_get_node(currentNode, 0), &declType); if (status) { return SEMANTIC_ERROR; } @@ -2137,12 +2145,12 @@ int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode) { return SEMANTIC_ERROR; } - for (size_t i = 0; i < nameList->child_count; i++) { + for (size_t i = 0; i < nameList->children->len; i++) { BoxMember *def = mem_alloc(MemoryNamespaceSet, sizeof(BoxMember)); def->box = ParentBox; def->type = declType; def->initalizer = init; - def->name = nameList->children[i]->value; + def->name = AST_get_node(nameList, i)->value; def->nodePtr = currentNode; if (g_hash_table_contains(ParentBox->member, (gpointer) def->name)) { return SEMANTIC_ERROR; @@ -2184,18 +2192,18 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode) { BoxType *box = mem_alloc(MemoryNamespaceSet, sizeof(BoxType)); box->nodePtr = currentNode; - const char *boxName = currentNode->children[0]->value; - AST_NODE_PTR boxMemberList = currentNode->children[1]; + const char *boxName = AST_get_node(currentNode, 0)->value; + AST_NODE_PTR boxMemberList = AST_get_node(currentNode, 1); Type *boxType = mem_alloc(MemoryNamespaceSet, sizeof(Type)); boxType->nodePtr = currentNode; boxType->impl.box = box; - for (size_t i = 0; boxMemberList->child_count; i++) { - switch (boxMemberList->children[i]->kind) { + for (size_t i = 0; boxMemberList->children->len; i++) { + switch (AST_get_node(boxMemberList, i)->kind) { case AST_Decl: case AST_Def: - if (createDeclMember(box, boxMemberList->children[i])) { + if (createDeclMember(box, AST_get_node(boxMemberList, i))) { return SEMANTIC_ERROR; } break; @@ -2220,8 +2228,8 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode) { int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode) { DEBUG("create Type define"); - AST_NODE_PTR typeNode = currentNode->children[0]; - AST_NODE_PTR nameNode = currentNode->children[1]; + AST_NODE_PTR typeNode = AST_get_node(currentNode, 0); + AST_NODE_PTR nameNode = AST_get_node(currentNode, 1); Type *type = mem_alloc(MemoryNamespaceSet, sizeof(Type)); int status = set_get_type_impl(typeNode, &type); @@ -2283,12 +2291,12 @@ Module *create_set(AST_NODE_PTR currentNode) { DEBUG("created Module struct"); - for (size_t i = 0; i < currentNode->child_count; i++) { - DEBUG("created Child with type: %i", currentNode->children[i]->kind); - switch (currentNode->children[i]->kind) { + for (size_t i = 0; i < currentNode->children->len; i++) { + DEBUG("created Child with type: %i", AST_get_node(currentNode, i)->kind); + switch (AST_get_node(currentNode, i)->kind) { case AST_Decl: { GArray *vars = NULL; - int status = createDecl(currentNode->children[i], &vars); + int status = createDecl(AST_get_node(currentNode, i), &vars); if (status) { return NULL; } @@ -2301,7 +2309,7 @@ Module *create_set(AST_NODE_PTR currentNode) { } case AST_Def: { GArray *vars; - int status = createDef(currentNode->children[i], &vars); + int status = createDef(AST_get_node(currentNode, i), &vars); if (status) { return NULL; } @@ -2313,7 +2321,7 @@ Module *create_set(AST_NODE_PTR currentNode) { break; } case AST_Box: { - int status = createBox(boxes, currentNode->children[i]); + int status = createBox(boxes, AST_get_node(currentNode, i)); if (status) { return NULL; } @@ -2324,7 +2332,7 @@ Module *create_set(AST_NODE_PTR currentNode) { DEBUG("start function"); Function *function = mem_alloc(MemoryNamespaceSet, sizeof(Function)); - if (createFunction(function, currentNode->children[i]) == SEMANTIC_ERROR) { + if (createFunction(function, AST_get_node(currentNode, i)) == SEMANTIC_ERROR) { return NULL; } @@ -2340,7 +2348,7 @@ Module *create_set(AST_NODE_PTR currentNode) { break; } case AST_Typedef: { - int status = createTypeDef(types, currentNode->children[i]); + int status = createTypeDef(types, AST_get_node(currentNode, i)); if (status) { return NULL; } @@ -2349,7 +2357,7 @@ Module *create_set(AST_NODE_PTR currentNode) { } case AST_Import: DEBUG("create Import"); - g_array_append_val(imports, currentNode->children[i]->value); + g_array_append_val(imports, AST_get_node(currentNode, i)->value); break; default: INFO("Provided source file could not be parsed because of semantic error."); diff --git a/src/yacc/parser.y b/src/yacc/parser.y index 438f421..70f3069 100644 --- a/src/yacc/parser.y +++ b/src/yacc/parser.y @@ -69,6 +69,7 @@ %type typecast %type reinterpretcast %type program +%type storage_expr %token KeyInt @@ -399,15 +400,18 @@ storagequalifier: KeyGlobal {$$ = AST_new_node(new_loc(), AST_Storage, "global") | KeyStatic {$$ = AST_new_node(new_loc(), AST_Storage, "static");} | KeyLocal {$$ = AST_new_node(new_loc(), AST_Storage, "local");}; -assign: Ident '=' expr { AST_NODE_PTR assign = AST_new_node(new_loc(), AST_Assign, NULL); - AST_NODE_PTR ident = AST_new_node(new_loc(), AST_Ident, $1); - AST_push_node(assign, ident); +assign: storage_expr '=' expr { AST_NODE_PTR assign = AST_new_node(new_loc(), AST_Assign, NULL); + AST_push_node(assign, $1); AST_push_node(assign, $3); - $$ = assign; - DEBUG("Assignment"); } - - | boxaccess '=' expr - | boxselfaccess '=' expr ; + $$ = assign; }; + +storage_expr: Ident { $$ = AST_new_node(new_loc(), AST_Ident, $1); } + | boxaccess { $$ = $1; } + | boxselfaccess { $$ = $1; } + | storage_expr '[' expr ']' { AST_NODE_PTR deref = AST_new_node(new_loc(), AST_Dereference, NULL); + AST_push_node(deref, $1); + AST_push_node(deref, $3); + $$ = deref; }; sign: KeySigned {$$ = AST_new_node(new_loc(), AST_Sign, "signed");} | KeyUnsigned{$$ = AST_new_node(new_loc(), AST_Sign, "unsigned");};