Jacek Caban : vbscript: Added support for exit do statement.
Alexandre Julliard
julliard at winehq.org
Fri Sep 16 13:28:33 CDT 2011
Module: wine
Branch: master
Commit: 9701bdb563046b1f7fa535882b4629c4b7417b11
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9701bdb563046b1f7fa535882b4629c4b7417b11
Author: Jacek Caban <jacek at 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
More information about the wine-cvs
mailing list