Adds a branch prediction hint when evaluating an expression
Наследование: extends Zephir\Operators\BaseOperator
Пример #1
0
 /**
  * Resolves an expression
  *
  * @param CompilationContext $compilationContext
  * @return bool|CompiledExpression|mixed
  * @throws CompilerException
  */
 public function compile(CompilationContext $compilationContext)
 {
     $expression = $this->_expression;
     $type = $expression['type'];
     $compilableExpression = null;
     switch ($type) {
         case 'null':
             return new LiteralCompiledExpression('null', null, $expression);
         case 'int':
         case 'integer':
             return new LiteralCompiledExpression('int', $expression['value'], $expression);
         case 'long':
         case 'double':
         case 'bool':
             return new LiteralCompiledExpression($type, $expression['value'], $expression);
         case 'string':
             if (!$this->_stringOperation) {
                 if (ctype_digit($expression['value'])) {
                     return new CompiledExpression('int', $expression['value'], $expression);
                 }
             }
             return new LiteralCompiledExpression('string', str_replace(PHP_EOL, '\\n', $expression['value']), $expression);
         case 'istring':
             return new LiteralCompiledExpression('istring', str_replace(PHP_EOL, '\\n', $expression['value']), $expression);
         case 'char':
             if (!strlen($expression['value'])) {
                 throw new CompilerException("Invalid empty char literal", $expression);
             }
             if (strlen($expression['value']) > 2) {
                 if (strlen($expression['value']) > 10) {
                     throw new CompilerException("Invalid char literal: '" . substr($expression['value'], 0, 10) . "...'", $expression);
                 } else {
                     throw new CompilerException("Invalid char literal: '" . $expression['value'] . "'", $expression);
                 }
             }
             return new LiteralCompiledExpression('char', $expression['value'], $expression);
         case 'variable':
             $var = $compilationContext->symbolTable->getVariable($expression['value']);
             if ($var) {
                 if ($var->getRealName() == 'this') {
                     $var = 'this';
                 } else {
                     $var = $var->getName();
                 }
             } else {
                 $var = $expression['value'];
             }
             return new CompiledExpression('variable', $var, $expression);
         case 'constant':
             $compilableExpression = new Constants();
             break;
         case 'empty-array':
             return $this->emptyArray($expression, $compilationContext);
         case 'array-access':
             $compilableExpression = new NativeArrayAccess();
             $compilableExpression->setNoisy($this->isNoisy());
             break;
         case 'property-access':
             $compilableExpression = new PropertyAccess();
             $compilableExpression->setNoisy($this->isNoisy());
             break;
         case 'property-string-access':
         case 'property-dynamic-access':
             $compilableExpression = new PropertyDynamicAccess();
             $compilableExpression->setNoisy($this->isNoisy());
             break;
         case 'static-constant-access':
             $compilableExpression = new StaticConstantAccess();
             break;
         case 'static-property-access':
             $compilableExpression = new StaticPropertyAccess();
             break;
         case 'fcall':
             $functionCall = new FunctionCall();
             return $functionCall->compile($this, $compilationContext);
         case 'mcall':
             $methodCall = new MethodCall();
             return $methodCall->compile($this, $compilationContext);
         case 'scall':
             $staticCall = new StaticCall();
             return $staticCall->compile($this, $compilationContext);
         case 'isset':
             $compilableExpression = new IssetOperator();
             break;
         case 'fetch':
             $compilableExpression = new FetchOperator();
             break;
         case 'empty':
             $compilableExpression = new EmptyOperator();
             break;
         case 'array':
             $compilableExpression = new NativeArray();
             break;
         case 'new':
             $compilableExpression = new NewInstanceOperator();
             break;
         case 'new-type':
             $compilableExpression = new NewInstanceTypeOperator();
             break;
         case 'not':
             $compilableExpression = new NotOperator();
             break;
         case 'bitwise_not':
             $compilableExpression = new BitwiseNotOperator();
             break;
         case 'equals':
             $compilableExpression = new EqualsOperator();
             break;
         case 'not-equals':
             $compilableExpression = new NotEqualsOperator();
             break;
         case 'identical':
             $compilableExpression = new IdenticalOperator();
             break;
         case 'not-identical':
             $compilableExpression = new NotIdenticalOperator();
             break;
         case 'greater':
             $compilableExpression = new GreaterOperator();
             break;
         case 'less':
             $compilableExpression = new LessOperator();
             break;
         case 'less-equal':
             $compilableExpression = new LessEqualOperator();
             break;
         case 'greater-equal':
             $compilableExpression = new GreaterEqualOperator();
             break;
         case 'add':
             $compilableExpression = new AddOperator();
             break;
         case 'minus':
             $compilableExpression = new MinusOperator();
             break;
         case 'sub':
             $compilableExpression = new SubOperator();
             break;
         case 'mul':
             $compilableExpression = new MulOperator();
             break;
         case 'div':
             $compilableExpression = new DivOperator();
             break;
         case 'mod':
             $compilableExpression = new ModOperator();
             break;
         case 'and':
             $compilableExpression = new AndOperator();
             break;
         case 'or':
             $compilableExpression = new OrOperator();
             break;
         case 'bitwise_and':
             $compilableExpression = new BitwiseAndOperator();
             break;
         case 'bitwise_or':
             $compilableExpression = new BitwiseOrOperator();
             break;
         case 'bitwise_xor':
             $compilableExpression = new BitwiseXorOperator();
             break;
         case 'bitwise_shiftleft':
             $compilableExpression = new ShiftLeftOperator();
             break;
         case 'bitwise_shiftright':
             $compilableExpression = new ShiftRightOperator();
             break;
         case 'concat':
             $expr = new ConcatOperator();
             $expr->setExpectReturn($this->_expecting, $this->_expectingVariable);
             return $expr->compile($expression, $compilationContext);
         case 'irange':
             $compilableExpression = new RangeInclusiveOperator();
             break;
         case 'erange':
             $compilableExpression = new RangeExclusiveOperator();
             break;
         case 'list':
             if ($expression['left']['type'] == 'list') {
                 $compilationContext->logger->warning("Unnecessary extra parentheses", "extra-parentheses", $expression);
             }
             $numberPrints = $compilationContext->codePrinter->getNumberPrints();
             $expr = new Expression($expression['left']);
             $expr->setExpectReturn($this->_expecting, $this->_expectingVariable);
             $resolved = $expr->compile($compilationContext);
             if ($compilationContext->codePrinter->getNumberPrints() - $numberPrints <= 1) {
                 if (strpos($resolved->getCode(), ' ') !== false) {
                     return new CompiledExpression($resolved->getType(), '(' . $resolved->getCode() . ')', $expression);
                 }
             }
             return $resolved;
         case 'cast':
             $compilableExpression = new CastOperator();
             break;
         case 'type-hint':
             return $this->compileTypeHint($expression, $compilationContext);
         case 'instanceof':
             $compilableExpression = new InstanceOfOperator();
             break;
         case 'clone':
             $compilableExpression = new CloneOperator();
             break;
         case 'ternary':
             $compilableExpression = new TernaryOperator();
             break;
         case 'short-ternary':
             $expr = new ShortTernaryOperator();
             $expr->setReadOnly($this->isReadOnly());
             $expr->setExpectReturn($this->_expecting, $this->_expectingVariable);
             return $expr->compile($expression, $compilationContext);
         case 'likely':
             if (!$this->_evalMode) {
                 throw new CompilerException("'likely' operator can only be used in evaluation expressions", $expression);
             }
             $expr = new LikelyOperator();
             $expr->setReadOnly($this->isReadOnly());
             return $expr->compile($expression, $compilationContext);
         case 'unlikely':
             if (!$this->_evalMode) {
                 throw new CompilerException("'unlikely' operator can only be used in evaluation expressions", $expression);
             }
             $expr = new UnlikelyOperator();
             $expr->setReadOnly($this->isReadOnly());
             return $expr->compile($expression, $compilationContext);
         case 'typeof':
             $compilableExpression = new TypeOfOperator();
             break;
         case 'require':
             $compilableExpression = new RequireOperator();
             break;
         case 'closure':
             $compilableExpression = new Closure();
             break;
         case 'closure-arrow':
             $compilableExpression = new ClosureArrow();
             break;
         case 'reference':
             $compilableExpression = new Reference();
             break;
         default:
             throw new CompilerException("Unknown expression: " . $type, $expression);
     }
     if (!$compilableExpression) {
         throw new CompilerException("Unknown expression passed as compilableExpression", $expression);
     }
     $compilableExpression->setReadOnly($this->isReadOnly());
     $compilableExpression->setExpectReturn($this->_expecting, $this->_expectingVariable);
     return $compilableExpression->compile($expression, $compilationContext);
 }