authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-19 18:52:09-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-04-19 18:52:09-07:00
log36c6acfc76eeeed1498b5cc9ecb3137214e69bbf
tree40e2ffa30130a2ed1dd8f5674843237b108176f6
parent7a7f83033c3fee3e92046b76dd33b9f8ded4f0fd

enum init uses container init syntax instead of fn call

See #5

5 files changed, 69 insertions(+), 50 deletions(-)

src/all_types.hpp+2-1
...@@ -392,7 +392,6 @@ struct AstNodeFnCallExpr {...@@ -392,7 +392,6 @@ struct AstNodeFnCallExpr {
392 Expr resolved_expr;392 Expr resolved_expr;
393 FnTableEntry *fn_entry;393 FnTableEntry *fn_entry;
394 CastOp cast_op;394 CastOp cast_op;
395 TypeTableEntry *enum_type;
396 // if cast_op is CastOpArrayToString, this will be a pointer to395 // if cast_op is CastOpArrayToString, this will be a pointer to
397 // the string struct on the stack396 // the string struct on the stack
398 LLVMValueRef tmp_ptr;397 LLVMValueRef tmp_ptr;
...@@ -429,6 +428,7 @@ struct AstNodeFieldAccessExpr {...@@ -429,6 +428,7 @@ struct AstNodeFieldAccessExpr {
429 bool is_fn_call;428 bool is_fn_call;
430 TypeTableEntry *bare_struct_type;429 TypeTableEntry *bare_struct_type;
431 bool is_member_fn;430 bool is_member_fn;
431 AstNode *container_init_expr_node;
432};432};
433433
434struct AstNodeDirective {434struct AstNodeDirective {
...@@ -665,6 +665,7 @@ struct AstNodeContainerInitExpr {...@@ -665,6 +665,7 @@ struct AstNodeContainerInitExpr {
665 // populated by semantic analyzer665 // populated by semantic analyzer
666 StructValExprCodeGen resolved_struct_val_expr;666 StructValExprCodeGen resolved_struct_val_expr;
667 Expr resolved_expr;667 Expr resolved_expr;
668 TypeTableEntry *enum_type;
668};669};
669670
670struct AstNodeNullLiteral {671struct AstNodeNullLiteral {
src/analyze.cpp+39-25
...@@ -2197,7 +2197,23 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry...@@ -2197,7 +2197,23 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
21972197
2198 ContainerInitKind kind = container_init_expr->kind;2198 ContainerInitKind kind = container_init_expr->kind;
21992199
2200 TypeTableEntry *container_type = analyze_type_expr(g, import, context, container_init_expr->type);2200 if (container_init_expr->type->type == NodeTypeFieldAccessExpr) {
2201 container_init_expr->type->data.field_access_expr.container_init_expr_node = node;
2202 }
2203
2204 TypeTableEntry *container_meta_type = analyze_expression(g, import, context, nullptr,
2205 container_init_expr->type);
2206
2207 if (container_meta_type->id == TypeTableEntryIdInvalid) {
2208 return g->builtin_types.entry_invalid;
2209 }
2210
2211 if (node->data.container_init_expr.enum_type) {
2212 get_resolved_expr(node)->const_val = get_resolved_expr(container_init_expr->type)->const_val;
2213 return node->data.container_init_expr.enum_type;
2214 }
2215
2216 TypeTableEntry *container_type = resolve_type(g, container_init_expr->type);
22012217
2202 if (container_type->id == TypeTableEntryIdInvalid) {2218 if (container_type->id == TypeTableEntryIdInvalid) {
2203 return container_type;2219 return container_type;
...@@ -2322,9 +2338,6 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry...@@ -2322,9 +2338,6 @@ static TypeTableEntry *analyze_container_init_expr(CodeGen *g, ImportTableEntry
2322 } else if (container_type->id == TypeTableEntryIdArray) {2338 } else if (container_type->id == TypeTableEntryIdArray) {
2323 zig_panic("TODO array container init");2339 zig_panic("TODO array container init");
2324 return container_type;2340 return container_type;
2325 } else if (container_type->id == TypeTableEntryIdEnum) {
2326 zig_panic("TODO enum container init");
2327 return container_type;
2328 } else if (container_type->id == TypeTableEntryIdVoid) {2341 } else if (container_type->id == TypeTableEntryIdVoid) {
2329 if (container_init_expr->entries.length != 0) {2342 if (container_init_expr->entries.length != 0) {
2330 add_node_error(g, node, buf_sprintf("void expression expects no arguments"));2343 add_node_error(g, node, buf_sprintf("void expression expects no arguments"));
...@@ -2414,7 +2427,28 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -2414,7 +2427,28 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
2414 } else if (wrapped_in_fn_call) {2427 } else if (wrapped_in_fn_call) {
2415 return resolve_expr_const_val_as_type(g, node, child_type);2428 return resolve_expr_const_val_as_type(g, node, child_type);
2416 } else if (child_type->id == TypeTableEntryIdEnum) {2429 } else if (child_type->id == TypeTableEntryIdEnum) {
2417 return analyze_enum_value_expr(g, import, context, node, nullptr, child_type, field_name, node);2430 AstNode *container_init_node = node->data.field_access_expr.container_init_expr_node;
2431 AstNode *value_node;
2432 if (container_init_node) {
2433 assert(container_init_node->type == NodeTypeContainerInitExpr);
2434 int param_count = container_init_node->data.container_init_expr.entries.length;
2435 if (param_count > 1) {
2436 AstNode *first_invalid_node = container_init_node->data.container_init_expr.entries.at(1);
2437 add_node_error(g, first_executing_node(first_invalid_node),
2438 buf_sprintf("enum values accept only one parameter"));
2439 return child_type;
2440 } else {
2441 if (param_count == 1) {
2442 value_node = container_init_node->data.container_init_expr.entries.at(0);
2443 } else {
2444 value_node = nullptr;
2445 }
2446 container_init_node->data.container_init_expr.enum_type = child_type;
2447 }
2448 } else {
2449 value_node = nullptr;
2450 }
2451 return analyze_enum_value_expr(g, import, context, node, value_node, child_type, field_name, node);
2418 } else if (child_type->id == TypeTableEntryIdStruct) {2452 } else if (child_type->id == TypeTableEntryIdStruct) {
2419 BlockContext *container_block_context = get_container_block_context(child_type);2453 BlockContext *container_block_context = get_container_block_context(child_type);
2420 auto entry = container_block_context->decl_table.maybe_get(field_name);2454 auto entry = container_block_context->decl_table.maybe_get(field_name);
...@@ -4725,26 +4759,6 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import...@@ -4725,26 +4759,6 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
47254759
4726 if (child_type->id == TypeTableEntryIdInvalid) {4760 if (child_type->id == TypeTableEntryIdInvalid) {
4727 return g->builtin_types.entry_invalid;4761 return g->builtin_types.entry_invalid;
4728 } else if (child_type->id == TypeTableEntryIdEnum) {
4729 Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;
4730 int param_count = node->data.fn_call_expr.params.length;
4731 if (param_count > 1) {
4732 add_node_error(g, first_executing_node(node->data.fn_call_expr.params.at(1)),
4733 buf_sprintf("enum values accept only one parameter"));
4734 return child_type;
4735 } else {
4736 AstNode *value_node;
4737 if (param_count == 1) {
4738 value_node = node->data.fn_call_expr.params.at(0);
4739 } else {
4740 value_node = nullptr;
4741 }
4742
4743 node->data.fn_call_expr.enum_type = child_type;
4744
4745 return analyze_enum_value_expr(g, import, context, fn_ref_expr, value_node,
4746 child_type, field_name, node);
4747 }
4748 } else if (child_type->id == TypeTableEntryIdStruct) {4762 } else if (child_type->id == TypeTableEntryIdStruct) {
4749 Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;4763 Buf *field_name = &fn_ref_expr->data.field_access_expr.field_name;
4750 BlockContext *container_block_context = get_container_block_context(child_type);4764 BlockContext *container_block_context = get_container_block_context(child_type);
src/codegen.cpp+16-13
...@@ -764,23 +764,11 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -764,23 +764,11 @@ static LLVMValueRef gen_fn_call_expr(CodeGen *g, AstNode *node) {
764 return gen_cast_expr(g, node);764 return gen_cast_expr(g, node);
765 }765 }
766766
767 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
768 if (node->data.fn_call_expr.enum_type) {
769 int param_count = node->data.fn_call_expr.params.length;
770 AstNode *arg1_node;
771 if (param_count == 1) {
772 arg1_node = node->data.fn_call_expr.params.at(0);
773 } else {
774 assert(param_count == 0);
775 arg1_node = nullptr;
776 }
777 return gen_enum_value_expr(g, fn_ref_expr, node->data.fn_call_expr.enum_type, arg1_node);
778 }
779
780 FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;767 FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
781 TypeTableEntry *struct_type = nullptr;768 TypeTableEntry *struct_type = nullptr;
782 AstNode *first_param_expr = nullptr;769 AstNode *first_param_expr = nullptr;
783770
771 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
784 if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&772 if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
785 fn_ref_expr->data.field_access_expr.is_member_fn)773 fn_ref_expr->data.field_access_expr.is_member_fn)
786 {774 {
...@@ -2207,6 +2195,21 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {...@@ -2207,6 +2195,21 @@ static LLVMValueRef gen_container_init_expr(CodeGen *g, AstNode *node) {
22072195
2208 TypeTableEntry *type_entry = get_expr_type(node);2196 TypeTableEntry *type_entry = get_expr_type(node);
22092197
2198
2199 if (node->data.container_init_expr.enum_type) {
2200 int param_count = node->data.container_init_expr.entries.length;
2201 AstNode *arg1_node;
2202 if (param_count == 1) {
2203 arg1_node = node->data.container_init_expr.entries.at(0);
2204 } else {
2205 assert(param_count == 0);
2206 arg1_node = nullptr;
2207 }
2208 return gen_enum_value_expr(g, node->data.container_init_expr.type,
2209 node->data.container_init_expr.enum_type, arg1_node);
2210 }
2211
2212
2210 if (type_entry->id == TypeTableEntryIdStruct) {2213 if (type_entry->id == TypeTableEntryIdStruct) {
2211 assert(node->data.container_init_expr.kind == ContainerInitKindStruct);2214 assert(node->data.container_init_expr.kind == ContainerInitKindStruct);
22122215
src/eval.cpp+5-4
...@@ -320,6 +320,11 @@ static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue *...@@ -320,6 +320,11 @@ static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue *
320320
321 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;321 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
322 ContainerInitKind kind = container_init_expr->kind;322 ContainerInitKind kind = container_init_expr->kind;
323
324 if (container_init_expr->enum_type) {
325 zig_panic("TODO");
326 }
327
323 TypeTableEntry *container_type = resolve_expr_type(container_init_expr->type);328 TypeTableEntry *container_type = resolve_expr_type(container_init_expr->type);
324 out_val->ok = true;329 out_val->ok = true;
325330
...@@ -723,10 +728,6 @@ static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val...@@ -723,10 +728,6 @@ static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val
723 return false;728 return false;
724 }729 }
725730
726 if (node->data.fn_call_expr.enum_type) {
727 zig_panic("TODO");
728 }
729
730 FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;731 FnTableEntry *fn_table_entry = node->data.fn_call_expr.fn_entry;
731732
732 if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&733 if (fn_ref_expr->type == NodeTypeFieldAccessExpr &&
test/self_hosted.zig+7-7
...@@ -353,8 +353,8 @@ fn maybe_type() {...@@ -353,8 +353,8 @@ fn maybe_type() {
353353
354#attribute("test")354#attribute("test")
355fn enum_type() {355fn enum_type() {
356 const foo1 = EnumTypeFoo.One(13);356 const foo1 = EnumTypeFoo.One {13};
357 const foo2 = EnumTypeFoo.Two(EnumType { .x = 1234, .y = 5678, });357 const foo2 = EnumTypeFoo.Two {EnumType { .x = 1234, .y = 5678, }};
358 const bar = EnumTypeBar.B;358 const bar = EnumTypeBar.B;
359359
360 assert(bar == EnumTypeBar.B);360 assert(bar == EnumTypeBar.B);
...@@ -449,7 +449,7 @@ fn should_be_not_equal(a: error, b: error) {...@@ -449,7 +449,7 @@ fn should_be_not_equal(a: error, b: error) {
449#attribute("test")449#attribute("test")
450fn constant_enum_with_payload() {450fn constant_enum_with_payload() {
451 var empty = AnEnumWithPayload.Empty;451 var empty = AnEnumWithPayload.Empty;
452 var full = AnEnumWithPayload.Full(13);452 var full = AnEnumWithPayload.Full {13};
453 should_be_empty(empty);453 should_be_empty(empty);
454 should_be_not_empty(full);454 should_be_not_empty(full);
455}455}
...@@ -547,8 +547,8 @@ enum SwitchStatmentFoo {...@@ -547,8 +547,8 @@ enum SwitchStatmentFoo {
547547
548#attribute("test")548#attribute("test")
549fn switch_prong_with_var() {549fn switch_prong_with_var() {
550 switch_prong_with_var_fn(SwitchProngWithVarEnum.One(13));550 switch_prong_with_var_fn(SwitchProngWithVarEnum.One {13});
551 switch_prong_with_var_fn(SwitchProngWithVarEnum.Two(13.0));551 switch_prong_with_var_fn(SwitchProngWithVarEnum.Two {13.0});
552 switch_prong_with_var_fn(SwitchProngWithVarEnum.Meh);552 switch_prong_with_var_fn(SwitchProngWithVarEnum.Meh);
553}553}
554enum SwitchProngWithVarEnum {554enum SwitchProngWithVarEnum {
...@@ -1221,8 +1221,8 @@ struct Test3Point {...@@ -1221,8 +1221,8 @@ struct Test3Point {
1221 x: i32,1221 x: i32,
1222 y: i32,1222 y: i32,
1223}1223}
1224const test3_foo = Test3Foo.Three(Test3Point {.x = 3, .y = 4});1224const test3_foo = Test3Foo.Three{Test3Point {.x = 3, .y = 4}};
1225const test3_bar = Test3Foo.Two(13);1225const test3_bar = Test3Foo.Two{13};
1226#static_eval_enable(false)1226#static_eval_enable(false)
1227fn test3_1(f: Test3Foo) {1227fn test3_1(f: Test3Foo) {
1228 switch (f) {1228 switch (f) {