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