vbscript: Added sub statement parser implementation.
authorJacek Caban <jacek@codeweavers.com>
Wed, 14 Sep 2011 10:54:50 +0000 (12:54 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Wed, 14 Sep 2011 12:55:49 +0000 (14:55 +0200)
dlls/vbscript/parse.h
dlls/vbscript/parser.y
dlls/vbscript/vbscript.h

index cfeb8c0ddd3231a320c5180f979a1a74a8c8f5b7..9b837c2efcdfdfb82670d7a47984bb148e979fac 100644 (file)
@@ -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;
index c9f9c76c4c450dd50dcc0756f1ee15e46df876eb..4964d71d0ee43feb388b7ce0fc88d03dff7e9ba6 100644 (file)
@@ -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;
index afa9d83f3f5079b8651caf8642a99523b3472842..b52aa093384a57e8de7907cbc0bb841651ae37d0 100644 (file)
@@ -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;