added: new parser rules for assignments

This commit is contained in:
Sven Vogel 2024-06-21 21:30:43 +02:00
parent 984c34cfc7
commit 30417592df
18 changed files with 360 additions and 260 deletions

View File

@ -8,11 +8,11 @@
# Unsigned integrals # Unsigned integrals
type unsgined half half int: u8 type unsigned half half int: u8
type unsgined half int: u16 type unsigned half int: u16
type unsgined int: u32 type unsigned int: u32
type unsgined double int: u64 type unsigned double int: u64
type unsgined double double int: u128 type unsigned double double int: u128
# Signed integrals # Signed integrals

View File

@ -9,7 +9,7 @@
import "def.gem" import "def.gem"
# platform specific handle to an I/O device # 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 # NOTE: this reference is not meant to be dereferenced
# which can lead to errors and undefined behavior # which can lead to errors and undefined behavior
type ptr: handle type ptr: handle
@ -37,14 +37,14 @@ fun getStderrHandle(out handle: stderr)
# -- Implementation note # -- Implementation note
# On Linux this will use the syscall write # On Linux this will use the syscall write
# On Windows this will use the WriteFile function # 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` # Read atmost `len` bytes to `buf` from the I/O resource specified by `dev`
# Returns the number of read bytes in `written` # Returns the number of read bytes in `written`
# -- Implementation note # -- Implementation note
# On Linux this will use the syscall read # On Linux this will use the syscall read
# On Windows this will use the ReadFile function # 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` # Flushes the buffers of the I/O resource specified by `dev`
# -- Implementation note # -- Implementation note

View File

