added: new parser rules for assignments
This commit is contained in:
parent
984c34cfc7
commit
30417592df
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
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_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(¤tNode->location, Error, "Box type cannot modified");
|
print_diagnostic(¤tNode->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(¤tNode->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(¤tNode->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(¤tNode->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(¤tNode->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(¶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;
|
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.");
|
||||||
|
|
|
@ -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"); }
|
|
||||||
|
|
||||||
| boxaccess '=' expr
|
storage_expr: Ident { $$ = AST_new_node(new_loc(), AST_Ident, $1); }
|
||||||
| boxselfaccess '=' expr ;
|
| 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");}
|
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");};
|
||||||
|
|
Loading…
Reference in New Issue