1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is [Open Source Virtual Machine.].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2008
21 * the Initial Developer. All Rights Reserved.
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
50 Stmt
* Parser::statement(bool config
)
52 AvmAssert(config
== true || hd() == T_LeftBrace
);
55 Stmt
* stmt
= ALLOC(EmptyStmt
, ());
61 return ALLOC(BlockStmt
, (statementBlock(config
)));
64 Stmt
* stmt
= breakStatement();
70 Stmt
* stmt
= continueStatement();
77 if (hd() == T_Identifier
&& identValue() == compiler
->SYM_xml
) {
78 Stmt
* stmt
= defaultXmlNamespaceStatement();
83 compiler
->syntaxError(position(), SYNTAXERR_DEFAULT_NOT_EXPECTED
);
90 Stmt
* stmt
= doStatement();
96 return forStatement();
102 return importStatement();
105 Stmt
* stmt
= returnStatement();
111 return switchStatement();
114 Stmt
* stmt
= throwStatement();
120 return tryStatement();
123 Stmt
* stmt
= useStatement();
130 Stmt
* stmt
= varStatement(hd() == T_Const
);
136 return whileStatement();
139 return withStatement ();
142 if (compiler
->local_functions
) {
143 // FIXME: should block-internal function definition be initialized on block entry?
144 uint32_t pos
= position();
146 FunctionDefn
* fn
= functionGuts(&qual
, true, false, true);
147 Str
* name
= fn
->name
;
149 addVarBinding(name
, NULL
);
150 return ALLOC(ExprStmt
, (pos
,
153 ALLOC(QualifiedName
, (NULL
, ALLOC(SimpleName
, (name
)), false, pos
)),
154 ALLOC(LiteralFunction
, (fn
))))));
157 compiler
->syntaxError(position(), SYNTAXERR_NO_FUNCTIONS_IN_BLOCKS
);
163 return superStatement();
166 if (hd() == T_Identifier
&& hd2() == T_Colon
)
167 return labeledStatement();
168 uint32_t pos
= position();
169 Stmt
* stmt
= ALLOC(ExprStmt
, (pos
, commaExpression(0)));
176 void Parser::semicolon()
188 compiler
->syntaxError(position(), SYNTAXERR_SEMICOLON_OR_NEWLINE
);
194 bool Parser::noNewline()
208 Seq
<Stmt
*>* Parser::statementBlock(bool config
)
210 SeqBuilder
<Stmt
*> stmts(allocator
);
212 while (hd() != T_RightBrace
)
213 stmts
.addAtEnd(statement(config
));
218 // updates bindings by side effect, returns a single expression
219 // statement for the initialization.
221 Stmt
* Parser::varStatement(bool is_const
)
224 Expr
* inits
= varBindings(&pos
, is_const
);
225 return ALLOC(ExprStmt
, (pos
, inits
));
228 // updates bindings by side effect, returns a single expression for
229 // the initialization, a LiteralUndefined node if there was no useful
232 Expr
* Parser::varBindings(uint32_t* pos
, bool is_const
, int flags
, uint32_t* numbindings
, Expr
** firstName
)
234 AvmAssert( !is_const
|| firstName
== NULL
);
237 eat(is_const
? T_Const
: T_Var
);
244 Str
* name
= identifier();
245 QualifiedName
* type_name
= NULL
;
247 type_name
= typeExpression();
251 addVarBinding(name
, type_name
);
253 if (is_const && hd() != T_Assign)
254 compiler->syntaxError(*pos, SYNTAXERR_CONST_INIT_REQD);
256 if (match(T_Assign
)) {
257 Expr
* init
= assignmentExpression(flags
);
258 Expr
* lhs
= ALLOC(QualifiedName
, (NULL
, ALLOC(SimpleName
, (name
)), false, *pos
));
260 addConstBinding(name
, type_name
);
261 Expr
* assign
= ALLOC(AssignExpr
, (is_const
? OPR_init
: OPR_assign
, lhs
, init
));
262 if (firstName
&& *firstName
== NULL
)
267 inits
= ALLOC(BinaryExpr
, (OPR_comma
, inits
, assign
));
269 else if (firstName
&& *firstName
== NULL
) {
270 *firstName
= ALLOC(QualifiedName
, (NULL
, ALLOC(SimpleName
, (name
)), false, *pos
));
276 return inits
? inits
: ALLOC(LiteralUndefined
, (*pos
));
279 Stmt
* Parser::useStatement()
281 uint32_t pos
= position();
283 if (!match(T_Namespace
))
284 compiler
->syntaxError(pos
, SYNTAXERR_ILLEGAL_USE
);
285 Str
* ns
= identifier();
286 addOpenNamespace(ALLOC(NamespaceRef
, (ns
)));
287 return ALLOC(EmptyStmt
, ());
290 // <import> ::= "import" <ident> { "." <ident> }* { "." "*" }
291 Stmt
* Parser::importStatement()
293 SeqBuilder
<Str
*> name(allocator
);
294 StringBuilder
id(compiler
);
297 if (hd() == T_Identifier
) {
298 name
.addAtEnd(identValue());
299 id
.append(identValue());
302 bool qualified
= true;
303 while (match(T_Dot
)) {
304 if (hd() == T_Multiply
) {
310 if (hd() == T_Identifier
) {
311 name
.addAtEnd(identValue());
312 id
.append(identValue());
316 Seq
<Str
*>* n
= name
.get();
318 addQualifiedImport(n
);
320 addOpenNamespace(ALLOC(CommonNamespace
, (id
.str())));
321 addUnqualifiedImport(n
);
323 return ALLOC(EmptyStmt
, ());
326 Stmt
* Parser::labeledStatement()
328 Str
* label
= identifier();
331 Stmt
* stmt
= statement();
334 while (s
->isLabeledStmt())
335 s
= ((LabeledStmt
*)s
)->stmt
;
336 if (s
->isLabelSetStmt()) {
337 LabelSetStmt
* ls
= (LabelSetStmt
*)s
;
338 ls
->labels
= ALLOC(Seq
<Str
*>, (label
, ls
->labels
));
341 return ALLOC(LabeledStmt
, (label
, stmt
));
344 Stmt
* Parser::returnStatement()
347 uint32_t pos
= position();
348 if (topRib
->tag
!= RIB_Function
)
349 compiler
->syntaxError(pos
, SYNTAXERR_RETURN_OUTSIDE_FN
);
353 compiler
->syntaxError(pos
, SYNTAXERR_VOIDFN_RETURNS_VALUE
);
354 expr
= commaExpression(0);
356 return ALLOC(ReturnStmt
, (pos
, expr
));
359 Stmt
* Parser::breakStatement()
361 uint32_t pos
= position();
362 return ALLOC(BreakStmt
, (pos
, breakOrContinueLabel(T_Break
)));
365 Stmt
* Parser::continueStatement()
367 uint32_t pos
= position();
368 return ALLOC(ContinueStmt
, (pos
, breakOrContinueLabel(T_Continue
)));
371 Str
* Parser::breakOrContinueLabel(Token tok
)
374 return noNewline() ? identifier() : NULL
;
377 // 'default' has been consumed, hd() is the identifier 'xml'
378 Stmt
* Parser::defaultXmlNamespaceStatement()
380 uint32_t pos
= position();
381 if(hd() != T_Identifier
|| identValue() != compiler
->SYM_xml
)
384 if(hd() != T_Namespace
)
388 setUsesDefaultXmlNamespace();
389 return ALLOC(DefaultXmlNamespaceStmt
, (pos
, commaExpression(0)));
391 compiler
->syntaxError(pos
, SYNTAXERR_EXPECT_DXNS
);
396 Stmt
* Parser::ifStatement()
399 uint32_t pos
= position();
400 Expr
* test
= parenExpression();
401 Stmt
* consequent
= statement();
402 Stmt
* alternate
= NULL
;
404 alternate
= statement();
406 return ALLOC(IfStmt
, (pos
, test
, consequent
, alternate
));
409 Stmt
* Parser::whileStatement()
412 uint32_t pos
= position();
413 Expr
* expr
= parenExpression();
414 Stmt
* body
= statement();
416 return ALLOC(WhileStmt
, (pos
, expr
, body
));
419 Stmt
* Parser::doStatement()
422 Stmt
* body
= statement();
424 uint32_t pos
= position();
425 Expr
* expr
= parenExpression ();
427 return ALLOC(DoWhileStmt
, (pos
, expr
, body
));
430 Stmt
* Parser::forStatement()
434 uint32_t numbindings
= 0;
435 bool is_each
= false;
438 if (hd() == T_Identifier
&& identValue() == compiler
->SYM_each
) {
442 uint32_t pos
= position();
448 init
= varBindings(&dummy
, false, EFLAG_NoIn
, &numbindings
, &lhs
);
450 else if (hd() == T_Semicolon
)
453 lhs
= init
= commaExpression(EFLAG_NoIn
);
457 compiler
->syntaxError(pos
, SYNTAXERR_FOR_IN_ONEBINDING
);
459 Expr
* objexpr
= commaExpression(0);
461 Stmt
* body
= statement();
463 AvmAssert( lhs
!= NULL
);
464 return ALLOC(ForInStmt
, (pos
, lhs
, init
, objexpr
, body
, is_each
));
468 compiler
->syntaxError(pos
, SYNTAXERR_FOR_EACH_REQS_IN
);
471 Expr
* test
= hd() == T_Semicolon
? NULL
: commaExpression(0);
473 Expr
* update
= hd() == T_RightParen
? NULL
: commaExpression(0);
475 Stmt
* body
= statement ();
477 return ALLOC(ForStmt
, (pos
, init
, test
, update
, body
));
481 Stmt
* Parser::switchStatement()
484 uint32_t pos
= position();
485 Expr
* expr
= parenExpression ();
488 Seq
<CaseClause
*>* cases
= NULL
;
489 if (hd() == T_Case
|| hd() == T_Default
)
490 cases
= caseElements();
493 return ALLOC(SwitchStmt
, (pos
, expr
, cases
));
496 Seq
<CaseClause
*>* Parser::caseElements()
498 SeqBuilder
<CaseClause
*> cases(allocator
);
499 bool hasDefault
= false;
500 CaseClause
* last
= NULL
;
508 if (hd2() != T_Colon
)
509 goto just_a_statement
; // default xml namespace
513 compiler
->syntaxError(position(), SYNTAXERR_DUPLICATE_DEFAULT
);
515 cases
.addAtEnd(last
= ALLOC(CaseClause
, (0, NULL
)));
521 uint32_t pos
= position();
522 Expr
* expr
= commaExpression(0);
524 cases
.addAtEnd(last
= ALLOC(CaseClause
, (pos
, expr
)));
530 compiler
->syntaxError(position(), SYNTAXERR_EXPECT_CASE_OR_DEFAULT
);
531 AvmAssert(last
->stmts
== NULL
);
532 SeqBuilder
<Stmt
*> stmts(allocator
);
533 while (hd() != T_RightBrace
&& hd() != T_Case
&& hd() != T_Default
)
534 stmts
.addAtEnd(statement());
535 last
->stmts
= stmts
.get();
542 Stmt
* Parser::throwStatement()
545 uint32_t pos
= position();
546 return ALLOC(ThrowStmt
, (pos
, commaExpression(0)));
549 Stmt
* Parser::tryStatement()
553 Seq
<Stmt
*>* tryblock
= statementBlock();
554 Seq
<CatchClause
*>* catchblocks
= catches();
555 Seq
<Stmt
*>* finallyblock
= NULL
;
557 if (match(T_Finally
)) {
559 finallyblock
= statementBlock();
562 return ALLOC(TryStmt
, (tryblock
, catchblocks
,finallyblock
));
565 Seq
<CatchClause
*>* Parser::catches()
567 SeqBuilder
<CatchClause
*> catches(allocator
);
569 // Sort of silly that this allows multiple catches yet catchClause() does not
570 // allow the clauses to discriminate by type.
572 while (match(T_Catch
)) {
574 catches
.addAtEnd(catchClause());
577 return catches
.get();
580 CatchClause
* Parser::catchClause()
583 Str
* catchvar_name
= identifier();
584 QualifiedName
* catchvar_type_name
= NULL
;
586 catchvar_type_name
= typeExpression();
588 Seq
<Stmt
*>* catchblock
= statementBlock();
589 return ALLOC(CatchClause
, (catchvar_name
, catchvar_type_name
, catchblock
));
592 Stmt
* Parser::withStatement()
595 uint32_t pos
= position();
596 Expr
* expr
= parenExpression();
597 Stmt
* body
= statement();
598 return ALLOC(WithStmt
, (pos
, expr
, body
));
601 // This also parses super expressions when they appear in the statement position.
602 Stmt
* Parser::superStatement()
605 uint32_t pos
= position();
606 Seq
<Expr
*>* arguments
= NULL
;
607 bool argsPresent
= false;
608 if (hd() == T_LeftParen
) {
610 arguments
= argumentList();
612 if (argsPresent
&& hd() != T_Dot
&& hd() != T_LeftBracket
)
613 return ALLOC(SuperStmt
, (pos
, arguments
));
614 if (argsPresent
&& (arguments
== NULL
|| arguments
->tl
!= NULL
))
615 compiler
->syntaxError(pos
, SYNTAXERR_ONE_ARGUMENT_REQUIRED
);
616 Expr
* obj
= argsPresent
? arguments
->hd
: ALLOC(ThisExpr
, ());
617 return ALLOC(ExprStmt
, (pos
, propertyOperator(ALLOC(SuperExpr
, (obj
)))));