Module: wine Branch: master Commit: ed53c40eda20dfb00544869cf6ca13cc7698a467 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ed53c40eda20dfb00544869cf6...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Sep 22 14:24:44 2011 +0200
vbscript: Added exit for statement support.
---
dlls/vbscript/compile.c | 27 +++++++++++++++++++++++++-- dlls/vbscript/parse.h | 1 + dlls/vbscript/parser.y | 1 + dlls/vbscript/tests/lang.vbs | 9 +++++++++ 4 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 1f1f041..153e9b0 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -39,6 +39,7 @@ typedef struct { unsigned labels_cnt;
unsigned while_end_label; + unsigned for_end_label; unsigned sub_end_label; unsigned func_end_label; unsigned prop_end_label; @@ -617,7 +618,7 @@ static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *
static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat) { - unsigned step_instr, instr; + unsigned step_instr, instr, prev_label; BSTR identifier; HRESULT hres;
@@ -654,10 +655,16 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st return hres; }
+ prev_label = ctx->for_end_label; + ctx->for_end_label = alloc_label(ctx); + if(ctx->for_end_label == -1) + return E_OUTOFMEMORY; + step_instr = push_instr(ctx, OP_step); if(step_instr == -1) return E_OUTOFMEMORY; instr_ptr(ctx, step_instr)->arg2.bstr = identifier; + instr_ptr(ctx, step_instr)->arg1.uint = ctx->for_end_label;
hres = compile_statement(ctx, stat->body); if(FAILED(hres)) @@ -672,7 +679,8 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st if(FAILED(hres)) return hres;
- instr_ptr(ctx, step_instr)->arg1.uint = ctx->instr_cnt; + label_set_addr(ctx, ctx->for_end_label); + ctx->for_end_label = prev_label;
return push_instr_uint(ctx, OP_pop, 2); } @@ -804,6 +812,16 @@ static HRESULT compile_exitdo_statement(compile_ctx_t *ctx) return push_instr_addr(ctx, OP_jmp, ctx->while_end_label); }
+static HRESULT compile_exitfor_statement(compile_ctx_t *ctx) +{ + if(ctx->for_end_label == -1) { + FIXME("Exit For outside For Loop\n"); + return E_FAIL; + } + + return push_instr_addr(ctx, OP_jmp, ctx->for_end_label); +} + static HRESULT compile_exitsub_statement(compile_ctx_t *ctx) { if(ctx->sub_end_label == -1) { @@ -864,6 +882,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat) case STAT_EXITDO: hres = compile_exitdo_statement(ctx); break; + case STAT_EXITFOR: + hres = compile_exitfor_statement(ctx); + break; case STAT_EXITFUNC: hres = compile_exitfunc_statement(ctx); break; @@ -931,6 +952,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f func->code_off = ctx->instr_cnt;
ctx->while_end_label = -1; + ctx->for_end_label = -1; ctx->sub_end_label = -1; ctx->func_end_label = -1; ctx->prop_end_label = -1; @@ -967,6 +989,7 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f return hres;
assert(ctx->while_end_label == -1); + assert(ctx->for_end_label == -1);
if(ctx->sub_end_label != -1) label_set_addr(ctx, ctx->sub_end_label); diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index a5bd505..e58e7f3 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -103,6 +103,7 @@ typedef enum { STAT_DOUNTIL, STAT_DOWHILE, STAT_EXITDO, + STAT_EXITFOR, STAT_EXITFUNC, STAT_EXITPROP, STAT_EXITSUB, diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 3b30051..d6bda55 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -178,6 +178,7 @@ SimpleStatement CHECK_ERROR; } | FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; } | tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 0); CHECK_ERROR; } + | tEXIT tFOR { $$ = new_statement(ctx, STAT_EXITFOR, 0); CHECK_ERROR; } | tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; } | tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 0); CHECK_ERROR; } | tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; } diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 3b3ad50..46a0330 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -387,6 +387,15 @@ for x = 5 to 8 next Call ok(y = "for8: 5 7", "y = " & y)
+for x = 1.5 to 1 + Call ok(false, "for..to called when unexpected") +next + +for x = 1 to 100 + exit for + Call ok(false, "exit for not escaped the loop?") +next + if false then Sub testsub x = true