Jacek Caban : vbscript: Added parser support for select case statement.

Alexandre Julliard julliard at winehq.org
Fri Jul 20 15:29:59 CDT 2012


Module: wine
Branch: master
Commit: 119c985cdaa72d4150e0040d4969cc747bdac87a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=119c985cdaa72d4150e0040d4969cc747bdac87a

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Jul 20 16:28:32 2012 +0200

vbscript: Added parser support for select case statement.

---

 dlls/vbscript/compile.c |    9 +++++++
 dlls/vbscript/lex.c     |    4 +++
 dlls/vbscript/parse.h   |   13 +++++++++++
 dlls/vbscript/parser.y  |   54 ++++++++++++++++++++++++++++++++++++++++------
 4 files changed, 73 insertions(+), 7 deletions(-)

diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c
index 7c4b0e6..fb8076c 100644
--- a/dlls/vbscript/compile.c
+++ b/dlls/vbscript/compile.c
@@ -752,6 +752,12 @@ static HRESULT compile_forto_statement(compile_ctx_t *ctx, forto_statement_t *st
     return S_OK;
 }
 
+static HRESULT compile_select_statement(compile_ctx_t *ctx, select_statement_t *stat)
+{
+    FIXME("\n");
+    return E_NOTIMPL;
+}
+
 static HRESULT compile_assignment(compile_ctx_t *ctx, member_expression_t *member_expr, expression_t *value_expr, BOOL is_set)
 {
     unsigned args_cnt;
@@ -1058,6 +1064,9 @@ static HRESULT compile_statement(compile_ctx_t *ctx, statement_ctx_t *stat_ctx,
         case STAT_ONERROR:
             hres = compile_onerror_statement(ctx, (onerror_statement_t*)stat);
             break;
+        case STAT_SELECT:
+            hres = compile_select_statement(ctx, (select_statement_t*)stat);
+            break;
         case STAT_SET:
             hres = compile_assign_statement(ctx, (assign_statement_t*)stat, TRUE);
             break;
diff --git a/dlls/vbscript/lex.c b/dlls/vbscript/lex.c
index fe5fbae..8e971e2 100644
--- a/dlls/vbscript/lex.c
+++ b/dlls/vbscript/lex.c
@@ -30,6 +30,7 @@ static const WCHAR andW[] = {'a','n','d',0};
 static const WCHAR byrefW[] = {'b','y','r','e','f',0};
 static const WCHAR byvalW[] = {'b','y','v','a','l',0};
 static const WCHAR callW[] = {'c','a','l','l',0};
+static const WCHAR caseW[] = {'c','a','s','e',0};
 static const WCHAR classW[] = {'c','l','a','s','s',0};
 static const WCHAR constW[] = {'c','o','n','s','t',0};
 static const WCHAR defaultW[] = {'d','e','f','a','u','l','t',0};
@@ -70,6 +71,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
 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 selectW[] = {'s','e','l','e','c','t',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};
@@ -90,6 +92,7 @@ static const struct {
     {byrefW,     tBYREF},
     {byvalW,     tBYVAL},
     {callW,      tCALL},
+    {caseW,      tCASE},
     {classW,     tCLASS},
     {constW,     tCONST},
     {defaultW,   tDEFAULT},
@@ -130,6 +133,7 @@ static const struct {
     {publicW,    tPUBLIC},
     {remW,       tREM},
     {resumeW,    tRESUME},
+    {selectW,    tSELECT},
     {setW,       tSET},
     {stepW,      tSTEP},
     {stopW,      tSTOP},
diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index 50151d3..df8f9b5 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -113,6 +113,7 @@ typedef enum {
     STAT_FUNC,
     STAT_IF,
     STAT_ONERROR,
+    STAT_SELECT,
     STAT_SET,
     STAT_STOP,
     STAT_UNTIL,
@@ -233,6 +234,18 @@ typedef struct {
     const_decl_t *decls;
 } const_statement_t;
 
+typedef struct _case_clausule_t {
+    expression_t *expr;
+    statement_t *stat;
+    struct _case_clausule_t *next;
+} case_clausule_t;
+
+typedef struct {
+    statement_t stat;
+    expression_t *expr;
+    case_clausule_t *case_clausules;
+} select_statement_t;
+
 typedef struct {
     const WCHAR *code;
     const WCHAR *ptr;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index fca0cf1..baac315 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -58,12 +58,14 @@ static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,el
 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 dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,dim_decl_t*);
 static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
 static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,arg_decl_t*,statement_t*);
 static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
 static const_decl_t *new_const_decl(parser_ctx_t*,const WCHAR*,expression_t*);
+static case_clausule_t *new_case_clausule(parser_ctx_t*,expression_t*,statement_t*,case_clausule_t*);
 
 static class_decl_t *new_class_decl(parser_ctx_t*);
 static class_decl_t *add_class_function(parser_ctx_t*,class_decl_t*,function_decl_t*);
@@ -94,6 +96,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
     arg_decl_t *arg_decl;
     class_decl_t *class_decl;
     const_decl_t *const_decl;
+    case_clausule_t *case_clausule;
     unsigned uint;
     LONG lng;
     BOOL bool;
@@ -107,6 +110,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
 %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 tEACH tIN
+%token tSELECT tCASE
 %token tBYREF tBYVAL
 %token tOPTION tEXPLICIT
 %token tSTOP
@@ -122,7 +126,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
 %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
 %type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
 %type <member> MemberExpression
-%type <expression> Arguments_opt ArgumentList_opt ArgumentList Step_opt
+%type <expression> Arguments_opt ArgumentList_opt Step_opt ExpressionList
 %type <bool> OptionExplicit_opt DoType
 %type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
 %type <func_decl> FunctionDecl PropertyDecl
@@ -132,6 +136,7 @@ static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0};
 %type <dim_decl> DimDeclList
 %type <const_decl> ConstDecl ConstDeclList
 %type <string> Identifier
+%type <case_clausule> CaseClausules
 
 %%
 
@@ -196,6 +201,8 @@ SimpleStatement
                                             { $$ = new_forto_statement(ctx, $2, $4, $6, $7, $9); CHECK_ERROR; }
     | tFOR tEACH Identifier tIN Expression tNL StatementsNl_opt tNEXT
                                             { $$ = new_foreach_statement(ctx, $3, $5, $7); }
+    | tSELECT tCASE Expression tNL CaseClausules tEND tSELECT
+                                            { $$ = new_select_statement(ctx, $3, $5); }
 
 MemberExpression
     : Identifier                            { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
@@ -247,22 +254,28 @@ Else_opt
     : /* empty */                           { $$ = NULL; }
     | tELSE tNL StatementsNl                { $$ = $3; }
 
+CaseClausules
+    : /* empty */                          { $$ = NULL; }
+    | tCASE tELSE tNL StatementsNl         { $$ = new_case_clausule(ctx, NULL, $4, NULL); }
+    | tCASE ExpressionList tNL StatementsNl_opt CaseClausules
+                                           { $$ = new_case_clausule(ctx, $2, $4, $5); }
+
 Arguments_opt
     : EmptyBrackets_opt             { $$ = NULL; }
-    | '(' ArgumentList ')'          { $$ = $2; }
+    | '(' ExpressionList ')'        { $$ = $2; }
 
 ArgumentList_opt
     : EmptyBrackets_opt             { $$ = NULL; }
-    | ArgumentList                  { $$ = $1; }
-
-ArgumentList
-    : Expression                    { $$ = $1; }
-    | Expression ',' ArgumentList   { $1->next = $3; $$ = $1; }
+    | ExpressionList                { $$ = $1; }
 
 EmptyBrackets_opt
     : /* empty */
     | tEMPTYBRACKETS
 
+ExpressionList
+    : Expression                    { $$ = $1; }
+    | Expression ',' ExpressionList { $1->next = $3; $$ = $1; }
+
 Expression
     : EqvExpression                             { $$ = $1; }
     | Expression tIMP EqvExpression             { $$ = new_binary_expression(ctx, EXPR_IMP, $1, $3); CHECK_ERROR; }
@@ -697,6 +710,33 @@ static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, stat
     return &stat->stat;
 }
 
+static statement_t *new_select_statement(parser_ctx_t *ctx, expression_t *expr, case_clausule_t *case_clausules)
+{
+    select_statement_t *stat;
+
+    stat = new_statement(ctx, STAT_SELECT, sizeof(*stat));
+    if(!stat)
+        return NULL;
+
+    stat->expr = expr;
+    stat->case_clausules = case_clausules;
+    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;
+
+    ret = parser_alloc(ctx, sizeof(*ret));
+    if(!ret)
+        return NULL;
+
+    ret->expr = expr;
+    ret->stat = stat;
+    ret->next = next;
+    return ret;
+}
+
 static statement_t *new_onerror_statement(parser_ctx_t *ctx, BOOL resume_next)
 {
     onerror_statement_t *stat;




More information about the wine-cvs mailing list