Jacek Caban : vbscript: Added a hack for parameterized assignments with one argument.

Alexandre Julliard julliard at winehq.org
Tue Jul 3 10:58:27 CDT 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Jul  3 17:04:51 2012 +0200

vbscript: Added a hack for parameterized assignments with one argument.

---

 dlls/vbscript/compile.c |   41 ++++++++++++++++++++++++++++++++++-------
 dlls/vbscript/parse.h   |    2 ++
 dlls/vbscript/parser.y  |   11 ++++++-----
 3 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index f3d88a0..28d1280 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -421,6 +421,8 @@ static HRESULT compile_expression(compile_ctx_t *ctx, expression_t *expr)
         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_and);
     case EXPR_BOOL:
         return push_instr_int(ctx, OP_bool, ((bool_expression_t*)expr)->value);
+    case EXPR_BRACKETS:
+        return compile_expression(ctx, ((unary_expression_t*)expr)->subexpr);
     case EXPR_CONCAT:
         return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_concat);
     case EXPR_DIV:
@@ -691,14 +693,14 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
     return push_instr_uint(ctx, OP_pop, 2);
 }
 
-static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
+static HRESULT compile_assignment(compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)
 {
     unsigned args_cnt;
     vbsop_t op;
     HRESULT hres;
 
-    if(stat->member_expr->obj_expr) {
-        hres = compile_expression(ctx, stat->member_expr->obj_expr);
+    if(member_expr->obj_expr) {
+        hres = compile_expression(ctx, member_expr->obj_expr);
         if(FAILED(hres))
             return hres;
 
@@ -707,15 +709,40 @@ static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *
         op = is_set ? OP_set_ident : OP_assign_ident;
     }
 
-    hres = compile_expression(ctx, stat->value_expr);
+    hres = compile_expression(ctx, value_expr);
     if(FAILED(hres))
         return hres;
 
-    hres = compile_args(ctx, stat->member_expr->args, &args_cnt);
+    hres = compile_args(ctx, member_expr->args, &args_cnt);
     if(FAILED(hres))
         return hres;
 
-    return push_instr_bstr_uint(ctx, op, stat->member_expr->identifier, args_cnt);
+    return push_instr_bstr_uint(ctx, op, member_expr->identifier, args_cnt);
+}
+
+static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t *stat, BOOL is_set)
+{
+    return compile_assignment(ctx, stat->member_expr, stat->value_expr, is_set);
+}
+
+static HRESULT compile_call_statement(compile_ctx_t *ctx, call_statement_t *stat)
+{
+    /* It's challenging for parser to distinguish parameterized assignment with one argument from call
+     * with equality expression argument, so we do it in compiler. */
+    if(!stat->is_strict && stat->expr->args && !stat->expr->args->next && stat->expr->args->type == EXPR_EQUAL) {
+        binary_expression_t *eqexpr = (binary_expression_t*)stat->expr->args;
+
+        if(eqexpr->left->type == EXPR_BRACKETS) {
+            member_expression_t new_member = *stat->expr;
+
+            WARN("converting call expr to assign expr\n");
+
+            new_member.args = ((unary_expression_t*)eqexpr->left)->subexpr;
+            return compile_assignment(ctx, &new_member, eqexpr->right, FALSE);
+        }
+    }
+
+    return compile_member_expression(ctx, stat->expr, FALSE);
 }
 
 static BOOL lookup_dim_decls(compile_ctx_t *ctx, const WCHAR *name)
@@ -874,7 +901,7 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat)
             hres = compile_assign_statement(ctx, (assign_statement_t*)stat, FALSE);
             break;
         case STAT_CALL:
-            hres = compile_member_expression(ctx, ((call_statement_t*)stat)->expr, FALSE);
+            hres = compile_call_statement(ctx, (call_statement_t*)stat);
             break;
         case STAT_CONST:
             hres = compile_const_statement(ctx, (const_statement_t*)stat);
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index b97ee13..50151d3 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -20,6 +20,7 @@ typedef enum {
     EXPR_ADD,
     EXPR_AND,
     EXPR_BOOL,
+    EXPR_BRACKETS,
     EXPR_CONCAT,
     EXPR_DIV,
     EXPR_DOUBLE,
@@ -127,6 +128,7 @@ typedef struct _statement_t {
 typedef struct {
     statement_t stat;
     member_expression_t *expr;
+    BOOL is_strict;
 } call_statement_t;
 
 typedef struct {
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index a5f7405..fca0cf1 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -47,7 +47,7 @@ static expression_t *new_new_expression(parser_ctx_t*,const WCHAR*);
 static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);
 
 static void *new_statement(parser_ctx_t*,statement_type_t,size_t);
-static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
+static statement_t *new_call_statement(parser_ctx_t*,BOOL,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*);
@@ -166,8 +166,8 @@ Statement
     | SimpleStatement ':'                   { $$ = $1; }
 
 SimpleStatement
-    : MemberExpression ArgumentList_opt     { $1->args = $2; $$ = new_call_statement(ctx, $1); CHECK_ERROR; }
-    | tCALL MemberExpression Arguments_opt  { $2->args = $3; $$ = new_call_statement(ctx, $2); CHECK_ERROR; }
+    : MemberExpression ArgumentList_opt     { $1->args = $2; $$ = new_call_statement(ctx, FALSE, $1); CHECK_ERROR; }
+    | tCALL MemberExpression Arguments_opt  { $2->args = $3; $$ = new_call_statement(ctx, TRUE, $2); CHECK_ERROR; }
     | MemberExpression Arguments_opt '=' Expression
                                             { $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
     | tDIM DimDeclList                      { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
@@ -349,7 +349,7 @@ LiteralExpression
     | tNOTHING                      { $$ = new_expression(ctx, EXPR_NOTHING, 0); CHECK_ERROR; }
 
 PrimaryExpression
-    : '(' Expression ')'            { $$ = $2; }
+    : '(' Expression ')'            { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
     | tME                           { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; }
 
 ClassDeclaration
@@ -558,7 +558,7 @@ static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size
     return stat;
 }
 
-static statement_t *new_call_statement(parser_ctx_t *ctx, member_expression_t *expr)
+static statement_t *new_call_statement(parser_ctx_t *ctx, BOOL is_strict, member_expression_t *expr)
 {
     call_statement_t *stat;
 
@@ -567,6 +567,7 @@ static statement_t *new_call_statement(parser_ctx_t *ctx, member_expression_t *e
         return NULL;
 
     stat->expr = expr;
+    stat->is_strict = is_strict;
     return &stat->stat;
 }
 




More information about the wine-cvs mailing list