vbscript: Add support for parsing with statement.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Jacek Caban 2019-10-29 19:01:14 +01:00 committed by Alexandre Julliard
parent 55e9c896ca
commit 74ab018763
3 changed files with 38 additions and 3 deletions

View File

@ -88,6 +88,7 @@ static const struct {
{L"until", tUNTIL},
{L"wend", tWEND},
{L"while", tWHILE},
{L"with", tWITH},
{L"xor", tXOR}
};
@ -379,9 +380,17 @@ static int parse_next_token(void *lval, parser_ctx_t *ctx)
case '/':
case '^':
case '\\':
case '.':
case '_':
return *ctx->ptr++;
case '.':
/*
* We need to distinguish between '.' used as part of a member expression and
* a beginning of a dot expression (a member expression accessing with statement
* expression).
*/
c = ctx->ptr > ctx->code ? ctx->ptr[-1] : '\n';
ctx->ptr++;
return is_identifier_char(c) || c == ')' ? '.' : tDOT;
case '-':
if(ctx->is_html && ctx->ptr[1] == '-' && ctx->ptr[2] == '>')
return comment_line(ctx);

View File

@ -24,6 +24,7 @@ typedef enum {
EXPR_CALL,
EXPR_CONCAT,
EXPR_DIV,
EXPR_DOT,
EXPR_DOUBLE,
EXPR_EMPTY,
EXPR_EQUAL,
@ -125,6 +126,7 @@ typedef enum {
STAT_UNTIL,
STAT_WHILE,
STAT_WHILELOOP,
STAT_WITH,
STAT_RETVAL
} statement_type_t;
@ -255,6 +257,12 @@ typedef struct {
case_clausule_t *case_clausules;
} select_statement_t;
typedef struct {
statement_t stat;
expression_t *expr;
statement_t *body;
} with_statement_t;
typedef struct {
statement_t stat;
expression_t *expr;

View File

@ -59,6 +59,7 @@ static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
static statement_t *new_onerror_statement(parser_ctx_t*,BOOL);
static statement_t *new_const_statement(parser_ctx_t*,const_decl_t*);
static statement_t *new_select_statement(parser_ctx_t*,expression_t*,case_clausule_t*);
static statement_t *new_with_statement(parser_ctx_t*,expression_t*,statement_t*);
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*);
@ -107,14 +108,14 @@ static statement_t *link_statements(statement_t*,statement_t*);
%token tEXPRESSION tEOF tNL tEMPTYBRACKETS
%token tLTEQ tGTEQ tNEQ
%token tSTOP tME tREM
%token tSTOP tME tREM tDOT
%token <string> tTRUE tFALSE
%token <string> tNOT tAND tOR tXOR tEQV tIMP
%token <string> tIS tMOD
%token <string> tCALL tDIM tSUB tFUNCTION tGET tLET tCONST
%token <string> tIF tELSE tELSEIF tEND tTHEN tEXIT
%token <string> tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN
%token <string> tSELECT tCASE
%token <string> tSELECT tCASE tWITH
%token <string> tBYREF tBYVAL
%token <string> tOPTION
%token <string> tNOTHING tEMPTY tNULL
@ -221,10 +222,14 @@ SimpleStatement
{ $$ = new_foreach_statement(ctx, $3, $5, $7); }
| tSELECT tCASE Expression StSep CaseClausules tEND tSELECT
{ $$ = new_select_statement(ctx, $3, $5); }
| tWITH Expression StSep StatementsNl_opt tEND tWITH
{ $$ = new_with_statement(ctx, $2, $4); }
MemberExpression
: Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
| CallExpression '.' DotIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
| tDOT DotIdentifier { expression_t *dot_expr = new_expression(ctx, EXPR_DOT, sizeof(*dot_expr)); CHECK_ERROR;
$$ = new_member_expression(ctx, dot_expr, $2); CHECK_ERROR; }
DimDeclList
: DimDecl { $$ = $1; }
@ -946,6 +951,19 @@ static statement_t *new_select_statement(parser_ctx_t *ctx, expression_t *expr,
return &stat->stat;
}
static statement_t *new_with_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *body)
{
with_statement_t *stat;
stat = new_statement(ctx, STAT_WITH, sizeof(*stat));
if(!stat)
return NULL;
stat->expr = expr;
stat->body = body;
return &stat->stat;
}
static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr, statement_t *stat, case_clausule_t *next)
{
case_clausule_t *ret;