From e169f01e09463e858a5a7807e132c74f88d9647c Mon Sep 17 00:00:00 2001 From: x-tyger Date: Sat, 6 May 2017 20:24:36 +0000 Subject: [PATCH] Implements do-while statement transpilation --- ast/do_stmt.go | 4 ++-- ast/do_stmt_test.go | 2 +- tests/do.c | 10 ++++++++++ transpiler/branch.go | 29 +++++++++++++++++++++++++++++ transpiler/transpiler.go | 3 +++ 5 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 tests/do.c diff --git a/ast/do_stmt.go b/ast/do_stmt.go index a4e03ffe2..c574cc10b 100644 --- a/ast/do_stmt.go +++ b/ast/do_stmt.go @@ -3,7 +3,7 @@ package ast type DoStmt struct { Address string Position string - Children []interface{} + Children []Node } func parseDoStmt(line string) *DoStmt { @@ -15,7 +15,7 @@ func parseDoStmt(line string) *DoStmt { return &DoStmt{ Address: groups["address"], Position: groups["position"], - Children: []interface{}{}, + Children: []Node{}, } } diff --git a/ast/do_stmt_test.go b/ast/do_stmt_test.go index 6d5bb9eb5..ff593f625 100644 --- a/ast/do_stmt_test.go +++ b/ast/do_stmt_test.go @@ -9,7 +9,7 @@ func TestDoStmt(t *testing.T) { `0x7ff36d0a0938 `: &DoStmt{ Address: "0x7ff36d0a0938", Position: "line:11:5, line:14:23", - Children: []interface{}{}, + Children: []Node{}, }, } diff --git a/tests/do.c b/tests/do.c new file mode 100644 index 000000000..d2c6ce50f --- /dev/null +++ b/tests/do.c @@ -0,0 +1,10 @@ +#include + +int main() { + int i = 0; + + do { + printf("do loop %d\n", i); + i = i + 1; + } while( i < 4 ); +} diff --git a/transpiler/branch.go b/transpiler/branch.go index cc736aa0f..2ed13cf43 100644 --- a/transpiler/branch.go +++ b/transpiler/branch.go @@ -154,3 +154,32 @@ func transpileWhileStmt(n *ast.WhileStmt, p *program.Program) (*goast.ForStmt, e Body: body, }, nil } + +func transpileDoStmt(n *ast.DoStmt, p *program.Program) (*goast.ForStmt, error) { + children := n.Children + + body, err := transpileToBlockStmt(children[0], p) + if err != nil { + return nil, err + } + + condition, conditionType, err := transpileToExpr(children[1], p) + if err != nil { + return nil, err + } + + // Add IfStmt to the end of the loop to check the condition + body.List = append(body.List, &goast.IfStmt{ + Cond: &goast.UnaryExpr{ + Op: token.NOT, + X: types.CastExpr(p, condition, conditionType, "bool"), + }, + Body: &goast.BlockStmt{ + List: []goast.Stmt{&goast.BranchStmt{Tok: token.BREAK}}, + }, + }) + + return &goast.ForStmt{ + Body: body, + }, nil +} diff --git a/transpiler/transpiler.go b/transpiler/transpiler.go index 3ffea6e3c..87b6c807e 100644 --- a/transpiler/transpiler.go +++ b/transpiler/transpiler.go @@ -137,6 +137,9 @@ func transpileToStmt(node ast.Node, p *program.Program) (goast.Stmt, error) { case *ast.WhileStmt: return transpileWhileStmt(n, p) + case *ast.DoStmt: + return transpileDoStmt(n, p) + case *ast.IfStmt: return transpileIfStmt(n, p)