Commit e56a5907 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

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

parent 0bd5ba82
...@@ -421,6 +421,8 @@ static HRESULT compile_expression(compile_ctx_t *ctx, expression_t *expr) ...@@ -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); return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_and);
case EXPR_BOOL: case EXPR_BOOL:
return push_instr_int(ctx, OP_bool, ((bool_expression_t*)expr)->value); 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: case EXPR_CONCAT:
return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_concat); return compile_binary_expression(ctx, (binary_expression_t*)expr, OP_concat);
case EXPR_DIV: case EXPR_DIV:
...@@ -691,14 +693,14 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st ...@@ -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); 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; unsigned args_cnt;
vbsop_t op; vbsop_t op;
HRESULT hres; HRESULT hres;
if(stat->member_expr->obj_expr) { if(member_expr->obj_expr) {
hres = compile_expression(ctx, stat->member_expr->obj_expr); hres = compile_expression(ctx, member_expr->obj_expr);
if(FAILED(hres)) if(FAILED(hres))
return hres; return hres;
...@@ -707,15 +709,40 @@ static HRESULT compile_assign_statement(compile_ctx_t *ctx, assign_statement_t * ...@@ -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; 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)) if(FAILED(hres))
return 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)) if(FAILED(hres))
return 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) 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) ...@@ -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); hres = compile_assign_statement(ctx, (assign_statement_t*)stat, FALSE);
break; break;
case STAT_CALL: case STAT_CALL:
hres = compile_member_expression(ctx, ((call_statement_t*)stat)->expr, FALSE); hres = compile_call_statement(ctx, (call_statement_t*)stat);
break; break;
case STAT_CONST: case STAT_CONST:
hres = compile_const_statement(ctx, (const_statement_t*)stat); hres = compile_const_statement(ctx, (const_statement_t*)stat);
......
...@@ -20,6 +20,7 @@ typedef enum { ...@@ -20,6 +20,7 @@ typedef enum {
EXPR_ADD, EXPR_ADD,
EXPR_AND, EXPR_AND,
EXPR_BOOL, EXPR_BOOL,
EXPR_BRACKETS,
EXPR_CONCAT, EXPR_CONCAT,
EXPR_DIV, EXPR_DIV,
EXPR_DOUBLE, EXPR_DOUBLE,
...@@ -127,6 +128,7 @@ typedef struct _statement_t { ...@@ -127,6 +128,7 @@ typedef struct _statement_t {
typedef struct { typedef struct {
statement_t stat; statement_t stat;
member_expression_t *expr; member_expression_t *expr;
BOOL is_strict;
} call_statement_t; } call_statement_t;
typedef struct { typedef struct {
......
...@@ -47,7 +47,7 @@ static expression_t *new_new_expression(parser_ctx_t*,const WCHAR*); ...@@ -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 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 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_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_set_statement(parser_ctx_t*,member_expression_t*,expression_t*);
static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*); static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*);
...@@ -166,8 +166,8 @@ Statement ...@@ -166,8 +166,8 @@ Statement
| SimpleStatement ':' { $$ = $1; } | SimpleStatement ':' { $$ = $1; }
SimpleStatement SimpleStatement
: MemberExpression ArgumentList_opt { $1->args = $2; $$ = new_call_statement(ctx, $1); 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, $2); CHECK_ERROR; } | tCALL MemberExpression Arguments_opt { $2->args = $3; $$ = new_call_statement(ctx, TRUE, $2); CHECK_ERROR; }
| MemberExpression Arguments_opt '=' Expression | MemberExpression Arguments_opt '=' Expression
{ $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; } { $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
| tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; } | tDIM DimDeclList { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
...@@ -349,7 +349,7 @@ LiteralExpression ...@@ -349,7 +349,7 @@ LiteralExpression
| tNOTHING { $$ = new_expression(ctx, EXPR_NOTHING, 0); CHECK_ERROR; } | tNOTHING { $$ = new_expression(ctx, EXPR_NOTHING, 0); CHECK_ERROR; }
PrimaryExpression PrimaryExpression
: '(' Expression ')' { $$ = $2; } : '(' Expression ')' { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
| tME { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; } | tME { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; }
ClassDeclaration ClassDeclaration
...@@ -558,7 +558,7 @@ static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size ...@@ -558,7 +558,7 @@ static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size
return stat; 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; call_statement_t *stat;
...@@ -567,6 +567,7 @@ static statement_t *new_call_statement(parser_ctx_t *ctx, member_expression_t *e ...@@ -567,6 +567,7 @@ static statement_t *new_call_statement(parser_ctx_t *ctx, member_expression_t *e
return NULL; return NULL;
stat->expr = expr; stat->expr = expr;
stat->is_strict = is_strict;
return &stat->stat; return &stat->stat;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment