Skip to content

Commit 912b502

Browse files
committed
[js] Implement nqp::chain.
1 parent 10f2b45 commit 912b502

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

src/vm/js/Operations.nqp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,38 @@ class QAST::OperationsJS {
192192
add_simple_op('istype', $T_BOOL, [$T_OBJ, $T_OBJ], sub ($value, $type) {"($value instanceof $type.constructor)"});
193193

194194

195+
add_op('chain', sub ($comp, $node, :$want, :$cps) {
196+
my $ret := $*BLOCK.add_tmp;
197+
198+
my sub is_chain($part) {
199+
$part ~~ QAST::Op && $part.op eq 'chain';
200+
}
201+
202+
my sub chain_part($part) {
203+
if is_chain($part) {
204+
my $callee := $comp.as_js(QAST::Var.new(:name($part.name),:scope('lexical')), :want($T_OBJ));
205+
my $left := chain_part($part[0]);
206+
my $right := $comp.as_js($part[1], :want($T_OBJ));
207+
my @setup;
208+
209+
@setup.push($left);
210+
211+
@setup.push("if (nqp.toBool($ret, $*CTX)) \{\n") if is_chain($part[0]);
212+
@setup.push($callee);
213+
@setup.push($right);
214+
@setup.push("$ret = {$callee.expr}.\$call($*CTX, null, {$left.expr}, {$right.expr});\n");
215+
@setup.push("\}") if is_chain($part[0]);
216+
217+
Chunk.new($T_OBJ, $right.expr, @setup, :node($part));
218+
}
219+
else {
220+
$comp.as_js($part, :want($T_OBJ));
221+
}
222+
}
223+
224+
Chunk.new($T_OBJ, $ret, [chain_part($node)]);
225+
});
226+
195227
add_simple_op('clone', $T_OBJ, [$T_OBJ]);
196228

197229
# TODO optimize cases where the class and the attribute are constants

0 commit comments

Comments
 (0)