@ -40,6 +40,7 @@ void flush(handle dev) {
// Compile for Linux and BSD // Compile for Linux and BSD
#include <unistd.h> #include <unistd.h>
#include <stdio.h>
// savely cast a 64-bit pointer down to a 32-bit value // savely cast a 64-bit pointer down to a 32-bit value
// this assumes that 64-bit system will use 32-bit handles // this assumes that 64-bit system will use 32-bit handles

View File

@ -20,8 +20,8 @@ fun heap_realloc(in u32: len, in out ref u8: ptr)
fun heap_free(in ref u8: ptr) fun heap_free(in ref u8: ptr)
# Copy `len` bytes from `dst` into `src` # 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` # 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)

View File

@ -19,8 +19,7 @@ struct AST_Node_t *AST_new_node(TokenLocation location, enum AST_SyntaxElement_t
// init to discrete state // init to discrete state
node->parent = NULL; node->parent = NULL;
node->children = NULL; node->children = mem_new_g_array(MemoryNamespaceAst, sizeof(AST_NODE_PTR));
node->child_count = 0;
node->kind = kind; node->kind = kind;
node->value = value; node->value = value;
node->location = location; 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(owner != NULL);
assert(child != 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) { if (owner->children == NULL) {
PANIC("failed to allocate children array of AST node"); 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); 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) { struct AST_Node_t *AST_get_node(struct AST_Node_t *owner, const size_t idx) {
DEBUG("retrvieng node %d from %p", idx, owner); DEBUG("retrvieng node %d from %p", idx, owner);
assert(owner != NULL); assert(owner != NULL);
assert(owner->children != NULL); assert(owner->children != NULL);
assert(idx < owner->child_count); assert(idx < owner->children->len);
if (owner->children == NULL) { if (owner->children == NULL) {
PANIC("AST owner node has no children"); 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) { if (child == NULL) {
PANIC("child node is 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) { struct AST_Node_t* AST_remove_child(struct AST_Node_t* owner, const size_t idx) {
assert(owner != NULL); assert(owner != NULL);
assert(owner->children != 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; 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; 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(child != NULL);
assert(owner->children != NULL); assert(owner->children != NULL);
for (size_t i = 0; i < owner->child_count; i++) { for (size_t i = 0; i < owner->children->len; i++) {
if (owner->children[i] == child) { if (g_array_index(owner->children, AST_NODE_PTR, i) == child) {
return AST_remove_child(owner, i); return AST_remove_child(owner, i);
} }
} }
@ -225,10 +207,10 @@ void AST_delete_node(struct AST_Node_t *node) {
} }
if (node->children != NULL) { 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 // prevent detach of children node
node->children[i]->parent = NULL; AST_get_node(node, i)->parent = NULL;
AST_delete_node(node->children[i]); AST_delete_node(AST_get_node(node, i));
} }
mem_free(node->children); mem_free(node->children);
} }
@ -246,8 +228,8 @@ static void AST_visit_nodes_recurse2(struct AST_Node_t *root,
(for_each)(root, depth); (for_each)(root, depth);
for (size_t i = 0; i < root->child_count; i++) { for (size_t i = 0; i < root->children->len; i++) {
AST_visit_nodes_recurse2(root->children[i], for_each, depth + 1); 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; return;
} }
for (size_t i = 0; i < node->child_count; i++) { for (size_t i = 0; i < node->children->len; i++) {
AST_fprint_graphviz_node_definition(stream, node->children[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; return;
} }
for (size_t i = 0; i < node->child_count; i++) { for (size_t i = 0; i < node->children->len; i++) {
fprintf(stream, "\tnode%p -- node%p\n", (void*) node, (void*) node->children[i]); AST_NODE_PTR child = g_array_index(node->children, AST_NODE_PTR, i);
AST_fprint_graphviz_node_connection(stream, node->children[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) { 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); AST_NODE_PTR child = AST_get_node(owner, i);
if (child->kind == kind) { 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) { 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++) { assert(dst != NULL);
AST_insert_node(dst, k + i, AST_remove_child(src, i)); 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); AST_delete_node(src);
} }
void AST_insert_node(AST_NODE_PTR owner, size_t idx, AST_NODE_PTR child) { 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"); DEBUG("Reallocating old children array");
owner->child_count++; g_array_insert_val(owner->children, idx, child);
const size_t size = sizeof(struct AST_Node_t *) * owner->child_count; }
owner->children = mem_realloc(MemoryNamespaceAst, owner->children, size);
size_t AST_get_child_count(AST_NODE_PTR node) {
// shift back every following element backwards by one return node->children->len;
for (size_t i = owner->child_count - 1; i > idx; i--) { }
owner->children[i] = owner->children[i - 1];
} AST_NODE_PTR AST_get_last_node(AST_NODE_PTR node) {
assert(node != NULL);
owner->children[idx] = child;
return g_array_index(node->children, AST_NODE_PTR, node->children->len - 1);
} }

View File

@ -89,7 +89,7 @@ enum AST_SyntaxElement_t {
* - kind: The type of the node. Such as AST_Expr, AST_Add, ... * - 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 * - 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 // parent node that owns this node
struct AST_Node_t *parent; struct AST_Node_t *parent;
@ -100,12 +100,9 @@ struct AST_Node_t {
TokenLocation location; TokenLocation location;
// number of child nodes ownd by this node // children array
// length of children array GArray* children;
size_t child_count; } AST_Node;
// variable amount of child nodes
struct AST_Node_t **children;
};
/** /**
* Shorthand type for a single 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)]] [[gnu::nonnull(1)]]
struct AST_Node_t *AST_get_node(struct AST_Node_t *owner, size_t idx); 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 * @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 * @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)]] [[gnu::nonnull(1), gnu::nonnull(3)]]
void AST_insert_node(AST_NODE_PTR owner, size_t idx, AST_NODE_PTR child); 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 #endif

View File

@ -11,7 +11,12 @@ static struct CodegenBackend_t {
} CodegenBackend; } CodegenBackend;
BackendError new_backend_error(BackendErrorKind kind) { 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) { 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); BackendError code = CodegenBackend.codegen_func(root, target);
if (code.kind) { 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; return code;
} }

View File

@ -158,9 +158,12 @@ static void run_backend_codegen(const Module* module, const TargetConfig* target
DEBUG("generating code..."); DEBUG("generating code...");
err = generate_code(module, target); err = generate_code(module, target);
if (err.kind != Success) { if (err.kind != Success) {
print_message(Error, "Backend failed: %s", err.impl.message);
return; return;
} }
print_message(Info, "Compilation finished successfully");
err = deinit_backend(); 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) { 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) { 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); AST_NODE_PTR child = AST_get_node(root_module, i);
if (child->kind == AST_Import) { if (child->kind == AST_Import) {
const char* path = get_absolute_import_path(target, child->value); const char* path = get_absolute_import_path(target, child->value);
if (path == NULL) { if (path == NULL) {
print_message(Error, "Cannot resolve path for import: `%s`", child->value);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (g_hash_table_contains(imports, path)) {
continue;
}
ModuleFile *imported_file = push_file(unit, path); ModuleFile *imported_file = push_file(unit, path);
AST_NODE_PTR imported_module = AST_new_node(empty_location(imported_file), AST_Module, NULL); 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 { } else {
return EXIT_FAILURE; 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 { } else {

View File

@ -42,22 +42,24 @@ ModuleFile *push_file(ModuleFileStack *stack, const char *path) {
// lazy init of heap stack // lazy init of heap stack
if (stack->files == NULL) { 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 = { ModuleFile* new_file = mem_alloc(MemoryNamespaceStatic, sizeof(ModuleFile));
.path = path, new_file->handle = NULL;
.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); 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) { void delete_files(ModuleFileStack *stack) {
for (size_t i = 0; i < stack->files->len; i++) { 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) { if (file->handle != NULL) {
DEBUG("closing file: %s", file->path); DEBUG("closing file: %s", file->path);
@ -254,7 +256,7 @@ void print_unit_statistics(ModuleFileStack *file_stack) {
stats.error_count = 0; stats.error_count = 0;
for (size_t i = 0; i < file_stack->files->len; i++) { 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.info_count += file->statistics.warning_count;
stats.warning_count += file->statistics.warning_count; stats.warning_count += file->statistics.warning_count;

View File

@ -340,7 +340,7 @@ BackendError impl_typecast(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
const LLVMOpcode opcode = const LLVMOpcode opcode =
LLVMGetCastOpcode(operand, src_signed, target_type, dst_signed); LLVMGetCastOpcode(operand, src_signed, target_type, dst_signed);
*llvm_result = *llvm_result =
LLVMBuildCast(builder, opcode, operand, target_type, "typecast"); LLVMBuildCast(builder, opcode, operand, target_type, "expr.typecast");
return err; return err;
} }
@ -352,26 +352,29 @@ BackendError impl_variable_load(LLVMBackendCompileUnit *unit, LLVMLocalScope *sc
LLVMValueRef llvm_variable = get_variable(scope, variable->name); 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) { if (llvm_variable == NULL) {
return new_backend_impl_error(Implementation, NULL, "Variable not found"); 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 // only reference wanted
*llvm_result = llvm_variable; *llvm_result = llvm_variable;
} else { } else {
// no referencing, load value // no referencing, load value
Type* type;
LLVMTypeRef llvm_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); get_type_impl(unit, scope->func_scope->global_scope, type, &llvm_type);
if (LLVMGetTypeKind(LLVMTypeOf(llvm_variable)) == LLVMPointerTypeKind) { 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); LLVMValueRef llvm_pointer = get_variable(scope, dereference->variable->impl.variable->name);
LLVMTypeRef llvm_deref_type = NULL; 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) { if (err.kind != Success) {
return err; return err;
} }
@ -416,7 +419,9 @@ BackendError impl_deref(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
return err; 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; return err;
} }
@ -430,7 +435,7 @@ BackendError impl_expr(LLVMBackendCompileUnit *unit, LLVMLocalScope *scope,
switch (expr->kind) { switch (expr->kind) {
case ExpressionKindConstant: 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); &expr->impl.constant, llvm_result);
break; break;
case ExpressionKindTransmute: case ExpressionKindTransmute:

View File

@ -54,6 +54,24 @@ LLVMValueRef get_variable(const LLVMLocalScope* scope, const char* name) {
return global_var; 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, BackendError impl_param_type(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope, Parameter* param, LLVMGlobalScope* scope, Parameter* param,
LLVMTypeRef* llvm_type) { LLVMTypeRef* llvm_type) {
@ -133,8 +151,7 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit,
Function* func, const char* name) { Function* func, const char* name) {
BackendError err = SUCCESS; BackendError err = SUCCESS;
LLVMValueRef llvm_func = NULL; LLVMValueRef llvm_func = LLVMGetNamedFunction(unit->module, name);
err = impl_func_type(unit, global_scope, func, &llvm_func);
if (err.kind == Success) { if (err.kind == Success) {
// create local function scope // create local function scope
@ -166,19 +183,22 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit,
LLVMBasicBlockRef llvm_start_body_block = NULL; LLVMBasicBlockRef llvm_start_body_block = NULL;
LLVMBasicBlockRef llvm_end_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); 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 if (err.kind == Success) {
LLVMBasicBlockRef end_block = LLVMPositionBuilderAtEnd(builder, entry);
LLVMAppendBasicBlockInContext(unit->context, llvm_func, "func.end"); LLVMBuildBr(builder, llvm_start_body_block);
LLVMPositionBuilderAtEnd(builder, end_block);
LLVMBuildRetVoid(builder);
LLVMPositionBuilderAtEnd(builder, llvm_end_body_block); // insert returning end block
LLVMBuildBr(builder, 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 // delete function scope GLib structs
g_hash_table_destroy(func_scope->params); g_hash_table_destroy(func_scope->params);
@ -187,6 +207,27 @@ BackendError impl_func_def(LLVMBackendCompileUnit* unit,
return err; 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, BackendError impl_functions(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope, GHashTable* functions) { LLVMGlobalScope* scope, GHashTable* functions) {
DEBUG("implementing functions..."); DEBUG("implementing functions...");
@ -202,10 +243,7 @@ BackendError impl_functions(LLVMBackendCompileUnit* unit,
while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) { while (g_hash_table_iter_next(&iterator, &key, &val) != FALSE) {
Function* func = (Function*) val; Function* func = (Function*) val;
if (func->kind == FunctionDeclarationKind) { if (func->kind != FunctionDeclarationKind) {
LLVMValueRef llvm_func = NULL;
err = impl_func_type(unit, scope, func, &llvm_func);
} else {
err = impl_func_def(unit, scope, func, (const char*)key); err = impl_func_def(unit, scope, func, (const char*)key);
} }

View File

@ -28,6 +28,12 @@ void delete_local_scope(LLVMLocalScope*);
LLVMValueRef get_variable(const LLVMLocalScope* scope, const char* name); 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, BackendError impl_functions(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope, LLVMGlobalScope* scope,
GHashTable* variables); GHashTable* variables);

View File

@ -170,6 +170,7 @@ BackendError impl_func_call(LLVMBackendCompileUnit *unit,
LLVMValueRef llvm_arg = NULL; LLVMValueRef llvm_arg = NULL;
err = impl_expr(unit, scope, builder, arg, reference, &llvm_arg); err = impl_expr(unit, scope, builder, arg, reference, &llvm_arg);
if (err.kind != Success) { if (err.kind != Success) {
break; break;
} }
@ -179,6 +180,7 @@ BackendError impl_func_call(LLVMBackendCompileUnit *unit,
if (err.kind == Success) { if (err.kind == Success) {
LLVMValueRef llvm_func = LLVMGetNamedFunction(unit->module, call->function->name); LLVMValueRef llvm_func = LLVMGetNamedFunction(unit->module, call->function->name);
if (llvm_func == NULL) { if (llvm_func == NULL) {
return new_backend_impl_error(Implementation, NULL, "no declared function"); return new_backend_impl_error(Implementation, NULL, "no declared function");
} }

View File

@ -6,10 +6,15 @@
#include <set/types.h> #include <set/types.h>
#include <sys/log.h> #include <sys/log.h>
#include <set/set.h> #include <set/set.h>
#include <mem/cache.h>
#define BASE_BYTES 4 #define BASE_BYTES 4
#define BITS_PER_BYTE 8 #define BITS_PER_BYTE 8
char* guid() {
return "uuid";
}
static BackendError get_const_primitive_value(PrimitiveType primitive, static BackendError get_const_primitive_value(PrimitiveType primitive,
LLVMTypeRef llvm_type, LLVMTypeRef llvm_type,
const char* value, const char* value,
@ -34,11 +39,19 @@ static BackendError get_const_composite_value(CompositeType composite,
llvm_value); 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; BackendError err = SUCCESS;
if (value->type->kind == TypeKindReference && compareTypes(value->type, (Type*) &StringLiteralType)) { if (value->type->kind == TypeKindReference && compareTypes(value->type, (Type*) &StringLiteralType)) {
// is string literal // 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 { } else {
err = new_backend_impl_error(Implementation, value->nodePtr, "reference initializer can only be string literals"); 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, BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
LLVMBuilderRef builder,
LLVMGlobalScope* scope, LLVMGlobalScope* scope,
TypeValue* gemstone_value, TypeValue* gemstone_value,
LLVMValueRef* llvm_value) { LLVMValueRef* llvm_value) {
BackendError err = new_backend_impl_error( BackendError err;
Implementation, gemstone_value->nodePtr, "No default value for type");
LLVMTypeRef llvm_type = NULL; LLVMTypeRef llvm_type = NULL;
err = get_type_impl(unit, scope, gemstone_value->type, &llvm_type); err = get_type_impl(unit, scope, gemstone_value->type, &llvm_type);
@ -70,7 +83,7 @@ BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
llvm_value); llvm_value);
break; break;
case TypeKindReference: case TypeKindReference:
err = impl_reference_const(gemstone_value, llvm_value); err = impl_reference_const(unit, builder, gemstone_value, llvm_value);
break; break;
case TypeKindBox: case TypeKindBox:
err = err =
@ -164,7 +177,7 @@ BackendError impl_composite_type(LLVMBackendCompileUnit* unit,
if (composite->sign == Signed) { if (composite->sign == Signed) {
err = impl_float_type(unit, composite->scale, llvm_type); err = impl_float_type(unit, composite->scale, llvm_type);
} else { } else {
ERROR("unsgined floating point not supported"); ERROR("unsigned floating point not supported");
err = new_backend_impl_error( err = new_backend_impl_error(
Implementation, composite->nodePtr, Implementation, composite->nodePtr,
"unsigned floating-point not supported"); "unsigned floating-point not supported");
@ -412,8 +425,7 @@ BackendError get_box_default_value(LLVMBackendCompileUnit* unit,
BackendError get_type_default_value(LLVMBackendCompileUnit* unit, BackendError get_type_default_value(LLVMBackendCompileUnit* unit,
LLVMGlobalScope* scope, Type* gemstone_type, LLVMGlobalScope* scope, Type* gemstone_type,
LLVMValueRef* llvm_value) { LLVMValueRef* llvm_value) {
BackendError err = new_backend_impl_error( BackendError err;
Implementation, gemstone_type->nodePtr, "No default value for type");
LLVMTypeRef llvm_type = NULL; LLVMTypeRef llvm_type = NULL;
err = get_type_impl(unit, scope, gemstone_type, &llvm_type); err = get_type_impl(unit, scope, gemstone_type, &llvm_type);

View File

@ -19,6 +19,7 @@ BackendError get_type_default_value(LLVMBackendCompileUnit* unit,
LLVMValueRef* llvm_value); LLVMValueRef* llvm_value);
BackendError get_const_type_value(LLVMBackendCompileUnit* unit, BackendError get_const_type_value(LLVMBackendCompileUnit* unit,
LLVMBuilderRef builder,
LLVMGlobalScope* scope, LLVMGlobalScope* scope,
TypeValue* gemstone_value, TypeValue* gemstone_value,
LLVMValueRef* llvm_value); LLVMValueRef* llvm_value);

View File

@ -91,6 +91,8 @@ BackendError emit_module_to_file(LLVMBackendCompileUnit* unit,
err = err =
new_backend_impl_error(Implementation, NULL, "failed to emit code"); new_backend_impl_error(Implementation, NULL, "failed to emit code");
LLVMDisposeMessage(error); LLVMDisposeMessage(error);
} else {
print_message(Info, "Generated code was written to: %s", filename);
} }
g_free((void*) 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, llvm_target, target->triple.str, target->cpu.str, target->features.str,
target->opt, target->reloc, target->model); target->opt, target->reloc, target->model);
print_message(Info, "Generating code for: %s", target->triple.str);
if (config->print_asm) { if (config->print_asm) {
err = emit_module_to_file(unit, target_machine, LLVMAssemblyFile, error, err = emit_module_to_file(unit, target_machine, LLVMAssemblyFile, error,
config); config);
@ -206,6 +210,11 @@ static BackendError build_module(LLVMBackendCompileUnit* unit,
return err; 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); err = impl_functions(unit, global_scope, module->functions);
if (err.kind != Success) { if (err.kind != Success) {
return err; return err;

View File

@ -118,7 +118,7 @@ int merge_scale_list(AST_NODE_PTR scale_list, Scale *scale) {
assert(scale_list != NULL); assert(scale_list != NULL);
assert(scale != 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; double scale_in_list = 1.0;
int scale_invalid = scale_factor_from(AST_get_node(scale_list, i)->value, &scale_in_list); 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; composite->sign = Signed;
// check if we have a sign // 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) { 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; return SEMANTIC_ERROR;
} }
@ -177,16 +177,16 @@ int set_impl_composite_type(AST_NODE_PTR ast_type, CompositeType *composite) {
composite->scale = 1.0; composite->scale = 1.0;
// check if we have a list of scale factors // 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) { if (status == SEMANTIC_ERROR) {
return 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); 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) { int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) {
assert(currentNode != NULL); assert(currentNode != NULL);
assert(currentNode->kind == AST_Type || currentNode->kind == AST_Reference); assert(currentNode->kind == AST_Type || currentNode->kind == AST_Reference);
assert(currentNode->child_count > 0); assert(currentNode->children->len > 0);
DEBUG("start Type"); DEBUG("start Type");
int status; int status;
@ -261,7 +261,7 @@ int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) {
return set_impl_reference_type(currentNode, 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 //find type in composites
if (g_hash_table_contains(declaredComposites, typekind) == TRUE) { 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) { if (g_hash_table_contains(declaredBoxes, typekind) == TRUE) {
*type = g_hash_table_lookup(declaredBoxes, typekind); *type = g_hash_table_lookup(declaredBoxes, typekind);
if (currentNode->child_count > 1) { if (currentNode->children->len > 1) {
print_diagnostic(&currentNode->location, Error, "Box type cannot modified"); print_diagnostic(&currentNode->location, Error, "Box type cannot modified");
return SEMANTIC_ERROR; 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 // only one child means either composite or primitive
// try to implement primitive first // try to implement primitive first
// if not successfull continue building a composite // if not successfull continue building a composite
if (currentNode->child_count == 1) { if (currentNode->children->len == 1) {
// type is a primitive // type is a primitive
new_type->kind = TypeKindPrimitive; new_type->kind = TypeKindPrimitive;
@ -298,7 +298,7 @@ int set_get_type_impl(AST_NODE_PTR currentNode, Type **type) {
return SEMANTIC_OK; return SEMANTIC_OK;
} }
print_diagnostic(&currentNode->children[currentNode->child_count - 1]->location, Error, print_diagnostic(&AST_get_last_node(currentNode)->location, Error,
"Expected either primitive or composite type"); "Expected either primitive or composite type");
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
@ -328,7 +328,7 @@ int addVarToScope(Variable *variable);
int createRef(AST_NODE_PTR currentNode, Type **reftype) { int createRef(AST_NODE_PTR currentNode, Type **reftype) {
assert(currentNode != NULL); assert(currentNode != NULL);
assert(currentNode->child_count == 1); assert(currentNode->children->len == 1);
assert(AST_get_node(currentNode, 0)->kind == AST_Type); assert(AST_get_node(currentNode, 0)->kind == AST_Type);
Type *type = malloc(sizeof(Type)); Type *type = malloc(sizeof(Type));
@ -336,7 +336,7 @@ int createRef(AST_NODE_PTR currentNode, Type **reftype) {
referenceType->kind = TypeKindReference; referenceType->kind = TypeKindReference;
referenceType->nodePtr = currentNode; 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) { if (signal) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
@ -349,7 +349,7 @@ int createRef(AST_NODE_PTR currentNode, Type **reftype) {
int createDecl(AST_NODE_PTR currentNode, GArray **variables) { int createDecl(AST_NODE_PTR currentNode, GArray **variables) {
DEBUG("create declaration"); 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 *)); *variables = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *));
@ -359,10 +359,10 @@ int createDecl(AST_NODE_PTR currentNode, GArray **variables) {
int status = SEMANTIC_OK; 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++) { for (size_t i = 0; i < currentNode->children->len; i++) {
switch (currentNode->children[i]->kind) { switch (AST_get_node(currentNode, i)->kind) {
case AST_Storage: case AST_Storage:
DEBUG("fill Qualifier"); DEBUG("fill Qualifier");
decl.qualifier = Qualifier_from_string(AST_get_node(currentNode, i)->value); 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); status = createRef(AST_get_node(currentNode, i), &decl.type);
break; break;
default: default:
PANIC("invalid node type: %ld", currentNode->children[i]->kind); PANIC("invalid node type: %ld", AST_get_node(currentNode, i)->kind);
break; 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 *variable = mem_alloc(MemoryNamespaceSet, sizeof(Variable));
variable->kind = VariableKindDeclaration; variable->kind = VariableKindDeclaration;
variable->nodePtr = currentNode; variable->nodePtr = currentNode;
variable->name = ident_list->children[i]->value; variable->name = AST_get_node(ident_list, i)->value;
variable->impl.declaration = decl; variable->impl.declaration = decl;
g_array_append_val(*variables, variable); g_array_append_val(*variables, variable);
@ -409,9 +409,9 @@ int createDef(AST_NODE_PTR currentNode, GArray **variables) {
DEBUG("create definition"); DEBUG("create definition");
AST_NODE_PTR declaration = currentNode->children[0]; AST_NODE_PTR declaration = AST_get_node(currentNode, 0);
AST_NODE_PTR expression = currentNode->children[1]; AST_NODE_PTR expression = AST_get_node(currentNode, 1);
AST_NODE_PTR ident_list = declaration->children[currentNode->child_count - 1]; AST_NODE_PTR ident_list = AST_get_last_node(declaration);
*variables = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *)); *variables = mem_new_g_array(MemoryNamespaceSet, sizeof(Variable *));
@ -423,17 +423,20 @@ int createDef(AST_NODE_PTR currentNode, GArray **variables) {
int status = SEMANTIC_OK; int status = SEMANTIC_OK;
DEBUG("Child Count: %i", declaration->child_count); DEBUG("Child Count: %i", declaration->children->len);
for (size_t i = 0; i < declaration->child_count; i++) { for (size_t i = 0; i < declaration->children->len; i++) {
switch (declaration->children[i]->kind) {
AST_NODE_PTR child = AST_get_node(declaration, i);
switch (child->kind) {
case AST_Storage: case AST_Storage:
DEBUG("fill Qualifier"); DEBUG("fill Qualifier");
decl.qualifier = Qualifier_from_string(declaration->children[i]->value); decl.qualifier = Qualifier_from_string(child->value);
break; break;
case AST_Reference: case AST_Reference:
case AST_Type: case AST_Type:
DEBUG("fill 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) { if (status == SEMANTIC_ERROR) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
@ -441,7 +444,7 @@ int createDef(AST_NODE_PTR currentNode, GArray **variables) {
case AST_IdentList: case AST_IdentList:
break; break;
default: default:
PANIC("invalid node type: %ld", declaration->children[i]->kind); PANIC("invalid node type: %ld", child->kind);
break; break;
} }
} }
@ -453,12 +456,12 @@ int createDef(AST_NODE_PTR currentNode, GArray **variables) {
} }
def.initializer = name; 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 *variable = mem_alloc(MemoryNamespaceSet, sizeof(Variable));
variable->kind = VariableKindDefinition; variable->kind = VariableKindDefinition;
variable->nodePtr = currentNode; variable->nodePtr = currentNode;
variable->name = ident_list->children[i]->value; variable->name = AST_get_node(ident_list, i)->value;
variable->impl.definiton = def; variable->impl.definiton = def;
g_array_append_val(*variables, variable); 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.nodePtr = currentNode;
ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *)); 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++) { for (size_t i = 0; i < currentNode->children->len; i++) {
Expression *expression = createExpression(currentNode->children[i]); Expression *expression = createExpression(AST_get_node(currentNode, i));
if (NULL == expression) { if (NULL == expression) {
return SEMANTIC_ERROR; 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 *)); ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *));
// fill Operands // fill Operands
for (size_t i = 0; i < currentNode->child_count; i++) { for (size_t i = 0; i < currentNode->children->len; i++) {
Expression *expression = createExpression(currentNode->children[i]); Expression *expression = createExpression(AST_get_node(currentNode, i));
if (NULL == expression) { if (NULL == expression) {
return SEMANTIC_ERROR; 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 *)); ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *));
// fill Operands // fill Operands
for (size_t i = 0; i < currentNode->child_count; i++) { for (size_t i = 0; i < currentNode->children->len; i++) {
Expression *expression = createExpression(currentNode->children[i]); Expression *expression = createExpression(AST_get_node(currentNode, i));
if (NULL == expression) { if (NULL == expression) {
return SEMANTIC_ERROR; 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 *)); ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *));
//fill Operand //fill Operand
Expression *expression = createExpression(currentNode->children[0]); Expression *expression = createExpression(AST_get_node(currentNode, 0));
if (NULL == expression) { if (NULL == expression) {
return SEMANTIC_ERROR; 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 *)); ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *));
// fill Operands // fill Operands
for (size_t i = 0; i < currentNode->child_count; i++) { for (size_t i = 0; i < currentNode->children->len; i++) {
Expression *expression = createExpression(currentNode->children[i]); Expression *expression = createExpression(AST_get_node(currentNode, i));
if (NULL == expression) { if (NULL == expression) {
return SEMANTIC_ERROR; 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 *)); ParentExpression->impl.operation.operands = g_array_new(FALSE, FALSE, sizeof(Expression *));
//fill Operand //fill Operand
Expression *expression = createExpression(currentNode->children[0]); Expression *expression = createExpression(AST_get_node(currentNode, 0));
if (NULL == expression) { if (NULL == expression) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
@ -1186,12 +1189,12 @@ GArray *getBoxMember(Type *currentBoxType, GArray *names) {
int createBoxAccess(Expression *ParentExpression, AST_NODE_PTR currentNode) { 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; Variable *boxVariable = NULL;
int status = getVariableFromScope(boxname, &boxVariable); int status = getVariableFromScope(boxname, &boxVariable);
if (status == SEMANTIC_ERROR) { if (status == SEMANTIC_ERROR) {
print_diagnostic(&currentNode->children[0]->location, Error, print_diagnostic(&AST_get_node(currentNode, 0)->location, Error,
"Variable of name `%s` does not exist"); "Variable of name `%s` does not exist");
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
@ -1221,12 +1224,12 @@ int createBoxAccess(Expression *ParentExpression, AST_NODE_PTR currentNode) {
//first one is the box itself //first one is the box itself
GArray *names = mem_alloc(MemoryNamespaceSet, sizeof(GArray)); GArray *names = mem_alloc(MemoryNamespaceSet, sizeof(GArray));
if (currentNode->kind == AST_IdentList) { if (currentNode->kind == AST_IdentList) {
for (size_t i = 1; i < currentNode->child_count; i++) { for (size_t i = 1; i < currentNode->children->len; i++) {
g_array_append_val(names, currentNode->children[i]->value); g_array_append_val(names, AST_get_node(currentNode, i)->value);
} }
} else if (currentNode->kind == AST_List) { } else if (currentNode->kind == AST_List) {
for (size_t i = 1; i < currentNode->children[1]->child_count; i++) { for (size_t i = 1; i < AST_get_node(currentNode, 1)->children->len; i++) {
g_array_append_val(names, currentNode->children[1]->children[i]->value); g_array_append_val(names, AST_get_node(AST_get_node(currentNode, 1), i)->value);
} }
} else { } else {
PANIC("current Node is not an Access"); PANIC("current Node is not an Access");
@ -1243,21 +1246,22 @@ int createTypeCast(Expression *ParentExpression, AST_NODE_PTR currentNode) {
DEBUG("create type cast"); DEBUG("create type cast");
ParentExpression->impl.typecast.nodePtr = currentNode; 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) { if (ParentExpression->impl.typecast.operand == NULL) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
if (ParentExpression->impl.typecast.operand->result->kind != TypeKindComposite 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; return SEMANTIC_ERROR;
} }
Type *target = mem_alloc(MemoryNamespaceSet, sizeof(Type)); 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) { if (status) {
print_diagnostic(&currentNode->children[1]->location, Error, "Unknown type"); print_diagnostic(&AST_get_node(currentNode, 1)->location, Error, "Unknown type");
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
ParentExpression->impl.typecast.targetType = target; 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) { int createTransmute(Expression *ParentExpression, AST_NODE_PTR currentNode) {
ParentExpression->impl.transmute.nodePtr = 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) { if (ParentExpression->impl.transmute.operand == NULL) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
Type *target = mem_alloc(MemoryNamespaceSet, sizeof(Type)); 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) { if (status) {
print_diagnostic(&currentNode->children[1]->location, Error, "Unknown type"); print_diagnostic(&AST_get_node(currentNode, 1)->location, Error, "Unknown type");
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
@ -1288,7 +1292,7 @@ int createTransmute(Expression *ParentExpression, AST_NODE_PTR currentNode) {
} }
int createDeref(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; Dereference deref;
deref.nodePtr = currentNode; deref.nodePtr = currentNode;
AST_NODE_PTR expression_node = AST_get_node(currentNode, 1); 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; Type *indexType = deref.index->result;
//indexType can only be a composite or a primitive //indexType can only be a composite or a primitive
if (indexType->kind != TypeKindComposite && indexType->kind != TypeKindPrimitive) { 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"); "Index must a primitive int or composite variation");
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
@ -1345,7 +1349,7 @@ int createDeref(Expression *ParentExpression, AST_NODE_PTR currentNode) {
int createAddressOf(Expression *ParentExpression, AST_NODE_PTR currentNode) { int createAddressOf(Expression *ParentExpression, AST_NODE_PTR currentNode) {
assert(currentNode != NULL); assert(currentNode != NULL);
assert(currentNode->child_count == 1); assert(currentNode->children->len == 1);
AddressOf address_of; AddressOf address_of;
address_of.node_ptr = currentNode; address_of.node_ptr = currentNode;
@ -1540,14 +1544,15 @@ int createAssign(Statement *ParentStatement, AST_NODE_PTR currentNode) {
DEBUG("create Assign"); DEBUG("create Assign");
Assignment assign; Assignment assign;
assign.nodePtr = currentNode; 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); int status = getVariableFromScope(varName, &assign.variable);
if (status) { if (status) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
assign.value = createExpression(currentNode->children[1]); assign.value = createExpression(AST_get_node(currentNode, 1));
if (assign.value == NULL) { if (assign.value == NULL) {
return SEMANTIC_ERROR; 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); GHashTable *lowerScope = g_hash_table_new(g_str_hash, g_str_equal);
g_array_append_val(Scope, lowerScope); 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)); int signal = createStatement(block, AST_get_node(currentNode, i));
if (signal) { if (signal) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
@ -1600,11 +1605,11 @@ int createWhile(Statement *ParentStatement, AST_NODE_PTR currentNode) {
While whileStruct; While whileStruct;
whileStruct.nodePtr = currentNode; whileStruct.nodePtr = currentNode;
whileStruct.conditon = createExpression(currentNode->children[0]); whileStruct.conditon = createExpression(AST_get_node(currentNode, 0));
if (NULL == whileStruct.conditon) { if (NULL == whileStruct.conditon) {
return SEMANTIC_ERROR; 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); int signal = fillBlock(&whileStruct.block, statementList);
if (signal) { if (signal) {
@ -1619,13 +1624,13 @@ int createIf(Branch *Parentbranch, AST_NODE_PTR currentNode) {
If ifbranch; If ifbranch;
ifbranch.nodePtr = currentNode; ifbranch.nodePtr = currentNode;
Expression *expression = createExpression(currentNode->children[0]); Expression *expression = createExpression(AST_get_node(currentNode, 0));
if (NULL == expression) { if (NULL == expression) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
ifbranch.conditon = expression; ifbranch.conditon = expression;
int status = fillBlock(&ifbranch.block, currentNode->children[1]); int status = fillBlock(&ifbranch.block, AST_get_node(currentNode, 1));
if (status) { if (status) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
@ -1638,7 +1643,7 @@ int createElse(Branch *Parentbranch, AST_NODE_PTR currentNode) {
Else elseBranch; Else elseBranch;
elseBranch.nodePtr = currentNode; elseBranch.nodePtr = currentNode;
int status = fillBlock(&elseBranch.block, currentNode->children[0]); int status = fillBlock(&elseBranch.block, AST_get_node(currentNode, 0));
if (status) { if (status) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
@ -1655,12 +1660,12 @@ int createElseIf(Branch *Parentbranch, AST_NODE_PTR currentNode) {
Parentbranch->elseIfBranches = mem_new_g_array(MemoryNamespaceSet, sizeof(ElseIf)); 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) { if (NULL == expression) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
elseIfBranch.conditon = expression; elseIfBranch.conditon = expression;
int status = fillBlock(&elseIfBranch.block, currentNode->children[1]); int status = fillBlock(&elseIfBranch.block, AST_get_node(currentNode, 1));
if (status) { if (status) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
@ -1675,22 +1680,22 @@ int createBranch(Statement *ParentStatement, AST_NODE_PTR currentNode) {
branch.elseBranch.block.statemnts = NULL; branch.elseBranch.block.statemnts = NULL;
branch.elseIfBranches = NULL; branch.elseIfBranches = NULL;
for (size_t i = 0; i < currentNode->child_count; i++) { for (size_t i = 0; i < currentNode->children->len; i++) {
switch (currentNode->children[i]->kind) { switch (AST_get_node(currentNode, i)->kind) {
case AST_If: case AST_If:
if (createIf(&branch, currentNode->children[i])) { if (createIf(&branch, AST_get_node(currentNode, i))) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
break; break;
case AST_IfElse: case AST_IfElse:
if (createElseIf(&branch, currentNode->children[i])) { if (createElseIf(&branch, AST_get_node(currentNode, i))) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
break; break;
case AST_Else: case AST_Else:
if (createElse(&branch, currentNode->children[i])) { if (createElse(&branch, AST_get_node(currentNode, i))) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
break; break;
@ -1708,7 +1713,7 @@ int getFunction(const char *name, Function **function);
int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) { int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) {
assert(currentNode != NULL); 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 argsListNode = AST_get_node(currentNode, 1);
AST_NODE_PTR nameNode = AST_get_node(currentNode, 0); 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) { if (nameNode->kind == AST_IdentList) {
assert(nameNode->child_count > 1); assert(nameNode->children->len > 1);
//idents.boxname.funname() //idents.boxname.funname()
//only boxname and funname are needed, because the combination is unique //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 *boxName = AST_get_node(nameNode, (nameNode->children->len - 2))->value;
const char *funName = AST_get_node(nameNode, (nameNode->child_count - 1))->value; const char *funName = AST_get_node(nameNode, (nameNode->children->len - 1))->value;
const char *name = g_strjoin("", boxName, ".", funName, NULL); const char *name = g_strjoin("", boxName, ".", funName, NULL);
@ -1750,8 +1755,8 @@ int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) {
} }
size_t count = 0; size_t count = 0;
for (size_t i = 0; i < argsListNode->child_count; i++) { for (size_t i = 0; i < argsListNode->children->len; i++) {
count += AST_get_node(argsListNode, i)->child_count; count += AST_get_node(argsListNode, i)->children->len;
} }
if (count != paramCount) { if (count != paramCount) {
@ -1762,14 +1767,16 @@ int createfuncall(Statement *parentStatement, AST_NODE_PTR currentNode) {
GArray *expressions = mem_new_g_array(MemoryNamespaceSet, (sizeof(Expression *))); GArray *expressions = mem_new_g_array(MemoryNamespaceSet, (sizeof(Expression *)));
//exprlists //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); AST_NODE_PTR currentExprList = AST_get_node(argsListNode, i);
for (size_t j = 0; j < currentExprList->child_count; j++) { for (int j = ((int) currentExprList->children->len) -1; j >= 0; j--) {
Expression *expr = createExpression(AST_get_node(currentExprList, j)); AST_NODE_PTR expr_node = AST_get_node(currentExprList, j);
Expression *expr = createExpression(expr_node);
if (expr == NULL) { if (expr == NULL) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
g_array_append_val(expressions, expr); 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) { int createParam(GArray *Paramlist, AST_NODE_PTR currentNode) {
assert(currentNode->kind == AST_Parameter); assert(currentNode->kind == AST_Parameter);
DEBUG("start param"); 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 paramdecl = AST_get_node(currentNode, 1);
AST_NODE_PTR ioQualifierList = currentNode->children[0]; AST_NODE_PTR ioQualifierList = AST_get_node(currentNode, 0);
ParameterDeclaration decl; ParameterDeclaration decl;
decl.nodePtr = paramdecl; decl.nodePtr = paramdecl;
DEBUG("iolistnode child count: %i", ioQualifierList->child_count); DEBUG("iolistnode child count: %i", ioQualifierList->children->len);
if (ioQualifierList->child_count == 2) { if (ioQualifierList->children->len == 2) {
decl.qualifier = InOut; decl.qualifier = InOut;
} else if (ioQualifierList->child_count == 1) { } else if (ioQualifierList->children->len == 1) {
if (strcmp(ioQualifierList->children[0]->value, "in") == 0) { if (strcmp(AST_get_node(ioQualifierList, 0)->value, "in") == 0) {
decl.qualifier = In; 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; decl.qualifier = Out;
} else { } else {
PANIC("IO_Qualifier is not in or out"); 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"); 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; return SEMANTIC_ERROR;
} }
Parameter param; Parameter param;
param.nodePtr = currentNode; param.nodePtr = currentNode;
param.kind = ParameterDeclarationKind; param.kind = ParameterDeclarationKind;
param.impl.declaration = decl; param.impl.declaration = decl;
param.name = paramdecl->children[1]->value; param.name = AST_get_node(paramdecl, 1)->value;
DEBUG("param name: %s", param.name); DEBUG("param name: %s", param.name);
g_array_append_val(Paramlist, param); 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; paramvar->impl.declaration.type = param.impl.declaration.type;
if (g_hash_table_contains(functionParameter, param.name)) { if (g_hash_table_contains(functionParameter, param.name)) {
print_diagnostic(&param.nodePtr->location, Error, "Names of function parameters must be unique"); print_diagnostic(&param.nodePtr->location, Error, "Names of function parameters must be unique: %s", param.name);
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
g_hash_table_insert(functionParameter, (gpointer) param.name, paramvar); 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) { int createFunDef(Function *Parentfunction, AST_NODE_PTR currentNode) {
DEBUG("start fundef"); DEBUG("start fundef");
AST_NODE_PTR nameNode = currentNode->children[0]; AST_NODE_PTR nameNode = AST_get_node(currentNode, 0);
AST_NODE_PTR paramlistlist = currentNode->children[1]; AST_NODE_PTR paramlistlist = AST_get_node(currentNode, 1);
AST_NODE_PTR statementlist = currentNode->children[2]; AST_NODE_PTR statementlist = AST_get_node(currentNode, 2);
FunctionDefinition fundef; FunctionDefinition fundef;
@ -1941,15 +1948,15 @@ int createFunDef(Function *Parentfunction, AST_NODE_PTR currentNode) {
fundef.body = mem_alloc(MemoryNamespaceSet, sizeof(Block)); fundef.body = mem_alloc(MemoryNamespaceSet, sizeof(Block));
fundef.parameter = g_array_new(FALSE, FALSE, sizeof(Parameter)); fundef.parameter = g_array_new(FALSE, FALSE, sizeof(Parameter));
DEBUG("paramlistlist child count: %i", paramlistlist->child_count); DEBUG("paramlistlist child count: %i", paramlistlist->children->len);
for (size_t i = 0; i < paramlistlist->child_count; i++) { for (size_t i = 0; i < paramlistlist->children->len; i++) {
//all parameterlists //all parameterlists
AST_NODE_PTR paramlist = paramlistlist->children[i]; AST_NODE_PTR paramlist = AST_get_node(paramlistlist, i);
DEBUG("paramlist child count: %i", paramlist->child_count); DEBUG("paramlist child count: %i", paramlist->children->len);
for (size_t j = 0; j < paramlist->child_count; j++) { 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))) { if (createParam(fundef.parameter, AST_get_node(paramlist, j))) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
@ -2039,8 +2046,8 @@ int getFunction(const char *name, Function **function) {
int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) { int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) {
DEBUG("start fundecl"); DEBUG("start fundecl");
AST_NODE_PTR nameNode = currentNode->children[0]; AST_NODE_PTR nameNode = AST_get_node(currentNode, 0);
AST_NODE_PTR paramlistlist = currentNode->children[1]; AST_NODE_PTR paramlistlist = AST_get_node(currentNode, 1);
FunctionDeclaration fundecl; FunctionDeclaration fundecl;
@ -2048,14 +2055,14 @@ int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) {
fundecl.name = nameNode->value; fundecl.name = nameNode->value;
fundecl.parameter = mem_new_g_array(MemoryNamespaceSet, sizeof(Parameter)); 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 //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++) { for (int j = ((int) paramlist->children->len) - 1; j >= 0; j--) {
AST_NODE_PTR param = AST_get_node(paramlist, j);
if (createParam(fundecl.parameter, paramlist->children[i])) { if (createParam(fundecl.parameter, param)) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
} }
@ -2065,6 +2072,7 @@ int createFunDecl(Function *Parentfunction, AST_NODE_PTR currentNode) {
Parentfunction->kind = FunctionDeclarationKind; Parentfunction->kind = FunctionDeclarationKind;
Parentfunction->impl.declaration = fundecl; Parentfunction->impl.declaration = fundecl;
Parentfunction->name = fundecl.name; Parentfunction->name = fundecl.name;
return SEMANTIC_OK; return SEMANTIC_OK;
} }
@ -2072,12 +2080,12 @@ int createFunction(Function *function, AST_NODE_PTR currentNode) {
assert(currentNode->kind == AST_Fun); assert(currentNode->kind == AST_Fun);
functionParameter = g_hash_table_new(g_str_hash, g_str_equal); 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); int signal = createFunDecl(function, currentNode);
if (signal) { if (signal) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
} else if (currentNode->child_count == 3) { } else if (currentNode->children->len == 3) {
int signal = createFunDef(function, currentNode); int signal = createFunDef(function, currentNode);
if (signal) { if (signal) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
@ -2100,15 +2108,15 @@ int createFunction(Function *function, AST_NODE_PTR currentNode) {
int createDeclMember(BoxType *ParentBox, AST_NODE_PTR currentNode) { int createDeclMember(BoxType *ParentBox, AST_NODE_PTR currentNode) {
Type *declType = mem_alloc(MemoryNamespaceSet, sizeof(Type)); 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) { if (status) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
AST_NODE_PTR nameList = currentNode->children[1]; AST_NODE_PTR nameList = AST_get_node(currentNode, 1);
for (size_t i = 0; i < nameList->child_count; i++) { for (size_t i = 0; i < nameList->children->len; i++) {
BoxMember *decl = mem_alloc(MemoryNamespaceSet, sizeof(BoxMember)); 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->nodePtr = currentNode;
decl->box = ParentBox; decl->box = ParentBox;
decl->initalizer = NULL; decl->initalizer = NULL;
@ -2122,12 +2130,12 @@ int createDeclMember(BoxType *ParentBox, AST_NODE_PTR currentNode) {
} }
int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode) { int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode) {
AST_NODE_PTR declNode = currentNode->children[0]; AST_NODE_PTR declNode = AST_get_node(currentNode, 0);
AST_NODE_PTR expressionNode = currentNode->children[1]; AST_NODE_PTR expressionNode = AST_get_node(currentNode, 1);
AST_NODE_PTR nameList = declNode->children[1]; AST_NODE_PTR nameList = AST_get_node(declNode, 1);
Type *declType = mem_alloc(MemoryNamespaceSet, sizeof(Type)); 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) { if (status) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
@ -2137,12 +2145,12 @@ int createDefMember(BoxType *ParentBox, AST_NODE_PTR currentNode) {
return SEMANTIC_ERROR; 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)); BoxMember *def = mem_alloc(MemoryNamespaceSet, sizeof(BoxMember));
def->box = ParentBox; def->box = ParentBox;
def->type = declType; def->type = declType;
def->initalizer = init; def->initalizer = init;
def->name = nameList->children[i]->value; def->name = AST_get_node(nameList, i)->value;
def->nodePtr = currentNode; def->nodePtr = currentNode;
if (g_hash_table_contains(ParentBox->member, (gpointer) def->name)) { if (g_hash_table_contains(ParentBox->member, (gpointer) def->name)) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
@ -2184,18 +2192,18 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode) {
BoxType *box = mem_alloc(MemoryNamespaceSet, sizeof(BoxType)); BoxType *box = mem_alloc(MemoryNamespaceSet, sizeof(BoxType));
box->nodePtr = currentNode; box->nodePtr = currentNode;
const char *boxName = currentNode->children[0]->value; const char *boxName = AST_get_node(currentNode, 0)->value;
AST_NODE_PTR boxMemberList = currentNode->children[1]; AST_NODE_PTR boxMemberList = AST_get_node(currentNode, 1);
Type *boxType = mem_alloc(MemoryNamespaceSet, sizeof(Type)); Type *boxType = mem_alloc(MemoryNamespaceSet, sizeof(Type));
boxType->nodePtr = currentNode; boxType->nodePtr = currentNode;
boxType->impl.box = box; boxType->impl.box = box;
for (size_t i = 0; boxMemberList->child_count; i++) { for (size_t i = 0; boxMemberList->children->len; i++) {
switch (boxMemberList->children[i]->kind) { switch (AST_get_node(boxMemberList, i)->kind) {
case AST_Decl: case AST_Decl:
case AST_Def: case AST_Def:
if (createDeclMember(box, boxMemberList->children[i])) { if (createDeclMember(box, AST_get_node(boxMemberList, i))) {
return SEMANTIC_ERROR; return SEMANTIC_ERROR;
} }
break; break;
@ -2220,8 +2228,8 @@ int createBox(GHashTable *boxes, AST_NODE_PTR currentNode) {
int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode) { int createTypeDef(GHashTable *types, AST_NODE_PTR currentNode) {
DEBUG("create Type define"); DEBUG("create Type define");
AST_NODE_PTR typeNode = currentNode->children[0]; AST_NODE_PTR typeNode = AST_get_node(currentNode, 0);
AST_NODE_PTR nameNode = currentNode->children[1]; AST_NODE_PTR nameNode = AST_get_node(currentNode, 1);
Type *type = mem_alloc(MemoryNamespaceSet, sizeof(Type)); Type *type = mem_alloc(MemoryNamespaceSet, sizeof(Type));
int status = set_get_type_impl(typeNode, &type); int status = set_get_type_impl(typeNode, &type);
@ -2283,12 +2291,12 @@ Module *create_set(AST_NODE_PTR currentNode) {
DEBUG("created Module struct"); DEBUG("created Module struct");
for (size_t i = 0; i < currentNode->child_count; i++) { for (size_t i = 0; i < currentNode->children->len; i++) {
DEBUG("created Child with type: %i", currentNode->children[i]->kind); DEBUG("created Child with type: %i", AST_get_node(currentNode, i)->kind);
switch (currentNode->children[i]->kind) { switch (AST_get_node(currentNode, i)->kind) {
case AST_Decl: { case AST_Decl: {
GArray *vars = NULL; GArray *vars = NULL;
int status = createDecl(currentNode->children[i], &vars); int status = createDecl(AST_get_node(currentNode, i), &vars);
if (status) { if (status) {
return NULL; return NULL;
} }
@ -2301,7 +2309,7 @@ Module *create_set(AST_NODE_PTR currentNode) {
} }
case AST_Def: { case AST_Def: {
GArray *vars; GArray *vars;
int status = createDef(currentNode->children[i], &vars); int status = createDef(AST_get_node(currentNode, i), &vars);
if (status) { if (status) {
return NULL; return NULL;
} }
@ -2313,7 +2321,7 @@ Module *create_set(AST_NODE_PTR currentNode) {
break; break;
} }
case AST_Box: { case AST_Box: {
int status = createBox(boxes, currentNode->children[i]); int status = createBox(boxes, AST_get_node(currentNode, i));
if (status) { if (status) {
return NULL; return NULL;
} }
@ -2324,7 +2332,7 @@ Module *create_set(AST_NODE_PTR currentNode) {
DEBUG("start function"); DEBUG("start function");
Function *function = mem_alloc(MemoryNamespaceSet, sizeof(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; return NULL;
} }
@ -2340,7 +2348,7 @@ Module *create_set(AST_NODE_PTR currentNode) {
break; break;
} }
case AST_Typedef: { case AST_Typedef: {
int status = createTypeDef(types, currentNode->children[i]); int status = createTypeDef(types, AST_get_node(currentNode, i));
if (status) { if (status) {
return NULL; return NULL;
} }
@ -2349,7 +2357,7 @@ Module *create_set(AST_NODE_PTR currentNode) {
} }
case AST_Import: case AST_Import:
DEBUG("create 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; break;
default: default:
INFO("Provided source file could not be parsed because of semantic error."); INFO("Provided source file could not be parsed because of semantic error.");

View File

@ -69,6 +69,7 @@
%type <node_ptr> typecast %type <node_ptr> typecast
%type <node_ptr> reinterpretcast %type <node_ptr> reinterpretcast
%type <node_ptr> program %type <node_ptr> program
%type <node_ptr> storage_expr
%token KeyInt %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");} | KeyStatic {$$ = AST_new_node(new_loc(), AST_Storage, "static");}
| KeyLocal {$$ = AST_new_node(new_loc(), AST_Storage, "local");}; | KeyLocal {$$ = AST_new_node(new_loc(), AST_Storage, "local");};
assign: Ident '=' expr { AST_NODE_PTR assign = AST_new_node(new_loc(), AST_Assign, NULL); assign: storage_expr '=' 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, $1);
AST_push_node(assign, ident);
AST_push_node(assign, $3); AST_push_node(assign, $3);
$$ = assign; $$ = assign; };
DEBUG("Assignment"); }
storage_expr: Ident { $$ = AST_new_node(new_loc(), AST_Ident, $1); }
| boxaccess '=' expr | boxaccess { $$ = $1; }
| boxselfaccess '=' expr ; | 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");} sign: KeySigned {$$ = AST_new_node(new_loc(), AST_Sign, "signed");}
| KeyUnsigned{$$ = AST_new_node(new_loc(), AST_Sign, "unsigned");}; | KeyUnsigned{$$ = AST_new_node(new_loc(), AST_Sign, "unsigned");};