Jacek Caban : vbscript: Add support for parsing with statement.
Alexandre Julliard
julliard at winehq.org
Tue Oct 29 17:41:47 CDT 2019
Module: wine
Branch: master
Commit: 74ab018763337e27e785ffcec7e4cab0e0e80ddb
URL: https://source.winehq.org/git/wine.git/?a=commit;h=74ab018763337e27e785ffcec7e4cab0e0e80ddb
Author: Jacek Caban <jacek at codeweavers.com>
Date: Tue Oct 29 19:01:14 2019 +0100
vbscript: Add support for parsing with statement.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/vbscript/lex.c | 11 ++++++++++-
dlls/vbscript/parse.h | 8 ++++++++
dlls/vbscript/parser.y | 22 ++++++++++++++++++++--
3 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index 6b20d1979d..d8c5ed3004 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -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);
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 7c333be30e..f4f8a5e5e2 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -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;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index b577c2146e..ffa12b2c4e 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -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;
More information about the wine-cvs
mailing list