authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-21 00:54:08-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-09-21 00:54:08-04:00
logeba45b0013bf06849ac55d99b4a20d44624c7016
tree122f95289a3ba636fa537893f81c0adccdecbd7f
parent0827a8f36bd0b99b876586b8c7ee099fbc903535

parse-c: field access expressions


3 files changed, 40 insertions(+), 4 deletions(-)

src/ast_render.cpp+2
...@@ -580,10 +580,12 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -580,10 +580,12 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
580 break;580 break;
581 case NodeTypePrefixOpExpr:581 case NodeTypePrefixOpExpr:
582 {582 {
583 if (!grouped) fprintf(ar->f, "(");
583 PrefixOp op = node->data.prefix_op_expr.prefix_op;584 PrefixOp op = node->data.prefix_op_expr.prefix_op;
584 fprintf(ar->f, "%s", prefix_op_str(op));585 fprintf(ar->f, "%s", prefix_op_str(op));
585586
586 render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr);587 render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr);
588 if (!grouped) fprintf(ar->f, ")");
587 break;589 break;
588 }590 }
589 case NodeTypeAddrOfExpr:591 case NodeTypeAddrOfExpr:
src/parsec.cpp+21-3
...@@ -291,6 +291,10 @@ static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_n...@@ -291,6 +291,10 @@ static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_n
291 return fn_def;291 return fn_def;
292}292}
293293
294static AstNode *trans_create_node_unwrap_null(Context *c, AstNode *child) {
295 return trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, child);
296}
297
294static AstNode *get_global(Context *c, Buf *name) {298static AstNode *get_global(Context *c, Buf *name) {
295 for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) {299 for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) {
296 AstNode *decl_node = c->root->data.root.top_level_decls.items[i];300 AstNode *decl_node = c->root->data.root.top_level_decls.items[i];
...@@ -1763,6 +1767,21 @@ static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, Ca...@@ -1763,6 +1767,21 @@ static AstNode *trans_call_expr(Context *c, bool result_used, AstNode *block, Ca
1763 return node;1767 return node;
1764}1768}
17651769
1770static AstNode *trans_member_expr(Context *c, AstNode *block, MemberExpr *stmt) {
1771 AstNode *container_node = trans_expr(c, true, block, stmt->getBase(), TransRValue);
1772 if (container_node == nullptr)
1773 return nullptr;
1774
1775 if (stmt->isArrow()) {
1776 container_node = trans_create_node_unwrap_null(c, container_node);
1777 }
1778
1779 const char *name = decl_name(stmt->getMemberDecl());
1780
1781 AstNode *node = trans_create_node_field_access_str(c, container_node, name);
1782 return node;
1783}
1784
1766static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) {1785static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) {
1767 Stmt::StmtClass sc = stmt->getStmtClass();1786 Stmt::StmtClass sc = stmt->getStmtClass();
1768 switch (sc) {1787 switch (sc) {
...@@ -1793,6 +1812,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s...@@ -1793,6 +1812,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
1793 case Stmt::CallExprClass:1812 case Stmt::CallExprClass:
1794 return trans_call_expr(c, result_used, block, (CallExpr *)stmt);1813 return trans_call_expr(c, result_used, block, (CallExpr *)stmt);
17951814
1815 case Stmt::MemberExprClass:
1816 return trans_member_expr(c, block, (MemberExpr *)stmt);
1796 case Stmt::CaseStmtClass:1817 case Stmt::CaseStmtClass:
1797 emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");1818 emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");
1798 return nullptr;1819 return nullptr;
...@@ -2037,9 +2058,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s...@@ -2037,9 +2058,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
2037 case Stmt::MaterializeTemporaryExprClass:2058 case Stmt::MaterializeTemporaryExprClass:
2038 emit_warning(c, stmt->getLocStart(), "TODO handle C MaterializeTemporaryExprClass");2059 emit_warning(c, stmt->getLocStart(), "TODO handle C MaterializeTemporaryExprClass");
2039 return nullptr;2060 return nullptr;
2040 case Stmt::MemberExprClass:
2041 emit_warning(c, stmt->getLocStart(), "TODO handle C MemberExprClass");
2042 return nullptr;
2043 case Stmt::NoInitExprClass:2061 case Stmt::NoInitExprClass:
2044 emit_warning(c, stmt->getLocStart(), "TODO handle C NoInitExprClass");2062 emit_warning(c, stmt->getLocStart(), "TODO handle C NoInitExprClass");
2045 return nullptr;2063 return nullptr;
test/parsec.zig+17-1
...@@ -98,7 +98,7 @@ pub fn addCases(cases: &tests.ParseCContext) {...@@ -98,7 +98,7 @@ pub fn addCases(cases: &tests.ParseCContext) {
98 ,98 ,
99 \\pub const BarB = enum_Bar.B;99 \\pub const BarB = enum_Bar.B;
100 ,100 ,
101 \\pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);101 \\pub extern fn func(a: ?&struct_Foo, b: ?&(?&enum_Bar));
102 ,102 ,
103 \\pub const Foo = struct_Foo;103 \\pub const Foo = struct_Foo;
104 ,104 ,
...@@ -444,4 +444,20 @@ pub fn addCases(cases: &tests.ParseCContext) {...@@ -444,4 +444,20 @@ pub fn addCases(cases: &tests.ParseCContext) {
444 \\ bar();444 \\ bar();
445 \\}445 \\}
446 );446 );
447
448 cases.add("field access expression",
449 \\struct Foo {
450 \\ int field;
451 \\};
452 \\int read_field(struct Foo *foo) {
453 \\ return foo->field;
454 \\}
455 ,
456 \\pub const struct_Foo = extern struct {
457 \\ field: c_int,
458 \\};
459 \\export fn read_field(foo: ?&struct_Foo) -> c_int {
460 \\ return (??foo).field;
461 \\}
462 );
447}463}