aboutsummaryrefslogtreecommitdiff
path: root/src/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast.c')
-rw-r--r--src/ast.c79
1 files changed, 55 insertions, 24 deletions
diff --git a/src/ast.c b/src/ast.c
index 04ec646..504c1f9 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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, &param->resolve_data.type) ||
- is_type_compatible_with(arg, &param->resolve_data.type, context) ||
- function_parameter_is_vararg(param, context);
+ is_arg_str_and_param_c_str(arg, &param->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;