793 $tt = $this->t->get();
814 $n =
new JSNode($this->t);
816 array_push($x->stmtStack, $n);
819 array_pop($x->stmtStack);
823 $n =
new JSNode($this->t);
828 $n->defaultIndex = -1;
830 array_push($x->stmtStack, $n);
839 if ($n->defaultIndex >= 0)
840 throw $this->t->newSyntaxError(
'More than one switch default');
843 $n2 =
new JSNode($this->t);
845 $n->defaultIndex = count($n->cases);
850 throw $this->t->newSyntaxError(
'Invalid switch case');
856 $n2->statements->addNode($this->
Statement($x));
858 array_push($n->cases, $n2);
861 array_pop($x->stmtStack);
865 $n =
new JSNode($this->t);
871 $x->inForLoopInit =
true;
881 $x->inForLoopInit =
false;
889 if (count($n2->treeNodes) != 1)
891 throw $this->t->SyntaxError(
892 'Invalid for..in left-hand side',
899 $n->iterator = $n2->treeNodes[0];
912 $n->setup = $n2 ? $n2 :
null;
920 $n->body = $this->
nest($x, $n);
924 $n =
new JSNode($this->t);
927 $n->body = $this->
nest($x, $n);
931 $n =
new JSNode($this->t);
935 if (!$x->ecmaStrictMode)
947 $n =
new JSNode($this->t);
952 $n->label = $this->t->currentToken()->value;
963 throw $this->t->newSyntaxError(
'Label not found');
965 while ($ss[$i]->label != $label);
972 throw $this->t->newSyntaxError(
'Invalid ' . $tt);
979 $n =
new JSNode($this->t);
980 $n->tryBlock = $this->
Block($x);
981 $n->catchClauses =
array();
985 $n2 =
new JSNode($this->t);
991 if ($x->ecmaStrictMode)
992 throw $this->t->newSyntaxError(
'Illegal catch guard');
994 if (count($n->catchClauses) && !end($n->catchClauses)->guard)
995 throw $this->t->newSyntaxError(
'Guarded catch after unguarded');
1005 $n2->block = $this->
Block($x);
1006 array_push($n->catchClauses, $n2);
1010 $n->finallyBlock = $this->
Block($x);
1012 if (!count($n->catchClauses) && !$n->finallyBlock)
1013 throw $this->t->newSyntaxError(
'Invalid try statement');
1018 throw $this->t->newSyntaxError($tt .
' without preceding try');
1021 $n =
new JSNode($this->t);
1026 if (!$x->inFunction)
1027 throw $this->t->newSyntaxError(
'Invalid return');
1029 $n =
new JSNode($this->t);
1030 $tt = $this->t->peekOnSameLine();
1038 $n =
new JSNode($this->t);
1040 $n->body = $this->
nest($x, $n);
1050 $n =
new JSNode($this->t);
1054 $n =
new JSNode($this->t);
1060 $n->expression =
null;
1066 $this->t->scanOperand =
false;
1067 $tt = $this->t->peek();
1068 $this->t->scanOperand =
true;
1071 $label = $this->t->currentToken()->value;
1072 $ss = $x->stmtStack;
1073 for ($i = count($ss) - 1; $i >= 0; --$i)
1075 if ($ss[$i]->label == $label)
1076 throw $this->t->newSyntaxError(
'Duplicate label');
1082 $n->statement = $this->
nest($x, $n);
1091 $n->end = $n->expression->end;
1095 if ($this->t->lineno == $this->t->currentToken()->lineno)
1097 $tt = $this->t->peekOnSameLine();
1099 throw $this->t->newSyntaxError(
'Missing ; before statement');
1109 $f =
new JSNode($this->t);
1115 $f->name = $this->t->currentToken()->value;
1116 elseif ($requireName)
1117 throw $this->t->newSyntaxError(
'Missing function identifier');
1120 $f->params =
array();
1125 throw $this->t->newSyntaxError(
'Missing formal parameter');
1127 array_push($f->params, $this->t->currentToken()->value);
1136 $f->body = $this->
Script($x2);
1139 $f->end = $this->t->currentToken()->end;
1141 $f->functionForm = $functionForm;
1143 array_push($x->funDecls, $f);
1179 $operators =
array();
1180 $operands =
array();
1183 $bl = $x->bracketLevel;
1184 $cl = $x->curlyLevel;
1185 $pl = $x->parenLevel;
1186 $hl = $x->hookLevel;
1188 while (($tt = $this->t->get()) !=
TOKEN_END)
1191 $x->bracketLevel == $bl &&
1192 $x->curlyLevel == $cl &&
1193 $x->parenLevel == $pl &&
1194 $x->hookLevel == $hl
1209 if ($this->t->scanOperand)
1212 while ( !empty($operators) &&
1213 $this->opPrecedence[end($operators)->
type] > $this->opPrecedence[$tt]
1215 $this->
reduce($operators, $operands);
1217 array_push($operators,
new JSNode($this->t));
1220 $this->t->scanOperand =
true;
1227 array_push($operands, $n);
1234 throw $this->t->newSyntaxError(
'Invalid label');
1238 if ($this->t->scanOperand)
1242 while ( !empty($operators) &&
1243 $this->opPrecedence[end($operators)->
type] > $this->opPrecedence[$tt]
1245 $this->
reduce($operators, $operands);
1247 array_push($operators,
new JSNode($this->t));
1248 end($operands)->assignOp = $this->t->currentToken()->assignOp;
1249 $this->t->scanOperand =
true;
1256 if ($x->inForLoopInit && !$x->hookLevel &&
1257 !$x->bracketLevel && !$x->curlyLevel &&
1265 if ($tt ==
OP_COMMA && $x->hookLevel &&
1266 !$x->bracketLevel && !$x->curlyLevel &&
1285 if ($this->t->scanOperand)
1288 while ( !empty($operators) &&
1289 $this->opPrecedence[end($operators)->
type] >= $this->opPrecedence[$tt]
1291 $this->
reduce($operators, $operands);
1296 array_push($operands,
new JSNode($this->t,
OP_DOT, array_pop($operands),
new JSNode($this->t)));
1300 array_push($operators,
new JSNode($this->t));
1301 $this->t->scanOperand =
true;
1308 if (!$this->t->scanOperand)
1311 array_push($operators,
new JSNode($this->t));
1315 if ($this->t->scanOperand)
1317 array_push($operators,
new JSNode($this->t));
1322 $t = $this->t->tokens[($this->t->tokenIndex + $this->t->lookahead - 1) & 3];
1323 if (
$t &&
$t->lineno != $this->t->lineno)
1326 if (!empty($operators))
1329 while ($this->opPrecedence[end($operators)->type] > $this->opPrecedence[$tt])
1330 $this->
reduce($operators, $operands);
1333 $n =
new JSNode($this->t, $tt, array_pop($operands));
1335 array_push($operands, $n);
1340 if (!$this->t->scanOperand)
1344 $this->t->scanOperand =
false;
1349 if (!$this->t->scanOperand)
1352 array_push($operands,
new JSNode($this->t));
1353 $this->t->scanOperand =
false;
1358 if ($this->t->scanOperand)
1359 array_push($operators,
new JSNode($this->t));
1361 array_push($operands,
new JSNode($this->t));
1365 if ($this->t->scanOperand)
1385 array_push($operands, $n);
1386 $this->t->scanOperand =
false;
1392 $this->t->scanOperand =
true;
1398 if ($this->t->scanOperand || $x->bracketLevel == $bl)
1408 if (!$this->t->scanOperand)
1419 $tt = $this->t->get();
1420 $tv = $this->t->currentToken()->value;
1421 if (($tv ==
'get' || $tv ==
'set') && $this->t->peek() ==
TOKEN_IDENTIFIER)
1423 if ($x->ecmaStrictMode)
1424 throw $this->t->newSyntaxError(
'Illegal property accessor');
1435 $id =
new JSNode($this->t);
1439 if ($x->ecmaStrictMode)
1440 throw $this->t->newSyntaxError(
'Illegal trailing ,');
1444 throw $this->t->newSyntaxError(
'Invalid property name');
1457 array_push($operands, $n);
1458 $this->t->scanOperand =
false;
1463 if (!$this->t->scanOperand && $x->curlyLevel != $cl)
1464 throw new Exception(
'PANIC: right curly botch');
1468 if ($this->t->scanOperand)
1474 while ( !empty($operators) &&
1475 $this->opPrecedence[end($operators)->
type] > $this->opPrecedence[
KEYWORD_NEW]
1477 $this->
reduce($operators, $operands);
1482 $n = end($operators);
1483 $this->t->scanOperand =
true;
1488 array_pop($operators);
1489 $n->addNode(array_pop($operands));
1496 array_push($operands, $n);
1497 $this->t->scanOperand =
false;
1511 if ($this->t->scanOperand || $x->parenLevel == $pl)
1523 $n = end($operands);
1524 if ($n->treeNodes[1]->type !=
OP_COMMA)
1525 $n->treeNodes[1] =
new JSNode($this->t,
JS_LIST, $n->treeNodes[1]);
1527 $n->treeNodes[1]->type =
JS_LIST;
1541 if ($x->hookLevel != $hl)
1542 throw $this->t->newSyntaxError(
'Missing : in conditional expression');
1544 if ($x->parenLevel != $pl)
1545 throw $this->t->newSyntaxError(
'Missing ) in parenthetical');
1547 if ($x->bracketLevel != $bl)
1548 throw $this->t->newSyntaxError(
'Missing ] in index expression');
1550 if ($this->t->scanOperand)
1551 throw $this->t->newSyntaxError(
'Missing operand');
1554 $this->t->scanOperand =
true;
1557 while (count($operators))
1558 $this->
reduce($operators, $operands);
1560 return array_pop($operands);
1585 private function reduce(&$operators, &$operands)
1587 $n = array_pop($operators);
1589 $arity = $this->opArity[$op];
1590 $c = count($operands);
1596 $left = $operands[$c - 2];
1597 if ($left->type == $op)
1599 $right = array_pop($operands);
1600 $left->addNode($right);
1608 $a = array_splice($operands, $c - $arity);
1609 for ($i = 0; $i < $arity; $i++)
1610 $n->addNode($a[$i]);
1613 $te = $this->t->currentToken()->end;
1617 array_push($operands, $n);