Jacek Caban : vbscript: Added do..while and do.. until statements implementation.
Alexandre Julliard
julliard at winehq.org
Fri Sep 16 13:28:33 CDT 2011
Module: wine
Branch: master
Commit: 004210f1fb4abe85fd62a37a915696b66502a372
URL: http://source.winehq.org/git/wine.git/?a=commit;h=004210f1fb4abe85fd62a37a915696b66502a372
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Sep 16 13:30:39 2011 +0200
vbscript: Added do..while and do..until statements implementation.
---
dlls/vbscript/compile.c | 34 +++++++++++++++++++++++++++++++++-
dlls/vbscript/parse.h | 2 ++
dlls/vbscript/parser.y | 3 +++
dlls/vbscript/tests/lang.vbs | 36 ++++++++++++++++++++++++++++++++++++
4 files changed, 74 insertions(+), 1 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 5737676..1ff3c40 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -211,7 +211,7 @@ static BSTR alloc_bstr_arg(compile_ctx_t *ctx, const WCHAR *str)
return NULL;
ctx->code->bstr_pool_size = 8;
}else if(ctx->code->bstr_pool_size == ctx->code->bstr_cnt) {
- BSTR *new_pool;
+ BSTR *new_pool;
new_pool = heap_realloc(ctx->code->bstr_pool, ctx->code->bstr_pool_size*2*sizeof(BSTR));
if(!new_pool)
@@ -524,6 +524,34 @@ static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *st
return S_OK;
}
+static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t *stat)
+{
+ unsigned start_addr, prev_label;
+ HRESULT hres;
+
+ start_addr = ctx->instr_cnt;
+
+ 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;
+
+ hres = compile_expression(ctx, stat->expr);
+ if(FAILED(hres))
+ return hres;
+
+ hres = push_instr_addr(ctx, stat->stat.type == STAT_DOUNTIL ? OP_jmp_false : OP_jmp_true, start_addr);
+ if(FAILED(hres))
+ return hres;
+
+ label_set_addr(ctx, ctx->while_end_label);
+ ctx->while_end_label = prev_label;
+ return S_OK;
+}
+
static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
{
HRESULT hres;
@@ -662,6 +690,10 @@ 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_DOWHILE:
+ case STAT_DOUNTIL:
+ hres = compile_dowhile_statement(ctx, (while_statement_t*)stat);
+ break;
case STAT_EXITDO:
hres = compile_exitdo_statement(ctx);
break;
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 624e49f..d121b72 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -93,6 +93,8 @@ typedef enum {
STAT_ASSIGN,
STAT_CALL,
STAT_DIM,
+ STAT_DOUNTIL,
+ STAT_DOWHILE,
STAT_EXITDO,
STAT_EXITFUNC,
STAT_EXITPROP,
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 820ae6c..b1b385b 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -159,6 +159,9 @@ Statement
| tDO DoType Expression tNL StatementsNl_opt tLOOP
{ $$ = new_while_statement(ctx, $2 ? STAT_WHILELOOP : STAT_UNTIL, $3, $5);
CHECK_ERROR; }
+ | tDO tNL StatementsNl_opt tLOOP DoType Expression
+ { $$ = new_while_statement(ctx, $5 ? STAT_DOWHILE : STAT_DOUNTIL, $6, $3);
+ 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; }
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 8b1d1c3..c62f17f 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -248,6 +248,42 @@ do until false
ok false, "exit do didn't work"
loop
+x = false
+y = false
+do
+ if x then
+ y = true
+ end if
+ x = true
+loop until x and y
+call ok((x and y), "x or y is false after while")
+
+do
+loop until true
+
+do
+ exit do
+ ok false, "exit do didn't work"
+loop until false
+
+x = false
+y = false
+do
+ if x then
+ y = true
+ end if
+ x = true
+loop while not (x and y)
+call ok((x and y), "x or y is false after while")
+
+do
+loop while false
+
+do
+ exit do
+ ok false, "exit do didn't work"
+loop while true
+
if false then
Sub testsub
x = true
More information about the wine-cvs
mailing list