/** * $a &= $b; * * @param \PhpParser\Node\Expr\AssignRef $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { $compiler = $context->getExpressionCompiler(); if ($expr->var instanceof VariableNode) { $name = $expr->var->name; $compiledExpression = $compiler->compile($expr->expr); $symbol = $context->getSymbol($name); if ($symbol) { $symbol->modify($compiledExpression->getType(), $compiledExpression->getValue()); } else { $symbol = new \PHPSA\Variable($name, $compiledExpression->getValue(), $compiledExpression->getType(), $context->getCurrentBranch()); $context->addVariable($symbol); } if ($expr->expr instanceof VariableNode) { $rightVarName = $expr->expr->name; $rightSymbol = $context->getSymbol($rightVarName); if ($rightSymbol) { $rightSymbol->incUse(); $symbol->setReferencedTo($rightSymbol); } else { $context->debug('Cannot fetch variable by name: ' . $rightVarName); } } $symbol->incSets(); return $compiledExpression; } $context->debug('Unknown how to pass symbol by ref'); return new CompiledExpression(); }
/** * {expr}++ * * @param \PhpParser\Node\Expr\PostDec $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { if ($expr->var instanceof \PHPParser\Node\Expr\Variable) { $variableName = $expr->var->name; if ($variableName instanceof Name) { $variableName = $variableName->parts[0]; } $variable = $context->getSymbol($variableName); if ($variable) { $variable->incUse(); switch ($variable->getType()) { case CompiledExpression::LNUMBER: case CompiledExpression::DNUMBER: $variable->dec(); return CompiledExpression::fromZvalValue($variable->getValue()); } $context->notice('postdec.variable.wrong-type', 'You are trying to use post derement operator on variable $' . $variableName . ' with type: ' . $variable->getTypeName(), $expr); } else { $context->notice('postdec.undefined-variable', 'You are trying to use post derement operator on undefined variable: ' . $variableName, $expr); } return new CompiledExpression(CompiledExpression::UNKNOWN); } $expression = new Expression($context); $compiledExpression = $expression->compile($expr->var); switch ($compiledExpression->getType()) { case CompiledExpression::LNUMBER: case CompiledExpression::DNUMBER: $value = $compiledExpression->getValue(); return CompiledExpression::fromZvalValue($value++); } return new CompiledExpression(CompiledExpression::UNKNOWN); }
/** * isset({expr]}) * * @param \PhpParser\Node\Expr\Isset_ $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { $result = false; foreach ($expr->vars as $var) { if ($var instanceof VariableNode) { $varName = $var->name; if ($varName instanceof Name) { $varName = $varName->parts[0]; } $variable = $context->getSymbol($varName); if ($variable) { $variable->incUse(); if ($variable->getValue() !== null) { $result = true; continue; // this variable is set, continue } } return CompiledExpression::fromZvalValue(false); // one of the vars is not set } } return CompiledExpression::fromZvalValue($result); // if all are set return true, else false }
/** * @param Node\Expr\Variable $expr * @param mixed $value * @param int $type * @return CompiledExpression */ public function declareVariable(Node\Expr\Variable $expr, $value = null, $type = CompiledExpression::UNKNOWN) { $variable = $this->context->getSymbol($expr->name); if (!$variable) { $variable = new Variable($expr->name, $value, $type, $this->context->getCurrentBranch()); $this->context->addVariable($variable); } return new CompiledExpression($variable->getType(), $variable->getValue(), $variable); }
/** * $a * * @param \PhpParser\Node\Expr\Variable $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { $variable = $context->getSymbol($expr->name); if ($variable) { $variable->incGets(); return new CompiledExpression($variable->getType(), $variable->getValue(), $variable); } $context->notice('undefined-variable', sprintf('You are trying to use an undefined variable $%s', $expr->name), $expr); return new CompiledExpression(); }
/** * @param Node\Expr\Variable $expr * @return CompiledExpression */ protected function passExprVariable(Node\Expr\Variable $expr) { $variable = $this->context->getSymbol($expr->name); if ($variable) { $variable->incGets(); return new CompiledExpression($variable->getType(), $variable->getName()); } $this->context->notice('undefined-variable', sprintf('You trying to use undefined variable $%s', $expr->name), $expr); return new CompiledExpression(); }
/** * @param \PhpParser\Node\Expr\MethodCall $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { if ($expr->var instanceof Variable) { $symbol = $context->getSymbol($expr->var->name); if ($symbol) { switch ($symbol->getType()) { case CompiledExpression::OBJECT: case CompiledExpression::DYNAMIC: $symbol->incUse(); /** @var ClassDefinition $calledObject */ $calledObject = $symbol->getValue(); if ($calledObject instanceof ClassDefinition) { $methodName = is_string($expr->name) ? $expr->name : false; if ($expr->name instanceof Variable) { /** * @todo implement fetch from symbol table */ //$methodName = $expr->name->name; } if ($methodName) { if (!$calledObject->hasMethod($methodName, true)) { $context->notice('undefined-mcall', sprintf('Method %s() does not exist in %s scope', $methodName, $expr->var->name), $expr); //it's needed to exit return new CompiledExpression(); } $method = $calledObject->getMethod($methodName); if (!$method) { $context->debug('getMethod is not working'); return new CompiledExpression(); } if ($method->isStatic()) { $context->notice('undefined-mcall', sprintf('Method %s() is a static function but called like class method in $%s variable', $methodName, $expr->var->name), $expr); } return new CompiledExpression(); } return new CompiledExpression(); } /** * It's a wrong type or value, maybe it's implemented and We need to fix it in another compilers */ $context->debug('Unknown $calledObject - is ' . gettype($calledObject)); return new CompiledExpression(); } $context->notice('variable-wrongtype.mcall', sprintf('Variable $%s is not object\\callable and cannot be called like this', $expr->var->name), $expr); return new CompiledExpression(); } else { $context->notice('undefined-variable.mcall', sprintf('Variable $%s is not defined in this scope', $expr->var->name), $expr); return new CompiledExpression(); } } $expression = new Expression($context); $expression->compile($expr->var); $context->debug('Unknown method call'); return new CompiledExpression(); }
/** * @param Context $context */ public function preCompile(Context $context) { if ($this->statement->uses) { /** * Store variables from User to next restore Context */ foreach ($this->statement->uses as $variable) { $variable = $context->getSymbol($variable->var); if ($variable) { $variable->incGets(); $this->symbolTable->add(clone $variable); } } } }
/** * empty({expr]}) * * @param \PhpParser\Node\Expr\Empty_ $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { if ($expr->expr instanceof VariableNode) { $varName = $expr->expr->name; if ($varName instanceof Name) { $varName = $varName->parts[0]; } $variable = $context->getSymbol($varName); if ($variable) { $variable->incUse(); if ($variable->getValue() !== null && $variable->getValue() != false) { return CompiledExpression::fromZvalValue(true); } } } return CompiledExpression::fromZvalValue(false); }
protected function compileVariableDeclaration(CompiledExpression $variableName, CompiledExpression $value, Context $context) { switch ($variableName->getType()) { case CompiledExpression::STRING: break; default: $context->debug('Unexpected type of Variable name after compile'); return new CompiledExpression(); } $symbol = $context->getSymbol($variableName->getValue()); if ($symbol) { $symbol->modify($value->getType(), $value->getValue()); $context->modifyReferencedVariables($symbol, $value->getType(), $value->getValue()); } else { $symbol = new \PHPSA\Variable($variableName->getValue(), $value->getValue(), $value->getType(), $context->getCurrentBranch()); $context->addVariable($symbol); } $symbol->incSets(); }
/** * {expr} ?? {expr} * * @param \PhpParser\Node\Expr\BinaryOp\Coalesce $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { if ($expr->left instanceof Variable) { $varName = $expr->left->name; if ($varName instanceof Name) { $varName = $varName->parts[0]; } $variable = $context->getSymbol($varName); if ($variable) { $variable->incUse(); if ($variable->getValue() !== null) { $leftCompiled = $context->getExpressionCompiler()->compile($expr->left); return CompiledExpression::fromZvalValue($leftCompiled->getValue()); } } } $rightCompiled = $context->getExpressionCompiler()->compile($expr->right); return CompiledExpression::fromZvalValue($rightCompiled->getValue()); }
/** * {expr}++ * * @param \PhpParser\Node\Expr\PostDec $expr * @param Context $context * @return CompiledExpression */ public function compile($expr, Context $context) { if ($expr->var instanceof \PHPParser\Node\Expr\Variable) { $name = $expr->var->name; $variable = $context->getSymbol($name); if ($variable) { $variable->inc(); $variable->incUse(); return CompiledExpression::fromZvalValue($variable->getValue()); } } $expression = new Expression($context); $compiledExpression = $expression->compile($expr->var); switch ($compiledExpression->getType()) { case CompiledExpression::LNUMBER: case CompiledExpression::DNUMBER: $value = $compiledExpression->getValue(); return CompiledExpression::fromZvalValue($value++); } return new CompiledExpression(CompiledExpression::UNKNOWN); }
/** * {expr}-- * * @param \PhpParser\Node\Expr\PostDec $expr * @param Context $context * @return CompiledExpression */ protected function compile($expr, Context $context) { if ($expr->var instanceof \PHPParser\Node\Expr\Variable) { $variableName = $expr->var->name; if ($variableName instanceof Name) { $variableName = $variableName->parts[0]; } $variable = $context->getSymbol($variableName); if ($variable) { $variable->incUse(); switch ($variable->getType()) { case CompiledExpression::INTEGER: case CompiledExpression::DOUBLE: case CompiledExpression::NUMBER: $variable->dec(); return CompiledExpression::fromZvalValue($variable->getValue()); } $context->notice('language_error', 'You are trying to use post decrement operator on variable $' . $variableName . ' with type: ' . $variable->getTypeName(), $expr); } else { $context->notice('language_error', 'You are trying to use post decrement operator on undefined variable: ' . $variableName, $expr); } } return new CompiledExpression(); }