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\Bin; 38 39use Hoa\Compiler; 40use Hoa\Console; 41use Hoa\File; 42use Hoa\Math; 43 44/** 45 * Class \Hoa\Math\Bin\Calc. 46 * 47 * A simple calculator. 48 * 49 * @copyright Copyright © 2007-2017 Hoa community 50 * @license New BSD License 51 */ 52class Calc extends Console\Dispatcher\Kit 53{ 54 /** 55 * Options description. 56 * 57 * @var array 58 */ 59 protected $options = [ 60 ['help', Console\GetOption::NO_ARGUMENT, 'h'], 61 ['help', Console\GetOption::NO_ARGUMENT, '?'] 62 ]; 63 64 65 66 /** 67 * The entry method. 68 * 69 * @return int 70 */ 71 public function main() 72 { 73 while (false !== $c = $this->getOption($v)) { 74 switch ($c) { 75 case 'h': 76 case '?': 77 return $this->usage(); 78 79 case '__ambiguous': 80 $this->resolveOptionAmbiguity($v); 81 82 break; 83 } 84 } 85 86 $this->parser->listInputs($expression); 87 88 $compiler = Compiler\Llk::load( 89 new File\Read('hoa://Library/Math/Arithmetic.pp') 90 ); 91 $visitor = new Math\Visitor\Arithmetic(); 92 $dump = new Compiler\Visitor\Dump(); 93 94 if (null !== $expression) { 95 $ast = $compiler->parse($expression); 96 echo $expression . ' = ' . $visitor->visit($ast), "\n"; 97 98 return; 99 } 100 101 $readline = new Console\Readline(); 102 $readline->setAutocompleter( 103 new Console\Readline\Autocompleter\Word( 104 array_merge( 105 array_keys($visitor->getConstants()->getArrayCopy()), 106 array_keys($visitor->getFunctions()->getArrayCopy()) 107 ) 108 ) 109 ); 110 $handle = null; 111 $expression = 'h'; 112 113 do { 114 switch ($expression) { 115 case 'h': 116 case 'help': 117 echo 118 'Usage:', "\n", 119 ' h[elp] to print this help;', "\n", 120 ' c[onstants] to print available constants;', "\n", 121 ' f[unctions] to print available functions;', "\n", 122 ' e[xpression] to print the current expression;', "\n", 123 ' d[ump] to dump the tree of the expression;', "\n", 124 ' q[uit] to quit.', "\n"; 125 126 break; 127 128 case 'c': 129 case 'constants': 130 echo 131 implode( 132 ', ', 133 array_keys( 134 $visitor->getConstants()->getArrayCopy() 135 ) 136 ), 137 "\n"; 138 139 break; 140 141 case 'f': 142 case 'functions': 143 echo 144 implode( 145 ', ', 146 array_keys( 147 $visitor->getFunctions()->getArrayCopy() 148 ) 149 ), 150 "\n"; 151 152 break; 153 154 case 'e': 155 case 'expression': 156 echo $handle, "\n"; 157 158 break; 159 160 case 'd': 161 case 'dump': 162 if (null === $handle) { 163 echo 'Type a valid expression before (“> 39 + 3”).', "\n"; 164 } else { 165 echo $dump->visit($compiler->parse($handle)), "\n"; 166 } 167 168 break; 169 170 case 'q': 171 case 'quit': 172 break 2; 173 174 default: 175 if (null === $expression) { 176 break; 177 } 178 179 try { 180 echo $visitor->visit($compiler->parse($expression)), "\n"; 181 } catch (Compiler\Exception $e) { 182 echo $e->getMessage(), "\n"; 183 184 break; 185 } 186 187 $handle = $expression; 188 189 break; 190 } 191 } while (false !== $expression = $readline->readLine('> ')); 192 193 return; 194 } 195 196 /** 197 * The command usage. 198 * 199 * @return int 200 */ 201 public function usage() 202 { 203 echo 204 'Usage : math:calc <options> [expression]', "\n", 205 'Options :', "\n", 206 $this->makeUsageOptionsList([ 207 'help' => 'This help.' 208 ]), "\n"; 209 210 return; 211 } 212} 213 214__halt_compiler(); 215A simple calculator. 216