コード例 #1
0
ファイル: Macro.php プロジェクト: lastguest/yay
 function apply(TokenStream $ts, Directives $directives, BlueContext $blueContext)
 {
     $from = $ts->index();
     $crossover = $this->pattern->match($ts);
     if (null === $crossover || $crossover instanceof Error) {
         return;
     }
     if ($this->hasExpansion) {
         $blueMacros = $this->getAllBlueMacrosFromCrossover($crossover->all(), $blueContext);
         if ($this->terminal && isset($blueMacros[$this->id])) {
             // already expanded
             $ts->jump($from);
             return;
         }
         $ts->unskip(...TokenStream::SKIPPABLE);
         $to = $ts->index();
         $ts->extract($from, $to);
         $expansion = $this->expansion->expand($crossover, $this->cycle, $directives, $blueContext);
         $blueMacros[$this->id] = true;
         // paint blue context with tokens from expansion and disabled macros
         $node = $expansion->index();
         while ($node instanceof Node) {
             $blueContext->addDisabledMacros($node->token, $blueMacros);
             $node = $node->next;
         }
         $ts->inject($expansion);
     } else {
         $ts->unskip(...TokenStream::SKIPPABLE);
         $ts->skip(T_WHITESPACE);
         $to = $ts->index();
         $ts->extract($from, $to);
     }
     $this->cycle->next();
 }
コード例 #2
0
ファイル: expanders.php プロジェクト: lastguest/yay
function hygienize(TokenStream $ts, array $context) : TokenStream
{
    $ts->reset();
    $cg = (object) ['node' => null, 'context' => $context, 'ts' => $ts];
    $saveNode = function (Parser $parser) use($cg) {
        return midrule(function ($ts) use($cg, $parser) {
            $cg->node = $ts->index();
            return $parser->parse($ts);
        });
    };
    traverse(chain(token(T_STRING, '··unsafe'), either(parentheses(), braces())), either($saveNode(token(T_VARIABLE)), chain($saveNode(identifier()), token(':')), chain(token(T_GOTO), $saveNode(identifier())))->onCommit(function (Ast $result) use($cg) {
        if (($t = $cg->node->token) && ($value = (string) $t) !== '$this') {
            $cg->node->token = new Token($t->type(), "{$value}·{$cg->context['scope']}", $t->line());
        }
    }))->parse($ts);
    $ts->reset();
    return $ts;
}
コード例 #3
0
ファイル: Macro.php プロジェクト: assertchris/yay
 function apply(TokenStream $ts)
 {
     $from = $ts->index();
     $crossover = $this->pattern->parse($ts);
     if (null === $crossover || $crossover instanceof Error) {
         return;
     }
     if ($this->expansion) {
         // infer blue context from matched tokens
         $context = new BlueContext();
         $tokens = $crossover->all();
         array_walk_recursive($tokens, function (Token $token) use($context) {
             $context->inherit($token->context());
         });
         if (!$this->hasTag('·recursion')) {
             if ($context->contains($this->id())) {
                 return;
             }
         }
         // already expanded
         $context->add($this->id());
         $ts->unskip(...TokenStream::SKIPPABLE);
         $to = $ts->index();
         $ts->extract($from, $to);
         $expansion = $this->mutate($this->expansion, $crossover);
         $this->cycle->next();
         // paint blue context of expasion tokens
         $expansion->each(function (Token $token) use($context) {
             $token->context()->inherit($context);
         });
         $ts->inject($expansion, $from);
     } else {
         $ts->unskip(...TokenStream::SKIPPABLE);
         $ts->skip(T_WHITESPACE);
         $to = $ts->index();
         $ts->extract($from, $to);
     }
 }