diff options
Diffstat (limited to 'src/ast.c')
-rw-r--r-- | src/ast.c | 72 |
1 files changed, 68 insertions, 4 deletions
@@ -21,7 +21,7 @@ static BufferView variable_type_get_name(VariableType *self); static void scope_named_object_init(ScopeNamedObject *self) { self->type = NAMED_OBJECT_NONE; - self->value.lhs_expr = NULL; + self->value.data = NULL; self->resolve_data = NULL; } @@ -75,13 +75,23 @@ static BufferView ast_resolved_type_get_name(AstResolvedType *self) { } static void ast_resolved_type_init(AstResolvedType *self) { - self->value.lhs_expr = NULL; + self->value.data = NULL; self->type = RESOLVED_TYPE_NONE; } static bool ast_resolved_type_equals(AstResolvedType *self, AstResolvedType *other) { - /* This should be fine, without checking AstResolvedType type, since they are only equal if the types are equal as well */ - return self->value.lhs_expr == other->value.lhs_expr; + if(self->type != other->type) + return bool_false; + + switch(self->type) { + case RESOLVED_TYPE_NONE: + return bool_true; + case RESOLVED_TYPE_LHS_EXPR: + return self->value.lhs_expr == other->value.lhs_expr; + case RESOLVED_TYPE_FUNC_SIG: + return function_signature_equals(self->value.func_sig, other->value.func_sig); + } + return bool_false; } static AstResolvedType lhs_expr_get_resolved_type(LhsExpr *self, AstCompilerContext *context) { @@ -214,6 +224,59 @@ int function_signature_add_return_type(FunctionSignature *self, const VariableTy return buffer_append(&self->return_types, &return_type, sizeof(return_type)); } +static CHECK_RESULT bool function_parameter_equals(FunctionParameter *self, FunctionParameter *other) { + /* It's fine if the name of the parameter is different. Only the type matters */ + return ast_resolved_type_equals(&self->resolve_data.type, &other->resolve_data.type); +} + +static CHECK_RESULT bool function_parameters_equals(Buffer *func_params, Buffer *other_func_params) { + FunctionParameter *func_param, *func_param_end; + FunctionParameter *other_func_param, *other_func_param_end; + + func_param = buffer_begin(func_params); + func_param_end = buffer_end(func_params); + other_func_param = buffer_begin(other_func_params); + other_func_param_end = buffer_end(other_func_params); + /* Different number of arguments */ + if(func_param_end - func_param != other_func_param_end - other_func_param) + return bool_false; + + for(; func_param != func_param_end; ++func_param, ++other_func_param) { + if(!function_parameter_equals(func_param, other_func_param)) + return bool_false; + } + return bool_true; +} + +static CHECK_RESULT bool function_return_type_equals(FunctionReturnType *self, FunctionReturnType *other) { + return ast_resolved_type_equals(&self->resolved_type, &other->resolved_type); +} + +static CHECK_RESULT bool function_return_types_equals(Buffer *func_return_types, Buffer *other_func_return_types) { + FunctionReturnType *func_return_type, *func_return_type_end; + FunctionReturnType *other_func_return_type, *other_func_return_type_end; + + func_return_type = buffer_begin(func_return_types); + func_return_type_end = buffer_end(func_return_types); + other_func_return_type = buffer_begin(other_func_return_types); + other_func_return_type_end = buffer_end(other_func_return_types); + /* Different number of arguments */ + if(func_return_type_end - func_return_type != other_func_return_type_end - other_func_return_type) + return bool_false; + + for(; func_return_type != func_return_type_end; ++func_return_type, ++other_func_return_type) { + if(!function_return_type_equals(func_return_type, other_func_return_type)) + return bool_false; + } + return bool_true; +} + +bool function_signature_equals(FunctionSignature *self, FunctionSignature *other) { + if(!function_parameters_equals(&self->parameters, &other->parameters)) + return bool_false; + return function_return_types_equals(&self->return_types, &other->return_types); +} + void function_parameter_init(FunctionParameter *self) { self->name = create_buffer_view_null(); self->type.type = VARIABLE_TYPE_NONE; @@ -256,6 +319,7 @@ void lhsexpr_init(LhsExpr *self, DeclFlag decl_flag, BufferView var_name) { self->type.value.variable = NULL; self->var_name = var_name; self->rhs_expr = NULL; + self->extern_index = 0; } void assignmentexpr_init(AssignmentExpr *self, Ast *lhs_expr, Ast *rhs_expr) { |