@@ -343,64 +343,6 @@ role NQPMatchRole is export {
343
343
# self;
344
344
# }
345
345
346
- my $ NO_CAPS := nqp ::hash();
347
- method CAPHASH () {
348
- my $ caps := nqp ::hash();
349
- my % caplist := $ NO_CAPS ;
350
- my $ iter ;
351
- my str $ curcap ;
352
- my $ cs ;
353
- my int $ csi ;
354
- my int $ cselems ;
355
- my $ subcur ;
356
- my $ submatch ;
357
- my str $ name ;
358
-
359
- if ! nqp ::isnull($ ! regexsub ) && nqp :: defined ($ ! regexsub ) {
360
- % caplist := nqp :: can ($ ! regexsub , ' CAPS' ) ?? $ ! regexsub . CAPS() !! nqp ::null();
361
- if ! nqp ::isnull(% caplist ) && % caplist {
362
- $ iter := nqp :: iterator (% caplist );
363
- while $ iter {
364
- $ curcap := nqp ::iterkey_s(nqp :: shift ($ iter ));
365
- $ caps {$ curcap } := nqp ::list() if nqp ::atkey(% caplist , $ curcap ) >= 2 ;
366
- }
367
- }
368
- }
369
- if ! nqp ::isnull($ ! cstack ) && $ ! cstack {
370
- $ cs := $ ! cstack ;
371
- $ cselems := nqp :: elems ($ cs );
372
- while $ csi < $ cselems {
373
- $ subcur := nqp ::atpos($ cs , $ csi );
374
- $ submatch := $ subcur . MATCH;
375
- $ name := nqp ::getattr_s($ subcur , $ ? CLASS , ' $!name' );
376
- unless nqp ::isnull_s($ name ) {
377
- if nqp :: index ($ name , ' =' ) < 0 {
378
- % caplist {$ name } >= 2
379
- ?? nqp :: push ($ caps {$ name }, $ submatch )
380
- !! nqp ::bindkey($ caps , $ name , $ submatch );
381
- }
382
- else {
383
- for nqp :: split (' =' , $ name ) -> $ name {
384
- % caplist {$ name } >= 2
385
- ?? nqp :: push ($ caps {$ name }, $ submatch )
386
- !! nqp ::bindkey($ caps , $ name , $ submatch );
387
- }
388
- }
389
- }
390
- ++ $ csi ;
391
- }
392
- }
393
-
394
- # Once we've produced the captures, and if we know we're finished and
395
- # will never be backtracked into, we can release cstack and regexsub.
396
- unless nqp :: defined ($ ! bstack ) {
397
- $ ! cstack := nqp ::null();
398
- $ ! regexsub := nqp ::null();
399
- }
400
-
401
- $ caps ;
402
- }
403
-
404
346
method ! cursor_init ($ orig , : $ p = 0 , : $ c , : $ shared , : $ braid , : $ build , : $ fail_cursor , * % ignore ) {
405
347
my $ new := $ build ?? self !! self . CREATE();
406
348
unless $ shared {
@@ -1137,53 +1079,44 @@ role NQPMatchRole is export {
1137
1079
1138
1080
class NQPMatch is NQPCapture does NQPMatchRole {
1139
1081
my @ EMPTY_LIST := [];
1140
- my $ NO_CAPS := nqp ::hash();
1082
+ my % EMPTY_HASH := nqp ::hash();
1141
1083
my $ DID_MATCH := nqp ::create(NQPdidMATCH);
1142
1084
method MATCH () {
1143
1085
my $ match := nqp ::getattr(self , NQPMatch, ' $!match' );
1144
1086
if nqp ::isnull($ match ) || ! nqp ::istype($ match , NQPdidMATCH) {
1145
1087
# Set up basic state of (old) Match.
1146
1088
my $ list ;
1147
- my $ hash := nqp ::hash() ;
1089
+ my $ hash ;
1148
1090
nqp ::bindattr(self , NQPMatch, ' $!match' ,
1149
1091
nqp ::getattr_i(self , NQPMatch, ' $!pos' ) >= nqp ::getattr_i(self , NQPMatch, ' $!from' )
1150
1092
?? $ DID_MATCH
1151
1093
!! nqp ::null());
1152
1094
1153
1095
# For captures with lists, initialize the lists.
1154
- my % caplist := $ NO_CAPS ;
1155
- my $ rxsub := nqp ::getattr(self , NQPMatch, ' $!regexsub' );
1156
- my str $ onlyname := ' ' ;
1157
- my int $ namecount := 0 ;
1096
+ my $ rxsub := nqp ::getattr(self , NQPMatch, ' $!regexsub' );
1097
+ my str $ onlyname ;
1098
+ my int $ hascaps ;
1158
1099
if ! nqp ::isnull($ rxsub ) && nqp :: defined ($ rxsub ) {
1159
- % caplist := nqp :: can ($ rxsub , ' CAPS' ) ?? $ rxsub . CAPS() !! nqp ::null();
1160
- if ! nqp ::isnull(% caplist ) && nqp ::istrue(% caplist ) {
1161
- my $ iter := nqp :: iterator (% caplist );
1162
- while $ iter {
1163
- my $ curcap := nqp :: shift ($ iter );
1164
- my str $ name := nqp ::iterkey_s($ curcap );
1165
- ++ $ namecount ;
1166
- if nqp ::iterval($ curcap ) >= 2 {
1167
- $ onlyname := $ name if $ namecount == 1 ;
1168
- nqp :: ord ($ name ) < 58
1169
- ?? nqp ::bindpos(
1170
- nqp ::defor($ list , $ list := nqp ::list()),
1171
- $ name , nqp ::list())
1172
- !! nqp ::bindkey($ hash , $ name , nqp ::list());
1173
- }
1100
+ my $ capdesc := nqp :: can ($ rxsub , ' CAPS' ) ?? $ rxsub . CAPS() !! nqp ::null();
1101
+ if ! nqp ::isnull($ capdesc ) {
1102
+ $ hascaps := $ capdesc . has-captures();
1103
+ if $ hascaps {
1104
+ $ list := $ capdesc . prepare-list();
1105
+ $ hash := $ capdesc . prepare-hash();
1106
+ $ onlyname := $ capdesc . onlyname();
1174
1107
}
1175
1108
}
1176
1109
}
1177
1110
1178
1111
# Walk the Cursor stack and populate the Cursor.
1179
1112
my $ cs := nqp ::getattr(self , NQPMatch, ' $!cstack' );
1180
1113
if nqp ::isnull($ cs ) || ! nqp ::istrue($ cs ) {}
1181
- elsif $ namecount == 1 && $ onlyname ne ' ' && ! nqp ::eqat( $ onlyname , ' $! ' , 0 ) {
1114
+ elsif $ onlyname ne ' ' {
1182
1115
# If there's only one destination, avoid repeated hash lookups
1183
1116
my int $ cselems := nqp :: elems ($ cs );
1184
1117
my int $ csi ;
1185
1118
my $ dest ;
1186
- if nqp :: ord ($ onlyname ) < 58 {
1119
+ if nqp :: ord ($ onlyname ) != 38 && nqp :: ord ( $ onlyname ) < 58 {
1187
1120
$ dest := nqp ::atpos($ list , $ onlyname );
1188
1121
}
1189
1122
else {
@@ -1197,78 +1130,49 @@ class NQPMatch is NQPCapture does NQPMatchRole {
1197
1130
++ $ csi ;
1198
1131
}
1199
1132
}
1200
- elsif ! nqp ::isnull( % caplist ) && % caplist {
1133
+ elsif $ hascaps {
1201
1134
my int $ cselems := nqp :: elems ($ cs );
1202
1135
my int $ csi ;
1203
- # note($cselems);
1204
1136
while $ csi < $ cselems {
1205
1137
my $ subcur := nqp ::atpos($ cs , $ csi );
1206
1138
my str $ name := nqp ::getattr_s($ subcur , $ ? CLASS , ' $!name' );
1207
- if ! nqp ::isnull_s($ name ) && nqp :: defined ( $ name ) && $ name ne ' ' {
1139
+ if ! nqp ::isnull_s($ name ) && $ name ne ' ' {
1208
1140
my $ submatch := $ subcur . MATCH();
1209
1141
if nqp :: ord ($ name ) == 36 && ($ name eq ' $!from' || $ name eq ' $!to' ) {
1210
1142
nqp ::bindattr_i(self , NQPMatch, $ name , $ submatch . from );
1211
1143
}
1212
1144
elsif nqp :: index ($ name , ' =' ) < 0 {
1213
- my int $ needs_list := % caplist {$ name } >= 2 ;
1214
1145
if nqp :: ord ($ name ) < 58 {
1215
- $ list := nqp ::list() unless nqp ::isconcrete($ list );
1216
- $ needs_list
1146
+ nqp ::islist(nqp ::atpos($ list , $ name ))
1217
1147
?? nqp :: push (nqp ::atpos($ list , $ name ), $ submatch )
1218
1148
!! nqp ::bindpos($ list , $ name , $ submatch );
1219
1149
}
1220
1150
else {
1221
- $ needs_list
1222
- ?? nqp :: push ($ hash { $ name } , $ submatch )
1151
+ nqp ::islist( nqp ::atkey( $ hash , $ name ))
1152
+ ?? nqp :: push (nqp ::atkey( $ hash , $ name ) , $ submatch )
1223
1153
!! nqp ::bindkey($ hash , $ name , $ submatch );
1224
1154
}
1225
1155
}
1226
1156
else {
1227
1157
for nqp :: split (' =' , $ name ) -> $ name {
1228
- my int $ needs_list := % caplist {$ name } >= 2 ;
1229
1158
if nqp :: ord ($ name ) < 58 {
1230
- $ list := nqp ::list() unless nqp ::isconcrete($ list );
1231
- $ needs_list
1159
+ nqp ::islist(nqp ::atkey($ hash , $ name ))
1232
1160
?? nqp :: push (nqp ::atpos($ list , $ name ), $ submatch )
1233
1161
!! nqp ::bindpos($ list , $ name , $ submatch );
1234
1162
}
1235
1163
else {
1236
- $ needs_list
1237
- ?? nqp :: push ($ hash { $ name } , $ submatch )
1164
+ nqp ::islist( nqp ::atkey( $ hash , $ name ))
1165
+ ?? nqp :: push (nqp ::atkey( $ hash , $ name ) , $ submatch )
1238
1166
!! nqp ::bindkey($ hash , $ name , $ submatch );
1239
1167
}
1240
1168
}
1241
1169
}
1242
1170
}
1243
1171
++ $ csi ;
1244
1172
}
1245
- # {
1246
- # my $iter := nqp::iterator(%caplist);
1247
- # while $iter {
1248
- # my $curcap := nqp::shift($iter);
1249
- # my str $name := nqp::iterkey_s($curcap);
1250
- # my int $iv := nqp::iterval($curcap);
1251
- # if $iv >= 2 {
1252
- # if nqp::iscclass(nqp::const::CCLASS_NUMERIC, $name, 0) {
1253
- # stderr().print("\t" ~ $name ~ "\t" ~ nqp::elems(nqp::atpos($list, $name)));
1254
- # }
1255
- # else {
1256
- # stderr().print("\t" ~ $name ~ "\t" ~ nqp::elems(nqp::atkey($hash, $name)));
1257
- # }
1258
- # }
1259
- # elsif $iv >= 1 {
1260
- # if nqp::iscclass(nqp::const::CCLASS_NUMERIC, $name, 0) {
1261
- # stderr().print("\t" ~ $name ~ "\t" ~ nqp::defined(nqp::atpos($list, $name)));
1262
- # }
1263
- # else {
1264
- # stderr().print("\t" ~ $name ~ "\t" ~ nqp::defined(nqp::atkey($hash, $name)));
1265
- # }
1266
- # }
1267
- # }
1268
- # }
1269
1173
}
1270
- nqp ::bindattr(self , NQPCapture, ' @!array' , nqp ::isconcrete ($ list ) ?? $ list !! @ EMPTY_LIST );
1271
- nqp ::bindattr(self , NQPCapture, ' %!hash' , $ hash );
1174
+ nqp ::bindattr(self , NQPCapture, ' @!array' , nqp ::defor ($ list , @ EMPTY_LIST ) );
1175
+ nqp ::bindattr(self , NQPCapture, ' %!hash' , nqp ::defor( $ hash , % EMPTY_HASH ) );
1272
1176
1273
1177
# Once we've produced the captures, and if we know we're finished and
1274
1178
# will never be backtracked into, we can release cstack and regexsub.
0 commit comments