1<?php 2 3/** 4 * Hoa 5 * 6 * 7 * @license 8 * 9 * New BSD License 10 * 11 * Copyright © 2007-2017, Hoa community. All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions are met: 15 * * Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * * Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * * Neither the name of the Hoa nor the names of its contributors may be 21 * used to endorse or promote products derived from this software without 22 * specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37namespace Hoa\Math; 38 39/** 40 * Class \Hoa\Math\Context. 41 * 42 * @copyright Copyright © 2007-2017 Hoa community 43 * @license New BSD License 44 */ 45class Context 46{ 47 /** 48 * List of supported functions: identifier => values as callable. 49 * 50 * @var \ArrayObject 51 */ 52 protected $_functions = null; 53 54 /** 55 * List of supported constants: identifier => values. 56 * 57 * @var \ArrayObject 58 */ 59 protected $_constants = null; 60 61 /** 62 * List of supported variables: identifier => values as callable. 63 * 64 * @var \ArrayObject 65 */ 66 protected $_variables = null; 67 68 69 70 /** 71 * Initialize constants and functions. 72 * 73 */ 74 public function __construct() 75 { 76 $this->initializeConstants(); 77 $this->initializeFunctions(); 78 $this->initializeVariables(); 79 80 return; 81 } 82 83 /** 84 * Add a constant. 85 * 86 * @param string $name Constant name. 87 * @param mixed $value Value. 88 * @return void 89 * @throws \Hoa\Math\Exception\AlreadyDefinedConstant 90 */ 91 public function addConstant($name, $value) 92 { 93 if (true === $this->_constants->offsetExists($name)) { 94 throw new Exception\AlreadyDefinedConstant( 95 'Constant %s is already defined.', 96 0, 97 $name 98 ); 99 } 100 101 $this->_constants[$name] = $value; 102 103 return; 104 } 105 106 /** 107 * Get a constant. 108 * 109 * @param string $name Constant name. 110 * @return mixed 111 * @throws \Hoa\Math\Exception\UnknownConstant 112 */ 113 public function getConstant($name) 114 { 115 if (false === $this->_constants->offsetExists($name)) { 116 throw new Exception\UnknownConstant( 117 'Constant %s does not exist.', 118 1, 119 $name 120 ); 121 } 122 123 return $this->_constants[$name]; 124 } 125 126 /** 127 * Get constants. 128 * 129 * @return \ArrayObject 130 */ 131 public function getConstants() 132 { 133 return $this->_constants; 134 } 135 136 /** 137 * Add a function. 138 * 139 * @param string $name Function name. 140 * @param mixed $callable Callable. 141 * @return void 142 * @throws \Hoa\Math\Exception\UnknownFunction 143 */ 144 public function addFunction($name, $callable = null) 145 { 146 if (null === $callable) { 147 if (false === function_exists($name)) { 148 throw new Exception\UnknownFunction( 149 'Function %s does not exist, cannot add it.', 150 2, 151 $name 152 ); 153 } 154 155 $callable = $name; 156 } 157 158 $this->_functions[$name] = xcallable($callable); 159 160 return; 161 } 162 163 /** 164 * Get a function. 165 * 166 * @param string $name Function name. 167 * @return \Hoa\Consistency\Xcallable 168 * @throws \Hoa\Math\Exception\UnknownFunction 169 */ 170 public function getFunction($name) 171 { 172 if (false === $this->_functions->offsetExists($name)) { 173 throw new Exception\UnknownFunction( 174 'Function %s does not exist.', 175 3, 176 $name 177 ); 178 } 179 180 return $this->_functions[$name]; 181 } 182 183 /** 184 * Get functions. 185 * 186 * @return \ArrayObject 187 */ 188 public function getFunctions() 189 { 190 return $this->_functions; 191 } 192 193 /** 194 * Add a variable. 195 * 196 * @param string $name Variable name. 197 * @param callable $callable Callable. 198 * @return void 199 */ 200 public function addVariable($name, callable $callable) 201 { 202 $this->_variables[$name] = xcallable($callable); 203 204 return; 205 } 206 207 /** 208 * Get a variable. 209 * 210 * @param string $name Variable name. 211 * @return callable 212 * @throws \Hoa\Math\Exception\UnknownVariable 213 */ 214 public function getVariable($name) 215 { 216 if (false === $this->_variables->offsetExists($name)) { 217 throw new Exception\UnknownVariable( 218 'Variable %s does not exist.', 219 4, 220 $name 221 ); 222 } 223 224 return $this->_variables[$name]($this); 225 } 226 227 /** 228 * Get variables. 229 * 230 * @return \ArrayObject 231 */ 232 public function getVariables() 233 { 234 return $this->_variables; 235 } 236 237 /** 238 * Initialize constants mapping. 239 * 240 * @return void 241 */ 242 protected function initializeConstants() 243 { 244 static $_constants = null; 245 246 if (null === $_constants) { 247 $_constants = new \ArrayObject([ 248 'PI' => M_PI, 249 'PI_2' => M_PI_2, 250 'PI_4' => M_PI_4, 251 'E' => M_E, 252 'SQRT_PI' => M_SQRTPI, 253 'SQRT_2' => M_SQRT2, 254 'SQRT_3' => M_SQRT3, 255 'LN_PI' => M_LNPI, 256 'LOG_2E' => M_LOG2E, 257 'LOG_10E' => M_LOG10E, 258 'LN_2' => M_LN2, 259 'LN_10' => M_LN10, 260 'ONE_OVER_PI' => M_1_PI, 261 'TWO_OVER_PI' => M_2_PI, 262 'TWO_OVER_SQRT_PI' => M_2_SQRTPI, 263 'ONE_OVER_SQRT_2' => M_SQRT1_2, 264 'EULER' => M_EULER, 265 'INFINITE' => INF 266 ]); 267 } 268 269 $this->_constants = $_constants; 270 271 return; 272 } 273 274 /** 275 * Initialize functions mapping. 276 * 277 * @return void 278 */ 279 protected function initializeFunctions() 280 { 281 static $_functions = null; 282 283 if (null === $_functions) { 284 $average = function () { 285 $arguments = func_get_args(); 286 287 return array_sum($arguments) / count($arguments); 288 }; 289 290 $_functions = new \ArrayObject([ 291 'abs' => xcallable('abs'), 292 'acos' => xcallable('acos'), 293 'asin' => xcallable('asin'), 294 'atan' => xcallable('atan'), 295 'average' => xcallable($average), 296 'avg' => xcallable($average), 297 'ceil' => xcallable('ceil'), 298 'cos' => xcallable('cos'), 299 'count' => xcallable(function () { return count(func_get_args()); }), 300 'deg2rad' => xcallable('deg2rad'), 301 'exp' => xcallable('exp'), 302 'floor' => xcallable('floor'), 303 'ln' => xcallable('log'), 304 'log' => xcallable(function ($value, $base = 10) { return log($value, $base); }), 305 'max' => xcallable('max'), 306 'min' => xcallable('min'), 307 'pow' => xcallable('pow'), 308 'rad2deg' => xcallable('rad2deg'), 309 'round' => xcallable(function ($value, $precision = 0) { return round($value, $precision); }), 310 'sin' => xcallable('sin'), 311 'sqrt' => xcallable('sqrt'), 312 'sum' => xcallable(function () { return array_sum(func_get_args()); }), 313 'tan' => xcallable('tan') 314 ]); 315 } 316 317 $this->_functions = $_functions; 318 319 return; 320 } 321 322 /** 323 * Initialize variables mapping. 324 * 325 * @return void 326 */ 327 protected function initializeVariables() 328 { 329 if (null === $this->_variables) { 330 $this->_variables = new \ArrayObject(); 331 } 332 333 return; 334 } 335} 336