public function assignDefaultValue(array $parameter, CompilationContext $compilationContext)
{
if (isset($parameter['data-type'])) {
$dataType = $parameter['data-type'];
} else {
$dataType = 'variable';
}
/**
* Class-Hinted parameters only can be null?
*/
if (isset($parameter['cast'])) {
if ($parameter['default']['type'] != 'null') {
throw new CompilerException('Class-Hinted parameters only can have "null" as default parameter', $parameter);
}
}
$oldCodePrinter = $compilationContext->codePrinter;
$codePrinter = new CodePrinter();
$codePrinter->increaseLevel();
$codePrinter->increaseLevel();
$compilationContext->codePrinter = $codePrinter;
$paramVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext);
/**
* @todo Refactoring this place, move to one - static-constant-access
*/
switch ($dataType) {
case 'int':
case 'uint':
case 'long':
case 'ulong':
switch ($parameter['default']['type']) {
case 'static-constant-access':
/**
* Now I can write code for easy use on Expression because code in this method don't write with codePrinter ;(
* @todo Rewrite all to codePrinter
*/
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext, $parameter['default']);
$expression = new Expression($parameter['default']);
$expression->setExpectReturn(true, $symbolVariable);
$compiledExpression = $expression->compile($compilationContext);
if ($compiledExpression->getType() != 'int') {
throw new CompilerException("Default parameter value type: " . $compiledExpression->getType() . " cannot be assigned to variable(int)", $parameter);
}
$parameter['default']['type'] = $compiledExpression->getType();
$parameter['default']['value'] = $compiledExpression->getCode();
$compilationContext->codePrinter = $oldCodePrinter;
return $this->assignDefaultValue($parameter, $compilationContext);
break;
case 'null':
$codePrinter->output($parameter['name'] . ' = 0;');
break;
case 'int':
case 'uint':
case 'long':
$codePrinter->output($parameter['name'] . ' = ' . $parameter['default']['value'] . ';');
break;
case 'double':
$codePrinter->output($parameter['name'] . ' = (int) ' . $parameter['default']['value'] . ';');
break;
default:
throw new CompilerException("Default parameter value type: " . $parameter['default']['type'] . " cannot be assigned to variable(int)", $parameter);
}
break;
case 'double':
switch ($parameter['default']['type']) {
case 'static-constant-access':
/**
* Now I can write code for easy use on Expression because code in this method don't write with codePrinter ;(
* @todo Rewrite all to codePrinter
*/
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext, $parameter['default']);
$expression = new Expression($parameter['default']);
$expression->setExpectReturn(true, $symbolVariable);
$compiledExpression = $expression->compile($compilationContext);
if ($compiledExpression->getType() != 'double') {
throw new CompilerException("Default parameter value type: " . $compiledExpression->getType() . " cannot be assigned to variable(double)", $parameter);
}
$parameter['default']['type'] = $compiledExpression->getType();
$parameter['default']['value'] = $compiledExpression->getCode();
$compilationContext->codePrinter = $oldCodePrinter;
return $this->assignDefaultValue($parameter, $compilationContext);
break;
case 'null':
$codePrinter->output($parameter['name'] . ' = 0;');
break;
case 'int':
case 'uint':
case 'long':
$codePrinter->output($parameter['name'] . ' = (double) ' . $parameter['default']['value'] . ';');
break;
case 'double':
$codePrinter->output($parameter['name'] . ' = ' . $parameter['default']['value'] . ';');
break;
default:
throw new CompilerException("Default parameter value type: " . $parameter['default']['type'] . " cannot be assigned to variable(double)", $parameter);
}
break;
case 'bool':
switch ($parameter['default']['type']) {
case 'static-constant-access':
/**
* Now I can write code for easy use on Expression because code in this method don't write with codePrinter ;(
* @todo Rewrite all to codePrinter
*/
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext, $parameter['default']);
$expression = new Expression($parameter['default']);
$expression->setExpectReturn(true, $symbolVariable);
$compiledExpression = $expression->compile($compilationContext);
if ($compiledExpression->getType() != 'bool') {
throw new CompilerException("Default parameter value type: " . $compiledExpression->getType() . " cannot be assigned to variable(bool)", $parameter);
}
$parameter['default']['type'] = $compiledExpression->getType();
$parameter['default']['value'] = $compiledExpression->getCode();
$compilationContext->codePrinter = $oldCodePrinter;
return $this->assignDefaultValue($parameter, $compilationContext);
break;
case 'null':
$codePrinter->output($parameter['name'] . ' = 0;');
break;
case 'bool':
if ($parameter['default']['value'] == 'true') {
$codePrinter->output($parameter['name'] . ' = 1;');
} else {
$codePrinter->output($parameter['name'] . ' = 0;');
}
break;
default:
throw new CompilerException("Default parameter value type: " . $parameter['default']['type'] . " cannot be assigned to variable(bool)", $parameter);
}
break;
case 'string':
$compilationContext->symbolTable->mustGrownStack(true);
$compilationContext->headersManager->add('kernel/memory');
switch ($parameter['default']['type']) {
case 'static-constant-access':
/**
* Now I can write code for easy use on Expression because code in this method don't write with codePrinter ;(
* @todo Rewrite all to codePrinter
*/
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext, $parameter['default']);
$expression = new Expression($parameter['default']);
$expression->setExpectReturn(true, $symbolVariable);
$compiledExpression = $expression->compile($compilationContext);
if ($compiledExpression->getType() != 'string') {
throw new CompilerException("Default parameter value type: " . $compiledExpression->getType() . " cannot be assigned to variable(string)", $parameter);
}
$parameter['default']['type'] = $compiledExpression->getType();
$parameter['default']['value'] = $compiledExpression->getCode();
$compilationContext->codePrinter = $oldCodePrinter;
return $this->assignDefaultValue($parameter, $compilationContext);
break;
case 'null':
$compilationContext->backend->initVar($paramVariable, $compilationContext);
$compilationContext->backend->assignString($paramVariable, null, $compilationContext);
break;
case 'string':
$compilationContext->backend->initVar($paramVariable, $compilationContext);
$compilationContext->backend->assignString($paramVariable, Utils::addSlashes($parameter['default']['value'], true), $compilationContext);
break;
default:
throw new CompilerException("Default parameter value type: " . $parameter['default']['type'] . " cannot be assigned to variable(string)", $parameter);
}
break;
case 'array':
$compilationContext->symbolTable->mustGrownStack(true);
$compilationContext->headersManager->add('kernel/memory');
switch ($parameter['default']['type']) {
case 'null':
$compilationContext->backend->initVar($paramVariable, $compilationContext);
$compilationContext->backend->initArray($paramVariable, $compilationContext, null);
break;
case 'empty-array':
case 'array':
$compilationContext->backend->initVar($paramVariable, $compilationContext);
$compilationContext->backend->initArray($paramVariable, $compilationContext, null);
break;
default:
throw new CompilerException("Default parameter value type: " . $parameter['default']['type'] . " cannot be assigned to variable(array)", $parameter);
}
break;
case 'variable':
$symbolVariable = $compilationContext->symbolTable->getVariableForWrite($parameter['name'], $compilationContext, $parameter['default']);
switch ($parameter['default']['type']) {
case 'static-constant-access':
/**
* Now I can write code for easy use on Expression because code in this method don't write with codePrinter ;(
* @todo Rewrite all to codePrinter
*/
$expression = new Expression($parameter['default']);
$expression->setExpectReturn(true, $symbolVariable);
$compiledExpression = $expression->compile($compilationContext);
$parameter['default']['type'] = $compiledExpression->getType();
$parameter['default']['value'] = $compiledExpression->getCode();
$compilationContext->codePrinter = $oldCodePrinter;
return $this->assignDefaultValue($parameter, $compilationContext);
break;
case 'int':
case 'uint':
case 'long':
case 'ulong':
$compilationContext->symbolTable->mustGrownStack(true);
$compilationContext->headersManager->add('kernel/memory');
$compilationContext->backend->initVar($symbolVariable, $compilationContext);
$compilationContext->backend->assignLong($symbolVariable, $parameter['default']['value'], $compilationContext);
break;
case 'double':
$compilationContext->symbolTable->mustGrownStack(true);
$compilationContext->headersManager->add('kernel/memory');
$compilationContext->backend->initVar($symbolVariable, $compilationContext);
$compilationContext->backend->assignDouble($symbolVariable, $parameter['default']['value'], $compilationContext);
break;
case 'string':
$compilationContext->symbolTable->mustGrownStack(true);
$compilationContext->headersManager->add('kernel/memory');
$compilationContext->backend->initVar($symbolVariable, $compilationContext);
$compilationContext->backend->assignString($paramVariable, Utils::addSlashes($parameter['default']['value'], true), $compilationContext);
break;
case 'bool':
$expectedMutations = $compilationContext->symbolTable->getExpectedMutations($parameter['name']);
if ($expectedMutations < 2) {
if ($parameter['default']['value'] == 'true') {
$compilationContext->backend->assignZval($paramVariable, $compilationContext->backend->resolveValue('true', $compilationContext), $compilationContext);
} else {
$compilationContext->backend->assignZval($paramVariable, $compilationContext->backend->resolveValue('false', $compilationContext), $compilationContext);
}
} else {
$compilationContext->symbolTable->mustGrownStack(true);
$compilationContext->headersManager->add('kernel/memory');
if ($parameter['default']['value'] == 'true') {
$compilationContext->backend->copyOnWrite($paramVariable, $compilationContext->backend->resolveValue('true', $compilationContext), $compilationContext);
} else {
$compilationContext->backend->copyOnWrite($paramVariable, $compilationContext->backend->resolveValue('false', $compilationContext), $compilationContext);
}
}
break;
case 'null':
$expectedMutations = $compilationContext->symbolTable->getExpectedMutations($parameter['name']);
if ($expectedMutations < 2) {
$compilationContext->backend->assignZval($symbolVariable, $compilationContext->backend->resolveValue('null', $compilationContext), $compilationContext);
} else {
$compilationContext->symbolTable->mustGrownStack(true);
$compilationContext->headersManager->add('kernel/memory');
$compilationContext->backend->copyOnWrite($paramVariable, $compilationContext->backend->resolveValue('null', $compilationContext), $compilationContext);
}
break;
case 'empty-array':
$compilationContext->symbolTable->mustGrownStack(true);
$compilationContext->headersManager->add('kernel/memory');
$compilationContext->backend->initVar($symbolVariable, $compilationContext);
$compilationContext->backend->initArray($symbolVariable, $compilationContext, null);
break;
default:
throw new CompilerException("Default parameter value type: " . $parameter['default']['type'] . " cannot be assigned to variable(variable)", $parameter);
}
break;
default:
throw new CompilerException("Default parameter type: " . $dataType, $parameter);
}
$compilationContext->codePrinter = $oldCodePrinter;
return $codePrinter->getOutput();
}