Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement Match object generation
  • Loading branch information
sorear committed Sep 13, 2010
1 parent 10151ff commit 6679769
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 14 deletions.
29 changes: 27 additions & 2 deletions lib/Cursor.cs
Expand Up @@ -64,6 +64,9 @@ public sealed class RxFrame {
// any more Lists
public bool return_one;

// .from in matches
public int from;

// our backing string, in a cheap to index form
public string orig_s;
public char[] orig;
Expand All @@ -80,6 +83,7 @@ public sealed class RxFrame {
rootf = bt = new Choice(csr.xact, "RULE " + name, -1, default(State));
st.klasses = new PSN<DynMetaObject>(csr.klass, null);
st.pos = csr.pos;
from = csr.pos;
}

public Frame Backtrack(Frame th) {
Expand Down Expand Up @@ -226,16 +230,21 @@ public sealed class RxFrame {
return new Cursor(st.klasses.obj, bt, orig_s, orig, st.pos);
}

public Cursor MakeMatch() {
return new Cursor(orig_s, from, st.pos, st.captures, st.capnames);
}

public static DynMetaObject MatchMO;
public static DynMetaObject ListMO;
public static DynMetaObject GatherIteratorMO;
public static IP6 EMPTYP;
public Frame End(Frame th) {
if (return_one) {
return Kernel.Take(th, Kernel.NewROScalar(MakeCursor()));
return Kernel.Take(th, Kernel.NewROScalar(MakeMatch()));
} else {
return_one = true;
VarDeque ks = new VarDeque();
ks.Push(Kernel.NewROScalar(MakeCursor()));
ks.Push(Kernel.NewROScalar(MakeMatch()));
DynObject it = new DynObject(GatherIteratorMO);
it.SetSlot("reify", Kernel.NewRWScalar(Kernel.AnyP));
it.SetSlot("frame", Kernel.NewRWScalar(th));
Expand All @@ -253,6 +262,9 @@ public sealed class RxFrame {

// This is used to carry match states in and out of subrules. Within subrules,
// match states are represented much more ephemerally in the state of RxFrame.

// this does double duty backing Match; note that Cursor and Match need to be
// treated polymorphically in a couple places
public class Cursor : IP6 {
public static bool Trace =
Environment.GetEnvironmentVariable("NIECZA_RX_TRACE") != null;
Expand All @@ -261,11 +273,24 @@ public class Cursor : IP6 {
public Choice xact;
public string backing;
public char[] backing_ca;
public int from;
public int pos;
public PSN<Cursor> captures;
public PSN<string[]> capnames;

public Cursor(IP6 proto, string text)
: this(proto.GetMO(), null, text, text.ToCharArray(), 0) { }

public Cursor(string backing, int from, int pos, PSN<Cursor> captures,
PSN<string[]> capnames) {
this.backing = backing;
this.captures = captures;
this.capnames = capnames;
this.pos = pos;
this.from = from;
this.klass = RxFrame.MatchMO;
}

public Cursor(DynMetaObject klass, Choice xact, string backing, char[] backing_ca, int pos) {
this.klass = klass;
this.xact = xact;
Expand Down
26 changes: 18 additions & 8 deletions lib/SAFE.setting
Expand Up @@ -831,7 +831,20 @@ my class Cursor {
method ws() { Q:CgOp { (rawcall (cast Cursor (@ {self})) SimpleWS) } }
}
my class Match {
method new($) { die "Match.new NYI" }
method from { Q:CgOp { (box Num (cast Double (getfield from
(cast Cursor (@ {self}))))) } }
method to { Q:CgOp { (box Num (cast Double (getfield pos
(cast Cursor (@ {self}))))) } }
method orig { Q:CgOp {
(box Str (getfield backing (cast Cursor (@ {self})))) } }
method chars { $.defined ?? $.to - $.from !! 0 }
method Str { $.defined ?? $.orig.substr($.from, $.chars) !! "" }
}

PRE-INIT {
Q:CgOp { (rnull (rawsset RxFrame.MatchMO (rawcall (@ {Match}) GetMO))) };
ClassHOW.HOW.add-method("add-multiregex",
anon method add-multiregex($name, $rx) {
Q:CgOp { (prog
Expand All @@ -845,22 +858,19 @@ PRE-INIT {
my class Regex is Sub {
method ACCEPTS($str) {
my $i = 0;
my $win = 0;
my $mat;
my $C = Cursor.new($str);
while !$win && ($i <= $str.chars) {
if (self)($C.cursor($i)) {
$win = 1;
}
$i++;
while !$mat && ($i <= $str.chars) {
$mat = (self)($C.cursor($i++));
}
$win;
$mat.head;
}
}

my class Grammar is Cursor {
method parse($text) {
my @results := self.new($text).TOP\
.grep({ $_.pos == $text.chars });
.grep({ $_.to == $text.chars });
@results ?? @results.shift !! Any; # TODO List.at-pos
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/CodeGen.pm
Expand Up @@ -78,6 +78,7 @@ use 5.010;
LTMPushAlts => [m => 'Void'],
PushCapture => [m => 'Void'],
MakeCursor => [m => 'Cursor'],
MakeMatch => [m => 'Cursor'],
SetPos => [m => 'Void'],
Backtrack => [c => 'Void'],
End => [c => 'Void'] },
Expand All @@ -88,6 +89,7 @@ use 5.010;
'Cursor' =>
{ At => [m => 'Cursor'],
pos => [f => 'Int32'],
from => [f => 'Int32'],
backing => [f => 'String'],
SimpleWS => [m => 'Variable'] },
'Lexer' =>
Expand Down
13 changes: 12 additions & 1 deletion test.pl
Expand Up @@ -2,7 +2,7 @@

use Test;

plan 424;
plan 430;

ok 1, "one is true";
ok 2, "two is also true";
Expand Down Expand Up @@ -946,3 +946,14 @@
("yky",), ("yfooy", "ybary");
rxtest /y [ [a||b] | c ]: y/, "|| exposes a declarative prefix",
("yay","yby","ycy"), Nil;
{
# one CgOp bug manifested as a failure to compile this
ok (/ <?before x>: <ws>: /).defined, "unnamed regression";
my $ma = ("ab29x" ~~ /\d+/);
ok $ma.defined, "match is defined";
ok $ma.WHAT === Match, "matches are Match";
is $ma.from, 2, '$ma.from works';
is $ma.to, 4, '$ma.to works';
is $ma.Str, '29', '$ma.Str works';
}
3 changes: 0 additions & 3 deletions test2.pl
@@ -1,7 +1,4 @@
# vim: ft=perl6
use Test;

# one CgOp bug manifested as a failure to compile this
ok (/ <?before x>: <ws>: /).defined, "unnamed regression";

done-testing;

0 comments on commit 6679769

Please sign in to comment.