diff --git a/CgOp.pm b/CgOp.pm index f4071271..baa49d3b 100644 --- a/CgOp.pm +++ b/CgOp.pm @@ -9,7 +9,7 @@ use warnings; package CgOp; use Moose; - has zyg => (isa => 'ArrayRef', is => 'ro', default => sub { [] }); + has zyg => (isa => 'ArrayRef[CgOp]', is => 'ro', default => sub { [] }); # filled in by cps_convert # 0: returns on eval stack, can appear w/ non-empty # 1: returns in resultSlot, cannot appear w/ non-empty @@ -429,7 +429,8 @@ use warnings; sub box { rawscall('Kernel.BoxAny', $_[1], - $_[0] eq 'Str' ? rawsget('Kernel.StrP') : + blessed($_[0]) ? $_[0] : + ($_[0] eq 'Str') ? rawsget('Kernel.StrP') : fetch(scopedlex($_[0]))); } diff --git a/CodeGen.pm b/CodeGen.pm index 887263c7..fd684eed 100644 --- a/CodeGen.pm +++ b/CodeGen.pm @@ -54,6 +54,10 @@ use 5.010; { SearchForHandler => [c => 'Void'] }, 'Niecza.LexoticControlException' => { SearchForHandler => [c => 'Void'] }, + 'Cursor' => + { At => [m => 'Cursor'], + Exact => [m => 'Cursor'], + pos => [f => 'Int32'] }, 'System.IO.File.ReadAllText' => [m => 'System.String'], diff --git a/Cursor.cs b/Cursor.cs index c1c7e480..6ae7cdd5 100644 --- a/Cursor.cs +++ b/Cursor.cs @@ -1,25 +1,45 @@ // this exists to allow O(1) addition, since additions (esp. in the presence // of backtracking) dominate lookups -public class Matched { - Matched prev; - string name; - Variable val; - bool listify_sentinel; -} - -public class Match { - public string backing; - public int from; - public int to; - public Dictionary captures; -} - -public class Xact { - +//public class Matched { +// Matched prev; +// string name; +// Variable val; +// bool listify_sentinel; +//} +// +//public class Match { +// public string backing; +// public int from; +// public int to; +// public Dictionary captures; +//} +// +//public class Xact { +// public class Cursor { - // TODO: use a mutable form, for + // XXX It's a bit wrong that we ref the string both from the cursor and + // from $*ORIG. public string backing; public int pos; - public Matched captures; + + public Cursor(string backing, int pos) { + this.backing = backing; + this.pos = pos; + } + + public Cursor(string backing) : this(backing, 0) { } + + public Cursor At(int npos) { + return new Cursor(backing, npos); + } + + public Cursor Exact(string what) { + if (backing.Length - what.Length >= pos && + backing.Substring(pos, what.Length) == what) { + return At(pos + what.Length); + } else { + return null; + } + } } diff --git a/Niecza.proj b/Niecza.proj index 17b58edf..a94f85f0 100644 --- a/Niecza.proj +++ b/Niecza.proj @@ -36,8 +36,8 @@ - - + diff --git a/SAFE.setting b/SAFE.setting index b81a2627..24f26edb 100644 --- a/SAFE.setting +++ b/SAFE.setting @@ -852,8 +852,13 @@ sub postcircumfix:<{ }> is rawcall { # these are immutable, though we may wind up reusing them in some cases by # uniqueness rules (TBD) my class Cursor { - has $.str; - has $.from; + method new($str) { Q:CgOp { (box (@ (l self)) (rawnew Cursor (unbox String + (@ (l $str))))) } } + method pos { Q:CgOp { (box Num (cast Double (getfield pos + (unbox Cursor (@ (l self)))))) } } + method cursor($np) { Q:CgOp { (box (@ (l self)) (rawcall + (unbox Cursor (@ (l self))) At + (cast Int32 (unbox Double (@ (l $np)))))) } } } # Outside a regex, a result is a lazy list. @@ -918,21 +923,23 @@ sub _rxplus($C, $sub) { sub _rxstr($C, $str) { #say "_rxstr : " ~ ($C.str ~ (" @ " ~ ($C.from ~ (" ? " ~ $str)))); - if (($C.from + $str.chars) <= $C.str.chars) && - ($C.str.substr($C.from, $str.chars) eq $str) { - _rxone(Cursor.RAWCREATE("str", $C.str, "from", ($C.from + $str.chars))); - } else { - &_rxnone; - } + Q:CgOp { + (letn rt (rawcall (unbox Cursor (@ (l $C))) Exact + (unbox String (@ (l $str)))) + [ternary + (!= (l rt) (null Cursor)) + (subcall (@ (l &_rxone)) (box (@ (l $C)) (l rt))) + (l &_rxnone)]) + }; } my class Regex is Sub { method ACCEPTS($str) { my $i = 0; my $win = 0; + my $C = Cursor.new($str); while !$win && ($i <= $str.chars) { - my $C = Cursor.RAWCREATE("str", $str, "from", $i); - if (self)($C) { + if (self)($C.cursor($i)) { $win = 1; } $i++; @@ -943,8 +950,8 @@ my class Regex is Sub { my class Grammar is Cursor { method parse($text) { - my @results := self.RAWCREATE("str", $text, "from", 0).TOP\ - .grep({ $_.from == $_.str.chars }); + my @results := self.new($text).TOP\ + .grep({ $_.pos == $text.chars }); @results ?? @results.shift !! Any; # TODO List.at-pos } }