Jacek Caban : vbscript: Added if statement parser implementation.

Alexandre Julliard julliard at winehq.org
Tue Sep 13 12:18:10 CDT 2011


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Sep 13 11:38:04 2011 +0200

vbscript: Added if statement parser implementation.

---

 dlls/vbscript/parse.h  |   15 +++++++++++
 dlls/vbscript/parser.y |   62 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 76 insertions(+), 1 deletions(-)

diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index d50889d..c8ed7f0 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -80,6 +80,7 @@ typedef struct {
 typedef enum {
     STAT_ASSIGN,
     STAT_CALL,
+    STAT_IF,
     STAT_DIM
 } statement_type_t;
 
@@ -109,6 +110,20 @@ typedef struct _dim_statement_t {
     dim_decl_t *dim_decls;
 } dim_statement_t;
 
+typedef struct _elseif_decl_t {
+    expression_t *expr;
+    statement_t *stat;
+    struct _elseif_decl_t *next;
+} elseif_decl_t;
+
+typedef struct {
+    statement_t stat;
+    expression_t *expr;
+    statement_t *if_stat;
+    elseif_decl_t *elseifs;
+    statement_t *else_stat;
+} if_statement_t;
+
 typedef struct {
     const WCHAR *code;
     const WCHAR *ptr;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index b5e740e..8efcc5a 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -48,8 +48,10 @@ static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,co
 static statement_t *new_call_statement(parser_ctx_t*,member_expression_t*);
 static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expression_t*);
 static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*);
+ static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_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*);
 
 #define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
 
@@ -63,6 +65,7 @@ static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,dim_decl_t*);
     statement_t *statement;
     expression_t *expression;
     member_expression_t *member;
+    elseif_decl_t *elseif;
     dim_decl_t *dim_decl;
     LONG lng;
     BOOL bool;
@@ -86,13 +89,14 @@ static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,dim_decl_t*);
 %token <lng> tLong tShort
 %token <dbl> tDouble
 
-%type <statement> Statement StatementNl
+%type <statement> Statement StatementNl StatementsNl IfStatement Else_opt
 %type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression
 %type <expression> ConcatExpression AdditiveExpression ModExpression
 %type <expression> NotExpression UnaryExpression
 %type <member> MemberExpression
 %type <expression> Arguments_opt ArgumentList_opt ArgumentList
 %type <bool> OptionExplicit_opt
+%type <elseif> ElseIfs_opt ElseIfs ElseIf
 %type <dim_decl> DimDeclList
 
 %%
@@ -108,6 +112,10 @@ SourceElements
     : /* empty */
     | SourceElements StatementNl    { source_add_statement(ctx, $2); }
 
+StatementsNl
+    : StatementNl                           { $$ = $1; }
+    | StatementNl StatementsNl              { $1->next = $2; $$ = $1; }
+
 StatementNl
     : Statement tNL                 { $$ = $1; }
 
@@ -117,6 +125,7 @@ Statement
     | MemberExpression Arguments_opt '=' Expression
                                             { $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
     | tDIM DimDeclList                      { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
+    | IfStatement                           { $$ = $1; }
 
 MemberExpression
     : tIdentifier                           { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
@@ -126,6 +135,27 @@ DimDeclList /* FIXME: Support arrays */
     : tIdentifier                           { $$ = new_dim_decl(ctx, $1, NULL); CHECK_ERROR; }
     | tIdentifier ',' DimDeclList           { $$ = new_dim_decl(ctx, $1, $3); CHECK_ERROR; }
 
+IfStatement
+    : tIF Expression tTHEN tNL StatementsNl ElseIfs_opt Else_opt tEND tIF
+                                            { $$ = new_if_statement(ctx, $2, $5, $6, $7); CHECK_ERROR; }
+    /* FIXME: short if statement */
+
+ElseIfs_opt
+    : /* empty */                           { $$ = NULL; }
+    | ElseIfs                               { $$ = $1; }
+
+ElseIfs
+    : ElseIf                                { $$ = $1; }
+    | ElseIf ElseIfs                        { $1->next = $2; $$ = $1; }
+
+ElseIf
+    : tELSEIF Expression tTHEN tNL StatementsNl
+                                            { $$ = new_elseif_decl(ctx, $2, $5); }
+
+Else_opt
+    : /* empty */                           { $$ = NULL; }
+    | tELSE tNL StatementsNl                { $$ = $3; }
+
 Arguments_opt
     : EmptyBrackets_opt             { $$ = NULL; }
     | '(' ArgumentList ')'          { $$ = $2; }
@@ -376,6 +406,36 @@ static statement_t *new_dim_statement(parser_ctx_t *ctx, dim_decl_t *decls)
     return &stat->stat;
 }
 
+static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, expression_t *expr, statement_t *stat)
+{
+    elseif_decl_t *decl;
+
+    decl = parser_alloc(ctx, sizeof(*decl));
+    if(!decl)
+        return NULL;
+
+    decl->expr = expr;
+    decl->stat = stat;
+    decl->next = NULL;
+    return decl;
+}
+
+static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
+        statement_t *else_stat)
+{
+    if_statement_t *stat;
+
+    stat = new_statement(ctx, STAT_IF, sizeof(*stat));
+    if(!stat)
+        return NULL;
+
+    stat->expr = expr;
+    stat->if_stat = if_stat;
+    stat->elseifs = elseif_decl;
+    stat->else_stat = else_stat;
+    return &stat->stat;
+}
+
 void *parser_alloc(parser_ctx_t *ctx, size_t size)
 {
     void *ret;




More information about the wine-cvs mailing list