Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implement <foo> calling my regex foo if in scope

  • Loading branch information...
commit bca1172445d3254bd16d1b7e9aaae5889ec3e869 1 parent df250ea
@sorear authored
Showing with 81 additions and 7 deletions.
  1. +6 −7 docs/TODO.S05
  2. +3 −0  lib/CodeGen.cs
  3. +61 −0 src/niecza
  4. +11 −0 test2.pl
View
13 docs/TODO.S05
@@ -15,16 +15,15 @@ All line numbers are relative to c4882a67. Also, deliberate discrepencies.)
( 535) No :rw
( 768) No internal smartmatches
( 924) $/ is a Cursor inside closures
-( 933) Don't know how fail is supposed to work there
-( 978) No negative quantifiers
+( 933) Don't know how fail is supposed to work there DISCUSS
+( 978) No negative quantifiers DUBIOUS
(1057) No special handling of zero-width matches DISCUSS
(1172) No auto-declared temporary variables $x = <.ident>
(1178) No bindings to existing variables
-(1186) No || @array temporal-alternation syntax DISCUSS PARSE
+(1186) No || @array temporal-alternation syntax DISCUSS
(1253) No handling of formal parameters in LTM
(1258) No {*} and funky proto handling in general
(1276) Declarativeness of constants is insufficiently general
-(1388) <foo> never uses a lexical regex
(1461) Arguments in <&foo(2)> not handled; STD parses EXPR but only this legal
(1507) No support for indirect <::($name)> calls
Also, nice fossil.
@@ -43,15 +42,15 @@ All line numbers are relative to c4882a67. Also, deliberate discrepencies.)
(2342) ::> is defined in terms of brackets, not temporal alternation
(2380) No <commit> or <cut>
(2460) $foo ~~ rule { } does not automatically dual-anchor (DISCUSS)
-(2501) No <prior> (probable fossil) DISCUSS
+(2501) No <prior> (probable fossil) DUBIOUS
(2738) No success value; failed matches return Match
(2818) In list context, $match[0] will return $match if $match[0] does not
otherwise exist; useful for improving DWIM ness of lists
(2851) @<foo> does not seem to work
(2868) No .values or .kv, .keys ignores numeric captures
(2895) Undefined: caps, chunks, prematch, postmatch
-(2910) No concept of cursor directionality
-(3144) Missing captures don't produce Nil
+(2910) No concept of cursor directionality DUBIOUS
+(3144) Missing captures don't produce Nil DISCUSS
(3718) $0=<.alpha>+ is processed backwards; $0=[<.alpha>]+ is fine
(3750) No array aliasing
(3923) No hash aliasing
View
3  lib/CodeGen.cs
@@ -3910,6 +3910,9 @@ public class DowncallReceiver : CallReceiver {
} else if (cmd == "sub_is_routine") {
SubInfo s = (SubInfo)Handle.Unbox(args[1]);
return s.mo.HasMRO(Kernel.RoutineMO);
+ } else if (cmd == "sub_is_regex") {
+ SubInfo s = (SubInfo)Handle.Unbox(args[1]);
+ return s.mo.HasMRO(Kernel.RegexMO);
} else if (cmd == "sub_has_lexical") {
SubInfo s = (SubInfo)Handle.Unbox(args[1]);
return s.dylex.ContainsKey((string)args[2]);
View
61 src/niecza
@@ -163,6 +163,67 @@ method assertion:method ($/) {
}
}
+method assertion:name ($/) {
+ my ($pname) = self.process_name($<longname>, :defer);
+ my $name = ~$<longname>;
+
+ if !$pname {
+ $pname = { name => 'alpha' };
+ $/.CURSOR.sorry('Method call requires a method name');
+ }
+
+ my @lex = $*CURLEX<!sub>.lookup_lex("&$name");
+ my $is_lexical = substr($/.orig, $/.from-1, 1) ne '.' &&
+ @lex && @lex[0] eq 'sub' && @lex[4].is_regex;
+
+ if $<assertion> {
+ make $<assertion>.ast;
+ } elsif $name eq 'sym' {
+ $/.CURSOR.sorry("<sym> is only valid in multiregexes")
+ unless defined %*RX<sym>;
+ make ::RxOp::Sym.new(igcase => %*RX<i>, igmark => %*RX<a>,
+ text => %*RX<sym> // '', endsym => %*RX<endsym>);
+ } elsif $name eq 'before' {
+ make ::RxOp::Before.new(zyg => [$<nibbler>[0].ast]);
+ return Nil;
+ } elsif $name eq 'after' {
+ my @l = $<nibbler>[0].ast.tocclist;
+ if grep { !defined $_ }, @l {
+ $/.CURSOR.sorry("Unsuppored elements in after list");
+ make ::RxOp::Sequence.new;
+ return Nil;
+ }
+ make ::RxOp::ZeroWidthCCs.new(neg => False, after => True, ccs => @l);
+ return;
+ } elsif !$<nibbler> && !$<arglist> && !$pname<pkg> && !$pname<iname> &&
+ !$is_lexical {
+ make ::RxOp::Subrule.new(method => $pname<name>);
+ } else {
+ my $args = $<nibbler> ??
+ [ self.op_for_regex($/, $<nibbler>.ast) ] !!
+ $<arglist> ?? $<arglist>.ast !! [];
+
+ if $pname<iname> {
+ $/.CURSOR.sorry('Indirect method calls NYI');
+ $pname = {name => 'alpha'};
+ }
+
+ my $callop;
+ if $is_lexical {
+ $callop = ::Op::CallSub.new(invocant => mklex($/, "&$name"),
+ positionals => [ mklex($/, '$¢'), @$args ]);
+ } else {
+ $callop = ::Operator::Method.new(name => $pname<name>, :$args,
+ package => $pname<pkg> && $pname<pkg>.xref)\
+ .with_args($/, mklex($/, '$¢'));
+ }
+
+ my $regex = self.rxembed($/, $callop, True);
+
+ make ::RxOp::Subrule.new(regex => $regex);
+ }
+ make self.rxcapturize($/, ~$<longname>, $/.ast);
+}
method assertion:variable ($/) {
given substr($/,0,1) {
when '&' {
View
11 test2.pl
@@ -42,6 +42,17 @@
is ("fooooooo" ~~ / <@a3> /), 'fooooooo', '<@var> has longest-token semantics (compiling)';
is ("foo" ~~ /<."alpha"()>/), "f", "dottyop assertions work";
+
+ my regex sam { \d+ }
+ is ("fo23op" ~~ /<sam>/), "23", "lexical regexes can be used without &";
+ {
+ sub alpha() { }
+ is ("xyz" ~~ /<alpha>/), "x", "non-regex subs do not confuse";
+ }
+ {
+ my regex alpha { . }
+ is ("4e" ~~ /<.alpha>/), "e", "leading dot forces method interpretation";
+ }
}
{
Please sign in to comment.
Something went wrong with that request. Please try again.