From 8c1b9a01bf20f13d470a06caeeb08f88cc7d7e25 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 4 Jan 2012 11:50:29 +0100 Subject: [PATCH] vbscript: Added for each loop parser implementation. --- dlls/vbscript/compile.c | 9 +++++++++ dlls/vbscript/lex.c | 4 ++++ dlls/vbscript/parse.h | 8 ++++++++ dlls/vbscript/parser.y | 20 +++++++++++++++++++- 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 435f9e32451..9f62a238b37 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -616,6 +616,12 @@ static HRESULT compile_dowhile_statement(compile_ctx_t *ctx, while_statement_t * return S_OK; } +static HRESULT compile_foreach_statement(compile_ctx_t *ctx, foreach_statement_t *stat) +{ + FIXME("for each loop not implemented\n"); + return E_NOTIMPL; +} + static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *stat) { unsigned step_instr, instr, prev_label; @@ -895,6 +901,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_t *stat) case STAT_EXITSUB: hres = compile_exitsub_statement(ctx); break; + case STAT_FOREACH: + hres = compile_foreach_statement(ctx, (foreach_statement_t*)stat); + break; case STAT_FORTO: hres = compile_forto_statement(ctx, (forto_statement_t*)stat); break; diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index 81d451752bb..fe5fbaebbf0 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -35,6 +35,7 @@ static const WCHAR constW[] = {'c','o','n','s','t',0}; static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0}; static const WCHAR dimW[] = {'d','i','m',0}; static const WCHAR doW[] = {'d','o',0}; +static const WCHAR eachW[] = {'e','a','c','h',0}; static const WCHAR elseW[] = {'e','l','s','e',0}; static const WCHAR elseifW[] = {'e','l','s','e','i','f',0}; static const WCHAR emptyW[] = {'e','m','p','t','y',0}; @@ -50,6 +51,7 @@ static const WCHAR getW[] = {'g','e','t',0}; static const WCHAR gotoW[] = {'g','o','t','o',0}; static const WCHAR ifW[] = {'i','f',0}; static const WCHAR impW[] = {'i','m','p',0}; +static const WCHAR inW[] = {'i','n',0}; static const WCHAR isW[] = {'i','s',0}; static const WCHAR letW[] = {'l','e','t',0}; static const WCHAR loopW[] = {'l','o','o','p',0}; @@ -93,6 +95,7 @@ static const struct { {defaultW, tDEFAULT}, {dimW, tDIM}, {doW, tDO}, + {eachW, tEACH}, {elseW, tELSE}, {elseifW, tELSEIF}, {emptyW, tEMPTY}, @@ -108,6 +111,7 @@ static const struct { {gotoW, tGOTO}, {ifW, tIF}, {impW, tIMP}, + {inW, tIN}, {isW, tIS}, {letW, tLET}, {loopW, tLOOP}, diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index e58e7f33517..b97ee13db70 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -107,6 +107,7 @@ typedef enum { STAT_EXITFUNC, STAT_EXITPROP, STAT_EXITSUB, + STAT_FOREACH, STAT_FORTO, STAT_FUNC, STAT_IF, @@ -207,6 +208,13 @@ typedef struct { statement_t *body; } forto_statement_t; +typedef struct { + statement_t stat; + const WCHAR *identifier; + expression_t *group_expr; + statement_t *body; +} foreach_statement_t; + typedef struct { statement_t stat; BOOL resume_next; diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index d6bda55a7ee..45e0e8a07a6 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -53,6 +53,7 @@ static statement_t *new_set_statement(parser_ctx_t*,member_expression_t*,express static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*); static statement_t *new_while_statement(parser_ctx_t*,statement_type_t,expression_t*,statement_t*); static statement_t *new_forto_statement(parser_ctx_t*,const WCHAR*,expression_t*,expression_t*,expression_t*,statement_t*); +static statement_t *new_foreach_statement(parser_ctx_t*,const WCHAR*,expression_t*,statement_t*); static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*); static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*); static statement_t *new_onerror_statement(parser_ctx_t*,BOOL); @@ -103,7 +104,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %token tIS tLTEQ tGTEQ tMOD %token tCALL tDIM tSUB tFUNCTION tPROPERTY tGET tLET tCONST %token tIF tELSE tELSEIF tEND tTHEN tEXIT -%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tSTEP +%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tSTEP tEACH tIN %token tBYREF tBYVAL %token tOPTION tEXPLICIT %token tSTOP @@ -190,6 +191,8 @@ SimpleStatement | tCONST ConstDeclList { $$ = new_const_statement(ctx, $2); CHECK_ERROR; } | tFOR tIdentifier '=' Expression tTO Expression Step_opt tNL StatementsNl_opt tNEXT { $$ = new_forto_statement(ctx, $2, $4, $6, $7, $9); CHECK_ERROR; } + | tFOR tEACH tIdentifier tIN Expression tNL StatementsNl_opt tNEXT + { $$ = new_foreach_statement(ctx, $3, $5, $7); } MemberExpression : tIdentifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; } @@ -651,6 +654,21 @@ static statement_t *new_forto_statement(parser_ctx_t *ctx, const WCHAR *identifi return &stat->stat; } +static statement_t *new_foreach_statement(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *group_expr, + statement_t *body) +{ + foreach_statement_t *stat; + + stat = new_statement(ctx, STAT_FOREACH, sizeof(*stat)); + if(!stat) + return NULL; + + stat->identifier = identifier; + stat->group_expr = group_expr; + stat->body = body; + return &stat->stat; +} + static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl, statement_t *else_stat) {