summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorVincent Burns <discoloda@gmail.com>2014-01-13 01:42:26 -0500
committerVincent Burns <discoloda@gmail.com>2014-01-13 01:42:26 -0500
commit58855c2fc71294bd08ca6637473a33389ecc7de5 (patch)
treef88c7dcdca134dc518022d7f0fa6aaa946c8e711 /compiler
parent97eaeb3aec42b2bf33190a8949d4673a547cdac6 (diff)
downloadNim-58855c2fc71294bd08ca6637473a33389ecc7de5.tar.gz
Support more proper do..while statements
Diffstat (limited to 'compiler')
-rw-r--r--compiler/c2nim/cparse.nim48
1 files changed, 39 insertions, 9 deletions
diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim
index cfda51167..aa2dfa3e1 100644
--- a/compiler/c2nim/cparse.nim
+++ b/compiler/c2nim/cparse.nim
@@ -1498,19 +1498,51 @@ proc parseWhile(p: var TParser): PNode =
   eat(p, pxParRi, result)
   addSon(result, nestedStatement(p))
 
+proc embedStmts(sl, a: PNode)
+
 proc parseDoWhile(p: var TParser): PNode =  
-  # we only support ``do stmt while (0)`` as an idiom for 
-  # ``block: stmt``
-  result = newNodeP(nkBlockStmt, p)
-  getTok(p, result) # skip "do"
-  addSon(result, ast.emptyNode, nestedStatement(p))
+  # parsing
+  result = newNodeP(nkWhileStmt, p)
+  getTok(p, result)
+  var stm = nestedStatement(p)
   eat(p, "while", result)
   eat(p, pxParLe, result)
-  if p.tok.xkind == pxIntLit and p.tok.iNumber == 0: getTok(p, result)
-  else: parMessage(p, errTokenExpected, "0")
+  var exp = expression(p)
   eat(p, pxParRi, result)
   if p.tok.xkind == pxSemicolon: getTok(p)
 
+  # while true:
+  #   stmt
+  #   if not expr:
+  #     break
+  addSon(result, newIdentNodeP("true", p))
+
+  stm = buildStmtList(stm)
+
+  # get the last exp if it is a stmtlist
+  var cleanedExp = exp
+  if exp.kind == nkStmtList:
+    cleanedExp = exp.sons[exp.len-1]
+    exp.sons = exp.sons[0..exp.len-2]
+    embedStmts(stm, exp)
+
+  var notExp = newNodeP(nkPrefix, p)
+  addSon(notExp, newIdentNodeP("not", p))
+  addSon(notExp, cleanedExp)
+
+  var brkStm = newNodeP(nkBreakStmt, p)
+  addSon(brkStm, ast.emptyNode)
+
+  var ifStm = newNodeP(nkIfStmt, p)
+  var ifBranch = newNodeP(nkElifBranch, p)
+  addSon(ifBranch, notExp)
+  addSon(ifBranch, brkStm)
+  addSon(ifStm, ifBranch)
+
+  embedStmts(stm, ifStm)
+
+  addSon(result, stm)
+
 proc declarationOrStatement(p: var TParser): PNode = 
   if p.tok.xkind != pxSymbol:
     result = expressionStatement(p)
@@ -1583,8 +1615,6 @@ proc parseStandaloneStruct(p: var TParser, isUnion: bool): PNode =
     backtrackContext(p)
     result = declaration(p)
 
-proc embedStmts(sl, a: PNode)
-
 proc parseFor(p: var TParser, result: PNode) = 
   # 'for' '(' expression_statement expression_statement expression? ')'
   #   statement