authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 16:45:17-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 16:45:17-07:00
logbb4f7835286f047fc596715101ee0318c8e7f924
tree4860d7b895c592e11ca32f451a256e4720d956ba
parent13220ccb51b7d2cf7b8d72a662eece95784116c3

ability to refer to member function directly

See #14

3 files changed, 41 insertions(+), 8 deletions(-)

src/analyze.cpp+16-5
......@@ -27,6 +27,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *
2727static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
2828 TypeTableEntry *expected_type, AstNode *node);
2929static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node);
30static TypeTableEntry *resolve_expr_const_val_as_fn(CodeGen *g, AstNode *node, FnTableEntry *fn);
3031static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node);
3132
3233static AstNode *first_executing_node(AstNode *node) {
......@@ -1895,13 +1896,23 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
18951896 return g->builtin_types.entry_invalid;
18961897 }
18971898 } else if (struct_type->id == TypeTableEntryIdMetaType) {
1898 TypeTableEntry *enum_type = resolve_type(g, struct_expr_node);
1899 TypeTableEntry *child_type = resolve_type(g, struct_expr_node);
18991900
1900 if (enum_type->id == TypeTableEntryIdInvalid) {
1901 if (child_type->id == TypeTableEntryIdInvalid) {
19011902 return g->builtin_types.entry_invalid;
1902 } else if (enum_type->id == TypeTableEntryIdEnum) {
1903 return analyze_enum_value_expr(g, import, context, node, nullptr, enum_type, field_name);
1904 } else if (enum_type->id == TypeTableEntryIdPureError) {
1903 } else if (child_type->id == TypeTableEntryIdEnum) {
1904 return analyze_enum_value_expr(g, import, context, node, nullptr, child_type, field_name);
1905 } else if (child_type->id == TypeTableEntryIdStruct) {
1906 auto entry = child_type->data.structure.fn_table.maybe_get(field_name);
1907 if (entry) {
1908 return resolve_expr_const_val_as_fn(g, node, entry->value);
1909 } else {
1910 add_node_error(g, node,
1911 buf_sprintf("struct '%s' has no function called '%s'",
1912 buf_ptr(&child_type->name), buf_ptr(field_name)));
1913 return g->builtin_types.entry_invalid;
1914 }
1915 } else if (child_type->id == TypeTableEntryIdPureError) {
19051916 return analyze_error_literal_expr(g, import, context, node, field_name);
19061917 } else {
19071918 add_node_error(g, node,
src/codegen.cpp+6-2
......@@ -816,8 +816,12 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lva
816816 }
817817 } else if (struct_type->id == TypeTableEntryIdMetaType) {
818818 assert(!is_lvalue);
819 TypeTableEntry *enum_type = get_type_for_type_node(struct_expr);
820 return gen_enum_value_expr(g, node, enum_type, nullptr);
819 TypeTableEntry *child_type = get_type_for_type_node(struct_expr);
820 if (child_type->id == TypeTableEntryIdEnum) {
821 return gen_enum_value_expr(g, node, child_type, nullptr);
822 } else {
823 zig_unreachable();
824 }
821825 } else {
822826 zig_unreachable();
823827 }
test/run_tests.cpp+19-1
......@@ -1386,9 +1386,27 @@ pub fn main(args: [][]u8) -> %void {
13861386 if (*ptr != 6) {
13871387 %%stdout.printf("BAD\n");
13881388 }
1389 %%stdout.printf("OK\n");
13901389
13911390 free(ptr);
1391
1392 %%stdout.printf("OK\n");
1393}
1394 )SOURCE", "OK\n");
1395
1396 add_simple_case("store member function in variable", R"SOURCE(
1397import "std.zig";
1398struct Foo {
1399 x: i32,
1400 fn member(foo: Foo) -> i32 { foo.x }
1401}
1402pub fn main(args: [][]u8) -> %void {
1403 const instance = Foo { .x = 1234, };
1404 const member_fn = Foo.member;
1405 const result = member_fn(instance);
1406 if (result != 1234) {
1407 %%stdout.printf("BAD\n");
1408 }
1409 %%stdout.printf("OK\n");
13921410}
13931411 )SOURCE", "OK\n");
13941412}