diff --git a/Test.hx b/Test.hx index de82e9a..f91fffd 100644 --- a/Test.hx +++ b/Test.hx @@ -75,6 +75,7 @@ class Test extends TestCase { assertScript("(function(a,b) return a + b)(4,5)",9); assertScript("var y = 0; var add = function(a) y += a; add(5); add(3); y", 8); assertScript("var a = [1,[2,[3,[4,null]]]]; var t = 0; while( a != null ) { t += a[0]; a = a[1]; }; t",10); + assertScript("var a = false; do { a = true; } while (!a); a;",true); assertScript("var t = 0; for( x in 1...10 ) t += x; t", 45); #if haxe3 assertScript("var t = 0; for( x in new IntIterator(1,10) ) t +=x; t", 45); diff --git a/hscript/Bytes.hx b/hscript/Bytes.hx index c28f12e..e11443a 100644 --- a/hscript/Bytes.hx +++ b/hscript/Bytes.hx @@ -177,6 +177,9 @@ class Bytes { case EWhile(cond,e): doEncode(cond); doEncode(e); + case EDoWhile(cond,e): + doEncode(cond); + doEncode(e); case EFor(v,it,e): doEncodeString(v); doEncode(it); @@ -347,6 +350,9 @@ class Bytes { } var def = doDecode(); ESwitch(e, cases, def); + case 24: + var cond = doDecode(); + EDoWhile(cond,doDecode()); case 255: null; default: diff --git a/hscript/Expr.hx b/hscript/Expr.hx index 1bab2c7..a84e69d 100644 --- a/hscript/Expr.hx +++ b/hscript/Expr.hx @@ -67,6 +67,7 @@ enum Expr { EObject( fl : Array<{ name : String, e : Expr }> ); ETernary( cond : Expr, e1 : Expr, e2 : Expr ); ESwitch( e : Expr, cases : Array<{ values : Array, expr : Expr }>, ?defaultExpr : Expr); + EDoWhile( cond : Expr, e : Expr); } typedef Argument = { name : String, ?t : CType, ?opt : Bool }; diff --git a/hscript/Interp.hx b/hscript/Interp.hx index 62cea31..ab6455c 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -365,6 +365,9 @@ class Interp { case EWhile(econd,e): whileLoop(econd,e); return null; + case EDoWhile(econd,e): + doWhileLoop(econd,e); + return null; case EFor(v,it,e): forLoop(v,it,e); return null; @@ -552,6 +555,23 @@ class Interp { return null; } + function doWhileLoop(econd,e) { + var old = declared.length; + do { + try { + expr(e); + } catch( err : Stop ) { + switch(err) { + case SContinue: + case SBreak: break; + case SReturn(_): throw err; + } + } + } + while( expr(econd) == true ); + restore(old); + } + function whileLoop(econd,e) { var old = declared.length; while( expr(econd) == true ) { diff --git a/hscript/Macro.hx b/hscript/Macro.hx index a2b59e9..2b8c286 100644 --- a/hscript/Macro.hx +++ b/hscript/Macro.hx @@ -180,6 +180,8 @@ class Macro { EIf(convert(c), convert(e1), e2 == null ? null : convert(e2)); case EWhile(c, e): EWhile(convert(c), convert(e), true); + case EDoWhile(c, e): + EWhile(convert(c), convert(e), false); #if (haxe_211 || haxe3) case EFor(v, it, efor): var p = #if hscriptPos { file : p.file, min : e.pmin, max : e.pmax } #else p #end; diff --git a/hscript/Parser.hx b/hscript/Parser.hx index df38cbd..d391505 100644 --- a/hscript/Parser.hx +++ b/hscript/Parser.hx @@ -241,6 +241,7 @@ class Parser { case EBinop(_,_,e): isBlock(e); case EUnop(_,prefix,e): !prefix && isBlock(e); case EWhile(_,e): isBlock(e); + case EDoWhile(_,e): isBlock(e); case EFor(_,_,e): isBlock(e); case EReturn(e): e != null && isBlock(e); case ETry(_, _, _, e): isBlock(e); @@ -370,7 +371,7 @@ class Parser { } if( a.length == 1 ) switch( expr(a[0]) ) { - case EFor(_), EWhile(_): + case EFor(_), EWhile(_), EDoWhile(_): var tmp = "__a_" + (uid++); var e = mk(EBlock([ mk(EVar(tmp, null, mk(EArrayDecl([]), p1)), p1), @@ -392,6 +393,8 @@ class Parser { EFor(v, it, mapCompr(tmp, e2)); case EWhile(cond, e2): EWhile(cond, mapCompr(tmp, e2)); + case EDoWhile(cond, e2): + EDoWhile(cond, mapCompr(tmp, e2)); case EIf(cond, e1, e2) if( e2 == null ): EIf(cond, mapCompr(tmp, e1), null); case EBlock([e]): @@ -476,6 +479,16 @@ class Parser { var econd = parseExpr(); var e = parseExpr(); mk(EWhile(econd,e),p1,pmax(e)); + case "do": + var e = parseExpr(); + var tk = token(); + switch(tk) + { + case TId("while"): // Valid + default: unexpected(tk); + } + var econd = parseExpr(); + mk(EDoWhile(econd,e),p1,pmax(econd)); case "for": ensure(TPOpen); var tk = token(); diff --git a/hscript/Printer.hx b/hscript/Printer.hx index 6189eda..4ed7bf8 100644 --- a/hscript/Printer.hx +++ b/hscript/Printer.hx @@ -148,6 +148,12 @@ class Printer { expr(cond); add(" ) "); expr(e); + case EDoWhile(cond,e): + add("do "); + expr(e); + add(" while ( "); + expr(cond); + add(" )"); case EFor(v, it, e): add("for( "+v+" in "); expr(it); diff --git a/hscript/Tools.hx b/hscript/Tools.hx index 9f60bb1..ef28231 100644 --- a/hscript/Tools.hx +++ b/hscript/Tools.hx @@ -15,6 +15,7 @@ class Tools { case ECall(e, args): f(e); for( a in args ) f(a); case EIf(c, e1, e2): f(c); f(e1); if( e2 != null ) f(e2); case EWhile(c, e): f(c); f(e); + case EDoWhile(c, e): f(c); f(e); case EFor(_, it, e): f(it); f(e); case EBreak,EContinue: case EFunction(_, e, _, _): f(e); @@ -48,6 +49,7 @@ class Tools { case ECall(e, args): ECall(f(e),[for( a in args ) f(a)]); case EIf(c, e1, e2): EIf(f(c),f(e1),if( e2 != null ) f(e2) else null); case EWhile(c, e): EWhile(f(c),f(e)); + case EDoWhile(c, e): EDoWhile(f(c),f(e)); case EFor(v, it, e): EFor(v, f(it), f(e)); case EBreak, EContinue: e; case EFunction(args, e, name, t): EFunction(args, f(e), name, t);