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) {
580580 break;
581581 case NodeTypePrefixOpExpr:
582582 {
583 if (!grouped) fprintf(ar->f, "(");
583584 PrefixOp op = node->data.prefix_op_expr.prefix_op;
584585 fprintf(ar->f, "%s", prefix_op_str(op));
585586
586587 render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr);
588 if (!grouped) fprintf(ar->f, ")");
587589 break;
588590 }
589591 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
291291 return fn_def;
292292}
293293
294static AstNode *trans_create_node_unwrap_null(Context *c, AstNode *child) {
295 return trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, child);
296}
297
294298static AstNode *get_global(Context *c, Buf *name) {
295299 for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) {
296300 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
17631767 return node;
17641768}
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
17661785static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) {
17671786 Stmt::StmtClass sc = stmt->getStmtClass();
17681787 switch (sc) {
......@@ -1793,6 +1812,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
17931812 case Stmt::CallExprClass:
17941813 return trans_call_expr(c, result_used, block, (CallExpr *)stmt);
17951814
1815 case Stmt::MemberExprClass:
1816 return trans_member_expr(c, block, (MemberExpr *)stmt);
17961817 case Stmt::CaseStmtClass:
17971818 emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass");
17981819 return nullptr;
......@@ -2037,9 +2058,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s
20372058 case Stmt::MaterializeTemporaryExprClass:
20382059 emit_warning(c, stmt->getLocStart(), "TODO handle C MaterializeTemporaryExprClass");
20392060 return nullptr;
2040 case Stmt::MemberExprClass:
2041 emit_warning(c, stmt->getLocStart(), "TODO handle C MemberExprClass");
2042 return nullptr;
20432061 case Stmt::NoInitExprClass:
20442062 emit_warning(c, stmt->getLocStart(), "TODO handle C NoInitExprClass");
20452063 return nullptr;
test/parsec.zig+17-1
......@@ -98,7 +98,7 @@ pub fn addCases(cases: &tests.ParseCContext) {
9898 ,
9999 \\pub const BarB = enum_Bar.B;
100100 ,
101 \\pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);
101 \\pub extern fn func(a: ?&struct_Foo, b: ?&(?&enum_Bar));
102102 ,
103103 \\pub const Foo = struct_Foo;
104104 ,
......@@ -444,4 +444,20 @@ pub fn addCases(cases: &tests.ParseCContext) {
444444 \\ bar();
445445 \\}
446446 );
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 );
447463}