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 ?:
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);
1295 $tt = $this->t->get();
1297 throw $this->t->newSyntaxError(
"Unexpected token; token identifier or keyword expected.");
1299 array_push($operands,
new JSNode($this->t,
OP_DOT, array_pop($operands),
new JSNode($this->t)));
1303 array_push($operators,
new JSNode($this->t));
1304 $this->t->scanOperand =
true;
1311 if (!$this->t->scanOperand)
1314 array_push($operators,
new JSNode($this->t));
1318 if ($this->t->scanOperand)
1320 array_push($operators,
new JSNode($this->t));
1325 $t = $this->t->tokens[($this->t->tokenIndex + $this->t->lookahead - 1) & 3];
1326 if (
$t &&
$t->lineno != $this->t->lineno)
1329 if (!empty($operators))
1332 while ($this->opPrecedence[end($operators)->type] > $this->opPrecedence[$tt])
1333 $this->
reduce($operators, $operands);
1336 $n =
new JSNode($this->t, $tt, array_pop($operands));
1338 array_push($operands, $n);
1343 if (!$this->t->scanOperand)
1347 $this->t->scanOperand =
false;
1352 if (!$this->t->scanOperand)
1355 array_push($operands,
new JSNode($this->t));
1356 $this->t->scanOperand =
false;
1361 if ($this->t->scanOperand)
1362 array_push($operators,
new JSNode($this->t));
1364 array_push($operands,
new JSNode($this->t));
1368 if ($this->t->scanOperand)
1388 array_push($operands, $n);
1389 $this->t->scanOperand =
false;
1395 $this->t->scanOperand =
true;
1401 if ($this->t->scanOperand || $x->bracketLevel == $bl)
1411 if (!$this->t->scanOperand)
1422 $tt = $this->t->get();
1423 $tv = $this->t->currentToken()->value;
1424 if (($tv ==
'get' || $tv ==
'set') && $this->t->peek() ==
TOKEN_IDENTIFIER)
1426 if ($x->ecmaStrictMode)
1427 throw $this->t->newSyntaxError(
'Illegal property accessor');
1443 $id =
new JSNode($this->t);
1447 if ($x->ecmaStrictMode)
1448 throw $this->t->newSyntaxError(
'Illegal trailing ,');
1452 throw $this->t->newSyntaxError(
'Invalid property name');
1465 array_push($operands, $n);
1466 $this->t->scanOperand =
false;
1471 if (!$this->t->scanOperand && $x->curlyLevel != $cl)
1472 throw new Exception(
'PANIC: right curly botch');
1476 if ($this->t->scanOperand)
1482 while ( !empty($operators) &&
1483 $this->opPrecedence[end($operators)->type] > $this->opPrecedence[
KEYWORD_NEW]
1485 $this->
reduce($operators, $operands);
1490 $n = end($operators);
1491 $this->t->scanOperand =
true;
1496 array_pop($operators);
1497 $n->addNode(array_pop($operands));
1504 array_push($operands, $n);
1505 $this->t->scanOperand =
false;
1519 if ($this->t->scanOperand || $x->parenLevel == $pl)
1522 while (($tt = $this->
reduce($operators, $operands)->type) !=
JS_GROUP &&
1531 $n = end($operands);
1532 if ($n->treeNodes[1]->type !=
OP_COMMA)
1533 $n->treeNodes[1] =
new JSNode($this->t,
JS_LIST, $n->treeNodes[1]);
1535 $n->treeNodes[1]->type =
JS_LIST;
1549 if ($x->hookLevel != $hl)
1550 throw $this->t->newSyntaxError(
'Missing : in conditional expression');
1552 if ($x->parenLevel != $pl)
1553 throw $this->t->newSyntaxError(
'Missing ) in parenthetical');
1555 if ($x->bracketLevel != $bl)
1556 throw $this->t->newSyntaxError(
'Missing ] in index expression');
1558 if ($this->t->scanOperand)
1559 throw $this->t->newSyntaxError(
'Missing operand');
1562 $this->t->scanOperand =
true;
1565 while (count($operators))
1566 $this->
reduce($operators, $operands);
1568 return array_pop($operands);
1593 private function reduce(&$operators, &$operands)
1595 $n = array_pop($operators);
1597 $arity = $this->opArity[$op];
1598 $c = count($operands);
1604 $left = $operands[$c - 2];
1605 if ($left->type == $op)
1607 $right = array_pop($operands);
1608 $left->addNode($right);
1616 $a = array_splice($operands, $c - $arity);
1617 for ($i = 0; $i < $arity; $i++)
1618 $n->addNode($a[$i]);
1621 $te = $this->t->currentToken()->end;
1625 array_push($operands, $n);