diff --git a/src/translate_c.cpp b/src/translate_c.cpp index 9f80d4e898..6c55aa6afc 100644 --- a/src/translate_c.cpp +++ b/src/translate_c.cpp @@ -2119,9 +2119,6 @@ static AstNode *trans_unary_expr_or_type_trait_expr(Context *c, AstNode *block, } static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) { - stmt->getBody(); - stmt->getCond(); - AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr); AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral); @@ -2171,6 +2168,51 @@ static AstNode *trans_do_loop(Context *c, AstNode *block, DoStmt *stmt) { return while_node; } +static AstNode *trans_for_loop(Context *c, AstNode *block, ForStmt *stmt) { + AstNode *loop_block_node; + AstNode *while_node = trans_create_node(c, NodeTypeWhileExpr); + Stmt *init_stmt = stmt->getInit(); + if (init_stmt == nullptr) { + loop_block_node = while_node; + } else { + loop_block_node = trans_create_node(c, NodeTypeBlock); + + AstNode *vars_node = trans_stmt(c, false, loop_block_node, init_stmt, TransRValue); + if (vars_node == nullptr) + return nullptr; + if (vars_node != skip_add_to_block_node) + loop_block_node->data.block.statements.append(vars_node); + + loop_block_node->data.block.statements.append(while_node); + } + + Stmt *cond_stmt = stmt->getCond(); + if (cond_stmt == nullptr) { + AstNode *true_node = trans_create_node(c, NodeTypeBoolLiteral); + true_node->data.bool_literal.value = true; + while_node->data.while_expr.condition = true_node; + } else { + while_node->data.while_expr.condition = trans_stmt(c, false, loop_block_node, cond_stmt, TransRValue); + if (while_node->data.while_expr.condition == nullptr) + return nullptr; + } + + Stmt *inc_stmt = stmt->getInc(); + if (inc_stmt != nullptr) { + AstNode *inc_node = trans_stmt(c, false, loop_block_node, inc_stmt, TransRValue); + if (inc_node == nullptr) + return nullptr; + while_node->data.while_expr.continue_expr = inc_node; + } + + AstNode *child_statement = trans_stmt(c, false, loop_block_node, stmt->getBody(), TransRValue); + if (child_statement == nullptr) + return nullptr; + while_node->data.while_expr.body = child_statement; + + return loop_block_node; +} + static AstNode *trans_string_literal(Context *c, AstNode *block, StringLiteral *stmt) { switch (stmt->getKind()) { case StringLiteral::Ascii: @@ -2230,6 +2272,8 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s return trans_unary_expr_or_type_trait_expr(c, block, (UnaryExprOrTypeTraitExpr *)stmt); case Stmt::DoStmtClass: return trans_do_loop(c, block, (DoStmt *)stmt); + case Stmt::ForStmtClass: + return trans_for_loop(c, block, (ForStmt *)stmt); case Stmt::StringLiteralClass: return trans_string_literal(c, block, (StringLiteral *)stmt); case Stmt::CaseStmtClass: @@ -2568,9 +2612,6 @@ static AstNode *trans_stmt(Context *c, bool result_used, AstNode *block, Stmt *s case Stmt::VAArgExprClass: emit_warning(c, stmt->getLocStart(), "TODO handle C VAArgExprClass"); return nullptr; - case Stmt::ForStmtClass: - emit_warning(c, stmt->getLocStart(), "TODO handle C ForStmtClass"); - return nullptr; case Stmt::GotoStmtClass: emit_warning(c, stmt->getLocStart(), "TODO handle C GotoStmtClass"); return nullptr; diff --git a/test/translate_c.zig b/test/translate_c.zig index feb44f2cf0..80ccdabc74 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -949,6 +949,19 @@ pub fn addCases(cases: &tests.TranslateCContext) { \\ return; \\} ); + + cases.add("for loop", + \\void foo(void) { + \\ for (int i = 0; i < 10; i += 1) { } + \\} + , + \\pub fn foo() { + \\ { + \\ var i: c_int = 0; + \\ while (i < 10) : (i += 1) {}; + \\ }; + \\} + ); }