@@ -1286,6 +1286,7 @@ class RegexCompiler {
1286
1286
}
1287
1287
}
1288
1288
1289
+
1289
1290
method pass ($ node ) {
1290
1291
my $ name ;
1291
1292
@@ -1305,6 +1306,91 @@ class RegexCompiler {
1305
1306
]);
1306
1307
}
1307
1308
1309
+
1310
+ method subrule ($ node ) {
1311
+
1312
+ my $ captured := 0 ;
1313
+
1314
+ my sub call ($ invocant , $ method , * @ args ) {
1315
+ nqp :: unshift (@ args , $ * BLOCK . ctx);
1316
+ nqp :: unshift (@ args , ' nqp.named([])' );
1317
+ $ invocant ~ " [" ~ quote_string($ method ) ~ " ](" ~ nqp :: join (" ," , @ args ) ~ " )" ;
1318
+ }
1319
+
1320
+ my $ call ;
1321
+ if nqp ::istype($ node [0 ][0 ], QAST ::Block) {
1322
+ $ call := $ ! compiler . NYI(" special subrule call" );
1323
+ # #TODO think if arguments are possible, etc.
1324
+ # #$call := self.as_js($node[0][0])~".apply(cursor,[{self.ctx},nqp.empty_named(),cursor])";
1325
+ }
1326
+ else {
1327
+ # TODO arguments
1328
+ my $ args := nqp :: clone ($ node [0 ]. list);
1329
+ my $ method := $ args . shift ;
1330
+
1331
+ # TODO .method name when it's valid
1332
+ $ call := Chunk. new ($ T_OBJ , $ ! cursor ~ ' [' ~ quote_string($ node . name ) ~ " ]()" , []);
1333
+ }
1334
+
1335
+ my $ testop := $ node . negate ?? ' >=' !! ' <' ;
1336
+
1337
+ my $ subcur := $ * BLOCK . add_tmp;
1338
+
1339
+ my $ capture_code := ' ' ;
1340
+
1341
+ if $ node . subtype ne ' zerowidth' {
1342
+ my $ pass_label := self . new_label();
1343
+ if $ node . backtrack eq ' r' {
1344
+ unless $ node . subtype eq ' method' {
1345
+ $ capture_code := self . mark($ pass_label ,-1 ,0 ) ~ self . case($ pass_label );
1346
+ }
1347
+ }
1348
+ else {
1349
+
1350
+
1351
+ my $ back_label := new_label();
1352
+
1353
+ $ capture_code := $ capture_code
1354
+ ~ self . goto($ pass_label )
1355
+ ~ self . case($ back_label )
1356
+ ~ " $ subcur =" ~ call($ ! subcur , " !cursor_next" ) ~ " ;\n "
1357
+ ~ " if($ subcur[ ' $!pos' ] $ testop 0) \{ { self . fail } \} ;\n "
1358
+ ~ self . case($ pass_label );
1359
+
1360
+ if $ node . subtype eq ' capture' {
1361
+ $ capture_code := $ capture_code
1362
+ ~ " $ ! cstack = "
1363
+ ~ call($ ! cursor , " !cursor_capture" , $ subcur , quote_string($ node . name )) ~ " ;\n " ;
1364
+ $ captured := 1 ;
1365
+ }
1366
+ else {
1367
+ $ capture_code := $ capture_code
1368
+ ~ " $ ! cstack = "
1369
+ ~ call($ ! cursor , " !cursor_push_cstack" , $ subcur ) ~ " ;\n " ~
1370
+ ~ " $ ! bstack. push ($ back_label , 0 , $ ! pos , $ ! cstack . length) ;\n " ;
1371
+ }
1372
+
1373
+ }
1374
+ }
1375
+
1376
+ if ! $ captured && $ node . subtype eq ' capture' {
1377
+ $ capture_code := $ capture_code
1378
+ ~ " $ ! cstack = " ~
1379
+ call($ ! cursor , " !cursor_capture" , $ subcur , quote_string($ node . name )) ~ " ;\n "
1380
+ }
1381
+
1382
+ # TODO proper $!pos access
1383
+ Chunk. new ($ T_VOID , " " , [
1384
+ " $ ! cursor[ ' \$!pos\' ] = $ ! pos ;\n " ,
1385
+ $ call ,
1386
+ " $ subcur = { $ call . expr} ;\n " ,
1387
+ " if ($ subcur[ ' \$!pos\' ] $ testop 0) \{ { self . fail } \}\n " ,
1388
+ $ capture_code ,
1389
+
1390
+ ($ node . subtype eq ' zerowidth' ?? ' ' !! " $ ! pos = $ subcur[ ' \$!pos\' ] ;\n " )
1391
+ ]);
1392
+ }
1393
+
1308
1394
method BUILD (: $ compiler ) {
1309
1395
$ ! compiler := $ compiler ;
1310
1396
0 commit comments