Skip to content

Commit

Permalink
user grammars should work more like real classes
Browse files Browse the repository at this point in the history
We now actually call .new (as we ought) to fire off all the BUILDALL stuff
for Capture, Match, and whatever attributes the user adds to their grammar.
(Capture and Match already had switched to using BUILD for the release, but
the parse methods didn't honor that yet.)
  • Loading branch information
TimToady committed Apr 20, 2017
1 parent b4fa6d6 commit db42d62
Showing 1 changed file with 46 additions and 51 deletions.
97 changes: 46 additions & 51 deletions src/core/Grammar.pm
@@ -1,73 +1,68 @@
my class Grammar is Match {

# cache cursor initialization lookup
my $cursor-init := Match.^lookup("!cursor_init");
method parse(\target, :$rule, :$args, Mu :$actions) is raw {
nqp::stmts(
(my $grammar := self.new(:orig(target), |%_).set_actions($actions)),
nqp::decont(nqp::getlexcaller('$/') =
nqp::if(
(my $cursor := nqp::if(
$rule,
nqp::if(
$args,
$grammar."$rule"(|$args.Capture),
$grammar."$rule"()
),
nqp::if(
$args,
$grammar.TOP(|$args.Capture),
$grammar.TOP()
),
)),
nqp::stmts(
(my $match := $cursor.MATCH),
nqp::while(
$match && nqp::isne_i(
nqp::getattr_i(($match := $cursor.MATCH),Match,'$!pos'),
target.chars
),
$match := ($cursor := $cursor.'!cursor_next'()).MATCH
),
$match || Nil
),
Nil
)
)
)
}

method parse(\target, :$rule, :$args, Mu :$actions) {
nqp::decont(nqp::getlexcaller('$/') =
nqp::if(
(my $cursor := nqp::if(
method subparse(\target, :$rule, :$args, Mu :$actions) is raw {
nqp::stmts(
(my $grammar := self.new(:orig(target), |%_).set_actions($actions)),
nqp::decont(nqp::getlexcaller('$/') =
nqp::if(
$rule,
nqp::if(
$args,
self!cursor-init(target, %_).set_actions($actions)."$rule"(|$args.Capture),
self!cursor-init(target, %_).set_actions($actions)."$rule"()
$grammar."$rule"(|$args.Capture).MATCH,
$grammar."$rule"().MATCH,
),
nqp::if(
$args,
self!cursor-init(target, %_).set_actions($actions).TOP(|$args.Capture),
self!cursor-init(target, %_).set_actions($actions).TOP()
),
)),
nqp::stmts(
(my $match := $cursor.MATCH),
nqp::while(
$match && nqp::isne_i(
nqp::getattr_i(($match := $cursor.MATCH),Match,'$!pos'),
target.chars
),
$match := ($cursor := $cursor.'!cursor_next'()).MATCH
$grammar.TOP(|$args.Capture).MATCH,
$grammar.TOP().MATCH
),
$match || Nil
),
Nil
)
)
)
}

method subparse(\target, :$rule, :$args, Mu :$actions) {
nqp::decont(nqp::getlexcaller('$/') =
nqp::if(
$rule,
nqp::if(
$args,
self!cursor-init(target, %_).set_actions($actions)."$rule"(|$args.Capture).MATCH,
self!cursor-init(target, %_).set_actions($actions)."$rule"().MATCH,
),
nqp::if(
$args,
self!cursor-init(target, %_).set_actions($actions).TOP(|$args.Capture).MATCH,
self!cursor-init(target, %_).set_actions($actions).TOP().MATCH
),
)
)
}
}

method parsefile(Str(Cool) $filename, :$enc) {
method parsefile(Str(Cool) $filename, :$enc) is raw {
nqp::decont(nqp::getlexcaller('$/') = nqp::if(
nqp::elems(nqp::getattr(%_,Map,'$!storage')),
self.parse($filename.IO.slurp(:$enc), |%_),
self.parse($filename.IO.slurp(:$enc))
))
}

method !cursor-init(\target, %opts) is raw {
nqp::if(
nqp::elems(nqp::getattr(%opts,Map,'$!storage')),
$cursor-init(self, target, |%opts),
$cursor-init(self, target)
)
}
}

# vim: ft=perl6 expandtab sw=4

0 comments on commit db42d62

Please sign in to comment.