zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit f7cb77a02c2e32e9522b247e4653f1c03a677266 (tree)
parent 2ae789d27cec716c104a9e817a66f59b2ed53f47
Author: Josh Wolfe <thejoshwolfe@gmail.com>
Date:   Wed, 20 Sep 2017 22:05:14 -0700

Merge remote-tracking branch 'origin/c-to-zig' into c-to-zig

Diffstat:
Msrc/ast_render.cpp | 2++
Msrc/parsec.cpp | 30+++++++++++++++++++++++-------
Mtest/parsec.zig | 26+++++++++++++++++++++++++-
3 files changed, 50 insertions(+), 8 deletions(-)

diff --git 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 @@ -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]; @@ -1760,6 +1764,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) { @@ -1789,7 +1808,10 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s return trans_if_statement(c, block, (IfStmt *)stmt); case Stmt::CallExprClass: return trans_call_expr(c, result_used, block, (CallExpr *)stmt); - + case Stmt::NullStmtClass: + return skip_add_to_block_node; + 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; @@ -2034,9 +2056,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; @@ -2159,9 +2178,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s case Stmt::MSDependentExistsStmtClass: emit_warning(c, stmt->getLocStart(), "TODO handle C MSDependentExistsStmtClass"); return nullptr; - case Stmt::NullStmtClass: - emit_warning(c, stmt->getLocStart(), "TODO handle C NullStmtClass"); - return nullptr; case Stmt::OMPAtomicDirectiveClass: emit_warning(c, stmt->getLocStart(), "TODO handle C OMPAtomicDirectiveClass"); return nullptr; diff --git 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; , @@ -454,4 +454,28 @@ 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; + \\} + ); + + cases.add("null statements", + \\void foo(void) { + \\ ;;;;; + \\} + , + \\export fn foo() {} + ); }