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