Jacek Caban : jscript: Added switch statement implementation.

Alexandre Julliard julliard at winehq.org
Thu Sep 18 07:55:45 CDT 2008


Module: wine
Branch: master
Commit: 2b16387708b2fc1842f726b899e8584eaf5c639f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2b16387708b2fc1842f726b899e8584eaf5c639f

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 17 23:30:20 2008 +0200

jscript: Added switch statement implementation.

---

 dlls/jscript/engine.c      |   79 ++++++++++++++++++++++++++++++++++++++++++--
 dlls/jscript/parser.y      |    6 ++--
 dlls/jscript/tests/lang.js |   30 ++++++++++++++++
 3 files changed, 109 insertions(+), 6 deletions(-)

diff --git a/dlls/jscript/engine.c b/dlls/jscript/engine.c
index 6833954..649ff47 100644
--- a/dlls/jscript/engine.c
+++ b/dlls/jscript/engine.c
@@ -717,10 +717,83 @@ HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_
     return E_NOTIMPL;
 }
 
-HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
+/* ECMA-262 3rd Edition    12.13 */
+HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
 {
-    FIXME("\n");
-    return E_NOTIMPL;
+    switch_statement_t *stat = (switch_statement_t*)_stat;
+    case_clausule_t *iter, *default_clausule = NULL;
+    statement_t *stat_iter;
+    VARIANT val, cval;
+    exprval_t exprval;
+    BOOL b;
+    HRESULT hres;
+
+    TRACE("\n");
+
+    hres = expr_eval(ctx, stat->expr, 0, &rt->ei, &exprval);
+    if(FAILED(hres))
+        return hres;
+
+    hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
+    exprval_release(&exprval);
+    if(FAILED(hres))
+        return hres;
+
+    for(iter = stat->case_list; iter; iter = iter->next) {
+        if(!iter->expr) {
+            default_clausule = iter;
+            continue;
+        }
+
+        hres = expr_eval(ctx, iter->expr, 0, &rt->ei, &exprval);
+        if(FAILED(hres))
+            break;
+
+        hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &cval);
+        exprval_release(&exprval);
+        if(FAILED(hres))
+            break;
+
+        hres = equal2_values(&val, &cval, &b);
+        VariantClear(&cval);
+        if(FAILED(hres) || b)
+            break;
+    }
+
+    VariantClear(&val);
+    if(FAILED(hres))
+        return hres;
+
+    if(!iter)
+        iter = default_clausule;
+
+    V_VT(&val) = VT_EMPTY;
+    if(iter) {
+        VARIANT tmp;
+
+        for(stat_iter = iter->stat; stat_iter; stat_iter = stat_iter->next) {
+            hres = stat_eval(ctx, stat_iter, rt, &tmp);
+            if(FAILED(hres))
+                break;
+
+            VariantClear(&val);
+            val = tmp;
+
+            if(rt->type != RT_NORMAL)
+                break;
+        }
+    }
+
+    if(FAILED(hres)) {
+        VariantClear(&val);
+        return hres;
+    }
+
+    if(rt->type == RT_BREAK)
+        rt->type = RT_NORMAL;
+
+    *ret = val;
+    return S_OK;
 }
 
 /* ECMA-262 3rd Edition    12.13 */
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index 998ab81..5cef648 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -977,14 +977,14 @@ static case_clausule_t *new_case_block(parser_ctx_t *ctx, case_list_t *case_list
     if(!ret)
         return NULL;
 
-    for(iter = ret->next; iter->next; iter = iter->next) {
-        for(iter2 = iter; iter2 && !iter2->expr; iter2 = iter2->next);
+    for(iter = ret; iter; iter = iter->next) {
+        for(iter2 = iter; iter2 && !iter2->stat; iter2 = iter2->next);
         if(!iter2)
             break;
 
         while(iter != iter2) {
             iter->stat = iter2->stat;
-            iter2 = iter2->next;
+            iter = iter->next;
         }
 
         if(stat) {
diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js
index 32bafc6..19b7cbe 100644
--- a/dlls/jscript/tests/lang.js
+++ b/dlls/jscript/tests/lang.js
@@ -416,4 +416,34 @@ try {
 }
 ok(state === "finally", "state = " + state + " expected finally");
 
+state = "";
+switch(1) {
+case "1":
+    ok(false, "unexpected case \"1\"");
+case 1:
+    ok(state === "", "case 1: state = " + state);
+    state = "1";
+default:
+    ok(state === "1", "default: state = " + state);
+    state = "default";
+case false:
+    ok(state === "default", "case false: state = " + state);
+    state = "false";
+}
+ok(state === "false", "state = " + state);
+
+state = "";
+switch("") {
+case "1":
+case 1:
+    ok(false, "unexpected case 1");
+default:
+    ok(state === "", "default: state = " + state);
+    state = "default";
+case false:
+    ok(state === "default", "case false: state = " + state);
+    state = "false";
+}
+ok(state === "false", "state = " + state);
+
 reportSuccess();




More information about the wine-cvs mailing list