diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c index f42d2fd3663..ac3d65e8f19 100644 --- a/dlls/vbscript/lex.c +++ b/dlls/vbscript/lex.c @@ -44,6 +44,7 @@ static const WCHAR errorW[] = {'e','r','r','o','r',0}; static const WCHAR exitW[] = {'e','x','i','t',0}; static const WCHAR explicitW[] = {'e','x','p','l','i','c','i','t',0}; static const WCHAR falseW[] = {'f','a','l','s','e',0}; +static const WCHAR forW[] = {'f','o','r',0}; static const WCHAR functionW[] = {'f','u','n','c','t','i','o','n',0}; static const WCHAR getW[] = {'g','e','t',0}; static const WCHAR gotoW[] = {'g','o','t','o',0}; @@ -68,9 +69,11 @@ static const WCHAR publicW[] = {'p','u','b','l','i','c',0}; static const WCHAR remW[] = {'r','e','m',0}; static const WCHAR resumeW[] = {'r','e','s','u','m','e',0}; static const WCHAR setW[] = {'s','e','t',0}; +static const WCHAR stepW[] = {'s','t','e','p',0}; static const WCHAR stopW[] = {'s','t','o','p',0}; static const WCHAR subW[] = {'s','u','b',0}; static const WCHAR thenW[] = {'t','h','e','n',0}; +static const WCHAR toW[] = {'t','o',0}; static const WCHAR trueW[] = {'t','r','u','e',0}; static const WCHAR untilW[] = {'u','n','t','i','l',0}; static const WCHAR wendW[] = {'w','e','n','d',0}; @@ -99,6 +102,7 @@ static const struct { {exitW, tEXIT}, {explicitW, tEXPLICIT}, {falseW, tFALSE}, + {forW, tFOR}, {functionW, tFUNCTION}, {getW, tGET}, {gotoW, tGOTO}, @@ -123,9 +127,11 @@ static const struct { {remW, tREM}, {resumeW, tRESUME}, {setW, tSET}, + {stepW, tSTEP}, {stopW, tSTOP}, {subW, tSUB}, {thenW, tTHEN}, + {toW, tTO}, {trueW, tTRUE}, {untilW, tUNTIL}, {wendW, tWEND}, diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h index 8e4be5742a4..a5bd5051319 100644 --- a/dlls/vbscript/parse.h +++ b/dlls/vbscript/parse.h @@ -106,6 +106,7 @@ typedef enum { STAT_EXITFUNC, STAT_EXITPROP, STAT_EXITSUB, + STAT_FORTO, STAT_FUNC, STAT_IF, STAT_ONERROR, @@ -196,6 +197,15 @@ typedef struct { statement_t *body; } while_statement_t; +typedef struct { + statement_t stat; + const WCHAR *identifier; + expression_t *from_expr; + expression_t *to_expr; + expression_t *step_expr; + statement_t *body; +} forto_statement_t; + typedef struct { statement_t stat; BOOL resume_next; diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 8435e92c39c..3b3005129f7 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -52,6 +52,7 @@ static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expr 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_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_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); @@ -102,7 +103,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 +%token tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tSTEP %token tBYREF tBYVAL %token tOPTION tEXPLICIT %token tSTOP @@ -118,7 +119,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %type ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression %type NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression %type MemberExpression -%type Arguments_opt ArgumentList_opt ArgumentList +%type Arguments_opt ArgumentList_opt ArgumentList Step_opt %type OptionExplicit_opt DoType %type ArgumentsDecl_opt ArgumentDeclList ArgumentDecl %type FunctionDecl PropertyDecl @@ -186,6 +187,8 @@ SimpleStatement | tON tERROR tRESUME tNEXT { $$ = new_onerror_statement(ctx, TRUE); CHECK_ERROR; } | tON tERROR tGOTO '0' { $$ = new_onerror_statement(ctx, FALSE); CHECK_ERROR; } | 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; } MemberExpression : tIdentifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; } @@ -206,6 +209,10 @@ DoType : tWHILE { $$ = TRUE; } | tUNTIL { $$ = FALSE; } +Step_opt + : /* empty */ { $$ = NULL;} + | tSTEP Expression { $$ = $2; } + IfStatement : tIF Expression tTHEN tNL StatementsNl ElseIfs_opt Else_opt tEND tIF { $$ = new_if_statement(ctx, $2, $5, $6, $7); CHECK_ERROR; } @@ -626,6 +633,23 @@ static statement_t *new_while_statement(parser_ctx_t *ctx, statement_type_t type return &stat->stat; } +static statement_t *new_forto_statement(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *from_expr, + expression_t *to_expr, expression_t *step_expr, statement_t *body) +{ + forto_statement_t *stat; + + stat = new_statement(ctx, STAT_FORTO, sizeof(*stat)); + if(!stat) + return NULL; + + stat->identifier = identifier; + stat->from_expr = from_expr; + stat->to_expr = to_expr; + stat->step_expr = step_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) {