aboutsummaryrefslogtreecommitdiff
path: root/src/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast.c')
-rw-r--r--src/ast.c118
1 files changed, 102 insertions, 16 deletions
diff --git a/src/ast.c b/src/ast.c
index 5314e90..0211d91 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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;
}