Permalink
Browse files

Implement @var in regexes, incl. LTM and regex elements

  • Loading branch information...
1 parent 886540f commit 95e070352f389939edfd0bb2f0f9ca16bed21f5a @sorear committed Dec 15, 2011
Showing with 103 additions and 4 deletions.
  1. +1 −1 docs/TODO.S05
  2. +80 −0 lib/Cursor.cs
  3. +11 −1 src/niecza
  4. +11 −2 test2.pl
View
@@ -20,7 +20,7 @@ All line numbers are relative to c4882a67. Also, deliberate discrepencies.)
(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 interpolation of arrays or || @array DISCUSS PARSE
+(1186) No || @array temporal-alternation syntax DISCUSS PARSE
(1253) No handling of formal parameters in LTM
(1258) No {*} and funky proto handling in general
(1276) Declarativeness of constants is insufficiently general
View
@@ -523,6 +523,86 @@ public sealed class RxFrame: IFreeze {
}
}
+ public Frame list_var(Frame th, Variable var) {
+ VarDeque iter = Builtins.start_iter(var);
+ List<object> toks = new List<object>();
+ List<LAD> lads = new List<LAD>();
+
+ NFA pad = new NFA();
+ pad.cursor_class = st.ns.klass;
+
+ while (Kernel.IterHasFlat(iter, true)) {
+ Variable svar = iter.Shift();
+ P6any sobj = svar.Fetch();
+
+ if (sobj.Isa(Kernel.RegexMO)) {
+ toks.Add(sobj);
+
+ pad.outer_stack.Add((Frame)sobj.GetSlot("outer"));
+ pad.info_stack.Add((SubInfo)sobj.GetSlot("info"));
+ lads.Add(pad.info_stack[0].ltm.Reify(pad));
+ pad.outer_stack.Clear();;
+ pad.info_stack.Clear();
+ } else {
+ string str = sobj.mo.mro_raw_Str.Get(svar);
+ toks.Add(str);
+ lads.Add(new LADStr(str));
+ }
+ }
+
+ int[] cases = (new Lexer(pad, "array_var", lads.ToArray())).
+ Run(global.orig_s, st.pos);
+
+ Frame nth = th.MakeChild(null, ArrayHelperSI, Kernel.AnyP);
+ nth.lex0 = MakeCursor();
+ nth.lex1 = toks;
+ nth.lex2 = cases;
+
+ return nth;
+ }
+
+ private static SubInfo ArrayHelperSI = new SubInfo("KERNEL ArrayHelper", ArrayHelperC);
+ private static Frame ArrayHelperC(Frame th) {
+ int[] cases = (int[]) th.lex2;
+ List<object> toks = (List<object>) th.lex1;
+ object tok;
+ switch (th.ip) {
+ default:
+ return Kernel.Die(th, "Invalid IP");
+ case 1:
+ return th.rx.Backtrack(th);
+ case 0:
+ th.rx = new RxFrame("ArrayHelper", (Cursor) th.lex0, false, false);
+ th.lexi0 = 0;
+ goto case 2;
+ case 2:
+ if (th.lexi0 == cases.Length)
+ goto case 1;
+ th.rx.PushBacktrack(2);
+ tok = toks[cases[th.lexi0++]];
+ if (tok is string) {
+ if (!th.rx.Exact((string)tok))
+ goto case 1;
+ th.ip = 5;
+ return th.rx.MakeMatch(th);
+ } else {
+ th.ip = 3;
+ return ((P6any)tok).Invoke(th, new Variable[] {
+ th.rx.MakeCursorV() }, null);
+ }
+ case 3:
+ th.lex2 = Builtins.start_iter((Variable) th.resultSlot);
+ goto case 4;
+ case 4:
+ if (!Kernel.IterHasFlat((VarDeque)th.lex2, true))
+ goto case 1;
+ th.ip = 4;
+ return th.rx.EndWith(th, (Cursor) ((VarDeque)th.lex2).Shift().Fetch());
+ case 5:
+ th.ip = 1;
+ return th.rx.End(th);
+ }
+ }
public void PushConjStart() {
st.ns = new NState(bt, "CSTART", st.ns);
st.ns.quant = st.pos;
View
@@ -46,10 +46,20 @@ class RxOp::ListPrim is RxOp {
@code;
}
- method lad() { $!type eq 'scalar_var' ?? ['Param', $!param] !! ['Imp'] }
+ method lad() { $!type eq 'scalar_var' ?? ['Param', $!name] !! ['Imp'] }
}
augment class NieczaActions {
+method op_for_regex($/, $rxop) {
+ my @lift = $rxop.oplift;
+ my $ltm = ::GLOBAL::OptRxSimple.run_lad($rxop.lad);
+ my ($orxop, $mb) = ::GLOBAL::OptRxSimple.run($rxop);
+ my $sub = self.thunk_sub(::Op::RegexBody.new(|node($/),
+ canback => $mb, pre => @lift, rxop => $orxop),
+ class => 'Regex', params => ['self'], :$ltm);
+ $sub.add_my_name('$/');
+ self.block_expr($/, $sub);
+}
method metachar:var ($/) {
sub _isnum { $_ ~~ /^\d+$/ }
if $<binding> {
View
@@ -20,8 +20,17 @@
"bar" ~~ / { make 5 } /;
is $(), 5, '$() gets AST';
-my $rx = /a+/;
-is ("ooofaaabkkk" ~~ /f $rx b/), "faaab", '$var can call regexes';
+{
+ my $rx = /a+/;
+ is ("ooofaaabkkk" ~~ /f $rx b/), "faaab", '$var can call regexes';
+
+ my @a1 = ( 'fo', 'fooo', 'bar' );
+ is ("barxy" ~~ / @a1 /), "bar", '@var works';
+ is ("fooooooo" ~~ / @a1 /), 'fooo', '@var has longest-token semantics';
+
+ my @a2 = ( /fooo/, /fo+/ );
+ is ("fooooooo" ~~ / @a2 /), "fooooooo", '@var has longest-token semantics with regex elements';
+}
{
my class Bt {

0 comments on commit 95e0703

Please sign in to comment.