| author | |
| committer | |
| log | 36c6acfc76eeeed1498b5cc9ecb3137214e69bbf |
| tree | 40e2ffa30130a2ed1dd8f5674843237b108176f6 |
| parent | 7a7f83033c3fee3e92046b76dd33b9f8ded4f0fd |
See #55 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 to | 395 | // if cast_op is CastOpArrayToString, this will be a pointer to |
| 397 | // the string struct on the stack | 396 | // 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 | }; |
| 433 | 433 | ||
| 434 | struct AstNodeDirective { | 434 | struct AstNodeDirective { |
| ... | @@ -665,6 +665,7 @@ struct AstNodeContainerInitExpr { | ... | @@ -665,6 +665,7 @@ struct AstNodeContainerInitExpr { |
| 665 | // populated by semantic analyzer | 665 | // 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 | }; |
| 669 | 670 | ||
| 670 | struct AstNodeNullLiteral { | 671 | struct 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 |
| 2197 | 2197 | ||
| 2198 | ContainerInitKind kind = container_init_expr->kind; | 2198 | ContainerInitKind kind = container_init_expr->kind; |
| 2199 | 2199 | ||
| 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); | ||
| 2201 | 2217 | ||
| 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 |
| 4725 | 4759 | ||
| 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 | } |
| 766 | 766 | ||
| 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; |
| 783 | 770 | ||
| 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) { |
| 2207 | 2195 | ||
| 2208 | TypeTableEntry *type_entry = get_expr_type(node); | 2196 | TypeTableEntry *type_entry = get_expr_type(node); |
| 2209 | 2197 | ||
| 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); |
| 2212 | 2215 |
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 * |
| 320 | 320 | ||
| 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; |
| 325 | 330 | ||
| ... | @@ -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 | } |
| 725 | 730 | ||
| 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; |
| 731 | 732 | ||
| 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() { |
| 353 | 353 | ||
| 354 | #attribute("test") | 354 | #attribute("test") |
| 355 | fn enum_type() { | 355 | fn 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; |
| 359 | 359 | ||
| 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") |
| 450 | fn constant_enum_with_payload() { | 450 | fn 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 { |
| 547 | 547 | ||
| 548 | #attribute("test") | 548 | #attribute("test") |
| 549 | fn switch_prong_with_var() { | 549 | fn 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 | } |
| 554 | enum SwitchProngWithVarEnum { | 554 | enum 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 | } |
| 1224 | const test3_foo = Test3Foo.Three(Test3Point {.x = 3, .y = 4}); | 1224 | const test3_foo = Test3Foo.Three{Test3Point {.x = 3, .y = 4}}; |
| 1225 | const test3_bar = Test3Foo.Two(13); | 1225 | const test3_bar = Test3Foo.Two{13}; |
| 1226 | #static_eval_enable(false) | 1226 | #static_eval_enable(false) |
| 1227 | fn test3_1(f: Test3Foo) { | 1227 | fn test3_1(f: Test3Foo) { |
| 1228 | switch (f) { | 1228 | switch (f) { |