Exemplo n.º 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 HoaPraspel\Model\Specification) {
         $oout = [];
         foreach ($element::getAllowedClauses() as $clause) {
             if (true === $element->clauseExists($clause)) {
                 $oout[] = $element->getClause($clause)->accept($this, $handle, $eldnah);
             }
         }
         $out = implode("\n", $oout);
     } elseif ($element instanceof HoaPraspel\Model\Is) {
         $out = '@is ' . $element->getPropertyName() . ';';
     } elseif ($element instanceof HoaPraspel\Model\Declaration) {
         $clause = $element->getName();
         $out = '@' . $clause;
         $oout = [];
         foreach ($element->getLocalVariables() as $name => $var) {
             $oout[] = ' ' . $var->accept($this, $handle, $eldnah);
         }
         foreach ($element->getPredicates() as $predicate) {
             $oout[] = ' \\pred(\'' . $predicate . '\')';
         }
         $out .= implode(' and', $oout) . ';';
     } elseif ($element instanceof HoaPraspel\Model\Variable) {
         $name = $element->getName();
         if (true === $element->isLocal()) {
             $out = 'let ';
         }
         $out .= $name;
         if (null === ($alias = $element->getAlias())) {
             $out .= ': ' . $element->getDomains()->accept($this, $handle, $eldnah);
         } else {
             $out .= ' domainof ' . $alias;
         }
         $constraints = $element->getConstraints();
         if (isset($constraints['is'])) {
             $out .= ' and ' . $name . ' is ' . implode(', ', $constraints['is']);
         }
         if (isset($constraints['contains'])) {
             foreach ($constraints['contains'] as $contains) {
                 $out .= ' and ' . $name . ' contains ' . $contains->accept($this, $handle, $eldnah);
             }
         }
         if (isset($constraints['key'])) {
             foreach ($constraints['key'] as $pairs) {
                 $out .= ' and ' . $name . '[' . $pairs[0]->accept($this, $handle, $eldnah) . ']: ' . $pairs[1]->accept($this, $handle, $eldnah);
             }
         }
     } elseif ($element instanceof HoaPraspel\Model\Throwable) {
         $oout = [];
         foreach ($element as $identifier) {
             $exception = $element[$identifier];
             if (true === $exception->isDisjointed()) {
                 continue;
             }
             $line = ' ' . $exception->getInstanceName() . ' ' . $identifier;
             foreach ((array) $exception->getDisjunction() as $_identifier) {
                 $_exception = $element[$_identifier];
                 $line .= ' or ' . $_exception->getInstanceName() . ' ' . $_identifier;
             }
             if (null !== ($with = $exception->getWith())) {
                 $line .= ' with ';
                 $liine = [];
                 foreach ($with as $var) {
                     $liine[] = $var->accept($this, $handle, $eldnah);
                 }
                 foreach ($with->getPredicates() as $predicate) {
                     $liine[] = '\\pred(\'' . $predicate . '\')';
                 }
                 $line .= implode(' and ', $liine);
             }
             $oout[] = $line;
         }
         $out = '@throwable' . implode(' or', $oout) . ';';
     } elseif ($element instanceof HoaPraspel\Model\DefaultBehavior) {
         $out = '@default {' . "\n";
         $oout = [];
         foreach ($element::getAllowedClauses() as $clause) {
             if (true === $element->clauseExists($clause)) {
                 $oout[] = '    ' . str_replace("\n", "\n" . '    ', $element->getClause($clause)->accept($this, $handle, $eldnah));
             }
         }
         $out .= implode("\n", $oout) . "\n" . '}';
     } elseif ($element instanceof HoaPraspel\Model\Behavior) {
         $out = '@behavior ' . $element->getIdentifier() . ' {' . "\n";
         $oout = [];
         foreach ($element::getAllowedClauses() as $clause) {
             if (true === $element->clauseExists($clause)) {
                 $oout[] = '    ' . str_replace("\n", "\n" . '    ', $element->getClause($clause)->accept($this, $handle, $eldnah));
             }
         }
         $out .= implode("\n", $oout) . "\n" . '}';
     } elseif ($element instanceof HoaPraspel\Model\Description) {
         $oout = [];
         foreach ($element as $example) {
             $oout[] = '@description \'' . preg_replace('#(?<!\\\\)\'#', '\\\'', $example) . '\';';
         }
         $out = implode("\n", $oout);
     } elseif ($element instanceof HoaPraspel\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) {
                 $oout[] = $realdom->accept($this, $handle, $eldnah);
             }
             $out .= implode(' or ', $oout);
         }
     } elseif ($element instanceof Realdom) {
         if ($element instanceof Realdom\IRealdom\Constant) {
             $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) {
         $praspel = $element->getPraspelRepresentation();
         $out .= $praspel();
     } elseif ($element instanceof Realdom\Crate\Variable) {
         $out .= $element->getVariable()->getName();
     } else {
         throw new HoaPraspel\Exception\Compiler('%s is not yet implemented.', 0, get_class($element));
     }
     return $out;
 }