function tokenize()
 {
     while (($this->chunk = substr($this->code, $this->index)) !== FALSE) {
         $types = array('identifier', 'comment', 'whitespace', 'line', 'heredoc', 'string', 'number', 'regex', 'js', 'literal');
         foreach ($types as $type) {
             if ($d = $this->{$type . '_token'}()) {
                 $this->index += $d;
                 break;
             }
         }
     }
     $this->close_indentation();
     if (($tag = array_pop($this->ends)) !== NULL) {
         $this->error('missing ' . t_canonical($tag));
     }
     if ($this->options['rewrite']) {
         $rewriter = new Rewriter($this->tokens);
         $this->tokens = $rewriter->rewrite();
     }
     return $this->tokens;
 }
 function tag_postfix_conditionals()
 {
     $original = NULL;
     $self = $this;
     $condition = function ($token, $i) {
         return in_array($token[0], t('TERMINATOR', 'INDENT'));
     };
     $action = function ($token, $i) use(&$original, &$self) {
         if ($token[0] !== t('INDENT') || isset($token['generated']) && $token['generated'] && !(isset($token['fromThen']) && $token['fromThen'])) {
             $self->tokens[$original][0] = t('POST_' . t_canonical($self->tokens[$original][0]));
             // $original[0] = t('POST_'.t_canonical($original[0]));
         }
     };
     $self = $this;
     $this->scan_tokens(function (&$token, $i) use(&$original, &$condition, &$action, &$self) {
         if (!($token[0] === t('IF'))) {
             return 1;
         }
         $original = $i;
         // $original = & $token;
         $self->detect_end($i + 1, $condition, $action);
         return 1;
     });
 }
/**
 * Change a CoffeeScript PHP token tag to it's equivalent canonical form (the
 * form used in the JavaScript version).
 *
 * This function is used for testing purposes only.
 */
function t_canonical($token)
{
    static $map = array('ACCESSOR' => '.', 'ARRAY_START' => '[', 'ARRAY_END' => ']', 'AT_SIGN' => '@', 'BOUND_FUNC' => '=>', 'COLON' => ':', 'COMMA' => ',', 'DECREMENT' => '--', 'EQUALS' => '=', 'EXISTENTIAL' => '?', 'EXISTENTIAL_ACCESSOR' => '?.', 'FUNC' => '->', 'INCREMENT' => '++', 'MINUS' => '-', 'OBJECT_START' => '{', 'OBJECT_END' => '}', 'PAREN_START' => '(', 'PAREN_END' => ')', 'PLUS' => '+', 'PROTOTYPE' => '::', 'RANGE_EXCLUSIVE' => '...', 'RANGE_INCLUSIVE' => '..');
    if (is_array($token)) {
        if (is_array($token[0])) {
            foreach ($token as &$t) {
                $t = t_canonical($t);
            }
        } else {
            // Single token.
            $token[0] = t_canonical($token[0]);
            if (is_object($token[1])) {
                $str = "< {$token[1]} ";
                foreach ($token[1] as $k => $v) {
                    if ($k !== 'v' && $v) {
                        $str .= $k . ' ';
                    }
                }
                $token[1] = $str . '>';
            }
        }
        return $token;
    } else {
        if (is_numeric($token)) {
            $token = substr(Parser::tokenName($token), 3);
        } else {
            if (is_string($token)) {
                // The token type isn't known to the parser, so t() returned a unique
                // string to use instead.
                $token = substr($token, strlen('CoffeeScript\\Parser::YY_'));
            }
        }
    }
    return isset($map[$token]) ? $map[$token] : $token;
}