Ejemplo n.º 1
0
 /**
  * Apply processing to a single node
  * 
  * @param Node $node
  */
 public function applyToNode(Node $node)
 {
     $expression = $node->getInstruction($this);
     $ast = $this->getParser()->parse($expression);
     $variables = $node->getResult() ?: [];
     $arithmetic = new Hoa\Math\Visitor\Arithmetic();
     foreach ($variables as $name => $value) {
         // Constants are upper case and variables lower case. We don't really care, so using a workaround.
         if (preg_match('/^[A-Z_][A-Z0-9_]*$/', $name)) {
             $arithmetic->addConstant($name, $value);
         } else {
             $arithmetic->addVariable($name, function () use($value) {
                 return $value;
             });
         }
     }
     $result = $arithmetic->visit($ast);
     $node->setResult($result);
 }
Ejemplo n.º 2
0
 public function case_visitor_exhaustively()
 {
     $this->given($sampler = new Compiler\Llk\Sampler\BoundedExhaustive(Compiler\Llk\Llk::load(new File\Read('hoa://Library/Math/Test/Unit/Arithmetic.pp')), new Regex\Visitor\Isotropic(new LUT\Sampler\Random()), 9), $compiler = Compiler\Llk\Llk::load(new File\Read('hoa://Library/Math/Arithmetic.pp')), $visitor = new CUT())->executeOnFailure(function () use(&$expression) {
         echo 'Failed expression: ', $expression, '.', "\n";
     })->when(function () use(&$sampler, &$compiler, &$visitor) {
         foreach ($sampler as $expression) {
             $dump = $expression;
             try {
                 $x = (double) $visitor->visit($compiler->parse($expression));
             } catch (\Exception $e) {
                 continue;
             }
             eval('$y = (float) ' . $expression . ';');
             if (is_nan($x) || is_nan($y)) {
                 $this->boolean(true);
                 continue;
             }
             $this->float($x)->isNearlyEqualTo($y);
         }
     });
 }
Ejemplo n.º 3
0
 /**
  * The entry method.
  *
  * @return  int
  */
 public function main()
 {
     while (false !== ($c = $this->getOption($v))) {
         switch ($c) {
             case 'h':
             case '?':
                 return $this->usage();
             case '__ambiguous':
                 $this->resolveOptionAmbiguity($v);
                 break;
         }
     }
     $this->parser->listInputs($expression);
     $compiler = Compiler\Llk::load(new File\Read('hoa://Library/Math/Arithmetic.pp'));
     $visitor = new Math\Visitor\Arithmetic();
     $dump = new Compiler\Visitor\Dump();
     if (null !== $expression) {
         $ast = $compiler->parse($expression);
         echo $expression . ' = ' . $visitor->visit($ast), "\n";
         return;
     }
     $readline = new Console\Readline();
     $readline->setAutocompleter(new Console\Readline\Autocompleter\Word(array_merge(array_keys($visitor->getConstants()->getArrayCopy()), array_keys($visitor->getFunctions()->getArrayCopy()))));
     $handle = null;
     $expression = 'h';
     do {
         switch ($expression) {
             case 'h':
             case 'help':
                 echo 'Usage:', "\n", '    h[elp]       to print this help;', "\n", '    c[onstants]  to print available constants;', "\n", '    f[unctions]  to print available functions;', "\n", '    e[xpression] to print the current expression;', "\n", '    d[ump]       to dump the tree of the expression;', "\n", '    q[uit]       to quit.', "\n";
                 break;
             case 'c':
             case 'constants':
                 echo implode(', ', array_keys($visitor->getConstants()->getArrayCopy())), "\n";
                 break;
             case 'f':
             case 'functions':
                 echo implode(', ', array_keys($visitor->getFunctions()->getArrayCopy())), "\n";
                 break;
             case 'e':
             case 'expression':
                 echo $handle, "\n";
                 break;
             case 'd':
             case 'dump':
                 if (null === $handle) {
                     echo 'Type a valid expression before (“> 39 + 3”).', "\n";
                 } else {
                     echo $dump->visit($compiler->parse($handle)), "\n";
                 }
                 break;
             case 'q':
             case 'quit':
                 break 2;
             default:
                 if (null === $expression) {
                     break;
                 }
                 try {
                     echo $visitor->visit($compiler->parse($expression)), "\n";
                 } catch (Compiler\Exception $e) {
                     echo $e->getMessage(), "\n";
                     break;
                 }
                 $handle = $expression;
                 break;
         }
     } while (false !== ($expression = $readline->readLine('> ')));
     return;
 }
Ejemplo n.º 4
0
 public function case_change_default_context()
 {
     $this->given($compiler = Compiler\Llk\Llk::load(new File\Read('hoa://Library/Math/Arithmetic.pp')), $visitor = new CUT(), $context = new \Mock\Hoa\Math\Context(), $variableName = 'a_variable', $variableValue = 42)->when($context->addVariable($variableName, function () use($variableValue) {
         return $variableValue;
     }))->then->object($visitor->setContext($context))->isNotIdenticalTo($context)->object($visitor->getContext())->isIdenticalTo($context)->float($visitor->visit($compiler->parse('abs(' . $variableName . ' - PI)')))->isEqualTo(abs($variableValue - M_PI))->mock($context)->call('getFunction')->withArguments('abs')->once->call('getVariable')->withArguments($variableName)->once->call('getConstant')->withArguments('PI')->once;
 }