diff options
Diffstat (limited to 'src/ast.c')
-rw-r--r-- | src/ast.c | 79 |
1 files changed, 55 insertions, 24 deletions
@@ -169,6 +169,9 @@ BufferView ast_get_name(Ast *self) { case AST_NUMBER: name = self->value.number->code_ref; break; + case AST_BOOL: + name = self->value.bool->code_ref; + break; case AST_LHS: name = self->value.lhs_expr->var_name; break; @@ -352,6 +355,11 @@ void number_init(Number *self, AmalNumber *value, BufferView code_ref) { self->code_ref = code_ref; } +void ast_bool_init(AstBool *self, bool value, BufferView code_ref) { + self->value = value; + self->code_ref = code_ref; +} + void variable_init(Variable *self, BufferView name) { self->name = name; scope_named_object_init(&self->resolved_var); @@ -464,8 +472,7 @@ static void __scope_get_resolved_variable(Scope *self, Scope *start, AstCompiler exists = hash_map_get(&self->named_objects, name, &ast_result); if(!exists) { if(self->function_signature) { - FunctionParameter *func_param; - func_param = function_signature_get_parameter_by_name(self->function_signature, name); + FunctionParameter *func_param = function_signature_get_parameter_by_name(self->function_signature, name); if(func_param) { prev_scope = context->scope; context->scope = self; @@ -477,6 +484,9 @@ static void __scope_get_resolved_variable(Scope *self, Scope *start, AstCompiler result->resolve_data = &func_param->resolve_data; return; } + + /* TODO: Remove this when closures can capture variables */ + assert(self->parent == &context->parser->struct_decl.body); } if(self->parent) { @@ -721,8 +731,7 @@ static Scope* ast_resolved_type_get_scope(AstResolvedType *self) { } static void funcdecl_resolve(Ast *self, AstCompilerContext *context) { - FunctionDecl *func_decl; - func_decl = self->value.func_decl; + FunctionDecl *func_decl = self->value.func_decl; function_signature_resolve(func_decl->signature, context); scope_resolve(&func_decl->body, context); self->resolve_data.type.type = RESOLVED_TYPE_FUNC_SIG; @@ -734,27 +743,39 @@ static usize min(usize a, usize b) { } static bool is_c_pointer_compatible(VariableType *self) { - return self->variable_type_flags & (VARIABLE_TYPE_FLAG_OPTIONAL | VARIABLE_TYPE_FLAG_BORROW); + return self->variable_type_flags & VARIABLE_TYPE_FLAG_BORROW; } -static bool is_type_compatible_with(AstResolvedType *self, AstResolvedType *other, AstCompilerContext *context) { - return self->value.data == &context->compiler->default_types.str->lhs_expr && - other->value.data == context->compiler->default_types.c_char && is_c_pointer_compatible(&other->value.lhs_expr->type); +static bool is_arg_str_and_param_c_str(AstResolvedType *arg_type, VariableType *param_type, AstCompilerContext *context) { + return arg_type->value.data == &context->compiler->default_types.str->lhs_expr && + param_type->type == VARIABLE_TYPE_VARIABLE && + param_type->value.variable->resolved_var.value.data == context->compiler->default_types.c_char && + is_c_pointer_compatible(param_type); } static bool resolve_data_type_equals(AstResolvedType *self, AstResolvedType *other) { - return self->value.data == other->value.data; + if(self->type != other->type) + return bool_false; + + switch(self->type) { + case RESOLVED_TYPE_NONE: + case RESOLVED_TYPE_LHS_EXPR: + return self->value.data == other->value.data; + case RESOLVED_TYPE_FUNC_SIG: + return function_signature_equals(self->value.func_sig, other->value.func_sig); + } + assert(bool_false); } -static bool function_parameter_is_vararg(FunctionParameter *self, AstCompilerContext *context) { +static bool function_parameter_is_c_vararg(FunctionParameter *self, AstCompilerContext *context) { amal_default_type *vararg_type = context->compiler->default_types.c_varargs; return self->resolve_data.type.value.data == &vararg_type->lhs_expr; } static bool is_function_arg_compatible_with_parameter(AstResolvedType *arg, FunctionParameter *param, AstCompilerContext *context) { return resolve_data_type_equals(arg, ¶m->resolve_data.type) || - is_type_compatible_with(arg, ¶m->resolve_data.type, context) || - function_parameter_is_vararg(param, context); + is_arg_str_and_param_c_str(arg, ¶m->type, context) || + function_parameter_is_c_vararg(param, context); } /* Pointers, isize and usize are returned with size 4, as that is the smallest possible size for them */ @@ -814,7 +835,7 @@ static void funccall_resolve_signature_types(FunctionCall *func_call, FunctionSi if(num_missing_args > 0) { FunctionParameter *vararg_param = buffer_begin(&func_sig->parameters); - bool has_vararg = num_params > 0 && function_parameter_is_vararg(&vararg_param[num_params - 1], context); + bool has_vararg = num_params > 0 && function_parameter_is_c_vararg(&vararg_param[num_params - 1], context); if (has_vararg) num_missing_args -= 1; if(num_missing_args > 0) { @@ -845,10 +866,14 @@ static void funccall_resolve(Ast *self, AstCompilerContext *context) { { func_sig = self->resolve_data.type.value.func_sig; - FunctionReturnType *return_type = buffer_begin(&func_sig->return_types); - assert(buffer_get_size(&func_sig->return_types, FunctionReturnType) == 1); self->resolve_data.type.type = RESOLVED_TYPE_LHS_EXPR; - self->resolve_data.type = return_type->resolved_type; + if(func_sig->return_types.size > 0) { + FunctionReturnType *return_type = buffer_begin(&func_sig->return_types); + self->resolve_data.type = return_type->resolved_type; + } else { + self->resolve_data.type.type = RESOLVED_TYPE_LHS_EXPR; + self->resolve_data.type.value.lhs_expr = &context->compiler->default_types.void_type->lhs_expr; + } } ast = buffer_begin(&func_call->args); @@ -918,12 +943,11 @@ static bool is_struct_decl(Ast *self) { return resolved_type->rhs_expr && resolved_type->rhs_expr->type == AST_STRUCT_DECL; } -static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) { +static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context, ScopeNamedObject *rhs_resolved_var) { Binop *self; Scope *lhs_scope; BufferView caller_code_ref; BufferView callee_code_ref; - ScopeNamedObject rhs_resolved_var; assert(ast->type == AST_BINOP); self = ast->value.binop; @@ -935,8 +959,8 @@ static void binop_resolve_dot_access(Ast *ast, AstCompilerContext *context) { } lhs_scope = ast_resolved_type_get_scope(&self->lhs->resolve_data.type); - scope_get_resolved_variable(lhs_scope, context, self->rhs->value.variable->name, &rhs_resolved_var); - self->rhs->resolve_data.type = scope_named_object_get_resolved_type(&rhs_resolved_var, context); + scope_get_resolved_variable(lhs_scope, context, self->rhs->value.variable->name, rhs_resolved_var); + self->rhs->resolve_data.type = scope_named_object_get_resolved_type(rhs_resolved_var, context); caller_code_ref = ast_get_code_reference(self->rhs); callee_code_ref = ast_resolved_type_get_name(&self->rhs->resolve_data.type); @@ -982,13 +1006,15 @@ static void binop_resolve(Ast *ast, AstCompilerContext *context) { self = ast->value.binop; ast_resolve(self->lhs, context); if(self->type == BINOP_DOT && (self->rhs->type == AST_VARIABLE || self->rhs->type == AST_FUNCTION_CALL)) { - binop_resolve_dot_access(ast, context); + ScopeNamedObject rhs_resolved_var; + binop_resolve_dot_access(ast, context, &rhs_resolved_var); /* Only function call has extra data that needs to be resolved (args) */ if(self->rhs->type == AST_FUNCTION_CALL) { - Scope *prev_scope = context->scope; - context->scope = ast_resolved_type_get_scope(&self->lhs->resolve_data.type); + /*Scope *prev_scope = context->scope;*/ + /*context->scope = ast_resolved_type_get_scope(&self->lhs->resolve_data.type);*/ + self->rhs->value.func_call->func.resolved_var = rhs_resolved_var; ast_resolve(self->rhs, context); - context->scope = prev_scope; + /*context->scope = prev_scope;*/ } self->rhs->resolve_data.status = AST_RESOLVED; ast->resolve_data.type = self->rhs->resolve_data.type; @@ -1206,6 +1232,11 @@ void ast_resolve(Ast *self, AstCompilerContext *context) { case AST_NUMBER: number_resolve(self, context); break; + case AST_BOOL: { + self->resolve_data.type.type = RESOLVED_TYPE_LHS_EXPR; + self->resolve_data.type.value.lhs_expr = &context->compiler->default_types.bool->lhs_expr; + break; + } case AST_FUNCTION_DECL: funcdecl_resolve(self, context); break; |