From: Nikolay Sivov nsivov@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53782 --- dlls/vbscript/compile.c | 23 ++++++++++++++-------- dlls/vbscript/parse.h | 9 +++++++-- dlls/vbscript/parser.y | 34 ++++++++++++++++++++++++++------ dlls/vbscript/tests/lang.vbs | 38 ++++++++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 16 deletions(-)
diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 79819c39026..f592697f4e3 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -1165,19 +1165,26 @@ static HRESULT compile_dim_statement(compile_ctx_t *ctx, dim_statement_t *stat)
static HRESULT compile_redim_statement(compile_ctx_t *ctx, redim_statement_t *stat) { + redim_decl_t *decl = stat->redim_decls; unsigned arg_cnt; HRESULT hres;
- hres = compile_args(ctx, stat->dims, &arg_cnt); - if(FAILED(hres)) - return hres; + while(1) { + hres = compile_args(ctx, decl->dims, &arg_cnt); + if(FAILED(hres)) + return hres;
- hres = push_instr_bstr_uint(ctx, stat->preserve ? OP_redim_preserve : OP_redim, stat->identifier, arg_cnt); - if(FAILED(hres)) - return hres; + hres = push_instr_bstr_uint(ctx, stat->preserve ? OP_redim_preserve : OP_redim, decl->identifier, arg_cnt); + if(FAILED(hres)) + return hres;
- if(!emit_catch(ctx, 0)) - return E_OUTOFMEMORY; + if(!emit_catch(ctx, 0)) + return E_OUTOFMEMORY; + + if(!decl->next) + break; + decl = decl->next; + }
return S_OK; } diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index 32cfcfe75c5..7c13ad72bf6 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -172,11 +172,16 @@ typedef struct _dim_statement_t { dim_decl_t *dim_decls; } dim_statement_t;
+typedef struct _redim_decl_t { + const WCHAR *identifier; + expression_t *dims; + struct _redim_decl_t *next; +} redim_decl_t; + typedef struct { statement_t stat; - const WCHAR *identifier; BOOL preserve; - expression_t *dims; + redim_decl_t *redim_decls; } redim_statement_t;
typedef struct _arg_decl_t { diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 90ed921c2a9..42838d34f17 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -51,7 +51,7 @@ static statement_t *new_call_statement(parser_ctx_t*,unsigned,expression_t*); static statement_t *new_assign_statement(parser_ctx_t*,unsigned,expression_t*,expression_t*); static statement_t *new_set_statement(parser_ctx_t*,unsigned,expression_t*,expression_t*); static statement_t *new_dim_statement(parser_ctx_t*,unsigned,dim_decl_t*); -static statement_t *new_redim_statement(parser_ctx_t*,unsigned,const WCHAR*,BOOL,expression_t*); +static statement_t *new_redim_statement(parser_ctx_t*,unsigned,BOOL,redim_decl_t*); static statement_t *new_while_statement(parser_ctx_t*,unsigned,statement_type_t,expression_t*,statement_t*); static statement_t *new_forto_statement(parser_ctx_t*,unsigned,const WCHAR*,expression_t*,expression_t*,expression_t*,statement_t*); static statement_t *new_foreach_statement(parser_ctx_t*,unsigned,const WCHAR*,expression_t*,statement_t*); @@ -64,6 +64,7 @@ static statement_t *new_with_statement(parser_ctx_t*,unsigned,expression_t*,stat
static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,BOOL,dim_list_t*); static dim_list_t *new_dim(parser_ctx_t*,unsigned,dim_list_t*); +static redim_decl_t *new_redim_decl(parser_ctx_t*,const WCHAR*,expression_t*); static elseif_decl_t *new_elseif_decl(parser_ctx_t*,unsigned,expression_t*,statement_t*); static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,arg_decl_t*,statement_t*); static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL); @@ -100,6 +101,7 @@ static statement_t *link_statements(statement_t*,statement_t*); elseif_decl_t *elseif; dim_decl_t *dim_decl; dim_list_t *dim_list; + redim_decl_t *redim_decl; function_decl_t *func_decl; arg_decl_t *arg_decl; class_decl_t *class_decl; @@ -150,6 +152,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %type <uint> Storage Storage_opt IntegerValue %type <dim_decl> DimDeclList DimDecl %type <dim_list> DimList +%type <redim_decl> ReDimDeclList ReDimDecl %type <const_decl> ConstDecl ConstDeclList %type <string> Identifier %type <case_clausule> CaseClausules @@ -209,8 +212,7 @@ SimpleStatement | CallExpression '=' Expression { $$ = new_assign_statement(ctx, @$, $1, $3); CHECK_ERROR; } | tDIM DimDeclList { $$ = new_dim_statement(ctx, @$, $2); CHECK_ERROR; } - | tREDIM Preserve_opt tIdentifier '(' ArgumentList ')' - { $$ = new_redim_statement(ctx, @$, $3, $2, $5); CHECK_ERROR; } + | tREDIM Preserve_opt ReDimDeclList { $$ = new_redim_statement(ctx, @$, $2, $3); CHECK_ERROR; } | IfStatement { $$ = $1; } | tWHILE Expression StSep StatementsNl_opt tWEND { $$ = new_while_statement(ctx, @$, STAT_WHILE, $2, $4); CHECK_ERROR; } @@ -251,6 +253,13 @@ Preserve_opt : /* empty */ { $$ = FALSE; } | tPRESERVE { $$ = TRUE; }
+ReDimDecl + : tIdentifier '(' ArgumentList ')' { $$ = new_redim_decl(ctx, $1, $3); CHECK_ERROR; } + +ReDimDeclList + : ReDimDecl { $$ = $1; } + | ReDimDecl ',' ReDimDeclList { $1->next = $3; $$ = $1; } + DimDeclList : DimDecl { $$ = $1; } | DimDecl ',' DimDeclList { $1->next = $3; $$ = $1; } @@ -846,7 +855,21 @@ static statement_t *new_dim_statement(parser_ctx_t *ctx, unsigned loc, dim_decl_ return &stat->stat; }
-static statement_t *new_redim_statement(parser_ctx_t *ctx, unsigned loc, const WCHAR *identifier, BOOL preserve, expression_t *dims) +static redim_decl_t *new_redim_decl(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *dims) +{ + redim_decl_t *decl; + + decl = parser_alloc(ctx, sizeof(*decl)); + if(!decl) + return NULL; + + decl->identifier = identifier; + decl->dims = dims; + decl->next = NULL; + return decl; +} + +static statement_t *new_redim_statement(parser_ctx_t *ctx, unsigned loc, BOOL preserve, redim_decl_t *decls) { redim_statement_t *stat;
@@ -854,9 +877,8 @@ static statement_t *new_redim_statement(parser_ctx_t *ctx, unsigned loc, const W if(!stat) return NULL;
- stat->identifier = identifier; stat->preserve = preserve; - stat->dims = dims; + stat->redim_decls = decls; return &stat->stat; }
diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index f147351b1af..2467b814eff 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -1503,6 +1503,44 @@ e = err.number on error goto 0 todo_wine_ok e = 10, "e = " & e
+sub TestReDimList + dim x, y + + x = Array(1) + y = Array(1) + redim x(1, 3), y(2) + ok ubound(x, 1) = 1, "ubound(x, 1) = " & ubound(x, 1) + ok ubound(x, 2) = 3, "ubound(x, 2) = " & ubound(x, 2) + ok ubound(y, 1) = 2, "ubound(y, 1) = " & ubound(y, 1) + + x(0,0) = 1.1 + x(0,1) = 1.2 + x(0,2) = 1.3 + x(0,3) = 1.4 + x(1,0) = 2.1 + x(1,1) = 2.2 + x(1,2) = 2.3 + x(1,3) = 2.4 + + y(0) = 2.1 + y(1) = 2.2 + y(2) = 2.3 + + redim preserve x(1,1), y(3) + ok ubound(x, 1) = 1, "ubound(x, 1) = " & ubound(x, 1) + ok ubound(x, 2) = 1, "ubound(x, 2) = " & ubound(x, 2) + ok x(0,0) = 1.1, "x(0,0) = " & x(0,0) + ok x(0,1) = 1.2, "x(0,1) = " & x(0,1) + ok x(1,0) = 2.1, "x(1,0) = " & x(1,0) + ok x(1,1) = 2.2, "x(1,1) = " & x(1,1) + ok ubound(y, 1) = 3, "ubound(y, 1) = " & ubound(y, 1) + ok y(0) = 2.1, "y(0) = " & y(0) + ok y(1) = 2.2, "y(1) = " & y(1) + ok y(2) = 2.3, "y(2) = " & y(2) + ok y(3) = vbEmpty, "y(3) = " & y(3) +end sub +call TestReDimList + Class ArrClass Dim classarr(3) Dim classnoarr()