my $ops := nqp::getcomp('QAST').operations; sub register_op_desugar($op, $desugar, :$compiler = 'Raku') is export { nqp::getcomp('QAST').operations.add_op(:hll($compiler), $op, sub ($comp, $node, :$want) { $comp.as_js($desugar($node), :$want); }); } # Stub register_op_desugar('', -> $qast { QAST::Op.new(:op('null')); }); $ops.add_simple_op('p6sink', $ops.VOID, [$ops.OBJ], :ctx, :side_effects, :await); $ops.add_simple_op('p6reprname', $ops.OBJ, [$ops.OBJ], :decont(0)); # Stub register_op_desugar('p6invokeflat', -> $qast { $qast[1].flat(1); QAST::Op.new( :op('call'), $qast[0], $qast[1]); }); # TODO only override for js # Override defor to call defined method. register_op_desugar('defor', -> $op { if +$op.list != 2 { nqp::die("Operation 'defor' needs 2 operands"); } my $tmp := $op.unique('defined'); QAST::Stmts.new( QAST::Op.new( :op('bind'), QAST::Var.new( :name($tmp), :scope('local'), :decl('var') ), $op[0] ), QAST::Op.new( :op('if'), QAST::Op.new( :op('callmethod'), :name('defined'), QAST::Var.new( :name($tmp), :scope('local') ) ), QAST::Var.new( :name($tmp), :scope('local') ), $op[1] )); }); $ops.add_hll_unbox('Raku', $ops.INT, 'getInt'); $ops.add_hll_unbox('Raku', $ops.NUM, 'getNum'); $ops.add_hll_unbox('Raku', $ops.STR, 'getStr'); $ops.add_hll_unbox('Raku', $ops.INT64, 'getInt64'); $ops.add_hll_unbox('Raku', $ops.UINT64, 'getUint64'); # Signature binding related bits. $ops.add_simple_op('p6setbinder', $ops.VOID, [$ops.OBJ], :side_effects, sub ($binder) {"nqp.p6binder = $binder"}); $ops.add_op('p6bindsig', :!inlinable, sub ($comp, $node, :$want) { my $ops := nqp::getcomp('QAST').operations; my $tmp := $*BLOCK.add_tmp; $ops.new_chunk($ops.VOID, "", [ "$tmp = /*await*/ nqp.p6binder.p6\$bind_sig($*CTX, null, nqp.p6binder, nqp.op.savecapture(Array.prototype.slice.call(arguments)));\n", "if ($tmp !== nqp.Null) return $tmp;\n" ]); }); $ops.add_simple_op('p6configposbindfailover', $ops.VOID, [$ops.OBJ, $ops.OBJ], sub ($pos, $pos_bind_failover) { "/*await*/ nqp.p6binder.p6\$set_pos_bind_failover($*CTX, null, nqp.p6binder, $pos, $pos_bind_failover)" }, :side_effects); $ops.add_simple_op('p6setautothreader', $ops.VOID, [$ops.OBJ], sub ($autothreader) { "/*await*/ nqp.p6binder.p6\$set_autothreader($*CTX, null, nqp.p6binder, $autothreader)" }, :side_effects); $ops.add_simple_op('p6trialbind', $ops.OBJ, [$ops.OBJ, $ops.OBJ, $ops.OBJ], :!inlinable, sub ($sig, $args, $sig_flags) { "/*await*/ nqp.p6binder.p6\$trial_bind($*CTX, null, nqp.p6binder, $sig, $args, $sig_flags)" }); $ops.add_simple_op('p6isbindable', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :!inlinable, sub ($sig, $cap) { "nqp.retval(HLL, /*await*/ nqp.p6binder.p6\$is_bindable($*CTX, null, nqp.p6binder, $sig, $cap))" }); $ops.add_simple_op('p6bindcaptosig', $ops.OBJ, [$ops.OBJ, $ops.OBJ], sub ($sig, $cap) { "/*await*/ nqp.p6binder.p6\$bind_cap_to_sig($*CTX, null, nqp.p6binder, $sig, $cap)" }, :side_effects); $ops.add_op('p6bindattrinvres', $ops.bindattr($ops.OBJ, :inverted_result)); $ops.add_simple_op('p6invokeunder', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :side_effects, :ctx, :takes_hll, :await); $ops.add_simple_op('p6settypes', $ops.OBJ, [$ops.OBJ], :side_effects); $ops.add_simple_op('p6init', $ops.OBJ, [], :side_effects, -> {"nqp.extraRuntime('Raku', {$ops.quote_string($*PERL6_RUNTIME)})"}); $ops.add_simple_op('p6typecheckrv', $ops.OBJ, [$ops.OBJ, $ops.OBJ, $ops.OBJ], :ctx, :await); $ops.add_simple_op('p6definite', $ops.OBJ, [$ops.OBJ], :decont(0)); $ops.add_simple_op('p6captureouters2', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :ctx); $ops.add_simple_op('p6capturelex', $ops.OBJ, [$ops.OBJ], :side_effects, sub ($codeObj) { # Use $*BLOCK.ctx instead of $*CTX so it doesn't get overwriten by exception handling "nqp.op.p6capturelex({$*BLOCK.ctx}, $codeObj)" }); $ops.add_simple_op('p6capturelexwhere', $ops.OBJ, [$ops.OBJ], :side_effects, sub ($codeObj) { # Use $*BLOCK.ctx instead of $*CTX so it doesn't get overwriten by exception handling "nqp.op.p6capturelexwhere({$*BLOCK.ctx}, $codeObj)" }); $ops.add_simple_op('p6bindassert', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :ctx, :side_effects, :await); $ops.add_simple_op('p6store', $ops.OBJ, [$ops.OBJ, $ops.OBJ], :ctx, :side_effects, :await); $ops.add_simple_op('p6argvmarray', $ops.OBJ, [], :side_effects, sub () { "/*await*/ nqp.op.p6argvmarray($*CTX, Array.prototype.slice.call(arguments))" }); $ops.add_simple_op('p6stateinit', $ops.INT, [], sub () { # XXX - this semantics seems suspect but rakudo seems to rely on this my $block := $*BLOCK; while $block.qast.blocktype eq 'immediate' { $block := $block.outer; } $block.first_time_marker ~ 'Init'; }); $ops.add_op('p6return', :!inlinable, sub ($comp, $node, :$want) { my $ops := nqp::getcomp('QAST').operations; unless $*RETURN_FROM_HANDLER { $*RETURN_FROM_HANDLER := $*BLOCK.add_tmp; } my $value := $comp.as_js($node[0], :$want); $ops.new_chunk($ops.VOID, "", [ $value, "$*RETURN_FROM_HANDLER = {$value.expr};\n" ]); }); $ops.add_op('p6decontrv', :!inlinable, sub ($comp, $node, :$want) { my $is_rw; if nqp::istype($node[0], QAST::WVal) { $is_rw := nqp::istrue($node[0].value.rw); } else { nqp::die('p6decontrv expects a QAST::WVal as its first child'); } if $is_rw { $comp.as_js($node[1], :$want) } else { $comp.as_js(QAST::Op.new( :op('p6decontrv_internal'), $node[1]), :$want); } }); $ops.add_simple_op('p6finddispatcher', $ops.OBJ, [$ops.STR], :side_effects, sub ($usage) { "/*await*/ nqp.op.p6finddispatcher({$*BLOCK.ctx}, $usage)" }); $ops.add_simple_op('p6argsfordispatcher', $ops.OBJ, [$ops.OBJ], :side_effects, sub ($dispatcher) { "nqp.op.p6argsfordispatcher({$*BLOCK.ctx}, $dispatcher)" }); $ops.add_simple_op('p6setfirstflag', $ops.OBJ, [$ops.OBJ], :side_effects); $ops.add_simple_op('p6takefirstflag', $ops.INT, [], :ctx, :side_effects); $ops.add_simple_op('p6setpre', $ops.OBJ, [], :ctx, :side_effects); $ops.add_simple_op('p6clearpre', $ops.OBJ, [], :ctx, :side_effects); $ops.add_simple_op('p6inpre', $ops.INT, [], :ctx, :side_effects); $ops.add_simple_op('p6getouterctx', $ops.OBJ, [$ops.OBJ], :decont(0), :!inlinable); $ops.add_simple_op('p6staticouter', $ops.OBJ, [$ops.OBJ], :ctx, :side_effects); $ops.add_simple_op('p6fakerun', $ops.OBJ, [$ops.OBJ], :side_effects, :takes_hll, :await); # vim: expandtab sw=4