Jacek Caban : vbscript: Fix parsing call expressions.

Alexandre Julliard julliard at winehq.org
Tue Nov 5 16:11:44 CST 2019


Module: wine
Branch: master
Commit: 509044296dde3688cfdaaf02325a1bc8f890bd85
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=509044296dde3688cfdaaf02325a1bc8f890bd85

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Nov  5 14:08:35 2019 +0100

vbscript: Fix parsing call expressions.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=41119
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/vbscript/compile.c      | 15 ---------------
 dlls/vbscript/lex.c          |  8 +++++++-
 dlls/vbscript/parser.y       | 22 ++++++++++++++++------
 dlls/vbscript/tests/lang.vbs | 19 +++++++++++++++++++
 4 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 6b0e113bef..e52b0814e0 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -1038,21 +1038,6 @@ static HRESULT compile_call_statement(compile_ctx_t *ctx, call_statement_t *stat
 {
     HRESULT hres;
 
-    /* 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) {
-            call_expression_t new_call = *stat->expr;
-
-            WARN("converting call expr to assign expr\n");
-
-            new_call.args = ((unary_expression_t*)eqexpr->left)->subexpr;
-            return compile_assignment(ctx, &new_call, eqexpr->right, FALSE);
-        }
-    }
-
     hres = compile_call_expression(ctx, stat->expr, FALSE);
     if(FAILED(hres))
         return hres;
diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index f78eee4ff9..005e7c3d58 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -409,7 +409,13 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
             ctx->ptr++;
             return tEMPTYBRACKETS;
         }
-        return '(';
+        /*
+         * Parser can't predict if bracket is part of argument expression or an argument
+         * in call expression. We predict it here instead.
+         */
+        if(ctx->last_token == tIdentifier || ctx->last_token == ')')
+            return '(';
+        return tEXPRLBRACKET;
     case '"':
         return parse_string_literal(ctx, lval);
     case '&':
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index 46af0b16be..9315b7ea39 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -107,7 +107,7 @@ static statement_t *link_statements(statement_t*,statement_t*);
     double dbl;
 }
 
-%token tEXPRESSION tEOF tNL tEMPTYBRACKETS
+%token tEXPRESSION tEOF tNL tEMPTYBRACKETS tEXPRLBRACKET
 %token tLTEQ tGTEQ tNEQ
 %token tSTOP tME tREM tDOT
 %token <string> tTRUE tFALSE
@@ -427,7 +427,7 @@ IntegerValue
     | tInt                          { $$ = $1; }
 
 PrimaryExpression
-    : '(' Expression ')'            { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
+    : tEXPRLBRACKET Expression ')'            { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
     | tME                           { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; }
 
 ClassDeclaration
@@ -729,18 +729,28 @@ static call_expression_t *make_call_expression(parser_ctx_t *ctx, expression_t *
     call_expr = (call_expression_t*)callee_expr;
     if(!call_expr->args) {
         call_expr->args = arguments;
-    }else if(call_expr->args->next) {
+        return call_expr;
+    }
+
+    if(call_expr->args->next) {
         FIXME("Invalid syntax: invalid use of parentheses for arguments\n");
         ctx->hres = E_FAIL;
         return NULL;
-    }else if(arguments->type != EXPR_NOARG) {
+    }
+
+    call_expr->args = new_unary_expression(ctx, EXPR_BRACKETS, call_expr->args);
+    if(!call_expr->args)
+        return NULL;
+    if(!arguments)
+        return call_expr;
+
+    if(arguments->type != EXPR_NOARG) {
         FIXME("Invalid syntax: missing comma\n");
         ctx->hres = E_FAIL;
         return NULL;
-    }else {
-        call_expr->args->next = arguments->next;
     }
 
+    call_expr->args->next = arguments->next;
     return call_expr;
 }
 
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs
index 8a6f0ecd45..46e2ac7ab8 100644
--- a/dlls/vbscript/tests/lang.vbs
+++ b/dlls/vbscript/tests/lang.vbs
@@ -1645,4 +1645,23 @@ end function
 set x = testsetresult(1, 2)
 ok x.prop = 1, "x.prop = " & x.prop
 
+set arr(0) = new TestPropSyntax
+arr(0).prop = 1
+ok arr(0).prop = 1, "arr(0) = " & arr(0).prop
+
+function f2(x,y)
+end function
+
+f2 1 = 1, 2
+
+function f1(x)
+    ok x = true, "x = " & x
+end function
+
+f1 1 = 1
+f1 1 = (1)
+f1 not 1 = 0
+
+arr (0) = 2 xor -2
+
 reportSuccess()




More information about the wine-cvs mailing list