Module: wine Branch: master Commit: 119c985cdaa72d4150e0040d4969cc747bdac87a URL: http://source.winehq.org/git/wine.git/?a=commit;h=119c985cdaa72d4150e0040d49...
Author: Jacek Caban jacek@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;