ntoskrnl.exe: Add KeQueryActiveProcessorCountEx() function.
[wine.git] / dlls / vbscript / parser.y
blob5c18af13d429421a7db79cc7b852e711c56ee648
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,BOOL,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 <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression ExpressionNl_opt
135 %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
136 %type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression SignExpression
137 %type <expression> ConstExpression NumericLiteralExpression
138 %type <member> MemberExpression
139 %type <expression> Arguments ArgumentList ArgumentList_opt Step_opt ExpressionList
140 %type <boolean> DoType Preserve_opt
141 %type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
142 %type <func_decl> FunctionDecl PropertyDecl
143 %type <elseif> ElseIfs_opt ElseIfs ElseIf
144 %type <class_decl> ClassDeclaration ClassBody
145 %type <uint> Storage Storage_opt IntegerValue
146 %type <dim_decl> DimDeclList DimDecl
147 %type <dim_list> DimList
148 %type <const_decl> ConstDecl ConstDeclList
149 %type <string> Identifier
150 %type <case_clausule> CaseClausules
154 Program
155 : OptionExplicit_opt SourceElements
156 | tEXPRESSION ExpressionNl_opt { handle_isexpression_script(ctx, $2); }
158 OptionExplicit_opt
159 : /* empty */
160 | tOPTION tEXPLICIT StSep { ctx->option_explicit = TRUE; }
162 SourceElements
163 : /* empty */
164 | SourceElements StatementNl { source_add_statement(ctx, $2); }
165 | SourceElements ClassDeclaration { source_add_class(ctx, $2); }
167 ExpressionNl_opt
168 : /* empty */ { $$ = NULL; }
169 | Expression tNL { $$ = $1; }
171 BodyStatements
172 : /* empty */ { $$ = NULL; }
173 | Statement { $$ = $1; }
174 | StatementNl BodyStatements { $$ = link_statements($1, $2); }
176 StatementsNl_opt
177 : /* empty */ { $$ = NULL; }
178 | StatementsNl { $$ = $1; }
180 StatementsNl
181 : StatementNl { $$ = $1; }
182 | StatementNl StatementsNl { $$ = link_statements($1, $2); }
184 StatementNl
185 : Statement tNL { $$ = $1; }
187 Statement
188 : ':' { $$ = NULL; }
189 | ':' Statement { $$ = $2; }
190 | SimpleStatement { $$ = $1; }
191 | SimpleStatement ':' Statement { $1->next = $3; $$ = $1; }
192 | SimpleStatement ':' { $$ = $1; }
194 SimpleStatement
195 : CallExpression ArgumentList_opt { call_expression_t *call_expr = make_call_expression(ctx, $1, $2); CHECK_ERROR;
196 $$ = new_call_statement(ctx, @$, FALSE, &call_expr->expr); CHECK_ERROR; };
197 | tCALL UnaryExpression { $$ = new_call_statement(ctx, @$, TRUE, $2); CHECK_ERROR; }
198 | CallExpression '=' Expression
199 { $$ = new_assign_statement(ctx, @$, $1, $3); CHECK_ERROR; }
200 | tDIM DimDeclList { $$ = new_dim_statement(ctx, @$, $2); CHECK_ERROR; }
201 | tREDIM Preserve_opt tIdentifier '(' ArgumentList ')'
202 { $$ = new_redim_statement(ctx, @$, $3, $2, $5); CHECK_ERROR; }
203 | IfStatement { $$ = $1; }
204 | tWHILE Expression StSep StatementsNl_opt tWEND
205 { $$ = new_while_statement(ctx, @$, STAT_WHILE, $2, $4); CHECK_ERROR; }
206 | tDO DoType Expression StSep StatementsNl_opt tLOOP
207 { $$ = new_while_statement(ctx, @$, $2 ? STAT_WHILELOOP : STAT_UNTIL, $3, $5);
208 CHECK_ERROR; }
209 | tDO StSep StatementsNl_opt tLOOP DoType Expression
210 { $$ = new_while_statement(ctx, @4, $5 ? STAT_DOWHILE : STAT_DOUNTIL, $6, $3);
211 CHECK_ERROR; }
212 | tDO StSep StatementsNl_opt tLOOP { $$ = new_while_statement(ctx, @$, STAT_DOWHILE, NULL, $3); CHECK_ERROR; }
213 | FunctionDecl { $$ = new_function_statement(ctx, @$, $1); CHECK_ERROR; }
214 | tEXIT tDO { $$ = new_statement(ctx, STAT_EXITDO, 0, @$); CHECK_ERROR; }
215 | tEXIT tFOR { $$ = new_statement(ctx, STAT_EXITFOR, 0, @$); CHECK_ERROR; }
216 | tEXIT tFUNCTION { $$ = new_statement(ctx, STAT_EXITFUNC, 0, @$); CHECK_ERROR; }
217 | tEXIT tPROPERTY { $$ = new_statement(ctx, STAT_EXITPROP, 0, @$); CHECK_ERROR; }
218 | tEXIT tSUB { $$ = new_statement(ctx, STAT_EXITSUB, 0, @$); CHECK_ERROR; }
219 | tSET CallExpression '=' Expression { $$ = new_set_statement(ctx, @$, $2, $4); CHECK_ERROR; }
220 | tSTOP { $$ = new_statement(ctx, STAT_STOP, 0, @$); CHECK_ERROR; }
221 | tON tERROR tRESUME tNEXT { $$ = new_onerror_statement(ctx, @$, TRUE); CHECK_ERROR; }
222 | tON tERROR tGOTO '0' { $$ = new_onerror_statement(ctx, @$, FALSE); CHECK_ERROR; }
223 | tCONST ConstDeclList { $$ = new_const_statement(ctx, @$, $2); CHECK_ERROR; }
224 | tFOR Identifier '=' Expression tTO Expression Step_opt StSep StatementsNl_opt tNEXT
225 { $$ = new_forto_statement(ctx, @$, $2, $4, $6, $7, $9); CHECK_ERROR; }
226 | tFOR tEACH Identifier tIN Expression StSep StatementsNl_opt tNEXT
227 { $$ = new_foreach_statement(ctx, @$, $3, $5, $7); }
228 | tSELECT tCASE Expression StSep CaseClausules tEND tSELECT
229 { $$ = new_select_statement(ctx, @$, $3, $5); }
230 | tWITH Expression StSep StatementsNl_opt tEND tWITH
231 { $$ = new_with_statement(ctx, @$, $2, $4); }
233 MemberExpression
234 : Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
235 | CallExpression '.' tIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
236 | tDOT tIdentifier { expression_t *dot_expr = new_expression(ctx, EXPR_DOT, sizeof(*dot_expr)); CHECK_ERROR;
237 $$ = new_member_expression(ctx, dot_expr, $2); CHECK_ERROR; }
239 Preserve_opt
240 : /* empty */ { $$ = FALSE; }
241 | tPRESERVE { $$ = TRUE; }
243 DimDeclList
244 : DimDecl { $$ = $1; }
245 | DimDecl ',' DimDeclList { $1->next = $3; $$ = $1; }
247 DimDecl
248 : Identifier { $$ = new_dim_decl(ctx, $1, FALSE, NULL); CHECK_ERROR; }
249 | Identifier '(' DimList ')' { $$ = new_dim_decl(ctx, $1, TRUE, $3); CHECK_ERROR; }
250 | Identifier tEMPTYBRACKETS { $$ = new_dim_decl(ctx, $1, TRUE, NULL); CHECK_ERROR; }
252 DimList
253 : IntegerValue { $$ = new_dim(ctx, $1, NULL); }
254 | IntegerValue ',' DimList { $$ = new_dim(ctx, $1, $3); }
256 ConstDeclList
257 : ConstDecl { $$ = $1; }
258 | ConstDecl ',' ConstDeclList { $1->next = $3; $$ = $1; }
260 ConstDecl
261 : Identifier '=' ConstExpression { $$ = new_const_decl(ctx, $1, $3); CHECK_ERROR; }
263 ConstExpression
264 : LiteralExpression { $$ = $1; }
265 | '-' NumericLiteralExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
267 DoType
268 : tWHILE { $$ = TRUE; }
269 | tUNTIL { $$ = FALSE; }
271 Step_opt
272 : /* empty */ { $$ = NULL;}
273 | tSTEP Expression { $$ = $2; }
275 IfStatement
276 : tIF Expression tTHEN tNL StatementsNl_opt ElseIfs_opt Else_opt tEND tIF
277 { $$ = new_if_statement(ctx, @$, $2, $5, $6, $7); CHECK_ERROR; }
278 | tIF Expression tTHEN Statement EndIf_opt { $$ = new_if_statement(ctx, @$, $2, $4, NULL, NULL); CHECK_ERROR; }
279 | tIF Expression tTHEN Statement tELSE Statement EndIf_opt
280 { $$ = new_if_statement(ctx, @$, $2, $4, NULL, $6); CHECK_ERROR; }
282 EndIf_opt
283 : /* empty */
284 | tEND tIF
286 ElseIfs_opt
287 : /* empty */ { $$ = NULL; }
288 | ElseIfs { $$ = $1; }
290 ElseIfs
291 : ElseIf { $$ = $1; }
292 | ElseIf ElseIfs { $1->next = $2; $$ = $1; }
294 ElseIf
295 : tELSEIF Expression tTHEN tNL StatementsNl_opt
296 { $$ = new_elseif_decl(ctx, @$, $2, $5); }
298 Else_opt
299 : /* empty */ { $$ = NULL; }
300 | tELSE tNL StatementsNl_opt { $$ = $3; }
302 CaseClausules
303 : /* empty */ { $$ = NULL; }
304 | tCASE tELSE StSep StatementsNl { $$ = new_case_clausule(ctx, NULL, $4, NULL); }
305 | tCASE ExpressionList StSep StatementsNl_opt CaseClausules
306 { $$ = new_case_clausule(ctx, $2, $4, $5); }
308 Arguments
309 : tEMPTYBRACKETS { $$ = NULL; }
310 | '(' ArgumentList ')' { $$ = $2; }
312 ArgumentList_opt
313 : /* empty */ { $$ = NULL; }
314 | ArgumentList { $$ = $1; }
316 ArgumentList
317 : Expression { $$ = $1; }
318 | Expression ',' ArgumentList { $1->next = $3; $$ = $1; }
319 | ',' ArgumentList { $$ = new_expression(ctx, EXPR_NOARG, 0); CHECK_ERROR; $$->next = $2; }
321 EmptyBrackets_opt
322 : /* empty */
323 | tEMPTYBRACKETS
325 ExpressionList
326 : Expression { $$ = $1; }
327 | Expression ',' ExpressionList { $1->next = $3; $$ = $1; }
329 Expression
330 : EqvExpression { $$ = $1; }
331 | Expression tIMP EqvExpression { $$ = new_binary_expression(ctx, EXPR_IMP, $1, $3); CHECK_ERROR; }
333 EqvExpression
334 : XorExpression { $$ = $1; }
335 | EqvExpression tEQV XorExpression { $$ = new_binary_expression(ctx, EXPR_EQV, $1, $3); CHECK_ERROR; }
337 XorExpression
338 : OrExpression { $$ = $1; }
339 | XorExpression tXOR OrExpression { $$ = new_binary_expression(ctx, EXPR_XOR, $1, $3); CHECK_ERROR; }
341 OrExpression
342 : AndExpression { $$ = $1; }
343 | OrExpression tOR AndExpression { $$ = new_binary_expression(ctx, EXPR_OR, $1, $3); CHECK_ERROR; }
345 AndExpression
346 : NotExpression { $$ = $1; }
347 | AndExpression tAND NotExpression { $$ = new_binary_expression(ctx, EXPR_AND, $1, $3); CHECK_ERROR; }
349 NotExpression
350 : EqualityExpression { $$ = $1; }
351 | tNOT NotExpression { $$ = new_unary_expression(ctx, EXPR_NOT, $2); CHECK_ERROR; }
353 EqualityExpression
354 : ConcatExpression { $$ = $1; }
355 | EqualityExpression '=' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_EQUAL, $1, $3); CHECK_ERROR; }
356 | EqualityExpression tNEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_NEQUAL, $1, $3); CHECK_ERROR; }
357 | EqualityExpression '>' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GT, $1, $3); CHECK_ERROR; }
358 | EqualityExpression '<' ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LT, $1, $3); CHECK_ERROR; }
359 | EqualityExpression tGTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GTEQ, $1, $3); CHECK_ERROR; }
360 | EqualityExpression tLTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LTEQ, $1, $3); CHECK_ERROR; }
361 | EqualityExpression tIS ConcatExpression { $$ = new_binary_expression(ctx, EXPR_IS, $1, $3); CHECK_ERROR; }
363 ConcatExpression
364 : AdditiveExpression { $$ = $1; }
365 | ConcatExpression '&' AdditiveExpression { $$ = new_binary_expression(ctx, EXPR_CONCAT, $1, $3); CHECK_ERROR; }
367 AdditiveExpression
368 : ModExpression { $$ = $1; }
369 | AdditiveExpression '+' ModExpression { $$ = new_binary_expression(ctx, EXPR_ADD, $1, $3); CHECK_ERROR; }
370 | AdditiveExpression '-' ModExpression { $$ = new_binary_expression(ctx, EXPR_SUB, $1, $3); CHECK_ERROR; }
372 ModExpression
373 : IntdivExpression { $$ = $1; }
374 | ModExpression tMOD IntdivExpression { $$ = new_binary_expression(ctx, EXPR_MOD, $1, $3); CHECK_ERROR; }
376 IntdivExpression
377 : MultiplicativeExpression { $$ = $1; }
378 | IntdivExpression '\\' MultiplicativeExpression
379 { $$ = new_binary_expression(ctx, EXPR_IDIV, $1, $3); CHECK_ERROR; }
381 MultiplicativeExpression
382 : ExpExpression { $$ = $1; }
383 | MultiplicativeExpression '*' ExpExpression
384 { $$ = new_binary_expression(ctx, EXPR_MUL, $1, $3); CHECK_ERROR; }
385 | MultiplicativeExpression '/' ExpExpression
386 { $$ = new_binary_expression(ctx, EXPR_DIV, $1, $3); CHECK_ERROR; }
388 ExpExpression
389 : SignExpression { $$ = $1; }
390 | ExpExpression '^' SignExpression { $$ = new_binary_expression(ctx, EXPR_EXP, $1, $3); CHECK_ERROR; }
392 SignExpression
393 : UnaryExpression { $$ = $1; }
394 | '-' SignExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
395 | '+' SignExpression { $$ = $2; }
397 UnaryExpression
398 : LiteralExpression { $$ = $1; }
399 | CallExpression { $$ = $1; }
400 | tNEW Identifier { $$ = new_new_expression(ctx, $2); CHECK_ERROR; }
402 CallExpression
403 : PrimaryExpression { $$ = $1; }
404 | MemberExpression { $$ = &$1->expr; }
405 | CallExpression Arguments { call_expression_t *expr = new_call_expression(ctx, $1, $2); CHECK_ERROR;
406 $$ = &expr->expr; }
408 LiteralExpression
409 : tTRUE { $$ = new_bool_expression(ctx, VARIANT_TRUE); CHECK_ERROR; }
410 | tFALSE { $$ = new_bool_expression(ctx, VARIANT_FALSE); CHECK_ERROR; }
411 | tString { $$ = new_string_expression(ctx, $1); CHECK_ERROR; }
412 | NumericLiteralExpression { $$ = $1; }
413 | tEMPTY { $$ = new_expression(ctx, EXPR_EMPTY, 0); CHECK_ERROR; }
414 | tNULL { $$ = new_expression(ctx, EXPR_NULL, 0); CHECK_ERROR; }
415 | tNOTHING { $$ = new_expression(ctx, EXPR_NOTHING, 0); CHECK_ERROR; }
417 NumericLiteralExpression
418 : '0' { $$ = new_long_expression(ctx, EXPR_INT, 0); CHECK_ERROR; }
419 | tInt { $$ = new_long_expression(ctx, EXPR_INT, $1); CHECK_ERROR; }
420 | tDouble { $$ = new_double_expression(ctx, $1); CHECK_ERROR; }
422 IntegerValue
423 : '0' { $$ = 0; }
424 | tInt { $$ = $1; }
426 PrimaryExpression
427 : tEXPRLBRACKET Expression ')' { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
428 | tME { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; }
430 ClassDeclaration
431 : tCLASS Identifier StSep ClassBody tEND tCLASS StSep { $4->name = $2; $$ = $4; }
433 ClassBody
434 : /* empty */ { $$ = new_class_decl(ctx); }
435 | FunctionDecl { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; }
436 | FunctionDecl StSep ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
437 /* FIXME: We should use DimDecl here to support arrays, but that conflicts with PropertyDecl. */
438 | Storage tIdentifier { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR;
439 $$ = add_dim_prop(ctx, new_class_decl(ctx), dim_decl, $1); CHECK_ERROR; }
440 | Storage tIdentifier StSep ClassBody { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR;
441 $$ = add_dim_prop(ctx, $4, dim_decl, $1); CHECK_ERROR; }
442 | tDIM DimDecl { $$ = add_dim_prop(ctx, new_class_decl(ctx), $2, 0); CHECK_ERROR; }
443 | tDIM DimDecl StSep ClassBody { $$ = add_dim_prop(ctx, $4, $2, 0); CHECK_ERROR; }
444 | PropertyDecl { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; }
445 | PropertyDecl StSep ClassBody { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
447 PropertyDecl
448 : Storage_opt tPROPERTY tGET tIdentifier ArgumentsDecl_opt StSep BodyStatements tEND tPROPERTY
449 { $$ = new_function_decl(ctx, $4, FUNC_PROPGET, $1, $5, $7); CHECK_ERROR; }
450 | Storage_opt tPROPERTY tLET tIdentifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
451 { $$ = new_function_decl(ctx, $4, FUNC_PROPLET, $1, $6, $9); CHECK_ERROR; }
452 | Storage_opt tPROPERTY tSET tIdentifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
453 { $$ = new_function_decl(ctx, $4, FUNC_PROPSET, $1, $6, $9); CHECK_ERROR; }
455 FunctionDecl
456 : Storage_opt tSUB Identifier ArgumentsDecl_opt StSep BodyStatements tEND tSUB
457 { $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, $4, $6); CHECK_ERROR; }
458 | Storage_opt tFUNCTION Identifier ArgumentsDecl_opt StSep BodyStatements tEND tFUNCTION
459 { $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, $4, $6); CHECK_ERROR; }
461 Storage_opt
462 : /* empty*/ { $$ = 0; }
463 | Storage { $$ = $1; }
465 Storage
466 : tPUBLIC tDEFAULT { $$ = STORAGE_IS_DEFAULT; }
467 | tPUBLIC { $$ = 0; }
468 | tPRIVATE { $$ = STORAGE_IS_PRIVATE; }
470 ArgumentsDecl_opt
471 : EmptyBrackets_opt { $$ = NULL; }
472 | '(' ArgumentDeclList ')' { $$ = $2; }
474 ArgumentDeclList
475 : ArgumentDecl { $$ = $1; }
476 | ArgumentDecl ',' ArgumentDeclList { $1->next = $3; $$ = $1; }
478 ArgumentDecl
479 : Identifier EmptyBrackets_opt { $$ = new_argument_decl(ctx, $1, TRUE); }
480 | tBYREF Identifier EmptyBrackets_opt { $$ = new_argument_decl(ctx, $2, TRUE); }
481 | tBYVAL Identifier EmptyBrackets_opt { $$ = new_argument_decl(ctx, $2, FALSE); }
483 /* these keywords may also be an identifier, depending on context */
484 Identifier
485 : tIdentifier { $$ = $1; }
486 | tDEFAULT { $$ = $1; }
487 | tERROR { $$ = $1; }
488 | tEXPLICIT { $$ = $1; }
489 | tPROPERTY { $$ = $1; }
490 | tSTEP { $$ = $1; }
492 /* Most statements accept both new line and ':' as separators */
493 StSep
494 : tNL
495 | ':'
496 | tNL StSep
497 | ':' StSep
501 static int parser_error(unsigned *loc, parser_ctx_t *ctx, const char *str)
503 if(ctx->error_loc == -1)
504 ctx->error_loc = *loc;
505 if(ctx->hres == S_OK) {
506 FIXME("%s: %s\n", debugstr_w(ctx->code + *loc), debugstr_a(str));
507 ctx->hres = E_FAIL;
508 }else {
509 WARN("%s: %08x\n", debugstr_w(ctx->code + *loc), ctx->hres);
511 return 0;
514 static void source_add_statement(parser_ctx_t *ctx, statement_t *stat)
516 if(!stat)
517 return;
519 if(ctx->stats) {
520 ctx->stats_tail->next = stat;
521 ctx->stats_tail = stat;
522 }else {
523 ctx->stats = ctx->stats_tail = stat;
527 static void source_add_class(parser_ctx_t *ctx, class_decl_t *class_decl)
529 class_decl->next = ctx->class_decls;
530 ctx->class_decls = class_decl;
533 static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr)
535 retval_statement_t *stat;
537 if(!expr)
538 return;
540 stat = new_statement(ctx, STAT_RETVAL, sizeof(*stat), 0);
541 if(!stat)
542 return;
544 stat->expr = expr;
545 ctx->stats = &stat->stat;
548 static void *new_expression(parser_ctx_t *ctx, expression_type_t type, size_t size)
550 expression_t *expr;
552 expr = parser_alloc(ctx, size ? size : sizeof(*expr));
553 if(expr) {
554 expr->type = type;
555 expr->next = NULL;
558 return expr;
561 static expression_t *new_bool_expression(parser_ctx_t *ctx, VARIANT_BOOL value)
563 bool_expression_t *expr;
565 expr = new_expression(ctx, EXPR_BOOL, sizeof(*expr));
566 if(!expr)
567 return NULL;
569 expr->value = value;
570 return &expr->expr;
573 static expression_t *new_string_expression(parser_ctx_t *ctx, const WCHAR *value)
575 string_expression_t *expr;
577 expr = new_expression(ctx, EXPR_STRING, sizeof(*expr));
578 if(!expr)
579 return NULL;
581 expr->value = value;
582 return &expr->expr;
585 static expression_t *new_long_expression(parser_ctx_t *ctx, expression_type_t type, LONG value)
587 int_expression_t *expr;
589 expr = new_expression(ctx, type, sizeof(*expr));
590 if(!expr)
591 return NULL;
593 expr->value = value;
594 return &expr->expr;
597 static expression_t *new_double_expression(parser_ctx_t *ctx, double value)
599 double_expression_t *expr;
601 expr = new_expression(ctx, EXPR_DOUBLE, sizeof(*expr));
602 if(!expr)
603 return NULL;
605 expr->value = value;
606 return &expr->expr;
609 static expression_t *new_unary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *subexpr)
611 unary_expression_t *expr;
613 expr = new_expression(ctx, type, sizeof(*expr));
614 if(!expr)
615 return NULL;
617 expr->subexpr = subexpr;
618 return &expr->expr;
621 static expression_t *new_binary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *left, expression_t *right)
623 binary_expression_t *expr;
625 expr = new_expression(ctx, type, sizeof(*expr));
626 if(!expr)
627 return NULL;
629 expr->left = left;
630 expr->right = right;
631 return &expr->expr;
634 static member_expression_t *new_member_expression(parser_ctx_t *ctx, expression_t *obj_expr, const WCHAR *identifier)
636 member_expression_t *expr;
638 expr = new_expression(ctx, EXPR_MEMBER, sizeof(*expr));
639 if(!expr)
640 return NULL;
642 expr->obj_expr = obj_expr;
643 expr->identifier = identifier;
644 return expr;
647 static call_expression_t *new_call_expression(parser_ctx_t *ctx, expression_t *expr, expression_t *arguments)
649 call_expression_t *call_expr;
651 call_expr = new_expression(ctx, EXPR_CALL, sizeof(*call_expr));
652 if(!call_expr)
653 return NULL;
655 call_expr->call_expr = expr;
656 call_expr->args = arguments;
657 return call_expr;
660 static call_expression_t *make_call_expression(parser_ctx_t *ctx, expression_t *callee_expr, expression_t *arguments)
662 call_expression_t *call_expr;
664 if(callee_expr->type == EXPR_MEMBER)
665 return new_call_expression(ctx, callee_expr, arguments);
666 if(callee_expr->type != EXPR_CALL) {
667 FIXME("Unhandled for expr type %u\n", callee_expr->type);
668 ctx->hres = E_FAIL;
669 return NULL;
671 call_expr = (call_expression_t*)callee_expr;
672 if(!call_expr->args) {
673 call_expr->args = arguments;
674 return call_expr;
677 if(call_expr->args->next) {
678 FIXME("Invalid syntax: invalid use of parentheses for arguments\n");
679 ctx->hres = E_FAIL;
680 return NULL;
683 call_expr->args = new_unary_expression(ctx, EXPR_BRACKETS, call_expr->args);
684 if(!call_expr->args)
685 return NULL;
686 if(!arguments)
687 return call_expr;
689 if(arguments->type != EXPR_NOARG) {
690 FIXME("Invalid syntax: missing comma\n");
691 ctx->hres = E_FAIL;
692 return NULL;
695 call_expr->args->next = arguments->next;
696 return call_expr;
699 static expression_t *new_new_expression(parser_ctx_t *ctx, const WCHAR *identifier)
701 string_expression_t *expr;
703 expr = new_expression(ctx, EXPR_NEW, sizeof(*expr));
704 if(!expr)
705 return NULL;
707 expr->value = identifier;
708 return &expr->expr;
711 static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size, unsigned loc)
713 statement_t *stat;
715 stat = parser_alloc(ctx, size ? size : sizeof(*stat));
716 if(stat) {
717 stat->type = type;
718 stat->loc = loc;
719 stat->next = NULL;
722 return stat;
725 static statement_t *new_call_statement(parser_ctx_t *ctx, unsigned loc, BOOL is_strict, expression_t *expr)
727 call_expression_t *call_expr = NULL;
728 call_statement_t *stat;
730 stat = new_statement(ctx, STAT_CALL, sizeof(*stat), loc);
731 if(!stat)
732 return NULL;
734 switch(expr->type) {
735 case EXPR_MEMBER:
736 call_expr = new_call_expression(ctx, expr, NULL);
737 break;
738 case EXPR_CALL:
739 call_expr = (call_expression_t*)expr;
740 break;
741 default:
742 FIXME("Unsupported expr type %u\n", expr->type);
743 ctx->hres = E_NOTIMPL;
745 if(!call_expr)
746 return NULL;
748 stat->expr = call_expr;
749 stat->is_strict = is_strict;
750 return &stat->stat;
753 static statement_t *new_assign_statement(parser_ctx_t *ctx, unsigned loc, expression_t *left, expression_t *right)
755 assign_statement_t *stat;
757 stat = new_statement(ctx, STAT_ASSIGN, sizeof(*stat), loc);
758 if(!stat)
759 return NULL;
761 stat->left_expr = left;
762 stat->value_expr = right;
764 return &stat->stat;
767 static statement_t *new_set_statement(parser_ctx_t *ctx, unsigned loc, expression_t *left, expression_t *right)
769 assign_statement_t *stat;
771 stat = new_statement(ctx, STAT_SET, sizeof(*stat), loc);
772 if(!stat)
773 return NULL;
775 stat->left_expr = left;
776 stat->value_expr = right;
778 return &stat->stat;
781 static dim_decl_t *new_dim_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL is_array, dim_list_t *dims)
783 dim_decl_t *decl;
785 decl = parser_alloc(ctx, sizeof(*decl));
786 if(!decl)
787 return NULL;
789 decl->name = name;
790 decl->is_array = is_array;
791 decl->dims = dims;
792 decl->next = NULL;
793 return decl;
796 static dim_list_t *new_dim(parser_ctx_t *ctx, unsigned val, dim_list_t *next)
798 dim_list_t *ret;
800 ret = parser_alloc(ctx, sizeof(*ret));
801 if(!ret)
802 return NULL;
804 ret->val = val;
805 ret->next = next;
806 return ret;
809 static statement_t *new_dim_statement(parser_ctx_t *ctx, unsigned loc, dim_decl_t *decls)
811 dim_statement_t *stat;
813 stat = new_statement(ctx, STAT_DIM, sizeof(*stat), loc);
814 if(!stat)
815 return NULL;
817 stat->dim_decls = decls;
818 return &stat->stat;
821 static statement_t *new_redim_statement(parser_ctx_t *ctx, unsigned loc, const WCHAR *identifier, BOOL preserve, expression_t *dims)
823 redim_statement_t *stat;
825 stat = new_statement(ctx, STAT_REDIM, sizeof(*stat), loc);
826 if(!stat)
827 return NULL;
829 stat->identifier = identifier;
830 stat->preserve = preserve;
831 stat->dims = dims;
832 return &stat->stat;
835 static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_t *stat)
837 elseif_decl_t *decl;
839 decl = parser_alloc(ctx, sizeof(*decl));
840 if(!decl)
841 return NULL;
843 decl->expr = expr;
844 decl->stat = stat;
845 decl->loc = loc;
846 decl->next = NULL;
847 return decl;
850 static statement_t *new_while_statement(parser_ctx_t *ctx, unsigned loc, statement_type_t type, expression_t *expr, statement_t *body)
852 while_statement_t *stat;
854 stat = new_statement(ctx, type, sizeof(*stat), loc);
855 if(!stat)
856 return NULL;
858 stat->expr = expr;
859 stat->body = body;
860 return &stat->stat;
863 static statement_t *new_forto_statement(parser_ctx_t *ctx, unsigned loc, const WCHAR *identifier, expression_t *from_expr,
864 expression_t *to_expr, expression_t *step_expr, statement_t *body)
866 forto_statement_t *stat;
868 stat = new_statement(ctx, STAT_FORTO, sizeof(*stat), loc);
869 if(!stat)
870 return NULL;
872 stat->identifier = identifier;
873 stat->from_expr = from_expr;
874 stat->to_expr = to_expr;
875 stat->step_expr = step_expr;
876 stat->body = body;
877 return &stat->stat;
880 static statement_t *new_foreach_statement(parser_ctx_t *ctx, unsigned loc, const WCHAR *identifier, expression_t *group_expr,
881 statement_t *body)
883 foreach_statement_t *stat;
885 stat = new_statement(ctx, STAT_FOREACH, sizeof(*stat), loc);
886 if(!stat)
887 return NULL;
889 stat->identifier = identifier;
890 stat->group_expr = group_expr;
891 stat->body = body;
892 return &stat->stat;
895 static statement_t *new_if_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
896 statement_t *else_stat)
898 if_statement_t *stat;
900 stat = new_statement(ctx, STAT_IF, sizeof(*stat), loc);
901 if(!stat)
902 return NULL;
904 stat->expr = expr;
905 stat->if_stat = if_stat;
906 stat->elseifs = elseif_decl;
907 stat->else_stat = else_stat;
908 return &stat->stat;
911 static statement_t *new_select_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr, case_clausule_t *case_clausules)
913 select_statement_t *stat;
915 stat = new_statement(ctx, STAT_SELECT, sizeof(*stat), loc);
916 if(!stat)
917 return NULL;
919 stat->expr = expr;
920 stat->case_clausules = case_clausules;
921 return &stat->stat;
924 static statement_t *new_with_statement(parser_ctx_t *ctx, unsigned loc, expression_t *expr, statement_t *body)
926 with_statement_t *stat;
928 stat = new_statement(ctx, STAT_WITH, sizeof(*stat), loc);
929 if(!stat)
930 return NULL;
932 stat->expr = expr;
933 stat->body = body;
934 return &stat->stat;
937 static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr, statement_t *stat, case_clausule_t *next)
939 case_clausule_t *ret;
941 ret = parser_alloc(ctx, sizeof(*ret));
942 if(!ret)
943 return NULL;
945 ret->expr = expr;
946 ret->stat = stat;
947 ret->next = next;
948 return ret;
951 static statement_t *new_onerror_statement(parser_ctx_t *ctx, unsigned loc, BOOL resume_next)
953 onerror_statement_t *stat;
955 stat = new_statement(ctx, STAT_ONERROR, sizeof(*stat), loc);
956 if(!stat)
957 return NULL;
959 stat->resume_next = resume_next;
960 return &stat->stat;
963 static arg_decl_t *new_argument_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL by_ref)
965 arg_decl_t *arg_decl;
967 arg_decl = parser_alloc(ctx, sizeof(*arg_decl));
968 if(!arg_decl)
969 return NULL;
971 arg_decl->name = name;
972 arg_decl->by_ref = by_ref;
973 arg_decl->next = NULL;
974 return arg_decl;
977 static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name, function_type_t type,
978 unsigned storage_flags, arg_decl_t *arg_decl, statement_t *body)
980 function_decl_t *decl;
982 if(storage_flags & STORAGE_IS_DEFAULT) {
983 if(type == FUNC_PROPGET) {
984 type = FUNC_DEFGET;
985 }else {
986 FIXME("Invalid default property\n");
987 ctx->hres = E_FAIL;
988 return NULL;
992 decl = parser_alloc(ctx, sizeof(*decl));
993 if(!decl)
994 return NULL;
996 decl->name = name;
997 decl->type = type;
998 decl->is_public = !(storage_flags & STORAGE_IS_PRIVATE);
999 decl->args = arg_decl;
1000 decl->body = body;
1001 decl->next = NULL;
1002 decl->next_prop_func = NULL;
1003 return decl;
1006 static statement_t *new_function_statement(parser_ctx_t *ctx, unsigned loc, function_decl_t *decl)
1008 function_statement_t *stat;
1010 stat = new_statement(ctx, STAT_FUNC, sizeof(*stat), loc);
1011 if(!stat)
1012 return NULL;
1014 stat->func_decl = decl;
1015 return &stat->stat;
1018 static class_decl_t *new_class_decl(parser_ctx_t *ctx)
1020 class_decl_t *class_decl;
1022 class_decl = parser_alloc(ctx, sizeof(*class_decl));
1023 if(!class_decl)
1024 return NULL;
1026 class_decl->funcs = NULL;
1027 class_decl->props = NULL;
1028 class_decl->next = NULL;
1029 return class_decl;
1032 static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_decl, function_decl_t *decl)
1034 function_decl_t *iter;
1036 for(iter = class_decl->funcs; iter; iter = iter->next) {
1037 if(!wcsicmp(iter->name, decl->name)) {
1038 if(decl->type == FUNC_SUB || decl->type == FUNC_FUNCTION) {
1039 FIXME("Redefinition of %s::%s\n", debugstr_w(class_decl->name), debugstr_w(decl->name));
1040 ctx->hres = E_FAIL;
1041 return NULL;
1044 while(1) {
1045 if(iter->type == decl->type) {
1046 FIXME("Redefinition of %s::%s\n", debugstr_w(class_decl->name), debugstr_w(decl->name));
1047 ctx->hres = E_FAIL;
1048 return NULL;
1050 if(!iter->next_prop_func)
1051 break;
1052 iter = iter->next_prop_func;
1055 iter->next_prop_func = decl;
1056 return class_decl;
1060 decl->next = class_decl->funcs;
1061 class_decl->funcs = decl;
1062 return class_decl;
1065 static class_decl_t *add_dim_prop(parser_ctx_t *ctx, class_decl_t *class_decl, dim_decl_t *dim_decl, unsigned storage_flags)
1067 if(storage_flags & STORAGE_IS_DEFAULT) {
1068 FIXME("variant prop van't be default value\n");
1069 ctx->hres = E_FAIL;
1070 return NULL;
1073 dim_decl->is_public = !(storage_flags & STORAGE_IS_PRIVATE);
1074 dim_decl->next = class_decl->props;
1075 class_decl->props = dim_decl;
1076 return class_decl;
1079 static const_decl_t *new_const_decl(parser_ctx_t *ctx, const WCHAR *name, expression_t *expr)
1081 const_decl_t *decl;
1083 decl = parser_alloc(ctx, sizeof(*decl));
1084 if(!decl)
1085 return NULL;
1087 decl->name = name;
1088 decl->value_expr = expr;
1089 decl->next = NULL;
1090 return decl;
1093 static statement_t *new_const_statement(parser_ctx_t *ctx, unsigned loc, const_decl_t *decls)
1095 const_statement_t *stat;
1097 stat = new_statement(ctx, STAT_CONST, sizeof(*stat), loc);
1098 if(!stat)
1099 return NULL;
1101 stat->decls = decls;
1102 return &stat->stat;
1105 static statement_t *link_statements(statement_t *head, statement_t *tail)
1107 statement_t *iter;
1109 for(iter = head; iter->next; iter = iter->next);
1110 iter->next = tail;
1112 return head;
1115 void *parser_alloc(parser_ctx_t *ctx, size_t size)
1117 void *ret;
1119 ret = heap_pool_alloc(&ctx->heap, size);
1120 if(!ret)
1121 ctx->hres = E_OUTOFMEMORY;
1122 return ret;
1125 HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, DWORD flags)
1127 ctx->code = ctx->ptr = code;
1128 ctx->end = ctx->code + lstrlenW(ctx->code);
1130 heap_pool_init(&ctx->heap);
1132 ctx->hres = S_OK;
1133 ctx->error_loc = -1;
1134 ctx->last_token = tNL;
1135 ctx->last_nl = 0;
1136 ctx->stats = ctx->stats_tail = NULL;
1137 ctx->class_decls = NULL;
1138 ctx->option_explicit = FALSE;
1139 ctx->is_html = delimiter && !wcsicmp(delimiter, L"</script>");
1141 if(flags & SCRIPTTEXT_ISEXPRESSION)
1142 ctx->last_token = tEXPRESSION;
1144 parser_parse(ctx);
1146 return ctx->hres;
1149 void parser_release(parser_ctx_t *ctx)
1151 heap_pool_free(&ctx->heap);