| ... | @@ -1987,6 +1987,59 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, AstNode *block, | ... | @@ -1987,6 +1987,59 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, AstNode *block, |
| 1987 | return node; | 1987 | return node; |
| 1988 | } | 1988 | } |
| 1989 | | 1989 | |
| | 1990 | static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) { |
| | 1991 | stmt->getBody(); |
| | 1992 | stmt->getCond(); |
| | 1993 | |
| | 1994 | AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr); |
| | 1995 | |
| | 1996 | AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral); |
| | 1997 | true_node->data.bool_literal.value = true; |
| | 1998 | while_node->data.while_expr.condition = true_node; |
| | 1999 | |
| | 2000 | AstNode *body_node; |
| | 2001 | if (stmt->getBody()->getStmtClass() == Stmt::CompoundStmtClass) { |
| | 2002 | // there's already a block in C, so we'll append our condition to it. |
| | 2003 | // c: do { |
| | 2004 | // c: a; |
| | 2005 | // c: b; |
| | 2006 | // c: } while(c); |
| | 2007 | // zig: while (true) { |
| | 2008 | // zig: a; |
| | 2009 | // zig: b; |
| | 2010 | // zig: if (!cond) break; |
| | 2011 | // zig: } |
| | 2012 | body_node = trans_stmt(c, false, block, stmt->getBody(), TransRValue); |
| | 2013 | if (body_node == nullptr) return nullptr; |
| | 2014 | assert(body_node->type == NodeTypeBlock); |
| | 2015 | } else { |
| | 2016 | // the C statement is without a block, so we need to create a block to contain it. |
| | 2017 | // c: do |
| | 2018 | // c: a; |
| | 2019 | // c: while(c); |
| | 2020 | // zig: while (true) { |
| | 2021 | // zig: a; |
| | 2022 | // zig: if (!cond) break; |
| | 2023 | // zig: } |
| | 2024 | body_node = trans_create_node(c, NodeTypeBlock); |
| | 2025 | AstNode *child_statement = trans_stmt(c, false, body_node, stmt->getBody(), TransRValue); |
| | 2026 | if (child_statement == nullptr) return nullptr; |
| | 2027 | body_node->data.block.statements.append(child_statement); |
| | 2028 | } |
| | 2029 | |
| | 2030 | // if (!cond) break; |
| | 2031 | AstNode *condition_node = trans_expr(c, true, body_node, stmt->getCond(), TransRValue); |
| | 2032 | if (condition_node == nullptr) return nullptr; |
| | 2033 | AstNode *terminator_node = trans_create_node(c, NodeTypeIfBoolExpr); |
| | 2034 | terminator_node->data.if_bool_expr.condition = trans_create_node_prefix_op(c, PrefixOpBoolNot, condition_node); |
| | 2035 | terminator_node->data.if_bool_expr.then_block = trans_create_node(c, NodeTypeBreak); |
| | 2036 | body_node->data.block.statements.append(terminator_node); |
| | 2037 | |
| | 2038 | while_node->data.while_expr.body = body_node; |
| | 2039 | |
| | 2040 | return while_node; |
| | 2041 | } |
| | 2042 | |
| 1990 | static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) { | 2043 | static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *stmt, TransLRValue lrvalue) { |
| 1991 | Stmt::StmtClass sc = stmt->getStmtClass(); | 2044 | Stmt::StmtClass sc = stmt->getStmtClass(); |
| 1992 | switch (sc) { | 2045 | switch (sc) { |
| ... | @@ -2026,6 +2079,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s | ... | @@ -2026,6 +2079,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s |
| 2026 | return trans_c_style_cast_expr(c, result_used, block, (CStyleCastExpr *)stmt, lrvalue); | 2079 | return trans_c_style_cast_expr(c, result_used, block, (CStyleCastExpr *)stmt, lrvalue); |
| 2027 | case Stmt::UnaryExprOrTypeTraitExprClass: | 2080 | case Stmt::UnaryExprOrTypeTraitExprClass: |
| 2028 | return trans_unary_expr_or_type_trait_expr(c, block, (UnaryExprOrTypeTraitExpr *)stmt); | 2081 | return trans_unary_expr_or_type_trait_expr(c, block, (UnaryExprOrTypeTraitExpr *)stmt); |
| | 2082 | case Stmt::DoStmtClass: |
| | 2083 | return trans_do_loop(c, block, (DoStmt *)stmt); |
| 2029 | case Stmt::CaseStmtClass: | 2084 | case Stmt::CaseStmtClass: |
| 2030 | emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass"); | 2085 | emit_warning(c, stmt->getLocStart(), "TODO handle C CaseStmtClass"); |
| 2031 | return nullptr; | 2086 | return nullptr; |
| ... | @@ -2071,9 +2126,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s | ... | @@ -2071,9 +2126,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s |
| 2071 | case Stmt::CoroutineBodyStmtClass: | 2126 | case Stmt::CoroutineBodyStmtClass: |
| 2072 | emit_warning(c, stmt->getLocStart(), "TODO handle C CoroutineBodyStmtClass"); | 2127 | emit_warning(c, stmt->getLocStart(), "TODO handle C CoroutineBodyStmtClass"); |
| 2073 | return nullptr; | 2128 | return nullptr; |
| 2074 | case Stmt::DoStmtClass: | | |
| 2075 | emit_warning(c, stmt->getLocStart(), "TODO handle C DoStmtClass"); | | |
| 2076 | return nullptr; | | |
| 2077 | case Stmt::BinaryConditionalOperatorClass: | 2129 | case Stmt::BinaryConditionalOperatorClass: |
| 2078 | emit_warning(c, stmt->getLocStart(), "TODO handle C BinaryConditionalOperatorClass"); | 2130 | emit_warning(c, stmt->getLocStart(), "TODO handle C BinaryConditionalOperatorClass"); |
| 2079 | return nullptr; | 2131 | return nullptr; |