Basic call expression and fix to assignment count checking

This commit is contained in:
gingerBill
2016-08-03 22:27:36 +01:00
parent 0e92166d44
commit 19aea1f198
11 changed files with 332 additions and 226 deletions
+2 -3
View File
@@ -427,7 +427,6 @@ void add_untyped(CheckerInfo *i, AstNode *expression, b32 lhs, AddressingMode mo
void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
GB_ASSERT(expression != NULL);
GB_ASSERT(type != NULL);
if (mode == Addressing_Invalid)
return;
@@ -530,8 +529,8 @@ void add_curr_ast_file(Checker *c, AstFile *file) {
#include "expression.cpp"
#include "statements.cpp"
#include "expr.cpp"
#include "stmt.cpp"
@@ -8,9 +8,9 @@ Type * check_type (Checker *c, AstNode *expression, Type *n
void check_selector (Checker *c, Operand *operand, AstNode *node);
void check_not_tuple (Checker *c, Operand *operand);
void convert_to_typed (Checker *c, Operand *operand, Type *target_type);
gbString expr_to_string (AstNode *expression);
gbString expr_to_string (AstNode *expression);
void check_entity_decl (Checker *c, Entity *e, DeclInfo *decl, Type *named_type);
void check_proc_body (Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body);
void check_proc_body (Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body);
void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
@@ -1880,12 +1880,10 @@ ExpressionKind check_expr_base(Checker *c, Operand *o, AstNode *node, Type *type
break;
}
if (type != NULL) {
if (is_type_untyped(type)) {
add_untyped(&c->info, node, false, o->mode, type, value);
} else {
add_type_and_value(&c->info, node, o->mode, type, value);
}
if (type != NULL && is_type_untyped(type)) {
add_untyped(&c->info, node, false, o->mode, type, value);
} else {
add_type_and_value(&c->info, node, o->mode, type, value);
}
return kind;
}
@@ -1972,7 +1970,9 @@ gbString write_field_list_to_string(gbString str, AstNode *field_list, char *sep
}
gbString string_append_token(gbString str, Token token) {
return gb_string_append_length(str, token.string.text, token.string.len);
if (token.string.len > 0)
return gb_string_append_length(str, token.string.text, token.string.len);
return str;
}
@@ -1980,9 +1980,13 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
if (node == NULL)
return str;
if (is_ast_node_stmt(node)) {
GB_ASSERT("stmt passed to write_expr_to_string");
}
switch (node->kind) {
default:
str = gb_string_appendc(str, "(bad expression)");
str = gb_string_appendc(str, "(BadExpr)");
break;
case_ast_node(i, Ident, node);
@@ -2000,7 +2004,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
case_ast_node(cl, CompoundLit, node);
str = gb_string_appendc(str, "(");
str = write_expr_to_string(str, cl->type);
str = gb_string_appendc(str, " literal)");
str = gb_string_appendc(str, " lit)");
case_end;
case_ast_node(te, TagExpr, node);
@@ -2061,7 +2065,6 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = write_expr_to_string(str, ce->expr);
case_end;
case_ast_node(pt, PointerType, node);
str = gb_string_appendc(str, "^");
str = write_expr_to_string(str, pt->type);
@@ -2079,7 +2082,9 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = gb_string_appendc(str, "(");
isize i = 0;
for (AstNode *arg = ce->arg_list; arg != NULL; arg = arg->next) {
if (i > 0) gb_string_appendc(str, ", ");
if (i > 0) {
str = gb_string_appendc(str, ", ");
}
str = write_expr_to_string(str, arg);
i++;
}
@@ -265,31 +265,34 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNode *in
if ((lhs == NULL || lhs_count == 0) && init_count == 0)
return;
isize i = 0;
AstNode *rhs = init_list;
for (;
i < lhs_count && i < init_count && rhs != NULL;
i++, rhs = rhs->next) {
Operand operand = {};
check_multi_expr(c, &operand, rhs);
if (operand.type->kind != Type_Tuple) {
check_init_variable(c, lhs[i], &operand, context_name);
// TODO(bill): Do not use heap allocation here if I can help it
gbArray(Operand) operands;
gb_array_init(operands, gb_heap_allocator());
defer (gb_array_free(operands));
for (AstNode *rhs = init_list; rhs != NULL; rhs = rhs->next) {
Operand o = {};
check_multi_expr(c, &o, rhs);
if (o.type->kind != Type_Tuple) {
gb_array_append(operands, o);
} else {
auto *tuple = &operand.type->tuple;
for (isize j = 0;
j < tuple->variable_count && i < lhs_count && i < init_count;
j++, i++) {
Type *type = tuple->variables[j]->type;
operand.type = type;
check_init_variable(c, lhs[i], &operand, context_name);
auto *tuple = &o.type->tuple;
for (isize j = 0; j < tuple->variable_count; j++) {
o.type = tuple->variables[j]->type;
gb_array_append(operands, o);
}
}
}
if (i < lhs_count && lhs[i]->type == NULL) {
error(&c->error_collector, lhs[i]->token, "Too few values on the right hand side of the declaration");
} else if (rhs != NULL) {
error(&c->error_collector, ast_node_token(rhs), "Too many values on the right hand side of the declaration");
isize rhs_count = gb_array_count(operands);
isize max = gb_min(lhs_count, rhs_count);
for (isize i = 0; i < max; i++) {
check_init_variable(c, lhs[i], &operands[i], context_name);
}
if (rhs_count > 0 && lhs_count != rhs_count) {
error(&c->error_collector, lhs[0]->token, "Assignment count mismatch `%td` := `%td`", lhs_count, rhs_count);
}
}
@@ -599,36 +602,37 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
return;
}
Operand operand = {};
AstNode *lhs = as->lhs_list;
AstNode *rhs = as->rhs_list;
isize i = 0;
for (;
lhs != NULL && rhs != NULL;
lhs = lhs->next, rhs = rhs->next) {
check_multi_expr(c, &operand, rhs);
if (operand.type->kind != Type_Tuple) {
check_assignment_variable(c, &operand, lhs);
i++;
// TODO(bill): Do not use heap allocation here if I can help it
gbArray(Operand) operands;
gb_array_init(operands, gb_heap_allocator());
defer (gb_array_free(operands));
for (AstNode *rhs = as->rhs_list; rhs != NULL; rhs = rhs->next) {
Operand o = {};
check_multi_expr(c, &o, rhs);
if (o.type->kind != Type_Tuple) {
gb_array_append(operands, o);
} else {
auto *tuple = &operand.type->tuple;
for (isize j = 0;
j < tuple->variable_count && lhs != NULL;
j++, i++, lhs = lhs->next) {
// TODO(bill): More error checking
operand.type = tuple->variables[j]->type;
check_assignment_variable(c, &operand, lhs);
auto *tuple = &o.type->tuple;
for (isize j = 0; j < tuple->variable_count; j++) {
o.type = tuple->variables[j]->type;
gb_array_append(operands, o);
}
if (lhs == NULL)
break;
}
}
if (i < as->lhs_count && i < as->rhs_count) {
if (lhs == NULL)
error(&c->error_collector, ast_node_token(lhs), "Too few values on the right hand side of the declaration");
} else if (rhs != NULL) {
error(&c->error_collector, ast_node_token(rhs), "Too many values on the right hand side of the declaration");
isize lhs_count = as->lhs_count;
isize rhs_count = gb_array_count(operands);
isize operand_index = 0;
for (AstNode *lhs = as->lhs_list;
lhs != NULL;
lhs = lhs->next, operand_index++) {
check_assignment_variable(c, &operands[operand_index], lhs);
}
if (lhs_count != rhs_count) {
error(&c->error_collector, ast_node_token(as->lhs_list), "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
}
} break;
+2
View File
@@ -268,6 +268,8 @@ gb_global Type *t_untyped_float = &basic_types[Basic_UntypedFloat];
gb_global Type *t_untyped_pointer = &basic_types[Basic_UntypedPointer];
gb_global Type *t_untyped_string = &basic_types[Basic_UntypedString];
gb_global Type *t_untyped_rune = &basic_types[Basic_UntypedRune];
gb_global Type *t_byte = &basic_type_aliases[Basic_byte];
gb_global Type *t_rune = &basic_type_aliases[Basic_rune];
b32 is_type_named(Type *t) {