@@ -246,8 +246,13 @@ role NQPCursorRole is export {
246
246
}
247
247
248
248
method ! cursor_push_cstack ($ capture ) {
249
- $ ! cstack := [] unless nqp :: defined ($ ! cstack );
250
- nqp :: push ($ ! cstack , $ capture );
249
+ if ! nqp :: defined ($ ! cstack ) { $ ! cstack := [$ capture ] }
250
+ elsif ! nqp ::isnull($ capture ) {
251
+ my $ name := nqp ::getattr($ capture , $ ? CLASS , ' $!name' );
252
+ if ! nqp ::isnull($ name ) && nqp :: defined ($ name ) {
253
+ nqp :: push ($ ! cstack , $ capture );
254
+ }
255
+ }
251
256
$ ! cstack ;
252
257
}
253
258
@@ -855,15 +860,19 @@ class NQPCursor does NQPCursorRole {
855
860
# For captures with lists, initialize the lists.
856
861
my % caplist := $ NO_CAPS ;
857
862
my $ rxsub := nqp ::getattr(self , NQPCursor, ' $!regexsub' );
863
+ my $ onlyname := ' ' ;
864
+ my int $ namecount := 0 ;
858
865
if ! nqp ::isnull($ rxsub ) && nqp :: defined ($ rxsub ) {
859
866
% caplist := nqp :: can ($ rxsub , ' CAPS' ) ?? $ rxsub . CAPS() !! nqp ::null();
860
867
if ! nqp ::isnull(% caplist ) && nqp ::istrue(% caplist ) {
861
868
my $ iter := nqp :: iterator (% caplist );
862
869
while $ iter {
863
870
my $ curcap := nqp :: shift ($ iter );
871
+ my str $ name := nqp ::iterkey_s($ curcap );
872
+ $ namecount ++ ;
864
873
if nqp ::iterval($ curcap ) >= 2 {
865
- my str $ name := nqp ::iterkey_s( $ curcap ) ;
866
- nqp ::iscclass( nqp ::const::CCLASS_NUMERIC, $ name , 0 )
874
+ $ onlyname := $ name if $ namecount == 1 ;
875
+ nqp :: ord ( $ name ) < 58
867
876
?? nqp ::bindpos(
868
877
nqp ::defor($ list , $ list := nqp ::list()),
869
878
$ name , nqp ::list())
@@ -875,9 +884,32 @@ class NQPCursor does NQPCursorRole {
875
884
876
885
# Walk the Cursor stack and populate the Cursor.
877
886
my $ cs := nqp ::getattr(self , NQPCursor, ' $!cstack' );
878
- if ! nqp ::isnull(% caplist ) && % caplist && ! nqp ::isnull($ cs ) && nqp ::istrue($ cs ) {
887
+ if nqp ::isnull($ cs ) || ! nqp ::istrue($ cs ) {}
888
+ elsif $ namecount == 1 && $ onlyname ne ' ' && ! nqp ::eqat($ onlyname ,' $!' ,0 ) {
889
+ # If there's only one destination, avoid repeated hash lookups
890
+ my int $ cselems := nqp :: elems ($ cs );
891
+ my int $ csi ;
892
+ my $ dest ;
893
+ if nqp :: ord ($ onlyname ) < 58 {
894
+ $ dest := nqp ::atpos($ list , $ onlyname );
895
+ }
896
+ else {
897
+ $ dest := nqp ::atkey($ hash , $ onlyname );
898
+ }
899
+ while $ csi < $ cselems {
900
+ my $ subcur := nqp ::atpos($ cs , $ csi );
901
+ my $ name := nqp ::getattr($ subcur , $ ? CLASS , ' $!name' );
902
+ if ! nqp ::isnull($ name ) && nqp :: defined ($ name ) {
903
+ my $ submatch := $ subcur . MATCH();
904
+ nqp :: push ($ dest , $ submatch );
905
+ }
906
+ $ csi ++ ;
907
+ }
908
+ }
909
+ elsif ! nqp ::isnull(% caplist ) && % caplist {
879
910
my int $ cselems := nqp :: elems ($ cs );
880
911
my int $ csi ;
912
+ # note($cselems);
881
913
while $ csi < $ cselems {
882
914
my $ subcur := nqp ::atpos($ cs , $ csi );
883
915
my $ name := nqp ::getattr($ subcur , $ ? CLASS , ' $!name' );
@@ -888,7 +920,7 @@ class NQPCursor does NQPCursorRole {
888
920
}
889
921
elsif nqp :: index ($ name , ' =' ) < 0 {
890
922
my int $ needs_list := % caplist {$ name } >= 2 ;
891
- if nqp ::iscclass( nqp ::const::CCLASS_NUMERIC, $ name , 0 ) {
923
+ if nqp :: ord ( $ name ) < 58 {
892
924
$ list := nqp ::list() unless nqp ::isconcrete($ list );
893
925
$ needs_list
894
926
?? nqp :: push (nqp ::atpos($ list , $ name ), $ submatch )
@@ -903,7 +935,7 @@ class NQPCursor does NQPCursorRole {
903
935
else {
904
936
for nqp :: split (' =' , $ name ) -> $ name {
905
937
my int $ needs_list := % caplist {$ name } >= 2 ;
906
- if nqp ::iscclass( nqp ::const::CCLASS_NUMERIC, $ name , 0 ) {
938
+ if nqp :: ord ( $ name ) < 58 {
907
939
$ list := nqp ::list() unless nqp ::isconcrete($ list );
908
940
$ needs_list
909
941
?? nqp :: push (nqp ::atpos($ list , $ name ), $ submatch )
@@ -919,6 +951,30 @@ class NQPCursor does NQPCursorRole {
919
951
}
920
952
$ csi ++ ;
921
953
}
954
+ # {
955
+ # my $iter := nqp::iterator(%caplist);
956
+ # while $iter {
957
+ # my $curcap := nqp::shift($iter);
958
+ # my str $name := nqp::iterkey_s($curcap);
959
+ # my int $iv := nqp::iterval($curcap);
960
+ # if $iv >= 2 {
961
+ # if nqp::iscclass(nqp::const::CCLASS_NUMERIC, $name, 0) {
962
+ # note("\t" ~ $name ~ "\t" ~ nqp::elems(nqp::atpos($list, $name)));
963
+ # }
964
+ # else {
965
+ # note("\t" ~ $name ~ "\t" ~ nqp::elems(nqp::atkey($hash, $name)));
966
+ # }
967
+ # }
968
+ # elsif $iv >= 1 {
969
+ # if nqp::iscclass(nqp::const::CCLASS_NUMERIC, $name, 0) {
970
+ # note("\t" ~ $name ~ "\t" ~ nqp::defined(nqp::atpos($list, $name)));
971
+ # }
972
+ # else {
973
+ # note("\t" ~ $name ~ "\t" ~ nqp::defined(nqp::atkey($hash, $name)));
974
+ # }
975
+ # }
976
+ # }
977
+ # }
922
978
}
923
979
nqp ::bindattr($ match , NQPCapture, ' @!array' , nqp ::isconcrete($ list ) ?? $ list !! @ EMPTY_LIST );
924
980
nqp ::bindattr($ match , NQPCapture, ' %!hash' , $ hash );
0 commit comments