require_once __DIR__ . "/php/json.php"; require_once __DIR__ . "/php/dtlfs/DtlFS.php"; require_once __DIR__ . "/php/dtlfs/DtlSys.php"; require_once __DIR__ . "/php/dtlfs/DtlParam.php"; require_once __DIR__ . "/php/ErrorHandler.php"; if (isset($_POST["script"]) || isset($_GET["file"])) { $root = Dtl::createEmptyRoot(); //----Load Builtin Libraries---- Dtl::initRoot($root); DtlFS::initRoot($root); DtlSys::initRoot($root); //-------------------------- $root->param = new DtlParam(); if (isset($_GET["file"])) { $scr = $root->FS->getContent($_GET["file"]); } else { $scr = $_POST["script"]; } $j = new Services_JSON(); $vmc = $j->decode($scr); header("Content-type: text/json; charset=utf8"); echo $j->encode(DtlUtil::unwrap(Dtl::run($root, $vmc))); } else { ?> <form action="runDtl.php" method="POST"> <textarea name="script" rows=10 cols=40> </textarea> <input type="submit"> </form> <?php }
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; } } }