public function advance($parser)
 {
     if ($this->pos >= 0) {
         $type = $this->tokens[$this->pos][0];
         switch ($type) {
             case T_FOR:
             case T_FOREACH:
                 $this->start_loop();
                 break;
             case T_DO:
                 $this->ignoreNextWhile = true;
                 $this->start_loop();
                 break;
             case T_WHILE:
                 if (!$this->ignoreNextWhile) {
                     $this->start_loop();
                 }
                 $this->ignoreNextWhile = false;
                 break;
             case T_SWITCH:
             case T_TRY:
                 $this->start_cond();
                 break;
             case T_IF:
                 if (!$this->lastWasElse) {
                     $this->start_cond();
                 } else {
                     // count the number of "T_ELSE T_IF" because for each of those we get another call
                     // to end_cond()
                     $this->vars->set_elseif();
                 }
                 break;
             case T_ELSEIF:
                 $this->start_cond(true, false);
                 break;
             case T_ELSE:
                 $this->start_cond(true, true);
                 break;
         }
         $this->lastWasElse = $type == T_ELSE;
     }
     $res = parent::advance($parser);
     if ($this->lastComment && $this->lastComment != $this->lastCheckComment) {
         // it was a comment, so lets see if it contains a "@var $<name> <type>" that gives us a
         // hint what type a variable has.
         $matches = array();
         if (preg_match('/\\@var\\s+\\$([a-z0-9_]+)\\s+(\\S+)/i', $this->lastComment, $matches)) {
             // do we know that variable?
             $scopename = $this->scope->get_name();
             if ($this->vars->exists($scopename, $matches[1])) {
                 // ok, determine type and set it
                 $type = PC_Obj_MultiType::get_type_by_name($matches[2]);
                 $var = $this->vars->get($scopename, $matches[1]);
                 $var->set_type($type);
             }
         }
         $this->lastCheckComment = $this->lastComment;
     }
     return $res;
 }
 /**
  * Changes the variable with given name in the current scope
  * 
  * @param string $file the current file
  * @param int $line the current line
  * @param PC_Engine_Scope $scope the current scope
  * @param array $layer the current layer
  * @param string $name the var-name
  * @param PC_Obj_Variable $backup the backup (0 if not present before the layer)
  * @param bool $present whether its present in all blocks in this layer
  */
 private function change_var($file, $line, $scope, $layer, $name, $backup, $present)
 {
     $scopename = $scope->get_name();
     // if its present in all blocks, merge the types
     if ($present) {
         // start with the type in scope; thats the one from the last block
         $mtype = $this->vars[$scopename][$name]->get_type();
         // don't include the first block since thats the backup from the previous layer
         for ($i = 1; $i <= $layer['blockno']; $i++) {
             $mtype->merge($layer['vars'][$i][$name]->get_type());
         }
         // note that this may discard the old value, if the variable was present
         $this->vars[$scopename][$name] = new PC_Obj_Variable($file, $line, $name, $mtype, $scope->get_name_of(T_FUNC_C), $scope->get_name_of(T_CLASS_C));
     } else {
         if ($backup !== 0) {
             $mtype = $this->vars[$scopename][$name]->get_type();
             for ($i = 0; $i <= $layer['blockno']; $i++) {
                 if (isset($layer['vars'][$i][$name])) {
                     $mtype->merge($layer['vars'][$i][$name]->get_type());
                 }
             }
         } else {
             if (!isset($this->vars[$scopename][$name])) {
                 $this->vars[$scopename][$name] = new PC_Obj_Variable($file, $line, $name, new PC_Obj_MultiType(), $scope->get_name_of(T_FUNC_C), $scope->get_name_of(T_CLASS_C));
             } else {
                 $this->vars[$scopename][$name]->set_type(new PC_Obj_MultiType());
             }
         }
     }
     // if there is a previous layer and the var is not known there in the last block, put
     // the first backup from this block in it. because this is the previous value for the previous
     // block, if it hasn't been assigned there
     if (count($this->layers) > 0) {
         $prevlayer =& $this->layers[count($this->layers) - 1];
         if (!isset($prevlayer['vars'][$prevlayer['blockno']][$name])) {
             $prevlayer['vars'][$prevlayer['blockno']][$name] = $backup;
         }
     }
 }