Jacek Caban : vbscript: Added do until..loop statement implementation.

Alexandre Julliard julliard at winehq.org
Fri Sep 16 13:28:33 CDT 2011


Module: wine
Branch: master
Commit: 223a407a7fd399a983d93b8ea10da821bb7f24b0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=223a407a7fd399a983d93b8ea10da821bb7f24b0

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Sep 16 13:30:31 2011 +0200

vbscript: Added do until..loop statement implementation.

---

 dlls/vbscript/compile.c      |    3 ++-
 dlls/vbscript/interp.c       |   25 +++++++++++++++++++++++++
 dlls/vbscript/parse.h        |    1 +
 dlls/vbscript/parser.y       |   11 ++++++++---
 dlls/vbscript/tests/lang.vbs |   18 ++++++++++++++++++
 dlls/vbscript/vbscript.h     |    1 +
 6 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 61854e3..5737676 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -496,7 +496,7 @@ static HRESULT compile_while_statement(compile_ctx_t *ctx, while_statement_t *st
     if(FAILED(hres))
         return hres;
 
-    jmp_end = push_instr(ctx, OP_jmp_false);
+    jmp_end = push_instr(ctx, stat->stat.type == STAT_UNTIL ? OP_jmp_true : OP_jmp_false);
     if(jmp_end == -1)
         return E_OUTOFMEMORY;
 
@@ -686,6 +686,7 @@ 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_UNTIL:
         case STAT_WHILE:
         case STAT_WHILELOOP:
             hres = compile_while_statement(ctx, (while_statement_t*)stat);
diff --git a/dlls/vbscript/interp.c b/dlls/vbscript/interp.c
index 474957c..c8e0514 100644
--- a/dlls/vbscript/interp.c
+++ b/dlls/vbscript/interp.c
@@ -611,6 +611,31 @@ static HRESULT interp_jmp_false(exec_ctx_t *ctx)
     return S_OK;
 }
 
+static HRESULT interp_jmp_true(exec_ctx_t *ctx)
+{
+    const unsigned arg = ctx->instr->arg1.uint;
+    variant_val_t val;
+    HRESULT hres;
+
+    TRACE("%u\n", arg);
+
+    hres = stack_pop_val(ctx, &val);
+    if(FAILED(hres))
+        return hres;
+
+    if(V_VT(val.v) != VT_BOOL) {
+        FIXME("unsupported for %s\n", debugstr_variant(val.v));
+        release_val(&val);
+        return E_NOTIMPL;
+    }
+
+    if(V_BOOL(val.v))
+        instr_jmp(ctx, ctx->instr->arg1.uint);
+    else
+        ctx->instr++;
+    return S_OK;
+}
+
 static HRESULT interp_ret(exec_ctx_t *ctx)
 {
     TRACE("\n");
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 5e9c9ae..624e49f 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -101,6 +101,7 @@ typedef enum {
     STAT_IF,
     STAT_SET,
     STAT_STOP,
+    STAT_UNTIL,
     STAT_WHILE,
     STAT_WHILELOOP
 } statement_type_t;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 1bd8f58..820ae6c 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -114,7 +114,7 @@ static class_decl_t *add_variant_prop(parser_ctx_t*,class_decl_t*,const WCHAR*,u
 %type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
 %type <member> MemberExpression
 %type <expression> Arguments_opt ArgumentList_opt ArgumentList
-%type <bool> OptionExplicit_opt
+%type <bool> OptionExplicit_opt DoType
 %type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
 %type <func_decl> FunctionDecl PropertyDecl
 %type <elseif> ElseIfs_opt ElseIfs ElseIf
@@ -156,8 +156,9 @@ Statement
     | IfStatement                           { $$ = $1; }
     | tWHILE Expression tNL StatementsNl_opt tWEND
                                             { $$ = new_while_statement(ctx, STAT_WHILE, $2, $4); CHECK_ERROR; }
-    | tDO tWHILE Expression tNL StatementsNl_opt tLOOP
-                                            { $$ = new_while_statement(ctx, STAT_WHILELOOP, $3, $5); CHECK_ERROR; }
+    | tDO DoType Expression tNL StatementsNl_opt tLOOP
+                                            { $$ = new_while_statement(ctx, $2 ? STAT_WHILELOOP : STAT_UNTIL, $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; }
@@ -175,6 +176,10 @@ DimDeclList /* FIXME: Support arrays */
     : tIdentifier                           { $$ = new_dim_decl(ctx, $1, NULL); CHECK_ERROR; }
     | tIdentifier ',' DimDeclList           { $$ = new_dim_decl(ctx, $1, $3); CHECK_ERROR; }
 
+DoType
+    : tWHILE        { $$ = TRUE; }
+    | tUNTIL        { $$ = FALSE; }
+
 IfStatement
     : tIF Expression tTHEN tNL StatementsNl ElseIfs_opt Else_opt tEND tIF
                                             { $$ = new_if_statement(ctx, $2, $5, $6, $7); CHECK_ERROR; }
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 78083e6..8b1d1c3 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -230,6 +230,24 @@ do while true
     ok false, "exit do didn't work"
 loop
 
+x = false
+y = false
+do until x and y
+    if x then
+        y = true
+    end if
+    x = true
+loop
+call ok((x and y), "x or y is false after do until")
+
+do until true
+loop
+
+do until false
+    exit do
+    ok false, "exit do didn't work"
+loop
+
 if false then
 Sub testsub
     x = true
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index a2c23ea..12315ae 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -167,6 +167,7 @@ typedef enum {
     X(imp,            1, 0,           0)          \
     X(jmp,            0, ARG_ADDR,    0)          \
     X(jmp_false,      0, ARG_ADDR,    0)          \
+    X(jmp_true,       0, ARG_ADDR,    0)          \
     X(long,           1, ARG_INT,     0)          \
     X(mcall,          1, ARG_BSTR,    ARG_UINT)   \
     X(mcallv,         1, ARG_BSTR,    ARG_UINT)   \




More information about the wine-cvs mailing list