diff options
Diffstat (limited to 'Calc.php')
| -rw-r--r-- | Calc.php | 138 | 
1 files changed, 0 insertions, 138 deletions
| diff --git a/Calc.php b/Calc.php deleted file mode 100644 index e8dba8d..0000000 --- a/Calc.php +++ /dev/null @@ -1,138 +0,0 @@ -<?php - -namespace kch42\ste; - -/* Class Calc contains static methods needed by <ste:calc /> */ -class Calc { -	private function __construct() {} -	 -	/* We could also just eval() the $infix_math code, but this is much cooler :-D (Parser inception) */ -	public static function shunting_yard($infix_math) { -		$operators = array( -			"+" => array("l", 2), -			"-" => array("l", 2), -			"*" => array("l", 3), -			"/" => array("l", 3), -			"^" => array("r", 4), -			"_" => array("r", 5), -			"(" => array("", 0),  -			")" => array("", 0) -		); -		 -		preg_match_all("/\s*(?:(?:[+\\-\\*\\/\\^\\(\\)])|(\\d*[\\.]?\\d*))\\s*/s", $infix_math, $tokens, PREG_PATTERN_ORDER); -		$tokens_raw   = array_filter(array_map('trim', $tokens[0]), function($x) { return ($x === "0") || (!empty($x)); }); -		$output_queue = array(); -		$op_stack     = array(); -		 -		$lastpriority = NULL; -		/* Make - unary, if neccessary */ -		$tokens = array(); -		foreach($tokens_raw as $token) { -			$priority = isset($operators[$token]) ? $operators[$token][1] : -1; -			if(($token == "-") && (($lastpriority === NULL) || ($lastpriority >= 0))) { -				$priority = $operators["_"][1]; -				$tokens[] = "_"; -			} else { -				$tokens[] = $token; -			} -			$lastpriority = $priority; -		} -		 -		while(!empty($tokens)) { -			$token = array_shift($tokens); -			if(is_numeric($token)) { -				$output_queue[] = $token; -			} else if($token == "(") { -				$op_stack[] = $token; -			} else if($token == ")") { -				$lbr_found = false; -				while(!empty($op_stack)) { -					$op = array_pop($op_stack); -					if($op == "(") { -						$lbr_found = true; -						break; -					} -					$output_queue[] = $op; -				} -				if(!$lbr_found) { -					throw new RuntimeError("Bracket mismatch."); -				} -			} else if(!isset($operators[$token])) { -				throw new RuntimeError("Invalid token ($token): Not a number, bracket or operator. Stop."); -			} else { -				$priority = $operators[$token][1]; -				if($operators[$token][0] == "l") { -					while((!empty($op_stack)) and ($priority <= $operators[$op_stack[count($op_stack)-1]][1])) { -						$output_queue[] = array_pop($op_stack); -					} -				} else { -					while((!empty($op_stack)) and ($priority < $operators[$op_stack[count($op_stack)-1]][1])) { -						$output_queue[] = array_pop($op_stack); -					} -				} -				$op_stack[] = $token; -			} -		} -		 -		while(!empty($op_stack)) { -			$op = array_pop($op_stack); -			if($op == "(") { -				throw new RuntimeError("Bracket mismatch..."); -			} -			$output_queue[] = $op; -		} -		 -		return $output_queue; -	} -	 -	public static function pop2(&$array) { -		$rv = array(array_pop($array), array_pop($array)); -		if(array_search(NULL, $rv, true) !== false) { -			throw new RuntimeError("Not enough numbers on stack. Invalid formula."); -		} -		return $rv; -	} -	 -	public static function calc_rpn($rpn) { -		$stack = array(); -		foreach($rpn as $token) { -			switch($token) { -			case "+": -				list($b, $a) = self::pop2($stack); -				$stack[] = $a + $b; -				break; -			case "-": -				list($b, $a) = self::pop2($stack); -				$stack[] = $a - $b; -				break; -			case "*": -				list($b, $a) = self::pop2($stack); -				$stack[] = $a * $b; -				break; -			case "/": -				list($b, $a) = self::pop2($stack); -				$stack[] = $a / $b; -				break; -			case "^": -				list($b, $a) = self::pop2($stack); -				$stack[] = pow($a, $b); -				break; -			case "_": -				$a = array_pop($stack); -				if($a === NULL) { -					throw new RuntimeError("Not enough numbers on stack. Invalid formula."); -				} -				$stack[] = -$a; -				break; -			default: -				$stack[] = $token; -				break; -			} -		} -		return array_pop($stack); -	} -	 -	public static function calc($expr) { -		return self::calc_rpn(self::shunting_yard($expr)); -	} -}
\ No newline at end of file | 
