Example #1
0
 public function select($b)
 {
     $a = new DtlArray();
     foreach ($this->raw as $k => $v) {
         if ($b->execute($v, is_int($k) ? $k + 1 : $k)) {
             $a->push($v);
         }
     }
     return $a;
 }
Example #2
0
 public static function run($self, $block, $args)
 {
     $stack = new DtlArray();
     $scope = $block->__scope->create();
     //DtlObj::create($block->scope);
     $scope->self = $self;
     $scope->arguments = $args;
     for ($i = 0; $i < count($args); $i++) {
         DtlObj::s_set($scope, "_param{$i}", $args[$i]);
     }
     //echo count($block->code);
     foreach ($block->code as $c) {
         //$len=count($this->stack);
         //echo " {$c[0]} sp=$len \n";
         switch ($c[0]) {
             //pushi (immedeate)
             case "pushi":
                 $stack->push(DtlUtil::wrap($c[1]));
                 break;
                 //push1 nameid (local)  -> push1 nameid(self::name)
             //push1 nameid (local)  -> push1 nameid(self::name)
             case "pushbinding":
                 $name = $c[1];
                 $layer = count($c) >= 3 ? $c[2] : 0;
                 $sscope = $scope;
                 while ($layer-- > 0) {
                     $sscope = $sscope->__proto__;
                 }
                 $stack->push(DtlObj::s_get($sscope, $name));
                 break;
             case "push1":
                 $name = $c[1];
                 if ($name == "self" || $name == "this") {
                     $stack->push($self);
                 } else {
                     $stack->push(DtlObj::s_get($self, $name));
                 }
                 break;
                 //[obj] push2 nameid
             //[obj] push2 nameid
             case "push2":
                 $name = $c[1];
                 $obj = $stack->pop();
                 $stack->push(DtlObj::s_get($obj, $name));
                 break;
                 //pushb blockid  (with dtlbind)
             //pushb blockid  (with dtlbind)
             case "pushbb":
                 // block with binding
             // block with binding
             case "pushb":
                 $stack->push(new DtlBlock($scope, $c[1]));
                 break;
                 //[obj] [arg1] .... [argN] send #N,$nameid
             //[obj] [arg1] .... [argN] send #N,$nameid
             case "send":
                 $n = $c[1];
                 $name = $c[2];
                 $args = array();
                 for ($i = 0; $i < $n; $i++) {
                     array_unshift($args, $stack->pop());
                 }
                 //$obj=$this->stack[count($this->stack)-($n+1)];
                 $obj = $stack->pop();
                 if (is_float($obj) || is_int($obj)) {
                     $obj = new DtlNumber($obj);
                 } else {
                     if (is_string($obj)) {
                         $obj = new DtlString($obj);
                     } else {
                         if (is_bool($obj)) {
                             $obj = new DtlBool($obj);
                         }
                     }
                 }
                 if (!is_object($obj)) {
                     throw new Exception("オブジェクトではない値にメソッド" . $name . "を呼び出しています");
                 }
                 $f = DtlObj::s_get($obj, $name);
                 $mmapped = isset(self::$methodMap[$name]) ? self::$methodMap[$name] : $name;
                 if ($f instanceof DtlBlock) {
                     $stack->push(self::run($obj, $f, $args));
                 } else {
                     if (method_exists($obj, $mmapped)) {
                         $stack->push(DtlUtil::wrap(call_user_func_array(array($obj, $mmapped), $args)));
                     } else {
                         throw new Exception($obj . "::" . $name . "はメソッドではありません");
                     }
                 }
                 break;
                 // ret
             // ret
             case "ret":
                 return $stack->pop();
                 // [val] store1 nameid layer
             // [val] store1 nameid layer
             case "storebinding":
                 $name = $c[1];
                 $layer = $c[2];
                 $val = $stack->pop();
                 $sscope = $scope;
                 while ($layer-- > 0) {
                     $sscope = $sscope->__proto__;
                 }
                 DtlObj::s_set($sscope, $name, $val);
                 $stack->push($val);
                 break;
             case "store1":
                 $name = $c[1];
                 $val = $stack->pop();
                 DtlObj::s_set($self, $name, $val);
                 $stack->push($val);
                 break;
                 //[obj] [val] store2 nameid (obj.nameid=val)
             //[obj] [val] store2 nameid (obj.nameid=val)
             case "store2":
                 $name = $c[1];
                 $val = $stack->pop();
                 $obj = $stack->pop();
                 DtlObj::s_set($obj, $name, $val);
                 $stack->push($val);
                 break;
                 // Deprecated?
                 /*case "para":
                       $name=$c[1];
                       DtlObj::s_set($scope, $name, array_shift($scope->arguments));
                       break;                
                   case "tmp":
                       $name=$c[1];
                       DtlObj::s_set($scope, $name, 0);
                       break;*/
             // Deprecated?
             /*case "para":
                   $name=$c[1];
                   DtlObj::s_set($scope, $name, array_shift($scope->arguments));
                   break;                
               case "tmp":
                   $name=$c[1];
                   DtlObj::s_set($scope, $name, 0);
                   break;*/
             case "pop":
                 $n = $c[1];
                 while ($n--) {
                     $stack->pop();
                 }
                 break;
         }
     }
 }