Permalink
Browse files

Implement binding with declarators.

This gets things like 'my (:$a, :$b) := foo()' style things working.
  • Loading branch information...
1 parent fdf347b commit 14f02309caf278f4b4cb051e8e0bb5b43e9d7749 @jnthn jnthn committed Sep 28, 2012
Showing with 58 additions and 1 deletion.
  1. +12 −1 src/Perl6/Actions.pm
  2. +1 −0 src/Perl6/Ops.pm
  3. +45 −0 src/ops/perl6.ops
View
@@ -1524,7 +1524,18 @@ class Perl6::Actions is HLL::Actions {
$/.CURSOR.panic("Cannot use .= initializer with a list of declarations");
}
else {
- $*W.throw($/, 'X::Comp::NYI', feature => "Binding to signatures in $*SCOPE declarations");
+ my %sig_info := $<signature>.ast;
+ my @params := %sig_info<parameters>;
+ set_default_parameter_type(@params, 'Mu');
+ my $signature := create_signature_object($/, %sig_info, $*W.cur_lexpad());
+ $list := QAST::Op.new(
+ :op('p6bindcaptosig'),
+ QAST::WVal.new( :value($signature) ),
+ QAST::Op.new(
+ :op('callmethod'), :name('Capture'),
+ $<initializer>[0].ast
+ )
+ );
}
if $*SCOPE eq 'state' {
$list := QAST::Op.new( :op('if'),
View
@@ -28,6 +28,7 @@ $ops.add_hll_pirop_mapping('perl6', 'p6multidispatch', 'perl6_enter_multi_dispat
$ops.add_hll_pirop_mapping('perl6', 'p6multidispatchlex', 'perl6_enter_multi_dispatch_in_lexical_context', 'P');
$ops.add_hll_pirop_mapping('perl6', 'p6bindsig', 'bind_signature', 'v');
$ops.add_hll_pirop_mapping('perl6', 'p6isbindable', 'perl6_is_sig_bindable', 'IPP');
+$ops.add_hll_pirop_mapping('perl6', 'p6bindcaptosig', 'perl6_bind_sig_to_cap', '0PP');
$ops.add_hll_pirop_mapping('perl6', 'p6typecheckrv', 'perl6_type_check_return_value', '0PP', :inlinable(1));
$ops.add_hll_pirop_mapping('perl6', 'p6decontrv', 'perl6_decontainerize_return_value', 'PP', :inlinable(1));
$ops.add_hll_pirop_mapping('perl6', 'p6capturelex', 'perl6_capture_lex', '0P');
View
@@ -465,6 +465,51 @@ inline op bind_signature() :base_core {
/*
+=item perl6_bind_sig_to_cap()
+
+Takes a signature and capture. Binds it in the current lexical context.
+
+=cut
+
+*/
+inline op perl6_bind_sig_to_cap(in PMC, in PMC) :base_core {
+ PMC *signature = $1;
+ PMC *capture = $2;
+
+ /* Need to make sure some stuff doesn't get destroyed. */
+ PMC * const ctx = CURRENT_CONTEXT(interp);
+ PMC * const saved_ccont = interp->current_cont;
+ PMC * const saved_sig = Parrot_pcc_get_signature(interp, ctx);
+ opcode_t * const current_pc = Parrot_pcc_get_pc(interp, ctx);
+
+ /* Obtain lexpad and other settings. */
+ PMC * const lexpad = Parrot_pcc_get_lex_pad(interp, ctx);
+ STRING * error = STRINGNULL;
+ INTVAL bind_error;
+
+ /* Call signature binder. */
+ bind_error = Rakudo_binding_bind(interp, lexpad, signature,
+ capture, 0, &error);
+
+ /* Bind ok? */
+ if (!bind_error) {
+ /* Re-instate anything we may have damaged. */
+ CURRENT_CONTEXT(interp) = ctx;
+ interp->current_cont = saved_ccont;
+ Parrot_pcc_set_signature(interp, ctx, saved_sig);
+ Parrot_pcc_set_pc(interp, ctx, current_pc);
+ goto NEXT();
+ }
+ else {
+ opcode_t * const handler = Parrot_ex_throw_from_op_args(interp, NULL,
+ EXCEPTION_INVALID_OPERATION, "%Ss", error);
+ goto ADDRESS(handler);
+ }
+}
+
+
+/*
+
=item perl6_trial_bind_ct()
Sees if we could potentially bind a signature.

0 comments on commit 14f0230

Please sign in to comment.