Permalink
Browse files

[PAST::Regex] added more regex compiler scaffolding - lots of things …

…faked, but it "works"
  • Loading branch information...
1 parent c6aa078 commit 91a2613762d6077826e51d1125492f65aa2a117d @diakopter diakopter committed Nov 23, 2010
Showing with 133 additions and 71 deletions.
  1. +5 −3 common/NQP/NQPSetting.pm
  2. +81 −65 common/NQP/P6Objects.pm
  3. +47 −3 dotnet/compiler/PAST2DNSTCompiler.pm
View
@@ -204,10 +204,10 @@ my knowhow NQPCapture is repr('P6capture') {
method new() {
nqp::instance_of(self.WHAT)
}
- method at_pos($pos) {
+ method pos_at($pos) {
nqp::llcap_get_at_pos(self, $pos)
}
- method at_key($key) {
+ method key_at($key) {
nqp::llcap_get_at_key(self, $key)
}
method bind_pos($pos, $val) {
@@ -431,7 +431,9 @@ sub die($message) {
}
sub substr(NQPStr $str, NQPInt $offset, NQPInt $length?) {
- nqp::substr($str, $offset, $length)
+ nqp::repr_defined($length)
+ ?? nqp::substr($str, $offset, $length)
+ !! nqp::substr($str, $offset)
}
# For tests.
View
@@ -30,17 +30,22 @@ class Mu {
class Capture {
has $.cap;
method new() {
- my $obj := self.CREATE();
- $obj.BUILD();
+ my $obj := self.CREATE;
+ $obj.BUILD;
$obj;
}
+
+ method CREATE() {
+ nqp::instance_of(self)
+ }
+
method BUILD() {
- $!cap := nqp::instance_of(NQPCapture.WHAT)
+ $!cap := nqp::instance_of(NQPCapture);
}
- method at_pos($pos) {
+ method pos_at($pos) {
nqp::llcap_get_at_pos($!cap, $pos)
}
- method at_key($key) {
+ method key_at($key) {
nqp::llcap_get_at_key($!cap, $key)
}
method bind_pos($pos, $val) {
@@ -115,70 +120,76 @@ class Regex::Cursor {
[]
}
+ method new() {
+ self.CREATE();
+ }
+
+ method CREATE() {
+ nqp::instance_of(self)
+ }
+
# Return this cursor's current Match object, generating a new one
# for the Cursor if one hasn't been created yet.
method MATCH() {
my $match := $!match;
- if !nqp::repr_defined($match) || !$match {
- if !nqp::repr_defined($match) {
- # First, create a Match object and bind it
- $match := self.new_match();
- self.match($match);
- $match.cursor(self);
- $match.target($!target);
- $match.to($!to);
- $match.from($!from);
-
- # Create any arrayed subcaptures.
- if nqp::repr_defined(@!caparray) {
- my @caparray := @!caparray;
- my %caphash := NQPHash.new();
- my @arr;
- my $keyint;
- for @caparray {
- @arr := self.new_array();
- %caphash{$_} := @arr;
- if nqp::is_cclass_str_index("Numeric", $_, 0) {
- $match.bind_pos($_, @arr);
- } else {
- $match.bind_key($_, @arr);
- }
+ if !nqp::repr_defined($match) {
+ # First, create a Match object and bind it
+ $match := self.new_match;
+ $!match := $match;
+ $match.cursor(self);
+ $match.target($!target);
+ $match.to($!pos);
+ $match.from($!from);
+
+ # Create any arrayed subcaptures.
+ if nqp::repr_defined(@!caparray) {
+ my @caparray := @!caparray;
+ my %caphash := NQPHash.new();
+ my @arr;
+ my $keyint;
+ for @caparray {
+ @arr := self.new_array();
+ %caphash{$_} := @arr;
+ if nqp::is_cclass_str_index("Numeric", $_, 0) {
+ $match.bind_pos($_, @arr);
+ } else {
+ $match.bind_key($_, @arr);
}
- # If it's not a successful match, or if there are
- # no saved subcursors, we're done.
- my @cstack := @!cstack;
- if $!to >= $!from || !nqp::repr_defined(@cstack) || !@cstack {
- my $subcur;
- my $submatch;
- my $names;
- my @namelist;
- for @cstack {
- if $_ ~~ Regex::Cursor {
- $subcur := $_;
- $names := $subcur.names;
- if nqp::repr_defined($names) {
- $submatch := $subcur.MATCH();
- if nqp::index_str($names, "=") >= 0 {
- @namelist := nqp::split_str($names, "=")
+ }
+ # If it's not a successful match, or if there are
+ # no saved subcursors, we're done.
+ my @cstack := @!cstack;
+ if $!to >= $!from || !nqp::repr_defined(@cstack) || !@cstack {
+ my $subcur;
+ my $submatch;
+ my $names;
+ my @namelist;
+ for @cstack {
+ if $_ ~~ Regex::Cursor {
+ $subcur := $_;
+ $names := $subcur.names;
+ if nqp::repr_defined($names) {
+ $submatch := $subcur.MATCH();
+ if nqp::index_str($names, "=") >= 0 {
+ @namelist := nqp::split_str($names, "=")
+ } else {
+ @namelist := [];
+ @namelist.push($names)
+ }
+ for @namelist {
+ $keyint := nqp::is_cclass_str($_, "Numeric");
+ if nqp::repr_defined(@caparray)
+ && nqp::repr_defined(%caphash{$_}) {
+ if $keyint {
+ $match.pos_at($_).push($submatch);
+ } else {
+ $match.key_at($_).push($submatch);
+ }
} else {
- @namelist := [];
- @namelist.push($names)
- }
- for @namelist {
- $keyint := nqp::is_cclass_str($_, "Numeric");
- if nqp::repr_defined(@caparray)
- && nqp::repr_defined(%caphash{$_}) {
- if $keyint {
- $match.pos_at($_).push($submatch);
- } else {
- $match.key_at($_).push($submatch);
- }
+ if $keyint {
+ $match.bind_pos($_, $submatch);
} else {
- if $keyint {
- $match.bind_pos($_, $submatch);
- } else {
- $match.bind_key($_, $submatch);
- }
+ $match.bind_key($_, $submatch);
}
}
}
@@ -205,7 +216,7 @@ class Regex::Cursor {
#}
my $cap := Capture.new;
$cap.bind_pos(0, $cur);
- Ops.invoke($rule, $cap).MATCH;
+ $rule($cur, $cap).MATCH
}
# Return the next match from a successful Cursor.
@@ -409,11 +420,16 @@ class Regex::Cursor {
class Regex::Regex {
has $!regex_block;
method new($regex_block) {
+ my $obj := nqp::instance_of(self);
+ $obj.BUILD($regex_block);
+ $obj
+ }
+ method BUILD($regex_block) {
$!regex_block := $regex_block;
- self
}
method ACCEPTS($target) {
- Regex::Cursor.new.parse($target, :rule($!regex_block))
+ my $cur := Regex::Cursor.new;
+ $cur.parse($target, :rule($!regex_block))
}
}
@@ -1172,8 +1172,27 @@ our multi sub dnst_for(PAST::Regex $r) {
my $pasttype := $r.pasttype;
pir::die("Don't know how to compile toplevel regex pasttype $pasttype.") if $pasttype ne 'concat';
my $stmts := PAST::Stmts.new;
-
- $stmts.push(dnst_for(PAST::Val.new( :value(1) )));
+ my $re_cur_tmp := DNST::Temp.new(
+ :name(get_unique_id('re_cur')), :type('RakudoObject'),
+ dnst_for(PAST::Var.new( :name('self'), :scope('lexical')))
+ );
+ my $*re_cur := DNST::Local.new($re_cur_tmp.name);
+ $stmts.push($re_cur_tmp);
+ my $re_pos_tmp := DNST::Temp.new(
+ :name(get_unique_id('re_pos')), :type('RakudoObject'),
+ dnst_for(PAST::Op.new(
+ :pasttype('callmethod'), :name('pos'),
+ $*re_cur
+ ))
+ );
+ my $*re_pos := DNST::Local.new($re_pos_tmp.name);
+ $stmts.push($re_pos_tmp);
+ for @($r) {
+ $stmts.push(dnst_regex($_));
+ }
+ $stmts.push(DNST::Return.new(
+ $*re_cur
+ ));
dnst_for($stmts);
}
@@ -1183,7 +1202,32 @@ our multi sub dnst_regex(PAST::Regex $r) {
my $pasttype := $r.pasttype;
if $pasttype eq 'concat' {
# Handle a concatenation of regexes.
- $res := dnst_for(PAST::Val.new( :value(1) ));
+ my $stmts := PAST::Stmts.new;
+ for @($r) {
+ $stmts.push(dnst_regex($_));
+ }
+ $res := dnst_for($stmts);
+ }
+ elsif $pasttype eq 'scan' {
+ # Code for initial regex scan.
+ my $stmts := PAST::Stmts.new;
+
+ $res := dnst_for($stmts)
+ }
+ elsif $pasttype eq 'literal' {
+ # Code for literal characters. Faked/stubbed.
+ my $stmts := PAST::Stmts.new;
+ $stmts.push(dnst_for(PAST::Op.new(
+ :pasttype('callmethod'), :name('pos'),
+ $*re_cur,
+ PAST::Val.new( :value(1) )
+ )));
+ $res := dnst_for($stmts)
+ }
+ elsif $pasttype eq 'pass' {
+ # Code for success
+ my $stmts := PAST::Stmts.new;
+ $res := dnst_for($stmts)
}
else {
pir::die("Don't know how to compile regex pasttype $pasttype.");

0 comments on commit 91a2613

Please sign in to comment.