protected function argumentDef(&$args, &$isVararg)
{
$s = $this->seek();
if (!$this->literal('(')) {
return false;
}
$values = array();
$delim = ",";
$method = "expressionList";
$isVararg = false;
while (true) {
if ($this->literal("...")) {
$isVararg = true;
break;
}
if ($this->{$method}($value)) {
if ($value[0] == "variable") {
$arg = array("arg", $value[1]);
$ss = $this->seek();
if ($this->assign() && $this->{$method}($rhs)) {
$arg[] = $rhs;
} else {
$this->seek($ss);
if ($this->literal("...")) {
$arg[0] = "rest";
$isVararg = true;
}
}
$values[] = $arg;
if ($isVararg) {
break;
}
continue;
} else {
$values[] = array("lit", $value);
}
}
if (!$this->literal($delim)) {
if ($delim == "," && $this->literal(";")) {
// found new delim, convert existing args
$delim = ";";
$method = "propertyValue";
// transform arg list
if (isset($values[1])) {
// 2 items
$newList = array();
foreach ($values as $i => $arg) {
switch ($arg[0]) {
case "arg":
if ($i) {
$this->throwError("Cannot mix ; and , as delimiter types");
}
$newList[] = $arg[2];
break;
case "lit":
$newList[] = $arg[1];
break;
case "rest":
$this->throwError("Unexpected rest before semicolon");
}
}
$newList = array("list", ", ", $newList);
switch ($values[0][0]) {
case "arg":
$newArg = array("arg", $values[0][1], $newList);
break;
case "lit":
$newArg = array("lit", $newList);
break;
}
} elseif ($values) {
// 1 item
$newArg = $values[0];
}
if ($newArg) {
$values = array($newArg);
}
} else {
break;
}
}
}
if (!$this->literal(')')) {
$this->seek($s);
return false;
}
$args = $values;
return true;
}