Zephir\Statements\Let\Incr::assign PHP Method

assign() public method

Compiles x++
public assign ( string $variable, Variable $symbolVariable, Zephir\CompilationContext $compilationContext, array $statement )
$variable string
$symbolVariable Zephir\Variable
$compilationContext Zephir\CompilationContext
$statement array
    public function assign($variable, ZephirVariable $symbolVariable, CompilationContext $compilationContext, $statement)
    {
        if (!$symbolVariable->isInitialized()) {
            throw new CompilerException("Cannot mutate variable '" . $variable . "' because it is not initialized", $statement);
        }
        if ($symbolVariable->isReadOnly()) {
            /**
             * @TODO implement increment of objects members
             */
            throw new CompilerException("Cannot mutate variable '" . $variable . "' because it is read only", $statement);
        }
        $codePrinter =& $compilationContext->codePrinter;
        switch ($symbolVariable->getType()) {
            case 'int':
            case 'uint':
            case 'long':
            case 'ulong':
            case 'double':
            case 'char':
            case 'uchar':
                $codePrinter->output($variable . '++;');
                break;
            case 'variable':
                /**
                 * Update non-numeric dynamic variables could be expensive
                 */
                if (!$symbolVariable->hasAnyDynamicType(array('undefined', 'long', 'double'))) {
                    $compilationContext->logger->warning('Possible attempt to increment non-numeric dynamic variable', 'non-valid-increment', $statement);
                }
                $compilationContext->headersManager->add('kernel/operators');
                if (!$symbolVariable->isLocalOnly()) {
                    $symbolVariable->separate($compilationContext);
                }
                $symbol = $compilationContext->backend->getVariableCode($symbolVariable);
                $codePrinter->output('zephir_increment(' . $symbol . ');');
                break;
            default:
                throw new CompilerException("Cannot increment: " . $symbolVariable->getType(), $statement);
        }
    }

Usage Example

Example #1
0
 /**
  * @param CompilationContext $compilationContext
  * @throws CompilerException
  */
 public function compile(CompilationContext $compilationContext)
 {
     $readDetector = new ReadDetector();
     $statement = $this->_statement;
     foreach ($statement['assignments'] as $assignment) {
         $variable = $assignment['variable'];
         /**
          * Get the symbol from the symbol table if necessary
          */
         switch ($assignment['assign-type']) {
             case 'static-property':
             case 'static-property-append':
             case 'static-property-array-index':
             case 'static-property-array-index-append':
             case 'dynamic-variable-string':
                 $symbolVariable = null;
                 break;
             case 'array-index':
             case 'variable-append':
             case 'object-property':
             case 'array-index-append':
             case 'string-dynamic-object-property':
             case 'variable-dynamic-object-property':
                 $symbolVariable = $compilationContext->symbolTable->getVariableForUpdate($variable, $compilationContext, $assignment);
                 break;
             default:
                 $symbolVariable = $compilationContext->symbolTable->getVariableForWrite($variable, $compilationContext, $assignment);
                 break;
         }
         /**
          * Incr/Decr assignments don't require an expression
          */
         if (isset($assignment['expr'])) {
             $expr = new Expression($assignment['expr']);
             switch ($assignment['assign-type']) {
                 case 'variable':
                     if (!$readDetector->detect($variable, $assignment['expr'])) {
                         if (isset($assignment['operator'])) {
                             if ($assignment['operator'] == 'assign') {
                                 $expr->setExpectReturn(true, $symbolVariable);
                             }
                         } else {
                             $expr->setExpectReturn(true, $symbolVariable);
                         }
                     } else {
                         if (isset($assignment['operator'])) {
                             if ($assignment['operator'] == 'assign') {
                                 $expr->setExpectReturn(true);
                             }
                         } else {
                             $expr->setExpectReturn(true);
                         }
                     }
                     break;
             }
             switch ($assignment['expr']['type']) {
                 case 'property-access':
                 case 'array-access':
                 case 'type-hint':
                     $expr->setReadOnly(true);
                     break;
             }
             $resolvedExpr = $expr->compile($compilationContext);
             /**
              * Bad implemented operators could return values different than objects
              */
             if (!is_object($resolvedExpr)) {
                 throw new CompilerException("Resolved expression is not valid", $assignment['expr']);
             }
         }
         /**
          * There are four types of assignments
          */
         switch ($assignment['assign-type']) {
             case 'variable':
                 $let = new LetVariable();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $readDetector, $compilationContext, $assignment);
                 break;
             case 'variable-append':
                 $let = new LetVariableAppend();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'object-property':
                 $let = new LetObjectProperty();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'variable-dynamic-object-property':
                 $let = new LetObjectDynamicProperty();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'string-dynamic-object-property':
                 $let = new LetObjectDynamicStringProperty();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'static-property':
                 $let = new LetStaticProperty();
                 $let->assignStatic($variable, $assignment['property'], $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'static-property-append':
                 $let = new LetStaticPropertyAppend();
                 $let->assignStatic($variable, $assignment['property'], $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'static-property-array-index':
                 $let = new LetStaticPropertyArrayIndex();
                 $let->assignStatic($variable, $assignment['property'], $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'static-property-array-index-append':
                 $let = new LetStaticPropertyArrayIndexAppend();
                 $let->assignStatic($variable, $assignment['property'], $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'array-index':
                 $let = new LetArrayIndex();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'array-index-append':
                 $let = new LetArrayIndexAppend();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'object-property-append':
                 $let = new LetObjectPropertyAppend();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'object-property-array-index':
                 $let = new LetObjectPropertyArrayIndex();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'object-property-array-index-append':
                 $let = new LetObjectPropertyArrayIndexAppend();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'incr':
                 $let = new LetIncr();
                 $let->assign($variable, $symbolVariable, $compilationContext, $assignment);
                 break;
             case 'decr':
                 $let = new LetDecr();
                 $let->assign($variable, $symbolVariable, $compilationContext, $assignment);
                 break;
             case 'object-property-incr':
                 $let = new LetObjectPropertyIncr();
                 $let->assign($variable, $assignment['property'], $symbolVariable, $compilationContext, $assignment);
                 break;
             case 'object-property-decr':
                 $let = new LetObjectPropertyDecr();
                 $let->assign($variable, $assignment['property'], $symbolVariable, $compilationContext, $assignment);
                 break;
             case 'dynamic-variable':
                 $let = new LetExportSymbol();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             case 'dynamic-variable-string':
                 $let = new LetExportSymbolString();
                 $let->assign($variable, $symbolVariable, $resolvedExpr, $compilationContext, $assignment);
                 break;
             default:
                 throw new CompilerException("Unknown assignment: " . $assignment['assign-type'], $assignment);
         }
     }
 }