Skip to content

Commit 9466f56

Browse files
committed
First cut at compiling nqp::chain.
1 parent 25157f7 commit 9466f56

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

src/vm/jvm/QAST/Compiler.nqp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,75 @@ class QAST::OperationsJAST {
390390
}
391391
}
392392

393+
# Chaining.
394+
QAST::OperationsJAST.add_core_op('chain', -> $qastcomp, $op {
395+
# First, we build up the list of nodes in the chain
396+
my @clist;
397+
my $cpast := $op;
398+
while nqp::istype($cpast, QAST::Op) && $cpast.op eq 'chain' {
399+
nqp::push(@clist, $cpast);
400+
$cpast := $cpast[0];
401+
}
402+
403+
my $il := JAST::InstructionList.new();
404+
my $result := $*TA.fresh_o();
405+
my $endlabel := JAST::Label.new(:name($qastcomp.unique('chain_end_')));
406+
407+
$cpast := nqp::pop(@clist);
408+
my $apast := $cpast[0];
409+
my $ares := $qastcomp.as_jast($apast, :want($RT_OBJ));
410+
my $atmp := $*TA.fresh_o();
411+
$il.append($ares.jast);
412+
$*STACK.obtain($il, $ares);
413+
$il.append(JAST::Instruction.new( :op('astore'), $atmp ));
414+
415+
my $more := 1;
416+
while $more {
417+
my $bpast := $cpast[1];
418+
my $bres := $qastcomp.as_jast($bpast, :want($RT_OBJ));
419+
my $btmp := $*TA.fresh_o();
420+
$il.append($bres.jast);
421+
$*STACK.obtain($il, $bres);
422+
$il.append(JAST::Instruction.new( :op('astore'), $btmp ));
423+
424+
my $cs_idx := $*CODEREFS.get_callsite_idx([$ARG_OBJ, $ARG_OBJ], []);
425+
$il.append($ALOAD_1);
426+
$il.append(JAST::Instruction.new( :op('aload'), $atmp ));
427+
$il.append(JAST::Instruction.new( :op('aload'), $btmp ));
428+
$il.append(JAST::InvokeDynamic.new(
429+
'subcall', 'V', [$TYPE_TC, $TYPE_SMO, $TYPE_SMO],
430+
'org/perl6/nqp/runtime/IndyBootstrap', 'subcall',
431+
[
432+
JAST::PushSVal.new( :value($cpast.name) ),
433+
JAST::PushIndex.new( :value($cs_idx) )
434+
]
435+
));
436+
$il.append(JAST::Instruction.new( :op('aload'), 'cf' ));
437+
$il.append(JAST::Instruction.new( :op('invokestatic'), $TYPE_OPS,
438+
'result_o', $TYPE_SMO, $TYPE_CF ));
439+
$il.append(JAST::Instruction.new( :op('astore'), $result ));
440+
441+
if @clist {
442+
$il.append(JAST::Instruction.new( :op('aload'), $result ));
443+
$il.append($ALOAD_1);
444+
$il.append(JAST::Instruction.new( :op('invokestatic'),
445+
$TYPE_OPS, 'istrue', 'Long', $TYPE_SMO, $TYPE_TC ));
446+
$il.append($IVAL_ZERO);
447+
$il.append($LCMP);
448+
$il.append(JAST::Instruction.new( :op('ifeq'), $endlabel ));
449+
$cpast := nqp::pop(@clist);
450+
$atmp := $btmp;
451+
}
452+
else {
453+
$more := 0;
454+
}
455+
}
456+
457+
$il.append($endlabel);
458+
$il.append(JAST::Instruction.new( :op('aload'), $result ));
459+
result($il, $RT_OBJ)
460+
});
461+
393462
# Set of sequential statements
394463
QAST::OperationsJAST.add_core_op('stmts', -> $qastcomp, $op {
395464
$qastcomp.as_jast(QAST::Stmts.new( |@($op) ))

0 commit comments

Comments
 (0)