From 4c8443d96db4a441b393ea0c3c8d76a7493f46d0 Mon Sep 17 00:00:00 2001 From: Josh Wolfe Date: Wed, 20 Sep 2017 21:37:56 -0700 Subject: logical and, logical or --- src/ast_render.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/ast_render.cpp') diff --git a/src/ast_render.cpp b/src/ast_render.cpp index 1ac9d8de79..a68e1efc58 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -14,8 +14,8 @@ static const char *bin_op_str(BinOpType bin_op) { switch (bin_op) { case BinOpTypeInvalid: return "(invalid)"; - case BinOpTypeBoolOr: return "||"; - case BinOpTypeBoolAnd: return "&&"; + case BinOpTypeBoolOr: return "or"; + case BinOpTypeBoolAnd: return "and"; case BinOpTypeCmpEq: return "=="; case BinOpTypeCmpNotEq: return "!="; case BinOpTypeCmpLessThan: return "<"; -- cgit v1.2.3 From eba45b0013bf06849ac55d99b4a20d44624c7016 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 21 Sep 2017 00:54:08 -0400 Subject: parse-c: field access expressions --- src/ast_render.cpp | 2 ++ src/parsec.cpp | 24 +++++++++++++++++++++--- test/parsec.zig | 18 +++++++++++++++++- 3 files changed, 40 insertions(+), 4 deletions(-) (limited to 'src/ast_render.cpp') diff --git a/src/ast_render.cpp b/src/ast_render.cpp index a68e1efc58..599d4b2659 100644 --- a/src/ast_render.cpp +++ b/src/ast_render.cpp @@ -580,10 +580,12 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { break; case NodeTypePrefixOpExpr: { + if (!grouped) fprintf(ar->f, "("); PrefixOp op = node->data.prefix_op_expr.prefix_op; fprintf(ar->f, "%s", prefix_op_str(op)); render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr); + if (!grouped) fprintf(ar->f, ")"); break; } case NodeTypeAddrOfExpr: diff --git a/src/parsec.cpp b/src/parsec.cpp index 0c49cf30ef..f559773497 100644 --- a/src/parsec.cpp +++ b/src/parsec.cpp @@ -291,6 +291,10 @@ static AstNode *trans_create_node_inline_fn(Context *c, Buf *fn_name, Buf *var_n return fn_def; } +static AstNode *trans_create_node_unwrap_null(Context *c, AstNode *child) { + return trans_create_node_prefix_op(c, PrefixOpUnwrapMaybe, child); +} + static AstNode *get_global(Context *c, Buf *name) { for (size_t i = 0; i < c->root->data.root.top_level_decls.length; i += 1) { 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 return node; } +static AstNode *trans_member_expr(Context *c, AstNode *block, MemberExpr *stmt) { + AstNode *container_node = trans_expr(c, true, block, stmt->getBase(), TransRValue); + if (container_node == nullptr) + return nullptr; + + if (stmt->isArrow()) { + container_node = trans_create_node_unwrap_null(c, container_node); + } + + const char *name = decl_name(stmt->getMemberDecl()); + + AstNode *node = trans_create_node_field_access_str(c, container_node, name); + return node; +} + static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) { Stmt::StmtClass sc = stmt->getStmtClass(); switch (sc) { @@ -1793,6 +1812,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s case Stmt::CallExprClass: return trans_call_expr(c, result_used, block, (CallExpr *)stmt); + case Stmt::MemberExprClass: + return trans_member_expr(c, block, (MemberExpr *)stmt); case Stmt::CaseStmtClass: emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass"); return nullptr; @@ -2037,9 +2058,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s case Stmt::MaterializeTemporaryExprClass: emit_warning(c, stmt->getLocStart(), "TODO handle C MaterializeTemporaryExprClass"); return nullptr; - case Stmt::MemberExprClass: - emit_warning(c, stmt->getLocStart(), "TODO handle C MemberExprClass"); - return nullptr; case Stmt::NoInitExprClass: emit_warning(c, stmt->getLocStart(), "TODO handle C NoInitExprClass"); return nullptr; diff --git a/test/parsec.zig b/test/parsec.zig index 0027903f36..45282e793a 100644 --- a/test/parsec.zig +++ b/test/parsec.zig @@ -98,7 +98,7 @@ pub fn addCases(cases: &tests.ParseCContext) { , \\pub const BarB = enum_Bar.B; , - \\pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar); + \\pub extern fn func(a: ?&struct_Foo, b: ?&(?&enum_Bar)); , \\pub const Foo = struct_Foo; , @@ -444,4 +444,20 @@ pub fn addCases(cases: &tests.ParseCContext) { \\ bar(); \\} ); + + cases.add("field access expression", + \\struct Foo { + \\ int field; + \\}; + \\int read_field(struct Foo *foo) { + \\ return foo->field; + \\} + , + \\pub const struct_Foo = extern struct { + \\ field: c_int, + \\}; + \\export fn read_field(foo: ?&struct_Foo) -> c_int { + \\ return (??foo).field; + \\} + ); } -- cgit v1.2.3