aboutsummaryrefslogtreecommitdiff
path: root/src/checker/expression.cpp
diff options
context:
space:
mode:
authorgingerBill <ginger.bill.22@gmail.com>2016-07-12 23:53:34 +0100
committergingerBill <ginger.bill.22@gmail.com>2016-07-12 23:53:34 +0100
commitaa6a2caecb759522914ba82cc506e60270ad1ab0 (patch)
tree68a5cf5479606bc1b10deb4cf63af01e7e513136 /src/checker/expression.cpp
parent9f90ff50cf4f93e6c6bb622bc2098dc7cea7f240 (diff)
Random Order File Scope Declaration
Diffstat (limited to 'src/checker/expression.cpp')
-rw-r--r--src/checker/expression.cpp61
1 files changed, 35 insertions, 26 deletions
diff --git a/src/checker/expression.cpp b/src/checker/expression.cpp
index 072cec859..a96ae74d6 100644
--- a/src/checker/expression.cpp
+++ b/src/checker/expression.cpp
@@ -9,6 +9,7 @@ void check_selector (Checker *c, Operand *operand, AstNode *n
void check_not_tuple (Checker *c, Operand *operand);
void convert_to_typed (Checker *c, Operand *operand, Type *target_type);
gbString expression_to_string (AstNode *expression);
+void check_entity_declaration(Checker *c, Entity *e, Type *named_type);
void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
@@ -40,7 +41,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
GB_ASSERT(name->kind == AstNode_Identifier);
Token name_token = name->identifier.token;
// TODO(bill): is the curr_scope correct?
- Entity *e = make_entity_field(c, c->curr_scope, name_token, type);
+ Entity *e = make_entity_field(c->allocator, c->curr_scope, name_token, type);
u64 key = hash_string(name_token.string);
if (map_get(&entity_map, key)) {
// TODO(bill): Scope checking already checks the declaration
@@ -71,7 +72,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *field_list, isize fiel
Type *type = check_type(c, type_expression);
for (AstNode *name = field->field.name_list; name != NULL; name = name->next) {
if (name->kind == AstNode_Identifier) {
- Entity *param = make_entity_param(c, scope, name->identifier.token, type);
+ Entity *param = make_entity_param(c->allocator, scope, name->identifier.token, type);
add_entity(c, scope, name, param);
variables[variable_index++] = param;
} else {
@@ -99,11 +100,12 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *list, isize list_coun
Token token = ast_node_token(item);
token.string = make_string(""); // NOTE(bill): results are not named
// TODO(bill): Should I have named results?
- Entity *param = make_entity_param(c, scope, token, type);
+ Entity *param = make_entity_param(c->allocator, scope, token, type);
// NOTE(bill): No need to record
variables[variable_index++] = param;
if (get_base_type(type)->kind == Type_Array) {
+ // TODO(bill): Should I allow array's to returned?
print_checker_error(c, token, "You cannot return an array from a procedure");
}
}
@@ -123,13 +125,14 @@ void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) {
Type *params = check_get_params(c, c->curr_scope, proc_type_node->procedure_type.param_list, param_count);
Type *results = check_get_results(c, c->curr_scope, proc_type_node->procedure_type.results_list, result_count);
- type->procedure.scope = c->curr_scope;
- type->procedure.params = params;
- type->procedure.params_count = proc_type_node->procedure_type.param_count;
- type->procedure.results = results;
+ type->procedure.scope = c->curr_scope;
+ type->procedure.params = params;
+ type->procedure.params_count = proc_type_node->procedure_type.param_count;
+ type->procedure.results = results;
type->procedure.results_count = proc_type_node->procedure_type.result_count;
}
+
void check_identifier(Checker *c, Operand *operand, AstNode *n, Type *named_type) {
GB_ASSERT(n->kind == AstNode_Identifier);
operand->mode = Addressing_Invalid;
@@ -138,17 +141,22 @@ void check_identifier(Checker *c, Operand *operand, AstNode *n, Type *named_type
scope_lookup_parent_entity(c->curr_scope, n->identifier.token.string, NULL, &e);
if (e == NULL) {
print_checker_error(c, n->identifier.token,
- "Undeclared type/identifier `%.*s`", LIT(n->identifier.token.string));
+ "Undeclared type or identifier `%.*s`", LIT(n->identifier.token.string));
return;
}
add_entity_use(c, n, e);
- Type *type = e->type;
- GB_ASSERT(type != NULL);
+ check_entity_declaration(c, e, named_type);
+
+ if (e->type == NULL) {
+ GB_PANIC("Compiler error: How did this happen? type: %s; identifier: %.*s\n", type_to_string(e->type), LIT(n->identifier.token.string));
+ return;
+ }
switch (e->kind) {
case Entity_Constant:
- if (type == &basic_types[Basic_Invalid])
+ add_declaration_dependency(c, e);
+ if (e->type == &basic_types[Basic_Invalid])
return;
operand->value = e->constant.value;
GB_ASSERT(operand->value.kind != Value_Invalid);
@@ -156,8 +164,9 @@ void check_identifier(Checker *c, Operand *operand, AstNode *n, Type *named_type
break;
case Entity_Variable:
+ add_declaration_dependency(c, e);
e->variable.used = true;
- if (type == &basic_types[Basic_Invalid])
+ if (e->type == &basic_types[Basic_Invalid])
return;
operand->mode = Addressing_Variable;
break;
@@ -167,6 +176,7 @@ void check_identifier(Checker *c, Operand *operand, AstNode *n, Type *named_type
break;
case Entity_Procedure:
+ add_declaration_dependency(c, e);
operand->mode = Addressing_Value;
break;
@@ -176,11 +186,11 @@ void check_identifier(Checker *c, Operand *operand, AstNode *n, Type *named_type
break;
default:
- GB_PANIC("Unknown EntityKind");
+ GB_PANIC("Compiler error: Unknown EntityKind");
break;
}
- operand->type = type;
+ operand->type = e->type;
}
i64 check_array_count(Checker *c, AstNode *expression) {
@@ -504,7 +514,7 @@ b32 check_value_is_expressible(Checker *c, Value in_value, Type *type, Value *ou
case Basic_UntypedInteger:
return true;
- default: GB_PANIC("Unknown integer type!"); break;
+ default: GB_PANIC("Compiler error: Unknown integer type!"); break;
}
} else if (is_type_float(type)) {
Value v = value_to_float(in_value);
@@ -1291,24 +1301,22 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
GB_ASSERT(call->kind == AstNode_CallExpression);
GB_ASSERT(proc_type->kind == Type_Procedure);
auto *ce = &call->call_expression;
+ isize error_code = 0;
+ isize param_index = 0;
isize param_count = 0;
+
if (proc_type->procedure.params)
param_count = proc_type->procedure.params->tuple.variable_count;
if (ce->arg_list_count == 0 && param_count == 0)
return;
- isize error_code = 0;
-
if (ce->arg_list_count > param_count) {
error_code = +1;
} else {
Entity **sig_params = proc_type->procedure.params->tuple.variables;
- isize param_index = 0;
AstNode *call_arg = ce->arg_list;
- for (;
- call_arg != NULL && param_index < param_count;
- call_arg = call_arg->next) {
+ for (; call_arg != NULL; call_arg = call_arg->next) {
check_multi_expression(c, operand, call_arg);
if (operand->mode == Addressing_Invalid)
continue;
@@ -1339,6 +1347,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
break;
}
+
if (param_index < param_count) {
error_code = -1;
} else if (call_arg != NULL && call_arg->next != NULL) {
@@ -1348,10 +1357,11 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
if (error_code != 0) {
char *err_fmt = "";
- if (error_code < 0)
+ if (error_code < 0) {
err_fmt = "Too few arguments for `%s`, expected %td arguments";
- else
+ } else {
err_fmt = "Too many arguments for `%s`, expected %td arguments";
+ }
gbString proc_str = expression_to_string(ce->proc);
print_checker_error(c, ast_node_token(call), err_fmt, proc_str, param_count);
@@ -1666,14 +1676,13 @@ ExpressionKind check_expression_base(Checker *c, Operand *operand, AstNode *node
i64 indices[3] = {};
AstNode *nodes[3] = {se->low, se->high, se->max};
for (isize i = 0; i < gb_count_of(nodes); i++) {
- AstNode *node = nodes[i];
i64 index = max_count;
- if (node != NULL) {
+ if (nodes[i] != NULL) {
i64 capacity = -1;
if (max_count >= 0)
capacity = max_count;
i64 j = 0;
- if (check_index_value(c, node, capacity, &j)) {
+ if (check_index_value(c, nodes[i], capacity, &j)) {
index = j;
}
} else if (i == 0) {