Skip to content

Instantly share code, notes, and snippets.

@FROGGS

FROGGS/outout Secret

Last active September 29, 2015 20:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FROGGS/55945f79a9fefb004a61 to your computer and use it in GitHub Desktop.
Save FROGGS/55945f79a9fefb004a61 to your computer and use it in GitHub Desktop.
$ perl6 -e 'my $chars; say "abc" ~~ /$chars=(.)/; say $chars;'
in Actions, before: - QAST::Regex(:rxtype(subrule) :subtype(capture)) (.)
- QAST::NodeList
- QAST::Block
- QAST::Var(local self :decl(param))
- QAST::Var(lexical $¢ :decl(var))
- QAST::Regex(:rxtype(concat) :subtype())
- QAST::Regex(:rxtype(scan) :subtype())
- QAST::Regex(:rxtype(concat) :subtype()) .
- QAST::Regex(:rxtype(cclass) :subtype() :name(.)) .
- QAST::Regex(:rxtype(pass) :subtype())
- QAST::Regex(:rxtype(concat) :subtype()) .
- QAST::Regex(:rxtype(cclass) :subtype() :name(.)) .
in Actions, after: - QAST::Regex(:rxtype(subrule) :subtype(capture)) (.)
- QAST::NodeList
- QAST::Block
- QAST::Var(local self :decl(param))
- QAST::Var(lexical $¢ :decl(var))
- QAST::Regex(:rxtype(subrule) :subtype(method)) $chars=(.)
- QAST::NodeList
- QAST::SVal(LEXICAL_CAPTURE)
- QAST::Var(lexical $chars) $chars
- QAST::Var(lexical $¢)
- QAST::Regex(:rxtype(concat) :subtype())
- QAST::Regex(:rxtype(scan) :subtype())
- QAST::Regex(:rxtype(concat) :subtype()) .
- QAST::Regex(:rxtype(cclass) :subtype() :name(.)) .
- QAST::Regex(:rxtype(pass) :subtype())
- QAST::Regex(:rxtype(concat) :subtype()) .
- QAST::Regex(:rxtype(cclass) :subtype() :name(.)) .
entering Cursor.LEXICAL_CAPTURE
Cursor.new
「」
「」
leaving Cursor.LEXICAL_CAPTURE
「a」
0 => 「a」
42
diff --git a/src/Perl6/Actions.nqp b/src/Perl6/Actions.nqp
index 957644c..1af4eee 100644
--- a/src/Perl6/Actions.nqp
+++ b/src/Perl6/Actions.nqp
@@ -8335,48 +8335,74 @@ class Perl6::RegexActions is QRegex::P6Regex::Actions does STDActions {
method metachar:sym<rakvar>($/) {
my $varast := $<var>.ast;
- if nqp::istype($varast, QAST::Var) {
- # See if it's a constant Scalar, in which case we can turn it to
- # a Str and use the value as a literal, so we get LTM.
- if nqp::substr($varast.name, 0, 1) eq '$' {
- my $constant;
- try {
- my $found := $*W.find_symbol([$varast.name]);
- $constant := $found.Str if nqp::isconcrete($found);
+ # Capturing to a variable or name ($foo vs $<foo>)
+ if $<quantified_atom> {
+ my $qast := $<quantified_atom>.ast;
+ nqp::say('in Actions, before: ' ~ $qast.dump);
+
+ $qast := QAST::Regex.new( :rxtype<quant>, :min(0), :max(-1), $qast)
+ if nqp::substr($varast.name, 0, 1) eq '@';
+
+ my $thing := $qast[0][0].pop;
+ $qast[0][0].push(
+ QAST::Regex.new(:rxtype<subrule>, :subtype<method>, :node($/),
+ QAST::NodeList.new(
+ QAST::SVal.new(:value<LEXICAL_CAPTURE>),
+ $varast,
+ QAST::Var.new( :name('$¢'), :scope<lexical> )
+ )
+ )
+ );
+ $qast[0][0].push($thing);
+
+ nqp::say('in Actions, after: ' ~ $qast.dump);
+ make $qast;
+ }
+ # Interpolating a variable or a backreference
+ else {
+ if nqp::istype($varast, QAST::Var) {
+ # See if it's a constant Scalar, in which case we can turn it to
+ # a Str and use the value as a literal, so we get LTM.
+ if nqp::substr($varast.name, 0, 1) eq '$' {
+ my $constant;
+ try {
+ my $found := $*W.find_symbol([$varast.name]);
+ $constant := $found.Str if nqp::isconcrete($found);
+ }
+ if nqp::isconcrete($constant) {
+ make self.apply_literal_modifiers(QAST::Regex.new(
+ nqp::unbox_s($constant), :rxtype<literal>, :node($/)
+ ));
+ return;
+ }
}
- if nqp::isconcrete($constant) {
- make self.apply_literal_modifiers(QAST::Regex.new(
- nqp::unbox_s($constant), :rxtype<literal>, :node($/)
- ));
+
+ # If it's a variable, but statically typed as a string, we know
+ # it's a simple interpolation; use LITERAL.
+ if nqp::istype($varast.returns, $*W.find_symbol(['Str'])) {
+ make QAST::Regex.new(QAST::NodeList.new(
+ QAST::SVal.new( :value('!LITERAL') ),
+ $varast,
+ QAST::IVal.new( :value(%*RX<i> ?? 1 !! 0) )
+ ),
+ :rxtype<subrule>, :subtype<method>, :node($/));
return;
}
}
- # If it's a variable, but statically typed as a string, we know
- # it's a simple interpolation; use LITERAL.
- if nqp::istype($varast.returns, $*W.find_symbol(['Str'])) {
- make QAST::Regex.new(QAST::NodeList.new(
- QAST::SVal.new( :value('!LITERAL') ),
- $varast,
- QAST::IVal.new( :value(%*RX<i> ?? 1 !! 0) )
- ),
- :rxtype<subrule>, :subtype<method>, :node($/));
- return;
- }
+ # Otherwise, slow path that checks what we have.
+ make QAST::Regex.new(QAST::NodeList.new(
+ QAST::SVal.new( :value('INTERPOLATE') ),
+ $varast,
+ QAST::IVal.new( :value(%*RX<i> ?? 1 !! 0) ),
+ QAST::IVal.new( :value(%*RX<m> ?? 1 !! 0) ),
+ QAST::IVal.new( :value($*SEQ ?? 1 !! 0) )
+ ),
+ QAST::Op.new( :op<callmethod>, :name<new>,
+ QAST::WVal.new( :value($*W.find_symbol(['PseudoStash']))),
+ ),
+ :rxtype<subrule>, :subtype<method>, :node($/));
}
-
- # Otherwise, slow path that checks what we have.
- make QAST::Regex.new(QAST::NodeList.new(
- QAST::SVal.new( :value('INTERPOLATE') ),
- $varast,
- QAST::IVal.new( :value(%*RX<i> ?? 1 !! 0) ),
- QAST::IVal.new( :value(%*RX<m> ?? 1 !! 0) ),
- QAST::IVal.new( :value($*SEQ ?? 1 !! 0) )
- ),
- QAST::Op.new( :op<callmethod>, :name<new>,
- QAST::WVal.new( :value($*W.find_symbol(['PseudoStash']))),
- ),
- :rxtype<subrule>, :subtype<method>, :node($/));
}
method assertion:sym<{ }>($/) {
diff --git a/src/Perl6/Grammar.nqp b/src/Perl6/Grammar.nqp
index 5348ce6..0e15f96 100644
--- a/src/Perl6/Grammar.nqp
+++ b/src/Perl6/Grammar.nqp
@@ -4966,7 +4966,7 @@ grammar Perl6::RegexGrammar is QRegex::P6Regex::Grammar does STD does CursorPack
<!before <sigil> <rxstopper> >
<var=.LANG('MAIN', 'variable')>
[
- || $<binding> = ( \s* '=' \s* <quantified_atom> )
+ || \s* '=' \s* <quantified_atom>
{ self.check_variable($<var>) unless $<twigil> eq '<' }
|| { self.check_variable($<var>) }
[ <?before '.'? <[ \[ \{ \< ]>> <.worry: "Apparent subscript will be treated as regex"> ]?
diff --git a/src/core/Cursor.pm b/src/core/Cursor.pm
index c591a7b..f9c1a02 100644
--- a/src/core/Cursor.pm
+++ b/src/core/Cursor.pm
@@ -314,6 +314,18 @@ my class Cursor does NQPCursorRole {
}
}
+ method LEXICAL_CAPTURE($var is rw, $cap is raw) is raw {
+ say 'entering Cursor.LEXICAL_CAPTURE';
+ $var = 42;
+ say $cap;
+ say $cap.MATCH();
+ say $cap.MATCH_SAVE();
+ say 'leaving Cursor.LEXICAL_CAPTURE';
+ my $cur := self.'!cursor_start_cur'();
+ my $pos := nqp::getattr_i($cur, $?CLASS, '$!from');
+ $cur.'!cursor_pass'($pos, '')
+ }
+
method CALL_SUBRULE($rule, |c) {
$rule(self, |c)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment