added: new parser rules for assignments
This commit is contained in:
parent
984c34cfc7
commit
30417592df
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -40,6 +40,7 @@ void flush(handle dev) {
|
|||
// Compile for Linux and BSD
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// savely cast a 64-bit pointer down to a 32-bit value
|
||||
// this assumes that 64-bit system will use 32-bit handles
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -6,10 +6,15 @@
|
|||
#include <set/types.h>
|
||||
#include <sys/log.h>
|
||||
#include <set/set.h>
|
||||
#include <mem/cache.h>
|
||||
|
||||
#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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
284
src/set/set.c
284
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.");
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
%type <node_ptr> typecast
|
||||
%type <node_ptr> reinterpretcast
|
||||
%type <node_ptr> program
|
||||
%type <node_ptr> 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"); }
|
||||
$$ = assign; };
|
||||
|
||||
| boxaccess '=' expr
|
||||
| boxselfaccess '=' expr ;
|
||||
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");};
|
||||
|
|
Loading…
Reference in New Issue