parser: fix not setting container init kind

This commit is contained in:
Andrew Kelley 2016-01-15 19:02:04 -07:00
parent dc162c7f83
commit 8818c59cbc
2 changed files with 49 additions and 45 deletions

View File

@ -1318,6 +1318,16 @@ static TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *
return nullptr; return nullptr;
} }
static const char *err_container_init_syntax_name(ContainerInitKind kind) {
switch (kind) {
case ContainerInitKindStruct:
return "struct";
case ContainerInitKindArray:
return "array";
}
zig_unreachable();
}
static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
AstNode *node) AstNode *node)
{ {
@ -1331,60 +1341,51 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
if (container_type->id == TypeTableEntryIdInvalid) { if (container_type->id == TypeTableEntryIdInvalid) {
return container_type; return container_type;
} else if (container_type->id == TypeTableEntryIdStruct) { } else if (container_type->id == TypeTableEntryIdStruct &&
switch (kind) { kind == ContainerInitKindStruct)
case ContainerInitKindStruct: {
{ StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr;
StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr; codegen->type_entry = container_type;
codegen->type_entry = container_type; codegen->source_node = node;
codegen->source_node = node; context->struct_val_expr_alloca_list.append(codegen);
context->struct_val_expr_alloca_list.append(codegen);
int expr_field_count = container_init_expr->entries.length; int expr_field_count = container_init_expr->entries.length;
int actual_field_count = container_type->data.structure.field_count; int actual_field_count = container_type->data.structure.field_count;
int *field_use_counts = allocate<int>(actual_field_count); int *field_use_counts = allocate<int>(actual_field_count);
for (int i = 0; i < expr_field_count; i += 1) { for (int i = 0; i < expr_field_count; i += 1) {
AstNode *val_field_node = container_init_expr->entries.at(i); AstNode *val_field_node = container_init_expr->entries.at(i);
assert(val_field_node->type == NodeTypeStructValueField); assert(val_field_node->type == NodeTypeStructValueField);
int field_index; int field_index;
TypeStructField *type_field = find_struct_type_field(container_type, TypeStructField *type_field = find_struct_type_field(container_type,
&val_field_node->data.struct_val_field.name, &field_index); &val_field_node->data.struct_val_field.name, &field_index);
if (!type_field) { if (!type_field) {
add_node_error(g, val_field_node, add_node_error(g, val_field_node,
buf_sprintf("no member named '%s' in '%s'", buf_sprintf("no member named '%s' in '%s'",
buf_ptr(&val_field_node->data.struct_val_field.name), buf_ptr(&container_type->name))); buf_ptr(&val_field_node->data.struct_val_field.name), buf_ptr(&container_type->name)));
continue; continue;
} }
field_use_counts[field_index] += 1; field_use_counts[field_index] += 1;
if (field_use_counts[field_index] > 1) { if (field_use_counts[field_index] > 1) {
add_node_error(g, val_field_node, buf_sprintf("duplicate field")); add_node_error(g, val_field_node, buf_sprintf("duplicate field"));
continue; continue;
} }
val_field_node->data.struct_val_field.type_struct_field = type_field; val_field_node->data.struct_val_field.type_struct_field = type_field;
analyze_expression(g, import, context, type_field->type_entry, analyze_expression(g, import, context, type_field->type_entry,
val_field_node->data.struct_val_field.expr); val_field_node->data.struct_val_field.expr);
} }
for (int i = 0; i < actual_field_count; i += 1) { for (int i = 0; i < actual_field_count; i += 1) {
if (field_use_counts[i] == 0) { if (field_use_counts[i] == 0) {
add_node_error(g, node,
buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
}
}
break;
}
case ContainerInitKindArray:
add_node_error(g, node, add_node_error(g, node,
buf_sprintf("struct '%s' does not support array initialization syntax", buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
buf_ptr(&container_type->name))); }
break;
} }
return container_type; return container_type;
} else if (container_type->id == TypeTableEntryIdArray) { } else if (container_type->id == TypeTableEntryIdArray) {
@ -1409,7 +1410,8 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
} }
} else { } else {
add_node_error(g, node, add_node_error(g, node,
buf_sprintf("type '%s' does not support initialization syntax", buf_ptr(&container_type->name))); buf_sprintf("type '%s' does not support %s syntax",
buf_ptr(&container_type->name), err_container_init_syntax_name(kind)));
return g->builtin_types.entry_invalid; return g->builtin_types.entry_invalid;
} }
} }

View File

@ -1423,6 +1423,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index,
Token *token = &pc->tokens->at(*token_index); Token *token = &pc->tokens->at(*token_index);
if (token->id == TokenIdDot) { if (token->id == TokenIdDot) {
node->data.container_init_expr.kind = ContainerInitKindStruct;
for (;;) { for (;;) {
if (token->id == TokenIdDot) { if (token->id == TokenIdDot) {
ast_eat_token(pc, token_index, TokenIdDot); ast_eat_token(pc, token_index, TokenIdDot);
@ -1456,6 +1457,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index,
} }
} else { } else {
node->data.container_init_expr.kind = ContainerInitKindArray;
for (;;) { for (;;) {
if (token->id == TokenIdRBrace) { if (token->id == TokenIdRBrace) {
*token_index += 1; *token_index += 1;