aboutsummaryrefslogtreecommitdiff
path: root/src/ast.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast.c')
-rw-r--r--src/ast.c72
1 files changed, 68 insertions, 4 deletions
diff --git a/src/ast.c b/src/ast.c
index 413f77e..1a44ce1 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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) {