authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-15 19:02:04-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-15 19:02:04-07:00
log8818c59cbc96e6b0699a408d2fbaa9846356d85a
treed99fff9c50625f7e4574e257d129c231d87d93f3
parentdc162c7f8385d82f1e5513a5412b98ec8c70e993

parser: fix not setting container init kind


2 files changed, 49 insertions(+), 45 deletions(-)

src/analyze.cpp+47-45
......@@ -1318,6 +1318,16 @@ static TypeStructField *find_struct_type_field(TypeTableEntry *type_entry, Buf *
13181318 return nullptr;
13191319}
13201320
1321static const char *err_container_init_syntax_name(ContainerInitKind kind) {
1322 switch (kind) {
1323 case ContainerInitKindStruct:
1324 return "struct";
1325 case ContainerInitKindArray:
1326 return "array";
1327 }
1328 zig_unreachable();
1329}
1330
13211331static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
13221332 AstNode *node)
13231333{
......@@ -1331,60 +1341,51 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
13311341
13321342 if (container_type->id == TypeTableEntryIdInvalid) {
13331343 return container_type;
1334 } else if (container_type->id == TypeTableEntryIdStruct) {
1335 switch (kind) {
1336 case ContainerInitKindStruct:
1337 {
1338 StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr;
1339 codegen->type_entry = container_type;
1340 codegen->source_node = node;
1341 context->struct_val_expr_alloca_list.append(codegen);
1344 } else if (container_type->id == TypeTableEntryIdStruct &&
1345 kind == ContainerInitKindStruct)
1346 {
1347 StructValExprCodeGen *codegen = &container_init_expr->resolved_struct_val_expr;
1348 codegen->type_entry = container_type;
1349 codegen->source_node = node;
1350 context->struct_val_expr_alloca_list.append(codegen);
13421351
13431352
1344 int expr_field_count = container_init_expr->entries.length;
1345 int actual_field_count = container_type->data.structure.field_count;
1353 int expr_field_count = container_init_expr->entries.length;
1354 int actual_field_count = container_type->data.structure.field_count;
13461355
1347 int *field_use_counts = allocate<int>(actual_field_count);
1348 for (int i = 0; i < expr_field_count; i += 1) {
1349 AstNode *val_field_node = container_init_expr->entries.at(i);
1350 assert(val_field_node->type == NodeTypeStructValueField);
1356 int *field_use_counts = allocate<int>(actual_field_count);
1357 for (int i = 0; i < expr_field_count; i += 1) {
1358 AstNode *val_field_node = container_init_expr->entries.at(i);
1359 assert(val_field_node->type == NodeTypeStructValueField);
13511360
1352 int field_index;
1353 TypeStructField *type_field = find_struct_type_field(container_type,
1354 &val_field_node->data.struct_val_field.name, &field_index);
1361 int field_index;
1362 TypeStructField *type_field = find_struct_type_field(container_type,
1363 &val_field_node->data.struct_val_field.name, &field_index);
13551364
1356 if (!type_field) {
1357 add_node_error(g, val_field_node,
1358 buf_sprintf("no member named '%s' in '%s'",
1359 buf_ptr(&val_field_node->data.struct_val_field.name), buf_ptr(&container_type->name)));
1360 continue;
1361 }
1365 if (!type_field) {
1366 add_node_error(g, val_field_node,
1367 buf_sprintf("no member named '%s' in '%s'",
1368 buf_ptr(&val_field_node->data.struct_val_field.name), buf_ptr(&container_type->name)));
1369 continue;
1370 }
13621371
1363 field_use_counts[field_index] += 1;
1364 if (field_use_counts[field_index] > 1) {
1365 add_node_error(g, val_field_node, buf_sprintf("duplicate field"));
1366 continue;
1367 }
1372 field_use_counts[field_index] += 1;
1373 if (field_use_counts[field_index] > 1) {
1374 add_node_error(g, val_field_node, buf_sprintf("duplicate field"));
1375 continue;
1376 }
13681377
1369 val_field_node->data.struct_val_field.type_struct_field = type_field;
1378 val_field_node->data.struct_val_field.type_struct_field = type_field;
13701379
1371 analyze_expression(g, import, context, type_field->type_entry,
1372 val_field_node->data.struct_val_field.expr);
1373 }
1380 analyze_expression(g, import, context, type_field->type_entry,
1381 val_field_node->data.struct_val_field.expr);
1382 }
13741383
1375 for (int i = 0; i < actual_field_count; i += 1) {
1376 if (field_use_counts[i] == 0) {
1377 add_node_error(g, node,
1378 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
1379 }
1380 }
1381 break;
1382 }
1383 case ContainerInitKindArray:
1384 for (int i = 0; i < actual_field_count; i += 1) {
1385 if (field_use_counts[i] == 0) {
13841386 add_node_error(g, node,
1385 buf_sprintf("struct '%s' does not support array initialization syntax",
1386 buf_ptr(&container_type->name)));
1387 break;
1387 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
1388 }
13881389 }
13891390 return container_type;
13901391 } else if (container_type->id == TypeTableEntryIdArray) {
......@@ -1409,7 +1410,8 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
14091410 }
14101411 } else {
14111412 add_node_error(g, node,
1412 buf_sprintf("type '%s' does not support initialization syntax", buf_ptr(&container_type->name)));
1413 buf_sprintf("type '%s' does not support %s syntax",
1414 buf_ptr(&container_type->name), err_container_init_syntax_name(kind)));
14131415 return g->builtin_types.entry_invalid;
14141416 }
14151417}
src/parser.cpp+2
......@@ -1423,6 +1423,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index,
14231423
14241424 Token *token = &pc->tokens->at(*token_index);
14251425 if (token->id == TokenIdDot) {
1426 node->data.container_init_expr.kind = ContainerInitKindStruct;
14261427 for (;;) {
14271428 if (token->id == TokenIdDot) {
14281429 ast_eat_token(pc, token_index, TokenIdDot);
......@@ -1456,6 +1457,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, int *token_index,
14561457 }
14571458
14581459 } else {
1460 node->data.container_init_expr.kind = ContainerInitKindArray;
14591461 for (;;) {
14601462 if (token->id == TokenIdRBrace) {
14611463 *token_index += 1;