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 *...@@ -27,6 +27,7 @@ static TypeTableEntry *analyze_error_literal_expr(CodeGen *g, ImportTableEntry *
27static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,27static TypeTableEntry *analyze_block_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
28 TypeTableEntry *expected_type, AstNode *node);28 TypeTableEntry *expected_type, AstNode *node);
29static TypeTableEntry *resolve_expr_const_val_as_void(CodeGen *g, AstNode *node);29static 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);
30static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node);31static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, AstNode *node);
3132
32static AstNode *first_executing_node(AstNode *node) {33static AstNode *first_executing_node(AstNode *node) {
...@@ -1895,13 +1896,23 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i...@@ -1895,13 +1896,23 @@ static TypeTableEntry *analyze_field_access_expr(CodeGen *g, ImportTableEntry *i
1895 return g->builtin_types.entry_invalid;1896 return g->builtin_types.entry_invalid;
1896 }1897 }
1897 } else if (struct_type->id == TypeTableEntryIdMetaType) {1898 } 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) {
1901 return g->builtin_types.entry_invalid;1902 return g->builtin_types.entry_invalid;
1902 } else if (enum_type->id == TypeTableEntryIdEnum) {1903 } else if (child_type->id == TypeTableEntryIdEnum) {
1903 return analyze_enum_value_expr(g, import, context, node, nullptr, enum_type, field_name);1904 return analyze_enum_value_expr(g, import, context, node, nullptr, child_type, field_name);
1904 } else if (enum_type->id == TypeTableEntryIdPureError) {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) {
1905 return analyze_error_literal_expr(g, import, context, node, field_name);1916 return analyze_error_literal_expr(g, import, context, node, field_name);
1906 } else {1917 } else {
1907 add_node_error(g, node,1918 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...@@ -816,8 +816,12 @@ static LLVMValueRef gen_field_access_expr(CodeGen *g, AstNode *node, bool is_lva
816 }816 }
817 } else if (struct_type->id == TypeTableEntryIdMetaType) {817 } else if (struct_type->id == TypeTableEntryIdMetaType) {
818 assert(!is_lvalue);818 assert(!is_lvalue);
819 TypeTableEntry *enum_type = get_type_for_type_node(struct_expr);819 TypeTableEntry *child_type = get_type_for_type_node(struct_expr);
820 return gen_enum_value_expr(g, node, enum_type, nullptr);820 if (child_type->id == TypeTableEntryIdEnum) {
821 return gen_enum_value_expr(g, node, child_type, nullptr);
822 } else {
823 zig_unreachable();
824 }
821 } else {825 } else {
822 zig_unreachable();826 zig_unreachable();
823 }827 }
test/run_tests.cpp+19-1
...@@ -1386,9 +1386,27 @@ pub fn main(args: [][]u8) -> %void {...@@ -1386,9 +1386,27 @@ pub fn main(args: [][]u8) -> %void {
1386 if (*ptr != 6) {1386 if (*ptr != 6) {
1387 %%stdout.printf("BAD\n");1387 %%stdout.printf("BAD\n");
1388 }1388 }
1389 %%stdout.printf("OK\n");
13901389
1391 free(ptr);1390 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");
1392}1410}
1393 )SOURCE", "OK\n");1411 )SOURCE", "OK\n");
1394}1412}