Jacek Caban : vbscript: Added while..wend statement implementation.
Alexandre Julliard
julliard at winehq.org
Fri Sep 16 13:28:33 CDT 2011
Module: wine
Branch: master
Commit: 3d34925802b62238ae9360ac1e210955cf63de91
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3d34925802b62238ae9360ac1e210955cf63de91
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Sep 16 13:29:59 2011 +0200
vbscript: Added while..wend statement implementation.
---
dlls/vbscript/compile.c | 31 +++++++++++++++++++++++++++++++
dlls/vbscript/parse.h | 9 ++++++++-
dlls/vbscript/parser.y | 16 ++++++++++++++++
dlls/vbscript/tests/lang.vbs | 13 +++++++++++++
4 files changed, 68 insertions(+), 1 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 6bacaa0..814d9ea 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -483,6 +483,34 @@ static HRESULT compile_if_statement(compile_ctx_t *ctx, if_statement_t *stat)
return S_OK;
}
+static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *stat)
+{
+ unsigned start_addr;
+ unsigned jmp_end;
+ HRESULT hres;
+
+ start_addr = ctx->instr_cnt;
+
+ hres = compile_expression(ctx, stat->expr);
+ if(FAILED(hres))
+ return hres;
+
+ jmp_end = push_instr(ctx, OP_jmp_false);
+ if(jmp_end == -1)
+ return E_OUTOFMEMORY;
+
+ hres = compile_statement(ctx, stat->body);
+ if(FAILED(hres))
+ return hres;
+
+ hres = push_instr_addr(ctx, OP_jmp, start_addr);
+ if(FAILED(hres))
+ return hres;
+
+ instr_ptr(ctx, jmp_end)->arg1.uint = ctx->instr_cnt;
+ return S_OK;
+}
+
static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
{
HRESULT hres;
@@ -632,6 +660,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
case STAT_STOP:
hres = push_instr(ctx, OP_stop) == -1 ? E_OUTOFMEMORY : S_OK;
break;
+ case STAT_WHILE:
+ hres = compile_while_statement(ctx, (while_statement_t*)stat);
+ break;
default:
FIXME("Unimplemented statement type %d\n", stat->type);
hres = E_NOTIMPL;
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 245badc..efd3d67 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -99,7 +99,8 @@ typedef enum {
STAT_FUNC,
STAT_IF,
STAT_SET,
- STAT_STOP
+ STAT_STOP,
+ STAT_WHILE
} statement_type_t;
typedef struct _statement_t {
@@ -177,6 +178,12 @@ typedef struct {
} if_statement_t;
typedef struct {
+ statement_t stat;
+ expression_t *expr;
+ statement_t *body;
+} while_statement_t;
+
+typedef struct {
const WCHAR *code;
const WCHAR *ptr;
const WCHAR *end;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index adf1aba..d06c84f 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -52,6 +52,7 @@ static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expression_t*);
static statement_t *new_set_statement(parser_ctx_t*,member_expression_t*,expression_t*);
static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*);
+static statement_t *new_while_statement(parser_ctx_t*,statement_type_t,expression_t*,statement_t*);
static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
@@ -153,6 +154,8 @@ Statement
{ $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
| tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
| IfStatement { $$ = $1; }
+ | tWHILE Expression tNL StatementsNl_opt tWEND
+ { $$ = new_while_statement(ctx, STAT_WHILE, $2, $4); CHECK_ERROR; }
| FunctionDecl { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
| tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; }
| tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 0); CHECK_ERROR; }
@@ -565,6 +568,19 @@ static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, expression_t *expr, sta
return decl;
}
+static statement_t *new_while_statement(parser_ctx_t *ctx, statement_type_t type, expression_t *expr, statement_t *body)
+{
+ while_statement_t *stat;
+
+ stat = new_statement(ctx, type, sizeof(*stat));
+ if(!stat)
+ return NULL;
+
+ stat->expr = expr;
+ stat->body = body;
+ return &stat->stat;
+}
+
static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
statement_t *else_stat)
{
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 961eea2..d3886d6 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -199,6 +199,19 @@ ElseIf not False Then
End If
Call ok(x, "elseif not called?")
+x = false
+y = false
+while not (x and y)
+ if x then
+ y = true
+ end if
+ x = true
+wend
+call ok((x and y), "x or y is false after while")
+
+while false
+wend
+
if false then
Sub testsub
x = true
More information about the wine-cvs
mailing list