Module: wine Branch: master Commit: 509044296dde3688cfdaaf02325a1bc8f890bd85 URL: https://source.winehq.org/git/wine.git/?a=commit;h=509044296dde3688cfdaaf023...
Author: Jacek Caban jacek@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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()