aboutsummaryrefslogtreecommitdiff
path: root/src/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast.c')
-rw-r--r--src/ast.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/src/ast.c b/src/ast.c
index c28b314..2154531 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -1,5 +1,6 @@
#include "../include/ast.h"
#include "../include/std/log.h"
+#include "../include/std/hash.h"
#include <assert.h>
static void ast_resolve(Ast *self);
@@ -11,9 +12,35 @@ Ast ast_none() {
return ast;
}
+BufferView ast_get_name(Ast *self) {
+ BufferView name;
+ switch(self->type) {
+ case AST_NONE:
+ case AST_IMPORT:
+ case AST_STRING:
+ case AST_NUMBER:
+ case AST_BINOP:
+ name = create_buffer_view_null();
+ break;
+ case AST_LHS:
+ name = self->value.lhs_expr->var_name;
+ break;
+ case AST_FUNCTION_DECL:
+ name = self->value.func_decl->name;
+ break;
+ case AST_FUNCTION_CALL:
+ name = self->value.func_call->name;
+ break;
+ case AST_VARIABLE:
+ name = self->value.variable->name;
+ break;
+ }
+ return name;
+}
+
int funcdecl_init(FunctionDecl *self, ScopedAllocator *allocator) {
self->name = create_buffer_view_null();
- return buffer_init(&self->body, allocator);
+ return scope_init(&self->body, allocator);
}
int funccall_init(FunctionCall *self, BufferView name, ScopedAllocator *allocator) {
@@ -51,7 +78,29 @@ void binop_init(Binop *self) {
}
int scope_init(Scope *self, ScopedAllocator *allocator) {
- return buffer_init(&self->ast_objects, allocator);
+ return_if_error(buffer_init(&self->ast_objects, allocator));
+ return_if_error(hash_map_init(&self->named_objects, allocator, sizeof(Ast), hash_compare_string, amal_hash_string));
+ return 0;
+}
+
+int scope_add_child(Scope *self, Ast *child) {
+ BufferView child_name;
+ Ast existing_child;
+ bool child_already_exists;
+
+ child_name = ast_get_name(child);
+ if(child_name.data) {
+ child_already_exists = hash_map_get(&self->named_objects, child_name, &existing_child);
+ if(child_already_exists)
+ return AST_ERR_DEF_DUP;
+
+ cleanup_if_error(hash_map_insert(&self->named_objects, child_name, child));
+ }
+ cleanup_if_error(buffer_append(&self->ast_objects, child, sizeof(Ast)));
+ return 0;
+
+ cleanup:
+ return AST_ERR;
}
void scope_resolve(Scope *self) {
@@ -74,6 +123,7 @@ void ast_resolve(Ast *self) {
lhs_resolve(self->value.lhs_expr);
break;
default:
+ /* TODO: Implement all, and remove default case to give error when adding new ast type */
assert(bool_false && "ast_resolve not implemented for type");
break;
}