/* This takes a signature element and either runs the closure to get a default * value if there is one, or creates an appropriate undefined-ish thingy. */ static PMC * Rakudo_binding_handle_optional(PARROT_INTERP, llsig_element *sig_info, PMC *lexpad) { PMC *cur_lex; /* Is the "get default from outer" flag set? */ if (sig_info->flags & SIG_ELEM_DEFAULT_FROM_OUTER) { PMC *outer_ctx = Parrot_pcc_get_outer_ctx(interp, CURRENT_CONTEXT(interp)); PMC *outer_lexpad = Parrot_pcc_get_lex_pad(interp, outer_ctx); return VTABLE_get_pmc_keyed_str(interp, outer_lexpad, sig_info->variable_name); } /* Do we have a default value closure? */ else if (!PMC_IS_NULL(sig_info->default_closure)) { /* Run it to get a value. */ PMC *result = PMCNULL; Parrot_sub_capture_lex(interp, sig_info->default_closure); Parrot_ext_call(interp, sig_info->default_closure, "->P", &result); return result; } /* Did the value already get initialized to something? (We can avoid re-creating a * PMC if so.) */ else if (!PMC_IS_NULL(cur_lex = VTABLE_get_pmc_keyed_str(interp, lexpad, sig_info->variable_name))) { /* Yes; if $ sigil then we want to bind set value in it to be the * type object of the default type. */ if (!(sig_info->flags & (SIG_ELEM_ARRAY_SIGIL | SIG_ELEM_HASH_SIGIL))) VTABLE_set_pmc(interp, cur_lex, sig_info->nominal_type); return cur_lex; } /* Otherwise, go by sigil to pick the correct default type of value. */ else { if (sig_info->flags & SIG_ELEM_ARRAY_SIGIL) { return Rakudo_binding_create_positional(interp, PMCNULL, ARRAY_str); } else if (sig_info->flags & SIG_ELEM_HASH_SIGIL) { return Rakudo_binding_create_hash(interp, pmc_new(interp, enum_class_Hash)); } else { return pmc_new_init(interp, pmc_type(interp, P6_SCALAR_str), sig_info->nominal_type); } } }
/* This takes a signature element and either runs the closure to get a default * value if there is one, or creates an appropriate undefined-ish thingy. */ static PMC * Rakudo_binding_handle_optional(PARROT_INTERP, Rakudo_Parameter *param, PMC *lexpad) { PMC *cur_lex; /* Is the "get default from outer" flag set? */ if (param->flags & SIG_ELEM_DEFAULT_FROM_OUTER) { PMC *outer_ctx = Parrot_pcc_get_outer_ctx(interp, CURRENT_CONTEXT(interp)); PMC *outer_lexpad = Parrot_pcc_get_lex_pad(interp, outer_ctx); return VTABLE_get_pmc_keyed_str(interp, outer_lexpad, param->variable_name); } /* Do we have a default value or value closure? */ else if (!PMC_IS_NULL(param->default_value)) { if (param->flags & SIG_ELEM_DEFAULT_IS_LITERAL) { return param->default_value; } else { /* Thunk; run it to get a value. */ PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp)); PMC *cappy = Parrot_pmc_new(interp, enum_class_CallContext); Parrot_pcc_invoke_from_sig_object(interp, param->default_value, cappy); cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp)); Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx); return VTABLE_get_pmc_keyed_int(interp, cappy, 0); } } /* Otherwise, go by sigil to pick the correct default type of value. */ else { if (param->flags & SIG_ELEM_ARRAY_SIGIL) { return Rakudo_binding_create_positional(interp, PMCNULL); } else if (param->flags & SIG_ELEM_HASH_SIGIL) { return Rakudo_binding_create_hash(interp, Parrot_pmc_new(interp, enum_class_Hash)); } else { return param->nominal_type; } } }