Skip to content

Commit 85faf51

Browse files
committed
Partial implementation of rxtype subrule
1 parent 6aedbc4 commit 85faf51

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

src/vm/js/QAST/Compiler.nqp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,6 +1286,7 @@ class RegexCompiler {
12861286
}
12871287
}
12881288

1289+
12891290
method pass($node) {
12901291
my $name;
12911292

@@ -1305,6 +1306,91 @@ class RegexCompiler {
13051306
]);
13061307
}
13071308

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+
13081394
method BUILD(:$compiler) {
13091395
$!compiler := $compiler;
13101396

0 commit comments

Comments
 (0)