translate-c supports for loops

This commit is contained in:
Andrew Kelley 2017-11-25 00:57:48 -05:00
parent 18eb3c5f90
commit bf20b260ce
2 changed files with 60 additions and 6 deletions

View File

@ -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;

View File

@ -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) {};
\\ };
\\}
);
}