mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-25 08:57:55 +00:00
Basic call expression and fix to assignment count checking
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user