/** * Calls the function and returns the value * @param String $paramSpace Space name * @param String $paramName function name * @param array $paramArgs args (optional) * @return OrongoVariable orongovariable(null) if it didnt return anything or any error occured else the OrongoVariable returned */ public function execFunction($paramSpace, $paramName, $paramArgs = null) { if (!is_array($paramArgs)) { $args = array(); } else { $args = $paramArgs; } //you should prevent this.. if (!$this->isFunction($paramSpace, $paramName)) { return new OrongoVariable(null); } if (isset($this->functions[$paramSpace][$paramName])) { $func =& $this->functions[$paramSpace][$paramName]; if ($func instanceof OrongoFunction == false) { return new OrongoVariable(null); } $return = $func($args); if ($return instanceof OrongoVariable == false && !is_array($return)) { return new OrongoVariable(null); } return $return; } else { $func =& $this->customFunctions[$paramSpace][$paramName]; $argCount = empty($args[0]) ? 0 : count($args); if ($func['param_count'] > $argCount) { throw new OrongoScriptParseException("Invalid function call to " . $paramName . " (parameter count)", -10); } $p = new OrongoScriptParser($func['logic']); $arguments = array(); if ($func['param_count'] > 0 && isset($func['params']) && is_array($func['params'])) { $i = 0; foreach ($func['params'] as $paramName) { $arguments[$paramName] = $args[$i]; $i++; } } $return = $p->startParser(clone $this, null, $arguments); $this->variables = $p->getRuntime()->getVars(); return new OrongoVariable($return); } }
/** * Parses current line */ private function parseLine() { if ($this->lineparsed) { return; } $line = trim($this->lines[$this->getCurrentLine()]); if (!empty($this->ifs)) { if ($this->lineStartsWith("if")) { $this->ifs[count($this->ifs) - 1]['ifs_passed']++; } if ($line == "end if" && $this->ifs[count($this->ifs) - 1]['ifs_passed'] != 0) { $this->ifs[count($this->ifs) - 1]['logic'] .= "end if;"; $this->ifs[count($this->ifs) - 1]['ifs_passed']--; return; } else { if ($line == "end if" && $this->ifs[count($this->ifs) - 1]['ifs_passed'] == 0) { } else { $this->ifs[count($this->ifs) - 1]['logic'] .= $line . ";"; return; } } } if (!empty($this->foreachs)) { if ($this->lineStartsWith("foreach")) { $this->foreachs[count($this->foreachs) - 1]['foreachs_passed']++; } if ($line == "end foreach" && $this->foreachs[count($this->foreachs) - 1]['foreachs_passed'] != 0) { $this->foreachs[count($this->foreachs) - 1]['logic'] .= "end foreach;"; $this->foreachs[count($this->foreachs) - 1]['foreachs_passed']--; return; } else { if ($line == "end foreach" && $this->foreachs[count($this->foreachs) - 1]['foreachs_passed'] == 0) { } else { $this->foreachs[count($this->foreachs) - 1]['logic'] .= $line . ";"; return; } } } if ($this->definingFunction != null && $line != "end function") { $this->definingFunction["logic"] .= $line . ";"; } else { if ($this->runtime->getCurrentSpace() == null && !$this->lineStartsWith("import") && !$this->lineStartsWith("space") && !$this->lineStartsWith("use")) { throw new OrongoScriptParseException("Can not execute: " . $line . " while not in space!"); } else { if ($this->lineStartsWith("space")) { if ($this->runtime->getCurrentSpace() != null) { throw new OrongoScriptParseException("Can't create a new space if you are still in a space!"); } $spaceName = trim(preg_replace("/space/", "", $line, 1)); $this->runtime->registerSpace($spaceName); $this->runtime->setCurrentSpace($spaceName); } else { if ($line == "end space") { if (!empty($this->ifs) || $this->definingFunction != null) { throw new OrongoScriptParseException("Can't end the space if you are still in a function/if."); } if ($this->runtime->getCurrentSpace() == null) { throw new OrongoScriptParseException("Can't end the space if you are not in a space!"); } $this->runtime->setCurrentSpace(null); } else { if ($this->lineStartsWith("if")) { if ($this->definingFunction == null && $this->onlyFunctionSpaces) { throw new OrongoScriptParseException("Can't perform: " . $line . " outside function when using the space as a function space."); } $f = preg_replace("/if/", "", $line, 1); $f = trim($f); if ($f[0] != "(" || $f[strlen($f) - 1] != ")") { throw new OrongoScriptParseException("Invalid if statement"); } $f[0] = ""; $f[strlen($f) - 1] = ""; $bool = $this->parseIf($f); $this->ifs[count($this->ifs)] = array('logic' => '', 'execute' => $bool, 'ifs_passed' => 0, 'new' => true); } else { if ($line == "end if") { if (empty($this->ifs)) { throw new OrongoScriptParseException("Can not exit an if you're not in an if."); } $currentIfNo = count($this->ifs) - 1; $curIf = $this->ifs[$currentIfNo]; if ($curIf['execute']) { $p = new OrongoScriptParser($curIf['logic']); $p->startParser($this->runtime, null, null, true); } unset($this->ifs[$currentIfNo]); } else { if ($this->lineStartsWith("import")) { $imp = trim(preg_replace("/import/", "", $line, 1)); $this->runtime->import($imp); } else { if ($this->lineStartsWith("let")) { $line = trim(preg_replace("/let/", "", $line, 1)); if (!stristr($line, "=")) { throw new OrongoScriptParseException("Invalid let at line " . $this->getCurrentLine(true)); } $toLet = explode("=", $line, 2); foreach ($toLet as &$var) { $var = trim($var); } if (count($toLet) < 2) { throw new OrongoScriptParseException("Invalid let at line " . $this->getCurrentLine(true)); } if (empty($toLet[0])) { throw new OrongoScriptParseException("Invalid let (empty variable name) at line " . $this->getCurrentLine(true)); } if (empty($toLet[1])) { throw new OrongoScriptParseException("Invalid let (empty value) at line " . $this->getCurrentLine(true)); } $toLet[0] = stristr($toLet[0], ":") ? $toLet[0] : $toLet[0] . ":__main__"; $field = explode(":", strrev($toLet[0]), 2); $name = trim(strrev($field[1])); $field = trim(strrev($field[0])); $var = $this->parseVar($toLet[1]); $var = $var instanceof OrongoVariable ? $var : is_array($var) ? $var : new OrongoVariable(null); $this->runtime->letVar($name, $var, $field); } else { if ($this->lineStartsWith("do")) { if ($this->definingFunction == null && $this->onlyFunctionSpaces) { throw new OrongoScriptParseException("Can't perform: " . $line . " outside function when using the space as a function space."); } $line[0] = ""; $line[1] = ""; $func = $this->parseFunction(trim($line)); $this->runtime->execFunction($func['space'], $func['function_name'], $func['args']); } else { if ($this->lineStartsWith("function")) { $line = trim(preg_replace("/function/", "", $line, 1)); if (substr_count($line, ")") != 1 || substr_count($line, "(") != 1 || strpos(")", $line) < strpos("(", $line)) { throw new OrongoScriptParseException("Invalid function declaration."); } $l = explode("(", $line); if (empty($l[0])) { throw new OrongoScriptParseException("Invalid function declaration: no function name!"); } $funcName = trim($l[0]); $l[1] = trim(str_replace(")", "", $l[1])); $rawParams = str_replace(" ", "", $l[1]); $params = empty($rawParams) ? null : explode(",", $rawParams); $this->definingFunction = array('name' => $funcName, 'param_count' => $params == null ? 0 : count($params), 'logic' => '', 'params' => $params); } else { if ($line == "end function") { if ($this->definingFunction == null) { throw OrongoScriptParseException("Invalid statement end function, no function is being defined!"); } $this->runtime->registerFunction($this->definingFunction); $this->definingFunction = null; } else { if ($this->lineStartsWith("use")) { $path = trim(preg_replace("/use/", "", $line, 1)); $path = $this->parseVar($path)->get(); if (!file_exists($path)) { throw new OrongoScriptParseException("Couldn't use: " . $path . " (file doesn't exists)"); } $p = new OrongoScriptParser(file_get_contents($path)); $p->startParser($this->getRuntime(), null, null, true, true); } else { if ($this->lineStartsWith("return")) { if ($this->definingFunction == null && $this->onlyFunctionSpaces) { throw new OrongoScriptParseException("Can't perform: " . $line . " outside function when using the space as a function space."); } $line = trim(preg_replace("/return/", "", $line, 1)); return array('action' => 'terminated', 'value' => $this->parseVar($line)->get()); } else { if ($line == "return") { if ($this->definingFunction == null && $this->onlyFunctionSpaces) { throw new OrongoScriptParseException("Can't perform: " . $line . " outside function when using the space as a function space."); } return array('action' => 'terminated', 'value' => 1); } else { if ($this->lineStartsWith("foreach")) { $line = trim(preg_replace("/foreach/", "", $line, 1)); if (!stristr($line, ")") || !stristr($line, "(")) { throw new OrongoScriptParseException("Invalid foreach loop: " . $line); } if ($line[0] != "(" || $line[strlen($line) - 1] != ")") { throw new OrongoScriptParseException("Invalid foreach loop: " . $line); } $line[strlen($line) - 1] = ""; $line[0] = ""; if (!stristr($line, "as")) { throw new OrongoScriptParseException("Invalid foreach loop: " . $line); } $exp = explode("as", $line, 2); $var = trim($exp[0]); $list = false; if (stristr($var, ":")) { $list = true; $var = $this->parseVar($var)->get(); } if ($list && $var instanceof OrongoList == false) { throw new OrongoScriptParseException("List expected in foreach loop: " . $line); } if (!$list) { $varTemp = $this->runtime->getRawVar($var); if ($varTemp['__main__'] instanceof OrongoList) { $var = $varTemp['__main__']; $list = true; } else { $var = $varTemp; } } $asVar = trim($exp[1]); $var = $list ? $var->getArray() : $var; $this->foreachs[end($this->foreachs)] = array('var' => $var, 'asVar' => $asVar, 'logic' => "", 'foreachs_passed' => 0, 'new' => true); } else { if ($line == "end foreach") { if (empty($this->foreachs)) { throw new OrongoScriptParseException("Can not end a foreach loop when you're not in a loop."); } $currentForeach = end($this->foreachs); unset($this->foreachs[count($this->foreachs) - 1]); foreach ($currentForeach['var'] as $as) { $p = new OrongoScriptParser($currentForeach['logic']); $p->startParser($this->runtime, null, array($currentForeach['asVar'] => $as->get()), true); $this->runtime->setVars($p->getRuntime()->getVars()); } } else { $done = false; foreach (self::$registeredLineHandlers as $statement => $pM) { if ($this->lineStartsWith($statement)) { call_user_method_array($pM[0], $pM[1], array($line, &$this)); $done = true; break; } } if (!$done) { throw new OrongoScriptParseException("Invalid characters at line: " . $line); } } } } } } } } } } } } } } } } } }