Jacek Caban : vbscript: Added sub statement parser implementation.

Alexandre Julliard julliard at winehq.org
Wed Sep 14 12:25:40 CDT 2011


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 14 12:54:50 2011 +0200

vbscript: Added sub statement parser implementation.

---

 dlls/vbscript/parse.h    |   24 +++++++++++++-
 dlls/vbscript/parser.y   |   75 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/vbscript/vbscript.h |    5 +++
 3 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/dlls/vbscript/parse.h b/dlls/vbscript/parse.h
index cfeb8c0..9b837c2 100644
--- a/dlls/vbscript/parse.h
+++ b/dlls/vbscript/parse.h
@@ -85,8 +85,9 @@ typedef struct {
 typedef enum {
     STAT_ASSIGN,
     STAT_CALL,
-    STAT_IF,
-    STAT_DIM
+    STAT_DIM,
+    STAT_FUNC,
+    STAT_IF
 } statement_type_t;
 
 typedef struct _statement_t {
@@ -115,6 +116,25 @@ typedef struct _dim_statement_t {
     dim_decl_t *dim_decls;
 } dim_statement_t;
 
+typedef struct _arg_decl_t {
+    const WCHAR *name;
+    BOOL by_ref;
+    struct _arg_decl_t *next;
+} arg_decl_t;
+
+typedef struct _function_decl_t {
+    const WCHAR *name;
+    function_type_t type;
+    arg_decl_t *args;
+    statement_t *body;
+    struct _function_decl_t *next;
+} function_decl_t;
+
+typedef struct _function_statement_t {
+    statement_t stat;
+    function_decl_t *func_decl;
+} function_statement_t;
+
 typedef struct _elseif_decl_t {
     expression_t *expr;
     statement_t *stat;
diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y
index c9f9c76..4964d71 100644
--- a/dlls/vbscript/parser.y
+++ b/dlls/vbscript/parser.y
@@ -48,10 +48,13 @@ 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 statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
+static statement_t *new_function_statement(parser_ctx_t*,function_decl_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,arg_decl_t*,statement_t*);
+static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
 
 #define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
 
@@ -67,6 +70,8 @@ static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
     member_expression_t *member;
     elseif_decl_t *elseif;
     dim_decl_t *dim_decl;
+    function_decl_t *func_decl;
+    arg_decl_t *arg_decl;
     LONG lng;
     BOOL bool;
     double dbl;
@@ -89,13 +94,15 @@ static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
 %token <lng> tLong tShort
 %token <dbl> tDouble
 
-%type <statement> Statement StatementNl StatementsNl IfStatement Else_opt
+%type <statement> Statement StatementNl StatementsNl StatementsNl_opt IfStatement Else_opt
 %type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression
 %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
 %type <expression> NotExpression UnaryExpression
 %type <member> MemberExpression
 %type <expression> Arguments_opt ArgumentList_opt ArgumentList
 %type <bool> OptionExplicit_opt
+%type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
+%type <func_decl> FunctionDecl
 %type <elseif> ElseIfs_opt ElseIfs ElseIf
 %type <dim_decl> DimDeclList
 
@@ -112,6 +119,10 @@ SourceElements
     : /* empty */
     | SourceElements StatementNl    { source_add_statement(ctx, $2); }
 
+StatementsNl_opt
+    : /* empty */                           { $$ = NULL; }
+    | StatementsNl                          { $$ = $1; }
+
 StatementsNl
     : StatementNl                           { $$ = $1; }
     | StatementNl StatementsNl              { $1->next = $2; $$ = $1; }
@@ -126,6 +137,7 @@ Statement
                                             { $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
     | tDIM DimDeclList                      { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
     | IfStatement                           { $$ = $1; }
+    | FunctionDecl                          { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
 
 MemberExpression
     : tIdentifier                           { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
@@ -236,6 +248,23 @@ LiteralExpression
 PrimaryExpression
     : '(' Expression ')'            { $$ = $2; }
 
+FunctionDecl
+    : /* Storage_opt */ tSUB tIdentifier ArgumentsDecl_opt tNL StatementsNl_opt tEND tSUB
+                                    { $$ = new_function_decl(ctx, $2, FUNC_SUB, $3, $5); CHECK_ERROR; }
+
+ArgumentsDecl_opt
+    : EmptyBrackets_opt                         { $$ = NULL; }
+    | '(' ArgumentDeclList ')'                  { $$ = $2; }
+
+ArgumentDeclList
+    : ArgumentDecl                              { $$ = $1; }
+    | ArgumentDecl ',' ArgumentDeclList         { $1->next = $3; $$ = $1; }
+
+ArgumentDecl
+    : tIdentifier                               { $$ = new_argument_decl(ctx, $1, TRUE); }
+    | tBYREF tIdentifier                        { $$ = new_argument_decl(ctx, $2, TRUE); }
+    | tBYVAL tIdentifier                        { $$ = new_argument_decl(ctx, $2, FALSE); }
+
 %%
 
 static int parser_error(const char *str)
@@ -452,6 +481,48 @@ static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, stat
     return &stat->stat;
 }
 
+static arg_decl_t *new_argument_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL by_ref)
+{
+    arg_decl_t *arg_decl;
+
+    arg_decl = parser_alloc(ctx, sizeof(*arg_decl));
+    if(!arg_decl)
+        return NULL;
+
+    arg_decl->name = name;
+    arg_decl->by_ref = by_ref;
+    arg_decl->next = NULL;
+    return arg_decl;
+}
+
+static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name, function_type_t type,
+        arg_decl_t *arg_decl, statement_t *body)
+{
+    function_decl_t *decl;
+
+    decl = parser_alloc(ctx, sizeof(*decl));
+    if(!decl)
+        return NULL;
+
+    decl->name = name;
+    decl->type = type;
+    decl->args = arg_decl;
+    decl->body = body;
+    return decl;
+}
+
+static statement_t *new_function_statement(parser_ctx_t *ctx, function_decl_t *decl)
+{
+    function_statement_t *stat;
+
+    stat = new_statement(ctx, STAT_FUNC, sizeof(*stat));
+    if(!stat)
+        return NULL;
+
+    stat->func_decl = decl;
+    return &stat->stat;
+}
+
 void *parser_alloc(parser_ctx_t *ctx, size_t size)
 {
     void *ret;
diff --git a/dlls/vbscript/vbscript.h b/dlls/vbscript/vbscript.h
index afa9d83..b52aa09 100644
--- a/dlls/vbscript/vbscript.h
+++ b/dlls/vbscript/vbscript.h
@@ -146,6 +146,11 @@ typedef struct {
     instr_arg_t arg2;
 } instr_t;
 
+typedef enum {
+    FUNC_GLOBAL,
+    FUNC_SUB
+} function_type_t;
+
 struct _function_t {
     unsigned code_off;
     vbscode_t *code_ctx;




More information about the wine-cvs mailing list