Module: wine Branch: master Commit: e56a5907a3b7794a4014114a844726b7377c2395 URL: http://source.winehq.org/git/wine.git/?a=commit;h=e56a5907a3b7794a4014114a84...
Author: Jacek Caban jacek@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; }