예제 #1
0
 /**
  * Visit an element.
  *
  * @param   \Hoa\Visitor\Element  $element    Element to visit.
  * @param   mixed                 &$handle    Handle (reference).
  * @param   mixed                 $eldnah     Handle (not reference).
  * @return  mixed
  */
 public function visit(Visitor\Element $element, &$handle = null, $eldnah = null)
 {
     $out = null;
     // Hoa\Praspel.
     if ($element instanceof Praspel\Model\Specification) {
         $variable = '$' . $element->getId();
         $out = $variable . ' = new \\Hoa\\Praspel\\Model\\Specification();' . "\n";
         foreach ($element::getAllowedClauses() as $clause) {
             if (true === $element->clauseExists($clause)) {
                 $out .= $element->getClause($clause)->accept($this, $handle, $eldnah);
             }
         }
     } elseif ($element instanceof Praspel\Model\Is) {
         $variable = '$' . $element->getParent()->getId();
         $out = "\n" . $variable . '->getClause(\'is\')->setProperty(' . $element->getProperty() . ');' . "\n";
     } elseif ($element instanceof Praspel\Model\Declaration) {
         $variable = '$' . ($eldnah ?: $element->getId());
         $out = "\n" . $variable . ' = $' . $element->getParent()->getId() . '->getClause(\'' . $element->getName() . '\');' . "\n";
         foreach ($element->getLocalVariables() as $var) {
             $out .= $var->accept($this, $handle, $eldnah);
         }
         foreach ($element->getPredicates() as $predicate) {
             $out .= $variable . '->predicate(\'' . $predicate . '\');' . "\n";
         }
     } elseif ($element instanceof Praspel\Model\Variable) {
         $variable = '$' . ($eldnah ?: $element->getClause()->getId());
         $name = $element->getName();
         $start = $variable . '[\'' . $name . '\']';
         if (true === $element->isLocal()) {
             $out .= $variable . '->let[\'' . $name . '\']';
         } else {
             $out .= $start;
         }
         if (null !== ($alias = $element->getAlias())) {
             $out .= '->domainof(\'' . $alias . '\');' . "\n";
         } else {
             $out .= '->in = ' . $element->getDomains()->accept($this, $handle, $eldnah) . ';' . "\n";
         }
         $constraints = $element->getConstraints();
         if (isset($constraints['is'])) {
             $out .= $start . '->is(\'' . implode('\', \'', $constraints['is']) . '\');' . "\n";
         }
         if (isset($constraints['contains'])) {
             foreach ($constraints['contains'] as $contains) {
                 $out .= $start . '->contains(' . $contains . ');' . "\n";
             }
         }
         if (isset($constraints['key'])) {
             foreach ($constraints['key'] as $pairs) {
                 $out .= $start . '->key(' . $pairs[0] . ')->in = ' . $pairs[1] . ';' . "\n";
             }
         }
     } elseif ($element instanceof Praspel\Model\Throwable) {
         $parent = '$' . $element->getParent()->getId();
         $_variable = $element->getId();
         $variable = '$' . $_variable;
         $out = "\n" . $variable . ' = ' . $parent . '->getClause(\'throwable\');' . "\n";
         foreach ($element as $identifier) {
             $exception = $element[$identifier];
             $start = $variable . '[\'' . $identifier . '\']';
             $out .= $start . ' = \'' . $exception->getInstanceName() . '\';' . "\n";
             if (false === $element->isDisjointed()) {
                 if (null !== ($with = $element->getWith())) {
                     $temp = $_variable . '_' . $identifier . '_with';
                     $out .= '$' . $temp . ' = ' . $variable . '->newWith();' . "\n";
                     foreach ($with->getLocalVariables() as $var) {
                         $out .= $var->accept($this, $handle, $temp);
                     }
                     foreach ($with->getPredicates() as $predicate) {
                         $out .= '$' . $temp . '->predicate(\'' . $predicate . '\');' . "\n";
                     }
                     $out .= $start . '->setWith($' . $temp . ');' . "\n";
                 }
             } else {
                 $out .= $start . '->disjunctionWith(\'' . $exception->getDisjunction() . '\');' . "\n";
             }
         }
     } elseif ($element instanceof Praspel\Model\DefaultBehavior) {
         $out = "\n" . '$' . $element->getId() . ' = $' . $element->getParent()->getId() . '->getClause(\'default\')' . "\n";
         foreach ($element::getAllowedClauses() as $clause) {
             if (true === $element->clauseExists($clause)) {
                 $out .= $element->getClause($clause)->accept($this, $handle, $eldnah);
             }
         }
     } elseif ($element instanceof Praspel\Model\Behavior) {
         $out = "\n" . '$' . $element->getId() . ' = $' . $element->getParent()->getId() . '->getClause(\'behavior\')' . '->get(\'' . $element->getIdentifier() . '\');' . "\n";
         foreach ($element::getAllowedClauses() as $clause) {
             if (true === $element->clauseExists($clause)) {
                 $out .= $element->getClause($clause)->accept($this, $handle, $eldnah);
             }
         }
     } elseif ($element instanceof Praspel\Model\Description) {
         $parent = '$' . $element->getParent()->getId();
         $variable = '$' . $element->getId();
         $out = "\n" . $variable . ' = ' . $parent . '->getClause(\'description\');' . "\n";
         foreach ($element as $example) {
             $out .= $variable . '[] = \'' . preg_replace('#(?<!\\\\)\'#', '\\\'', $example) . '\';' . "\n";
         }
     } elseif ($element instanceof Praspel\Model\Collection) {
         foreach ($element as $el) {
             $out .= $el->accept($this, $handle, $eldnah);
         }
     } elseif ($element instanceof Realdom\Disjunction) {
         $realdoms = $element->getUnflattenedRealdoms();
         if (!empty($realdoms)) {
             $oout = [];
             foreach ($realdoms as $realdom) {
                 if ($realdom instanceof Realdom\IRealdom\Constant) {
                     $oout[] = 'const(' . $realdom->accept($this, $handle, $eldnah) . ')';
                 } else {
                     $oout[] = $realdom->accept($this, $handle, $eldnah);
                 }
             }
             $out .= 'realdom()->' . implode('->or->', $oout);
         }
     } elseif ($element instanceof Realdom) {
         if ($element instanceof Realdom\IRealdom\Constant) {
             if ($element instanceof Realdom\_Array) {
                 $oout = [];
                 foreach ($element['pairs'] as $pair) {
                     $_oout = null;
                     foreach ($pair as $_pair) {
                         if (null !== $_oout) {
                             $_oout .= ', ';
                         }
                         $_oout .= $_pair->accept($this, $handle, $eldnah);
                     }
                     $oout[] = 'array(' . $_oout . ')';
                 }
                 $out .= 'array(' . implode(', ', $oout) . ')';
             } else {
                 $out .= $element->getConstantRepresentation();
             }
         } else {
             $oout = [];
             foreach ($element->getArguments() as $argument) {
                 $oout[] = $argument->accept($this, $handle, $eldnah);
             }
             $out .= $element->getName() . '(' . implode(', ', $oout) . ')';
         }
     } elseif ($element instanceof Realdom\Crate\Constant) {
         $holder = $element->getHolder();
         $praspel = $element->getPraspelRepresentation();
         $out .= '$' . $element->getDeclaration()->getId() . '[\'' . $praspel() . '\']';
     } elseif ($element instanceof Realdom\Crate\Variable) {
         $holder = $element->getVariable();
         if ($holder instanceof Praspel\Model\Variable\Implicit) {
             $out .= 'variable($' . $holder->getClause()->getId() . '->getImplicitVariable(\'' . $holder->getName() . '\'))';
         } else {
             $out .= 'variable($' . $holder->getClause()->getId() . '->getVariable(\'' . $holder->getName() . '\', true))';
         }
     } else {
         throw new Praspel\Exception\Compiler('%s is not yet implemented.', 0, get_class($element));
     }
     return $out;
 }