#include "../include/ast.h" #include "../include/std/log.h" #include "../include/std/hash.h" #include static void ast_resolve(Ast *self); Ast ast_none() { Ast ast; ast.value.func_decl = NULL; ast.type = 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 scope_init(&self->body, allocator); } int funccall_init(FunctionCall *self, BufferView name, ScopedAllocator *allocator) { self->name = name; return buffer_init(&self->args, allocator); } void lhsexpr_init(LhsExpr *self, int isConst, BufferView var_name) { self->isConst = isConst; self->type_name = create_buffer_view_null(); self->var_name = var_name; self->rhs_expr = ast_none(); } void import_init(Import *self, BufferView path) { self->path = path; } int string_init(String *self, BufferView str) { /* TODO: Convert special characters. For example \n should be converted to binary newline etc */ self->str = str; return 0; } void number_init(Number *self, i64 value, bool is_integer) { self->value.integer = value; self->is_integer = is_integer; } void binop_init(Binop *self) { self->lhs = ast_none(); self->rhs = ast_none(); self->type = BINOP_ADD; self->grouped = bool_false; } int scope_init(Scope *self, ScopedAllocator *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) { Ast *ast; Ast *ast_end; ast = buffer_start(&self->ast_objects); ast_end = buffer_end(&self->ast_objects); for(; ast != ast_end; ++ast) { ast_resolve(ast); } } static void lhs_resolve(LhsExpr *self) { amal_log_debug("Lhs resolve var name: %.*s", self->var_name.size, self->var_name.data); /*ast_resolve(&self->rhs_expr);*/ } void ast_resolve(Ast *self) { switch(self->type) { case AST_LHS: 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; } }