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