From 2b16387708b2fc1842f726b899e8584eaf5c639f Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 17 Sep 2008 23:30:20 +0200 Subject: [PATCH] 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 68339547d10..649ff47f7e4 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 998ab81e5eb..5cef6484314 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 32bafc6bce3..19b7cbe6368 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();