Location: PHPKode > scripts > Logo Interpreter > logo-interpreter/class.logo.parser.php
<?php

  // License: GNU General Public License (GPL) 
  // class.logo.parser.php
  // @ver 0.1

  // Author: Zhihua Lai
  // Example URL: http://www.zhihua-lai.com/?do=Crap.Logo

	// Include necessary files
	
	@include_once("logo.php");
	@include_once("util.php");
	@include_once("class.storage.php");

  // Constants Definition
  	
  	define("LOGO_OK_PROC_RETURN",-1);
  	define("LOGO_OK",0);
  	define("LOGO_ERROR_UNFINISHED_COMMENTS",1);
  	define("LOGO_ERROR_MISSING_COMMAND",2);
  	define("LOGO_WARNING_NOT_FULLY_IMPLEMENTED",3);
  	define("LOGO_WARNING_NUMBER_ROUNDED",4);
  	define("LOGO_ERROR_MISSING_ARG",5);
  	define("LOGO_ERROR_BAD_COMMAND",6);
  	define("LOGO_WARNING_UNSUPPORTED_BG_CHANGE",7);
  	define("LOGO_ERROR_NO_REPEAT_TIME",8);
  	define("LOGO_ERROR_UNSUPPORTED_GROUP_ACTION",9);
    define("LOGO_ERROR_TOO_MANY_LEFT",10);
  	define("LOGO_ERROR_TOO_MANY_RIGHT",11);
  	define("LOGO_INFORMATION_TOO_MANY_WARNING",12);
  	define("LOGO_ERROR_TIME_OUT",13);
  	define("LOGO_WARNING_MISSING_REPEAT_BODY",14);
  	define("LOGO_ERROR_STOP_NOT_IN_PROC",15);
  	define("LOGO_ERROR_END_NOT_FOUND",16);
  	define("LOGO_ERROR_KEYWORD_IN_USE",17);
  	define("LOGO_ERROR_NESTED_PROCEDURE_NOT_ALLOWED",18);
  	define("LOGO_ERROR_INVALID_PROC_NAME",19);
  	define("LOGO_ERROR_PROC_DEFINED",20);
  	define("LOGO_ERROR_NO_TO",21);
  	define("LOGO_ERROR_INVALID_SYMBOL",22);
  	define("LOGO_ERROR_TOO_MANY_PROC",23);
  	define("LOGO_WARNING_TURTLE_OUT",24);
  	define("LOGO_ERROR_REPEAT_PROC_ARG",25);
  	define("LOGO_ERROR_TOO_MANY_LEVELS",26);
  	define("LOGO_WARNING_LOCAL_MAKE_GLOBALUSE",27);
  	define("LOGO_ERROR_MAKE_NEED_QUOTE",28);
  	define("LOGO_ERROR_MAKE_INVALID_NAME",29);
  	define("LOGO_ERROR_MAKE_INVALID_VALUE",30);
  	define("LOGO_ERROR_UNKNOWN_GROUP",31);
  	define("LOGO_ERROR_MISSING_BOOLEAN",32);


  // Interpreter Class	
  	
	class LogoParser
	{	
	  var $_logo;
	  var $_s;
	  var $_vars;
	  var $_makevars;
    var $_localmake=array();
	  var $_coms=array();
	  var $_args=array();
	  var $_lineX;
	  var $_lineY;
	  var $_warnings=array();
	  var $_lineW;
	  var $_maxW;
	  var $_repeat=array();
	  var $_repeatT=array();
	  var $_maxT;
    var $_runningT;
    var $_maxProcLevel;
    var $_endT;
    var $_maxProc;
    var $_inProc;
    var $_rlvl;
    var $_to_names=array();
    var $_to_start=array();
    var $_to_end=array();
    var $_to_args=array();
    var $_to_counting_args;
    var $_var_stack=array();
    var $_src_line;
    
    var $_runningProc=array();
    
    
    var $Logo_Color_R=array(0,0,0,0,255,255,255,255,155,197,100,120,255,144,255,183);
    var $Logo_Color_G=array(0,0,255,255,0,0,255,255,96,136,162,187,149,113,163,183);
    var $Logo_Color_B=array(0,255,0,255,0,255,0,255,59,18,64,187,119,208,0,183);
    var $_keywords_args=array(
             "FORWARD","FD",
             "BACK","BK",
             "RIGHT","RT",
             "LEFT","LT",
             "SETPC","SETPENCOLOR","SETPENCOLOUR",
             "SETSCREENCOLOR","SETSC","SETSCREENCOLOUR",
             "REPEAT",
             "SETXY","SETPOS",
             "SETX",
             "SETY",
             "TO",
             "ARC",
             "MAKE",
             "LOCALMAKE",
             "LOCAL",
             "IF",
             //"IFELSE",
             "SETFC","SETFLOODCOLOR","SETFLOODCOLOUR"
      );
      
      var $_keywords=array(
            "HT","HIDETURTLE",
            "ST","SHOWTURTLE",
            "PU","PENUP",
            "PD","PENDOWN",
            "CS","CLEANSCREEN",
            "HOME",
            "FENCE",
            "WINDOW",
            "WRAP",
            "FILL",
            "END",
            "STOP"
      );
      
    
    /* Constructor */
    function LogoParser(&$lgo, $s="")
    {
      $this->_logo=&$lgo;
      $this->_lineX=0;
      $this->_lineY=0;
      $this->_lineW="";
      $this->_maxW=5;
      $this->_maxT=3;
      $this->_maxProcLevel=200;
      $this->_maxProc=200;
      $this->_inProc=false;
      $this->_rlvl=0;
      $this->_to_counting_args=false;
      $this->_makevars=new Storage();
      $this->_vars=new Storage();
      $this->_vars->_setVar("SCREENCOLOUR",($lgo->getSC()));
      $this->_vars->_setVar("FLOODCOLOUR",($lgo->getFC()));
      $this->_vars->_setVar("PENCOLOUR",($lgo->getPC()));
      $this->_vars->_setVar("SCREENCOLOR",($lgo->getSC()));
      $this->_vars->_setVar("FLOODCOLOR",($lgo->getFC()));
      $this->_vars->_setVar("PENCOLOR",($lgo->getPC()));
      $this->_vars->_setVar("PI",pi());
      $this->_vars->_setVar("WIDTH", $lgo->getImageX());
      $this->_vars->_setVar("HEIGHT", $lgo->getImageY());
      $this->_vars->_setVar("MAXX", $lgo->getImageHX());
      $this->_vars->_setVar("MAXY", $lgo->getImageHY());
      $this->_vars->_setVar("MINX", -$lgo->getImageHX());
      $this->_vars->_setVar("MINY", -$lgo->getImageHY());
      $this->_vars->_setVar("ISTRUECOLOR", $lgo->isTrueColor()?1:0);
    	$this->_vars->_setVar("LOGO_BLACK",0);
    	$this->_vars->_setVar("LOGO_BLUE",1);
    	$this->_vars->_setVar("LOGO_GREEN",2);
    	$this->_vars->_setVar("LOGO_CYAN",3);
    	$this->_vars->_setVar("LOGO_RED",4);
    	$this->_vars->_setVar("LOGO_MAGENTA",5);
    	$this->_vars->_setVar("LOGO_YELLOW",6);
    	$this->_vars->_setVar("LOGO_WHITE",7);
    	$this->_vars->_setVar("LOGO_BROWN",8);
    	$this->_vars->_setVar("LOGO_LIGHT_BROWN",9);
    	$this->_vars->_setVar("LOGO_MID_GREEN",10);
    	$this->_vars->_setVar("LOGO_BLUE_GREEN",11);
    	$this->_vars->_setVar("LOGO_SALMON",12);
    	$this->_vars->_setVar("LOGO_BLUE_ISH",13);
    	$this->_vars->_setVar("LOGO_ORANGE",14);
    	$this->_vars->_setVar("LOGO_SILVER",15);
    	$this->_vars->_setVar("POSX",0);
    	$this->_vars->_setVar("POSY",0);
    	$this->_vars->_setVar("DEGREE",0);
    }
    
    function setMaxTimeout($d)
    {
      $d=(integer)$d;
      if ($d<1) $d=1;
      if ($d>5) $d=5;
      $this->_maxT=$d;
    }
    
    function getMaxTimeout()
    {
      return ($this->_maxT);
    }
    
	  function getMsg($code, $x=0, $y=0, $w="")
	  {
      $code=(integer)$code;
      $m="";
      switch ($code)
      {
        case LOGO_OK:
        case LOGO_OK_PROC_RETURN: $m="OK - EXECUTED"; break;
        case LOGO_ERROR_UNFINISHED_COMMENTS: $m="ERROR - UNFINISHED COMMENTS"; break;
        case LOGO_ERROR_MISSING_COMMAND: $m="ERROR - MISSING COMMAND"; break;
        case LOGO_WARNING_NUMBER_ROUNDED: $m="WARNING - FLOAT ROUNDED AS INTEGER"; break;
        case LOGO_ERROR_MISSING_ARG: $m="ERROR - MISSING ARGUMENTS"; break;
        case LOGO_ERROR_BAD_COMMAND: $m="ERROR - UNKNOWN COMMAND OR PROCEDURE"; break;
        case LOGO_WARNING_UNSUPPORTED_BG_CHANGE: $m="WARNING - UNABLE TO CHANGE SCREEN COLOR IN PROCESS"; break;
        case LOGO_ERROR_TOO_MANY_LEFT: $m="ERROR - MISSING ']'"; break;
        case LOGO_ERROR_TOO_MANY_RIGHT: $m="ERROR - MISSING '['"; break;
        case LOGO_INFORMATION_TOO_MANY_WARNING: $m="MSG - TOO MANY WARNINGS, THE REST IGNORED"; break;
        case LOGO_ERROR_TIME_OUT: $m="ERROR - TIME OUT"; break;
        case LOGO_WARNING_MISSING_REPEAT_BODY: $m="WARNING - MISSING A GROUP STATMENT"; break;
        case LOGO_WARNING_NOT_FULLY_IMPLEMENTED: $m="WARNING - NOT FULLY IMPLEMENTED"; break;
        case LOGO_ERROR_STOP_NOT_IN_PROC: $m="ERROR - CAN ONLY USE STOP IN PROCEDURE"; break;
        case LOGO_ERROR_END_NOT_FOUND: $m="ERROR - NEED A 'END' TO FINISH DEFINITION OF 'TO'";break;
        case LOGO_ERROR_KEYWORD_IN_USE: $m="ERROR - PROCEDURE NAME IS A RESERVED KEYWORD"; break;
        case LOGO_ERROR_NESTED_PROCEDURE_NOT_ALLOWED: $m="ERROR - NESTED PROCEDURE NOT ALLOWED"; break;
        case LOGO_ERROR_INVALID_PROC_NAME: $m="ERROR - INVALID PROCEDURE NAME"; break;
        case LOGO_ERROR_PROC_DEFINED: $m="ERROR - PROCEDURE CAN NOT BE RE-DEFINED"; break;
        case LOGO_ERROR_NO_TO: $m="ERROR - CANNOT FIND 'TO' TO START DEFINING PROCEDURE"; break;
        case LOGO_ERROR_INVALID_SYMBOL: $m="ERROR - NOT A VALID PROCEDURE NAME"; break;
        case LOGO_ERROR_TOO_MANY_PROC: $m="ERROR - EXCEED MAXIMUM ".$this->_maxProc." DEFINED PROCEDURES "; break;
        case LOGO_WARNING_TURTLE_OUT: $m="WARNING - TURTLE IS OUT OF BOUND"; break;
        case LOGO_ERROR_REPEAT_PROC_ARG: $m="ERROR - DUPLICATION OF PROCEDURE ARGUMENTS"; break;
        case LOGO_ERROR_TOO_MANY_LEVELS: $m="ERROR - TOO MANY LEVELS OF PROCEDURE"; break;
        case LOGO_WARNING_LOCAL_MAKE_GLOBALUSE: $m="WARNING - LOCALMAKE GLOBALLY USE (NOT DELETED)"; break;
        case LOGO_ERROR_MAKE_NEED_QUOTE: $m="ERROR - MAKE VARIABLE NEEDS DOUBLE QUOTA"; break;
        case LOGO_ERROR_MAKE_INVALID_NAME: $m="ERROR - MAKE VARIABLE IS NOT A VALID KEYWORD"; break;
        case LOGO_ERROR_MAKE_INVALID_VALUE: $m="ERROR - MAKE DOES NOT HAVE A VALID VALUE"; break;
        case LOGO_ERROR_UNKNOWN_GROUP: $m="ERROR - UNKNOWN ACTION TO START A GROUP '['"; break;
        case LOGO_ERROR_NO_REPEAT_TIME: $m="ERROR - NO ENOUGH INPUT TO REPEAT"; break;
        case LOGO_ERROR_UNSUPPORTED_GROUP_ACTION: $m="ERROR - UNSUPPORTED GROUP ACTION"; break;
        case LOGO_ERROR_MISSING_BOOLEAN: $m="ERROR - IF STATEMENT MISSING BOOLEAN EXPRESSION"; break;
        default: $m="ERROR - UNKNOWN REASONS FAILED THE PROCESS";break;
      }
      $s="";
      $extra="";
      if (strlen($w)>8) $w=substr($w,0,8).'[..]';
      if ($x&&$y)
      {
        if ($w)
        {
          $extra=" - ('".$w."')";
        }
        $s=$m."$extra AT ROW ".$y." COL ".$x;            
      }
      else
      {
        if ($this->_lineW)
        {
          $extra=" - ( '".$this->_lineW."' )";
        }
        $s=$m."$extra AT ROW ".$this->_lineY." COL ".$this->_lineX;      
      }
      if (($this->_src_line)&&($code!=LOGO_OK))
      {
        $extra=" (__LINE__:".$this->_src_line.")";
      }
      return ($s.$extra);
    }
    
    function getMemAndTime()
    {
      return ("[IN ".$this->_endT." SECONDS, ".(memory_get_usage())." BYTES ALLOCATED]");
    }

    function isSymbol($s)
    {
      if (strlen($s)==0) return (false);
      if (isDigit($s{0})) return (false);
      if (($s{0}=="'")||($s{0}=='"')||($s{0}==":")) return (false);
      $i=1;
      while ((isChar($s{$i}))||(isDigit($s{$i}))||($s{$i}=='_')) { $i++; }
      return ($i>=strlen($s));
    }
    
    function isGood($s)
    {
      return ( ($this->isSymbol($s)) && (!in_array($s, $this->_keywords))
              &&(!in_array($s, $this->_keywords_args)) 
              &&(!in_array($s, $this->_to_names))
               );
    }
    
    function str2num($str, &$changes)
    {
      $t=$str;
      $changes=true;
      $str = preg_replace('`([^+\-*=/\(\)0-9<>&|\.%]*)`','',$str);
      if (strlen($str)==0)
      {
        $str = '0';
      }
      else
      {
        if (strlen($t)==strlen($str))
        {
          eval("\$str = $str;");
          $changes=false;
        }
        else
        {
          $str = '0';
        }
      }
      return $str;
    }

    function isNumber($s, &$realnum, &$value)
    {
      if (strpos($s, "==")===false)
      {
        $s=str_replace("=","==",$s);
      }
      foreach ($this->_vars->keys() as $keys)
      {
        $s=str_replace(":".$keys, $this->_vars->getVar($keys), $s);
      }
      $s=str_replace($this->_vars->keys(), $this->_vars->values(), $s);
      if (count($this->_runningProc))
      {
        $procVarIdx=array_search($this->_runningProc[count($this->_runningProc)-1], $this->_to_names);
        foreach ($this->_to_args[$procVarIdx]->keys() as $key)
        {
          $s=str_replace(":".$key, $this->_to_args[$procVarIdx]->getVar($key), $s);
        }
      }
      foreach ($this->_makevars->keys() as $keys)
      {
        $s=str_replace(":".$keys, $this->_makevars->getVar($keys), $s);
      }
      $s=str_replace("RANDOMNUMBER0_100",mt_rand(0,100), $s);
      $value=$this->str2num($s, &$c);
      $realnum=false;
      if (!$c)
      {
        $realnum=is_float($value);
        //$value=$value;
        return (true);
      }
      $value=(integer)$value;
      return (false);
    }
    
    function getNextWord(&$s, $i, $U, &$j)
    {
      $t="";
      while (isSpace($s{$i})) { $i++; }
      if ($i>=$U) 
      {
        $j=$i;
        return ("");
      }
      if (($s{$i}=="[") || ($s{$i}=="]"))
      {
        $j=$i;
        return ($s{$i});
      }
      if ($s{$i}==";")
      {
        $j=$i;
        return ($s{$i});
      }
      while ( ( (!isSpace($s{$i})) && ($i<$U) ) &&
              ($s{$i}!="[") && ($s{$i}!="]") && 
              ($s{$i}!=";") && 
              ( !(($s{$i}=="/")&&($s{$i+1}=="/")) ) &&
              ( !(($s{$i}=="/")&&($s{$i+1}=="*")) )
            )
      {
        $t.=$s{$i};
        $i++;
      }
      $j=$i-1;
      if ($i>=$U) $j=$i;
      return ($t);
    }
    
    
    function printWarnings()
    {
      $i=0;
      $j=-$this->_logo->getImageHY();
      $t=1;
      while ($i<count($this->_warnings))
      {
        $j+=$this->_logo->printText(-$this->_logo->getImageHX(), $j, 
                          $this->getMsg($this->_warnings[$i],
                                        $this->_warnings[$i+1],
                                        $this->_warnings[$i+2],
                                        $this->_warnings[$i+3])
                          );
        $t++;
        if ($t>$this->_maxW)
        {
          $j+=$this->_logo->printText(-$this->_logo->getImageHX(), $j, 
                            $this->getMsg(LOGO_INFORMATION_TOO_MANY_WARNING)
                            );     
          break;     
        }
        $i+=4;
      }
      return ($this->_logo->getIYd($j));
    }
    
    function pushWarn($code, $x, $y, $w)
    {
      $t=(integer)(((count($this->_warnings)+1)/4)-1);
      if ($t>$this->_maxW)
      {
        return;
      }
      $same=false;
      for ($i=0;$i<count($this->_warnings);$i+=4)
      {
        if (  ($code==$this->_warnings[$i]) && 
              ($x==$this->_warnings[$i+1]) &&
              ($y==$this->_warnings[$i+2])
           )
        {
          $same=true;
          break;
        }
      }
      if (!$same)
      {
        array_push($this->_warnings, $code, $x, $y, $w);
      }
    }
    
    function getX()
    {
      return ($this->_lineX);
    }
    
    function getY()
    {
      return ($this->_lineY);
    }
    
    function getW()
    {
      return ($this->_lineW);
    }
    
    function _getXY(&$s, $d, $w="")
    {
      $i=0;
      $x=0;
      $j=1;
      while ($i<$d)
      {
        $x++;
        if (($s{$i}=="\n"))
        {
          $j++;
          $x=0;
        }
        $i++;
      }
      $this->_lineX=$x+1;
      $this->_lineY=$j;
      $this->_lineW=$w;
    }
    
    function removeLocalVars()
    {
      $k=array_search($this->_runningProc[count($this->_runningProc)-1], $this->_to_names);
      $s=$this->_localmake;
      foreach ($s as $key=>$v)
      {
        if ($v[0]==$this->_to_names[$k])
        {
          $this->_to_args[$k]->delVar($v[1]);
          unset($this->_localmake[$key]);
        }
      }
    }
    
    function _parse(&$s, $i=0, $U=0)
    {  
      if ($U<=0)
      {
        $U=strlen($s);
      }
      
      if ($i>=$U) return (LOGO_OK);
      
      $i--;
      while ($i<$U)
      {
        /* Check if Time Out */
        $this->_endT=abs(round(microtime()-$this->_runningT,5));
        if ($this->_endT>$this->_maxT)
        {
          $this->_getXY(&$s, $i+1);
          $this->_src_line=__LINE__;
          return (LOGO_ERROR_TIME_OUT);          
        }
        
        $i++;
        if ($i>=$U)
        {
          break;
        } 
        
        /* Skip Spaces */
        if (isSpace($s{$i})) continue;

        /* Comments Start */
        if (($s{$i}=="/")&&($s{$i+1}=="*"))
        {
          $i+=2;
          while ( ($i<$U) &&
                  !(($s{$i}=="*")&&($s{$i+1}=="/"))
                )
          { 
            $i++;
          }
          if (($s{$i}=="*")&&($s{$i+1}=="/"))
          {
            $i+=1;
            continue;
          }
          else
          {
            $this->_getXY(&$s, $i);
            $this->_src_line=__LINE__;
            return (LOGO_ERROR_UNFINISHED_COMMENTS);
          }
        }
        if (($s{$i}=="/")&&($s{$i+1}=="/"))
        {
          $i+=2;
          while (($i<$U)&&($s{$i}!="\n")) { $i++; }
          if ($s{$i}=="\n")
          {
            continue;
          }
          break;
        }
        if (($s{$i}==";")||($s{$i}=="#"))
        {
          $i++;
          while (($i<$U)&&($s{$i}!="\n")) { $i++; }
          if ($s{$i}=="\n")
          {
            continue;
          }
          break;
        }
        /* Coments Ends */
        
        /* Group */
        if (!$this->_inProc)
        {
          
          if ($s{$i}=="[")
          {
            if (count($this->_coms)==0)
            {
              $this->_getXY(&$s, $i);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_UNKNOWN_GROUP);            
            }
            array_push($this->_repeat, $i);
            continue;
          }
          
          if ($s{$i}=="]")
          {
            if (count($this->_repeat)==0)
            {
              $this->_getXY(&$s, $i);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_TOO_MANY_RIGHT);                     
            }
            $groupstart=array_pop($this->_repeat);
            if (count($this->_repeat))
            {
              continue;
            }
            $k=array_pop($this->_coms);
            if (($k=="REPEAT"))
            {
              if (count($this->_repeatT)==0)
              {
                $this->_getXY(&$s, $i);
                $this->_src_line=__LINE__;
                return (LOGO_ERROR_NO_REPEAT_TIME);              
              }
              $lastRT=array_pop($this->_repeatT);
              for ($tt=0;$tt<round($lastRT);$tt++)
              {
                $t=$this->_parse(&$s, $groupstart+1, $i);
                if ($t!=LOGO_OK) break;
              }
              if ($t==LOGO_OK_PROC_RETURN)
              {
                if ($this->_rlvl==0)
                {
                  $this->_rlvl=1;
                  return ($t);
                }
                continue;
              }
              if (($t==LOGO_OK))
                continue;
              else
                return ($t);
            }
            else
            if ($k=="IF")
            {
              if (count($this->_repeatT)==0)
              {
                $this->_getXY(&$s, $i);
                $this->_src_line=__LINE__;
                return (LOGO_ERROR_MISSING_BOOLEAN);              
              }
              $lastRT=array_pop($this->_repeatT);
              if ($lastRT>0)
              {
                $lastRT=1;
              }
              else
              {
                $lastRT=0;
              }
              for ($tt=0;$tt<round($lastRT);$tt++)
              {
                $t=$this->_parse(&$s, $groupstart+1, $i);
                if ($t!=LOGO_OK) break;
              }
              if ($t==LOGO_OK_PROC_RETURN)
              {
                if ($this->_rlvl==0)
                {
                  $this->_rlvl=1;
                  return ($t);
                }
                continue;
              }
              if (($t==LOGO_OK))
                continue;
              else
                return ($t);            
            }
            $this->_getXY(&$s, $i);
            $this->_src_line=__LINE__;
            return (LOGO_ERROR_UNSUPPORTED_GROUP_ACTION);              
          }
          
          /* Skip parsing until complete group statement */
          if (count($this->_repeat))
          {
            continue;
          }
          
        } // Not _inProc
        
        /* Get a word */
        $w=(strtoupper($this->getNextWord(&$s, $i, $U, &$j)));   
        if (strlen($w)==0)
        {
          break;
        }
        
        if ($this->_inProc)
        {
          if ($w=="TO")
          {
            $this->_getXY(&$s, $i);
            $this->_src_line=__LINE__;
            return (LOGO_ERROR_NESTED_PROCEDURE_NOT_ALLOWED);
          }
          else
          if ($w=="END")
          {
            $this->_inProc=false;
            array_push($this->_to_end,$i);
            $i=$j;
            $this->_to_counting_args=false;
            continue;
          }
          else
          {
            if ($this->_to_counting_args)
            {
              if (($w{0}==":")&&($this->isGood(substr($w,1))))
              {
                if (count($this->_to_args)==0)
                {
                  array_push($this->_to_args, new Storage());
                }
                if ($this->_to_args[count($this->_to_args)-1]->isVar(substr($w,1)))
                {
                  $this->_getXY(&$s, $i);
                  $this->_src_line=__LINE__;
                  return (LOGO_ERROR_REPEAT_PROC_ARG);
                }
                else
                {
                  $this->_to_args[count($this->_to_args)-1]->_setVar(substr($w,1), 0);
                }
              }
              else
              {
                $this->_to_counting_args=false;
              }
            }
            $i=$j;
            continue;
          }
        } // Not _inProc
        else
        {
          if ($w=="END")
          {
            $this->_getXY(&$s, $i);
            $this->_src_line=__LINE__;
            return (LOGO_ERROR_NO_TO);            
          }
        }
  /*      
        if (count($this->_repeatT)>0)
        {
          if (($w=="REPEAT")||($w=="IF"))
          {
            array_push($this->_repeatT,-1);
          }
          $i=$j;
          continue;
        }
        
   */
   
        if (count($this->_coms)>0)
        {
          $k=array_pop($this->_coms);
          if ($k=="TO")
          {
            if (  in_array($w, $this->_keywords) ||
                  in_array($w, $this->_keywords_args) )
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_KEYWORD_IN_USE);
            }
            if ( in_array($w, $this->_to_names))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_PROC_DEFINED);                
            }
            if (!$this->isSymbol($w))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_INVALID_SYMBOL);              
            }
            if (count($this->_to_names)+1>$this->_maxProc)
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_TOO_MANY_PROC);
            }
            $this->_inProc=true;
            array_push($this->_to_names, $w);
            array_push($this->_to_start, $i+strlen($w));
            $this->_to_counting_args=true;
            array_push($this->_to_args, new Storage());
            $i=$j;
            continue;
          }
          array_push($this->_coms, $k);
        }
        
        // Commands with at least one arg
        if (in_array($w, $this->_keywords_args)) 
        {
          if (count($this->_coms)>0)
          {
            $this->_getXY(&$s, $i);
            $this->_src_line=__LINE__;
            return (LOGO_ERROR_MISSING_ARG);   
          }
          array_push($this->_coms, $w);
          $i=$j;
          continue;
        }
        
        if (in_array($w, $this->_to_names))
        {
            $procpos=array_search($w, $this->_to_names);
            $argnum=$this->_to_args[$procpos]->getSize();
            if ($argnum>0)
            {
              array_push($this->_coms, $w);
              $i=$j;
              continue;
            }
            /* Procedure with no arguments */
            array_push($this->_runningProc, $w);
            if (count($this->_runningProc)>$this->_maxProcLevel)
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_TOO_MANY_LEVELS);
            }
            array_push($this->_var_stack, $this->_to_args[$procpos]);
            $this->removeLocalVars();
            $ret=$this->_parse($s, $this->_to_start[$procpos], $this->_to_end[$procpos]);
            $this->_to_args[$procpos]=array_pop($this->_var_stack);
            array_pop($this->_runningProc);
            /*if ($ret==LOGO_OK_PROC_RETURN)
            {
              if ($this->_rlvl==0)
              {
                $this->_rlvl=1;
                return ($ret);
              }
              $i=$j;
              continue;
            }*/
            if (($ret==LOGO_OK)||($ret==LOGO_OK_PROC_RETURN))
            {
              $i=$j;
              continue;          
            }
            else
            {
              return ($ret);               
            }
        }
        
        // Commands with no args
        if (in_array($w, $this->_keywords))
        { 
          if ($w=="STOP")
          {
            if (($this->_inProc)||(count($this->_runningProc)))
            {
              $this->_rlvl=0;
              return (LOGO_OK_PROC_RETURN);        
            }
            else
            {
              $this->_getXY(&$s, $i, $w); 
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_STOP_NOT_IN_PROC);
            }
          }
          if (($w=="PU")||($w=="PENUP"))
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->pu();
            $i=$j;
            continue;          
          }
          if (($w=="PD")||($w=="PENDOWN"))
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->pd();
            $i=$j;
            continue;          
          }
          if (($w=="ST")||($w=="SHOWTURTLE"))
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->st();
            $i=$j;
            continue;
          }
          if ($w=="FILL")
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->fill();
            $i=$j;
            continue;
          }
          if ($w=="HOME")
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->home();
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY()); 
            $this->_vars->_setVar("DEGREE", $this->_logo->getD());
            $i=$j;
            continue;          
          }
          if (($w=="HT")||($w=="HIDETURTLE"))
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->ht();
            $i=$j;
            continue;
          }
          if (($w=="WINDOW"))
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->setWrap(LOGO_WINDOW);
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY()); 
            $this->_vars->_setVar("DEGREE", $this->_logo->getD());
            $i=$j;
            continue;
          }
          if (($w=="FENCE"))
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->setWrap(LOGO_FENCE);
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY()); 
            $this->_vars->_setVar("DEGREE", $this->_logo->getD());            
            $i=$j;
            continue;
          }
          if (($w=="WRAP"))
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->setWrap(LOGO_WRAP);
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY()); 
            $this->_vars->_setVar("DEGREE", $this->_logo->getD());
            $i=$j;
            continue;
          }
          if (($w=="CS")||($w=="CLEANSCREEN"))
          {
            if (count($this->_coms))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MISSING_ARG);            
            }
            $this->_logo->cs();
            $this->_getXY(&$s, $i, $w);
            $this->_src_line=__LINE__;
            $this->pushWarn( LOGO_WARNING_NOT_FULLY_IMPLEMENTED,
                         $this->_lineX,
                         $this->_lineY,
                         $w
                         );          
            $i=$j;
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY()); 
            $this->_vars->_setVar("DEGREE", $this->_logo->getD());
            continue;
          }
        } // end of Commands with no args
        
        if (count($this->_coms))
        {
          $k=array_pop($this->_coms);
          if ($k=="LOCAL")
          {
            if (($w{0}!='"'))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MAKE_NEED_QUOTE);              
            }
            if (!$this->isGood(substr($w,1)))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_MAKE_INVALID_NAME);                    
            }
            if (!(($this->_inProc)||(count($this->_runningProc))))
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              $this->pushWarn( LOGO_WARNING_LOCAL_MAKE_GLOBALUSE,
                      $this->_lineX,
                      $this->_lineY,
                        $w
                      );                       
            }
            else
            {
              array_push($this->_localmake, array($this->_runningProc[count($this->_runningProc)-1],substr($w,1)));
            }
            $i=$j;
            continue;
          }
          else
          if (($k=="MAKE")||($k=="LOCALMAKE"))
          {
            if (count($this->_args)==0)
            {
              if (($w{0}!='"'))
              {
                $this->_getXY(&$s, $i, $w);
                $this->_src_line=__LINE__;
                return (LOGO_ERROR_MAKE_NEED_QUOTE);              
              }
              if (!$this->isGood(substr($w,1)))
              {
                $this->_getXY(&$s, $i, $w);
                $this->_src_line=__LINE__;
                return (LOGO_ERROR_MAKE_INVALID_NAME);                    
              }
              array_push($this->_coms, $k);
              array_push($this->_args, substr($w,1));
              $i=$j;
              continue;
            }
            else
            {
              $t=array_pop($this->_args);
              if ($w{0}=="\"")
              {
                if ($k=="MAKE")
                {
                  $this->_makevars->_setVar($t, substr($w,1));
                  $i=$j;
                  continue;
                }
                else
                {
                  if (!(($this->_inProc)||(count($this->_runningProc))))
                  {
                    $this->_getXY(&$s, $i, $w);
                    $this->_src_line=__LINE__;
                    $this->pushWarn( LOGO_WARNING_LOCAL_MAKE_GLOBALUSE,
                        $this->_lineX,
                        $this->_lineY,
                        $w
                      );             
                    $this->_makevars->_setVar($t, substr($w,1));      
                    $i=$j;
                    continue;     
                  }
                  else
                  {
                    array_push($this->_localmake, array(
                      $this->_runningProc[count($this->_runningProc)-1],
                      $t
                    ));
                    $procpos=array_search($this->_runningProc[count($this->_runningProc)-1], $this->_to_names);
                    $this->_to_args[$procpos]->_setVar($t, substr($w,1));
                    $i=$j;
                    continue;
                  }
                }
              }
              else
              {
                if ($this->isNumber($w, &$_real, &$value))
                {
                  if ($k=="MAKE")
                  {
                    $this->_makevars->_setVar($t, $value);
                    $i=$j;
                    continue;
                  }
                  else
                  {
                    if (!(($this->_inProc)||(count($this->_runningProc))))
                    {
                      $this->_getXY(&$s, $i, $w);
                      $this->_src_line=__LINE__;
                      $this->pushWarn( LOGO_WARNING_LOCAL_MAKE_GLOBALUSE,
                          $this->_lineX,
                          $this->_lineY,
                          $w
                        );             
                      $this->_makevars->_setVar($t, $value);
                      $i=$j;
                      continue;           
                    }
                    else
                    {
                      array_push($this->_localmake, array(
                        $this->_runningProc[count($this->_runningProc)-1],
                        $t
                      ));
                      $procpos=array_search($this->_runningProc[count($this->_runningProc)-1], $this->_to_names);
                      $this->_to_args[$procpos]->_setVar($t, $value);
                      $i=$j;
                      continue;
                    }
                  }
                }
                else
                {
                  $this->_getXY(&$s, $i, $w);
                  $this->_src_line=__LINE__;
                  return (LOGO_ERROR_MAKE_INVALID_VALUE);                       
                }
              }
            } 
          }// end of make, local make
          array_push($this->_coms, $k);
        }
        
        if ($this->isNumber($w,&$realnum,&$value))
        {
          if (count($this->_coms)==0)
          {
            $this->_getXY(&$s, $i, $w);
            $this->_src_line=__LINE__;
            return (LOGO_ERROR_MISSING_COMMAND);             
          }
          /*
          if ($realnum)
          {
            $this->_getXY(&$s, $i, $w);
            $this->_src_line=__LINE__;
            $this->pushWarn( LOGO_WARNING_NUMBER_ROUNDED,
                       $this->_lineX,
                       $this->_lineY,
                       $w
                       );
          }
          */
          $k=array_pop($this->_coms);
          
          if (in_array($k, $this->_to_names))
          {
            $procpos=array_search($k, $this->_to_names);
            $argnum=$this->_to_args[$procpos]->getSize();
            if ($argnum>count($this->_args)+1)
            {
              array_push($this->_coms, $k);
              array_push($this->_args, $w);
              $i=$j;
              continue;
            }
            array_push($this->_args, $w);
            $u=0;
            array_push($this->_var_stack, $this->_to_args[$procpos]);
            $this->removeLocalVars();
            $varlist=$this->_to_args[$procpos]->keys();
            foreach ($varlist as $key)
            {
              $this->isNumber($this->_args[$u++],&$real, &$value);
              $this->_to_args[$procpos]->_setVar($key,$value);
            }
            $usa=$this->_to_start[$procpos]+1;
            for ($sk=0;$sk<$argnum;$sk++)
            {
              $t=$this->getNextWord(&$s, $usa, $this->_to_end[$procpos], &$usa);
              $usa++;
            }
            array_push($this->_runningProc, $k);
            if (count($this->_runningProc)>$this->_maxProcLevel)
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_TOO_MANY_LEVELS);
            }
            for (; $u>0; $u--)
            {
              array_pop($this->_args);
            }

            $ret=$this->_parse($s, $usa, $this->_to_end[$procpos]);
            $this->_to_args[$procpos]=array_pop($this->_var_stack);
            array_pop($this->_runningProc);
           /* if ($ret==LOGO_OK_PROC_RETURN)
            {
              if ($this->_rlvl==0)
              {
                $this->_rlvl=1;
                return ($ret);
              }
              $i=$j;
              continue;
            } */
            if (($ret==LOGO_OK)||($ret==LOGO_OK_PROC_RETURN))
            {
              $i=$j;
              continue;
            }
            else
            {
              return ($ret);               
            }

          }
          else
          if (($k=="FD")||($k=="FORWARD"))
          {
            if ($this->_logo->isWrap()==LOGO_FENCE)
            {
              $x1=$this->_logo->getX();
              $y1=$this->_logo->getY();
              $x2=round($x1+$value*sin($this->_logo->getD()*pi()/180));
              $y2=round($y1-$value*cos($this->_logo->getD()*pi()/180));
              if ($this->_logo->isOutXY($x2,$y2))
              {
                $this->_getXY(&$s, $i, $w);
                $this->_src_line=__LINE__;
                $this->pushWarn( LOGO_WARNING_TURTLE_OUT,
                      $this->_lineX,
                      $this->_lineY,
                      $w
                    );               
              }
            }
            $this->_logo->fd($value);
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY());            
          }
          else
          if (($k=="BK")||($k=="BACK"))
          {
            if ($this->_logo->isWrap()==LOGO_FENCE)
            {
              $x1=$this->_logo->getX();
              $y1=$this->_logo->getY();
              $x2=round($x1+$value*sin($this->_logo->getD()*pi()/180));
              $y2=round($y1-$value*cos($this->_logo->getD()*pi()/180));
              if ($this->_logo->isOutXY($x2,$y2))
              {
                $this->_getXY(&$s, $i, $w);
                $this->_src_line=__LINE__;
                $this->pushWarn( LOGO_WARNING_TURTLE_OUT,
                      $this->_lineX,
                      $this->_lineY,
                      $w
                    );               
              }
            }
            $this->_logo->bk($value);
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY());       
          }
          else
          if (($k=="RT")||($k=="RIGHT"))
          {
            $this->_logo->rt($value);
            $this->_vars->_setVar("DEGREE", $this->_logo->getD());    
          }
          else
          if (($k=="LT")||($k=="LEFT"))
          {
            $this->_logo->lt($value);
            $this->_vars->_setVar("DEGREE", $this->_logo->getD());    
          }
          else
          if (($k=="SETPC")||($k=="SETPENCOLOR")||($k=="SETPENCOLOUR"))
          {
            $value=(integer)$value;
            if (($value>=0)&&($value<=15))
            {
              $this->_logo->setPCrgb($this->Logo_Color_R[$value],
                                     $this->Logo_Color_G[$value],
                                     $this->Logo_Color_B[$value]);
            }
            else
            {
              $this->_logo->setPC($value);            
            }
            $this->_vars->_setVar("PENCOLOR",$value);
            $this->_vars->_setVar("PENCOLOUR",$value);
          }
          else
          if (($k=="SETFC")||($k=="SETFLOODCOLOR")||($k=="SETFLOODCOLOUR"))
          {
            $value=(integer)$value;
            if (($value>=0)&&($value<=15))
            {
              $this->_logo->setFCrgb($this->Logo_Color_R[$value],
                                     $this->Logo_Color_G[$value],
                                     $this->Logo_Color_B[$value]);
            }
            else
            {
              $this->_logo->setFC($value);       
            }
            $this->_vars->_setVar("FLOODCOLOR",$value);
            $this->_vars->_setVar("FLOODCOLOUR",$value);
          }
          else
          if (($k=="SETSC")||($k=="SETSCREENCOLOR")||($k=="SETSCREENCOLOUR"))
          {
            $this->_getXY(&$s, $i, $w);
            $this->_src_line=__LINE__;
            $this->pushWarn( LOGO_WARNING_UNSUPPORTED_BG_CHANGE,
                      $this->_lineX,
                      $this->_lineY,
                      $w
                    ); 
            if (($value>=0)&&($value<=15))
            {
              $this->_logo->setSCrgb($this->Logo_Color_R[$value],
                                     $this->Logo_Color_G[$value],
                                     $this->Logo_Color_B[$value]);
            }
            else
            {
              $this->_logo->setSC($value);       
            }
            $this->_vars->_setVar("SCREENCOLOR",$value);
            $this->_vars->_setVar("SCREENCOLOUR",$value);
          }
          else
          if (($k=="REPEAT")||($k=="IF"))
          {
            array_push($this->_repeatT, round($value));
            array_push($this->_coms, $k);
          }
          else
          if (($k=="SETXY")||($k=="SETPOS"))
          {
            if (count($this->_args)==0)
            {
              array_push($this->_coms, $k);
              array_push($this->_args, $value);
            }
            else
            {
              $t=array_pop($this->_args);
              $this->_logo->lineTo($t, -$value, true);
              if ($this->_logo->isWrap()==LOGO_FENCE)
              {
                if ($this->_logo->isOutXY($t, -$value))
                {
                  $this->_getXY(&$s, $i, $w);
                  $this->_src_line=__LINE__;
                  $this->pushWarn( LOGO_WARNING_TURTLE_OUT,
                        $this->_lineX,
                        $this->_lineY,
                        $w
                      );               
                }
              }
            }
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY()); 
          }
          else
          if (($k=="ARC"))
          {
            if (count($this->_args)==0)
            {
              array_push($this->_coms, $k);
              array_push($this->_args, $value);
            }
            else
            {
              $t=array_pop($this->_args);
              $this->_logo->arc($t, $value);
            }
          }
          else
          if ($k=="SETX")
          {
            $this->_logo->lineTo($value, $this->_logo->getY(), true);
            if ($this->_logo->isWrap()==LOGO_FENCE)
            {
              if (($value>$this->_logo->getImageHX())||($value<-$this->_logo->getImageHX()))
              {
                $this->_getXY(&$s, $i, $w);
                $this->_src_line=__LINE__;
                $this->pushWarn( LOGO_WARNING_TURTLE_OUT,
                      $this->_lineX,
                      $this->_lineY,
                      $w
                    );               
              }
            }
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY()); 
          }
          else
          if ($k=="SETY")
          {
            $this->_logo->lineTo($this->_logo->getX(), -$value, true);
            if ($this->_logo->isWrap()==LOGO_FENCE)
            {
              if ((-$value>$this->_logo->getImageHY())||(-$value<-$this->_logo->getImageHY()))
              {
                $this->_getXY(&$s, $i, $w);
                $this->_src_line=__LINE__;
                $this->pushWarn( LOGO_WARNING_TURTLE_OUT,
                      $this->_lineX,
                      $this->_lineY,
                      $w
                    );               
              }
            }
            $this->_vars->_setVar("POSX", $this->_logo->getX());
            $this->_vars->_setVar("POSY", $this->_logo->getY()); 
          }
          else
          if ($k=="TO")
          {
            $this->_getXY(&$s, $i, $w);
            $this->_src_line=__LINE__;
            return (LOGO_ERROR_INVALID_PROC_NAME);     
          }
          else
          if (in_array($w, $this->_to_names))
          {
            $procpos=array_search($w, $this->_to_names);
            $argnum=$this->_to_args[$procpos]->getSize();
            if ($argnum>0)
            {
              array_push($this->_coms, $w);
              $i=$j;
              continue;
            }
            array_push($this->_runningProc, $w);
            if (count($this->_runningProc)>$this->_maxProcLevel)
            {
              $this->_getXY(&$s, $i, $w);
              $this->_src_line=__LINE__;
              return (LOGO_ERROR_TOO_MANY_LEVELS);
            }
            array_push($this->_var_stack, $this->_to_args[$procpos]);
            $this->removeLocalVars();
            $ret=$this->_parse($s, $this->_to_start[$procpos], $this->_to_end[$procpos]);
            $this->_to_args[$procpos]=array_pop($this->_var_stack);
            array_pop($this->_runningProc);
          /*  if ($ret==LOGO_OK_PROC_RETURN)
            {
              if ($this->_rlvl==0)
              {
                $this->_rlvl=1;
                return ($ret);
              }
              $i=$j;
              continue;
            }*/
            if (($ret==LOGO_OK)||($ret==LOGO_OK_PROC_RETURN))
            {
              $i=$j;
              continue;          
            }
            else
            {
              return ($ret);               
            }
          }
          $i=$j;
          continue;
        }  // end of isNumber

      
        /* The word is Not Recongized */
        if ($w)
        {
          $this->_getXY(&$s, $i, $w);
          $this->_src_line=__LINE__;
          return (LOGO_ERROR_BAD_COMMAND);
        }
        
      }// end of processing


      /* Error Handling */
      $this->_getXY(&$s, $U);
      if ($this->_inProc)
      {
        $this->_src_line=__LINE__;
        return (LOGO_ERROR_END_NOT_FOUND);
      }
      else
      if (count($this->_repeat))
      {
        $this->_src_line=__LINE__;
        return (LOGO_ERROR_TOO_MANY_LEFT);
      }
      else
      if (count($this->_repeatT))
      {
        $this->_getXY(&$s, $i);
        $this->_src_line=__LINE__;
        $this->pushWarn( LOGO_WARNING_MISSING_REPEAT_BODY,
                         $this->_lineX,
                         $this->_lineY,
                         "");         
      }   
      else   
      if (count($this->_coms))
      {
        $this->_src_line=__LINE__;
        return (LOGO_ERROR_MISSING_ARG);
      }
      // Return OK
      return (LOGO_OK);
    }
    
    function parse($s="")
    {
      $this->_runningT=microtime();
      if (strlen($s))
      {
        $t=($this->_parse(&$s));  
      }
      else
      {
        $t=($this->_parse(&$this->_s));
      }
      $this->_logo->drawTurtle();
      return ($t);
    }
  
  }
	
?>
Return current item: Logo Interpreter