Module: wine Branch: master Commit: 9701bdb563046b1f7fa535882b4629c4b7417b11 URL: http://source.winehq.org/git/wine.git/?a=commit;h=9701bdb563046b1f7fa535882b...
Author: Jacek Caban jacek@codeweavers.com Date: Fri Sep 16 13:30:20 2011 +0200
vbscript: Added support for exit do statement.
---
dlls/vbscript/compile.c | 31 ++++++++++++++++++++++++++++++- dlls/vbscript/parse.h | 1 + dlls/vbscript/parser.y | 1 + dlls/vbscript/tests/lang.vbs | 5 +++++ 4 files changed, 37 insertions(+), 1 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index e29513b..61854e3 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -38,6 +38,7 @@ typedef struct { unsigned labels_size; unsigned labels_cnt;
+ unsigned while_end_label; unsigned sub_end_label; unsigned func_end_label; unsigned prop_end_label; @@ -485,7 +486,7 @@ static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat)
static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *stat) { - unsigned start_addr; + unsigned start_addr, prev_label; unsigned jmp_end; HRESULT hres;
@@ -499,6 +500,12 @@ static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *st if(jmp_end == -1) return E_OUTOFMEMORY;
+ if(stat->stat.type != STAT_WHILE) { + prev_label = ctx->while_end_label; + if((ctx->while_end_label = alloc_label(ctx)) == -1) + return E_OUTOFMEMORY; + } + hres = compile_statement(ctx, stat->body); if(FAILED(hres)) return hres; @@ -508,6 +515,12 @@ static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *st return hres;
instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt; + + if(stat->stat.type != STAT_WHILE) { + label_set_addr(ctx, ctx->while_end_label); + ctx->while_end_label = prev_label; + } + return S_OK; }
@@ -594,6 +607,16 @@ static HRESULT compile_function_statement(compile_ctx_t *ctx, function_statement return S_OK; }
+static HRESULT compile_exitdo_statement(compile_ctx_t *ctx) +{ + if(ctx->while_end_label == -1) { + FIXME("Exit Do outside Do Loop\n"); + return E_FAIL; + } + + return push_instr_addr(ctx, OP_jmp, ctx->while_end_label); +} + static HRESULT compile_exitsub_statement(compile_ctx_t *ctx) { if(ctx->sub_end_label == -1) { @@ -639,6 +662,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat) case STAT_DIM: hres = compile_dim_statement(ctx, (dim_statement_t*)stat); break; + case STAT_EXITDO: + hres = compile_exitdo_statement(ctx); + break; case STAT_EXITFUNC: hres = compile_exitfunc_statement(ctx); break; @@ -698,6 +724,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->sub_end_label = -1; ctx->func_end_label = -1; ctx->prop_end_label = -1; @@ -732,6 +759,8 @@ static HRESULT compile_func(compile_ctx_t *ctx, statement_t *stat, function_t *f if(FAILED(hres)) return hres;
+ assert(ctx->while_end_label == -1); + if(ctx->sub_end_label != -1) label_set_addr(ctx, ctx->sub_end_label); if(ctx->func_end_label != -1) diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index ff8c137..5e9c9ae 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -93,6 +93,7 @@ typedef enum { STAT_ASSIGN, STAT_CALL, STAT_DIM, + STAT_EXITDO, STAT_EXITFUNC, STAT_EXITPROP, STAT_EXITSUB, diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index c73f368..1bd8f58 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -159,6 +159,7 @@ Statement | tDO tWHILE Expression tNL StatementsNl_opt tLOOP { $$ = new_while_statement(ctx, STAT_WHILELOOP, $3, $5); CHECK_ERROR; } | FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; } + | tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 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 da1e5cb..78083e6 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -225,6 +225,11 @@ call ok((x and y), "x or y is false after while") do while false loop
+do while true + exit do + ok false, "exit do didn't work" +loop + if false then Sub testsub x = true