aboutsummaryrefslogtreecommitdiff
path: root/src/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast.c')
-rw-r--r--src/ast.c31
1 files changed, 15 insertions, 16 deletions
diff --git a/src/ast.c b/src/ast.c
index 35ece2e..db2f61d 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -107,7 +107,7 @@ void lhsexpr_init(LhsExpr *self, bool is_extern, bool is_pub, bool is_const, Buf
self->type.type = VARIABLE_TYPE_NONE;
self->type.value.variable = NULL;
self->var_name = var_name;
- self->rhs_expr = NULL;
+ nullable_assign(self->rhs_expr, NULL);
}
void assignmentexpr_init(AssignmentExpr *self, Ast *lhs_expr, Ast *rhs_expr) {
@@ -333,11 +333,11 @@ static BufferView variable_type_get_name(VariableType *self) {
static LhsExpr* lhsexpr_resolve_rhs(LhsExpr *self, AstCompilerContext *context) {
LhsExpr *rhs_resolved_type;
- ast_resolve(self->rhs_expr, context);
- if(ast_is_decl(self->rhs_expr))
+ ast_resolve(nullable_unwrap(self->rhs_expr), context);
+ if(ast_is_decl(nullable_unwrap(self->rhs_expr)))
rhs_resolved_type = self;
else
- rhs_resolved_type = self->rhs_expr->resolve_data.type;
+ rhs_resolved_type = nullable_unwrap(self->rhs_expr)->resolve_data.type;
return rhs_resolved_type;
}
@@ -354,15 +354,15 @@ static void lhsexpr_resolve(Ast *ast, AstCompilerContext *context) {
the parameters and return types have been resolved as recursive function calls should
be allowed but recursive function calls still require parameters and return types to be known.
*/
- if(self->rhs_expr) {
+ if(is_not_null(self->rhs_expr)) {
LhsExpr *rhs_resolve_type;
- if(self->rhs_expr->type == AST_FUNCTION_DECL) {
+ if(nullable_unwrap(self->rhs_expr)->type == AST_FUNCTION_DECL) {
/*
The function declaration itself always resolves the signature, but we also do it here because we
want to have the signature solved before setting the lhs expr as solved. Also function signatures can exist
without lhs expr (anonymous function).
*/
- function_signature_resolve(self->rhs_expr->value.func_decl->signature, context);
+ function_signature_resolve(nullable_unwrap(self->rhs_expr)->value.func_decl->signature, context);
ast->resolve_data.status = AST_RESOLVED;
/*
If rhs is a function declaration then there is no need to wait until it has been resolved before setting the type as the type
@@ -374,9 +374,8 @@ static void lhsexpr_resolve(Ast *ast, AstCompilerContext *context) {
rhs_resolve_type = lhsexpr_resolve_rhs(self, context);
- /* self->rhs_expr can be null here because this is valid: var num: i32; */
/* TODO: Add casting */
- if(ast->resolve_data.type && self->rhs_expr && ast->resolve_data.type != rhs_resolve_type) {
+ if(ast->resolve_data.type && ast->resolve_data.type != rhs_resolve_type) {
Parser *parser;
parser = scope_get_parser(context->scope);
/*
@@ -463,9 +462,9 @@ static void import_resolve(Ast *ast, AstCompilerContext *context) {
static Scope* lhsexpr_get_scope(LhsExpr *self) {
AstValue value;
- if(self->rhs_expr) {
- value = self->rhs_expr->value;
- switch(self->rhs_expr->type) {
+ if(is_not_null(self->rhs_expr)) {
+ value = nullable_unwrap(self->rhs_expr)->value;
+ switch(nullable_unwrap(self->rhs_expr)->type) {
case AST_FUNCTION_DECL:
return &value.func_decl->body;
case AST_STRUCT_DECL:
@@ -496,9 +495,9 @@ static void funcdecl_resolve(FunctionDecl *self, AstCompilerContext *context) {
Dont need to check if @self is resolved, since it will always be partially resolved when called from @funccall_resolve.
Meaning the resolve status wont be set to solved but the resolve type will be set.
*/
-static bool is_func_decl(Ast *self) {
+bool resolved_type_is_func_decl(Ast *self) {
const LhsExpr *resolved_type = self->resolve_data.type;
- return (resolved_type->rhs_expr && resolved_type->rhs_expr->type == AST_FUNCTION_DECL) ||
+ return (is_not_null(resolved_type->rhs_expr) && nullable_unwrap(resolved_type->rhs_expr)->type == AST_FUNCTION_DECL) ||
resolved_type->type.type == VARIABLE_TYPE_SIGNATURE;
}
@@ -510,7 +509,7 @@ static void funccall_resolve(Ast *self, AstCompilerContext *context) {
func_call = self->value.func_call;
variable_resolve(&func_call->func, context, &self->resolve_data);
/* Attemping to use call syntax (variable_name ( ) ) with a variable that is not a function */
- if(!is_func_decl(self)) {
+ if(!resolved_type_is_func_decl(self)) {
Parser *caller_parser;
Parser *callee_parser;
BufferView callee_code_ref;
@@ -550,7 +549,7 @@ static void structfield_resolve(Ast *self, AstCompilerContext *context) {
static bool is_struct_decl(Ast *self) {
const LhsExpr *resolved_type = self->resolve_data.type;
assert(self->resolve_data.status == AST_RESOLVED);
- return resolved_type->rhs_expr && resolved_type->rhs_expr->type == AST_STRUCT_DECL;
+ return is_not_null(resolved_type->rhs_expr) && nullable_unwrap(resolved_type->rhs_expr)->type == AST_STRUCT_DECL;
}
static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) {