Esempio n. 1
0
 /**
  * @param array $expression
  * @param CompilationContext $compilationContext
  * @param boolean $isFullString
  */
 private function _getOptimizedConcat($expression, CompilationContext $compilationContext, &$isFullString)
 {
     $originalExpr = $expression;
     $isFullString = true;
     $parts = array();
     while ($expression && isset($expression['left'])) {
         $parts[] = $expression['right'];
         if ($expression['left']['type'] == 'concat') {
             $expression = $expression['left'];
         } else {
             $parts[] = $expression['left'];
             $expression = null;
         }
     }
     if ($expression) {
         $parts[] = $expression['right'];
         $parts[] = $expression['left'];
     }
     $key = '';
     $concatParts = array();
     $parts = array_reverse($parts);
     foreach ($parts as $part) {
         $expr = new Expression($part);
         $expr->setStringOperation(true);
         switch ($part['type']) {
             case 'array-access':
             case 'property-access':
                 $expr->setReadOnly(true);
                 break;
             default:
                 $expr->setReadOnly($this->_readOnly);
                 break;
         }
         $compiledExpr = $expr->compile($compilationContext);
         switch ($compiledExpr->getType()) {
             case 'variable':
                 $variable = $compilationContext->symbolTable->getVariableForRead($compiledExpr->getCode(), $compilationContext, $originalExpr);
                 switch ($variable->getType()) {
                     case 'variable':
                         $key .= 'v';
                         $concatParts[] = $variable->getName();
                         $isFullString = false;
                         break;
                     case 'string':
                         $key .= 'v';
                         $concatParts[] = $variable->getName();
                         break;
                     case 'int':
                     case 'long':
                         $key .= 'v';
                         $tempVariable = $compilationContext->symbolTable->getTempLocalVariableForWrite('variable', $compilationContext, $originalExpr);
                         $compilationContext->codePrinter->output('ZVAL_LONG(&' . $tempVariable->getName() . ', ' . $compiledExpr->getCode() . ');');
                         $concatParts[] = '&' . $tempVariable->getName();
                         break;
                     default:
                         throw new CompilerException("Variable type: " . $variable->getType() . " cannot be used in concat operation", $compiledExpr->getOriginal());
                 }
                 break;
             case 'string':
                 $key .= 's';
                 $concatParts[] = '"' . $compiledExpr->getCode() . '"';
                 break;
             default:
                 throw new CompilerException("Variable type: " . $compiledExpr->getType() . " cannot be used in concat operation", $compiledExpr->getOriginal());
         }
     }
     $compilationContext->stringsManager->addConcatKey($key);
     return array($key, join(', ', $concatParts));
 }