mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / vbscript / parser.y
blob37b14f05e1478c9f7abe68dd92c3b08d107a0c03
1 /*
2 * Copyright 2011 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "vbscript.h"
22 #include "parse.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
28 static int parser_error(unsigned*,parser_ctx_t*,const char*);
30 static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr);
32 static void source_add_statement(parser_ctx_t*,statement_t*);
33 static void source_add_class(parser_ctx_t*,class_decl_t*);
35 static void *new_expression(parser_ctx_t*,expression_type_t,size_t);
36 static expression_t *new_bool_expression(parser_ctx_t*,VARIANT_BOOL);
37 static expression_t *new_string_expression(parser_ctx_t*,const WCHAR*);
38 static expression_t *new_long_expression(parser_ctx_t*,expression_type_t,LONG);
39 static expression_t *new_double_expression(parser_ctx_t*,double);
40 static expression_t *new_unary_expression(parser_ctx_t*,expression_type_t,expression_t*);
41 static expression_t *new_binary_expression(parser_ctx_t*,expression_type_t,expression_t*,expression_t*);
42 static expression_t *new_new_expression(parser_ctx_t*,const WCHAR*);
44 static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);
45 static call_expression_t *new_call_expression(parser_ctx_t*,expression_t*,expression_t*);
46 static call_expression_t *make_call_expression(parser_ctx_t*,expression_t*,expression_t*);
48 static void *new_statement(parser_ctx_t*,statement_type_t,size_t,unsigned);
49 static statement_t *new_call_statement(parser_ctx_t*,unsigned,expression_t*);
50 static statement_t *new_assign_statement(parser_ctx_t*,unsigned,expression_t*,expression_t*);
51 static statement_t *new_set_statement(parser_ctx_t*,unsigned,expression_t*,expression_t*);
52 static statement_t *new_dim_statement(parser_ctx_t*,unsigned,dim_decl_t*);
53 static statement_t *new_redim_statement(parser_ctx_t*,unsigned,const WCHAR*,BOOL,expression_t*);
54 static statement_t *new_while_statement(parser_ctx_t*,unsigned,statement_type_t,expression_t*,statement_t*);
55 static statement_t *new_forto_statement(parser_ctx_t*,unsigned,const WCHAR*,expression_t*,expression_t*,expression_t*,statement_t*);
56 static statement_t *new_foreach_statement(parser_ctx_t*,unsigned,const WCHAR*,expression_t*,statement_t*);
57 static statement_t *new_if_statement(parser_ctx_t*,unsigned,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
58 static statement_t *new_function_statement(parser_ctx_t*,unsigned,function_decl_t*);
59 static statement_t *new_onerror_statement(parser_ctx_t*,unsigned,BOOL);
60 static statement_t *new_const_statement(parser_ctx_t*,unsigned,const_decl_t*);
61 static statement_t *new_select_statement(parser_ctx_t*,unsigned,expression_t*,case_clausule_t*);
62 static statement_t *new_with_statement(parser_ctx_t*,unsigned,expression_t*,statement_t*);
64 static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,BOOL,dim_list_t*);
65 static dim_list_t *new_dim(parser_ctx_t*,unsigned,dim_list_t*);
66 static elseif_decl_t *new_elseif_decl(parser_ctx_t*,unsigned,expression_t*,statement_t*);
67 static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,arg_decl_t*,statement_t*);
68 static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
69 static const_decl_t *new_const_decl(parser_ctx_t*,const WCHAR*,expression_t*);
70 static case_clausule_t *new_case_clausule(parser_ctx_t*,expression_t*,statement_t*,case_clausule_t*);
72 static class_decl_t *new_class_decl(parser_ctx_t*);
73 static class_decl_t *add_class_function(parser_ctx_t*,class_decl_t*,function_decl_t*);
74 static class_decl_t *add_dim_prop(parser_ctx_t*,class_decl_t*,dim_decl_t*,unsigned);
76 static statement_t *link_statements(statement_t*,statement_t*);
78 #define STORAGE_IS_PRIVATE 1
79 #define STORAGE_IS_DEFAULT 2
81 #define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
83 #define YYLTYPE unsigned
84 #define YYLLOC_DEFAULT(Cur, Rhs, N) Cur = YYRHSLOC((Rhs), (N) ? 1 : 0)
88 %lex-param { parser_ctx_t *ctx }
89 %parse-param { parser_ctx_t *ctx }
90 %define api.pure
91 %start Program
93 %union {
94 const WCHAR *string;
95 statement_t *statement;
96 expression_t *expression;
97 member_expression_t *member;
98 elseif_decl_t *elseif;
99 dim_decl_t *dim_decl;
100 dim_list_t *dim_list;
101 function_decl_t *func_decl;
102 arg_decl_t *arg_decl;
103 class_decl_t *class_decl;
104 const_decl_t *const_decl;
105 case_clausule_t *case_clausule;
106 unsigned uint;
107 LONG integer;
108 BOOL boolean;
109 double dbl;
112 %token tEXPRESSION tNL tEMPTYBRACKETS tEXPRLBRACKET
113 %token tLTEQ tGTEQ tNEQ
114 %token tSTOP tME tREM tDOT
115 %token <string> tTRUE tFALSE
116 %token <string> tNOT tAND tOR tXOR tEQV tIMP
117 %token <string> tIS tMOD
118 %token <string> tCALL tSUB tFUNCTION tGET tLET tCONST
119 %token <string> tDIM tREDIM tPRESERVE
120 %token <string> tIF tELSE tELSEIF tEND tTHEN tEXIT
121 %token <string> tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN
122 %token <string> tSELECT tCASE tWITH
123 %token <string> tBYREF tBYVAL
124 %token <string> tOPTION
125 %token <string> tNOTHING tEMPTY tNULL
126 %token <string> tCLASS tSET tNEW tPUBLIC tPRIVATE
127 %token <string> tNEXT tON tRESUME tGOTO
128 %token <string> tIdentifier tString
129 %token <string> tDEFAULT tERROR tEXPLICIT tPROPERTY tSTEP
130 %token <integer> tInt
131 %token <dbl> tDouble
133 %type <statement> Statement SimpleStatement StatementNl StatementsNl StatementsNl_opt BodyStatements IfStatement Else_opt
134 %type <statement> GlobalDimDeclaration
135 %type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression ExpressionNl_opt
136 %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
137 %type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression SignExpression
138 %type <expression> ConstExpression NumericLiteralExpression
139 %type <member> MemberExpression
140 %type <expression> Arguments ArgumentList ArgumentList_opt Step_opt ExpressionList
141 %type <boolean> DoType Preserve_opt
142 %type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
143 %type <func_decl> FunctionDecl PropertyDecl
144 %type <elseif> ElseIfs_opt ElseIfs ElseIf
145 %type <class_decl> ClassDeclaration ClassBody
146 %type <uint> Storage Storage_opt IntegerValue
147 %type <dim_decl> DimDeclList DimDecl
148 %type <dim_list> DimList
149 %type <const_decl> ConstDecl ConstDeclList
150 %type <string> Identifier
151 %type <case_clausule> CaseClausules
155 Program
156 : OptionExplicit_opt SourceElements
157 | tEXPRESSION ExpressionNl_opt { handle_isexpression_script(ctx, $2); }
159 OptionExplicit_opt
160 : /* empty */
161 | tOPTION tEXPLICIT StSep { ctx->option_explicit = TRUE; }
163 SourceElements
164 : /* empty */
165 | SourceElements GlobalDimDeclaration StSep
166 { source_add_statement(ctx, $2); }
167 | SourceElements StatementNl { source_add_statement(ctx, $2); }
168 | SourceElements ClassDeclaration { source_add_class(ctx, $2); }
170 GlobalDimDeclaration
171 : tPRIVATE DimDeclList { $$ = new_dim_statement(ctx, @$, $2); CHECK_ERROR; }
172 | tPUBLIC DimDeclList { $$ = new_dim_statement(ctx, @$, $2); CHECK_ERROR; }
174 ExpressionNl_opt
175 : /* empty */ { $$ = NULL; }
176 | Expression tNL { $$ = $1; }
178 BodyStatements
179 : /* empty */ { $$ = NULL; }
180 | Statement { $$ = $1; }
181 | StatementNl BodyStatements { $$ = link_statements($1, $2); }
183 StatementsNl_opt
184 : /* empty */ { $$ = NULL; }
185 | StatementsNl { $$ = $1; }
187 StatementsNl
188 : SimpleStatement StSep { $$ = $1; }
189 | SimpleStatement StSep StatementsNl { $$ = link_statements($1, $3); }
191 StatementNl
192 : Statement tNL { $$ = $1; }
194 Statement
195 : ':' { $$ = NULL; }
196 | ':' Statement { $$ = $2; }
197 | SimpleStatement { $$ = $1; }
198 | SimpleStatement ':' Statement { $1->next = $3; $$ = $1; }
199 | SimpleStatement ':' { $$ = $1; }
201 SimpleStatement
202 : CallExpression ArgumentList_opt { call_expression_t *call_expr = make_call_expression(ctx, $1, $2); CHECK_ERROR;
203 $$ = new_call_statement(ctx, @$, &call_expr->expr); CHECK_ERROR; };
204 | tCALL UnaryExpression { $$ = new_call_statement(ctx, @$, $2); CHECK_ERROR; }
205 | CallExpression '=' Expression
206 { $$ = new_assign_statement(ctx, @$, $1, $3); CHECK_ERROR; }
207 | tDIM DimDeclList { $$ = new_dim_statement(ctx, @$, $2); CHECK_ERROR; }
208 | tREDIM Preserve_opt tIdentifier '(' ArgumentList ')'
209 { $$ = new_redim_statement(ctx, @$, $3, $2, $5); CHECK_ERROR; }
210 | IfStatement { $$ = $1; }
211 | tWHILE Expression StSep StatementsNl_opt tWEND
212 { $$ = new_while_statement(ctx, @$, STAT_WHILE, $2, $4); CHECK_ERROR; }
213 | tDO DoType Expression StSep StatementsNl_opt tLOOP
214 { $$ = new_while_statement(ctx, @$, $2 ? STAT_WHILELOOP : STAT_UNTIL, $3, $5);
215 CHECK_ERROR; }
216 | tDO StSep StatementsNl_opt tLOOP DoType Expression
217 { $$ = new_while_statement(ctx, @4, $5 ? STAT_DOWHILE : STAT_DOUNTIL, $6, $3);
218 CHECK_ERROR; }
219 | tDO StSep StatementsNl_opt tLOOP { $$ = new_while_statement(ctx, @$, STAT_DOWHILE, NULL, $3); CHECK_ERROR; }
220 | FunctionDecl { $$ = new_function_statement(ctx, @$, $1); CHECK_ERROR; }
221 | tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 0, @$); CHECK_ERROR; }
222 | tEXIT tFOR { $$ = new_statement(ctx, STAT_EXITFOR, 0, @$); CHECK_ERROR; }
223 | tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0, @$); CHECK_ERROR; }
224 | tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 0, @$); CHECK_ERROR; }
225 | tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0, @$); CHECK_ERROR; }
226 | tSET CallExpression '=' Expression { $$ = new_set_statement(ctx, @$, $2, $4); CHECK_ERROR; }
227 | tSTOP { $$ = new_statement(ctx, STAT_STOP, 0, @$); CHECK_ERROR; }
228 | tON tERROR tRESUME tNEXT { $$ = new_onerror_statement(ctx, @$, TRUE); CHECK_ERROR; }
229 | tON tERROR tGOTO '0' { $$ = new_onerror_statement(ctx, @$, FALSE); CHECK_ERROR; }
230 | tCONST ConstDeclList { $$ = new_const_statement(ctx, @$, $2); CHECK_ERROR; }
231 | tFOR Identifier '=' Expression tTO Expression Step_opt StSep StatementsNl_opt tNEXT
232 { $$ = new_forto_statement(ctx, @$, $2, $4, $6, $7, $9); CHECK_ERROR; }
233 | tFOR tEACH Identifier tIN Expression StSep StatementsNl_opt tNEXT
234 { $$ = new_foreach_statement(ctx, @$, $3, $5, $7); }
235 | tSELECT tCASE Expression StSep CaseClausules tEND tSELECT
236 { $$ = new_select_statement(ctx, @$, $3, $5); }
237 | tWITH Expression StSep StatementsNl_opt tEND tWITH
238 { $$ = new_with_statement(ctx, @$, $2, $4); }
240 MemberExpression
241 : Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
242 | CallExpression '.' tIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
243 | tDOT tIdentifier { expression_t *dot_expr = new_expression(ctx, EXPR_DOT, sizeof(*dot_expr)); CHECK_ERROR;
244 $$ = new_member_expression(ctx, dot_expr, $2); CHECK_ERROR; }
246 Preserve_opt
247 : /* empty */ { $$ = FALSE; }
248 | tPRESERVE { $$ = TRUE; }
250 DimDeclList
251 : DimDecl { $$ = $1; }
252 | DimDecl ',' DimDeclList { $1->next = $3; $$ = $1; }
254 DimDecl
255 : Identifier { $$ = new_dim_decl(ctx, $1, FALSE, NULL); CHECK_ERROR; }
256 | Identifier '(' DimList ')' { $$ = new_dim_decl(ctx, $1, TRUE, $3); CHECK_ERROR; }
257 | Identifier tEMPTYBRACKETS { $$ = new_dim_decl(ctx, $1, TRUE, NULL); CHECK_ERROR; }
259 DimList
260 : IntegerValue { $$ = new_dim(ctx, $1, NULL); }
261 | IntegerValue ',' DimList { $$ = new_dim(ctx, $1, $3); }
263 ConstDeclList
264 : ConstDecl { $$ = $1; }
265 | ConstDecl ',' ConstDeclList { $1->next = $3; $$ = $1; }
267 ConstDecl
268 : Identifier '=' ConstExpression { $$ = new_const_decl(ctx, $1, $3); CHECK_ERROR; }
270 ConstExpression
271 : LiteralExpression { $$ = $1; }
272 | '-' NumericLiteralExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
274 DoType
275 : tWHILE { $$ = TRUE; }
276 | tUNTIL { $$ = FALSE; }
278 Step_opt
279 : /* empty */ { $$ = NULL;}
280 | tSTEP Expression { $$ = $2; }
282 IfStatement
283 : tIF Expression tTHEN tNL StatementsNl_opt ElseIfs_opt Else_opt tEND tIF
284 { $$ = new_if_statement(ctx, @$, $2, $5, $6, $7); CHECK_ERROR; }
285 | tIF Expression tTHEN Statement EndIf_opt { $$ = new_if_statement(ctx, @$, $2, $4, NULL, NULL); CHECK_ERROR; }
286 | tIF Expression tTHEN Statement tELSE Statement EndIf_opt
287 { $$ = new_if_statement(ctx, @$, $2, $4, NULL, $6); CHECK_ERROR; }
289 EndIf_opt
290 : /* empty */
291 | tEND tIF
293 ElseIfs_opt
294 : /* empty */ { $$ = NULL; }
295 | ElseIfs { $$ = $1; }
297 ElseIfs
298 : ElseIf { $$ = $1; }
299 | ElseIf ElseIfs { $1->next = $2; $$ = $1; }
301 ElseIf
302 : tELSEIF Expression tTHEN tNL StatementsNl_opt
303 { $$ = new_elseif_decl(ctx, @$, $2, $5); }
305 Else_opt
306 : /* empty */ { $$ = NULL; }
307 | tELSE tNL StatementsNl_opt { $$ = $3; }
309 CaseClausules
310 : /* empty */ { $$ = NULL; }
311 | tCASE tELSE StSep StatementsNl_opt { $$ = new_case_clausule(ctx, NULL, $4, NULL); }
312 | tCASE ExpressionList StSep StatementsNl_opt CaseClausules
313 { $$ = new_case_clausule(ctx, $2, $4, $5); }
315 Arguments
316 : tEMPTYBRACKETS { $$ = NULL; }
317 | '(' ArgumentList ')' { $$ = $2; }
319 ArgumentList_opt
320 : /* empty */ { $$ = NULL; }
321 | ArgumentList { $$ = $1; }
323 ArgumentList
324 : Expression { $$ = $1; }
325 | Expression ',' ArgumentList { $1->next = $3; $$ = $1; }
326 | ',' ArgumentList { $$ = new_expression(ctx, EXPR_NOARG, 0); CHECK_ERROR; $$->next = $2; }
328 EmptyBrackets_opt
329 : /* empty */
330 | tEMPTYBRACKETS
332 ExpressionList
333 : Expression { $$ = $1; }
334 | Expression ',' ExpressionList { $1->next = $3; $$ = $1; }
336 Expression
337 : EqvExpression { $$ = $1; }
338 | Expression tIMP EqvExpression { $$ = new_binary_expression(ctx, EXPR_IMP, $1, $3); CHECK_ERROR; }
340 EqvExpression
341 : XorExpression { $$ = $1; }
342 | EqvExpression tEQV XorExpression { $$ = new_binary_expression(ctx, EXPR_EQV, $1, $3); CHECK_ERROR; }
344 XorExpression
345 : OrExpression { $$ = $1; }
346 | XorExpression tXOR OrExpression { $$ = new_binary_expression(ctx, EXPR_XOR, $1, $3); CHECK_ERROR; }
348 OrExpression
349 : AndExpression { $$ = $1; }
350 | OrExpression tOR AndExpression { $$ = new_binary_expression(ctx, EXPR_OR, $1, $3); CHECK_ERROR; }
352 AndExpression
353 : NotExpression { $$ = $1; }
354 | AndExpression tAND NotExpression { $$ = new_binary_expression(ctx, EXPR_AND, $1, $3); CHECK_ERROR; }
356 NotExpression
357 : EqualityExpression { $$ = $1; }
358 | tNOT NotExpression { $$ = new_unary_expression(ctx, EXPR_NOT, $2); CHECK_ERROR; }
360 EqualityExpression
361 : ConcatExpression { $$ = $1; }
362 | EqualityExpression '=' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_EQUAL, $1, $3); CHECK_ERROR; }
363 | EqualityExpression tNEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_NEQUAL, $1, $3); CHECK_ERROR; }
364 | EqualityExpression '>' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GT, $1, $3); CHECK_ERROR; }
365 | EqualityExpression '<' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LT, $1, $3); CHECK_ERROR; }
366 | EqualityExpression tGTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GTEQ, $1, $3); CHECK_ERROR; }
367 | EqualityExpression tLTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LTEQ, $1, $3); CHECK_ERROR; }
368 | EqualityExpression tIS ConcatExpression { $$ = new_binary_expression(ctx, EXPR_IS, $1, $3); CHECK_ERROR; }
370 ConcatExpression
371 : AdditiveExpression { $$ = $1; }
372 | ConcatExpression '&' AdditiveExpression { $$ = new_binary_expression(ctx, EXPR_CONCAT, $1, $3); CHECK_ERROR; }
374 AdditiveExpression
375 : ModExpression { $$ = $1; }
376 | AdditiveExpression '+' ModExpression { $$ = new_binary_expression(ctx, EXPR_ADD, $1, $3); CHECK_ERROR; }
377 | AdditiveExpression '-' ModExpression { $$ = new_binary_expression(ctx, EXPR_SUB, $1, $3); CHECK_ERROR; }
379 ModExpression
380 : IntdivExpression { $$ = $1; }
381 | ModExpression tMOD IntdivExpression { $$ = new_binary_expression(ctx, EXPR_MOD, $1, $3); CHECK_ERROR; }
383 IntdivExpression
384 : MultiplicativeExpression { $$ = $1; }
385 | IntdivExpression '\\' MultiplicativeExpression
386 { $$ = new_binary_expression(ctx, EXPR_IDIV, $1, $3); CHECK_ERROR; }
388 MultiplicativeExpression
389 : ExpExpression { $$ = $1; }
390 | MultiplicativeExpression '*' ExpExpression
391 { $$ = new_binary_expression(ctx, EXPR_MUL, $1, $3); CHECK_ERROR; }
392 | MultiplicativeExpression '/' ExpExpression
393 { $$ = new_binary_expression(ctx, EXPR_DIV, $1, $3); CHECK_ERROR; }
395 ExpExpression
396 : SignExpression { $$ = $1; }
397 | ExpExpression '^' SignExpression { $$ = new_binary_expression(ctx, EXPR_EXP, $1, $3); CHECK_ERROR; }
399 SignExpression
400 : UnaryExpression { $$ = $1; }
401 | '-' SignExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
402 | '+' SignExpression { $$ = $2; }
404 UnaryExpression
405 : LiteralExpression { $$ = $1; }
406 | CallExpression { $$ = $1; }
407 | tNEW Identifier { $$ = new_new_expression(ctx, $2); CHECK_ERROR; }
409 CallExpression
410 : PrimaryExpression { $$ = $1; }
411 | MemberExpression { $$ = &$1->expr; }
412 | CallExpression Arguments { call_expression_t *expr = new_call_expression(ctx, $1, $2); CHECK_ERROR;
413 $$ = &expr->expr; }
415 LiteralExpression
416 : tTRUE { $$ = new_bool_expression(ctx, VARIANT_TRUE); CHECK_ERROR; }
417 | tFALSE { $$ = new_bool_expression(ctx, VARIANT_FALSE); CHECK_ERROR; }
418 | tString { $$ = new_string_expression(ctx, $1); CHECK_ERROR; }
419 | NumericLiteralExpression { $$ = $1; }
420 | tEMPTY { $$ = new_expression(ctx, EXPR_EMPTY, 0); CHECK_ERROR; }
421 | tNULL { $$ = new_expression(ctx, EXPR_NULL, 0); CHECK_ERROR; }
422 | tNOTHING { $$ = new_expression(ctx, EXPR_NOTHING, 0); CHECK_ERROR; }
424 NumericLiteralExpression
425 : '0' { $$ = new_long_expression(ctx, EXPR_INT, 0); CHECK_ERROR; }
426 | tInt { $$ = new_long_expression(ctx, EXPR_INT, $1); CHECK_ERROR; }
427 | tDouble { $$ = new_double_expression(ctx, $1); CHECK_ERROR; }
429 IntegerValue
430 : '0' { $$ = 0; }
431 | tInt { $$ = $1; }
433 PrimaryExpression
434 : tEXPRLBRACKET Expression ')' { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
435 | tME { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; }
437 ClassDeclaration
438 : tCLASS Identifier StSep ClassBody tEND tCLASS StSep { $4->name = $2; $$ = $4; }
440 ClassBody
441 : /* empty */ { $$ = new_class_decl(ctx); }
442 | FunctionDecl { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; }
443 | FunctionDecl StSep ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
444 /* FIXME: We should use DimDecl here to support arrays, but that conflicts with PropertyDecl. */
445 | Storage tIdentifier { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR;
446 $$ = add_dim_prop(ctx, new_class_decl(ctx), dim_decl, $1); CHECK_ERROR; }
447 | Storage tIdentifier StSep ClassBody { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR;
448 $$ = add_dim_prop(ctx, $4, dim_decl, $1); CHECK_ERROR; }
449 | tDIM DimDecl { $$ = add_dim_prop(ctx, new_class_decl(ctx), $2, 0); CHECK_ERROR; }
450 | tDIM DimDecl StSep ClassBody { $$ = add_dim_prop(ctx, $4, $2, 0); CHECK_ERROR; }
451 | PropertyDecl { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; }
452 | PropertyDecl StSep ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
454 PropertyDecl
455 : Storage_opt tPROPERTY tGET Identifier ArgumentsDecl_opt StSep BodyStatements tEND tPROPERTY
456 { $$ = new_function_decl(ctx, $4, FUNC_PROPGET, $1, $5, $7); CHECK_ERROR; }
457 | Storage_opt tPROPERTY tLET Identifier '(' ArgumentDeclList ')' StSep BodyStatements tEND tPROPERTY
458 { $$ = new_function_decl(ctx, $4, FUNC_PROPLET, $1, $6, $9); CHECK_ERROR; }
459 | Storage_opt tPROPERTY tSET Identifier '(' ArgumentDeclList ')' StSep BodyStatements tEND tPROPERTY
460 { $$ = new_function_decl(ctx, $4, FUNC_PROPSET, $1, $6, $9); CHECK_ERROR; }
462 FunctionDecl
463 : Storage_opt tSUB Identifier ArgumentsDecl_opt StSep BodyStatements tEND tSUB
464 { $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, $4, $6); CHECK_ERROR; }
465 | Storage_opt tFUNCTION Identifier ArgumentsDecl_opt StSep BodyStatements tEND tFUNCTION
466 { $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, $4, $6); CHECK_ERROR; }
468 Storage_opt
469 : /* empty*/ { $$ = 0; }
470 | Storage { $$ = $1; }
472 Storage
473 : tPUBLIC tDEFAULT { $$ = STORAGE_IS_DEFAULT; }
474 | tPUBLIC { $$ = 0; }
475 | tPRIVATE { $$ = STORAGE_IS_PRIVATE; }
477 ArgumentsDecl_opt
478 : EmptyBrackets_opt { $$ = NULL; }
479 | '(' ArgumentDeclList ')' { $$ = $2; }
481 ArgumentDeclList
482 : ArgumentDecl { $$ = $1; }
483 | ArgumentDecl ',' ArgumentDeclList { $1->next = $3; $$ = $1; }
485 ArgumentDecl
486 : Identifier EmptyBrackets_opt { $$ = new_argument_decl(ctx, $1, TRUE); }
487 | tBYREF Identifier EmptyBrackets_opt { $$ = new_argument_decl(ctx, $2, TRUE); }
488 | tBYVAL Identifier EmptyBrackets_opt { $$ = new_argument_decl(ctx, $2, FALSE); }
490 /* these keywords may also be an identifier, depending on context */
491 Identifier
492 : tIdentifier { $$ = $1; }
493 | tDEFAULT { ctx->last_token = tIdentifier; $$ = $1; }
494 | tERROR { ctx->last_token = tIdentifier; $$ = $1; }
495 | tEXPLICIT { ctx->last_token = tIdentifier; $$ = $1; }
496 | tPROPERTY { ctx->last_token = tIdentifier; $$ = $1; }
497 | tSTEP { ctx->last_token = tIdentifier; $$ = $1; }
499 /* Most statements accept both new line and ':' as separators */
500 StSep
501 : tNL
502 | ':'
503 | tNL StSep
504 | ':' StSep
508 static int parser_error(unsigned *loc, parser_ctx_t *ctx, const char *str)
510 if(ctx->error_loc == -1)
511 ctx->error_loc = *loc;
512 if(ctx->hres == S_OK) {
513 FIXME("%s: %s\n", debugstr_w(ctx->code + *loc), debugstr_a(str));
514 ctx->hres = E_FAIL;
515 }else {
516 WARN("%s: %08x\n", debugstr_w(ctx->code + *loc), ctx->hres);
518 return 0;
521 static void source_add_statement(parser_ctx_t *ctx, statement_t *stat)
523 if(!stat)
524 return;
526 /* concatenate both linked lists */
527 if(ctx->stats) {
528 ctx->stats_tail->next = stat;
529 ctx->stats_tail = stat;
530 }else {
531 ctx->stats = ctx->stats_tail = stat;
533 /* find new tail */
534 while(ctx->stats_tail->next) {
535 ctx->stats_tail=ctx->stats_tail->next;
539 static void source_add_class(parser_ctx_t *ctx, class_decl_t *class_decl)
541 class_decl->next = ctx->class_decls;
542 ctx->class_decls = class_decl;
545 static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr)
547 retval_statement_t *stat;
549 if(!expr)
550 return;
552 stat = new_statement(ctx, STAT_RETVAL, sizeof(*stat), 0);
553 if(!stat)
554 return;
556 stat->expr = expr;
557 ctx->stats = &stat->stat;
560 static void *new_expression(parser_ctx_t *ctx, expression_type_t type, size_t size)
562 expression_t *expr;
564 expr = parser_alloc(ctx, size ? size : sizeof(*expr));
565 if(expr) {
566 expr->type = type;
567 expr->next = NULL;
570 return expr;
573 static expression_t *new_bool_expression(parser_ctx_t *ctx, VARIANT_BOOL value)
575 bool_expression_t *expr;
577 expr = new_expression(ctx, EXPR_BOOL, sizeof(*expr));
578 if(!expr)
579 return NULL;
581 expr->value = value;
582 return &expr->expr;
585 static expression_t *new_string_expression(parser_ctx_t *ctx, const WCHAR *value)
587 string_expression_t *expr;
589 expr = new_expression(ctx, EXPR_STRING, sizeof(*expr));
590 if(!expr)
591 return NULL;
593 expr->value = value;
594 return &expr->expr;
597 static expression_t *new_long_expression(parser_ctx_t *ctx, expression_type_t type, LONG value)
599 int_expression_t *expr;
601 expr = new_expression(ctx, type, sizeof(*expr));
602 if(!expr)
603 return NULL;
605 expr->value = value;
606 return &expr->expr;
609 static expression_t *new_double_expression(parser_ctx_t *ctx, double value)
611 double_expression_t *expr;
613 expr = new_expression(ctx, EXPR_DOUBLE, sizeof(*expr));
614 if(!expr)
615 return NULL;
617 expr->value = value;
618 return &expr->expr;
621 static expression_t *new_unary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *subexpr)
623 unary_expression_t *expr;
625 expr = new_expression(ctx, type, sizeof(*expr));
626 if(!expr)
627 return NULL;
629 expr->subexpr = subexpr;
630 return &expr->expr;
633 static expression_t *new_binary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *left, expression_t *right)
635 binary_expression_t *expr;
637 expr = new_expression(ctx, type, sizeof(*expr));
638 if(!expr)
639 return NULL;
641 expr->left = left;
642 expr->right = right;
643 return &expr->expr;
646 static member_expression_t *new_member_expression(parser_ctx_t *ctx, expression_t *obj_expr, const WCHAR *identifier)
648 member_expression_t *expr;
650 expr = new_expression(ctx, EXPR_MEMBER, sizeof(*expr));
651 if(!expr)
652 return NULL;
654 expr->obj_expr = obj_expr;
655 expr->identifier = identifier;
656 return expr;
659 static call_expression_t *new_call_expression(parser_ctx_t *ctx, expression_t *expr, expression_t *arguments)
661 call_expression_t *call_expr;
663 call_expr = new_expression(ctx, EXPR_CALL, sizeof(*call_expr));
664 if(!call_expr)
665 return NULL;
667 call_expr->call_expr = expr;
668 call_expr->args = arguments;
669 return call_expr;
672 static call_expression_t *make_call_expression(parser_ctx_t *ctx, expression_t *callee_expr, expression_t *arguments)
674 call_expression_t *call_expr;
676 if(callee_expr->type == EXPR_MEMBER)
677 return new_call_expression(ctx, callee_expr, arguments);
678 if(callee_expr->type != EXPR_CALL) {
679 FIXME("Unhandled for expr type %u\n", callee_expr->type);
680 ctx->hres = E_FAIL;
681 return NULL;
683 call_expr = (call_expression_t*)callee_expr;
684 if(!call_expr->args) {
685 call_expr->args = arguments;
686 return call_expr;
689 if(call_expr->args->next) {
690 FIXME("Invalid syntax: invalid use of parentheses for arguments\n");
691 ctx->hres = E_FAIL;
692 return NULL;
695 call_expr->args = new_unary_expression(ctx, EXPR_BRACKETS, call_expr->args);
696 if(!call_expr->args)
697 return NULL;
698 if(!arguments)
699 return call_expr;
701 if(arguments->type != EXPR_NOARG) {
702 FIXME("Invalid syntax: missing comma\n");
703 ctx->hres = E_FAIL;
704 return NULL;
707 call_expr->args->next = arguments->next;
708 return call_expr;
711 static expression_t *new_new_expression(parser_ctx_t *ctx, const WCHAR *identifier)
713 string_expression_t *expr;
715 expr = new_expression(ctx, EXPR_NEW, sizeof(*expr));
716 if(!expr)
717 return NULL;
719 expr->value = identifier;
720 return &expr->expr;
723 static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size, unsigned loc)
725 statement_t *stat;
727 stat = parser_alloc(ctx, size ? size : sizeof(*stat));
728 if(stat) {
729 stat->type = type;
730 stat->loc = loc;
731 stat->next = NULL;
734 return stat;
737 static statement_t *new_call_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr)
739 call_expression_t *call_expr = NULL;
740 call_statement_t *stat;
742 stat = new_statement(ctx, STAT_CALL, sizeof(*stat), loc);
743 if(!stat)
744 return NULL;
746 switch(expr->type) {
747 case EXPR_MEMBER:
748 call_expr = new_call_expression(ctx, expr, NULL);
749 break;
750 case EXPR_CALL:
751 call_expr = (call_expression_t*)expr;
752 break;
753 default:
754 FIXME("Unsupported expr type %u\n", expr->type);
755 ctx->hres = E_NOTIMPL;
757 if(!call_expr)
758 return NULL;
760 stat->expr = call_expr;
761 return &stat->stat;
764 static statement_t *new_assign_statement(parser_ctx_t *ctx, unsigned loc, expression_t *left, expression_t *right)
766 assign_statement_t *stat;
768 stat = new_statement(ctx, STAT_ASSIGN, sizeof(*stat), loc);
769 if(!stat)
770 return NULL;
772 stat->left_expr = left;
773 stat->value_expr = right;
775 return &stat->stat;
778 static statement_t *new_set_statement(parser_ctx_t *ctx, unsigned loc, expression_t *left, expression_t *right)
780 assign_statement_t *stat;
782 stat = new_statement(ctx, STAT_SET, sizeof(*stat), loc);
783 if(!stat)
784 return NULL;
786 stat->left_expr = left;
787 stat->value_expr = right;
789 return &stat->stat;
792 static dim_decl_t *new_dim_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL is_array, dim_list_t *dims)
794 dim_decl_t *decl;
796 decl = parser_alloc(ctx, sizeof(*decl));
797 if(!decl)
798 return NULL;
800 decl->name = name;
801 decl->is_array = is_array;
802 decl->dims = dims;
803 decl->next = NULL;
804 return decl;
807 static dim_list_t *new_dim(parser_ctx_t *ctx, unsigned val, dim_list_t *next)
809 dim_list_t *ret;
811 ret = parser_alloc(ctx, sizeof(*ret));
812 if(!ret)
813 return NULL;
815 ret->val = val;
816 ret->next = next;
817 return ret;
820 static statement_t *new_dim_statement(parser_ctx_t *ctx, unsigned loc, dim_decl_t *decls)
822 dim_statement_t *stat;
824 stat = new_statement(ctx, STAT_DIM, sizeof(*stat), loc);
825 if(!stat)
826 return NULL;
828 stat->dim_decls = decls;
829 return &stat->stat;
832 static statement_t *new_redim_statement(parser_ctx_t *ctx, unsigned loc, const WCHAR *identifier, BOOL preserve, expression_t *dims)
834 redim_statement_t *stat;
836 stat = new_statement(ctx, STAT_REDIM, sizeof(*stat), loc);
837 if(!stat)
838 return NULL;
840 stat->identifier = identifier;
841 stat->preserve = preserve;
842 stat->dims = dims;
843 return &stat->stat;
846 static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_t *stat)
848 elseif_decl_t *decl;
850 decl = parser_alloc(ctx, sizeof(*decl));
851 if(!decl)
852 return NULL;
854 decl->expr = expr;
855 decl->stat = stat;
856 decl->loc = loc;
857 decl->next = NULL;
858 return decl;
861 static statement_t *new_while_statement(parser_ctx_t *ctx, unsigned loc, statement_type_t type, expression_t *expr, statement_t *body)
863 while_statement_t *stat;
865 stat = new_statement(ctx, type, sizeof(*stat), loc);
866 if(!stat)
867 return NULL;
869 stat->expr = expr;
870 stat->body = body;
871 return &stat->stat;
874 static statement_t *new_forto_statement(parser_ctx_t *ctx, unsigned loc, const WCHAR *identifier, expression_t *from_expr,
875 expression_t *to_expr, expression_t *step_expr, statement_t *body)
877 forto_statement_t *stat;
879 stat = new_statement(ctx, STAT_FORTO, sizeof(*stat), loc);
880 if(!stat)
881 return NULL;
883 stat->identifier = identifier;
884 stat->from_expr = from_expr;
885 stat->to_expr = to_expr;
886 stat->step_expr = step_expr;
887 stat->body = body;
888 return &stat->stat;
891 static statement_t *new_foreach_statement(parser_ctx_t *ctx, unsigned loc, const WCHAR *identifier, expression_t *group_expr,
892 statement_t *body)
894 foreach_statement_t *stat;
896 stat = new_statement(ctx, STAT_FOREACH, sizeof(*stat), loc);
897 if(!stat)
898 return NULL;
900 stat->identifier = identifier;
901 stat->group_expr = group_expr;
902 stat->body = body;
903 return &stat->stat;
906 static statement_t *new_if_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
907 statement_t *else_stat)
909 if_statement_t *stat;
911 stat = new_statement(ctx, STAT_IF, sizeof(*stat), loc);
912 if(!stat)
913 return NULL;
915 stat->expr = expr;
916 stat->if_stat = if_stat;
917 stat->elseifs = elseif_decl;
918 stat->else_stat = else_stat;
919 return &stat->stat;
922 static statement_t *new_select_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr, case_clausule_t *case_clausules)
924 select_statement_t *stat;
926 stat = new_statement(ctx, STAT_SELECT, sizeof(*stat), loc);
927 if(!stat)
928 return NULL;
930 stat->expr = expr;
931 stat->case_clausules = case_clausules;
932 return &stat->stat;
935 static statement_t *new_with_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_t *body)
937 with_statement_t *stat;
939 stat = new_statement(ctx, STAT_WITH, sizeof(*stat), loc);
940 if(!stat)
941 return NULL;
943 stat->expr = expr;
944 stat->body = body;
945 return &stat->stat;
948 static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr, statement_t *stat, case_clausule_t *next)
950 case_clausule_t *ret;
952 ret = parser_alloc(ctx, sizeof(*ret));
953 if(!ret)
954 return NULL;
956 ret->expr = expr;
957 ret->stat = stat;
958 ret->next = next;
959 return ret;
962 static statement_t *new_onerror_statement(parser_ctx_t *ctx, unsigned loc, BOOL resume_next)
964 onerror_statement_t *stat;
966 stat = new_statement(ctx, STAT_ONERROR, sizeof(*stat), loc);
967 if(!stat)
968 return NULL;
970 stat->resume_next = resume_next;
971 return &stat->stat;
974 static arg_decl_t *new_argument_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL by_ref)
976 arg_decl_t *arg_decl;
978 arg_decl = parser_alloc(ctx, sizeof(*arg_decl));
979 if(!arg_decl)
980 return NULL;
982 arg_decl->name = name;
983 arg_decl->by_ref = by_ref;
984 arg_decl->next = NULL;
985 return arg_decl;
988 static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name, function_type_t type,
989 unsigned storage_flags, arg_decl_t *arg_decl, statement_t *body)
991 function_decl_t *decl;
992 BOOL is_default = FALSE;
994 if(storage_flags & STORAGE_IS_DEFAULT) {
995 if(type == FUNC_PROPGET || type == FUNC_FUNCTION || type == FUNC_SUB) {
996 is_default = TRUE;
997 }else {
998 FIXME("Invalid default property\n");
999 ctx->hres = E_FAIL;
1000 return NULL;
1004 decl = parser_alloc(ctx, sizeof(*decl));
1005 if(!decl)
1006 return NULL;
1008 decl->name = name;
1009 decl->type = type;
1010 decl->is_public = !(storage_flags & STORAGE_IS_PRIVATE);
1011 decl->is_default = is_default;
1012 decl->args = arg_decl;
1013 decl->body = body;
1014 decl->next = NULL;
1015 decl->next_prop_func = NULL;
1016 return decl;
1019 static statement_t *new_function_statement(parser_ctx_t *ctx, unsigned loc, function_decl_t *decl)
1021 function_statement_t *stat;
1023 stat = new_statement(ctx, STAT_FUNC, sizeof(*stat), loc);
1024 if(!stat)
1025 return NULL;
1027 stat->func_decl = decl;
1028 return &stat->stat;
1031 static class_decl_t *new_class_decl(parser_ctx_t *ctx)
1033 class_decl_t *class_decl;
1035 class_decl = parser_alloc(ctx, sizeof(*class_decl));
1036 if(!class_decl)
1037 return NULL;
1039 class_decl->funcs = NULL;
1040 class_decl->props = NULL;
1041 class_decl->next = NULL;
1042 return class_decl;
1045 static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_decl, function_decl_t *decl)
1047 function_decl_t *iter;
1049 for(iter = class_decl->funcs; iter; iter = iter->next) {
1050 if(!wcsicmp(iter->name, decl->name)) {
1051 if(decl->type == FUNC_SUB || decl->type == FUNC_FUNCTION) {
1052 FIXME("Redefinition of %s::%s\n", debugstr_w(class_decl->name), debugstr_w(decl->name));
1053 ctx->hres = E_FAIL;
1054 return NULL;
1057 while(1) {
1058 if(iter->type == decl->type) {
1059 FIXME("Redefinition of %s::%s\n", debugstr_w(class_decl->name), debugstr_w(decl->name));
1060 ctx->hres = E_FAIL;
1061 return NULL;
1063 if(!iter->next_prop_func)
1064 break;
1065 iter = iter->next_prop_func;
1068 iter->next_prop_func = decl;
1069 return class_decl;
1073 decl->next = class_decl->funcs;
1074 class_decl->funcs = decl;
1075 return class_decl;
1078 static class_decl_t *add_dim_prop(parser_ctx_t *ctx, class_decl_t *class_decl, dim_decl_t *dim_decl, unsigned storage_flags)
1080 if(storage_flags & STORAGE_IS_DEFAULT) {
1081 FIXME("variant prop van't be default value\n");
1082 ctx->hres = E_FAIL;
1083 return NULL;
1086 dim_decl->is_public = !(storage_flags & STORAGE_IS_PRIVATE);
1087 dim_decl->next = class_decl->props;
1088 class_decl->props = dim_decl;
1089 return class_decl;
1092 static const_decl_t *new_const_decl(parser_ctx_t *ctx, const WCHAR *name, expression_t *expr)
1094 const_decl_t *decl;
1096 decl = parser_alloc(ctx, sizeof(*decl));
1097 if(!decl)
1098 return NULL;
1100 decl->name = name;
1101 decl->value_expr = expr;
1102 decl->next = NULL;
1103 return decl;
1106 static statement_t *new_const_statement(parser_ctx_t *ctx, unsigned loc, const_decl_t *decls)
1108 const_statement_t *stat;
1110 stat = new_statement(ctx, STAT_CONST, sizeof(*stat), loc);
1111 if(!stat)
1112 return NULL;
1114 stat->decls = decls;
1115 return &stat->stat;
1118 static statement_t *link_statements(statement_t *head, statement_t *tail)
1120 statement_t *iter;
1122 for(iter = head; iter->next; iter = iter->next);
1123 iter->next = tail;
1125 return head;
1128 void *parser_alloc(parser_ctx_t *ctx, size_t size)
1130 void *ret;
1132 ret = heap_pool_alloc(&ctx->heap, size);
1133 if(!ret)
1134 ctx->hres = E_OUTOFMEMORY;
1135 return ret;
1138 HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, DWORD flags)
1140 ctx->code = ctx->ptr = code;
1141 ctx->end = ctx->code + lstrlenW(ctx->code);
1143 heap_pool_init(&ctx->heap);
1145 ctx->hres = S_OK;
1146 ctx->error_loc = -1;
1147 ctx->last_token = tNL;
1148 ctx->last_nl = 0;
1149 ctx->stats = ctx->stats_tail = NULL;
1150 ctx->class_decls = NULL;
1151 ctx->option_explicit = FALSE;
1152 ctx->is_html = delimiter && !wcsicmp(delimiter, L"</script>");
1154 if(flags & SCRIPTTEXT_ISEXPRESSION)
1155 ctx->last_token = tEXPRESSION;
1157 parser_parse(ctx);
1159 return ctx->hres;
1162 void parser_release(parser_ctx_t *ctx)
1164 heap_pool_free(&ctx->heap);