Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implement $var in regexes using Regex objects as subregexes (fixes #77)

  • Loading branch information...
commit 886540f65ef10be0969586c23789fc8210946a7d 1 parent 86bc474
@sorear authored
View
1  docs/TODO.S05
@@ -18,7 +18,6 @@ All line numbers are relative to c4882a67. Also, deliberate discrepencies.)
( 933) Don't know how fail is supposed to work there
( 978) No negative quantifiers
(1057) No special handling of zero-width matches DISCUSS
-(1124) 'Regex' scalar values not called (ticket #77)
(1172) No auto-declared temporary variables $x = <.ident>
(1178) No bindings to existing variables
(1186) No interpolation of arrays or || @array DISCUSS PARSE
View
8 lib/CodeGen.cs
@@ -2769,6 +2769,14 @@ class NamProcessor {
Tokens.RxFrame.GetMethod(FixStr(z[1])), args);
return CpsOp.Goto("backtrack", true, call);
};
+ handlers["rxlprim"] = delegate(NamProcessor th, object[] z) {
+ CpsOp[] args = new CpsOp[z.Length - 1];
+ for(int i = 0; i < z.Length - 2; i++)
+ args[i+1] = th.Scan(z[i+2]);
+ args[0] = CpsOp.RxFrame();
+ return CpsOp.CpsCall(Tokens.Variable,
+ Tokens.RxFrame.GetMethod(FixStr(z[1])), args);
+ };
handlers["const"] = delegate(NamProcessor th, object[] z) {
object[] ch = z[1] as object[];
string chh = JScalar.S(ch[0]);
View
25 lib/Cursor.cs
@@ -509,6 +509,20 @@ public sealed class RxFrame: IFreeze {
}
}
+ public Frame scalar_var(Frame th, Variable var) {
+ P6any o = var.Fetch();
+ if (o.Isa(Kernel.RegexMO)) {
+ return o.Invoke(th, new Variable[] { MakeCursorV() }, null);
+ } else {
+ if (Exact(o.mo.mro_raw_Str.Get(var))) {
+ th.resultSlot = MakeCursorV();
+ } else {
+ th.resultSlot = Kernel.NilP.mo.typeVar;
+ }
+ return th;
+ }
+ }
+
public void PushConjStart() {
st.ns = new NState(bt, "CSTART", st.ns);
st.ns.quant = st.pos;
@@ -808,24 +822,17 @@ public Cursor(P6any proto, string text, P6any actions)
int l = backing_ca.Length;
int p = pos;
- VarDeque ks = new VarDeque();
-
- P6opaque lst = new P6opaque(Kernel.ListMO);
- lst.slots[0 /*items*/] = ks;
- lst.slots[1 /*rest*/ ] = new VarDeque();
-
if (p != 0 && p != l && CC.Word.Accepts(backing[p]) &&
CC.Word.Accepts(backing[p-1])) {
if (Trace)
Console.WriteLine("! no match <ws> at {0}", pos);
+ return Kernel.NilP.mo.typeVar;
} else {
while (p != l && Char.IsWhiteSpace(backing, p)) { p++; }
if (Trace)
Console.WriteLine("* match <ws> at {0} to {1}", pos, p);
- ks.Push(Kernel.NewROScalar(At(p)));
+ return Kernel.NewROScalar(At(p));
}
-
- return Kernel.NewRWListVar(lst);
}
}
View
62 src/niecza
@@ -25,7 +25,68 @@ use STD;
# }
# }
+# RxOp::VarString.param NO LONGER USED
+
+class RxOp::ListPrim is RxOp {
+ has Str $.name; # used for LTM cheatery
+ has Str $.type;
+ has $.ops = die "RxOp::Variable.ops required"; # Op
+
+ method ctxopzyg() { $!ops, 1 }
+ method opzyg() { $!ops }
+
+ method code($body) {
+ my $bt = self.label;
+
+ my @code;
+ push @code, CgOp.rxcall("InitCursorList",
+ CgOp.rxlprim($!type, $!ops.cgop($body)));
+ push @code, CgOp.label($bt);
+ push @code, CgOp.rxincorpshift([], 0, $bt);
+ @code;
+ }
+
+ method lad() { $!type eq 'scalar_var' ?? ['Param', $!param] !! ['Imp'] }
+}
+
augment class NieczaActions {
+method metachar:var ($/) {
+ sub _isnum { $_ ~~ /^\d+$/ }
+ if $<binding> {
+ my $a = $<binding><quantified_atom>.ast.uncut;
+ my $cid = $<variable>.ast.<capid>;
+
+ if !defined $cid {
+ $/.CURSOR.sorry("Non-Match bindings NYI");
+ make ::RxOp::Sequence.new;
+ return Nil;
+ }
+
+ if $a.^isa(::RxOp::VoidBlock) {
+ make ::RxOp::SaveValue.new(capid => $cid, block => $a.block);
+ return Nil;
+ }
+
+ if _isnum($cid) {
+ %*RX<paren> = $cid + 1;
+ }
+
+ make self.rxcapturize($/, $cid, $a);
+ return;
+ }
+
+ my $kind = 'scalar_var';
+ given substr($<variable>,0,1) {
+ when '$' { $kind = 'scalar_var'; }
+ when '@' { $kind = 'list_var'; }
+ default {
+ $/.CURSOR.sorry('Only $ and @ variables may be used in regexes for now');
+ }
+ }
+ make ::RxOp::ListPrim.new(name => ~$<variable>, type => $kind,
+ ops => self.rxembed($/,
+ self.do_variable_reference($/, $<variable>.ast), True));
+}
method circumfix:sigil ($/) {
# XXX duplicates logic in variable
if $<semilist>.ast.elems == 0 {
@@ -126,6 +187,7 @@ augment class RxOp::Quantifier {
}
CgOp._register_ops: < who sc_root sc_indir temporize _addmethod _invalidate
+ rxlprim
>;
my $usage = q:to/EOM/;
View
3  test2.pl
@@ -20,6 +20,9 @@
"bar" ~~ / { make 5 } /;
is $(), 5, '$() gets AST';
+my $rx = /a+/;
+is ("ooofaaabkkk" ~~ /f $rx b/), "faaab", '$var can call regexes';
+
{
my class Bt {
has $!pie;
Please sign in to comment.
Something went wrong with that request. Please try again.