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