From 8d35e2ff8caf7a9396f7c0bdf23db8496bbae61d Mon Sep 17 00:00:00 2001 From: Nicolas Cannasse Date: Thu, 11 Sep 2014 17:13:31 +0200 Subject: [PATCH] added TSwitch support --- README.md | 2 +- hscript/Expr.hx | 1 + hscript/Interp.hx | 17 +++++++++++++++++ hscript/Parser.hx | 40 +++++++++++++++++++++++++++++++++++++--- hscript/Tools.hx | 8 ++++++++ 5 files changed, 64 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9455363..ec07c06 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ limitations Compared to Haxe, limitations are : - no type declarations (classes, enums, typedefs) : only expressions -- no switch construct +- switch construct is supported but not pattern matching (no variable capture, we use strict equality to compare case values and switch valueà - only one variable declaration is allowed in var - the parser supports optional types for var and function if allowTypes is set, but the interpreter ignore them - you can enable per-expression position tracking by compiling with -D hscriptPos diff --git a/hscript/Expr.hx b/hscript/Expr.hx index c100c03..ed31aea 100644 --- a/hscript/Expr.hx +++ b/hscript/Expr.hx @@ -66,6 +66,7 @@ enum Expr { ETry( e : Expr, v : String, t : Null, ecatch : 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); } enum CType { diff --git a/hscript/Interp.hx b/hscript/Interp.hx index f08dcf6..3dc4e27 100644 --- a/hscript/Interp.hx +++ b/hscript/Interp.hx @@ -378,6 +378,23 @@ class Interp { return o; case ETernary(econd,e1,e2): return if( expr(econd) == true ) expr(e1) else expr(e2); + case ESwitch(e, cases, def): + var val : Dynamic = expr(e); + var match = false; + for( c in cases ) { + for( v in c.values ) + if( expr(v) == val ) { + match = true; + break; + } + if( match ) { + val = expr(c.expr); + break; + } + } + if( !match ) + val = def == null ? null : expr(def); + return val; } return null; } diff --git a/hscript/Parser.hx b/hscript/Parser.hx index e93d1ae..9171544 100644 --- a/hscript/Parser.hx +++ b/hscript/Parser.hx @@ -58,7 +58,7 @@ class Parser { public var opRightAssoc : Hash; public var unops : Hash; // true if allow postfix #end - + /** activate JSON compatiblity **/ @@ -92,7 +92,7 @@ class Parser { #else var tokens : haxe.FastList; #end - + #end @@ -556,7 +556,41 @@ class Parser { } ensure(TPClose); var ec = parseExpr(); - mk(ETry(e,vname,t,ec),p1,pmax(ec)); + mk(ETry(e, vname, t, ec), p1, pmax(ec)); + case "switch": + var e = parseExpr(); + var def = null, cases = []; + ensure(TBrOpen); + while( true ) { + var tk = token(); + switch( tk ) { + case TId("case"): + var c = { values : [], expr : null }; + cases.push(c); + while( true ) { + var e = parseExpr(); + c.values.push(e); + switch( token() ) { + case TComma: + // next expr + case TSemicolon: + break; + default: + unexpected(tk); + } + } + c.expr = parseExpr(); + case TId("default"): + if( def != null ) unexpected(tk); + ensure(TSemicolon); + def = parseExpr(); + case TBrClose: + break; + default: + unexpected(tk); + } + } + mk(ESwitch(e, cases, def), p1, tokenMax); default: null; } diff --git a/hscript/Tools.hx b/hscript/Tools.hx index 1e6f35b..9f60bb1 100644 --- a/hscript/Tools.hx +++ b/hscript/Tools.hx @@ -26,6 +26,13 @@ class Tools { case ETry(e, _, _, c): f(e); f(c); case EObject(fl): for( fi in fl ) f(fi.e); case ETernary(c, e1, e2): f(c); f(e1); f(e2); + case ESwitch(e, cases, def): + f(e); + for( c in cases ) { + for( v in c.values ) f(v); + f(c.expr); + } + if( def != null ) f(def); } } @@ -52,6 +59,7 @@ class Tools { case ETry(e, v, t, c): ETry(f(e), v, t, f(c)); case EObject(fl): EObject([for( fi in fl ) { name : fi.name, e : f(fi.e) }]); case ETernary(c, e1, e2): ETernary(f(c), f(e1), f(e2)); + case ESwitch(e, cases, def): ESwitch(f(e), [for( c in cases ) { values : [for( v in c.values ) f(v)], expr : f(c.expr) } ], def == null ? null : f(def)); } }