diff options
Diffstat (limited to 'src/ast.c')
-rw-r--r-- | src/ast.c | 118 |
1 files changed, 102 insertions, 16 deletions
@@ -1,9 +1,19 @@ #include "../include/ast.h" +#include "../include/parser.h" #include "../include/std/log.h" #include "../include/std/hash.h" #include <assert.h> -static void ast_resolve(Ast *self); +#define throw(result) do { longjmp(context->env, (result)); } while(0) +#define throw_if_error(result) \ +do { \ + int return_if_result; \ + return_if_result = (result); \ + if((return_if_result) != 0) \ + throw(return_if_result); \ +} while(0) + +static void ast_resolve(Ast *self, AstCompilerContext *context); Ast ast_none() { Ast ast; @@ -12,10 +22,17 @@ Ast ast_none() { return ast; } +void ast_init(Ast *self, AstValue value, AstType type) { + self->value = value; + self->type = type; + self->resolve_status = AST_NOT_RESOLVED; +} + BufferView ast_get_name(Ast *self) { BufferView name; switch(self->type) { case AST_NONE: + case AST_FUNCTION_DECL: case AST_IMPORT: case AST_STRING: case AST_NUMBER: @@ -25,9 +42,6 @@ BufferView ast_get_name(Ast *self) { 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; @@ -39,7 +53,6 @@ BufferView ast_get_name(Ast *self) { } int funcdecl_init(FunctionDecl *self, ScopedAllocator *allocator) { - self->name = create_buffer_view_null(); return scope_init(&self->body, allocator); } @@ -49,7 +62,7 @@ int funccall_init(FunctionCall *self, BufferView name, ScopedAllocator *allocato } void lhsexpr_init(LhsExpr *self, int isConst, BufferView var_name) { - self->isConst = isConst; + self->is_const = isConst; self->type_name = create_buffer_view_null(); self->var_name = var_name; self->rhs_expr = ast_none(); @@ -70,6 +83,11 @@ void number_init(Number *self, i64 value, bool is_integer) { self->is_integer = is_integer; } +void variable_init(Variable *self, BufferView name) { + self->name = name; + self->resolved_variable = ast_none(); +} + void binop_init(Binop *self) { self->lhs = ast_none(); self->rhs = ast_none(); @@ -103,29 +121,97 @@ int scope_add_child(Scope *self, Ast *child) { return AST_ERR; } -void scope_resolve(Scope *self) { +void scope_resolve(Scope *self, AstCompilerContext *context) { 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); + ast_resolve(ast, context); + } +} + +static void lhs_resolve(LhsExpr *self, AstCompilerContext *context) { + /* TODO: Implement */ + amal_log_debug("Lhs resolve %s name: %.*s, type: %.*s", + self->is_const ? "const" : "var", + self->var_name.size, self->var_name.data, + self->type_name.size, self->type_name.data); + ast_resolve(&self->rhs_expr, context); +} + +static void funcdecl_resolve(FunctionDecl *self, AstCompilerContext *context) { + /* TODO: Implement */ + amal_log_debug("funcdecl resolve"); + scope_resolve(&self->body, context); +} + +static void funccall_resolve(FunctionCall *self, AstCompilerContext *context) { + /* TODO: Implement */ + Ast *ast; + Ast *ast_end; + ast = buffer_start(&self->args); + ast_end = buffer_end(&self->args); + amal_log_debug("funccall resolve, func name: %.*s", self->name.size, self->name.data); + for(; ast != ast_end; ++ast) { + ast_resolve(ast, context); } } -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);*/ +static void variable_resolve(Variable *self, AstCompilerContext *context) { + /* TODO: Implement */ + amal_log_debug("variable resolve, var name: %.*s", self->name.size, self->name.data); + (void)context; } -void ast_resolve(Ast *self) { +static void binop_resolve(Binop *self, AstCompilerContext *context) { + /* TODO: Implement */ + ast_resolve(&self->lhs, context); + ast_resolve(&self->rhs, context); +} + +static BufferView ast_get_code_reference(Ast *self) { + return ast_get_name(self); +} + +void ast_resolve(Ast *self, AstCompilerContext *context) { + if(self->resolve_status == AST_RESOLVED) { + return; + } else if(self->resolve_status == AST_RESOLVING) { + tokenizer_get_code_reference_index(&context->parser->tokenizer, ast_get_code_reference(self).data); + tokenizer_print_error(&context->parser->tokenizer, + tokenizer_get_code_reference_index(&context->parser->tokenizer, ast_get_code_reference(self).data), + "Found recursive declaration"); + throw(AST_ERR); + } + + self->resolve_status = AST_RESOLVING; switch(self->type) { + case AST_NONE: + case AST_NUMBER: + /* Nothing to resolve for numbers */ + break; + case AST_FUNCTION_DECL: + funcdecl_resolve(self->value.func_decl, context); + break; + case AST_FUNCTION_CALL: + funccall_resolve(self->value.func_call, context); + break; case AST_LHS: - lhs_resolve(self->value.lhs_expr); + lhs_resolve(self->value.lhs_expr, context); 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"); + case AST_IMPORT: + /* TODO: When @import(...).data syntax is added, implement the resolve for it */ + break; + case AST_STRING: + /* TODO: Convert special combinations. For example \n to newline */ + break; + case AST_VARIABLE: + variable_resolve(self->value.variable, context); + break; + case AST_BINOP: + binop_resolve(self->value.binop, context); break; } + self->resolve_status = AST_RESOLVED; } |