# This file automatically generated by /friends/.rakubrew/versions/moar-main/tools/build/gen-cat.nqp #line 1 src/Perl6/bootstrap.c/BOOTSTRAP.nqp use Perl6::Metamodel; use QRegex; # Here we start to piece together the top of the object model hierarchy. # We can't just declare these bits in CORE.setting with normal Raku # syntax due to circularity issues. Note that we don't compose any of # these - which is equivalent to a { ... } body. # # One particular circularity we break here is that you can't have # inheritance in Raku without traits, but that needs multiple # dispatch, which can't function without some type hierarchy in # place. It also needs us to be able to declare signatures with # parameters and code objects with dispatchees, which in turn needs # attributes. So, we set up quite a few bits in here, though the aim # is to keep it "lagom". :-) # Bootstrapping Attribute class that we eventually replace with the real # one. my class BOOTSTRAPATTR { has $!name; has $!type; has $!box_target; has $!package; has $!inlined; has $!dimensions; method name() { $!name } method type() { $!type } method box_target() { $!box_target } method package() { $!package } method inlined() { $!inlined } method dimensions() { $!dimensions } method is_built() { 0 } method is_bound() { 0 } method has_accessor() { 0 } method positional_delegate() { 0 } method associative_delegate() { 0 } method build() { } method is_generic() { $!type.HOW.archetypes($!type).generic } method instantiate_generic($type_environment) { my $ins := $!type.HOW.instantiate_generic($!type, $type_environment); self.new(:name($!name), :box_target($!box_target), :type($ins)) } method compose($obj, :$compiler_services) { } method gist() { $!type.HOW.name($!type) ~ ' ' ~ $!name } method perl() { 'BOOTSTRAPATTR.new' } method raku() { 'BOOTSTRAPATTR.new' } method Str() { $!name } } # Stub all types. my stub Mu metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Any metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Nil metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Cool metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Attribute metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Scalar metaclass Perl6::Metamodel::ClassHOW { ... }; my stub ScalarVAR metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Proxy metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Signature metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Parameter metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Code metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Block metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Routine metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Sub metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Operator metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Method metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Submethod metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Regex metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Str metaclass Perl6::Metamodel::ClassHOW { ... }; my knowhow bigint is repr('P6bigint') { } my stub Int metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Num metaclass Perl6::Metamodel::ClassHOW { ... }; my stub List metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Slip metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Array metaclass Perl6::Metamodel::ClassHOW { ... }; my stub array metaclass Perl6::Metamodel::ClassHOW is repr('VMArray') { ... }; my stub IterationBuffer metaclass Perl6::Metamodel::ClassHOW is repr('VMArray') { ... }; my stub Map metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Hash metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Capture metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Bool metaclass Perl6::Metamodel::EnumHOW { ... }; my stub ObjAt metaclass Perl6::Metamodel::ClassHOW { ... }; my stub ValueObjAt metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Stash metaclass Perl6::Metamodel::ClassHOW { ... }; my stub PROCESS metaclass Perl6::Metamodel::ModuleHOW { ... }; my stub Grammar metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Junction metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Metamodel metaclass Perl6::Metamodel::PackageHOW { ... }; my stub ForeignCode metaclass Perl6::Metamodel::ClassHOW { ... }; my stub Version metaclass Perl6::Metamodel::ClassHOW { ... }; my stub IntLexRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub UIntLexRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub NumLexRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub StrLexRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub IntAttrRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub UIntAttrRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub NumAttrRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub StrAttrRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub IntPosRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub UIntPosRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub NumPosRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub StrPosRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub IntMultidimRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub UIntMultidimRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub NumMultidimRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; my stub StrMultidimRef metaclass Perl6::Metamodel::NativeRefHOW { ... }; # Implement the signature binder. # The JVM backend really only uses trial_bind, # so we exclude everything else. my class Binder { # Flags that can be set on a signature element. See Parameter.pm6 my int $SIG_ELEM_BIND_CAPTURE := 1; my int $SIG_ELEM_BIND_PRIVATE_ATTR := 2; my int $SIG_ELEM_BIND_PUBLIC_ATTR := 4; my int $SIG_ELEM_BIND_ATTRIBUTIVE := ($SIG_ELEM_BIND_PRIVATE_ATTR +| $SIG_ELEM_BIND_PUBLIC_ATTR); my int $SIG_ELEM_SLURPY_POS := 8; my int $SIG_ELEM_SLURPY_NAMED := 16; my int $SIG_ELEM_SLURPY_LOL := 32; my int $SIG_ELEM_INVOCANT := 64; my int $SIG_ELEM_MULTI_INVOCANT := 128; my int $SIG_ELEM_IS_RW := 256; my int $SIG_ELEM_IS_COPY := 512; my int $SIG_ELEM_IS_RAW := 1024; my int $SIG_ELEM_IS_OPTIONAL := 2048; my int $SIG_ELEM_ARRAY_SIGIL := 4096; my int $SIG_ELEM_HASH_SIGIL := 8192; my int $SIG_ELEM_DEFAULT_FROM_OUTER := 16384; my int $SIG_ELEM_IS_CAPTURE := 32768; my int $SIG_ELEM_UNDEFINED_ONLY := 65536; my int $SIG_ELEM_DEFINED_ONLY := 131072; my int $SIG_ELEM_DEFINEDNES_CHECK := ($SIG_ELEM_UNDEFINED_ONLY +| $SIG_ELEM_DEFINED_ONLY); my int $SIG_ELEM_TYPE_GENERIC := 524288; my int $SIG_ELEM_DEFAULT_IS_LITERAL := 1048576; my int $SIG_ELEM_NATIVE_INT_VALUE := 2097152; my int $SIG_ELEM_NATIVE_UINT_VALUE := 134217728; my int $SIG_ELEM_NATIVE_NUM_VALUE := 4194304; my int $SIG_ELEM_NATIVE_STR_VALUE := 8388608; my int $SIG_ELEM_NATIVE_VALUE := ($SIG_ELEM_NATIVE_UINT_VALUE +| $SIG_ELEM_NATIVE_INT_VALUE +| $SIG_ELEM_NATIVE_NUM_VALUE +| $SIG_ELEM_NATIVE_STR_VALUE); my int $SIG_ELEM_SLURPY_ONEARG := 16777216; my int $SIG_ELEM_SLURPY := ($SIG_ELEM_SLURPY_POS +| $SIG_ELEM_SLURPY_NAMED +| $SIG_ELEM_SLURPY_LOL +| $SIG_ELEM_SLURPY_ONEARG); my int $SIG_ELEM_CODE_SIGIL := 33554432; my int $SIG_ELEM_IS_COERCIVE := 67108864; # Binding result flags. my int $BIND_RESULT_OK := 0; my int $BIND_RESULT_FAIL := 1; my int $BIND_RESULT_JUNCTION := 2; my $autothreader; my $Positional; my $PositionalBindFailover; sub arity_fail($params, int $num_params, int $num_pos_args, int $too_many, $lexpad) { my str $error_prefix := $too_many ?? "Too many" !! "Too few"; my int $count; my int $arity; my int $param_i := 0; while $param_i < $num_params { my $param := nqp::atpos($params, $param_i); my int $flags := nqp::getattr_i($param, Parameter, '$!flags'); if !nqp::isnull(nqp::getattr($param, Parameter, '@!named_names')) { } elsif $flags +& $SIG_ELEM_SLURPY_NAMED { } elsif $flags +& $SIG_ELEM_SLURPY { $count := -1000; # in case a pos can sneak past a slurpy somehow } elsif $flags +& $SIG_ELEM_IS_OPTIONAL { ++$count } else { ++$count; ++$arity; } ++$param_i; } my str $s := $arity == 1 ?? "" !! "s"; my str $routine := nqp::getcodeobj(nqp::ctxcode($lexpad)).name; $routine := '' unless $routine; if $arity == $count { return "$error_prefix positionals passed to '$routine'; expected $arity argument$s but got $num_pos_args"; } elsif $count < 0 { return "$error_prefix positionals passed to '$routine'; expected at least $arity argument$s but got only $num_pos_args"; } else { my str $conj := $count == $arity+1 ?? "or" !! "to"; return "$error_prefix positionals passed to '$routine'; expected $arity $conj $count arguments but got $num_pos_args"; } } method set_autothreader($callable) { $autothreader := $callable; } method set_pos_bind_failover($pos, $pos_bind_failover) { $Positional := $pos; $PositionalBindFailover := $pos_bind_failover; } # Binds a single parameter. sub bind_one_param($lexpad, $sig, $param, int $no_param_type_check, $error, int $got_native, $oval, int $ival, num $nval, str $sval) { # Grab flags and variable name. my int $flags := nqp::getattr_i($param, Parameter, '$!flags'); my str $varname := nqp::getattr_s($param, Parameter, '$!variable_name'); my int $has_varname; nqp::isnull_s($varname) ?? ($varname := '') !! ($has_varname := 1); # Check if boxed/unboxed expectations are met. my int $desired_native := $flags +& $SIG_ELEM_NATIVE_VALUE; my int $is_rw := $flags +& $SIG_ELEM_IS_RW; if $is_rw && $desired_native { if $got_native { if $desired_native == $SIG_ELEM_NATIVE_INT_VALUE && !nqp::iscont_i($oval) ?? "int" !! $desired_native == $SIG_ELEM_NATIVE_UINT_VALUE && !nqp::iscont_u($oval) ?? "unsigned int" !! $desired_native == $SIG_ELEM_NATIVE_NUM_VALUE && !nqp::iscont_n($oval) ?? "num" !! !nqp::iscont_s($oval) # SIG_ELEM_NATIVE_STR_VALUE ?? "str" !! 0 -> $expected { if nqp::defined($error) { $error[0] := "Expected a modifiable native $expected argument for '$varname'"; } return $BIND_RESULT_FAIL; } } } elsif $desired_native != $got_native { # Maybe we need to box the native. if $desired_native == 0 { $got_native == $SIG_ELEM_NATIVE_INT_VALUE ?? ($oval := nqp::box_i($ival, Int)) !! $got_native == $SIG_ELEM_NATIVE_UINT_VALUE ?? ($oval := nqp::box_u($ival, Int)) !! $got_native == $SIG_ELEM_NATIVE_NUM_VALUE ?? ($oval := nqp::box_n($nval, Num)) # assume SIG_ELEM_NATIVE_STR_VALUE !! ($oval := nqp::box_s($sval, Str)); } # Otherwise, maybe we need to unbox. elsif !$got_native { # XXX Probably want to do this a little differently to get a # better error. $desired_native == $SIG_ELEM_NATIVE_INT_VALUE ?? ($ival := nqp::unbox_i($oval)) !! $desired_native == $SIG_ELEM_NATIVE_UINT_VALUE ?? ($ival := nqp::unbox_u($oval)) !! $desired_native == $SIG_ELEM_NATIVE_NUM_VALUE ?? ($nval := nqp::unbox_n($oval)) # assume SIG_ELEM_NATIVE_STR_VALUE !! ($sval := nqp::unbox_s($oval)); } # Otherwise, incompatible native types. else { if nqp::defined($error) { $error[0] := "Incompatible native type passed for '$varname'"; } return $BIND_RESULT_FAIL; } $got_native := $desired_native; } # By this point, we'll either have an object that we might be able to # bind if it passes the type check, or a native value that needs no # further checking. my $param_type := nqp::getattr($param, Parameter, '$!type'); unless $got_native || ($is_rw && $desired_native) { # HLL-ize. $oval := nqp::hllizefor($oval, 'Raku'); # Skip nominal type check if not needed. unless $no_param_type_check { # Is the nominal type generic and in need of instantiation? (This # can happen in (::T, T) where we didn't learn about the type until # during the signature bind). if $flags +& $SIG_ELEM_TYPE_GENERIC { $param_type := $param_type.HOW.instantiate_generic($param_type, $lexpad); } # If the expected type is Positional, see if we need to do the # positional bind failover. if nqp::eqaddr($param_type, $Positional) && nqp::istype($oval, $PositionalBindFailover) { $oval := $oval.cache; } # If not, do the check. If the wanted nominal type is Mu, then # anything goes. unless $param_type =:= Mu || nqp::istype($oval, $param_type) { # Type check failed; produce error if needed. # Try to figure out the most helpful name for the expected my $expected := ( (my $post := nqp::getattr($param, Parameter, '@!post_constraints')) && ! nqp::istype(nqp::atpos($post, 0), Code) ) ?? nqp::atpos($post, 0) !! $param_type; if nqp::defined($error) { $error[0] := { Perl6::Metamodel::Configuration.throw_or_die( 'X::TypeCheck::Binding::Parameter', "Nominal type check failed for parameter '" ~ $varname ~ "'; expected " ~ $expected.HOW.name($expected) ~ " but got " ~ $oval.HOW.name($oval), :got($oval), :expected($expected.WHAT), :symbol(nqp::hllizefor($varname, 'Raku')), :parameter($param)) }; } # Report junction failure mode if it's a junction. return $oval.WHAT =:= Junction && nqp::isconcrete($oval) ?? $BIND_RESULT_JUNCTION !! $BIND_RESULT_FAIL; } # Also enforce definedness constraints. if $flags +& $SIG_ELEM_DEFINEDNES_CHECK { if (my $should_be_concrete := $flags +& $SIG_ELEM_DEFINED_ONLY && !nqp::isconcrete($oval)) || $flags +& $SIG_ELEM_UNDEFINED_ONLY && nqp::isconcrete($oval) { if nqp::defined($error) { my $method := nqp::getcodeobj(nqp::ctxcode($lexpad)).name; my $class := $param_type.HOW.name($param_type); my $got := $oval.HOW.name($oval); my $die_msg := $flags +& $SIG_ELEM_INVOCANT ?? $should_be_concrete ?? "Invocant of method '$method' must be an object instance of type '$class', not a type object of type '$got'. Did you forget a '.new'?" !! "Invocant of method '$method' must be a type object of type '$class', not an object instance of type '$got'. Did you forget a 'multi'?" !! $should_be_concrete ?? "Parameter '$varname' of routine '$method' must be an object instance of type '$class', not a type object of type '$got'. Did you forget a '.new'?" !! "Parameter '$varname' of routine '$method' must be a type object of type '$class', not an object instance of type '$got'. Did you forget a 'multi'?"; $error[0] := { Perl6::Metamodel::Configuration.throw_or_die( 'X::Parameter::InvalidConcreteness', $die_msg, :expected($class), :got($got), :routine($method), :param($varname), :should-be-concrete(nqp::hllboolfor($should_be_concrete, 'Raku')), :param-is-invocant(nqp::hllboolfor($flags +& $SIG_ELEM_INVOCANT, 'Raku')) ); }; } return $oval.WHAT =:= Junction && nqp::isconcrete($oval) ?? $BIND_RESULT_JUNCTION !! $BIND_RESULT_FAIL; } } } } # Do we have any type captures to bind? my $type_caps := nqp::getattr($param, Parameter, '@!type_captures'); unless nqp::isnull($type_caps) { my int $num_type_caps := nqp::elems($type_caps); my int $i := -1; while ++$i < $num_type_caps { nqp::bindkey($lexpad, nqp::atpos_s($type_caps, $i), $oval.WHAT); } } # Do a coercion, if one is needed. if $param.coercive { # Coercing natives not possible - nothing to call a method on. if $got_native { if nqp::defined($error) { $error[0] := "Unable to coerce natively typed parameter '$varname'"; } return $BIND_RESULT_FAIL; } my $coercion_type := $param_type.HOW.wrappee($param_type, :coercion); $oval := $coercion_type.HOW.coerce($coercion_type, $oval); } # If it's not got attributive binding, we'll go about binding it into # the lex pad. my int $is_attributive := $flags +& $SIG_ELEM_BIND_ATTRIBUTIVE; unless $is_attributive { # Is it native? If so, just go ahead and bind it. if $got_native { $got_native == $SIG_ELEM_NATIVE_INT_VALUE ?? nqp::bindkey_i($lexpad, $varname, $ival) !! $got_native == $SIG_ELEM_NATIVE_UINT_VALUE ?? nqp::bindkey_i($lexpad, $varname, $ival) #FIXME bindkey_u missing !! $got_native == $SIG_ELEM_NATIVE_NUM_VALUE ?? nqp::bindkey_n($lexpad, $varname, $nval) # assume SIG_ELEM_NATIVE_STR_VALUE !! nqp::bindkey_s($lexpad, $varname, $sval); } # Otherwise it's some objecty case. elsif $is_rw { if nqp::isrwcont($oval) { nqp::bindkey($lexpad, $varname, $oval) if $has_varname; } else { if nqp::defined($error) { $error[0] := { Perl6::Metamodel::Configuration.throw_or_die( 'X::Parameter::RW', "Parameter '$varname' expected a writable container, but got an " ~ ~ $oval.HOW.name($oval) ~ " value", :got($oval), :symbol($varname) ) }; } return $BIND_RESULT_FAIL; } } elsif $has_varname { if $flags +& $SIG_ELEM_IS_RAW { # Just bind the thing as is into the lexpad. nqp::bindkey($lexpad, $varname, $oval); } # If it's an array, copy means make a new one and store, # and a normal bind is a straightforward binding. elsif $flags +& $SIG_ELEM_ARRAY_SIGIL { if $flags +& $SIG_ELEM_IS_COPY { my $bindee := nqp::create(Array); $bindee.STORE(nqp::decont($oval)); nqp::bindkey($lexpad, $varname, $bindee); } else { nqp::bindkey($lexpad, $varname, nqp::decont($oval)); } } # If it's a hash, similar approach to array. elsif $flags +& $SIG_ELEM_HASH_SIGIL { if $flags +& $SIG_ELEM_IS_COPY { my $bindee := nqp::create(Hash); $bindee.STORE(nqp::decont($oval)); nqp::bindkey($lexpad, $varname, $bindee); } else { nqp::bindkey($lexpad, $varname, nqp::decont($oval)); } } # If it's a scalar, we always need to wrap it into a new # container and store it; the container descriptor will be # provided and make it rw if it's an `is copy`. else { my $new_cont := nqp::create(Scalar); nqp::bindattr($new_cont, Scalar, '$!descriptor', nqp::getattr($param, Parameter, '$!container_descriptor')); nqp::bindattr($new_cont, Scalar, '$!value', nqp::decont($oval)); nqp::bindkey($lexpad, $varname, $new_cont); } } } # Is it the invocant? If so, also have to bind to self lexical. if $flags +& $SIG_ELEM_INVOCANT { nqp::bindkey($lexpad, 'self', nqp::decont($oval)); } if nqp::defined(my $sigc := nqp::getattr($param, Parameter, '$!signature_constraint')) { # Assume argument not passed if it is undefined and is the same as parameter default type unless !nqp::isconcrete($oval) && nqp::eqaddr(nqp::decont($oval), nqp::getattr($param, Parameter, '$!type')) { my $can_signature; unless ($can_signature := nqp::can($oval, 'signature')) && ( $sigc.is_generic ?? ($sigc := $sigc.instantiate_generic($lexpad)) !! $sigc ).ACCEPTS($oval.signature) { if nqp::defined($error) { $error[0] := { Perl6::Metamodel::Configuration.throw_or_die( 'X::TypeCheck::Binding::Parameter', "Signature check failed for parameter '$varname'", :got($can_signature ?? $oval.signature !! Nil), :expected($sigc), :symbol($varname), :parameter($param), :what("Signature constraint") ) }; } return $BIND_RESULT_FAIL; } } } # Handle any constraint types (note that they may refer to the parameter by # name, so we need to have bound it already). my $post_cons := nqp::getattr($param, Parameter, '@!post_constraints'); unless nqp::isnull($post_cons) { my int $n := nqp::elems($post_cons); my int $i := -1; while ++$i < $n { # Check we meet the constraint. my $cons_type := nqp::atpos($post_cons, $i); if nqp::istype($cons_type, Code) { $cons_type := nqp::p6capturelexwhere($cons_type.clone()); } my $result; my $bad_value; if $got_native == 0 { $result := $cons_type.ACCEPTS($oval); $bad_value := $oval unless $result; } elsif $got_native == $SIG_ELEM_NATIVE_INT_VALUE { $result := $cons_type.ACCEPTS($ival); $bad_value := $ival unless $result; } elsif $got_native == $SIG_ELEM_NATIVE_UINT_VALUE { $result := $cons_type.ACCEPTS($ival); $bad_value := $ival unless $result; } elsif $got_native == $SIG_ELEM_NATIVE_NUM_VALUE { $result := $cons_type.ACCEPTS($nval); $bad_value := $nval unless $result; } elsif $got_native == $SIG_ELEM_NATIVE_STR_VALUE { $result := $cons_type.ACCEPTS($sval); $bad_value := $sval unless $result; } unless $result { if nqp::defined($error) { $error[0] := { Perl6::Metamodel::Configuration.throw_or_die( 'X::TypeCheck::Binding::Parameter', "Constraint type check failed for parameter '$varname'", :got($bad_value), :expected($cons_type), :symbol($varname), :parameter($param), :constraint(nqp::hllboolfor(1, 'Raku')) ) }; } return $BIND_RESULT_FAIL; } } } # If it's attributive, now we assign it. if $is_attributive { # Find self. my $self; if nqp::existskey($lexpad, 'self') { $self := nqp::atkey($lexpad, 'self'); } else { if nqp::defined($error) { $error[0] := "Unable to bind attributive parameter '$varname'; could not find self"; } return $BIND_RESULT_FAIL; } # Ensure it's not native; NYI. if $got_native { if nqp::defined($error) { $error[0] := "Binding to natively typed attributive parameter '$varname' not supported"; } return $BIND_RESULT_FAIL; } # If it's private, just need to fetch the attribute. my $assignee; if ($flags +& $SIG_ELEM_BIND_PRIVATE_ATTR) { $assignee := nqp::getattr($self, nqp::getattr($param, Parameter, '$!attr_package'), $varname); } # Otherwise if it's public, do a method call to get the assignee. else { $assignee := $self."$varname"(); } nqp::iscont($assignee) ?? nqp::assign($assignee, $oval) !! $assignee.STORE(nqp::decont($oval)); } # If it has a sub-signature, bind that. my $subsig := nqp::getattr($param, Parameter, '$!sub_signature'); unless nqp::isnull($subsig) { # Turn value into a capture, unless we already have one. my $capture; if $flags +& $SIG_ELEM_IS_CAPTURE { $capture := $oval; } elsif nqp::can($oval, 'Capture') { $capture := $oval.Capture; } else { if nqp::defined($error) { $error[0] := "Could not turn argument into capture"; } return $BIND_RESULT_FAIL; } # Recurse into signature binder. my $result := bind(make_vm_capture($capture), $subsig, $lexpad, $no_param_type_check, $error); unless $result == $BIND_RESULT_OK { if $error && nqp::isstr($error[0]) { # Note in the error message that we're in a sub-signature. $error[0] := $error[0] ~ " in sub-signature"; if $has_varname { $error[0] := $error[0] ~ " of parameter " ~ $varname; } } return $BIND_RESULT_FAIL; } } # Binding of this parameter was thus successful - we're done. $BIND_RESULT_OK } # 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. sub handle_optional($param, int $flags, $lexpad) { # Is the "get default from outer" flag set? if $flags +& $SIG_ELEM_DEFAULT_FROM_OUTER { nqp::atkey( nqp::ctxouter($lexpad), nqp::getattr_s($param, Parameter, '$!variable_name')) } # Do we have a default value or value closure? elsif !nqp::isnull(my $default_value := nqp::getattr($param, Parameter, '$!default_value')) { if $flags +& $SIG_ELEM_DEFAULT_IS_LITERAL { $default_value; } else { nqp::p6capturelexwhere($default_value.clone)(); } } # Otherwise, go by sigil to pick the correct default type of value. else { my $type := nqp::getattr($param, Parameter, '$!type'); if $flags +& $SIG_ELEM_ARRAY_SIGIL { nqp::create($type =:= Positional ?? Array !! Array.HOW.parameterize(Array, $type.of)); } elsif $flags +& $SIG_ELEM_HASH_SIGIL { nqp::create($type =:= Associative ?? Hash !! Hash.HOW.parameterize(Hash, $type.of, $type.keyof)); } else { $type } } } # Drives the overall binding process. sub bind($capture, $sig, $lexpad, int $no_param_type_check, $error) { # Get params. my @params := nqp::getattr($sig, Signature, '@!params'); # If we do have some named args, we get hold of a hash of them. We # can safely delete from this as we go. my $named_args; if nqp::capturehasnameds($capture) { $named_args := nqp::capturenamedshash($capture); } # Now we'll walk through the signature and go about binding things. my $named_names; my int $cur_pos_arg := 0; my int $num_pos_args := nqp::captureposelems($capture); my int $suppress_arity_fail := 0; my int $num_params := nqp::elems(@params); my int $i := 0; while $i < $num_params { # Get parameter object and its flags. my $param := nqp::atpos(@params, $i); my int $flags := nqp::getattr_i($param, Parameter, '$!flags'); my str $var_name := nqp::getattr_s($param, Parameter, '$!variable_name'); ++$i; # Is it looking for us to bind a capture here? my int $bind_fail; my int $got_prim; if $flags +& $SIG_ELEM_IS_CAPTURE { # Capture the arguments from this point forwards into a Capture. # Of course, if there's no variable name we can (cheaply) do pretty # much nothing. if nqp::isnull_s($var_name) && !nqp::getattr($param, Parameter, '$!sub_signature') && !nqp::getattr($param, Parameter, '@!post_constraints') { $bind_fail := $BIND_RESULT_OK; } else { my $capsnap := nqp::create(Capture); my @pos_args; my int $k := $cur_pos_arg; while $k < $num_pos_args { $got_prim := nqp::captureposprimspec($capture, $k); if $got_prim == 0 { nqp::push(@pos_args, nqp::captureposarg($capture, $k)); } elsif $got_prim == 1 { nqp::push(@pos_args, nqp::box_i(nqp::captureposarg_i($capture, $k), Int)); } elsif $got_prim == 2 { nqp::push(@pos_args, nqp::box_n(nqp::captureposarg_n($capture, $k), Num)); } elsif $got_prim == 10 { nqp::push(@pos_args, nqp::box_i(nqp::captureposarg_u($capture, $k), Int)); } else { nqp::push(@pos_args, nqp::box_s(nqp::captureposarg_s($capture, $k), Str)); } ++$k; } nqp::bindattr($capsnap, Capture, '@!list', @pos_args); if $named_args { nqp::bindattr($capsnap, Capture, '%!hash', nqp::clone($named_args)); } else { nqp::bindattr($capsnap, Capture, '%!hash', nqp::hash()); } $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, 0, $capsnap, 0, 0.0, ''); } if ($bind_fail) { return $bind_fail; } elsif $i == $num_params { # Since a capture acts as "the ultimate slurpy" in a sense, if # this is the last parameter in the signature we can return # success right off the bat. return $BIND_RESULT_OK; } else { my $next_param := nqp::atpos(@params, $i); my int $next_flags := nqp::getattr_i($next_param, Parameter, '$!flags'); if $next_flags +& ($SIG_ELEM_SLURPY_POS +| $SIG_ELEM_SLURPY_NAMED) { $suppress_arity_fail := 1; } } } # Could it be a named slurpy? elsif $flags +& $SIG_ELEM_SLURPY_NAMED { # We'll either take the current named arguments copy hash which # will by definition contain all unbound named arguments and use # that. If there are none, just keep the storage uninitialized # and rely on autovivification to build up an empty nqp::hash # whenever needed. my $hash := nqp::create(Hash); nqp::bindattr($hash, Map, '$!storage', $named_args) if $named_args; $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, 0, $hash, 0, 0.0, ''); return $bind_fail if $bind_fail; # Undefine named arguments hash now we've consumed it, to mark all # is well. $named_args := NQPMu; } # Otherwise, maybe it's a positional. elsif nqp::isnull($named_names := nqp::getattr($param, Parameter, '@!named_names')) { # Slurpy or LoL-slurpy? if $flags +& ($SIG_ELEM_SLURPY_POS +| $SIG_ELEM_SLURPY_LOL +| $SIG_ELEM_SLURPY_ONEARG) { # Create Perl 6 array, create VM Array of all remaining things, then # store it. my $temp := nqp::list(); while $cur_pos_arg < $num_pos_args { $got_prim := nqp::captureposprimspec($capture, $cur_pos_arg); if $got_prim == 0 { nqp::push($temp, nqp::captureposarg($capture, $cur_pos_arg)); } elsif $got_prim == 1 { nqp::push($temp, nqp::box_i(nqp::captureposarg_i($capture, $cur_pos_arg), Int)); } elsif $got_prim == 2 { nqp::push($temp, nqp::box_n(nqp::captureposarg_n($capture, $cur_pos_arg), Num)); } elsif $got_prim == 10 { nqp::push($temp, nqp::box_i(nqp::captureposarg_u($capture, $cur_pos_arg), Int)); } else { nqp::push($temp, nqp::box_s(nqp::captureposarg_s($capture, $cur_pos_arg), Str)); } ++$cur_pos_arg; } my $slurpy_type := $flags +& $SIG_ELEM_IS_RAW || $flags +& $SIG_ELEM_IS_RW ?? List !! Array; my $bindee := $flags +& $SIG_ELEM_SLURPY_ONEARG ?? $slurpy_type.from-slurpy-onearg($temp) !! $flags +& $SIG_ELEM_SLURPY_POS ?? $slurpy_type.from-slurpy-flat($temp) !! $slurpy_type.from-slurpy($temp); $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, 0, $bindee, 0, 0.0, ''); return $bind_fail if $bind_fail; } # Otherwise, a positional. else { # Do we have a value? if $cur_pos_arg < $num_pos_args { # Easy - just bind that. $got_prim := nqp::captureposprimspec($capture, $cur_pos_arg); if $got_prim == 0 { $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, 0, nqp::captureposarg($capture, $cur_pos_arg), 0, 0.0, ''); } elsif $got_prim == 1 { $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, $SIG_ELEM_NATIVE_INT_VALUE, nqp::null(), nqp::captureposarg_i($capture, $cur_pos_arg), 0.0, ''); } elsif $got_prim == 2 { $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, $SIG_ELEM_NATIVE_NUM_VALUE, nqp::null(), 0, nqp::captureposarg_n($capture, $cur_pos_arg), ''); } elsif $got_prim == 10 { $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, $SIG_ELEM_NATIVE_INT_VALUE, nqp::null(), nqp::captureposarg_u($capture, $cur_pos_arg), 0.0, ''); } else { $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, $SIG_ELEM_NATIVE_STR_VALUE, nqp::null(), 0, 0.0, nqp::captureposarg_s($capture, $cur_pos_arg)); } return $bind_fail if $bind_fail; ++$cur_pos_arg; } # No value. If it's optional, fetch a default and bind that; # if not, we're screwed. Note that we never nominal type check # an optional with no value passed. elsif $flags +& $SIG_ELEM_IS_OPTIONAL { $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, 0, handle_optional($param, $flags, $lexpad), 0, 0.0, ''); return $bind_fail if $bind_fail; } else { if nqp::defined($error) { $error[0] := arity_fail(@params, $num_params, $num_pos_args, 0, $lexpad); } return $BIND_RESULT_FAIL; } } } # Else, it's a non-slurpy named. else { # Try and get hold of value. my $value := nqp::null(); if $named_args { my int $num_names := nqp::elems($named_names); my int $j := -1; my str $cur_name; while ++$j < $num_names { $cur_name := nqp::atpos_s($named_names, $j); $value := nqp::atkey($named_args, $cur_name); unless nqp::isnull($value) { nqp::deletekey($named_args, $cur_name); $j := $num_names; } } } # Did we get one? if nqp::isnull($value) { # Nope. We'd better hope this param was optional... if $flags +& $SIG_ELEM_IS_OPTIONAL { $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, 0, handle_optional($param, $flags, $lexpad), 0, 0.0, ''); } elsif !$suppress_arity_fail { if nqp::defined($error) { $error[0] := "Required named argument '" ~ nqp::atpos_s($named_names,0) ~ "' not passed"; } return $BIND_RESULT_FAIL; } } else { $bind_fail := bind_one_param($lexpad, $sig, $param, $no_param_type_check, $error, 0, $value, 0, 0.0, ''); } # If we got a binding failure, return it. return $bind_fail if $bind_fail; } } # Do we have any left-over args? if $cur_pos_arg < $num_pos_args && !$suppress_arity_fail { # Oh noes, too many positionals passed. if nqp::defined($error) { $error[0] := arity_fail(@params, $num_params, $num_pos_args, 1, $lexpad); } return $BIND_RESULT_FAIL; } if $named_args { # Oh noes, unexpected named args. if nqp::defined($error) { my int $num_extra := nqp::elems($named_args); my @names; for $named_args { nqp::push(@names, $_.key); } if $num_extra == 1 { $error[0] := "Unexpected named argument '" ~ @names[0] ~ "' passed"; } else { $error[0] := $num_extra ~ " unexpected named arguments passed (" ~ nqp::join(",", @names) ~")"; } } return $BIND_RESULT_FAIL; } # If we get here, we're done. return $BIND_RESULT_OK; } method bind($capture, $sig, $lexpad, int $no_param_type_check, $error) { bind($capture, $sig, $lexpad, $no_param_type_check, $error); } method try_bind_sig($capture) { # Get signature and lexpad. my $caller := nqp::getcodeobj(nqp::callercode()); my $sig := nqp::getattr($caller, Code, '$!signature'); my $lexpad := nqp::ctxcaller(nqp::ctx()); # Call binder, and return non-zero if the bind is successful. bind($capture, $sig, $lexpad, 0, NQPMu) == 0 } method bind_sig($capture) { # Get signature and lexpad. my $caller := nqp::getcodeobj(nqp::callercode()); my $sig := nqp::getattr($caller, Code, '$!signature'); my $lexpad := nqp::ctxcaller(nqp::ctx()); # Call binder. my @error; my int $bind_res := bind($capture, $sig, $lexpad, 0, @error); if $bind_res { if $bind_res == $BIND_RESULT_JUNCTION { my @pos_args; my int $num_pos_args := nqp::captureposelems($capture); my int $k := -1; my int $got_prim; while ++$k < $num_pos_args { $got_prim := nqp::captureposprimspec($capture, $k); if $got_prim == 0 { nqp::push(@pos_args, nqp::captureposarg($capture, $k)); } elsif $got_prim == 1 { nqp::push(@pos_args, nqp::box_i(nqp::captureposarg_i($capture, $k), Int)); } elsif $got_prim == 2 { nqp::push(@pos_args, nqp::box_n(nqp::captureposarg_n($capture, $k), Num)); } elsif $got_prim == 10 { nqp::push(@pos_args, nqp::box_u(nqp::captureposarg_u($capture, $k), Int)); } else { nqp::push(@pos_args, nqp::box_s(nqp::captureposarg_s($capture, $k), Str)); } } my %named_args := nqp::capturenamedshash($capture); return Junction.AUTOTHREAD($caller, |@pos_args, |%named_args); } else { nqp::isinvokable(@error[0]) ?? @error[0]() !! nqp::die(@error[0]); } } nqp::null(); } sub make_vm_capture($capture) { sub vm_capture(*@pos, *%named) { nqp::savecapture() } my @list := nqp::getattr($capture, Capture, '@!list'); @list := nqp::list() unless nqp::islist(@list); my %hash := nqp::getattr($capture, Capture, '%!hash'); %hash := nqp::hash() unless nqp::ishash(%hash); vm_capture(|@list, |%hash) } method is_bindable($sig, $capture) { unless nqp::reprname($capture) eq 'MVMCapture' { $capture := make_vm_capture($capture); } my $bind-test := -> { bind($capture, $sig, nqp::ctxcaller(nqp::ctx()), 0, NQPMu) != $BIND_RESULT_FAIL } nqp::p6invokeunder( nqp::getattr(nqp::getattr($sig, Signature, '$!code'), Code, '$!do'), $bind-test) } method bind_cap_to_sig($sig, $cap) { my $capture := make_vm_capture($cap); my $lexpad := nqp::ctxcaller(nqp::ctx()); my @error; if bind($capture, $sig, $lexpad, 0, @error) != $BIND_RESULT_OK { nqp::isinvokable(@error[0]) ?? @error[0]() !! nqp::die(@error[0]); } $sig } method get_return_type($code) { nqp::getattr(nqp::getattr($code, Code, '$!signature'), Signature, '$!returns') } my int $TRIAL_BIND_NOT_SURE := 0; # Plausible, but need to check at runtime. my int $TRIAL_BIND_OK := 1; # Bind will always work out. my int $TRIAL_BIND_NO_WAY := -1; # Bind could never work out. method trial_bind($sig, $args, $sigflags) { my @params := nqp::getattr($sig, Signature, '@!params'); my int $num_params := nqp::elems(@params); # If there's a single capture parameter, then we're OK. (Worth # handling especially as it's the common case for protos). if $num_params == 1 { if nqp::getattr_i(@params[0], Parameter, '$!flags') +& $SIG_ELEM_IS_CAPTURE && nqp::isnull( nqp::getattr(@params[0], Parameter, '@!post_constraints')) { return $TRIAL_BIND_OK; } } # Walk through the signature and consider the parameters. my int $num_pos_args := nqp::elems($args); my int $cur_pos_arg := 0; my int $i := -1; while ++$i < $num_params { my $param := @params[$i]; # If the parameter is anything other than a boring old # positional parameter, we won't analyze it and will bail out, # unless it's a slurpy named param, in which case just ignore it my int $flags := nqp::getattr_i($param, Parameter, '$!flags'); if $flags +& $SIG_ELEM_SLURPY_NAMED && nqp::isnull( nqp::getattr($param, Parameter, '@!post_constraints')) { next } if $flags +& nqp::bitneg_i( $SIG_ELEM_MULTI_INVOCANT +| $SIG_ELEM_IS_RAW +| $SIG_ELEM_IS_COPY +| $SIG_ELEM_ARRAY_SIGIL +| $SIG_ELEM_HASH_SIGIL +| $SIG_ELEM_NATIVE_VALUE +| $SIG_ELEM_IS_OPTIONAL) || $flags +& $SIG_ELEM_IS_RW { return $TRIAL_BIND_NOT_SURE; } unless nqp::isnull(nqp::getattr($param, Parameter, '@!named_names')) { return $TRIAL_BIND_NOT_SURE; } unless nqp::isnull(nqp::getattr($param, Parameter, '@!post_constraints')) { return $TRIAL_BIND_NOT_SURE; } unless nqp::isnull(nqp::getattr($param, Parameter, '@!type_captures')) { return $TRIAL_BIND_NOT_SURE; } if $param.coercive { return $TRIAL_BIND_NOT_SURE; } # Do we have an argument for this parameter? if $cur_pos_arg >= $num_pos_args { # No; if it's not optional, fail. unless $flags +& $SIG_ELEM_IS_OPTIONAL { return $TRIAL_BIND_NO_WAY; } } else { # Yes, need to consider type my int $got_prim := $sigflags[$cur_pos_arg] +& 0xF; if $flags +& $SIG_ELEM_NATIVE_VALUE { if $got_prim == 0 { # We got an object; if we aren't sure we can unbox, we can't # be sure about the dispatch. if $flags +& $SIG_ELEM_NATIVE_INT_VALUE { return $TRIAL_BIND_NOT_SURE unless nqp::isint($args[$cur_pos_arg]); } elsif $flags +& $SIG_ELEM_NATIVE_UINT_VALUE { return $TRIAL_BIND_NOT_SURE unless nqp::isint($args[$cur_pos_arg]); } elsif $flags +& $SIG_ELEM_NATIVE_NUM_VALUE { return $TRIAL_BIND_NOT_SURE unless nqp::isnum($args[$cur_pos_arg]); } elsif $flags +& $SIG_ELEM_NATIVE_STR_VALUE { return $TRIAL_BIND_NOT_SURE unless nqp::isstr($args[$cur_pos_arg]); } else { # WTF... return $TRIAL_BIND_NOT_SURE; } } else { # If it's the wrong type of native, there's no way it # can ever bind. if (($flags +& $SIG_ELEM_NATIVE_INT_VALUE) && $got_prim != 1) || (($flags +& $SIG_ELEM_NATIVE_UINT_VALUE) && $got_prim != 10 && $got_prim != 1) || (($flags +& $SIG_ELEM_NATIVE_NUM_VALUE) && $got_prim != 2) || (($flags +& $SIG_ELEM_NATIVE_STR_VALUE) && $got_prim != 3) { return $TRIAL_BIND_NO_WAY; } } } else { # Work out a parameter type to consider, and see if it matches. my $arg := $got_prim == 1 ?? Int !! $got_prim == 10 ?? Int !! $got_prim == 2 ?? Num !! $got_prim == 3 ?? Str !! $args[$cur_pos_arg]; my $param_type := nqp::getattr($param, Parameter, '$!type'); unless $param_type =:= Mu || nqp::istype($arg, $param_type) { # If it failed because we got a junction, may auto-thread; # hand back 'not sure' for now. if $arg.WHAT =:= Junction { return $TRIAL_BIND_NOT_SURE; } # It failed to, but that doesn't mean it can't work at runtime; # we perhaps want an Int, and the most we know is we have an Any, # which would include Int. However, the Int ~~ Str case can be # rejected now, as there's no way it'd ever match. Basically, we # just flip the type check around. return nqp::istype($param_type, $arg.WHAT) ?? $TRIAL_BIND_NOT_SURE !! $TRIAL_BIND_NO_WAY; } } } # Continue to next argument. ++$cur_pos_arg; } # If we have any left over arguments, it's a binding fail. if $cur_pos_arg < $num_pos_args { return $TRIAL_BIND_NO_WAY; } # Otherwise, if we get there, all is well. return $TRIAL_BIND_OK; } } BEGIN { nqp::p6setbinder(Binder); } # We need it in for the next BEGIN block nqp::p6setbinder(Binder); # The load-time case. # Container descriptors come here so that they can refer to Raku types. class ContainerDescriptor does Perl6::Metamodel::Explaining { has $!of; has str $!name; has $!default; has int $!dynamic; method BUILD(:$of, str :$name, :$default, int :$dynamic) { $!of := $of; $!name := $name; $!default := $default; $!dynamic := $dynamic; } method of() { $!of } method name() { $!name } method default() { $!default } method dynamic() { $!dynamic } method set_of($of) { $!of := $of; self } method set_default($default) { $!default := $default; self } method set_dynamic($dynamic) { $!dynamic := $dynamic; self } method is_generic() { $!of.HOW.archetypes($!of).generic } method is_default_generic() { $!default.HOW.archetypes($!default).generic } method instantiate_generic($type_environment) { my $ins_of := $!of.HOW.instantiate_generic($!of, $type_environment); my $ins_default := self.is_default_generic ?? $!default.HOW.instantiate_generic($!default, $type_environment) !! $!default; my $ins := nqp::clone(self); nqp::bindattr($ins, $?CLASS, '$!of', $ins_of); nqp::bindattr($ins, $?CLASS, '$!default', $ins_default); $ins } } class ContainerDescriptor::Untyped is ContainerDescriptor { # Container descriptor for when the type is Mu; the type of this # container descriptor is used as a marker } role ContainerDescriptor::Whence { has $!next-descriptor; method next() { my $next := $!next-descriptor; nqp::isconcrete($next) ?? $next !! ($!next-descriptor := nqp::gethllsym('Raku', 'default_cont_spec')) } method of() { self.next.of } method default() { self.next.default } method dynamic() { self.next.dynamic } } class ContainerDescriptor::BindArrayPos does ContainerDescriptor::Whence { has $!target; has int $!pos; method new($desc, $target, int $pos) { my $self := nqp::create(self); nqp::bindattr($self, ContainerDescriptor::BindArrayPos, '$!next-descriptor', $desc); nqp::bindattr($self, ContainerDescriptor::BindArrayPos, '$!target', $target); nqp::bindattr_i($self, ContainerDescriptor::BindArrayPos, '$!pos', $pos); $self } method name() { self.next.name ~ '[' ~ $!pos ~ ']' } method assigned($scalar) { nqp::bindpos($!target, $!pos, $scalar); } } class ContainerDescriptor::BindArrayPos2D does ContainerDescriptor::Whence { has $!target; has int $!one; has int $!two; method new($desc, $target, int $one, int $two) { my $self := nqp::create(self); nqp::bindattr($self, ContainerDescriptor::BindArrayPos2D, '$!next-descriptor', $desc); nqp::bindattr($self, ContainerDescriptor::BindArrayPos2D, '$!target', $target); nqp::bindattr_i($self, ContainerDescriptor::BindArrayPos2D, '$!one', $one); nqp::bindattr_i($self, ContainerDescriptor::BindArrayPos2D, '$!two', $two); $self } method name() { 'element at [' ~ $!one ~ ',' ~ $!two ~ ']' # XXX name ? } method assigned($scalar) { nqp::bindpos2d($!target, $!one, $!two, $scalar); } } class ContainerDescriptor::BindArrayPos3D does ContainerDescriptor::Whence { has $!target; has int $!one; has int $!two; has int $!three; method new($desc, $target, int $one, int $two, int $three) { my $self := nqp::create(self); nqp::bindattr($self, ContainerDescriptor::BindArrayPos3D, '$!next-descriptor', $desc); nqp::bindattr($self, ContainerDescriptor::BindArrayPos3D, '$!target', $target); nqp::bindattr_i($self, ContainerDescriptor::BindArrayPos3D, '$!one', $one); nqp::bindattr_i($self, ContainerDescriptor::BindArrayPos3D, '$!two', $two); nqp::bindattr_i($self, ContainerDescriptor::BindArrayPos3D, '$!three', $three); $self } method name() { 'element at [' ~ $!one ~ ',' ~ $!two ~ ',' ~ $!three ~ ']' } method assigned($scalar) { nqp::bindpos3d($!target, $!one, $!two, $!three, $scalar); } } class ContainerDescriptor::BindArrayPosND does ContainerDescriptor::Whence { has $!target; has $!idxs; method new($desc, $target, $idxs) { my $self := nqp::create(self); nqp::bindattr($self, ContainerDescriptor::BindArrayPosND, '$!next-descriptor', $desc); nqp::bindattr($self, ContainerDescriptor::BindArrayPosND, '$!target', $target); nqp::bindattr($self, ContainerDescriptor::BindArrayPosND, '$!idxs', $idxs); $self } method name() { 'element of ' ~ self.next.name } # XXX show indexes method assigned($scalar) { nqp::bindposnd($!target, $!idxs, $scalar); } } class ContainerDescriptor::BindHashKey does ContainerDescriptor::Whence { has $!target; has $!key; method new($desc, $target, $key) { my $self := nqp::create(self); nqp::bindattr($self, ContainerDescriptor::BindHashKey, '$!next-descriptor', $desc); nqp::bindattr($self, ContainerDescriptor::BindHashKey, '$!target', $target); nqp::bindattr($self, ContainerDescriptor::BindHashKey, '$!key', $key); $self } method name() { self.next.name ~ "\{'" ~ $!key ~ "'\}" } method assigned($scalar) { my $hash := nqp::getattr($!target, Map, '$!storage'); $hash := nqp::bindattr($!target, Map, '$!storage', nqp::hash()) unless nqp::isconcrete($hash); nqp::bindkey($hash, $!key, $scalar); } } class ContainerDescriptor::BindObjHashKey does ContainerDescriptor::Whence { has $!target; has $!key; has $!which; has $!pair; method new($desc, $target, $key, $which, $pair) { my $self := nqp::create(self); nqp::bindattr($self, ContainerDescriptor::BindObjHashKey, '$!next-descriptor', $desc); nqp::bindattr($self, ContainerDescriptor::BindObjHashKey, '$!target', $target); nqp::bindattr($self, ContainerDescriptor::BindObjHashKey, '$!key', $key); nqp::bindattr($self, ContainerDescriptor::BindObjHashKey, '$!which', $which); nqp::bindattr($self, ContainerDescriptor::BindObjHashKey, '$!pair', $pair); $self } method name() { 'element of ' ~ self.next.name } # XXX correct key method assigned($scalar) { my $hash := nqp::getattr($!target, Map, '$!storage'); $hash := nqp::bindattr($!target, Map, '$!storage', nqp::hash()) unless nqp::isconcrete($hash); nqp::bindkey($hash, $!which, $!pair.new($!key, $scalar)); } } class ContainerDescriptor::VivifyArray does ContainerDescriptor::Whence { has $!target; has int $!pos; method new($target, int $pos) { my $self := nqp::create(self); nqp::bindattr($self, ContainerDescriptor::VivifyArray, '$!target', $target); nqp::bindattr_i($self, ContainerDescriptor::VivifyArray, '$!pos', $pos); $self } method name() { self.next.name ~ '[' ~ $!pos ~ ']' } method assigned($scalar) { my $target := $!target; my $array := nqp::isconcrete($target) ?? $target !! nqp::assign($target, Array.new); $array.BIND-POS($!pos, $scalar); } } class ContainerDescriptor::VivifyHash does ContainerDescriptor::Whence { has $!target; has $!key; method new($target, $key) { my $self := nqp::create(self); nqp::bindattr($self, ContainerDescriptor::VivifyHash, '$!target', $target); nqp::bindattr($self, ContainerDescriptor::VivifyHash, '$!key', $key); $self } method name() { self.next.name ~ "\{'" ~ $!key ~ "'\}" } method assigned($scalar) { my $target := $!target; my $hash := nqp::isconcrete($target) ?? $target !! nqp::assign($target, Hash.new); $hash.BIND-KEY($!key, $scalar); } } # Attributes that are either required or have a default need us to detect if # they have been initialized. We do this by starting them out with a descriptor # that indicates they are uninitialized, and then swapping it out for a the # underlying one upon assignment. class ContainerDescriptor::UninitializedAttribute { has $!next-descriptor; method new($next) { my $obj := nqp::create(self); nqp::bindattr($obj, ContainerDescriptor::UninitializedAttribute, '$!next-descriptor', $next); $obj } method next() { my $next := $!next-descriptor; nqp::isconcrete($next) ?? $next !! ($!next-descriptor := nqp::gethllsym('Raku', 'default_cont_spec')) } method name() { self.next.name } method of() { self.next.of } method default() { self.next.default } method dynamic() { self.next.dynamic } method instantiate_generic($type_environment) { self.new(self.next.instantiate_generic($type_environment)) } method is_generic() { self.next.is_generic } method is_default_generic() { self.next.is_default_generic } } # On MoarVM we have a dispatcher for checking if an attribute is not # initialized, this is the portable fallback for other VMs. # We stick all the declarative bits inside of a BEGIN, so they get # serialized. BEGIN { # Ensure Rakudo runtime support is initialized. nqp::p6init(); # On MoarVM, to get us through the bootstrap, put the NQP dispatchers in place # as the Raku ones; they will get replaced later in the bootstrap. nqp::sethllconfig('Raku', nqp::hash( 'call_dispatcher', 'nqp-call', 'method_call_dispatcher', 'nqp-meth-call', 'find_method_dispatcher', 'nqp-find-meth', )); # class Mu { ... } Mu.HOW.compose_repr(Mu); # class Any is Mu { ... } Any.HOW.add_parent(Any, Mu); Any.HOW.compose_repr(Any); # class Cool is Any { ... } Cool.HOW.add_parent(Cool, Any); Cool.HOW.compose_repr(Cool); # class Attribute is Any { # has str $!name; # has int $!rw; # has int $!is_built; # has int $!is_bound; # has int $!has_accessor; # has Mu $!type; # has Mu $!container_descriptor; # has Mu $!auto_viv_container; # has Mu $!build_closure; # has Mu $!package; # has int $!inlined; # has Mu $!dimensions; # has int $!positional_delegate; # has int $!associative_delegate; # has Mu $!why; # has Mu $!container_initializer; # has Attribute $!original; # original attribute object used for instantiation Attribute.HOW.add_parent(Attribute, Any); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!name>, :type(str), :package(Attribute))); # The existence of both $!rw and $!ro might be confusing, but they're needed for late trait application with # `also is rw`. In this case we must remember the earlier applied per-attribute traits. Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!rw>, :type(int), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!ro>, :type(int), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!required>, :type(Mu), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!is_built>, :type(int), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!is_bound>, :type(int), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!has_accessor>, :type(int), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!type>, :type(Mu), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!container_descriptor>, :type(Mu), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!auto_viv_container>, :type(Mu), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!build_closure>, :type(Mu), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!package>, :type(Mu), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!inlined>, :type(int), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!dimensions>, :type(Mu), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!box_target>, :type(int), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!positional_delegate>, :type(int), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!associative_delegate>, :type(int), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!why>, :type(Mu), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!container_initializer>, :type(Mu), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!original>, :type(Attribute), :package(Attribute))); Attribute.HOW.add_attribute(Attribute, BOOTSTRAPATTR.new(:name<$!composed>, :type(int), :package(Attribute))); # Need new and accessor methods for Attribute in here for now. Attribute.HOW.add_method(Attribute, 'new', nqp::getstaticcode(sub ($self, :$name!, :$type!, :$package!, :$inlined = 0, :$has_accessor = 0, :$is_built = $has_accessor, :$is_bound = 0, :$positional_delegate = 0, :$associative_delegate = 0, *%other) { my $attr := nqp::create($self); nqp::bindattr_s($attr, Attribute, '$!name', $name); nqp::bindattr($attr, Attribute, '$!type', nqp::decont($type)); nqp::bindattr_i($attr, Attribute, '$!is_built', $is_built); nqp::bindattr_i($attr, Attribute, '$!is_bound', $is_bound); nqp::bindattr_i($attr, Attribute, '$!has_accessor', $has_accessor); nqp::bindattr($attr, Attribute, '$!package', nqp::decont($package)); nqp::bindattr_i($attr, Attribute, '$!inlined', $inlined); nqp::bindattr($attr, Attribute, '$!original', $attr); if nqp::existskey(%other, 'auto_viv_primitive') { nqp::bindattr($attr, Attribute, '$!auto_viv_container', %other); } elsif nqp::existskey(%other, 'container_descriptor') { nqp::bindattr($attr, Attribute, '$!container_descriptor', %other); if nqp::existskey(%other, 'auto_viv_container') { nqp::bindattr($attr, Attribute, '$!auto_viv_container', %other); } } else { my $cd := ContainerDescriptor.new(:of(nqp::decont($type)), :$name); my $scalar := nqp::create(Scalar); nqp::bindattr($scalar, Scalar, '$!descriptor', $cd); nqp::bindattr($scalar, Scalar, '$!value', nqp::decont($type)); nqp::bindattr($attr, Attribute, '$!container_descriptor', $cd); nqp::bindattr($attr, Attribute, '$!auto_viv_container', $scalar); } if nqp::existskey(%other, 'container_initializer') { nqp::bindattr($attr, Attribute, '$!container_initializer', %other); } nqp::bindattr_i($attr, Attribute, '$!positional_delegate', $positional_delegate); nqp::bindattr_i($attr, Attribute, '$!associative_delegate', $associative_delegate); if nqp::existskey(%other, 'build') { $attr.set_build(%other); } $attr })); Attribute.HOW.add_method(Attribute, 'name', nqp::getstaticcode(sub ($self) { nqp::getattr_s(nqp::decont($self), Attribute, '$!name'); })); Attribute.HOW.add_method(Attribute, 'type', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Attribute, '$!type'); })); Attribute.HOW.add_method(Attribute, 'container_descriptor', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Attribute, '$!container_descriptor'); })); Attribute.HOW.add_method(Attribute, 'auto_viv_container', nqp::getstaticcode(sub ($self) { my $dcself := nqp::decont($self); my $cont := nqp::getattr($dcself, Attribute, '$!auto_viv_container'); if nqp::isconcrete_nd($cont) && ( nqp::getattr($dcself, Attribute, '$!required') || nqp::isconcrete(nqp::getattr($dcself, Attribute, '$!build_closure'))) { try { my $base := nqp::how_nd($cont).mixin_base($cont); my $desc := nqp::getattr($cont, $base, '$!descriptor'); $cont := nqp::clone_nd($cont); nqp::bindattr($cont, $base, '$!descriptor', ContainerDescriptor::UninitializedAttribute.new($desc)); } } $cont })); Attribute.HOW.add_method(Attribute, 'is_built', nqp::getstaticcode(sub ($self) { nqp::hllboolfor(nqp::getattr_i(nqp::decont($self), Attribute, '$!is_built'), "Raku"); })); Attribute.HOW.add_method(Attribute, 'is_bound', nqp::getstaticcode(sub ($self) { nqp::hllboolfor(nqp::getattr_i(nqp::decont($self), Attribute, '$!is_bound'), "Raku"); })); Attribute.HOW.add_method(Attribute, 'has_accessor', nqp::getstaticcode(sub ($self) { nqp::hllboolfor(nqp::getattr_i(nqp::decont($self), Attribute, '$!has_accessor'), "Raku"); })); Attribute.HOW.add_method(Attribute, 'rw', nqp::getstaticcode(sub ($self) { nqp::hllboolfor(nqp::getattr_i(nqp::decont($self), Attribute, '$!rw'), "Raku"); })); Attribute.HOW.add_method(Attribute, 'set_rw', nqp::getstaticcode(sub ($self) { nqp::bindattr_i(nqp::decont($self), Attribute, '$!rw', 1); nqp::hllboolfor(1, "Raku") })); Attribute.HOW.add_method(Attribute, 'set_readonly', nqp::getstaticcode(sub ($self) { nqp::bindattr_i(nqp::decont($self), Attribute, '$!ro', 1); # Explicit set of readonly must reset rw as it might be a result of `is rw` trait. nqp::bindattr_i(nqp::decont($self), Attribute, '$!rw', 0); nqp::hllboolfor(1, "Raku") })); Attribute.HOW.add_method(Attribute, 'set_required', nqp::getstaticcode(sub ($self, $value) { $*W.add_object_if_no_sc($value); nqp::bindattr(nqp::decont($self), Attribute, '$!required', $value); nqp::hllboolfor(1, "Raku") })); Attribute.HOW.add_method(Attribute, 'required', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Attribute, '$!required'); })); Attribute.HOW.add_method(Attribute, 'default_to_rw', nqp::getstaticcode(sub ($self) { my $dcself := nqp::decont($self); unless nqp::getattr_i($dcself, Attribute, '$!ro') { nqp::bindattr_i($dcself, Attribute, '$!rw', 1); } nqp::hllboolfor(1, "Raku") })); Attribute.HOW.add_method(Attribute, 'set_build', nqp::getstaticcode(sub ($self, $closure) { nqp::bindattr(nqp::decont($self), Attribute, '$!build_closure', $closure); $self })); Attribute.HOW.add_method(Attribute, 'build', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Attribute, '$!build_closure'); })); Attribute.HOW.add_method(Attribute, 'set_box_target', nqp::getstaticcode(sub ($self) { nqp::bindattr_i(nqp::decont($self), Attribute, '$!box_target', 1); nqp::hllboolfor(1, "Raku") })); Attribute.HOW.add_method(Attribute, 'box_target', nqp::getstaticcode(sub ($self) { nqp::getattr_i(nqp::decont($self), Attribute, '$!box_target') })); Attribute.HOW.add_method(Attribute, 'positional_delegate', nqp::getstaticcode(sub ($self) { nqp::getattr_i(nqp::decont($self), Attribute, '$!positional_delegate'); })); Attribute.HOW.add_method(Attribute, 'associative_delegate', nqp::getstaticcode(sub ($self) { nqp::getattr_i(nqp::decont($self), Attribute, '$!associative_delegate') })); Attribute.HOW.add_method(Attribute, 'container_initializer', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Attribute, '$!container_initializer'); })); Attribute.HOW.add_method(Attribute, 'original', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Attribute, '$!original'); })); Attribute.HOW.add_method(Attribute, 'is_generic', nqp::getstaticcode(sub ($self) { my $dcself := nqp::decont($self); my $type := nqp::getattr(nqp::decont($dcself), Attribute, '$!type'); my $package := nqp::getattr(nqp::decont($dcself), Attribute, '$!package'); my $build := nqp::getattr(nqp::decont($dcself), Attribute, '$!build_closure'); nqp::hllboolfor( $type.HOW.archetypes($type).generic || $package.HOW.archetypes($package).generic || nqp::defined($build), "Raku"); })); Attribute.HOW.add_method(Attribute, 'instantiate_generic', nqp::getstaticcode(sub ($self, $type_environment) { my $dcself := nqp::decont($self); my $type := nqp::getattr($dcself, Attribute, '$!type'); my $cd := nqp::getattr($dcself, Attribute, '$!container_descriptor'); my $pkg := nqp::getattr($dcself, Attribute, '$!package'); my $avc := nqp::getattr($dcself, Attribute, '$!auto_viv_container'); my $bc := nqp::getattr($dcself, Attribute, '$!build_closure'); my $ins := nqp::clone($dcself); if $type.HOW.archetypes($type).generic { nqp::bindattr($ins, Attribute, '$!type', $type.HOW.instantiate_generic($type, $type_environment)); my $cd_ins := $cd.instantiate_generic($type_environment); nqp::bindattr($ins, Attribute, '$!container_descriptor', $cd_ins); my $avc_copy := nqp::clone_nd($avc); my @avc_mro := nqp::how_nd($avc).mro($avc); my int $i := 0; $i := $i + 1 while @avc_mro[$i].HOW.is_mixin(@avc_mro[$i]); nqp::bindattr($avc_copy, @avc_mro[$i], '$!descriptor', $cd_ins); nqp::bindattr($ins, Attribute, '$!auto_viv_container', $avc_copy); } if $pkg.HOW.archetypes($pkg).generic { nqp::bindattr($ins, Attribute, '$!package', $pkg.HOW.instantiate_generic($pkg, $type_environment)); } if nqp::defined($bc) { nqp::bindattr($ins, Attribute, '$!build_closure', $bc.clone()); } $ins })); Attribute.HOW.compose_repr(Attribute); # class Scalar is Any { # has Mu $!descriptor; # has Mu $!value; Scalar.HOW.add_parent(Scalar, Any); Scalar.HOW.add_attribute(Scalar, BOOTSTRAPATTR.new(:name<$!descriptor>, :type(Mu), :package(Scalar))); Scalar.HOW.add_attribute(Scalar, BOOTSTRAPATTR.new(:name<$!value>, :type(Mu), :package(Scalar))); Scalar.HOW.add_method(Scalar, 'is_generic', nqp::getstaticcode(sub ($self) { my $dcself := nqp::decont($self); nqp::getattr($dcself, Scalar, '$!descriptor').is_generic() })); Scalar.HOW.add_method(Scalar, 'instantiate_generic', nqp::getstaticcode(sub ($self, $type_environment) { my $dcself := nqp::decont($self); nqp::bindattr($dcself, Scalar, '$!descriptor', nqp::getattr($dcself, Scalar, '$!descriptor').instantiate_generic( $type_environment)); my $val := nqp::getattr($dcself, Scalar, '$!value'); if $val.HOW.archetypes($val).generic { nqp::bindattr($dcself, Scalar, '$!value', $val.HOW.instantiate_generic($val, $type_environment)); } $dcself })); Scalar.HOW.compose_repr(Scalar); # To preserve historical behavior, we never repossess a Scalar container. nqp::neverrepossess(Scalar); # Scalar needs to be registered as a container type. Also provide the # slow-path implementation of various container operations. sub setup_scalar_contspec($type) { nqp::setcontspec($type, 'value_desc_cont', nqp::hash( 'attrs_class', Scalar, 'descriptor_attr', '$!descriptor', 'value_attr', '$!value', 'store', nqp::getstaticcode(sub ($cont, $val) { my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); if nqp::isconcrete($desc) { $val := $desc.default if nqp::eqaddr($val.WHAT, Nil); my $type := $desc.of; if nqp::eqaddr($type, Mu) || nqp::istype($val, $type) { if $type.HOW.archetypes($type).coercive { my $coercion_type := $type.HOW.wrappee($type, :coercion); nqp::bindattr($cont, Scalar, '$!value', nqp::dispatch('raku-coercion', $coercion_type, $val)); } else { nqp::bindattr($cont, Scalar, '$!value', $val); } my $what := $desc.WHAT; unless nqp::eqaddr($what, ContainerDescriptor) || nqp::eqaddr($what, ContainerDescriptor::Untyped) { $desc.assigned($cont) unless nqp::eqaddr($what, ContainerDescriptor::UninitializedAttribute); nqp::bindattr($cont, Scalar, '$!descriptor', $desc.next); } } else { Perl6::Metamodel::Configuration.throw_or_die( 'X::TypeCheck::Assignment', "Type check failed in assignment", :symbol($desc.name), :$desc, :got($val), :expected($type) ); } } else { nqp::die("Cannot assign to a readonly variable or a value"); } }), 'store_unchecked', nqp::getstaticcode(sub ($cont, $val) { nqp::bindattr($cont, Scalar, '$!value', $val); my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); my $what := $desc.WHAT; unless nqp::eqaddr($what, ContainerDescriptor) || nqp::eqaddr($what, ContainerDescriptor::Untyped) { $desc.assigned($cont) unless nqp::eqaddr($what, ContainerDescriptor::UninitializedAttribute); nqp::bindattr($cont, Scalar, '$!descriptor', $desc.next); } }), 'cas', nqp::getstaticcode(sub ($cont, $expected, $val) { my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); if nqp::isconcrete($desc) { $val := $desc.default if nqp::eqaddr($val.WHAT, Nil); my $type := $desc.of; if nqp::eqaddr($type, Mu) || nqp::istype($val, $type) { nqp::casattr($cont, Scalar, '$!value', $expected, $val); } else { Perl6::Metamodel::Configuration.throw_or_die( 'X::TypeCheck::Assignment', "Type check failed in assignment", :symbol($desc.name), :$desc, :got($val), :expected($type) ); } } else { nqp::die("Cannot assign to a readonly variable or a value"); } }), 'atomic_store', nqp::getstaticcode(sub ($cont, $val) { my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); if nqp::isconcrete($desc) { $val := $desc.default if nqp::eqaddr($val.WHAT, Nil); my $type := $desc.of; if nqp::eqaddr($type, Mu) || nqp::istype($val, $type) { nqp::atomicbindattr($cont, Scalar, '$!value', $val); } else { Perl6::Metamodel::Configuration.throw_or_die( 'X::TypeCheck::Assignment', "Type check failed in assignment", :symbol($desc.name), :$desc, :got($val), :expected($type) ); } } else { nqp::die("Cannot assign to a readonly variable or a value"); } }), )); } setup_scalar_contspec(Scalar); # Cache a single default Scalar container spec, to ensure we only get # one of them. Scalar.HOW.cache_add(Scalar, 'default_cont_spec', ContainerDescriptor::Untyped.new( :of(Mu), :default(Any), :name('element'))); # class ScalarVAR is Scalar { ScalarVAR.HOW.add_parent(ScalarVAR, Scalar); ScalarVAR.HOW.compose_repr(ScalarVAR); setup_scalar_contspec(ScalarVAR); # Set up various native reference types. sub setup_native_ref_type($type, $primitive, $ref_kind) { $type.HOW.add_parent($type, Any); $type.HOW.set_native_type($type, $primitive); $type.HOW.set_ref_kind($type, $ref_kind); $type.HOW.compose_repr($type); nqp::setcontspec($type, 'native_ref', nqp::null()); } setup_native_ref_type(IntLexRef, int, 'lexical'); setup_native_ref_type(UIntLexRef, uint, 'lexical'); setup_native_ref_type(NumLexRef, num, 'lexical'); setup_native_ref_type(StrLexRef, str, 'lexical'); setup_native_ref_type(IntAttrRef, int, 'attribute'); setup_native_ref_type(UIntAttrRef, uint, 'attribute'); setup_native_ref_type(NumAttrRef, num, 'attribute'); setup_native_ref_type(StrAttrRef, str, 'attribute'); setup_native_ref_type(IntPosRef, int, 'positional'); setup_native_ref_type(UIntPosRef, uint, 'positional'); setup_native_ref_type(NumPosRef, num, 'positional'); setup_native_ref_type(StrPosRef, str, 'positional'); setup_native_ref_type(IntMultidimRef, int, 'multidim'); setup_native_ref_type(UIntMultidimRef, uint, 'multidim'); setup_native_ref_type(NumMultidimRef, num, 'multidim'); setup_native_ref_type(StrMultidimRef, str, 'multidim'); # class Proxy is Any { # has Mu &!FETCH; # has Mu &!STORE; my $PROXY_FETCH; my $PROXY_STORE; Proxy.HOW.add_parent(Proxy, Any); Proxy.HOW.add_attribute(Proxy, BOOTSTRAPATTR.new(:name<&!FETCH>, :type(Mu), :package(Proxy))); Proxy.HOW.add_attribute(Proxy, BOOTSTRAPATTR.new(:name<&!STORE>, :type(Mu), :package(Proxy))); Proxy.HOW.add_method(Proxy, 'FETCH', ($PROXY_FETCH := nqp::getstaticcode(sub ($cont) { my $var := nqp::create(Scalar); nqp::bindattr($var, Scalar, '$!value', $cont); nqp::decont(nqp::getattr($cont, Proxy, '&!FETCH')($var)) }))); Proxy.HOW.add_method(Proxy, 'STORE', ($PROXY_STORE := nqp::getstaticcode(sub ($cont, $val) { my $var := nqp::create(Scalar); nqp::bindattr($var, Scalar, '$!value', $cont); nqp::getattr($cont, Proxy, '&!STORE')($var, $val) }))); Proxy.HOW.add_method(Proxy, 'new', nqp::getstaticcode(sub ($type, :$FETCH!, :$STORE!) { my $cont := nqp::create(nqp::decont($type)); nqp::bindattr($cont, Proxy, '&!FETCH', $FETCH); nqp::bindattr($cont, Proxy, '&!STORE', $STORE); $cont })); Proxy.HOW.set_container_spec(Proxy, nqp::hash( 'fetch', $PROXY_FETCH, 'store', $PROXY_STORE )); Proxy.HOW.compose(Proxy); Proxy.HOW.compose_repr(Proxy); # Helper for creating a scalar attribute. Sets it up as a real Perl 6 # Attribute instance, complete with container descriptor and optional # auto-viv container. sub scalar_attr($name, $type, $package, :$associative_delegate, :$auto_viv_container = 1) { my $cd := ContainerDescriptor.new(:of($type), :$name); if $auto_viv_container { my $scalar := nqp::create(Scalar); nqp::bindattr($scalar, Scalar, '$!descriptor', $cd); nqp::bindattr($scalar, Scalar, '$!value', $type); return Attribute.new( :$name, :$type, :$package, :container_descriptor($cd), :auto_viv_container($scalar), :$associative_delegate ); } else { return Attribute.new( :$name, :$type, :$package, :container_descriptor($cd), :$associative_delegate ); } } # Helper for creating an attribute that vivifies to a clone of some VM # storage type (or, if it's a type object, is just initialized with that # type object); used for the storage slots of arrays and hashes. sub storage_attr($name, $type, $package, $clonee, :$associative_delegate) { return Attribute.new( :$name, :$type, :$package, :auto_viv_primitive($clonee), :$associative_delegate ); } # class Signature is Any{ # has @!params; # has Mu $!returns; # has int $!arity; # has Num $!count; # has Code $!code; # has int $!readonly; Signature.HOW.add_parent(Signature, Any); Signature.HOW.add_attribute(Signature, Attribute.new(:name<@!params>, :type(List), :package(Signature))); Signature.HOW.add_attribute(Signature, scalar_attr('$!returns', Mu, Signature, :!auto_viv_container)); Signature.HOW.add_attribute(Signature, Attribute.new(:name<$!arity>, :type(int), :package(Signature))); Signature.HOW.add_attribute(Signature, Attribute.new(:name<$!count>, :type(Num), :package(Signature))); Signature.HOW.add_attribute(Signature, Attribute.new(:name<$!code>, :type(Code), :package(Signature))); Signature.HOW.add_attribute(Signature, Attribute.new(:name<$!readonly>, :type(int), :package(Signature))); Signature.HOW.add_method(Signature, 'is_generic', nqp::getstaticcode(sub ($self) { # If any parameter is generic, so are we. my @params := nqp::getattr($self, Signature, '@!params'); for @params { my $is_generic := $_.is_generic(); if $is_generic { return $is_generic } } return nqp::hllboolfor(0, "Raku"); })); Signature.HOW.add_method(Signature, 'instantiate_generic', nqp::getstaticcode(sub ($self, $type_environment) { # Go through parameters, builidng new list. If any # are generic, instantiate them. Otherwise leave them # as they are. my $ins := nqp::clone($self); my @params := nqp::getattr($self, Signature, '@!params'); my @ins_params; for @params { if $_.is_generic() { @ins_params.push($_.instantiate_generic($type_environment)) } else { @ins_params.push($_); } } nqp::bindattr($ins, Signature, '@!params', @ins_params); my $returns := nqp::getattr($self, Signature, '$!returns'); if !nqp::isnull($returns) && $returns.HOW.archetypes($returns).generic { nqp::bindattr($ins, Signature, '$!returns', $returns.HOW.instantiate_generic($returns, $type_environment)); } $ins })); Signature.HOW.add_method(Signature, 'returns', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self),Signature,'$!returns') })); Signature.HOW.add_method(Signature, 'set_returns', nqp::getstaticcode(sub ($self, $type) { nqp::bindattr(nqp::decont($self), Signature, '$!returns', nqp::decont($type)); })); Signature.HOW.add_method(Signature, 'has_returns', nqp::getstaticcode(sub ($self) { nqp::hllboolfor( nqp::not_i( nqp::isnull( nqp::getattr(nqp::decont($self), Signature, '$!returns') ) ), 'Raku' ); })); Signature.HOW.compose_repr(Signature); # class Parameter is Any { # has str $!variable_name # has @!named_names # has @!type_captures # has int $!flags # has Mu $!type # has @!post_constraints # has Signature $!sub_signature # has Code $!default_value # has Mu $!container_descriptor; # has Mu $!attr_package; # has Mu $!why; Parameter.HOW.add_parent(Parameter, Any); Parameter.HOW.add_attribute(Parameter, Attribute.new(:name<$!variable_name>, :type(str), :package(Parameter))); Parameter.HOW.add_attribute(Parameter, scalar_attr('@!named_names', Mu, Parameter, :!auto_viv_container)); Parameter.HOW.add_attribute(Parameter, scalar_attr('@!type_captures', Mu, Parameter, :!auto_viv_container)); Parameter.HOW.add_attribute(Parameter, Attribute.new(:name<$!flags>, :type(int), :package(Parameter))); Parameter.HOW.add_attribute(Parameter, Attribute.new(:name<$!type>, :type(Mu), :package(Parameter))); Parameter.HOW.add_attribute(Parameter, scalar_attr('@!post_constraints', List, Parameter, :!auto_viv_container)); Parameter.HOW.add_attribute(Parameter, scalar_attr('$!sub_signature', Signature, Parameter, :!auto_viv_container)); Parameter.HOW.add_attribute(Parameter, scalar_attr('$!default_value', Code, Parameter, :!auto_viv_container)); Parameter.HOW.add_attribute(Parameter, scalar_attr('$!container_descriptor', Mu, Parameter, :!auto_viv_container)); Parameter.HOW.add_attribute(Parameter, Attribute.new(:name<$!attr_package>, :type(Mu), :package(Parameter))); Parameter.HOW.add_attribute(Parameter, Attribute.new(:name<$!why>, :type(Mu), :package(Parameter))); Parameter.HOW.add_attribute(Parameter, scalar_attr('$!signature_constraint', Signature, Parameter, :!auto_viv_container)); Parameter.HOW.add_method(Parameter, 'is_generic', nqp::getstaticcode(sub ($self) { # If nonimnal type or attr_package is generic, so are we. my $type := nqp::getattr($self, Parameter, '$!type'); my $ap := nqp::getattr($self, Parameter, '$!attr_package'); my $sigc := nqp::getattr($self, Parameter, '$!signature_constraint'); nqp::hllboolfor( $type.HOW.archetypes($type).generic || (!nqp::isnull($ap) && $ap.HOW.archetypes($ap).generic) || (nqp::defined($sigc) && $sigc.is_generic), "Raku") })); Parameter.HOW.add_method(Parameter, 'instantiate_generic', nqp::getstaticcode(sub ($self, $type_environment) { # Clone with the type instantiated. my int $SIG_ELEM_TYPE_GENERIC := 524288; my int $SIG_ELEM_IS_COERCIVE := 67108864; my $ins := nqp::clone($self); my $type := nqp::getattr($self, Parameter, '$!type'); my $cd := nqp::getattr($self, Parameter, '$!container_descriptor'); my $ap := nqp::getattr($self, Parameter, '$!attr_package'); my $sigc := nqp::getattr($self, Parameter, '$!signature_constraint'); my $ins_type := $type; my $ins_cd := $cd; if $type.HOW.archetypes($type).generic { $ins_type := $type.HOW.instantiate_generic($type, $type_environment); $ins_cd := nqp::isnull($cd) ?? $cd !! $cd.instantiate_generic($type_environment); } my $ins_ap := !nqp::isnull($ap) && $ap.HOW.archetypes($ap).generic ?? $ap.HOW.instantiate_generic($ap, $type_environment) !! $ap; my $ins_sigc := nqp::defined($sigc) && $sigc.is_generic ?? $sigc.instantiate_generic($type_environment) !! $sigc; my int $flags := nqp::getattr_i($ins, Parameter, '$!flags'); unless $ins_type.HOW.archetypes($ins_type).generic { if $flags +& $SIG_ELEM_TYPE_GENERIC { nqp::bindattr_i($ins, Parameter, '$!flags', $flags - $SIG_ELEM_TYPE_GENERIC); } } my $archetypes := $ins_type.HOW.archetypes($ins_type); if nqp::can($archetypes, 'coercive') && $archetypes.coercive { nqp::bindattr_i($ins, Parameter, '$!flags', $flags +| $SIG_ELEM_IS_COERCIVE); } nqp::bindattr($ins, Parameter, '$!type', $ins_type); nqp::bindattr($ins, Parameter, '$!container_descriptor', $ins_cd); nqp::bindattr($ins, Parameter, '$!attr_package', $ins_ap); nqp::bindattr($ins, Parameter, '$!signature_constraint', $ins_sigc); $ins })); Parameter.HOW.add_method(Parameter, 'set_rw', nqp::getstaticcode(sub ($self) { my $SIG_ELEM_IS_RW := 256; my $SIG_ELEM_IS_OPTIONAL := 2048; my $dcself := nqp::decont($self); my str $varname := nqp::getattr_s($dcself, Parameter, '$!variable_name'); unless nqp::isnull_s($varname) || nqp::eqat($varname, '$', 0) { my $error; if nqp::eqat($varname, '%', 0) || nqp::eqat($varname, '@', 0) { my $sig := nqp::substr($varname, 0, 1); $error := "For parameter '$varname', '$sig' sigil containers don't need 'is rw' to be writable\n"; } $error := $error ~ "Can only use 'is rw' on a scalar ('\$' sigil) parameter, not '$varname'"; nqp::die($error); } my int $flags := nqp::getattr_i($dcself, Parameter, '$!flags'); if $flags +& $SIG_ELEM_IS_OPTIONAL { Perl6::Metamodel::Configuration.throw_or_die( 'X::Trait::Invalid', "Cannot use 'is rw' on optional parameter '$varname'", :type('is'), :subtype('rw'), :declaring('optional parameter'), :name($varname) ); } nqp::bindattr_i($dcself, Parameter, '$!flags', $flags + $SIG_ELEM_IS_RW); $dcself })); Parameter.HOW.add_method(Parameter, 'set_copy', nqp::getstaticcode(sub ($self) { my $SIG_ELEM_IS_COPY := 512; my $dcself := nqp::decont($self); nqp::bindattr_i($dcself, Parameter, '$!flags', nqp::getattr_i($dcself, Parameter, '$!flags') + $SIG_ELEM_IS_COPY); $dcself })); Parameter.HOW.add_method(Parameter, 'set_required', nqp::getstaticcode(sub ($self) { my $SIG_ELEM_IS_OPTIONAL := 2048; my $dcself := nqp::decont($self); my int $flags := nqp::getattr_i($dcself, Parameter, '$!flags'); if $flags +& $SIG_ELEM_IS_OPTIONAL { nqp::bindattr_i($dcself, Parameter, '$!flags', $flags - $SIG_ELEM_IS_OPTIONAL); } $dcself })); Parameter.HOW.add_method(Parameter, 'set_raw', nqp::getstaticcode(sub ($self) { my $SIG_ELEM_IS_RAW := 1024; my $dcself := nqp::decont($self); my int $flags := nqp::getattr_i($dcself, Parameter, '$!flags'); unless $flags +& $SIG_ELEM_IS_RAW { nqp::bindattr_i($dcself, Parameter, '$!flags', $flags + $SIG_ELEM_IS_RAW); } $dcself })); Parameter.HOW.add_method(Parameter, 'set_onearg', nqp::getstaticcode(sub ($self) { my $SIG_ELEM_SLURPY_ONEARG := 16777216; my $dcself := nqp::decont($self); my int $flags := nqp::getattr_i($dcself, Parameter, '$!flags'); unless $flags +& $SIG_ELEM_SLURPY_ONEARG { nqp::bindattr_i($dcself, Parameter, '$!flags', $flags + $SIG_ELEM_SLURPY_ONEARG); } $dcself })); Parameter.HOW.add_method(Parameter, 'WHY', nqp::getstaticcode(sub ($self) { my $why := nqp::getattr(nqp::decont($self), Parameter, '$!why'); if nqp::isnull($why) || !$why { Nil } else { $why.set_docee($self); $why } })); Parameter.HOW.add_method(Parameter, 'container_descriptor', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Parameter, '$!container_descriptor'); })); Parameter.HOW.add_method(Parameter, 'coercive', nqp::getstaticcode(sub ($self) { #my int $SIG_ELEM_IS_COERCIVE := 67108864; nqp::if(nqp::bitand_i(nqp::getattr(nqp::decont($self), Parameter, '$!flags'), 67108864), 1, 0) })); Parameter.HOW.compose_repr(Parameter); # class Code { # has Code $!do; # Low level code object # has Signature $!signature; # Signature object # has @!compstuff; # Place for the compiler to hang stuff Code.HOW.add_parent(Code, Any); Code.HOW.add_attribute(Code, Attribute.new(:name<$!do>, :type(Code), :package(Code))); Code.HOW.add_attribute(Code, Attribute.new(:name<$!signature>, :type(Signature), :package(Code))); Code.HOW.add_attribute(Code, scalar_attr('@!compstuff', List, Code, :!auto_viv_container)); # Need clone in here, plus generics instantiation. Code.HOW.add_method(Code, 'clone', nqp::getstaticcode(sub ($self) { my $dcself := nqp::decont($self); if nqp::isconcrete($dcself) { my $clself := nqp::clone($dcself); my $do := nqp::getattr($dcself, Code, '$!do'); my $cldo := nqp::clone($do); nqp::bindattr($clself, Code, '$!do', $cldo); nqp::setcodeobj($cldo, $clself); my $compstuff := nqp::getattr($dcself, Code, '@!compstuff'); $compstuff[2]($do, $clself) unless nqp::isnull($compstuff); $clself } else { $dcself } })); Code.HOW.add_method(Code, 'is_generic', nqp::getstaticcode(sub ($self) { # Delegate to signature, since it contains all the type info. nqp::getattr(nqp::decont($self), Code, '$!signature').is_generic() })); Code.HOW.add_method(Code, 'instantiate_generic', nqp::getstaticcode(sub ($self, $type_environment) { # Clone the code object, then instantiate the generic signature. Also # need to clone dispatchees list. my $dcself := nqp::decont($self); my $ins := $self.clone(); if nqp::defined(nqp::getattr($dcself, Routine, '@!dispatchees')) { nqp::bindattr($ins, Routine, '@!dispatchees', nqp::clone(nqp::getattr($dcself, Routine, '@!dispatchees'))); } my $sig := nqp::getattr($dcself, Code, '$!signature'); nqp::bindattr($ins, Code, '$!signature', $sig.instantiate_generic($type_environment)); $ins })); Code.HOW.add_method(Code, 'name', nqp::getstaticcode(sub ($self) { nqp::getcodename(nqp::getattr(nqp::decont($self), Code, '$!do')) })); Code.HOW.add_method(Code, 'set_name', nqp::getstaticcode(sub ($self, $name) { nqp::setcodename( nqp::getattr(nqp::decont($self), Code, '$!do'), $name) })); Code.HOW.add_method(Code, 'id', nqp::getstaticcode(sub ($self) { nqp::where(nqp::getattr(nqp::decont($self), Code, '$!do')) })); Code.HOW.compose_repr(Code); # class Block is Code { # has Mu $!phasers; # phasers for this block # has Mu $!why; Block.HOW.add_parent(Block, Code); Block.HOW.add_attribute(Block, Attribute.new(:name<$!phasers>, :type(Mu), :package(Block), :auto_viv_primitive(nqp::null()))); Block.HOW.add_attribute(Block, scalar_attr('$!why', Mu, Block, :!auto_viv_container)); Block.HOW.add_method(Block, 'clone', nqp::getstaticcode(sub ($self) { my $dcself := nqp::decont($self); if nqp::isconcrete($dcself) { my $cloned := nqp::clone($dcself); my $do := nqp::getattr($dcself, Code, '$!do'); nqp::setcodeobj( nqp::bindattr($cloned, Code, '$!do', my $cldo := nqp::clone($do)), $cloned ); my $phasers := nqp::getattr($dcself, Block, '$!phasers'); $dcself."!clone_phasers"($cloned, $phasers) if nqp::ishash($phasers); my $compstuff := nqp::getattr($dcself, Code, '@!compstuff'); nqp::atpos($compstuff, 2)($do, $cloned) unless nqp::isnull($compstuff); # XXX this should probably be done after the clone that installs # the sub my $why := nqp::getattr($dcself, Block, '$!why'); $why.set_docee($cloned) unless nqp::isnull($why); $cloned } else { $dcself } })); Block.HOW.add_method(Block, '!clone_phasers', nqp::getstaticcode(sub ($self, $cloned, $phasers) { my int $next := nqp::existskey($phasers, 'NEXT'); my int $last := nqp::existskey($phasers, 'LAST'); my int $quit := nqp::existskey($phasers, 'QUIT'); my int $close := nqp::existskey($phasers, 'CLOSE'); if $next +| $last +| $quit +| $close { my %pclone := nqp::clone($phasers); if $next { my @nexts := nqp::clone($phasers); my int $i := -1; while ++$i < nqp::elems(@nexts) { @nexts[$i] := @nexts[$i].clone(); } %pclone := @nexts; } if $last { my @lasts := nqp::clone($phasers); my int $i := -1; while ++$i < nqp::elems(@lasts) { nqp::captureinnerlex(nqp::getattr( (@lasts[$i] := @lasts[$i].clone()), Code, '$!do')); } %pclone := @lasts; } if $quit { my @quits := nqp::clone($phasers); my int $i := -1; while ++$i < nqp::elems(@quits) { nqp::captureinnerlex(nqp::getattr( (@quits[$i] := @quits[$i].clone()), Code, '$!do')); } %pclone := @quits; } if $close { my @closes := nqp::clone($phasers); my int $i := -1; while ++$i < nqp::elems(@closes) { nqp::captureinnerlex(nqp::getattr( (@closes[$i] := @closes[$i].clone()), Code, '$!do')); } %pclone := @closes; } nqp::bindattr($cloned, Block, '$!phasers', %pclone); } })); Block.HOW.add_method(Block, '!capture_phasers', nqp::getstaticcode(sub ($self) { my $dcself := nqp::decont($self); my $phasers := nqp::getattr($dcself, Block, '$!phasers'); if nqp::ishash($phasers) { my @next := nqp::atkey($phasers, 'NEXT'); if nqp::islist(@next) { my int $i := -1; while ++$i < nqp::elems(@next) { nqp::p6capturelexwhere(@next[$i]); } } my @last := nqp::atkey($phasers, 'LAST'); if nqp::islist(@last) { my int $i := -1; while ++$i < nqp::elems(@last) { nqp::p6capturelexwhere(@last[$i]); } } my @quit := nqp::atkey($phasers, 'QUIT'); if nqp::islist(@quit) { my int $i := -1; while ++$i < nqp::elems(@quit) { nqp::p6capturelexwhere(@quit[$i]); } } my @close := nqp::atkey($phasers, 'CLOSE'); if nqp::islist(@close) { my int $i := -1; while ++$i < nqp::elems(@close) { nqp::p6capturelexwhere(@close[$i]); } } } $dcself })); Block.HOW.compose_repr(Block); # class Routine is Block { # has @!dispatchees; # has Mu $!dispatcher; # has int $!flags; # has Mu $!inline_info; # has Mu $!package; # has @!dispatch_order; # has Mu $!dispatch_cache; # has Mu $!op_props; Routine.HOW.add_parent(Routine, Block); Routine.HOW.add_attribute(Routine, Attribute.new(:name<@!dispatchees>, :type(List), :package(Routine), :auto_viv_primitive(nqp::null()))); Routine.HOW.add_attribute(Routine, Attribute.new(:name<$!dispatcher>, :type(Mu), :package(Routine), :auto_viv_primitive(nqp::null()))); Routine.HOW.add_attribute(Routine, Attribute.new(:name<$!flags>, :type(int), :package(Routine))); Routine.HOW.add_attribute(Routine, Attribute.new(:name<$!inline_info>, :type(Mu), :package(Routine))); Routine.HOW.add_attribute(Routine, Attribute.new(:name<$!package>, :type(Mu), :package(Routine))); Routine.HOW.add_attribute(Routine, scalar_attr('@!dispatch_order', List, Routine, :!auto_viv_container)); Routine.HOW.add_attribute(Routine, Attribute.new(:name<$!op_props>, :type(Mu), :package(Routine))); Routine.HOW.add_method(Routine, 'is_dispatcher', nqp::getstaticcode(sub ($self) { my $dc_self := nqp::decont($self); my $disp_list := nqp::getattr($dc_self, Routine, '@!dispatchees'); nqp::hllboolfor(nqp::defined($disp_list), "Raku"); })); Routine.HOW.add_method(Routine, 'add_dispatchee', nqp::getstaticcode(sub ($self, $dispatchee) { my $dc_self := nqp::decont($self); my $disp_list := nqp::getattr($dc_self, Routine, '@!dispatchees'); if nqp::defined($disp_list) { $disp_list.push($dispatchee); nqp::bindattr(nqp::decont($dispatchee), Routine, '$!dispatcher', $dc_self); nqp::scwbdisable(); nqp::bindattr($dc_self, Routine, '@!dispatch_order', nqp::null()); nqp::scwbenable(); $dc_self } else { nqp::die("Cannot add dispatchee '" ~ $dispatchee.name() ~ "' to non-dispatcher code object '" ~ $self.name() ~ "'"); } })); Routine.HOW.add_method(Routine, 'derive_dispatcher', nqp::getstaticcode(sub ($self) { my $clone := $self.clone(); nqp::bindattr($clone, Routine, '@!dispatchees', nqp::clone(nqp::getattr($self, Routine, '@!dispatchees'))); $clone })); Routine.HOW.add_method(Routine, 'dispatcher', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Routine, '$!dispatcher') })); Routine.HOW.add_method(Routine, 'dispatchees', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Routine, '@!dispatchees') })); Routine.HOW.add_method(Routine, '!configure_positional_bind_failover', nqp::getstaticcode(sub ($self, $Positional, $PositionalBindFailover) { nqp::bindhllsym('Raku', 'MD_Pos', $Positional); nqp::bindhllsym('Raku', 'MD_PBF', $PositionalBindFailover); })); Routine.HOW.add_method(Routine, '!sort_dispatchees_internal', nqp::getstaticcode(sub ($self) { my int $SLURPY_ARITY := nqp::bitshiftl_i(1, 30); my int $EDGE_REMOVAL_TODO := -1; my int $EDGE_REMOVED := -2; my int $DEFCON_NONE := 0; my int $DEFCON_DEFINED := 1; my int $DEFCON_UNDEFINED := 2; my int $DEFCON_MASK := $DEFCON_DEFINED +| $DEFCON_UNDEFINED; my int $TYPE_NATIVE_INT := 4; my int $TYPE_NATIVE_NUM := 8; my int $TYPE_NATIVE_STR := 16; my int $TYPE_NATIVE_UINT := 32; my int $TYPE_NATIVE_MASK := $TYPE_NATIVE_INT +| $TYPE_NATIVE_UINT +| $TYPE_NATIVE_NUM +| $TYPE_NATIVE_STR; my int $SIG_ELEM_SLURPY_POS := 8; my int $SIG_ELEM_SLURPY_NAMED := 16; my int $SIG_ELEM_SLURPY_LOL := 32; my int $SIG_ELEM_MULTI_INVOCANT := 128; my int $SIG_ELEM_IS_RW := 256; my int $SIG_ELEM_IS_OPTIONAL := 2048; my int $SIG_ELEM_IS_CAPTURE := 32768; my int $SIG_ELEM_UNDEFINED_ONLY := 65536; my int $SIG_ELEM_DEFINED_ONLY := 131072; my int $SIG_ELEM_TYPE_GENERIC := 524288; my int $SIG_ELEM_NATIVE_INT_VALUE := 2097152; my int $SIG_ELEM_NATIVE_UINT_VALUE := 134217728; my int $SIG_ELEM_NATIVE_NUM_VALUE := 4194304; my int $SIG_ELEM_NATIVE_STR_VALUE := 8388608; my int $SIG_ELEM_SLURPY_ONEARG := 16777216; # Takes two candidates and determines if the first one is narrower # than the second. Returns a true value if they are. sub is_narrower(%a, %b) { # Work out how many parameters to compare, factoring in # slurpiness and optionals. my int $types_to_check; if %a == %b { $types_to_check := %a; } elsif %a == %b { $types_to_check := %a > %b ?? %b !! %a; } elsif %a != $SLURPY_ARITY && %b == $SLURPY_ARITY { return 1; } else { return 0; } # Analyse each parameter in the two candidates. my int $narrower := 0; my int $tied := 0; my int $i := -1; while ++$i < $types_to_check { my $type_obj_a := %a[$i]; my $type_obj_b := %b[$i]; if nqp::eqaddr($type_obj_a, $type_obj_b) { # Same type; narrower if first has constraints and other doesn't; # narrower if first is rw and second isn't; tied if neither has # constraints or both have constraints. if %a[$i] && !%b[$i] { ++$narrower; } elsif nqp::atpos_i(%a, $i) > nqp::atpos_i(%b, $i) { ++$narrower; } elsif (!%a[$i] && !%b[$i]) || (%a[$i] && %b[$i]) { ++$tied; } } elsif (nqp::atpos_i(%a, $i) +& $TYPE_NATIVE_MASK) && !(nqp::atpos_i(%b, $i) +& $TYPE_NATIVE_MASK) { # Narrower because natives always are. ++$narrower; } elsif (nqp::atpos_i(%b, $i) +& $TYPE_NATIVE_MASK) && !(nqp::atpos_i(%a, $i) +& $TYPE_NATIVE_MASK) { # Wider; skip over here so we don't go counting this as tied in # the next branch. } else { if nqp::istype($type_obj_a, $type_obj_b) { # Narrower - note it and we're done. ++$narrower; } else { # Make sure it's tied, rather than the other way around. unless nqp::istype($type_obj_b, $type_obj_a) { ++$tied; } } } } # If one is narrower than the other from current analysis, we're done. if $narrower >= 1 && $narrower + $tied == $types_to_check { return 1; } # If they aren't tied, we're also done. elsif $tied != $types_to_check { return 0; } # Otherwise, we see if one has a slurpy and the other not. A lack of # slurpiness makes the candidate narrower. if %a != $SLURPY_ARITY && %b == $SLURPY_ARITY { return 1; } # Also narrower if the first needs a bind check and the second doesn't, if # we wouldn't deem the other one narrower than this one in terms of # slurpyness. Otherwise, they're tied. return !(%b != $SLURPY_ARITY && %a == $SLURPY_ARITY) && (%a && !%b); } my $dcself := nqp::decont($self); my @candidates := nqp::getattr($dcself, Routine, '@!dispatchees'); # Create a node for each candidate in the graph. my @graph; for @candidates -> $candidate { # Get hold of signature. my $sig := nqp::getattr($candidate, Code, '$!signature'); my @params := nqp::getattr($sig, Signature, '@!params'); # Create it an entry. my %info := nqp::hash( 'sub', $candidate, 'signature', $sig, 'types', [], 'type_flags', nqp::list_i(), 'constraints', [], 'rwness', nqp::list_i() ); if nqp::istype($candidate, Submethod) { %info := 1; } my int $significant_param := 0; my int $min_arity := 0; my int $max_arity := 0; my int $num_types := 0; my @coerce_type_idxs; my @coerce_type_objs; for @params -> $param { # If it's got a sub-signature, also need a bind check and # to check constraint on every dispatch. Same if it's got a # `where` clause. unless nqp::isnull(nqp::getattr($param, Parameter, '$!sub_signature')) && nqp::isnull(nqp::getattr($param, Parameter, '@!post_constraints')) && !nqp::defined(nqp::getattr($param, Parameter, '$!signature_constraint')) { %info := 1; %info := 1; } # For named arguments: # * Under the legacy dispatcher (not on MoarVM, which uses new-disp) # we leave named argument checking to be done via a bind check. We # only set that if it's a required named. # * For the new-disp based dispatcher, we collect a list of required # named arguments and allowed named arguments, and filter those out # without the bind check. my int $flags := nqp::getattr_i($param, Parameter, '$!flags'); my $named_names := nqp::getattr($param, Parameter, '@!named_names'); unless nqp::isnull($named_names) { if $flags +& $SIG_ELEM_MULTI_INVOCANT { unless $flags +& $SIG_ELEM_IS_OPTIONAL { %info := [] unless %info; nqp::push(%info, $named_names); if nqp::elems($named_names) == 1 { %info := nqp::atpos_s($named_names, 0); } } %info := 1; } %info := nqp::hash() unless %info; my int $i; my int $n := nqp::elems($named_names); while $i < $n { %info{nqp::atpos_s($named_names, $i)} := NQPMu; $i++; } next; } if $flags +& ($SIG_ELEM_SLURPY_NAMED +| $SIG_ELEM_IS_CAPTURE) { %info := 1; nqp::deletekey(%info, 'allowed_names'); } if $flags +& $SIG_ELEM_SLURPY_NAMED { last; } # Otherwise, positional or slurpy and contributes to arity. if $flags +& ($SIG_ELEM_SLURPY_POS +| $SIG_ELEM_SLURPY_LOL +| $SIG_ELEM_IS_CAPTURE +| $SIG_ELEM_SLURPY_ONEARG) { $max_arity := $SLURPY_ARITY; next; } elsif $flags +& $SIG_ELEM_IS_OPTIONAL { ++$max_arity; } else { ++$max_arity; ++$min_arity; } # Record type info for this parameter. if $flags +& $SIG_ELEM_TYPE_GENERIC { %info := 1; %info := 1; %info[$significant_param] := Any; } else { my $ptype := nqp::getattr($param, Parameter, '$!type'); if $ptype.HOW.archetypes($ptype).coercive { my $coercion_type := $ptype.HOW.wrappee($ptype, :coercion); $ptype := $coercion_type.HOW.constraint_type($coercion_type); } %info[$significant_param] := $ptype; } unless nqp::isnull(nqp::getattr($param, Parameter, '@!post_constraints')) && !nqp::defined(nqp::getattr($param, Parameter, '$!signature_constraint')) { %info[$significant_param] := 1; } if $flags +& $SIG_ELEM_MULTI_INVOCANT { ++$num_types; } if $flags +& $SIG_ELEM_IS_RW { nqp::bindpos_i(%info, $significant_param, 1); } if $flags +& $SIG_ELEM_DEFINED_ONLY { nqp::bindpos_i(%info, $significant_param, $DEFCON_DEFINED); } elsif $flags +& $SIG_ELEM_UNDEFINED_ONLY { nqp::bindpos_i(%info, $significant_param, $DEFCON_UNDEFINED); } if $flags +& $SIG_ELEM_NATIVE_INT_VALUE { nqp::bindpos_i(%info, $significant_param, $TYPE_NATIVE_INT + nqp::atpos_i(%info, $significant_param)); } elsif $flags +& $SIG_ELEM_NATIVE_UINT_VALUE { nqp::bindpos_i(%info, $significant_param, $TYPE_NATIVE_UINT + nqp::atpos_i(%info, $significant_param)); } elsif $flags +& $SIG_ELEM_NATIVE_NUM_VALUE { nqp::bindpos_i(%info, $significant_param, $TYPE_NATIVE_NUM + nqp::atpos_i(%info, $significant_param)); } elsif $flags +& $SIG_ELEM_NATIVE_STR_VALUE { nqp::bindpos_i(%info, $significant_param, $TYPE_NATIVE_STR + nqp::atpos_i(%info, $significant_param)); } # Keep track of coercion types; they'll need an extra entry # in the things we sort. if $param.coercive { nqp::push(@coerce_type_idxs, $significant_param); my $param_type := nqp::getattr($param, Parameter, '$!type'); my $coercion_type := $param_type.HOW.wrappee($param_type, :coercion); nqp::push(@coerce_type_objs, $coercion_type.HOW.target_type($coercion_type)); } ++$significant_param; } %info := $min_arity; %info := $max_arity; %info := $num_types; # Add it to graph node, and initialize list of edges. nqp::push(@graph, nqp::hash( 'info', %info, 'edges', [], 'edges_in', 0, 'edges_out', 0 )); # If there were any coercion types, then we also need to create # a candidate entry for the specific types. if @coerce_type_idxs { my %c_info := nqp::clone(%info); %c_info := nqp::clone(%c_info); my int $i := 0; while $i < nqp::elems(@coerce_type_idxs) { %c_info[@coerce_type_idxs[$i]] := @coerce_type_objs[$i]; ++$i; } nqp::push(@graph, nqp::hash( 'info', %c_info, 'edges', [], 'edges_in', 0, 'edges_out', 0 )); } } # Now analyze type narrowness of the candidates relative to each # other and create the edges. my int $j; my int $n := nqp::elems(@graph); my int $i := -1; while ++$i < $n { $j := -1; while ++$j < $n { unless $i == $j { if is_narrower(@graph[$i], @graph[$j]) { @graph[$i][@graph[$i]] := @graph[$j]; ++@graph[$i]; ++@graph[$j]; } } } } # Perform the topological sort. my int $candidates_to_sort := nqp::elems(@graph); my @result; while $candidates_to_sort > 0 { my int $rem_results := nqp::elems(@result); # Find any nodes that have no incoming edges and add them to # results. $i := -1; while ++$i < $n { if @graph[$i] == 0 { # Add to results. nqp::push(@result, @graph[$i]); --$candidates_to_sort; @graph[$i] := $EDGE_REMOVAL_TODO; } } if $rem_results == nqp::elems(@result) { nqp::die("Circularity detected in multi sub types" ~ ($self.name ?? " for &" ~ $self.name !! '')); } # Now we need to decrement edges in counts for things that had # edges from candidates we added here. $i := -1; while ++$i < $n { if @graph[$i] == $EDGE_REMOVAL_TODO { $j := -1; while ++$j < @graph[$i] { --@graph[$i][$j]; } @graph[$i] := $EDGE_REMOVED; } } # This is end of a tied group, so leave a gap. nqp::push(@result, Mu); } # Add final null sentinel. nqp::push(@result, Mu); @result })); Routine.HOW.add_method(Routine, 'sort_dispatchees', nqp::getstaticcode(sub ($self) { my $dcself := nqp::decont($self); unless nqp::isnull(nqp::getattr($dcself, Routine, '@!dispatch_order')) { nqp::bindattr($dcself, Routine, '@!dispatch_order', $self.'!sort_dispatchees_internal'()); } })); Routine.HOW.add_method(Routine, 'find_best_dispatchee', nqp::getstaticcode(sub ($self, $capture, int $many = 0) { my int $DEFCON_DEFINED := 1; my int $DEFCON_UNDEFINED := 2; my int $DEFCON_MASK := $DEFCON_DEFINED +| $DEFCON_UNDEFINED; my int $TYPE_NATIVE_INT := 4; my int $TYPE_NATIVE_NUM := 8; my int $TYPE_NATIVE_STR := 16; my int $TYPE_NATIVE_UINT := 32; my int $TYPE_NATIVE_MASK := $TYPE_NATIVE_INT +| $TYPE_NATIVE_UINT +| $TYPE_NATIVE_NUM +| $TYPE_NATIVE_STR; my int $BIND_VAL_OBJ := 0; my int $BIND_VAL_INT := 1; my int $BIND_VAL_UINT := 10; my int $BIND_VAL_NUM := 2; my int $BIND_VAL_STR := 3; # Count arguments. my int $num_args := nqp::captureposelems($capture); # Get list and number of candidates, triggering a sort if there are none. my $dcself := nqp::decont($self); my @candidates := nqp::getattr($dcself, Routine, '@!dispatch_order'); if nqp::isnull(@candidates) { nqp::scwbdisable(); @candidates := $dcself.'!sort_dispatchees_internal'(); nqp::bindattr($dcself, Routine, '@!dispatch_order', @candidates); nqp::scwbenable(); } # Iterate over the candidates and collect best ones; terminate # when we see two type objects (indicating end). my int $cur_idx := 0; my $cur_candidate; my int $type_check_count; my int $type_mismatch; my int $rwness_mismatch; my int $i; my int $pure_type_result := 1; my $many_res := $many ?? [] !! Mu; my @possibles; my int $done := 0; my int $done_bind_check := 0; my $Positional := nqp::gethllsym('Raku', 'MD_Pos'); until $done { $cur_candidate := nqp::atpos(@candidates, $cur_idx); if nqp::isconcrete($cur_candidate) { # Check if it's admissible by arity. unless $num_args < nqp::atkey($cur_candidate, 'min_arity') || $num_args > nqp::atkey($cur_candidate, 'max_arity') { # Arity OK; now check if it's admissible by type. $type_check_count := nqp::atkey($cur_candidate, 'num_types') > $num_args ?? $num_args !! nqp::atkey($cur_candidate, 'num_types'); $type_mismatch := 0; $rwness_mismatch := 0; $i := -1; while ++$i < $type_check_count && !$type_mismatch && !$rwness_mismatch { my $type_obj := nqp::atpos(nqp::atkey($cur_candidate, 'types'), $i); my int $type_flags := nqp::atpos_i(nqp::atkey($cur_candidate, 'type_flags'), $i); my int $got_prim := nqp::captureposprimspec($capture, $i); my int $rwness := nqp::atpos_i(nqp::atkey($cur_candidate, 'rwness'), $i); if $rwness && !nqp::isrwcont(nqp::captureposarg($capture, $i)) { # If we need a container but don't have one it clearly can't work. $rwness_mismatch := 1; } elsif $type_flags +& $TYPE_NATIVE_MASK { # Looking for a natively typed value. Did we get one? if $got_prim == $BIND_VAL_OBJ { # Object, but could be a native container. If not, mismatch. my $contish := nqp::captureposarg($capture, $i); unless (($type_flags +& $TYPE_NATIVE_INT) && nqp::iscont_i($contish)) || (($type_flags +& $TYPE_NATIVE_UINT) && nqp::iscont_u($contish)) || (($type_flags +& $TYPE_NATIVE_NUM) && nqp::iscont_n($contish)) || (($type_flags +& $TYPE_NATIVE_STR) && nqp::iscont_s($contish)) { $type_mismatch := 1; } } elsif (($type_flags +& $TYPE_NATIVE_INT) && $got_prim != $BIND_VAL_INT) || (($type_flags +& $TYPE_NATIVE_UINT) && $got_prim != $BIND_VAL_UINT) || (($type_flags +& $TYPE_NATIVE_NUM) && $got_prim != $BIND_VAL_NUM) || (($type_flags +& $TYPE_NATIVE_STR) && $got_prim != $BIND_VAL_STR) { # Mismatch. $type_mismatch := 1; } } else { my $param; my int $primish := 0; if $got_prim == $BIND_VAL_OBJ { $param := nqp::captureposarg($capture, $i); if nqp::iscont_i($param) { $param := Int; $primish := 1; } elsif nqp::iscont_u($param) { $param := Int; $primish := 1; } elsif nqp::iscont_n($param) { $param := Num; $primish := 1; } elsif nqp::iscont_s($param) { $param := Str; $primish := 1; } else { $param := nqp::hllizefor($param, 'Raku') } } else { $param := $got_prim == $BIND_VAL_INT ?? Int !! $got_prim == $BIND_VAL_UINT ?? Int !! $got_prim == $BIND_VAL_NUM ?? Num !! Str; $primish := 1; } if nqp::eqaddr($type_obj, Mu) || nqp::istype($param, $type_obj) { if $i == 0 && nqp::existskey($cur_candidate, 'exact_invocant') { unless $param.WHAT =:= $type_obj { $type_mismatch := 1; } } } else { if $type_obj =:= $Positional { my $PositionalBindFailover := nqp::gethllsym('Raku', 'MD_PBF'); unless nqp::istype($param, $PositionalBindFailover) { $type_mismatch := 1; } } else { $type_mismatch := 1; } } if !$type_mismatch && $type_flags +& $DEFCON_MASK { my int $defined := $primish || nqp::isconcrete($param); my int $desired := $type_flags +& $DEFCON_MASK; if ($defined && $desired == $DEFCON_UNDEFINED) || (!$defined && $desired == $DEFCON_DEFINED) { $type_mismatch := 1; } } } } unless $type_mismatch || $rwness_mismatch { # It's an admissible candidate; add to list. nqp::push(@possibles, $cur_candidate); } } ++$cur_idx; } else { # We've hit the end of a tied group now. If any of them have a # bindability check requirement, we'll do any of those now. if nqp::elems(@possibles) { my $new_possibles; my %info; $i := -1; while ++$i < nqp::elems(@possibles) { %info := nqp::atpos(@possibles, $i); # First, if there's a required named parameter and it was # not passed, we can very quickly eliminate this candidate # without doing a full bindability check. if nqp::existskey(%info, 'req_named') && !nqp::captureexistsnamed($capture, nqp::atkey(%info, 'req_named')) { # Required named arg not passed, so we eliminate # it right here. Flag that we've built a list of # new possibles, and that this was not a pure # type-based result that we can cache. $new_possibles := [] unless nqp::islist($new_possibles); } # Otherwise, may need full bind check. elsif nqp::existskey(%info, 'bind_check') { my $sub := nqp::atkey(%info, 'sub'); my $cs := nqp::getattr($sub, Code, '@!compstuff'); unless nqp::isnull($cs) { # We need to do the tie-break on something not yet compiled. # Get it compiled. my $ctf := $cs[1]; $ctf() if $ctf; } # Since we had to do a bindability check, this is not # a result we can cache on nominal type. $pure_type_result := 0 if nqp::existskey(%info, 'constrainty'); # If we haven't got a possibles storage space, allocate it now. $new_possibles := [] unless nqp::islist($new_possibles); my $sig := nqp::getattr($sub, Code, '$!signature'); unless $done_bind_check { # Need a copy of the capture, as we may later do a # multi-dispatch when evaluating the constraint. $capture := nqp::clone($capture); $done_bind_check := 1; } if nqp::p6isbindable($sig, $capture) { nqp::push($new_possibles, nqp::atpos(@possibles, $i)); unless $many { # Terminate the loop. $i := nqp::elems(@possibles); } } } # Otherwise, it's just nominal; accept it. elsif $new_possibles { nqp::push($new_possibles, nqp::atpos(@possibles, $i)); } else { $new_possibles := [nqp::atpos(@possibles, $i)]; } } # If we have an updated list of possibles, use this # new one from here on in. if nqp::islist($new_possibles) { @possibles := $new_possibles; } } # Now we have eliminated any that fail the bindability check. # See if we need to push it onto the many list and continue. # Otherwise, we have the result we were looking for. if $many { while @possibles { nqp::push($many_res, nqp::atkey(nqp::shift(@possibles), 'sub')) } ++$cur_idx; unless nqp::isconcrete(nqp::atpos(@candidates, $cur_idx)) { $done := 1; } } elsif @possibles { $done := 1; } else { # Keep looping and looking, unless we really hit the end. ++$cur_idx; unless nqp::isconcrete(nqp::atpos(@candidates, $cur_idx)) { $done := 1; } } } } # If we were looking for many candidates, we're done now. if $many { return $many_res; } # If we still have multiple options and we want one, then check default # trait and then, failing that, if we got an exact arity match on required # parameters (which will beat matches on optional parameters). if nqp::elems(@possibles) > 1 { # Locate any default candidates; if we find multiple defaults, this is # no help, so we'll not bother collecting just which ones are good. my $default_cand; for @possibles { my $sub := nqp::atkey($_, 'sub'); if nqp::can($sub, 'default') && $sub.default { if nqp::isconcrete($default_cand) { $default_cand := Mu; } else { $default_cand := $_; } } } if nqp::isconcrete($default_cand) { nqp::pop(@possibles) while @possibles; @possibles[0] := $default_cand; } # Failing that, look for exact arity match. if nqp::elems(@possibles) > 1 { my $exact_arity; for @possibles { if nqp::atkey($_, 'min_arity') == $num_args && nqp::atkey($_, 'max_arity') == $num_args { if nqp::isconcrete($exact_arity) { $exact_arity := NQPMu; last; } else { $exact_arity := $_; } } } if nqp::isconcrete($exact_arity) { nqp::pop(@possibles) while @possibles; @possibles[0] := $exact_arity; } } } # If we're at a single candidate here, and we also know there's no # type constraints that follow, we can cache the result. sub add_to_cache($entry) { } if nqp::elems(@possibles) == 1 && $pure_type_result { add_to_cache(nqp::atkey(nqp::atpos(@possibles, 0), 'sub')); } # Perhaps we found nothing but have junctional arguments? my $junctional_res; if nqp::elems(@possibles) == 0 { my int $has_junc_args := 0; $i := -1; while ++$i < $num_args { if !nqp::captureposprimspec($capture, $i) { my $arg := nqp::captureposarg($capture, $i); if nqp::istype($arg, Junction) && nqp::isconcrete($arg) { $has_junc_args := 1; } } } if $has_junc_args { $junctional_res := -> *@pos, *%named { Junction.AUTOTHREAD($self, |@pos, |%named) } add_to_cache($junctional_res); } } # Need a unique candidate. if nqp::elems(@possibles) == 1 { nqp::atkey(nqp::atpos(@possibles, 0), 'sub') } elsif nqp::isconcrete($junctional_res) { $junctional_res; } elsif nqp::elems(@possibles) == 0 { Perl6::Metamodel::Configuration.throw_or_die( 'X::Multi::NoMatch', "Cannot call " ~ $self.name() ~ "; no signatures match", :dispatcher($self), :capture($self.'!p6capture'($capture))); } else { my @ambiguous; for @possibles { nqp::push(@ambiguous, $_); } Perl6::Metamodel::Configuration.throw_or_die( 'X::Multi::Ambiguous', "Ambiguous call to " ~ $self.name(), :dispatcher($self), :@ambiguous, :capture($self.'!p6capture'($capture))); } })); Routine.HOW.add_method(Routine, '!p6capture', nqp::getstaticcode(sub ($self, $capture) { my $raku-capture := nqp::create(Capture); nqp::bindattr($raku-capture, Capture, '@!list', nqp::dispatch('boot-syscall', 'capture-pos-args', $capture)); nqp::bindattr($raku-capture, Capture, '%!hash', nqp::dispatch('boot-syscall', 'capture-named-args', $capture)); $raku-capture })); Routine.HOW.add_method(Routine, 'analyze_dispatch', nqp::getstaticcode(sub ($self, @args, @flags) { # Compile time dispatch result. my $MD_CT_NOT_SURE := 0; # Needs a runtime dispatch. my $MD_CT_DECIDED := 1; # Worked it out; see result. my $MD_CT_NO_WAY := -1; # Proved it'd never manage to dispatch. # Other constants we need. my int $DEFCON_DEFINED := 1; my int $DEFCON_UNDEFINED := 2; my int $DEFCON_MASK := $DEFCON_DEFINED +| $DEFCON_UNDEFINED; my int $TYPE_NATIVE_INT := 4; my int $TYPE_NATIVE_NUM := 8; my int $TYPE_NATIVE_STR := 16; my int $TYPE_NATIVE_UINT := 32; my int $TYPE_NATIVE_MASK := $TYPE_NATIVE_INT +| $TYPE_NATIVE_UINT +| $TYPE_NATIVE_NUM +| $TYPE_NATIVE_STR; my int $BIND_VAL_OBJ := 0; my int $BIND_VAL_INT := 1; my int $BIND_VAL_UINT := 10; my int $BIND_VAL_NUM := 2; my int $BIND_VAL_STR := 3; my int $ARG_IS_LITERAL := 32; # Count arguments. my int $num_args := nqp::elems(@args); # Get list and number of candidates, triggering a sort if there are none. my $dcself := nqp::decont($self); my @candidates := nqp::getattr($dcself, Routine, '@!dispatch_order'); if nqp::isnull(@candidates) { nqp::scwbdisable(); @candidates := $dcself.'!sort_dispatchees_internal'(); nqp::bindattr($dcself, Routine, '@!dispatch_order', @candidates); nqp::scwbenable(); } # Look through the candidates. If we see anything that needs a bind # check or a definedness check, we can't decide it at compile time, # so bail out immediately. my int $all_native := 1; my int $cur_idx := 0; my int $seen_all := 0; my int $arity_possible := 0; my int $type_possible := 0; my int $used_defcon; my int $type_mismatch; my int $type_check_count; my int $type_match_possible; my int $i; my $cur_candidate; my $cur_result; while 1 { $cur_candidate := nqp::atpos(@candidates, $cur_idx); $used_defcon := 0; # Did we reach the end of a tied group? If so, note we can only # consider the narrowest group, *unless* they are all natively # typed candidates in which case we can look a bit further. # We also exit if we found something. unless nqp::isconcrete($cur_candidate) { ++$cur_idx; if nqp::isconcrete(nqp::atpos(@candidates, $cur_idx)) && $all_native && !nqp::isconcrete($cur_result) { next; } else { $seen_all := !nqp::isconcrete(nqp::atpos(@candidates, $cur_idx)); last; } } # Check if it's admissible by arity. if $num_args < nqp::atkey($cur_candidate, 'min_arity') || $num_args > nqp::atkey($cur_candidate, 'max_arity') { ++$cur_idx; next; } # If we got this far, something at least matched on arity. $arity_possible := 1; # Check if it's admissible by type. $type_check_count := nqp::atkey($cur_candidate, 'num_types') > $num_args ?? $num_args !! nqp::atkey($cur_candidate, 'num_types'); $type_mismatch := 0; $type_match_possible := 1; $i := -1; while ++$i < $type_check_count { my int $type_flags := nqp::atpos_i(nqp::atkey($cur_candidate, 'type_flags'), $i); my int $got_prim := nqp::atpos(@flags, $i) +& 0xF; if $type_flags +& $TYPE_NATIVE_MASK { # Looking for a natively typed value. Did we get one? if $got_prim == $BIND_VAL_OBJ { # Object; won't do. $type_mismatch := 1; last; } # Yes, but does it have the right type? Also look at rw-ness for literals. my int $literal := nqp::atpos(@flags, $i) +& $ARG_IS_LITERAL; if (($type_flags +& $TYPE_NATIVE_INT) && $got_prim != $BIND_VAL_INT) || (($type_flags +& $TYPE_NATIVE_UINT) && $got_prim != $BIND_VAL_UINT) || (($type_flags +& $TYPE_NATIVE_NUM) && $got_prim != $BIND_VAL_NUM) || (($type_flags +& $TYPE_NATIVE_STR) && $got_prim != $BIND_VAL_STR) || ($literal && nqp::atpos_i(nqp::atkey($cur_candidate, 'rwness'), $i)) { # Mismatch. $type_mismatch := 1; $type_match_possible := 0; last; } } else { my $type_obj := nqp::atpos(nqp::atkey($cur_candidate, 'types'), $i); # Work out parameter. my $param := $got_prim == $BIND_VAL_OBJ ?? nqp::atpos(@args, $i) !! $got_prim == $BIND_VAL_INT ?? Int !! $got_prim == $BIND_VAL_UINT ?? Int !! $got_prim == $BIND_VAL_NUM ?? Num !! Str; # If we're here, it's a non-native. $all_native := 0; # A literal won't work with rw parameter. my int $literal := nqp::atpos(@flags, $i) +& $ARG_IS_LITERAL; if $literal && nqp::atpos_i(nqp::atkey($cur_candidate, 'rwness'), $i) { $type_mismatch := 1; $type_match_possible := 0; last; } # Check type. If that doesn't rule it out, then check if it's # got definedness constraints. If it does, note that; if we # match but depend on definedness constraints we can't do # any more. if !nqp::eqaddr($type_obj, Mu) && !nqp::istype($param, $type_obj) { $type_mismatch := 1; # We didn't match, but that doesn't mean we cannot at # runtime (e.g. the most we know about the type could # be that it's Any, but at runtime that feasibly could # be Int). In some cases we never could though (Str # passed to an Int parameter). if !nqp::istype($type_obj, $param) { $type_match_possible := 0; last; } } elsif $type_flags +& $DEFCON_MASK { $used_defcon := 1; } } } if $type_match_possible { $type_possible := 1; } if $type_mismatch { ++$cur_idx; next; } if ($used_defcon) { return [$MD_CT_NOT_SURE, NQPMu]; } # If it's possible but needs a bind check, we're not going to be # able to decide it. if nqp::existskey($cur_candidate, 'bind_check') { return [$MD_CT_NOT_SURE, NQPMu]; } # If we get here, it's the result. Well, unless we already had one, # in which case we're in bother 'cus we don't know how to disambiguate # at compile time. if nqp::isconcrete($cur_result) { return [$MD_CT_NOT_SURE, NQPMu]; } else { $cur_result := nqp::atkey($cur_candidate, 'sub'); ++$cur_idx; } } # If we saw all the candidates, and got no result, and the arity never # matched or when it did there was no way any candidates could get # passed matching types, then we know it would never work. if $seen_all && (!$arity_possible || !$type_possible) && !nqp::isconcrete($cur_result) { # Ensure no junctional args before we flag the failure. for @args { if nqp::istype($_, Junction) { return [$MD_CT_NOT_SURE, NQPMu]; } } return [$MD_CT_NO_WAY, NQPMu]; } # If we got a result, return it. if nqp::isconcrete($cur_result) { return [$MD_CT_DECIDED, $cur_result]; } # Otherwise, dunno...we'll have to find out at runtime. return [$MD_CT_NOT_SURE, NQPMu]; })); Routine.HOW.add_method(Routine, 'set_flag', nqp::getstaticcode(sub ($self, $bit) { my $dcself := nqp::decont($self); nqp::bindattr_i($dcself, Routine, '$!flags', nqp::bitor_i(nqp::getattr_i($dcself, Routine, '$!flags'), $bit) ); $dcself })); Routine.HOW.add_method(Routine, 'get_flag', nqp::getstaticcode(sub ($self, $bit) { my $dcself := nqp::decont($self); nqp::hllboolfor( nqp::bitand_i(nqp::getattr_i($dcself, Routine, '$!flags'), $bit), "Raku" ); })); Routine.HOW.add_method(Routine, 'set_rw', nqp::getstaticcode(sub ($self) { $self.set_flag(0x01) })); Routine.HOW.add_method(Routine, 'rw', nqp::getstaticcode(sub ($self) { $self.get_flag(0x01) })); Routine.HOW.add_method(Routine, 'set_yada', nqp::getstaticcode(sub ($self) { $self.set_flag(0x02) })); Routine.HOW.add_method(Routine, 'yada', nqp::getstaticcode(sub ($self) { $self.get_flag(0x02) })); Routine.HOW.add_method(Routine, 'set_inline_info', nqp::getstaticcode(sub ($self, $info) { my $dcself := nqp::decont($self); nqp::bindattr($dcself, Routine, '$!inline_info', $info); $dcself })); Routine.HOW.add_method(Routine, 'inline_info', nqp::getstaticcode(sub ($self) { my $dcself := nqp::decont($self); nqp::getattr($dcself, Routine, '$!inline_info') })); Routine.HOW.add_method(Routine, 'set_onlystar', nqp::getstaticcode(sub ($self) { $self.set_flag(0x04) })); Routine.HOW.add_method(Routine, 'onlystar', nqp::getstaticcode(sub ($self) { $self.get_flag(0x04) })); Routine.HOW.compose_repr(Routine); # class Sub is Routine { Sub.HOW.add_parent(Sub, Routine); Sub.HOW.compose_repr(Sub); # class Operator is Sub { # has Mu $!properties; Operator.HOW.add_parent(Operator, Sub); Operator.HOW.add_attribute(Operator, Attribute.new(:name<$!properties>, :type(Mu), :package(Operator))); Operator.HOW.compose_repr(Operator); # class Method is Routine { Method.HOW.add_parent(Method, Routine); Method.HOW.compose_repr(Method); # class Submethod is Routine { Submethod.HOW.add_parent(Submethod, Routine); Submethod.HOW.compose_repr(Submethod); # Capture store for SET_CAPS. my class RegexCaptures { # An integer array of positional capture counts. has @!pos-capture-counts; # A string array of named capture names and a matching integer array of # capture counts. has @!named-capture-names; has @!named-capture-counts; # Form this data structure from a capnames hash. method from-capnames(%capnames) { nqp::create(self).'!from-capnames'(%capnames) } method !from-capnames(%capnames) { # Initialize. @!pos-capture-counts := nqp::list_i(); @!named-capture-names := nqp::list_s(); @!named-capture-counts := nqp::list_i(); # Go over the captures and build up the data structure. for %capnames { my $name := nqp::iterkey_s($_); if $name ne '' { my $count := nqp::iterval($_); if nqp::ord($name) != 36 && nqp::ord($name) < 58 { nqp::bindpos_i(@!pos-capture-counts, +$name, $count); } else { nqp::push_s(@!named-capture-names, $name); nqp::push_i(@!named-capture-counts, $count); } } } self } # Are there any captures? method has-captures() { nqp::elems(@!named-capture-counts) || nqp::elems(@!pos-capture-counts) } ## Raku Match object building ## (for use in standard Raku regexes) # Build a list of positional captures, or return a shared empty list if # there are none. This only populates the slots which need an array. my @EMPTY-LIST; my %EMPTY-HASH; method prepare-raku-list() { my int $n := nqp::elems(@!pos-capture-counts); if $n > 0 { my $result := nqp::list(); my int $i := -1; while ++$i < $n { nqp::bindpos($result, $i, nqp::create(Array)) if nqp::atpos_i(@!pos-capture-counts, $i) >= 2; } $result } else { @EMPTY-LIST } } # Build a hash of named captures, or return a shared empty hash if there # are none. This only populates the slots that need an array. method prepare-raku-hash() { my int $n := nqp::elems(@!named-capture-counts); if $n > 0 { my $result := nqp::hash(); my int $i := -1; while ++$i < $n { if nqp::atpos_i(@!named-capture-counts, $i) >= 2 { nqp::bindkey($result, nqp::atpos_s(@!named-capture-names, $i), nqp::create(Array)); } } $result } else { %EMPTY-HASH } } ## NQP Match object building ## (for use when we override stuff from the Rakudo grammar) # Build a list of positional captures, or return a shared empty list if # there are none. This only populates the slots which need an array. method prepare-list() { my int $n := nqp::elems(@!pos-capture-counts); if $n > 0 { my $result := nqp::list(); my int $i := -1; while ++$i < $n { nqp::bindpos($result, $i, nqp::list()) if nqp::atpos_i(@!pos-capture-counts, $i) >= 2; } $result } else { @EMPTY-LIST } } # Build a hash of named camptures, or return a shared empty hash if there # are none. This only poplates the slots that need an array. method prepare-hash() { my int $n := nqp::elems(@!named-capture-counts); if $n > 0 { my $result := nqp::hash(); my int $i := -1; while ++$i < $n { if nqp::atpos_i(@!named-capture-counts, $i) >= 2 { nqp::bindkey($result, nqp::atpos_s(@!named-capture-names, $i), nqp::list()); } } $result } else { %EMPTY-HASH } } # Get the name of the only capture, if there is only one. method onlyname() { '' } } # class Regex is Method { # has $!caps; # has Mu $!nfa; # has @!alt_nfas; # has str $!source; # has $!topic; # has $!slash; Regex.HOW.add_parent(Regex, Method); Regex.HOW.add_attribute(Regex, scalar_attr('$!caps', Mu, Regex)); Regex.HOW.add_attribute(Regex, scalar_attr('$!nfa', Mu, Regex)); Regex.HOW.add_attribute(Regex, scalar_attr('%!alt_nfas', Hash, Regex)); Regex.HOW.add_attribute(Regex, scalar_attr('$!source', str, Regex)); Regex.HOW.add_attribute(Regex, scalar_attr('$!topic', Mu, Regex)); Regex.HOW.add_attribute(Regex, scalar_attr('$!slash', Mu, Regex)); Regex.HOW.add_method(Regex, 'SET_CAPS', nqp::getstaticcode(sub ($self, $capnames) { nqp::bindattr(nqp::decont($self), Regex, '$!caps', RegexCaptures.from-capnames($capnames)) })); Regex.HOW.add_method(Regex, 'SET_NFA', nqp::getstaticcode(sub ($self, $nfa) { nqp::bindattr(nqp::decont($self), Regex, '$!nfa', $nfa) })); Regex.HOW.add_method(Regex, 'SET_ALT_NFA', nqp::getstaticcode(sub ($self, str $name, $nfa) { my %alts := nqp::getattr(nqp::decont($self), Regex, '%!alt_nfas'); unless %alts { %alts := nqp::hash(); nqp::bindattr(nqp::decont($self), Regex, '%!alt_nfas', %alts); } nqp::bindkey(%alts, $name, $nfa); })); Regex.HOW.add_method(Regex, 'CAPS', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Regex, '$!caps') })); Regex.HOW.add_method(Regex, 'NFA', nqp::getstaticcode(sub ($self) { nqp::getattr(nqp::decont($self), Regex, '$!nfa') })); Regex.HOW.add_method(Regex, 'ALT_NFA', nqp::getstaticcode(sub ($self, str $name) { nqp::atkey( nqp::getattr(nqp::decont($self), Regex, '%!alt_nfas'), $name) })); Regex.HOW.add_method(Regex, 'ALT_NFAS', nqp::getstaticcode(sub ($self) { my $store := nqp::decont(nqp::getattr(nqp::decont($self), Regex, '%!alt_nfas')); if nqp::istype($store, Hash) { nqp::hash(); } else { $store } })); Regex.HOW.compose_repr(Regex); # class Str is Cool { # has str $!value is box_target; Str.HOW.add_parent(Str, Cool); Str.HOW.add_attribute(Str, BOOTSTRAPATTR.new(:name<$!value>, :type(str), :box_target(1), :package(Str))); Str.HOW.set_boolification_mode(Str, 3); Str.HOW.publish_boolification_spec(Str); Str.HOW.compose_repr(Str); # class Int is Cool { # has bigint $!value is box_target; Int.HOW.add_parent(Int, Cool); Int.HOW.add_attribute(Int, BOOTSTRAPATTR.new(:name<$!value>, :type(bigint), :box_target(1), :package(Int))); Int.HOW.set_boolification_mode(Int, 6); Int.HOW.publish_boolification_spec(Int); Int.HOW.compose_repr(Int); # class Num is Cool { # has num $!value is box_target; Num.HOW.add_parent(Num, Cool); Num.HOW.add_attribute(Num, BOOTSTRAPATTR.new(:name<$!value>, :type(num), :box_target(1), :package(Num))); Num.HOW.set_boolification_mode(Num, 2); Num.HOW.publish_boolification_spec(Num); Num.HOW.compose_repr(Num); # class Nil is Cool { Nil.HOW.compose_repr(Nil); # class List is Cool { # has Mu $!reified; # has Mu $!todo; List.HOW.add_parent(List, Cool); List.HOW.add_attribute(List, storage_attr('$!reified', Mu, List, Mu)); List.HOW.add_attribute(List, storage_attr('$!todo', Mu, List, Mu)); List.HOW.compose_repr(List); # class Slip is List { Slip.HOW.add_parent(Slip, List); Slip.HOW.compose_repr(Slip); # class Array is List { # has Mu $!descriptor; Array.HOW.add_parent(Array, List); Array.HOW.add_attribute(Array, storage_attr('$!descriptor', Mu, Array, Scalar.HOW.cache_get(Scalar, 'default_cont_spec'))); Array.HOW.compose_repr(Array); # class array does Iterable does Positional { array.HOW.compose_repr(array); # class IterationBuffer { IterationBuffer.HOW.compose_repr(IterationBuffer); # my class Map is Cool { # has Mu $!storage; Map.HOW.add_parent(Map, Cool); Map.HOW.add_attribute(Map, storage_attr('$!storage', Mu, Map, nqp::hash(), :associative_delegate)); Map.HOW.compose_repr(Map); nqp::settypehllrole(Map, 5); # my class Hash is Map { # has Mu $!descriptor; Hash.HOW.add_parent(Hash, Map); Hash.HOW.add_attribute(Hash, storage_attr('$!descriptor', Mu, Hash, Scalar.HOW.cache_get(Scalar, 'default_cont_spec'))); Hash.HOW.compose_repr(Hash); nqp::settypehllrole(Hash, 5); # class Capture is Any { # has @!list; # has %!hash; Capture.HOW.add_parent(Capture, Any); Capture.HOW.add_attribute(Capture, scalar_attr('@!list', List, Capture, :!auto_viv_container)); Capture.HOW.add_attribute(Capture, scalar_attr('%!hash', Hash, Capture, :!auto_viv_container)); Capture.HOW.compose_repr(Capture); # class Junction is Mu { # has Mu $!eigenstates; # has str $!type; Junction.HOW.add_parent(Junction, Mu); Junction.HOW.add_attribute(Junction, scalar_attr('$!eigenstates', Mu, Junction)); Junction.HOW.add_attribute(Junction, scalar_attr('$!type', str, Junction)); Junction.HOW.add_attribute(Junction, Attribute.new(:name<$!WHICH>, :type(ValueObjAt), :package(Junction))); Junction.HOW.compose_repr(Junction); # class Bool is Int { # has str $!key; # has int $!value; Bool.HOW.set_base_type(Bool, Int); Bool.HOW.add_attribute(Bool, Attribute.new(:name<$!key>, :type(str), :package(Bool))); Bool.HOW.add_attribute(Bool, Attribute.new(:name<$!value>, :type(int), :package(Bool))); Bool.HOW.set_boolification_mode(Bool, 1); Bool.HOW.publish_boolification_spec(Bool); Bool.HOW.compose_repr(Bool); Bool.HOW.add_method(Bool, 'key', nqp::getstaticcode(sub ($self) { nqp::getattr_s(nqp::decont($self), Bool, '$!key'); })); Bool.HOW.add_method(Bool, 'value', nqp::getstaticcode(sub ($self) { nqp::getattr_i(nqp::decont($self), Bool, '$!value'); })); # class ObjAt is Any { # has str $!value; ObjAt.HOW.add_parent(ObjAt, Any); ObjAt.HOW.add_attribute(ObjAt, BOOTSTRAPATTR.new(:name<$!value>, :type(str), :box_target(1), :package(ObjAt))); ObjAt.HOW.compose_repr(ObjAt); # class ValueObjAt is ObjAt { ValueObjAt.HOW.add_parent(ValueObjAt, ObjAt); ValueObjAt.HOW.compose_repr(ValueObjAt); # class ForeignCode { # has Mu $!do; # Code object we delegate to ForeignCode.HOW.add_parent(ForeignCode, Any); ForeignCode.HOW.add_attribute(ForeignCode, Attribute.new(:name<$!do>, :type(Code), :package(ForeignCode))); ForeignCode.HOW.compose_repr(ForeignCode); # class Version { # has $!parts; # has int $!plus; # has str $!string; Version.HOW.add_parent(Version, Any); Version.HOW.add_attribute(Version, Attribute.new(:name('$!parts'), :type(Mu), :package(Version))); Version.HOW.add_attribute(Version, Attribute.new(:name('$!plus'), :type(int), :package(Version))); Version.HOW.add_attribute(Version, Attribute.new(:name('$!string'), :type(str), :package(Version))); Version.HOW.compose_repr(Version); # Set up Stash type, which is really just a hash with a name. # class Stash is Hash { # has str $!longname; # has $!lock; Stash.HOW.add_parent(Stash, Hash); Stash.HOW.add_attribute(Stash, Attribute.new(:name<$!longname>, :type(str), :package(Stash))); Stash.HOW.add_attribute(Stash, Attribute.new(:name<$!lock>, :type(Any), :package(Stash))); Stash.HOW.compose_repr(Stash); # Configure the stash type. Perl6::Metamodel::Configuration.set_stash_type(Stash, Map); # Give everything we've set up so far a Stash. Perl6::Metamodel::ClassHOW.add_stash(Mu); Perl6::Metamodel::ClassHOW.add_stash(Any); Perl6::Metamodel::ClassHOW.add_stash(Nil); Perl6::Metamodel::ClassHOW.add_stash(Cool); Perl6::Metamodel::ClassHOW.add_stash(Attribute); Perl6::Metamodel::ClassHOW.add_stash(Scalar); Perl6::Metamodel::ClassHOW.add_stash(ScalarVAR); Perl6::Metamodel::ClassHOW.add_stash(Proxy); Perl6::Metamodel::ClassHOW.add_stash(Signature); Perl6::Metamodel::ClassHOW.add_stash(Parameter); Perl6::Metamodel::ClassHOW.add_stash(Code); Perl6::Metamodel::ClassHOW.add_stash(Block); Perl6::Metamodel::ClassHOW.add_stash(Routine); Perl6::Metamodel::ClassHOW.add_stash(Sub); Perl6::Metamodel::ClassHOW.add_stash(Operator); Perl6::Metamodel::ClassHOW.add_stash(Method); Perl6::Metamodel::ClassHOW.add_stash(Submethod); Perl6::Metamodel::ClassHOW.add_stash(Regex); Perl6::Metamodel::ClassHOW.add_stash(Str); Perl6::Metamodel::ClassHOW.add_stash(Int); Perl6::Metamodel::ClassHOW.add_stash(Num); Perl6::Metamodel::NativeRefHOW.add_stash(IntLexRef); Perl6::Metamodel::NativeRefHOW.add_stash(UIntLexRef); Perl6::Metamodel::NativeRefHOW.add_stash(NumLexRef); Perl6::Metamodel::NativeRefHOW.add_stash(StrLexRef); Perl6::Metamodel::NativeRefHOW.add_stash(IntAttrRef); Perl6::Metamodel::NativeRefHOW.add_stash(UIntAttrRef); Perl6::Metamodel::NativeRefHOW.add_stash(NumAttrRef); Perl6::Metamodel::NativeRefHOW.add_stash(StrAttrRef); Perl6::Metamodel::NativeRefHOW.add_stash(IntPosRef); Perl6::Metamodel::NativeRefHOW.add_stash(UIntPosRef); Perl6::Metamodel::NativeRefHOW.add_stash(NumPosRef); Perl6::Metamodel::NativeRefHOW.add_stash(StrPosRef); Perl6::Metamodel::NativeRefHOW.add_stash(IntMultidimRef); Perl6::Metamodel::NativeRefHOW.add_stash(UIntMultidimRef); Perl6::Metamodel::NativeRefHOW.add_stash(NumMultidimRef); Perl6::Metamodel::NativeRefHOW.add_stash(StrMultidimRef); Perl6::Metamodel::ClassHOW.add_stash(List); Perl6::Metamodel::ClassHOW.add_stash(Slip); Perl6::Metamodel::ClassHOW.add_stash(Array); Perl6::Metamodel::ClassHOW.add_stash(array); Perl6::Metamodel::ClassHOW.add_stash(IterationBuffer); Perl6::Metamodel::ClassHOW.add_stash(Map); Perl6::Metamodel::ClassHOW.add_stash(Hash); Perl6::Metamodel::ClassHOW.add_stash(Capture); Perl6::Metamodel::EnumHOW.add_stash(Bool); Perl6::Metamodel::ClassHOW.add_stash(ObjAt); Perl6::Metamodel::ClassHOW.add_stash(ValueObjAt); Perl6::Metamodel::ClassHOW.add_stash(Stash); Perl6::Metamodel::ClassHOW.add_stash(Grammar); Perl6::Metamodel::ClassHOW.add_stash(Junction); Perl6::Metamodel::ClassHOW.add_stash(ForeignCode); Perl6::Metamodel::ClassHOW.add_stash(Version); # If we don't already have a PROCESS, set it up. my $PROCESS := nqp::gethllsym('Raku', 'PROCESS'); if nqp::isnull($PROCESS) { PROCESS.HOW.compose(PROCESS); Perl6::Metamodel::ModuleHOW.add_stash(PROCESS); $PROCESS := PROCESS; nqp::bindhllsym('Raku', 'PROCESS', $PROCESS); } # Bool::False and Bool::True. my $false := nqp::box_i(0, Bool); nqp::bindattr_s($false, Bool, '$!key', 'False'); nqp::bindattr_i($false, Bool, '$!value', 0); #nqp::bindattr($false, Int, '$!value', 0); Bool.HOW.add_enum_value(Bool, $false); (Bool.WHO) := $false; my $true := nqp::box_i(1, Bool); nqp::bindattr_s($true, Bool, '$!key', 'True'); nqp::bindattr_i($true, Bool, '$!value', 1); #nqp::bindattr($true, Int, '$!value', 1); Bool.HOW.add_enum_value(Bool, $true); (Bool.WHO) := $true; # Setup some regexy/grammary bits. Perl6::Metamodel::ClassHOW.add_stash(Grammar); Grammar.HOW.compose_repr(Grammar); # Export the metamodel bits to a Metamodel namespace so it's available # from user land. Perl6::Metamodel::PackageHOW.add_stash(Metamodel); for Perl6::Metamodel.WHO { (Metamodel.WHO){$_.key} := $_.value; } # Fill out EXPORT namespace. EXPORT::DEFAULT.WHO := Mu; EXPORT::DEFAULT.WHO := Any; EXPORT::DEFAULT.WHO := Cool; EXPORT::DEFAULT.WHO := Nil; EXPORT::DEFAULT.WHO := Attribute; EXPORT::DEFAULT.WHO := Signature; EXPORT::DEFAULT.WHO := Parameter; EXPORT::DEFAULT.WHO := Code; EXPORT::DEFAULT.WHO := Block; EXPORT::DEFAULT.WHO := Routine; EXPORT::DEFAULT.WHO := Sub; EXPORT::DEFAULT.WHO := Operator; EXPORT::DEFAULT.WHO := Method; EXPORT::DEFAULT.WHO := Submethod; EXPORT::DEFAULT.WHO := Regex; EXPORT::DEFAULT.WHO := Str; EXPORT::DEFAULT.WHO := Int; EXPORT::DEFAULT.WHO := Num; EXPORT::DEFAULT.WHO := List; EXPORT::DEFAULT.WHO := Slip; EXPORT::DEFAULT.WHO := Array; EXPORT::DEFAULT.WHO := array; EXPORT::DEFAULT.WHO := IterationBuffer; EXPORT::DEFAULT.WHO := Map; EXPORT::DEFAULT.WHO := Hash; EXPORT::DEFAULT.WHO := Capture; EXPORT::DEFAULT.WHO := ObjAt; EXPORT::DEFAULT.WHO := ValueObjAt; EXPORT::DEFAULT.WHO := Stash; EXPORT::DEFAULT.WHO := Scalar; EXPORT::DEFAULT.WHO := ScalarVAR; EXPORT::DEFAULT.WHO := IntLexRef; EXPORT::DEFAULT.WHO := UIntLexRef; EXPORT::DEFAULT.WHO := NumLexRef; EXPORT::DEFAULT.WHO := StrLexRef; EXPORT::DEFAULT.WHO := IntAttrRef; EXPORT::DEFAULT.WHO := UIntAttrRef; EXPORT::DEFAULT.WHO := NumAttrRef; EXPORT::DEFAULT.WHO := StrAttrRef; EXPORT::DEFAULT.WHO := IntPosRef; EXPORT::DEFAULT.WHO := UIntPosRef; EXPORT::DEFAULT.WHO := NumPosRef; EXPORT::DEFAULT.WHO := StrPosRef; EXPORT::DEFAULT.WHO := Proxy; EXPORT::DEFAULT.WHO := Grammar; EXPORT::DEFAULT.WHO := Junction; EXPORT::DEFAULT.WHO := $PROCESS; EXPORT::DEFAULT.WHO := Bool; EXPORT::DEFAULT.WHO := $false; EXPORT::DEFAULT.WHO := $true; EXPORT::DEFAULT.WHO := ContainerDescriptor; EXPORT::DEFAULT.WHO := Perl6::Metamodel::MethodDispatcher; EXPORT::DEFAULT.WHO := Perl6::Metamodel::MultiDispatcher; EXPORT::DEFAULT.WHO := Perl6::Metamodel::WrapDispatcher; EXPORT::DEFAULT.WHO := Metamodel; EXPORT::DEFAULT.WHO := ForeignCode; EXPORT::DEFAULT.WHO := Version; } EXPORT::DEFAULT.WHO := NQPMatchRole; EXPORT::DEFAULT.WHO := NQPdidMATCH; # HLL configuration: interop, boxing and exit handling. nqp::sethllconfig('Raku', nqp::hash( 'int_box', Int, 'num_box', Num, 'str_box', Str, 'null_value', Mu, 'true_value', (Bool.WHO), 'false_value', (Bool.WHO), 'foreign_type_int', Int, 'foreign_type_num', Num, 'foreign_type_str', Str, 'foreign_transform_array', -> $farray { my $list := nqp::create(List); nqp::bindattr($list, List, '$!reified', $farray); $list }, 'foreign_transform_hash', -> $hash { my $result := nqp::create(Hash); nqp::bindattr($result, Map, '$!storage', $hash); $result }, 'foreign_transform_code', -> $code { my $result := nqp::create(ForeignCode); nqp::bindattr($result, ForeignCode, '$!do', $code); $result }, 'exit_handler', -> $coderef, $resultish { unless nqp::p6inpre() { # when we get here, we assume the $!phasers attribute is concrete. # if it is *not* a hash, it is a lone LEAVE phaser, the most # commonly used phaser (in the core at least). my $phasers := nqp::getattr( nqp::getcodeobj($coderef),Block,'$!phasers' ); # slow path here if nqp::ishash($phasers) { my @exceptions; my @leaves := nqp::atkey($phasers, '!LEAVE-ORDER'); unless nqp::isnull(@leaves) { my $valid := !nqp::isnull($resultish) && nqp::isconcrete($resultish) && $resultish.defined; for @leaves -> $phaser { CATCH { nqp::push(@exceptions, $_) } # a KEEP/UNDO phaser if nqp::islist($phaser) { my $name := nqp::atpos($phaser,0); if ($name eq 'KEEP' && $valid) || ($name eq 'UNDO' && !$valid) { nqp::p6capturelexwhere( nqp::atpos($phaser,1).clone )(); } } # an ordinary LEAVE phaser else { nqp::p6capturelexwhere($phaser.clone)(); } } } my @posts := nqp::atkey($phasers, 'POST'); unless nqp::isnull(@posts) { my $value := nqp::ifnull($resultish,Mu); for @posts -> $phaser { nqp::p6capturelexwhere($phaser.clone)($value); } } if @exceptions { nqp::elems(@exceptions) > 1 ?? Perl6::Metamodel::Configuration.throw_or_die( 'X::PhaserExceptions', "Multiple exceptions were thrown by LEAVE/POST phasers", :exceptions(@exceptions) ) !! nqp::rethrow(@exceptions[0]); } } # only have a lone LEAVE phaser, so no frills needed # don't bother to CATCH, there can only be one exception else { nqp::p6capturelexwhere($phasers.clone)(); } } }, 'bind_error', -> $capture { # Get signature and lexpad. my $caller := nqp::getcodeobj(nqp::callercode()); my $sig := nqp::getattr($caller, Code, '$!signature'); my $lexpad := nqp::ctxcaller(nqp::ctx()); # Run full binder to produce an error. my @error; my int $bind_res := Binder.bind($capture, $sig, $lexpad, 0, @error); if $bind_res { if $bind_res == 2 { my @pos_args; my int $num_pos_args := nqp::captureposelems($capture); my int $got_prim; my int $k := -1; while ++$k < $num_pos_args { $got_prim := nqp::captureposprimspec($capture, $k); if $got_prim == 0 { nqp::push(@pos_args, nqp::captureposarg($capture, $k)); } elsif $got_prim == 1 { nqp::push(@pos_args, nqp::box_i(nqp::captureposarg_i($capture, $k), Int)); } elsif $got_prim == 2 { nqp::push(@pos_args, nqp::box_n(nqp::captureposarg_n($capture, $k), Num)); } elsif $got_prim == 10 { nqp::push(@pos_args, nqp::box_u(nqp::captureposarg_u($capture, $k), Int)); } else { nqp::push(@pos_args, nqp::box_s(nqp::captureposarg_s($capture, $k), Str)); } } my %named_args := nqp::capturenamedshash($capture); Junction.AUTOTHREAD($caller, |@pos_args, |%named_args); } else { nqp::isinvokable(@error[0]) ?? @error[0]() !! nqp::die(@error[0]); } } else { nqp::die("Internal error: inconsistent bind result"); } }, 'method_not_found_error', -> $obj, str $name, *@pos, *%named { my $class := nqp::getlexcaller('$?CLASS'); my $die_msg := "Method '$name' not found for invocant of class '{$obj.HOW.name($obj)}'"; if $name eq 'STORE' { Perl6::Metamodel::Configuration.throw_or_die( 'X::Assignment::RO', $die_msg, :value($obj) ); } Perl6::Metamodel::Configuration.throw_or_die( 'X::Method::NotFound', $die_msg, :invocant($obj), :method($name), :typename($obj.HOW.name($obj)), :private(nqp::hllboolfor(0, 'Raku')), :in-class-call(nqp::hllboolfor(nqp::eqaddr(nqp::what($obj), $class), 'Raku')) ); }, 'lexical_handler_not_found_error', -> int $cat, int $out_of_dyn_scope { if $cat == nqp::const::CONTROL_RETURN { Perl6::Metamodel::Configuration.throw_or_die( 'X::ControlFlow::Return', 'Attempt to return outside of any Routine', :out-of-dynamic-scope(nqp::hllboolfor($out_of_dyn_scope, 'Raku')) ); } else { my $ex := nqp::newexception(); nqp::setextype($ex, $cat); nqp::getcomp('Raku').handle-control($ex); } }, 'finalize_handler', -> @objs { # Reinstate $*STACK-ID if invoked in a specilized finalization thread. # Preserve the current stack ID otherwise. my $*STACK-ID := nqp::ifnull( nqp::getlexreldyn(nqp::ctxcaller(nqp::ctx()), '$*STACK-ID'), Perl6::Metamodel::Configuration.next_id ); for @objs -> $o { for $o.HOW.destroyers($o) -> $d { $d($o) } } }, 'int_lex_ref', IntLexRef, 'uint_lex_ref', UIntLexRef, 'num_lex_ref', NumLexRef, 'str_lex_ref', StrLexRef, 'int_attr_ref', IntAttrRef, 'uint_attr_ref', UIntAttrRef, 'num_attr_ref', NumAttrRef, 'str_attr_ref', StrAttrRef, 'int_pos_ref', IntPosRef, 'uint_pos_ref', UIntPosRef, 'num_pos_ref', NumPosRef, 'str_pos_ref', StrPosRef, 'int_multidim_ref', IntMultidimRef, 'uint_multidim_ref', UIntMultidimRef, 'num_multidim_ref', NumMultidimRef, 'str_multidim_ref', StrMultidimRef, 'call_dispatcher', 'raku-call', 'method_call_dispatcher', 'raku-meth-call', 'find_method_dispatcher', 'raku-find-meth', 'resume_error_dispatcher', 'raku-resume-error', 'hllize_dispatcher', 'raku-hllize', 'istype_dispatcher', 'nqp-istype', # Can write a Raku one later for more opts 'isinvokable_dispatcher', 'raku-isinvokable', 'max_inline_size', 384, )); my @types_for_hll_role := nqp::list(Mu, Int, Num, Str, List, Hash, ForeignCode); my @transform_type := nqp::list( Mu, -> $int { nqp::box_i($int, Int) }, -> $num { nqp::box_n($num, Num) }, -> $str { nqp::box_s($str, Str) }, -> $farray { my $list := nqp::create(List); nqp::bindattr($list, List, '$!reified', $farray); $list }, -> $hash { my $result := nqp::create(Hash); nqp::bindattr($result, Map, '$!storage', $hash); $result }, -> $code { my $result := nqp::create(ForeignCode); nqp::bindattr($result, ForeignCode, '$!do', $code); $result }, -> $uint { nqp::box_u($uint, Int) }, ); nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-hllize', -> $capture { my $arg := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $arg); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $arg); my $spec := nqp::captureposprimspec($capture, 0); if $spec { nqp::dispatch( 'boot-syscall', 'dispatcher-delegate', 'lang-call', nqp::dispatch( 'boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, @transform_type[$spec == 10 ?? 7 !! $spec > 3 ?? 1 !! $spec] ) ) } else { my $obj := nqp::captureposarg($capture, 0); if nqp::isnull($obj) { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, Mu ) ); } else { my $role := nqp::gettypehllrole($obj); if $role > 0 { if nqp::isconcrete($obj) { nqp::dispatch( 'boot-syscall', 'dispatcher-delegate', 'lang-call', nqp::dispatch( 'boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, @transform_type[$role] ) ) } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, @types_for_hll_role[$role] ) ); } } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } } } }); # Tell parametric role groups how to create a dispatcher. Perl6::Metamodel::ParametricRoleGroupHOW.set_selector_creator({ my $sel := nqp::create(Sub); my $onlystar := sub (*@pos, *%named) { nqp::dispatch('boot-resume', nqp::const::DISP_ONLYSTAR) }; nqp::setcodeobj($onlystar, $sel); nqp::bindattr($sel, Code, '$!do', $onlystar); nqp::bindattr($sel, Routine, '@!dispatchees', []); $sel }); # Roles pretend to be narrower than certain types for the purpose # of type checking. Also, they pun to classes. my %excluded := nqp::hash( 'ACCEPTS', Mu, 'item', Mu, 'dispatch:<.=>', Mu, 'Bool', Mu, 'gist', Mu, 'perl', Mu, 'raku', Mu, 'Str', Mu, 'sink', Mu, 'defined', Mu, 'WHICH', Mu, 'WHERE', Mu, 'WHY', Mu, 'set_why', Mu, 'so', Mu, 'not', Mu, 'Numeric', Mu, 'Real', Mu, 'Stringy', Mu, 'say', Mu, 'print', Mu, 'put', Mu, 'note', Mu, 'DUMP', Mu, 'dispatch:', Mu, 'dispatch:<.?>', Mu, 'dispatch:<.^>', Mu); Perl6::Metamodel::ParametricRoleGroupHOW.pretend_to_be([Cool, Any, Mu]); Perl6::Metamodel::ParametricRoleGroupHOW.configure_punning( Perl6::Metamodel::ClassHOW, %excluded); Perl6::Metamodel::ParametricRoleHOW.pretend_to_be([Cool, Any, Mu]); Perl6::Metamodel::ParametricRoleHOW.configure_punning( Perl6::Metamodel::ClassHOW, %excluded); Perl6::Metamodel::CurriedRoleHOW.pretend_to_be([Cool, Any, Mu]); Perl6::Metamodel::CurriedRoleHOW.configure_punning( Perl6::Metamodel::ClassHOW, %excluded); # Similar for packages and modules, but just has methods from Any. Perl6::Metamodel::PackageHOW.pretend_to_be([Any, Mu]); Perl6::Metamodel::PackageHOW.delegate_methods_to(Any); Perl6::Metamodel::ModuleHOW.pretend_to_be([Any, Mu]); Perl6::Metamodel::ModuleHOW.delegate_methods_to(Any); # Configure the MOP (not persisted as it ends up in a lexical...) Perl6::Metamodel::Configuration.set_stash_type(Stash, Map); Perl6::Metamodel::Configuration.set_submethod_type(Submethod); # Register default parent types. Perl6::Metamodel::ClassHOW.set_default_parent_type(Any); Perl6::Metamodel::GrammarHOW.set_default_parent_type(Grammar); # Put PROCESS in place, and ensure it's never repossessed. nqp::neverrepossess(PROCESS.WHO); nqp::neverrepossess(nqp::getattr(PROCESS.WHO, Map, '$!storage')); nqp::bindhllsym('Raku', 'PROCESS', PROCESS); # Stash Scalar and a default container spec away in the HLL state. nqp::bindhllsym('Raku', 'Scalar', Scalar); nqp::bindhllsym('Raku', 'ScalarVAR', ScalarVAR); nqp::bindhllsym('Raku', 'default_cont_spec', Scalar.HOW.cache_get(Scalar, 'default_cont_spec')); nqp::bindhllsym('Raku', 'Capture', Capture); nqp::bindhllsym('Raku', 'Version', Version); #line 1 src/Perl6/bootstrap.c/EXPORTHOW.nqp # Bind the HOWs into the EXPORTHOW package under the package declarator # names. my module EXPORTHOW { my %who := $?PACKAGE.WHO; %who := Perl6::Metamodel::PackageHOW; %who := Perl6::Metamodel::ModuleHOW; %who := Perl6::Metamodel::GenericHOW; %who := Perl6::Metamodel::ClassHOW; %who := Attribute; %who := Perl6::Metamodel::ParametricRoleHOW; %who := Attribute; %who := Perl6::Metamodel::ParametricRoleGroupHOW; %who := Perl6::Metamodel::GrammarHOW; %who := Attribute; %who := Perl6::Metamodel::NativeHOW; %who := Perl6::Metamodel::SubsetHOW; %who := Perl6::Metamodel::EnumHOW; %who := Perl6::Metamodel::CoercionHOW; %who := Perl6::Metamodel::DefiniteHOW; }; #line 1 gen/moar/ast.nqp # Generated by tools/build/raku-ast-compiler.nqp stub RakuAST metaclass Perl6::Metamodel::PackageHOW { ... }; BEGIN { Perl6::Metamodel::PackageHOW.add_stash(RakuAST); } stub RakuAST::IMPL::QASTContext metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::IMPL::InterpContext metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Resolver metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Resolver::EVAL metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Resolver::Compile metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Resolver::Compile::Scope metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Origin metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Origin::Match metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Origin::Source metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Node metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::CompileTimeValue metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::CheckTime metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::SinkBoundary metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::SinkPropagator metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Sinkable metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::BlockStatementSensitive metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::LexicalScope metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Declaration metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ImplicitDeclarations metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Declaration::External metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Declaration::Mergeable metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Declaration::External::Constant metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Declaration::External::Setting metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Declaration::Import metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Declaration::LexicalPackage metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Declaration::ResolvedConstant metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Lookup metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::UndeclaredSymbolDescription metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::UndeclaredSymbolDescription::Routine metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ImplicitLookups metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::PackageInstaller metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Attaching metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::AttachTarget metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::BeginTime metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::TraitTarget metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Trait metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Trait::Is metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Trait::Type metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Trait::Hides metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Trait::Does metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Trait::Of metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Trait::Returns metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Trait::Will metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Trait::Handles metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Meta metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StubbyMeta metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Doc metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Doc::Paragraph metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Doc::Block metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Doc::Markup metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Doc::Declarator metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Doc::DeclaratorTarget metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Blorst metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Contextualizable metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Label metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ImplicitBlockSemanticsProvider metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ForLoopImplementation metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementList metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::SemiList metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementSequence metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ProducesNil metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Empty metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Expression metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::IMPL::ImmediateBlockUser metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::IfWith metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::If metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::With metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Elsif metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Orwith metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Unless metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Without metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Loop metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Loop::While metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Loop::Until metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Loop::RepeatWhile metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Loop::RepeatUntil metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::For metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Given metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::When metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Whenever metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Default metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::ExceptionHandler metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Catch metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Control metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Categorical metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ModuleLoading metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Use metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Need metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Import metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Statement::Require metaclass Perl6::Metamodel::ClassHOW { ... }; stub OperatorProperties metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::CaptureSource metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Expression metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::OperatorProperties metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Infixish metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Infix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Feed metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::FlipFlop metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Assignment metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::BracketedInfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::FunctionInfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MetaInfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MetaInfix::Assign metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MetaInfix::Negate metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MetaInfix::Reverse metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MetaInfix::Cross metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MetaInfix::Zip metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MetaInfix::Hyper metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::WhateverApplicable metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ApplyInfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ApplyListInfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::DottyInfixish metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::DottyInfix::Call metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::DottyInfix::CallAssign metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ApplyDottyInfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Prefixish metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Prefix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MetaPrefix::Hyper metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Termish metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ApplyPrefix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Postfixish metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Postfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Postfix::Literal metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Postfix::Power metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Postfix::Vulgar metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Postcircumfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Postcircumfix::ArrayIndex metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Postcircumfix::HashIndex metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Postcircumfix::LiteralHashIndex metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MetaPostfix::Hyper metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ApplyPostfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Ternary metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Pragma metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::NamedArg metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::FatArrow metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ColonPairish metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ColonPair metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ColonPairs metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::QuotePair metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ColonPair::True metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ColonPair::False metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ColonPair::Number metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ColonPair::Value metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ColonPair::Variable metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Circumfix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Circumfix::Parentheses metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Circumfix::ArrayComposer metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Circumfix::HashComposer metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ArgList metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::Name metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::Name::WithoutParentheses metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::Term metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::Methodish metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::Method metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::QuotedMethod metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::PrivateMethod metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::MetaMethod metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::MaybeMethod metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Call::VarMethod metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Stub metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Stub::Fail metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Stub::Warn metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Stub::Die metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Nqp metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Nqp::Const metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::Name metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::True metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::False metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::Self metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::TopicCall metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::Named metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::EmptySet metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::Rand metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::Whatever metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::WhateverCode::Argument metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::HyperWhatever metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::Capture metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::Reduce metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Term::RadixNumber metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Name metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Name::Part metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Name::Part::Simple metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Name::Part::Expression metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Name::Part::Empty metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type::Simple metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type::Setting metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type::Derived metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type::Coercion metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type::Definedness metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type::Capture metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type::Parameterized metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type::Enum metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Type::Subset metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Initializer metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Initializer::Assign metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Initializer::Bind metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Initializer::CallAssign metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ContainerCreator metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::TraitTarget::Variable metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Constant metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Simple metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Auto metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Signature metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Anonymous metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Term metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Special metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::BlockTopic metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Constant metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Block metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Self metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Cursor metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Routine metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::State metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Doc metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Doc::Pod metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Doc::Data metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Doc::Finish metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Implicit::Doc::Rakudoc metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Placeholder metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Placeholder::Positional metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Placeholder::Named metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Placeholder::SlurpyArray metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VarDeclaration::Placeholder::SlurpyHash metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Lexical metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Lexical::Constant metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Lexical::Setting metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Dynamic metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Attribute metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Compiler metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Compiler::File metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Compiler::Line metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Compiler::Block metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Compiler::Routine metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Compiler::Lookup metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Doc metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::PositionalCapture metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::NamedCapture metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Package metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Var::Slang metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Contextualizer metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Contextualizer::Item metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Contextualizer::List metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Contextualizer::Hash metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Blockoid metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::OnlyStar metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Code metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ExpressionThunk metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::PlaceholderParameterOwner metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ScopePhaser metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Block metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::PointyBlock metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Routine metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Sub metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Methodish metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Method metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Submethod metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::RegexDeclaration metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::TokenDeclaration metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::RuleDeclaration metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::RegexThunk metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::QuotedMatchConstruct metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::QuotedRegex metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Substitution metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::SubstitutionReplacementThunk metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::CurryThunk metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::BlockThunk metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::CompUnit metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::LiteralBuilder metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Do metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Quietly metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Race metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Hyper metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Lazy metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Eager metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Try metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Thunky metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Gather metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Blorst metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Once metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Start metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::React metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Supply metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Sinky metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Begin metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Check metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Init metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Enter metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::End metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Quit metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Block metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::First metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Next metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Last metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Leave metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Keep metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Pre metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Post metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Undo metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementPrefix::Phaser::Close metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::Condition metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::If metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::Unless metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::When metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::With metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::Without metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::Loop metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::While metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::Until metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::Given metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::For metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::For::Thunk metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StatementModifier::Condition::Thunk metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Signature metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::FakeSignature metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Parameter metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ParameterTarget metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ParameterTarget::Var metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ParameterTarget::Term metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ParameterTarget::Whatever metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Parameter::Slurpy metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Parameter::Slurpy::Flattened metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Parameter::Slurpy::Unflattened metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Parameter::Slurpy::SingleArgument metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Parameter::Slurpy::Capture metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ParameterDefaultThunk metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Package metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Role metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Class metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Grammar metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Module metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Knowhow metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Native metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Literal metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Constant metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::IntLiteral metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::NumLiteral metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::RatLiteral metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ComplexLiteral metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::VersionLiteral metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::ListLiteral metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::MapLiteral metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::StrLiteral metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::QuotedString metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Heredoc metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Heredoc::InterpolatedWhiteSpace metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::QuoteWordsAtom metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Branching metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::SequentialAlternation metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::SequentialConjunction metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Alternation metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Conjunction metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Sequence metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Term metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Atom metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Literal metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Quote metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Group metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CapturingGroup metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::NamedCapture metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Anchor metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Anchor::BeginningOfString metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Anchor::BeginningOfLine metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Anchor::EndOfString metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Anchor::EndOfLine metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Anchor::LeftWordBoundary metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Anchor::RightWordBoundary metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::MatchFrom metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::MatchTo metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Any metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Negatable metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClassEnumerationElement metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::BackSpace metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Digit metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Escape metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::FormFeed metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::HorizontalSpace metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Newline metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::CarriageReturn metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Space metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Tab metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::VerticalSpace metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Word metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Specified metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClass::Nul metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::BackReference metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::BackReference::Positional metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::BackReference::Named metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Statement metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Block metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Interpolation metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::Pass metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::Fail metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::Named metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::Named::Args metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::Named::RegexArg metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::Alias metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::Lookahead metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::InterpolatedBlock metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::InterpolatedVar metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::Callable metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::PredicateBlock metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::CharClass metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Assertion::Recurse metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClassElement metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClassElement::Rule metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClassElement::Property metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClassElement::Enumeration metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClassEnumerationElement::Character metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::CharClassEnumerationElement::Range metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::InternalModifier metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::InternalModifier::IgnoreCase metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::InternalModifier::IgnoreMark metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::InternalModifier::Ratchet metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::InternalModifier::Sigspace metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::QuantifiedAtom metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Quantifier metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Quantifier::ZeroOrOne metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Quantifier::ZeroOrMore metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Quantifier::OneOrMore metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Quantifier::Range metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Quantifier::BlockRange metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::BacktrackModifiedAtom metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Backtrack metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Backtrack::Greedy metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Backtrack::Frugal metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::Backtrack::Ratchet metaclass Perl6::Metamodel::ClassHOW { ... }; stub RakuAST::Regex::WithWhitespace metaclass Perl6::Metamodel::ClassHOW { ... }; BEGIN { #line 1 src/Raku/ast/rakuast-prologue.nqp ## ## Various utility subs to help us produce types that look Raku-like. ## sub parent($class, $parent) { $class.HOW.add_parent($class, $parent); } sub add-attribute($class, $type, $name) { $class.HOW.add_attribute($class, Attribute.new( :$name, :$type, :package($class), :auto_viv_primitive($type) )); } sub add-method($class, $name, @parameters, $impl) { # Assemble a signature object for introspection purposes. my @params; my $first := 1; for @parameters -> $type, $name, $named, $optional { my $param := nqp::create(Parameter); nqp::bindattr($param, Parameter, '$!type', $type); nqp::bindattr_s($param, Parameter, '$!variable_name', $name); my int $flags := 128; # Multi-invocant $flags := $flags + 64 if $first; # Invocant $flags := $flags + 2048 if $optional; nqp::bindattr_i($param, Parameter, '$!flags', $flags); if $named { nqp::bindattr($param, Parameter, '@!named_names', nqp::list_s(nqp::substr($name, 1))); } nqp::push(@params, $param); } my $signature := nqp::create(Signature); nqp::bindattr($signature, Signature, '@!params', @params); nqp::bindattr($signature, Signature, '$!returns', Mu); # Wrap code up in a Method object. my $static-code := nqp::getstaticcode($impl); my $wrapper := nqp::create(Method); nqp::bindattr($wrapper, Code, '$!do', $static-code); nqp::bindattr($wrapper, Code, '$!signature', $signature); nqp::bindattr($wrapper, Routine, '$!package', $class); $wrapper.set_name($name); $class.HOW.add_method($class, $name, $wrapper); } sub compose($type) { $type.HOW.compose_repr($type); $type.HOW.publish_type_cache($type); $type.HOW.publish_method_cache($type); } parent(RakuAST::IMPL::QASTContext, Any); add-attribute(RakuAST::IMPL::QASTContext, Mu, '$!sc'); add-attribute(RakuAST::IMPL::QASTContext, Mu, '$!post-deserialize'); add-attribute(RakuAST::IMPL::QASTContext, Mu, '$!code-ref-blocks'); add-attribute(RakuAST::IMPL::QASTContext, int, '$!precompilation-mode'); add-attribute(RakuAST::IMPL::QASTContext, Hash, '$!sub-id-to-code-object'); add-attribute(RakuAST::IMPL::QASTContext, Hash, '$!sub-id-to-cloned-code-objects'); add-attribute(RakuAST::IMPL::QASTContext, Hash, '$!sub-id-to-sc-idx'); add-attribute(RakuAST::IMPL::QASTContext, List, '$!cleanup-tasks'); add-attribute(RakuAST::IMPL::QASTContext, int, '$!is-nested'); add-method(RakuAST::IMPL::QASTContext, 'new', [RakuAST::IMPL::QASTContext, '', 0, 0, Mu, '$sc', 1, 0, int, '$precompilation-mode', 1, 1], anon sub new ($SELF_CONT, :$sc!, :$precompilation-mode?) { my $SELF := nqp::decont($SELF_CONT); $sc := nqp::decont($sc); $precompilation-mode := nqp::decont($precompilation-mode); #line 28 src/Raku/ast/impl.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::IMPL::QASTContext, '$!sc', $sc); nqp::bindattr_i($obj, RakuAST::IMPL::QASTContext, '$!precompilation-mode', $precompilation-mode); nqp::bindattr($obj, RakuAST::IMPL::QASTContext, '$!post-deserialize', []); nqp::bindattr($obj, RakuAST::IMPL::QASTContext, '$!code-ref-blocks', []); nqp::bindattr($obj, RakuAST::IMPL::QASTContext, '$!sub-id-to-code-object', {}); nqp::bindattr($obj, RakuAST::IMPL::QASTContext, '$!sub-id-to-cloned-code-objects', {}); nqp::bindattr($obj, RakuAST::IMPL::QASTContext, '$!sub-id-to-sc-idx', {}); nqp::bindattr($obj, RakuAST::IMPL::QASTContext, '$!cleanup-tasks', []); nqp::bindattr_i($obj, RakuAST::IMPL::QASTContext, '$!is-nested', 0); $obj }); add-method(RakuAST::IMPL::QASTContext, 'create-nested', [RakuAST::IMPL::QASTContext, '', 0, 0], anon sub create-nested ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 42 src/Raku/ast/impl.rakumod my $context := nqp::clone($SELF); nqp::bindattr($context, RakuAST::IMPL::QASTContext, '$!cleanup-tasks', []); nqp::bindattr_i($context, RakuAST::IMPL::QASTContext, '$!is-nested', 1); $context }); add-method(RakuAST::IMPL::QASTContext, 'sc-handle', [RakuAST::IMPL::QASTContext, '', 0, 0], anon sub sc-handle ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 50 src/Raku/ast/impl.rakumod nqp::scgethandle(nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sc')) }); add-method(RakuAST::IMPL::QASTContext, 'lang-version', [RakuAST::IMPL::QASTContext, '', 0, 0], anon sub lang-version ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 56 src/Raku/ast/impl.rakumod 'd' }); add-method(RakuAST::IMPL::QASTContext, 'is-moar', [RakuAST::IMPL::QASTContext, '', 0, 0], anon sub is-moar ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 58 src/Raku/ast/impl.rakumod nqp::getcomp('Raku').backend.name eq 'moar' }); add-method(RakuAST::IMPL::QASTContext, 'is-precompilation-mode', [RakuAST::IMPL::QASTContext, '', 0, 0], anon sub is-precompilation-mode ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 62 src/Raku/ast/impl.rakumod nqp::getattr_i($SELF, RakuAST::IMPL::QASTContext, '$!precompilation-mode') }); add-method(RakuAST::IMPL::QASTContext, 'ensure-sc', [RakuAST::IMPL::QASTContext, '', 0, 0, Mu, '$obj', 0, 0], anon sub ensure-sc ($SELF_CONT, $obj!) { my $SELF := nqp::decont($SELF_CONT); #line 67 src/Raku/ast/impl.rakumod if nqp::isnull(nqp::getobjsc($obj)) { my $sc := nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sc'); nqp::setobjsc($obj, $sc); my int $idx := nqp::scobjcount($sc); nqp::scsetobj($sc, $idx, $obj); } $obj }); add-method(RakuAST::IMPL::QASTContext, 'add-code-ref', [RakuAST::IMPL::QASTContext, '', 0, 0, Mu, '$code-ref', 0, 0, Mu, '$block', 0, 0], anon sub add-code-ref ($SELF_CONT, $code-ref!, $block!) { my $SELF := nqp::decont($SELF_CONT); $code-ref := nqp::decont($code-ref); $block := nqp::decont($block); #line 77 src/Raku/ast/impl.rakumod my int $code-ref-idx := nqp::elems(nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!code-ref-blocks')); nqp::push(nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!code-ref-blocks'), $block); nqp::scsetcode(nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sc'), $code-ref-idx, $code-ref); nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sub-id-to-sc-idx'){$block.cuid} := $code-ref-idx; }); add-method(RakuAST::IMPL::QASTContext, 'add-fixup-task', [RakuAST::IMPL::QASTContext, '', 0, 0, Mu, '$fixup-producer', 0, 0], anon sub add-fixup-task ($SELF_CONT, $fixup-producer!) { my $SELF := nqp::decont($SELF_CONT); $fixup-producer := nqp::decont($fixup-producer); #line 86 src/Raku/ast/impl.rakumod # TODO conditional on if we're doing precomp nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!post-deserialize').push($fixup-producer()); }); add-method(RakuAST::IMPL::QASTContext, 'add-fixup-and-deserialize-task', [RakuAST::IMPL::QASTContext, '', 0, 0, Mu, '$qast', 0, 0], anon sub add-fixup-and-deserialize-task ($SELF_CONT, $qast!) { my $SELF := nqp::decont($SELF_CONT); $qast := nqp::decont($qast); #line 93 src/Raku/ast/impl.rakumod nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!post-deserialize').push($qast); }); add-method(RakuAST::IMPL::QASTContext, 'sub-id-to-code-object', [RakuAST::IMPL::QASTContext, '', 0, 0], anon sub sub-id-to-code-object ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 97 src/Raku/ast/impl.rakumod nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sub-id-to-code-object') }); add-method(RakuAST::IMPL::QASTContext, 'sub-id-to-sc-idx', [RakuAST::IMPL::QASTContext, '', 0, 0], anon sub sub-id-to-sc-idx ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 101 src/Raku/ast/impl.rakumod nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sub-id-to-sc-idx') }); add-method(RakuAST::IMPL::QASTContext, 'add-clone-for-cuid', [RakuAST::IMPL::QASTContext, '', 0, 0, Any, '$clone', 0, 0, Any, '$cuid', 0, 0], anon sub add-clone-for-cuid ($SELF_CONT, $clone!, $cuid!) { my $SELF := nqp::decont($SELF_CONT); $clone := nqp::decont($clone); $cuid := nqp::decont($cuid); #line 105 src/Raku/ast/impl.rakumod unless nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sub-id-to-cloned-code-objects'){$cuid} { nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sub-id-to-cloned-code-objects'){$cuid} := []; } nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sub-id-to-cloned-code-objects'){$cuid}.push($clone); }); add-method(RakuAST::IMPL::QASTContext, 'sub-id-to-cloned-code-objects', [RakuAST::IMPL::QASTContext, '', 0, 0], anon sub sub-id-to-cloned-code-objects ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 112 src/Raku/ast/impl.rakumod nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!sub-id-to-cloned-code-objects') }); add-method(RakuAST::IMPL::QASTContext, 'add-cleanup-task', [RakuAST::IMPL::QASTContext, '', 0, 0, Any, '$task', 0, 0], anon sub add-cleanup-task ($SELF_CONT, $task!) { my $SELF := nqp::decont($SELF_CONT); $task := nqp::decont($task); #line 116 src/Raku/ast/impl.rakumod nqp::push(nqp::getattr($SELF, RakuAST::IMPL::QASTContext, '$!cleanup-tasks'), $task) }); #line 4 src/Raku/ast/impl.rakumod add-method(RakuAST::IMPL::QASTContext, 'sc', [], anon sub sc ($self) { nqp::getattr(nqp::decont($self), RakuAST::IMPL::QASTContext, '$!sc') }); #line 5 src/Raku/ast/impl.rakumod add-method(RakuAST::IMPL::QASTContext, 'post-deserialize', [], anon sub post-deserialize ($self) { nqp::getattr(nqp::decont($self), RakuAST::IMPL::QASTContext, '$!post-deserialize') }); #line 26 src/Raku/ast/impl.rakumod add-method(RakuAST::IMPL::QASTContext, 'is-nested', [], anon sub is-nested ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::IMPL::QASTContext, '$!is-nested') }); #line 6 src/Raku/ast/impl.rakumod add-method(RakuAST::IMPL::QASTContext, 'code-ref-blocks', [], anon sub code-ref-blocks ($self) { nqp::getattr(nqp::decont($self), RakuAST::IMPL::QASTContext, '$!code-ref-blocks') }); #line 24 src/Raku/ast/impl.rakumod add-method(RakuAST::IMPL::QASTContext, 'cleanup-tasks', [], anon sub cleanup-tasks ($self) { nqp::getattr(nqp::decont($self), RakuAST::IMPL::QASTContext, '$!cleanup-tasks') }); compose(RakuAST::IMPL::QASTContext); parent(RakuAST::IMPL::InterpContext, Any); compose(RakuAST::IMPL::InterpContext); parent(RakuAST::Resolver, Any); add-attribute(RakuAST::Resolver, Mu, '$!setting'); add-attribute(RakuAST::Resolver, Mu, '$!outer'); add-attribute(RakuAST::Resolver, Mu, '$!global'); add-attribute(RakuAST::Resolver, Mu, '$!attach-targets'); add-attribute(RakuAST::Resolver, Mu, '$!packages'); add-attribute(RakuAST::Resolver, Mu, '$!nodes-with-check-time-problems'); add-attribute(RakuAST::Resolver, Mu, '$!nodes-unresolved-after-check-time'); add-attribute(RakuAST::Resolver, Mu, '$!export-package'); add-method(RakuAST::Resolver, 'clone', [RakuAST::Resolver, '', 0, 0], anon sub clone ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 29 src/Raku/ast/resolver.rakumod my $clone := nqp::clone($SELF); nqp::bindattr($clone,RakuAST::Resolver,'$!attach-targets', nqp::clone(nqp::getattr($SELF, RakuAST::Resolver, '$!attach-targets'))); nqp::bindattr($clone,RakuAST::Resolver,'$!packages', nqp::clone(nqp::getattr($SELF, RakuAST::Resolver, '$!packages'))); $clone }); add-method(RakuAST::Resolver, 'push-attach-target', [RakuAST::Resolver, '', 0, 0, RakuAST::AttachTarget, '$target', 0, 0], anon sub push-attach-target ($SELF_CONT, $target!) { my $SELF := nqp::decont($SELF_CONT); $target := nqp::decont($target); #line 39 src/Raku/ast/resolver.rakumod $target.clear-attachments(); for $target.IMPL-UNWRAP-LIST($target.attach-target-names()) -> str $name { my @stack := nqp::getattr($SELF, RakuAST::Resolver, '$!attach-targets'){$name}; unless nqp::isconcrete(@stack) { @stack := []; nqp::getattr($SELF, RakuAST::Resolver, '$!attach-targets'){$name} := @stack; } nqp::push(@stack, $target); } Nil }); add-method(RakuAST::Resolver, 'pop-attach-target', [RakuAST::Resolver, '', 0, 0, RakuAST::AttachTarget, '$target', 0, 0], anon sub pop-attach-target ($SELF_CONT, $target!) { my $SELF := nqp::decont($SELF_CONT); $target := nqp::decont($target); #line 53 src/Raku/ast/resolver.rakumod for $target.IMPL-UNWRAP-LIST($target.attach-target-names()) -> str $name { my @stack := nqp::getattr($SELF, RakuAST::Resolver, '$!attach-targets'){$name}; unless nqp::eqaddr(nqp::pop(@stack),$target) { nqp::die('Inconsistent attachment target stack for ' ~ $target.HOW.name($target)); } } Nil }); add-method(RakuAST::Resolver, 'find-attach-target', [RakuAST::Resolver, '', 0, 0, str, '$name', 0, 0], anon sub find-attach-target ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 67 src/Raku/ast/resolver.rakumod my @stack := nqp::getattr($SELF, RakuAST::Resolver, '$!attach-targets'){$name}; nqp::isconcrete(@stack) && nqp::elems(@stack) ?? @stack[nqp::elems(@stack) - 1] !! Nil }); add-method(RakuAST::Resolver, 'set-global', [RakuAST::Resolver, '', 0, 0, Mu, '$global', 0, 0], anon sub set-global ($SELF_CONT, $global!) { my $SELF := nqp::decont($SELF_CONT); $global := nqp::decont($global); #line 75 src/Raku/ast/resolver.rakumod nqp::die("This resolver's GLOBAL is already set") unless nqp::eqaddr(nqp::getattr($SELF, RakuAST::Resolver, '$!global'),Mu); nqp::bindattr($SELF, RakuAST::Resolver, '$!global', $global); Nil }); add-method(RakuAST::Resolver, 'get-global', [RakuAST::Resolver, '', 0, 0], anon sub get-global ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 82 src/Raku/ast/resolver.rakumod nqp::getattr($SELF, RakuAST::Resolver, '$!global') }); add-method(RakuAST::Resolver, 'set-export-package', [RakuAST::Resolver, '', 0, 0, Mu, '$package', 0, 0], anon sub set-export-package ($SELF_CONT, $package!) { my $SELF := nqp::decont($SELF_CONT); $package := nqp::decont($package); #line 85 src/Raku/ast/resolver.rakumod nqp::die("This resolver's EXPORT is already set") unless nqp::eqaddr(nqp::getattr($SELF, RakuAST::Resolver, '$!export-package'),Mu); nqp::bindattr($SELF,RakuAST::Resolver,'$!export-package',$package); Nil }); add-method(RakuAST::Resolver, 'push-package', [RakuAST::Resolver, '', 0, 0, RakuAST::Package, '$package', 0, 0], anon sub push-package ($SELF_CONT, $package!) { my $SELF := nqp::decont($SELF_CONT); $package := nqp::decont($package); #line 93 src/Raku/ast/resolver.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Resolver, '$!packages'), $package); $SELF.push-attach-target($package); Nil }); add-method(RakuAST::Resolver, 'current-package', [RakuAST::Resolver, '', 0, 0], anon sub current-package ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 101 src/Raku/ast/resolver.rakumod if nqp::elems(nqp::getattr($SELF, RakuAST::Resolver, '$!packages')) { nqp::getattr($SELF, RakuAST::Resolver, '$!packages')[nqp::elems(nqp::getattr($SELF, RakuAST::Resolver, '$!packages')) - 1].compile-time-value } else { my $current := nqp::getattr($SELF, RakuAST::Resolver, '$!outer'); until nqp::eqaddr($current, nqp::getattr($SELF, RakuAST::Resolver, '$!setting')) { return nqp::atkey($current, '$?PACKAGE') if nqp::existskey($current, '$?PACKAGE'); $current := nqp::ctxouterskipthunks($current); } nqp::getattr($SELF, RakuAST::Resolver, '$!global') } }); add-method(RakuAST::Resolver, 'pop-package', [RakuAST::Resolver, '', 0, 0], anon sub pop-package ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 117 src/Raku/ast/resolver.rakumod my $package := nqp::pop(nqp::getattr($SELF, RakuAST::Resolver, '$!packages')); $SELF.pop-attach-target($package); Nil }); add-method(RakuAST::Resolver, 'packages', [RakuAST::Resolver, '', 0, 0], anon sub packages ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 124 src/Raku/ast/resolver.rakumod my $result := nqp::create(List); nqp::bindattr($result, List, '$!reified', nqp::getattr($SELF, RakuAST::Resolver, '$!packages')); $result }); add-method(RakuAST::Resolver, 'resolve-infix', [RakuAST::Resolver, '', 0, 0, Str, '$name', 0, 0], anon sub resolve-infix ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 131 src/Raku/ast/resolver.rakumod $SELF.resolve-lexical('&infix' ~ $SELF.IMPL-CANONICALIZE-PAIR($name)) }); add-method(RakuAST::Resolver, 'resolve-prefix', [RakuAST::Resolver, '', 0, 0, Str, '$name', 0, 0], anon sub resolve-prefix ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 136 src/Raku/ast/resolver.rakumod $SELF.resolve-lexical('&prefix' ~ $SELF.IMPL-CANONICALIZE-PAIR($name)) }); add-method(RakuAST::Resolver, 'resolve-postfix', [RakuAST::Resolver, '', 0, 0, Str, '$name', 0, 0], anon sub resolve-postfix ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 141 src/Raku/ast/resolver.rakumod $SELF.resolve-lexical('&postfix' ~ $SELF.IMPL-CANONICALIZE-PAIR($name)) }); add-method(RakuAST::Resolver, 'resolve-term', [RakuAST::Resolver, '', 0, 0, Str, '$name', 0, 0], anon sub resolve-term ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 146 src/Raku/ast/resolver.rakumod $SELF.resolve-lexical('&term' ~ $SELF.IMPL-CANONICALIZE-PAIR($name)) }); add-method(RakuAST::Resolver, 'global-package', [RakuAST::Resolver, '', 0, 0], anon sub global-package ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 151 src/Raku/ast/resolver.rakumod RakuAST::VarDeclaration::Implicit::Constant.new( :name, :value(nqp::getattr($SELF, RakuAST::Resolver, '$!global')) ) }); add-method(RakuAST::Resolver, 'resolve-name', [RakuAST::Resolver, '', 0, 0, RakuAST::Name, '$Rname', 0, 0, str, '$sigil', 1, 1], anon sub resolve-name ($SELF_CONT, $Rname!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $Rname := nqp::decont($Rname); $sigil := nqp::decont($sigil); #line 159 src/Raku/ast/resolver.rakumod my $found; if $Rname.is-identifier { my str $name := $Rname.canonicalize; return $SELF.global-package() if $name eq 'GLOBAL'; # Single-part name, so look lexically. $name := $sigil ~ $name if $sigil; $found := $SELF.resolve-lexical($name) } else { # All package name installations happen via the symbol table as # BEGIN-time effects, so chase it down as if it were a constant. $found := $SELF.resolve-name-constant($Rname, :$sigil) } $found || $SELF.IMPL-RESOLVE-NAME-IN-PACKAGES($Rname, :$sigil) }); add-method(RakuAST::Resolver, 'resolve-name-constant', [RakuAST::Resolver, '', 0, 0, RakuAST::Name, '$Rname', 0, 0, str, '$sigil', 1, 1], anon sub resolve-name-constant ($SELF_CONT, $Rname!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $Rname := nqp::decont($Rname); $sigil := nqp::decont($sigil); #line 179 src/Raku/ast/resolver.rakumod $SELF.IMPL-RESOLVE-NAME-CONSTANT($Rname, :$sigil) // $SELF.IMPL-RESOLVE-NAME-IN-PACKAGES($Rname, :$sigil) }); add-method(RakuAST::Resolver, 'resolve-name-constant-in-setting', [RakuAST::Resolver, '', 0, 0, RakuAST::Name, '$Rname', 0, 0], anon sub resolve-name-constant-in-setting ($SELF_CONT, $Rname!) { my $SELF := nqp::decont($SELF_CONT); $Rname := nqp::decont($Rname); #line 185 src/Raku/ast/resolver.rakumod $SELF.IMPL-RESOLVE-NAME-CONSTANT($Rname, :setting) }); add-method(RakuAST::Resolver, 'external-constant', [RakuAST::Resolver, '', 0, 0, Mu, '$stash', 0, 0, str, '$lexical-name', 0, 0], anon sub external-constant ($SELF_CONT, $stash!, $lexical-name!) { my $SELF := nqp::decont($SELF_CONT); $stash := nqp::decont($stash); $lexical-name := nqp::decont($lexical-name); #line 190 src/Raku/ast/resolver.rakumod RakuAST::Declaration::External::Constant.new( :$lexical-name, :compile-time-value(nqp::atkey($stash,$lexical-name)) ) }); add-method(RakuAST::Resolver, 'IMPL-RESOLVE-NAME-IN-PACKAGES', [RakuAST::Resolver, '', 0, 0, Any, '$Rname', 0, 0, Any, '$sigil', 1, 1], anon sub IMPL-RESOLVE-NAME-IN-PACKAGES ($SELF_CONT, $Rname!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $Rname := nqp::decont($Rname); $sigil := nqp::decont($sigil); #line 197 src/Raku/ast/resolver.rakumod # Try looking in the packages my str $name := $Rname.canonicalize; # This breaks "our &foo" lookup. But if the sigil isn't needed, why is # it being passed as an argument then??? XXX # $name := $sigil ~ $name if $sigil; for nqp::getattr($SELF, RakuAST::Resolver, '$!packages') { my $stash := $SELF.IMPL-STASH-HASH($_.compile-time-value); return $SELF.external-constant($stash, $name) if nqp::existskey($stash,$name); } my $stash := $SELF.IMPL-STASH-HASH(nqp::getattr($SELF, RakuAST::Resolver, '$!global')); nqp::existskey($stash,$name) ?? $SELF.external-constant($stash, $name) !! Nil }); add-method(RakuAST::Resolver, 'IMPL-RESOLVE-NAME-CONSTANT', [RakuAST::Resolver, '', 0, 0, RakuAST::Name, '$constant', 0, 0, Bool, '$setting', 1, 1, Bool, '$partial', 1, 1, str, '$sigil', 1, 1], anon sub IMPL-RESOLVE-NAME-CONSTANT ($SELF_CONT, $constant!, :$setting?, :$partial?, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $constant := nqp::decont($constant); $setting := nqp::decont($setting); $partial := nqp::decont($partial); $sigil := nqp::decont($sigil); #line 222 src/Raku/ast/resolver.rakumod my @parts := nqp::clone($constant.IMPL-UNWRAP-LIST($constant.parts)); nqp::die('0-part name lookup not possible as a constant') unless @parts; my $root := @parts.shift; # TODO pseudo-packages # TODO GLOBALish fallback if nqp::istype($root, RakuAST::Name::Part::Empty) { return Nil; } elsif nqp::istype($root, RakuAST::Name::Part::Expression) { return Nil; } # Resolve the root part. my $name := $root.name; my $resolved := $name eq 'GLOBAL' ?? $SELF.global-package() !! $name eq 'EXPORT' ?? RakuAST::Declaration::ResolvedConstant.new( compile-time-value => nqp::getattr($SELF, RakuAST::Resolver, '$!export-package') ) !! $setting ?? $SELF.resolve-lexical-constant-in-setting($name) !! $SELF.resolve-lexical-constant($name); $resolved ?? (my $symbol := $resolved.compile-time-value) !! (return Nil); # Other parts to resolve. if @parts { # Chase down through the packages until we find something. while @parts { my $part := @parts.shift; $name := nqp::istype($part,RakuAST::Name::Part::Simple) ?? $part.name !! ''; # Add any sigil for last iteration $name := $sigil ~ $name unless @parts; # Lookup in the current symbol's stash my $next := nqp::atkey($SELF.IMPL-STASH-HASH($symbol),$name); if nqp::isnull($next) { if $partial { # put the symbol we failed to resolve back into the list nqp::unshift(@parts, $part); return ($symbol, $constant.IMPL-WRAP-LIST(@parts)); } else { return Nil } } $symbol := $next; } # Wrap it. $resolved := RakuAST::Declaration::ResolvedConstant.new( compile-time-value => $symbol ); } $partial ?? ($symbol, List.new) !! $resolved }); add-method(RakuAST::Resolver, 'partially-resolve-name-constant', [RakuAST::Resolver, '', 0, 0, RakuAST::Name, '$Rname', 0, 0, str, '$sigil', 1, 1], anon sub partially-resolve-name-constant ($SELF_CONT, $Rname!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $Rname := nqp::decont($Rname); $sigil := nqp::decont($sigil); #line 289 src/Raku/ast/resolver.rakumod $SELF.IMPL-RESOLVE-NAME-CONSTANT($Rname, :$sigil, :partial) }); add-method(RakuAST::Resolver, 'IMPL-STASH-HASH', [RakuAST::Resolver, '', 0, 0, Mu, '$pkg', 0, 0], anon sub IMPL-STASH-HASH ($SELF_CONT, $pkg!) { my $SELF := nqp::decont($SELF_CONT); $pkg := nqp::decont($pkg); #line 293 src/Raku/ast/resolver.rakumod nqp::ishash(my $hash := $pkg.WHO) ?? $hash !! $hash.FLATTENABLE_HASH() }); add-method(RakuAST::Resolver, 'resolve-lexical-in-outer', [RakuAST::Resolver, '', 0, 0, Str, '$name', 0, 0, Bool, '$current-scope-only', 1, 1], anon sub resolve-lexical-in-outer ($SELF_CONT, $name!, :$current-scope-only?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $current-scope-only := nqp::decont($current-scope-only); #line 300 src/Raku/ast/resolver.rakumod # Mapping primspec to apprpriate native type my constant PRIMSPEC-TO-TYPE := nqp::list(Mu, int, num, str); # Look through the contexts for the name. my $context := nqp::getattr($SELF, RakuAST::Resolver, '$!outer'); my int $seen-setting; until nqp::isnull($context) { $seen-setting := 1 if nqp::existskey($context,'CORE-SETTING-REV'); # found it! if nqp::existskey($context,$name) { my $prim-spec := nqp::lexprimspec($context,$name); if $prim-spec { return RakuAST::Declaration::External.new( :lexical-name($name), :native-type(PRIMSPEC-TO-TYPE[$prim-spec]) ); } # Non-native things in the setting are assumed constant elsif $seen-setting { return RakuAST::Declaration::External::Setting.new( :lexical-name($name), :compile-time-value(nqp::atkey($context, $name)) ); } # else { return RakuAST::Declaration::External.new( :lexical-name($name) ); } } # not found, and requested to only look in this scope elsif $current-scope-only { return Nil; } $context := nqp::ctxouter($context); } # Nothing found. Nil }); add-method(RakuAST::Resolver, 'setting-constant', [RakuAST::Resolver, '', 0, 0, Str, '$name', 0, 0], anon sub setting-constant ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 351 src/Raku/ast/resolver.rakumod nqp::isconcrete( my $resolved := $SELF.resolve-lexical-constant-in-setting($name) ) ?? $resolved.compile-time-value !! $resolved }); add-method(RakuAST::Resolver, 'resolve-lexical-constant-in-context', [RakuAST::Resolver, '', 0, 0, Mu, '$context', 0, 0, Str, '$name', 0, 0], anon sub resolve-lexical-constant-in-context ($SELF_CONT, $context!, $name!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $name := nqp::decont($name); #line 360 src/Raku/ast/resolver.rakumod until nqp::isnull($context) { nqp::existskey($context, $name) ?? (return $SELF.external-constant($context, $name)) !! ($context := nqp::ctxouter($context)); } Nil }); add-method(RakuAST::Resolver, 'resolve-lexical-constant-in-outer', [RakuAST::Resolver, '', 0, 0, Str, '$name', 0, 0], anon sub resolve-lexical-constant-in-outer ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 371 src/Raku/ast/resolver.rakumod $SELF.resolve-lexical-constant-in-context(nqp::getattr($SELF, RakuAST::Resolver, '$!outer'), $name) }); add-method(RakuAST::Resolver, 'resolve-lexical-constant-in-setting', [RakuAST::Resolver, '', 0, 0, Str, '$name', 0, 0], anon sub resolve-lexical-constant-in-setting ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 377 src/Raku/ast/resolver.rakumod $SELF.resolve-lexical-constant-in-context(nqp::getattr($SELF, RakuAST::Resolver, '$!setting'), $name) }); add-method(RakuAST::Resolver, 'IMPL-SETTING-FROM-CONTEXT', [RakuAST::Resolver, '', 0, 0, Mu, '$context', 0, 0], anon sub IMPL-SETTING-FROM-CONTEXT ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 382 src/Raku/ast/resolver.rakumod # TODO locate the setting frame until nqp::isnull($context) { nqp::existskey(nqp::ctxlexpad($context),'CORE-SETTING-REV') ?? (return $context) !! ($context := nqp::ctxouterskipthunks($context)); } Nil }); add-method(RakuAST::Resolver, 'IMPL-CANONICALIZE-PAIR', [RakuAST::Resolver, '', 0, 0, Str, '$v', 0, 0], anon sub IMPL-CANONICALIZE-PAIR ($SELF_CONT, $v!) { my $SELF := nqp::decont($SELF_CONT); $v := nqp::decont($v); #line 395 src/Raku/ast/resolver.rakumod if $v ~~ /<[ < > ]>/ && !($v ~~ /<[ « » $ \\ " ' ]>/) { ':«' ~ $v ~ '»' } else { my $new := ''; my int $i := 0; my int $e := nqp::chars($v); while $i < $e { my $ch := nqp::substr($v,$i,1); $new := $new ~ '\\' if $ch eq '<' || $ch eq '>'; $new := $new ~ $ch; ++$i; } ':<' ~ $new ~ '>'; } }); add-method(RakuAST::Resolver, 'is-identifier-type', [RakuAST::Resolver, '', 0, 0, Str, '$identifier', 0, 0], anon sub is-identifier-type ($SELF_CONT, $identifier!) { my $SELF := nqp::decont($SELF_CONT); $identifier := nqp::decont($identifier); #line 414 src/Raku/ast/resolver.rakumod # Can optimize this later to avoid the throwaway name creation $SELF.is-name-type(RakuAST::Name.from-identifier($identifier)) }); add-method(RakuAST::Resolver, 'is-name-type', [RakuAST::Resolver, '', 0, 0, RakuAST::Name, '$Rname', 0, 0], anon sub is-name-type ($SELF_CONT, $Rname!) { my $SELF := nqp::decont($SELF_CONT); $Rname := nqp::decont($Rname); #line 420 src/Raku/ast/resolver.rakumod my $constant := $SELF.resolve-name($Rname); nqp::istype($constant, RakuAST::CompileTimeValue) # Name resolves, but is it an instance or a type object? ?? nqp::isconcrete($constant.compile-time-value) ?? (Bool.WHO) !! (Bool.WHO) # Name doesn't resolve to a constant at all, so can't be a type. !! (Bool.WHO) }); add-method(RakuAST::Resolver, 'is-identifier-known', [RakuAST::Resolver, '', 0, 0, Str, '$identifier', 0, 0, Any, '$exact', 1, 1], anon sub is-identifier-known ($SELF_CONT, $identifier!, :$exact?) { my $SELF := nqp::decont($SELF_CONT); $identifier := nqp::decont($identifier); $exact := nqp::decont($exact); #line 432 src/Raku/ast/resolver.rakumod nqp::isconcrete($SELF.resolve-lexical($identifier)) ?? (Bool.WHO) !! $exact ?? (Bool.WHO) !! nqp::isconcrete($SELF.resolve-lexical('&' ~ $identifier)) ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Resolver, 'is-name-known', [RakuAST::Resolver, '', 0, 0, RakuAST::Name, '$Rname', 0, 0], anon sub is-name-known ($SELF_CONT, $Rname!) { my $SELF := nqp::decont($SELF_CONT); $Rname := nqp::decont($Rname); #line 443 src/Raku/ast/resolver.rakumod $Rname.is-pseudo-package || nqp::isconcrete($SELF.resolve-name($Rname)) ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Resolver, 'build-exception', [RakuAST::Resolver, '', 0, 0, Str, '$type-name', 0, 0, Any, '%opts', 0, 0], anon sub build-exception ($SELF_CONT, $type-name!, *%opts) { my $SELF := nqp::decont($SELF_CONT); $type-name := nqp::decont($type-name); %opts := nqp::decont(%opts); #line 450 src/Raku/ast/resolver.rakumod my $name := RakuAST::Name.from-identifier-parts(|nqp::split('::', $type-name)); my $type-res := $SELF.resolve-name-constant-in-setting($name); my $XComp-res := $SELF.resolve-name-constant-in-setting: RakuAST::Name.from-identifier-parts('X', 'Comp'); if $type-res && $XComp-res { # Successfully resolved. Maka sure it is an X::Comp. my $type := $type-res.compile-time-value; my $XComp := $XComp-res.compile-time-value; unless nqp::istype($type, $XComp) { $type := $type.HOW.mixin($type, $XComp); } # Ensure that the options are Raku types. for %opts -> $p { if nqp::islist($p.value) { my @a := []; for $p.value { nqp::push(@a, nqp::hllizefor($_, 'Raku')); } %opts{$p.key} := nqp::hllizefor(@a, 'Raku'); } else { %opts{$p.key} := nqp::hllizefor($p.value, 'Raku'); } } # Construct the exception object and return it. %opts := (Bool.WHO); $type.new(|%opts) } else { # Could not find exception type, so build a fake (typically happens # during CORE.setting compilation). nqp::die('nyi missing exception type fallback') } }); add-method(RakuAST::Resolver, 'add-node-with-check-time-problems', [RakuAST::Resolver, '', 0, 0, RakuAST::CheckTime, '$node', 0, 0], anon sub add-node-with-check-time-problems ($SELF_CONT, $node!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); #line 489 src/Raku/ast/resolver.rakumod unless nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-with-check-time-problems') { nqp::bindattr($SELF, RakuAST::Resolver, '$!nodes-with-check-time-problems', []); } nqp::push(nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-with-check-time-problems'), $node); Nil }); add-method(RakuAST::Resolver, 'add-node-unresolved-after-check-time', [RakuAST::Resolver, '', 0, 0, RakuAST::Lookup, '$node', 0, 0], anon sub add-node-unresolved-after-check-time ($SELF_CONT, $node!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); #line 498 src/Raku/ast/resolver.rakumod unless nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-unresolved-after-check-time') { nqp::bindattr($SELF, RakuAST::Resolver, '$!nodes-unresolved-after-check-time', []); } nqp::push(nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-unresolved-after-check-time'), $node); Nil }); add-method(RakuAST::Resolver, 'produce-compilation-exception', [RakuAST::Resolver, '', 0, 0, Any, '$panic', 1, 1], anon sub produce-compilation-exception ($SELF_CONT, :$panic?) { my $SELF := nqp::decont($SELF_CONT); $panic := nqp::decont($panic); #line 511 src/Raku/ast/resolver.rakumod my $sorries := $SELF.all-sorries; my $worries := $SELF.all-worries; my int $num-sorries := $sorries.elems; my int $num-worries := $worries.elems; if $panic && $num-sorries == 0 && $num-worries == 0 { # There's just the panic, so return it without an enclosing group. $panic } elsif !$panic && $num-sorries == 1 && $num-worries == 0 { # Only one sorry and no worries, so no need to wrap that either. $sorries.AT-POS(0) } elsif $num-sorries || $num-worries { # Resolve the group exception type. my $XCompGroup-res := $SELF.resolve-name-constant-in-setting: RakuAST::Name.from-identifier-parts('X', 'Comp', 'Group'); if $XCompGroup-res { my $XCompGroup := $XCompGroup-res.compile-time-value; $panic ?? $XCompGroup.new(:$panic, :$sorries, :$worries) !! $XCompGroup.new( :$sorries, :$worries) } # Fallback if missing group. else { $panic || $sorries.AT-POS(0) } } else { Nil } }); add-method(RakuAST::Resolver, 'has-compilation-errors', [RakuAST::Resolver, '', 0, 0], anon sub has-compilation-errors ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 546 src/Raku/ast/resolver.rakumod $SELF.all-sorries.Bool }); add-method(RakuAST::Resolver, 'all-sorries', [RakuAST::Resolver, '', 0, 0], anon sub all-sorries ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 550 src/Raku/ast/resolver.rakumod my @sorries; if nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-with-check-time-problems') { for nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-with-check-time-problems') -> $node { for $node.IMPL-UNWRAP-LIST($node.sorries) { @sorries.push($_); } } } for RakuAST::Node.IMPL-UNWRAP-LIST($SELF.unresolved-symbol-exceptions) { @sorries.push($_); } RakuAST::Node.IMPL-WRAP-LIST(@sorries) }); add-method(RakuAST::Resolver, 'all-worries', [RakuAST::Resolver, '', 0, 0], anon sub all-worries ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 567 src/Raku/ast/resolver.rakumod my @worries; if nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-with-check-time-problems') { for nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-with-check-time-problems') -> $node { for $node.IMPL-UNWRAP-LIST($node.worries) { @worries.push($_); } } } RakuAST::Node.IMPL-WRAP-LIST(@worries) }); add-method(RakuAST::Resolver, 'unresolved-symbol-exceptions', [RakuAST::Resolver, '', 0, 0], anon sub unresolved-symbol-exceptions ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 581 src/Raku/ast/resolver.rakumod my %types; my %routines; my @exceptions; if nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-unresolved-after-check-time') { for nqp::getattr($SELF, RakuAST::Resolver, '$!nodes-unresolved-after-check-time') -> $node { my $problem := $node.undeclared-symbol-details(); if $problem { $problem.IMPL-REPORT($node, %types, %routines, @exceptions); } } } if %routines || %types { @exceptions.push: $SELF.build-exception: 'X::Undeclared::Symbols', :unk_types(nqp::hllizefor(%types, 'Raku')), :unk_routines(nqp::hllizefor(%routines, 'Raku')); } RakuAST::Node.IMPL-WRAP-LIST(@exceptions) }); #line 4 src/Raku/ast/resolver.rakumod add-method(RakuAST::Resolver, 'setting', [], anon sub setting ($self) { nqp::getattr(nqp::decont($self), RakuAST::Resolver, '$!setting') }); compose(RakuAST::Resolver); parent(RakuAST::Resolver::EVAL, RakuAST::Resolver); add-attribute(RakuAST::Resolver::EVAL, Mu, '$!scopes'); add-method(RakuAST::Resolver::EVAL, 'new', [RakuAST::Resolver::EVAL, '', 0, 0, Mu, '$global', 1, 0, Mu, '$context', 1, 0], anon sub new ($SELF_CONT, :$global!, :$context!) { my $SELF := nqp::decont($SELF_CONT); $global := nqp::decont($global); $context := nqp::decont($context); #line 612 src/Raku/ast/resolver.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Resolver, '$!outer', $context); nqp::bindattr($obj, RakuAST::Resolver, '$!setting', $SELF.IMPL-SETTING-FROM-CONTEXT($context)); nqp::bindattr($obj, RakuAST::Resolver, '$!global', $global); nqp::bindattr($obj, RakuAST::Resolver, '$!attach-targets', nqp::hash()); my $cur-package := $obj.resolve-lexical-constant-in-outer('$?PACKAGE'); nqp::bindattr($obj, RakuAST::Resolver, '$!packages', $cur-package ?? [$cur-package] !! []); nqp::bindattr($obj, RakuAST::Resolver::EVAL, '$!scopes', []); $obj }); add-method(RakuAST::Resolver::EVAL, 'clone', [RakuAST::Resolver::EVAL, '', 0, 0], anon sub clone ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 627 src/Raku/ast/resolver.rakumod my $clone := nqp::findmethod(RakuAST::Resolver, 'clone')($SELF); nqp::bindattr($clone, RakuAST::Resolver::EVAL, '$!scopes', nqp::clone(nqp::getattr($SELF, RakuAST::Resolver::EVAL, '$!scopes'))); $clone }); add-method(RakuAST::Resolver::EVAL, 'push-scope', [RakuAST::Resolver::EVAL, '', 0, 0, RakuAST::LexicalScope, '$scope', 0, 0], anon sub push-scope ($SELF_CONT, $scope!) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); #line 634 src/Raku/ast/resolver.rakumod nqp::getattr($SELF, RakuAST::Resolver::EVAL, '$!scopes').push($scope); if nqp::istype($scope, RakuAST::AttachTarget) { $SELF.push-attach-target($scope); } Nil }); add-method(RakuAST::Resolver::EVAL, 'current-scope', [RakuAST::Resolver::EVAL, '', 0, 0], anon sub current-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 643 src/Raku/ast/resolver.rakumod nqp::getattr($SELF, RakuAST::Resolver::EVAL, '$!scopes')[nqp::elems(nqp::getattr($SELF, RakuAST::Resolver::EVAL, '$!scopes')) - 1] }); add-method(RakuAST::Resolver::EVAL, 'outer-scope', [RakuAST::Resolver::EVAL, '', 0, 0], anon sub outer-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 646 src/Raku/ast/resolver.rakumod nqp::getattr($SELF, RakuAST::Resolver::EVAL, '$!scopes')[nqp::elems(nqp::getattr($SELF, RakuAST::Resolver::EVAL, '$!scopes')) - 2] }); add-method(RakuAST::Resolver::EVAL, 'pop-scope', [RakuAST::Resolver::EVAL, '', 0, 0], anon sub pop-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 651 src/Raku/ast/resolver.rakumod my $scope := nqp::getattr($SELF, RakuAST::Resolver::EVAL, '$!scopes').pop; $SELF.pop-attach-target($scope) if nqp::istype($scope, RakuAST::AttachTarget); Nil }); add-method(RakuAST::Resolver::EVAL, 'resolve-lexical', [RakuAST::Resolver::EVAL, '', 0, 0, Str, '$name', 0, 0, Bool, '$current-scope-only', 1, 1], anon sub resolve-lexical ($SELF_CONT, $name!, :$current-scope-only?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $current-scope-only := nqp::decont($current-scope-only); #line 660 src/Raku/ast/resolver.rakumod my @scopes := nqp::getattr($SELF, RakuAST::Resolver::EVAL, '$!scopes'); # If it's in the current scope only, just look at the top one, if any if $current-scope-only { return nqp::elems(@scopes) ?? @scopes[nqp::elems(@scopes) - 1].find-lexical($name) !! Nil; } # No need to look further if $name eq 'GLOBAL' { $SELF.global-package; } # Walk active scopes, most nested first. else { my int $i := nqp::elems(@scopes); while $i-- { my $found := @scopes[$i].find-lexical($name); return $found if nqp::isconcrete($found); } # Fallback handling $SELF.resolve-lexical-in-outer($name) } }); add-method(RakuAST::Resolver::EVAL, 'resolve-lexical-constant', [RakuAST::Resolver::EVAL, '', 0, 0, Str, '$name', 0, 0], anon sub resolve-lexical-constant ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 690 src/Raku/ast/resolver.rakumod # No need to look further if $name eq 'GLOBAL' { $SELF.global-package; } # Walk active scopes, most nested first. else { my @scopes := nqp::getattr($SELF, RakuAST::Resolver::EVAL, '$!scopes'); my int $i := nqp::elems(@scopes); while $i-- { my $found := @scopes[$i].find-lexical($name); if nqp::isconcrete($found) { nqp::istype($found,RakuAST::CompileTimeValue) ?? (return $found) !! nqp::die( "Symbol '$name' does not have a compile-time value" ); } } # Fallback handling $SELF.resolve-lexical-constant-in-outer($name) } }); compose(RakuAST::Resolver::EVAL); parent(RakuAST::Resolver::Compile, RakuAST::Resolver); add-attribute(RakuAST::Resolver::Compile, Mu, '$!scopes'); add-attribute(RakuAST::Resolver::Compile, Mu, '$!sorries'); add-attribute(RakuAST::Resolver::Compile, Mu, '$!worries'); add-method(RakuAST::Resolver::Compile, 'new', [RakuAST::Resolver::Compile, '', 0, 0, Mu, '$setting', 1, 0, Mu, '$outer', 1, 0, Mu, '$global', 1, 0, Mu, '$scopes', 1, 1], anon sub new ($SELF_CONT, :$setting!, :$outer!, :$global!, :$scopes?) { my $SELF := nqp::decont($SELF_CONT); $setting := nqp::decont($setting); $outer := nqp::decont($outer); $global := nqp::decont($global); $scopes := nqp::decont($scopes); #line 735 src/Raku/ast/resolver.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Resolver, '$!setting', $setting); nqp::bindattr($obj, RakuAST::Resolver, '$!outer', $outer); nqp::bindattr($obj, RakuAST::Resolver, '$!attach-targets', nqp::hash()); nqp::bindattr($obj, RakuAST::Resolver, '$!global', $global); nqp::bindattr($obj, RakuAST::Resolver, '$!packages', []); nqp::bindattr($obj, RakuAST::Resolver::Compile, '$!scopes', $scopes // []); nqp::bindattr($obj, RakuAST::Resolver::Compile, '$!sorries', []); nqp::bindattr($obj, RakuAST::Resolver::Compile, '$!worries', []); $obj }); add-method(RakuAST::Resolver::Compile, 'from-context', [RakuAST::Resolver::Compile, '', 0, 0, Mu, '$context', 1, 0, Mu, '$global', 1, 0, RakuAST::Resolver, '$resolver', 1, 1], anon sub from-context ($SELF_CONT, :$context!, :$global!, :$resolver?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $global := nqp::decont($global); $resolver := nqp::decont($resolver); #line 752 src/Raku/ast/resolver.rakumod my $setting := $resolver ?? nqp::getattr($resolver, RakuAST::Resolver, '$!setting') !! $SELF.IMPL-SETTING-FROM-CONTEXT($context); $SELF.new( :$setting, :outer($resolver ?? $setting !! $context), :$global, :scopes($resolver ?? nqp::getattr($resolver, RakuAST::Resolver::Compile, '$!scopes') !! Mu) ) }); add-method(RakuAST::Resolver::Compile, 'clone', [RakuAST::Resolver::Compile, '', 0, 0], anon sub clone ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 764 src/Raku/ast/resolver.rakumod my $clone := nqp::findmethod(RakuAST::Resolver, 'clone')($SELF); nqp::bindattr($clone, RakuAST::Resolver::Compile, '$!scopes', nqp::clone(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes'))); $clone }); add-method(RakuAST::Resolver::Compile, 'from-setting', [RakuAST::Resolver::Compile, '', 0, 0, Str, '$setting-name', 1, 0], anon sub from-setting ($SELF_CONT, :$setting-name!) { my $SELF := nqp::decont($SELF_CONT); $setting-name := nqp::decont($setting-name); #line 772 src/Raku/ast/resolver.rakumod my $loader := nqp::gethllsym('Raku', 'ModuleLoader'); my $setting := $loader.load_setting($setting-name); # We can't actually have the global yet, since the resolver is # needed in order to look up the package meta-object used to # create it. Thus it's set later. $SELF.new(:$setting, :outer($setting), :global(Mu)) }); add-method(RakuAST::Resolver::Compile, 'set-setting', [RakuAST::Resolver::Compile, '', 0, 0, Str, '$setting-name', 1, 0], anon sub set-setting ($SELF_CONT, :$setting-name!) { my $SELF := nqp::decont($SELF_CONT); $setting-name := nqp::decont($setting-name); #line 781 src/Raku/ast/resolver.rakumod my $loader := nqp::gethllsym('Raku', 'ModuleLoader'); my $setting := $loader.load_setting($setting-name); nqp::bindattr($SELF, RakuAST::Resolver, '$!setting', $setting); nqp::bindattr($SELF, RakuAST::Resolver, '$!outer', $setting); }); add-method(RakuAST::Resolver::Compile, 'push-scope', [RakuAST::Resolver::Compile, '', 0, 0, RakuAST::LexicalScope, '$scope', 0, 0], anon sub push-scope ($SELF_CONT, $scope!) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); #line 790 src/Raku/ast/resolver.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes'), RakuAST::Resolver::Compile::Scope.new(:$scope, :batch-mode)); if nqp::istype($scope, RakuAST::AttachTarget) { $SELF.push-attach-target($scope); } Nil }); add-method(RakuAST::Resolver::Compile, 'current-scope', [RakuAST::Resolver::Compile, '', 0, 0], anon sub current-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 799 src/Raku/ast/resolver.rakumod nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')[nqp::elems(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')) - 1].scope }); add-method(RakuAST::Resolver::Compile, 'outer-scope', [RakuAST::Resolver::Compile, '', 0, 0], anon sub outer-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 802 src/Raku/ast/resolver.rakumod nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')[nqp::elems(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')) - 2].scope }); add-method(RakuAST::Resolver::Compile, 'pop-scope', [RakuAST::Resolver::Compile, '', 0, 0], anon sub pop-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 807 src/Raku/ast/resolver.rakumod my $scope := nqp::pop(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')); $scope.batch-mode || nqp::die('pop-scope should only be used on batch mode scopes'); if nqp::istype($scope.scope, RakuAST::AttachTarget) { $SELF.pop-attach-target($scope.scope); } Nil }); add-method(RakuAST::Resolver::Compile, 'enter-scope', [RakuAST::Resolver::Compile, '', 0, 0, RakuAST::LexicalScope, '$scope', 0, 0], anon sub enter-scope ($SELF_CONT, $scope!) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); #line 820 src/Raku/ast/resolver.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes'), RakuAST::Resolver::Compile::Scope.new(:$scope, :!batch-mode)); if nqp::istype($scope, RakuAST::AttachTarget) { $SELF.push-attach-target($scope); } Nil }); add-method(RakuAST::Resolver::Compile, 'create-scope-implicits', [RakuAST::Resolver::Compile, '', 0, 0], anon sub create-scope-implicits ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 831 src/Raku/ast/resolver.rakumod nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')[nqp::elems(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')) - 1].create-implicits(); Nil }); add-method(RakuAST::Resolver::Compile, 'leave-scope', [RakuAST::Resolver::Compile, '', 0, 0], anon sub leave-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 837 src/Raku/ast/resolver.rakumod my $scope := nqp::pop(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')); $scope.batch-mode && nqp::die('leave-scope should never be used on batch mode scopes'); if nqp::istype($scope.scope, RakuAST::AttachTarget) { $SELF.pop-attach-target($scope.scope); } Nil }); add-method(RakuAST::Resolver::Compile, 'declare-lexical', [RakuAST::Resolver::Compile, '', 0, 0, RakuAST::Declaration, '$decl', 0, 0], anon sub declare-lexical ($SELF_CONT, $decl!) { my $SELF := nqp::decont($SELF_CONT); $decl := nqp::decont($decl); #line 850 src/Raku/ast/resolver.rakumod nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')[nqp::elems(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')) - 1].declare-lexical($decl) }); add-method(RakuAST::Resolver::Compile, 'declare-lexical-in-outer', [RakuAST::Resolver::Compile, '', 0, 0, RakuAST::Declaration, '$decl', 0, 0], anon sub declare-lexical-in-outer ($SELF_CONT, $decl!) { my $SELF := nqp::decont($SELF_CONT); $decl := nqp::decont($decl); #line 857 src/Raku/ast/resolver.rakumod nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')[nqp::elems(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes')) - 2].declare-lexical($decl) }); add-method(RakuAST::Resolver::Compile, 'resolve-lexical', [RakuAST::Resolver::Compile, '', 0, 0, Str, '$name', 0, 0, Bool, '$current-scope-only', 1, 1], anon sub resolve-lexical ($SELF_CONT, $name!, :$current-scope-only?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $current-scope-only := nqp::decont($current-scope-only); #line 863 src/Raku/ast/resolver.rakumod # If it's in the current scope only, we just look at the top one. if $current-scope-only { my @scopes := nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes'); my int $i := nqp::elems(@scopes); return $i > 0 ?? @scopes[$i - 1].find-lexical($name) !! Nil; } if $name eq 'GLOBAL' { return $SELF.global-package; } # Walk active scopes, most nested first. my @scopes := nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes'); my int $i := nqp::elems(@scopes); while $i-- { my $scope := @scopes[$i]; my $found := $scope.find-lexical($name); return $found if nqp::isconcrete($found); } $SELF.resolve-lexical-in-outer($name) }); add-method(RakuAST::Resolver::Compile, 'resolve-lexical-constant', [RakuAST::Resolver::Compile, '', 0, 0, Str, '$name', 0, 0], anon sub resolve-lexical-constant ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 889 src/Raku/ast/resolver.rakumod if $name eq 'GLOBAL' { return $SELF.global-package; } # Walk active scopes, most nested first. my @scopes := nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes'); my int $i := nqp::elems(@scopes); while $i-- { my $scope := @scopes[$i]; my $found := $scope.find-lexical($name); if nqp::isconcrete($found) { if nqp::istype($found, RakuAST::CompileTimeValue) { return $found; } else { nqp::die("Symbol '$name' does not have a compile-time value"); } } } # Fall back to looking in outer scopes. $SELF.resolve-lexical-constant-in-outer($name); }); add-method(RakuAST::Resolver::Compile, 'add-sorry', [RakuAST::Resolver::Compile, '', 0, 0, Any, '$exception', 0, 0], anon sub add-sorry ($SELF_CONT, $exception!) { my $SELF := nqp::decont($SELF_CONT); $exception := nqp::decont($exception); #line 915 src/Raku/ast/resolver.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!sorries'), $exception); Nil }); add-method(RakuAST::Resolver::Compile, 'has-sorries', [RakuAST::Resolver::Compile, '', 0, 0], anon sub has-sorries ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 919 src/Raku/ast/resolver.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!sorries')) > 0 }); add-method(RakuAST::Resolver::Compile, 'add-worry', [RakuAST::Resolver::Compile, '', 0, 0, Any, '$exception', 0, 0], anon sub add-worry ($SELF_CONT, $exception!) { my $SELF := nqp::decont($SELF_CONT); $exception := nqp::decont($exception); #line 922 src/Raku/ast/resolver.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!worries'), $exception); Nil }); add-method(RakuAST::Resolver::Compile, 'has-worries', [RakuAST::Resolver::Compile, '', 0, 0], anon sub has-worries ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 926 src/Raku/ast/resolver.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!worries')) > 0 }); add-method(RakuAST::Resolver::Compile, 'panic', [RakuAST::Resolver::Compile, '', 0, 0, Any, '$exception', 0, 0], anon sub panic ($SELF_CONT, $exception!) { my $SELF := nqp::decont($SELF_CONT); $exception := nqp::decont($exception); #line 930 src/Raku/ast/resolver.rakumod $SELF.produce-compilation-exception(:panic($exception)).throw }); add-method(RakuAST::Resolver::Compile, 'all-sorries', [RakuAST::Resolver::Compile, '', 0, 0], anon sub all-sorries ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 935 src/Raku/ast/resolver.rakumod my @sorries := RakuAST::Node.IMPL-UNWRAP-LIST: nqp::findmethod(RakuAST::Resolver,'all-sorries')($SELF); for nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!sorries') { @sorries.push($_); } RakuAST::Node.IMPL-WRAP-LIST(@sorries) }); add-method(RakuAST::Resolver::Compile, 'all-worries', [RakuAST::Resolver::Compile, '', 0, 0], anon sub all-worries ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 945 src/Raku/ast/resolver.rakumod my @worries := RakuAST::Node.IMPL-UNWRAP-LIST: nqp::findmethod(RakuAST::Resolver,'all-worries')($SELF); for nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!worries') { @worries.push($_); } RakuAST::Node.IMPL-WRAP-LIST(@worries) }); add-method(RakuAST::Resolver::Compile, 'levenshtein', [RakuAST::Resolver::Compile, '', 0, 0, Any, '$a', 0, 0, Any, '$b', 0, 0], anon sub levenshtein ($SELF_CONT, $a!, $b!) { my $SELF := nqp::decont($SELF_CONT); $a := nqp::decont($a); $b := nqp::decont($b); #line 956 src/Raku/ast/resolver.rakumod my %memo; my int $alen := nqp::chars($a); my int $blen := nqp::chars($b); return 0 if $alen == 0 || $blen == 0; my sub changecost(str $ac, str $bc) { my sub issigil($_) { nqp::index('$@%&|', $_) != -1 }; return 0 if $ac eq $bc; return 0.1 if nqp::fc($ac) eq nqp::fc($bc); return 0.5 if issigil($ac) && issigil($bc); 1; } my sub levenshtein_impl(int $apos, int $bpos, num $estimate) { my $key := "$apos:$bpos"; return %memo{$key} if nqp::existskey(%memo, $key); # if either cursor reached the end of the respective string, # the result is the remaining length of the other string. my sub check(int $pos1, int $len1, int $pos2, int $len2) { if $pos2 == $len2 { return $len1 - $pos1; } -1; } my int $check := check($apos, $alen, $bpos, $blen); return $check unless $check == -1; $check := check($bpos, $blen, $apos, $alen); return $check unless $check == -1; my str $achar := nqp::substr($a, $apos, 1); my str $bchar := nqp::substr($b, $bpos, 1); my num $cost := changecost($achar, $bchar); # hyphens and underscores cost half when adding/deleting. my num $addcost := 1; $addcost := 0.5 if $bchar eq "-" || $bchar eq "_"; my num $delcost := 1; $delcost := 0.5 if $achar eq "-" || $achar eq "_"; my num $ca := nqp::add_n(levenshtein_impl($apos+1, $bpos, nqp::add_n($estimate, $delcost)), $delcost); # what if we remove the current letter from A? my num $cb := nqp::add_n(levenshtein_impl($apos, $bpos+1, nqp::add_n($estimate, $addcost)), $addcost); # what if we add the current letter from B? my num $cc := nqp::add_n(levenshtein_impl($apos+1, $bpos+1, nqp::add_n($estimate, $cost)), $cost); # what if we change/keep the current letter? # the result is the shortest of the three sub-tasks my num $distance; $distance := $ca if nqp::isle_n($ca, $cb) && nqp::isle_n($ca, $cc); $distance := $cb if nqp::isle_n($cb, $ca) && nqp::isle_n($cb, $cc); $distance := $cc if nqp::isle_n($cc, $ca) && nqp::isle_n($cc, $cb); # switching two letters costs only 1 instead of 2. if $apos + 1 <= $alen && $bpos + 1 <= $blen && nqp::eqat($a, $bchar, $apos + 1) && nqp::eqat($b, $achar, $bpos + 1) { my num $cd := nqp::add_n(levenshtein_impl($apos+2, $bpos+2, nqp::add_n($estimate, 1)), 1); $distance := $cd if nqp::islt_n($cd, $distance); } %memo{$key} := $distance; } return levenshtein_impl(0, 0, 0e0); }); add-method(RakuAST::Resolver::Compile, 'make_levenshtein_evaluator', [RakuAST::Resolver::Compile, '', 0, 0, Any, '$orig_name', 0, 0, Any, '@candidates', 0, 0], anon sub make_levenshtein_evaluator ($SELF_CONT, $orig_name!, @candidates!) { my $SELF := nqp::decont($SELF_CONT); $orig_name := nqp::decont($orig_name); @candidates := nqp::decont(@candidates); #line 1025 src/Raku/ast/resolver.rakumod my $find-count := 0; my $try-count := 0; my &inner := my sub ($name) { # difference in length is a good lower bound. $try-count := $try-count + 1; return 0 if $find-count > 20 || $try-count > 1000; my $parlen := nqp::chars($orig_name); my $lendiff := nqp::chars($name) - $parlen; $lendiff := -$lendiff if $lendiff < 0; return 1 if nqp::isge_n($lendiff, nqp::mul_n($parlen, 0.3)); my num $dist := nqp::div_n($SELF.levenshtein($orig_name, $name), $parlen); my $target := -1; $target := @candidates[0] if nqp::isle_n($dist, 0.1); $target := @candidates[1] if nqp::islt_n(0.1, $dist) && nqp::isle_n($dist, 0.2); $target := @candidates[2] if nqp::islt_n(0.2, $dist) && nqp::isle_n($dist, 0.35); if $target != -1 { my $name-str := nqp::box_s($name, Str); nqp::push($target, $name-str); $find-count := $find-count + 1; } 1; } return &inner; }); add-method(RakuAST::Resolver::Compile, 'levenshtein_candidate_heuristic', [RakuAST::Resolver::Compile, '', 0, 0, Any, '@candidates', 0, 0, Any, '$target', 0, 0], anon sub levenshtein_candidate_heuristic ($SELF_CONT, @candidates!, $target!) { my $SELF := nqp::decont($SELF_CONT); @candidates := nqp::decont(@candidates); $target := nqp::decont($target); #line 1052 src/Raku/ast/resolver.rakumod # only take a few suggestions my $to-add := 5; for @candidates[0] { $target.push($_) if $to-add > 0; $to-add := $to-add - 1; } $to-add := $to-add - 1 if +@candidates[0] > 0; for @candidates[1] { $target.push($_) if $to-add > 0; $to-add := $to-add - 1; } $to-add := $to-add - 2 if +@candidates[1] > 0; for @candidates[2] { $target.push($_) if $to-add > 0; $to-add := $to-add - 1; } }); add-method(RakuAST::Resolver::Compile, 'suggest-lexicals', [RakuAST::Resolver::Compile, '', 0, 0, Str, '$name', 0, 0], anon sub suggest-lexicals ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 1071 src/Raku/ast/resolver.rakumod my @suggestions; my @candidates := [[], [], []]; my &inner-evaluator := $SELF.make_levenshtein_evaluator($name, @candidates); my %seen; %seen{$name} := 1; sub evaluate($name, $value, $has_value) { # the descriptor identifies variables. return 1 if nqp::existskey(%seen, $name); %seen{$name} := 1; return &inner-evaluator($name); } # Walk active scopes, most nested first. my @scopes := nqp::getattr($SELF, RakuAST::Resolver::Compile, '$!scopes'); my int $i := nqp::elems(@scopes); while $i-- { my $scope := @scopes[$i]; for $scope.lexical-declarations { my $name := $_.lexical-name; next if nqp::existskey(%seen, $name); %seen{$name} := 1; &inner-evaluator($name); } } my $ctx := nqp::getattr($SELF, RakuAST::Resolver, '$!outer'); while !nqp::isnull($ctx) { for $ctx -> $name { next if nqp::existskey(%seen, $name); %seen{$name} := 1; &inner-evaluator($name); } $ctx := nqp::ctxouter($ctx); } $SELF.levenshtein_candidate_heuristic(@candidates, @suggestions); return @suggestions; }); compose(RakuAST::Resolver::Compile); parent(RakuAST::Resolver::Compile::Scope, RakuAST::Resolver); add-attribute(RakuAST::Resolver::Compile::Scope, RakuAST::LexicalScope, '$!scope'); add-attribute(RakuAST::Resolver::Compile::Scope, int, '$!batch-mode'); add-attribute(RakuAST::Resolver::Compile::Scope, Mu, '$!live-decl-map'); add-method(RakuAST::Resolver::Compile::Scope, 'new', [RakuAST::Resolver::Compile::Scope, '', 0, 0, RakuAST::LexicalScope, '$scope', 1, 0, int, '$batch-mode', 1, 1], anon sub new ($SELF_CONT, :$scope!, :$batch-mode?) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $batch-mode := nqp::decont($batch-mode); #line 1128 src/Raku/ast/resolver.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Resolver::Compile::Scope, '$!scope', $scope); nqp::bindattr_i($obj, RakuAST::Resolver::Compile::Scope, '$!batch-mode', $batch-mode); unless $batch-mode { nqp::bindattr($obj, RakuAST::Resolver::Compile::Scope, '$!live-decl-map', {}); } $obj }); add-method(RakuAST::Resolver::Compile::Scope, 'batch-mode', [RakuAST::Resolver::Compile::Scope, '', 0, 0], anon sub batch-mode ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1138 src/Raku/ast/resolver.rakumod nqp::getattr_i($SELF, RakuAST::Resolver::Compile::Scope, '$!batch-mode') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Resolver::Compile::Scope, 'find-lexical', [RakuAST::Resolver::Compile::Scope, '', 0, 0, Str, '$name', 0, 0], anon sub find-lexical ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 1142 src/Raku/ast/resolver.rakumod if nqp::getattr_i($SELF, RakuAST::Resolver::Compile::Scope, '$!batch-mode') { nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!scope').find-lexical($name) // Nil } else { nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!live-decl-map'){$name} // nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!scope').find-generated-lexical($name) // Nil } }); add-method(RakuAST::Resolver::Compile::Scope, 'lexical-declarations', [RakuAST::Resolver::Compile::Scope, '', 0, 0], anon sub lexical-declarations ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1151 src/Raku/ast/resolver.rakumod my $declarations := nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!scope').lexical-declarations; my @declarations := nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!scope').IMPL-UNWRAP-LIST($declarations); unless nqp::getattr_i($SELF, RakuAST::Resolver::Compile::Scope, '$!batch-mode') { for nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!live-decl-map') { nqp::push(@declarations, $_.value); } } @declarations }); add-method(RakuAST::Resolver::Compile::Scope, 'declare-lexical', [RakuAST::Resolver::Compile::Scope, '', 0, 0, RakuAST::Declaration, '$decl', 0, 0], anon sub declare-lexical ($SELF_CONT, $decl!) { my $SELF := nqp::decont($SELF_CONT); $decl := nqp::decont($decl); #line 1162 src/Raku/ast/resolver.rakumod nqp::die('Should not be calling declare-lexical in batch mode') if nqp::getattr_i($SELF, RakuAST::Resolver::Compile::Scope, '$!batch-mode'); my $name := $decl.lexical-name; my $existed := nqp::existskey(nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!live-decl-map'), $name); nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!live-decl-map'){$decl.lexical-name} := $decl; $existed }); add-method(RakuAST::Resolver::Compile::Scope, 'create-implicits', [RakuAST::Resolver::Compile::Scope, '', 0, 0], anon sub create-implicits ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1171 src/Raku/ast/resolver.rakumod nqp::die('Should not be calling create-implicits in batch mode') if nqp::getattr_i($SELF, RakuAST::Resolver::Compile::Scope, '$!batch-mode'); if nqp::istype(nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!scope'), RakuAST::ImplicitDeclarations) { for nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!scope').IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!scope').get-implicit-declarations) -> $decl { if $decl.is-lexical { nqp::getattr($SELF, RakuAST::Resolver::Compile::Scope, '$!live-decl-map'){$decl.lexical-name} := $decl; } } } Nil }); #line 1118 src/Raku/ast/resolver.rakumod add-method(RakuAST::Resolver::Compile::Scope, 'scope', [], anon sub scope ($self) { nqp::getattr(nqp::decont($self), RakuAST::Resolver::Compile::Scope, '$!scope') }); compose(RakuAST::Resolver::Compile::Scope); parent(RakuAST::Origin, Any); add-attribute(RakuAST::Origin, int, '$!from'); add-attribute(RakuAST::Origin, int, '$!to'); add-attribute(RakuAST::Origin, RakuAST::Origin::Source, '$!source'); add-attribute(RakuAST::Origin, Mu, '$!nestings'); add-method(RakuAST::Origin, 'new', [RakuAST::Origin, '', 0, 0, int, '$from', 1, 1, int, '$to', 1, 1, Mu, '$nestings', 1, 1, RakuAST::Origin::Source, '$source', 1, 1], anon sub new ($SELF_CONT, :$from?, :$to?, :$nestings?, :$source?) { my $SELF := nqp::decont($SELF_CONT); $from := nqp::decont($from); $to := nqp::decont($to); $nestings := nqp::decont($nestings); $source := nqp::decont($source); #line 14 src/Raku/ast/origins.rakumod my $obj := nqp::create($SELF); nqp::bindattr_i($obj, RakuAST::Origin, '$!from', $from); nqp::bindattr_i($obj, RakuAST::Origin, '$!to', $to); if nqp::isconcrete($nestings) { nqp::bindattr($obj, RakuAST::Origin, '$!nestings', $nestings); } if nqp::isconcrete($source) || nqp::isconcrete($*ORIGIN-SOURCE) { nqp::bindattr($obj, RakuAST::Origin, '$!source', ($source // $*ORIGIN-SOURCE)) } $obj }); add-method(RakuAST::Origin, 'set-nestings', [RakuAST::Origin, '', 0, 0, Mu, '$nestings', 0, 0], anon sub set-nestings ($SELF_CONT, $nestings!) { my $SELF := nqp::decont($SELF_CONT); $nestings := nqp::decont($nestings); #line 27 src/Raku/ast/origins.rakumod nqp::bindattr($SELF, RakuAST::Origin, '$!nestings', $nestings); }); add-method(RakuAST::Origin, 'is-key', [RakuAST::Origin, '', 0, 0], anon sub is-key ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 31 src/Raku/ast/origins.rakumod nqp::isconcrete(nqp::getattr($SELF, RakuAST::Origin, '$!nestings')) ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Origin, 'as-match', [RakuAST::Origin, '', 0, 0], anon sub as-match ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 33 src/Raku/ast/origins.rakumod nqp::getattr($SELF, RakuAST::Origin, '$!source').match-from($SELF) }); add-method(RakuAST::Origin, 'Str', [RakuAST::Origin, '', 0, 0], anon sub Str ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 35 src/Raku/ast/origins.rakumod nqp::substr(nqp::getattr($SELF, RakuAST::Origin, '$!source').orig, nqp::getattr_i($SELF, RakuAST::Origin, '$!from'), nqp::getattr_i($SELF, RakuAST::Origin, '$!to') - nqp::getattr_i($SELF, RakuAST::Origin, '$!from')) }); #line 3 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin, 'to', [], anon sub to ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Origin, '$!to') }); #line 4 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin, 'source', [], anon sub source ($self) { nqp::getattr(nqp::decont($self), RakuAST::Origin, '$!source') }); #line 12 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin, 'nestings', [], anon sub nestings ($self) { nqp::getattr(nqp::decont($self), RakuAST::Origin, '$!nestings') }); #line 2 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin, 'from', [], anon sub from ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Origin, '$!from') }); compose(RakuAST::Origin); parent(RakuAST::Origin::Match, Any); add-attribute(RakuAST::Origin::Match, str, '$!file'); add-attribute(RakuAST::Origin::Match, str, '$!orig'); add-attribute(RakuAST::Origin::Match, int, '$!line'); add-attribute(RakuAST::Origin::Match, int, '$!orig-line'); add-attribute(RakuAST::Origin::Match, int, '$!from'); add-attribute(RakuAST::Origin::Match, int, '$!to'); add-method(RakuAST::Origin::Match, 'new', [RakuAST::Origin::Match, '', 0, 0, str, '$file', 1, 1, str, '$orig', 1, 1, int, '$line', 1, 1, int, '$orig-line', 1, 1, int, '$from', 1, 1, int, '$to', 1, 1], anon sub new ($SELF_CONT, :$file?, :$orig?, :$line?, :$orig-line?, :$from?, :$to?) { my $SELF := nqp::decont($SELF_CONT); $file := nqp::decont($file); $orig := nqp::decont($orig); $line := nqp::decont($line); $orig-line := nqp::decont($orig-line); $from := nqp::decont($from); $to := nqp::decont($to); #line 52 src/Raku/ast/origins.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Origin::Match, '$!file', $file); nqp::bindattr_s($obj, RakuAST::Origin::Match, '$!orig', $orig); nqp::bindattr_i($obj, RakuAST::Origin::Match, '$!line', $line); nqp::bindattr_i($obj, RakuAST::Origin::Match, '$!orig-line', $orig-line); nqp::bindattr_i($obj, RakuAST::Origin::Match, '$!from', $from); nqp::bindattr_i($obj, RakuAST::Origin::Match, '$!to', $to); $obj }); add-method(RakuAST::Origin::Match, 'target', [RakuAST::Origin::Match, '', 0, 0], anon sub target ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 63 src/Raku/ast/origins.rakumod nqp::getattr_s($SELF, RakuAST::Origin::Match, '$!orig') }); add-method(RakuAST::Origin::Match, 'chars', [RakuAST::Origin::Match, '', 0, 0], anon sub chars ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 64 src/Raku/ast/origins.rakumod nqp::getattr_i($SELF, RakuAST::Origin::Match, '$!to') - nqp::getattr_i($SELF, RakuAST::Origin::Match, '$!from') }); add-method(RakuAST::Origin::Match, 'Str', [RakuAST::Origin::Match, '', 0, 0], anon sub Str ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 65 src/Raku/ast/origins.rakumod nqp::substr(nqp::getattr_s($SELF, RakuAST::Origin::Match, '$!orig'), nqp::getattr_i($SELF, RakuAST::Origin::Match, '$!from'), nqp::getattr_i($SELF, RakuAST::Origin::Match, '$!to') - nqp::getattr_i($SELF, RakuAST::Origin::Match, '$!from')) }); #line 50 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin::Match, 'to', [], anon sub to ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Origin::Match, '$!to') }); #line 48 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin::Match, 'orig-line', [], anon sub orig-line ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Origin::Match, '$!orig-line') }); #line 46 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin::Match, 'orig', [], anon sub orig ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Origin::Match, '$!orig') }); #line 47 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin::Match, 'line', [], anon sub line ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Origin::Match, '$!line') }); #line 49 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin::Match, 'from', [], anon sub from ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Origin::Match, '$!from') }); #line 45 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin::Match, 'file', [], anon sub file ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Origin::Match, '$!file') }); compose(RakuAST::Origin::Match); parent(RakuAST::Origin::Source, Any); add-attribute(RakuAST::Origin::Source, str, '$!orig'); add-attribute(RakuAST::Origin::Source, Mu, '$!line-ends'); add-attribute(RakuAST::Origin::Source, Mu, '$!line-file'); add-method(RakuAST::Origin::Source, 'new', [RakuAST::Origin::Source, '', 0, 0, str, '$orig', 1, 1], anon sub new ($SELF_CONT, :$orig?) { my $SELF := nqp::decont($SELF_CONT); $orig := nqp::decont($orig); #line 79 src/Raku/ast/origins.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Origin::Source, '$!orig', $orig); my $file := %*COMPILING<%?OPTIONS>; if !nqp::isconcrete($file) { if nqp::isnull($file := nqp::getlexdyn('$?FILES')) { $file := ''; } elsif !nqp::eqat($file,'/',0) && !nqp::eqat($file,'-',0) && !nqp::eqat($file,':',1) { $file := nqp::cwd ~ '/' ~ $file; } } nqp::bindattr($obj, RakuAST::Origin::Source, '$!line-file', nqp::list(nqp::list(0, 0, $file))); $obj.SETUP-LINE-POSITIONS(); $obj }); add-method(RakuAST::Origin::Source, 'SETUP-LINE-POSITIONS', [RakuAST::Origin::Source, '', 0, 0], anon sub SETUP-LINE-POSITIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 97 src/Raku/ast/origins.rakumod nqp::bindattr($SELF, RakuAST::Origin::Source, '$!line-ends', []); my int $nl-pos := 0; my int $total := nqp::chars(nqp::getattr_s($SELF, RakuAST::Origin::Source, '$!orig')); while ($nl-pos := nqp::findcclass(nqp::const::CCLASS_NEWLINE, nqp::getattr_s($SELF, RakuAST::Origin::Source, '$!orig'), $nl-pos, $total)) < $total { my $ord := nqp::ord(nqp::getattr_s($SELF, RakuAST::Origin::Source, '$!orig'), $nl-pos); nqp::push(nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-ends'), ++$nl-pos); # Treat \r\n as a single logical newline. Note that NFG # implementations, we should check it really is a lone \r, # not the first bit of a \r\n grapheme. if $ord == 13 && nqp::eqat(nqp::getattr_s($SELF, RakuAST::Origin::Source, '$!orig'), "\r", $nl-pos - 1) && $nl-pos < $total && nqp::ord(nqp::getattr_s($SELF, RakuAST::Origin::Source, '$!orig'), $nl-pos) == 10 { ++$nl-pos; } } }); add-method(RakuAST::Origin::Source, 'register-line-directive', [RakuAST::Origin::Source, '', 0, 0, int, '$orig-line', 0, 0, int, '$directive-line', 0, 0, Any, '$filename', 0, 0], anon sub register-line-directive ($SELF_CONT, $orig-line!, $directive-line!, $filename!) { my $SELF := nqp::decont($SELF_CONT); $orig-line := nqp::decont($orig-line); $directive-line := nqp::decont($directive-line); $filename := nqp::decont($filename); #line 115 src/Raku/ast/origins.rakumod my $registered := nqp::elems(nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')); # Make sure we're not trying to re-register an existing directive. This can happen when grammar retracts # and the same line directive gets parsed repeatedly. if $registered == 1 || nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')[$registered - 1][0] < $orig-line { if nqp::isconcrete($filename) { $filename := $filename.Str; } else { $filename := nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')[0][2]; } nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file').push([$orig-line, $directive-line - $orig-line - 1, $filename]); } }); add-method(RakuAST::Origin::Source, 'original-file', [RakuAST::Origin::Source, '', 0, 0], anon sub original-file ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 130 src/Raku/ast/origins.rakumod nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')[0][2] }); add-method(RakuAST::Origin::Source, 'original-line-column', [RakuAST::Origin::Source, '', 0, 0, int, '$pos', 0, 0], anon sub original-line-column ($SELF_CONT, $pos!) { my $SELF := nqp::decont($SELF_CONT); $pos := nqp::decont($pos); #line 134 src/Raku/ast/origins.rakumod my @line-ends := nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-ends'); my int $lo := 0; my int $hi := nqp::elems(@line-ends); my int $line; while $lo < $hi { $line := nqp::div_i(($lo + $hi), 2); if @line-ends[$line] > $pos { $hi := $line; } else { $lo := $line + 1; } } my $column := $lo == 0 ?? $pos !! ($pos - @line-ends[$lo - 1]); [$lo + 1, $column + 1] }); add-method(RakuAST::Origin::Source, 'original-line', [RakuAST::Origin::Source, '', 0, 0, int, '$pos', 0, 0], anon sub original-line ($SELF_CONT, $pos!) { my $SELF := nqp::decont($SELF_CONT); $pos := nqp::decont($pos); #line 152 src/Raku/ast/origins.rakumod $SELF.original-line-column($pos)[0] }); add-method(RakuAST::Origin::Source, 'location-of-pos', [RakuAST::Origin::Source, '', 0, 0, int, '$pos', 0, 0], anon sub location-of-pos ($SELF_CONT, $pos!) { my $SELF := nqp::decont($SELF_CONT); $pos := nqp::decont($pos); #line 157 src/Raku/ast/origins.rakumod my @orig-line-col := $SELF.original-line-column($pos); my $orig-line := @orig-line-col[0]; my $column := @orig-line-col[1]; my int $hi := nqp::elems(nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')); my int $lo := 0; my int $idx; while $lo < $hi { $idx := nqp::div_i($lo + $hi, 2); if nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')[$idx][0] > $orig-line { $hi := $idx; } else { $lo := $idx + 1; } } --$lo; [ $orig-line + nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')[$lo][1], $column, nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')[$lo][2] ] }); add-method(RakuAST::Origin::Source, 'file-of-pos', [RakuAST::Origin::Source, '', 0, 0, int, '$pos', 0, 0], anon sub file-of-pos ($SELF_CONT, $pos!) { my $SELF := nqp::decont($SELF_CONT); $pos := nqp::decont($pos); #line 177 src/Raku/ast/origins.rakumod return nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')[0][2] if nqp::elems(nqp::getattr($SELF, RakuAST::Origin::Source, '$!line-file')) == 1; $SELF.location-of-pos($pos)[2] }); add-method(RakuAST::Origin::Source, 'line-of-pos', [RakuAST::Origin::Source, '', 0, 0, int, '$pos', 0, 0], anon sub line-of-pos ($SELF_CONT, $pos!) { my $SELF := nqp::decont($SELF_CONT); $pos := nqp::decont($pos); #line 182 src/Raku/ast/origins.rakumod $SELF.location-of-pos($pos)[0] }); add-method(RakuAST::Origin::Source, 'column-of-pos', [RakuAST::Origin::Source, '', 0, 0, int, '$pos', 0, 0], anon sub column-of-pos ($SELF_CONT, $pos!) { my $SELF := nqp::decont($SELF_CONT); $pos := nqp::decont($pos); #line 186 src/Raku/ast/origins.rakumod $SELF.location-of-pos($pos)[1] }); add-method(RakuAST::Origin::Source, 'match-from', [RakuAST::Origin::Source, '', 0, 0, Any, '$from-to', 0, 0], anon sub match-from ($SELF_CONT, $from-to!) { my $SELF := nqp::decont($SELF_CONT); $from-to := nqp::decont($from-to); #line 191 src/Raku/ast/origins.rakumod my $from := $from-to.from(); my @location := $SELF.location-of-pos($from); RakuAST::Origin::Match.new( :from($from), :to($from-to.to()), :orig(nqp::getattr_s($SELF, RakuAST::Origin::Source, '$!orig')), :line(@location[0]), :file(@location[2]), :orig-line($SELF.original-line($from))) }); #line 70 src/Raku/ast/origins.rakumod add-method(RakuAST::Origin::Source, 'orig', [], anon sub orig ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Origin::Source, '$!orig') }); compose(RakuAST::Origin::Source); parent(RakuAST::Node, Any); add-attribute(RakuAST::Node, RakuAST::Origin, '$!origin'); add-method(RakuAST::Node, 'type', [RakuAST::Node, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 6 src/Raku/ast/base.rakumod Mu }); add-method(RakuAST::Node, 'pure', [RakuAST::Node, '', 0, 0], anon sub pure ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 10 src/Raku/ast/base.rakumod (Bool.WHO) }); add-method(RakuAST::Node, 'visit-children', [RakuAST::Node, '', 0, 0, Any, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 14 src/Raku/ast/base.rakumod # Default is that we have no children to visit. Nil }); add-method(RakuAST::Node, 'apply-sink', [RakuAST::Node, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub apply-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 20 src/Raku/ast/base.rakumod # If we are sunk and this is a sinkable node, apply that. if $is-sunk && nqp::istype($SELF, RakuAST::Sinkable) { $SELF.mark-sunk(); } # If this node knows how to propagate sinks itself, ask it to do so. if nqp::istype($SELF, RakuAST::SinkPropagator) { $SELF.propagate-sink($is-sunk); } # Otherwise, we assume it's a wanted child, and just walk its children, # unless it is a sink boundary. elsif !nqp::istype($SELF, RakuAST::SinkBoundary) { $SELF.visit-children: -> $child { $child.apply-sink((Bool.WHO)); } } }); add-method(RakuAST::Node, 'needs-sink-call', [RakuAST::Node, '', 0, 0], anon sub needs-sink-call ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 42 src/Raku/ast/base.rakumod (Bool.WHO) }); add-method(RakuAST::Node, 'can-be-bound-to', [RakuAST::Node, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 46 src/Raku/ast/base.rakumod (Bool.WHO) }); add-method(RakuAST::Node, 'resolve-all', [RakuAST::Node, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub resolve-all ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 50 src/Raku/ast/base.rakumod $SELF.IMPL-CHECK($resolver, $context, (Bool.WHO)); }); add-method(RakuAST::Node, 'set-origin', [RakuAST::Node, '', 0, 0, RakuAST::Origin, '$origin', 0, 0], anon sub set-origin ($SELF_CONT, $origin!) { my $SELF := nqp::decont($SELF_CONT); $origin := nqp::decont($origin); #line 54 src/Raku/ast/base.rakumod nqp::bindattr($SELF, RakuAST::Node, '$!origin', $origin); }); add-method(RakuAST::Node, 'locate-node', [RakuAST::Node, '', 0, 0, int, '$pos', 0, 0, int, '$to', 0, 1, Any, '$key', 1, 1], anon sub locate-node ($SELF_CONT, $pos!, $to?, :$key?) { my $SELF := nqp::decont($SELF_CONT); $pos := nqp::decont($pos); $to := nqp::decont($to); $key := nqp::decont($key); #line 59 src/Raku/ast/base.rakumod return Nil unless nqp::isconcrete(nqp::getattr($SELF, RakuAST::Node, '$!origin')) && $pos >= nqp::getattr($SELF, RakuAST::Node, '$!origin').from && $pos < nqp::getattr($SELF, RakuAST::Node, '$!origin').to && (!nqp::isconcrete($to) || $to <= nqp::getattr($SELF, RakuAST::Node, '$!origin').to); if $key && !nqp::getattr($SELF, RakuAST::Node, '$!origin').is-key { nqp::die("Only a key node can search for key nodes") } if $key { my @nestings := nqp::getattr($SELF, RakuAST::Node, '$!origin').nestings; for @nestings { my $cand := $_.locate-node($pos, $to, :key); return $cand if nqp::isconcrete($cand); } } else { $SELF.visit-children(-> $child { my $cand := $child.locate-node($pos, $to); return $cand if nqp::isconcrete($cand); }); } # If no nested key node gave a match then we are the one. $SELF }); add-method(RakuAST::Node, 'IMPL-CHECK', [RakuAST::Node, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Bool, '$resolve-only', 0, 0], anon sub IMPL-CHECK ($SELF_CONT, $resolver!, $context!, $resolve-only!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $resolve-only := nqp::decont($resolve-only); #line 85 src/Raku/ast/base.rakumod # Perform resolutions. if nqp::istype($SELF, RakuAST::Lookup) && !$SELF.is-resolved { $SELF.resolve-with($resolver); if !$resolve-only && !$SELF.is-resolved && $SELF.needs-resolution { $resolver.add-node-unresolved-after-check-time($SELF); } } if nqp::istype($SELF, RakuAST::ImplicitLookups) { $SELF.resolve-implicit-lookups-with($resolver); } if nqp::istype($SELF, RakuAST::Attaching) { $SELF.attach($resolver); } if nqp::istype($SELF, RakuAST::ImplicitBlockSemanticsProvider) { $SELF.apply-implicit-block-semantics(); } # Apply any pre-children BEGIN-time effects that were not yet # performed (and figure out if we have to do the later). my int $needs-begin-after := nqp::istype($SELF, RakuAST::BeginTime) && $SELF.is-begin-performed-after-children(); if nqp::istype($SELF, RakuAST::BeginTime) && $SELF.is-begin-performed-before-children() { $SELF.ensure-begin-performed($resolver, $context, :phase(1)); } # Visit children. But don't run CHECK yet if this will be followed by more BEGIN handling my int $is-scope := nqp::istype($SELF, RakuAST::LexicalScope); my int $is-package := nqp::istype($SELF, RakuAST::Package); $resolver.push-scope($SELF) if $is-scope; $resolver.push-package($SELF) if $is-package; $SELF.visit-children(-> $child { $child.IMPL-CHECK($resolver, $context, $resolve-only || $needs-begin-after) }); $resolver.pop-scope() if $is-scope; $resolver.pop-package() if $is-package; # Perform any after-children BEGIN-time effects. if $needs-begin-after { $SELF.ensure-begin-performed($resolver, $context, :phase(2)); } # Unless in resolve-only mode, do other check-time activities. unless $resolve-only { if $needs-begin-after { # Run children's CHECK processing. Couldn't do it earlier as # that would have interfered with our BEGIN handling. $resolver.push-scope($SELF) if $is-scope; $resolver.push-package($SELF) if $is-package; $SELF.visit-children(-> $child { $child.IMPL-CHECK($resolver, $context, $resolve-only) }); $resolver.pop-scope() if $is-scope; $resolver.pop-package() if $is-package; } if nqp::istype($SELF, RakuAST::SinkBoundary) && !$SELF.sink-calculated { $SELF.calculate-sink(); } if nqp::istype($SELF, RakuAST::CheckTime) { $SELF.clear-check-time-problems(); $SELF.PERFORM-CHECK($resolver, $context); if $SELF.has-check-time-problems { $resolver.add-node-with-check-time-problems($SELF); } } } Nil }); add-method(RakuAST::Node, 'find-nodes', [RakuAST::Node, '', 0, 0, Mu, '$type', 0, 0, Code, '$condition', 1, 1, Mu, '$stopper', 1, 1], anon sub find-nodes ($SELF_CONT, $type!, :$condition?, :$stopper?) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); $condition := nqp::decont($condition); $stopper := nqp::decont($stopper); #line 156 src/Raku/ast/base.rakumod # Walk the tree searching for matching nodes. my int $have-stopper := !nqp::eqaddr($stopper, Mu); my @visit-queue := [$SELF]; my @result; my $collector := sub collector($node) { if nqp::istype($node, $type) { unless $condition && !$condition($node) { nqp::push(@result, $node); } } unless $have-stopper && nqp::istype($node, $stopper) { nqp::push(@visit-queue, $node); } } while @visit-queue { nqp::shift(@visit-queue).visit-children($collector); } $SELF.IMPL-WRAP-LIST(@result) }); add-method(RakuAST::Node, 'find-nodes-exclusive', [RakuAST::Node, '', 0, 0, Mu, '$type', 0, 0, Code, '$condition', 1, 1, Code, '$stopper', 1, 1], anon sub find-nodes-exclusive ($SELF_CONT, $type!, :$condition?, :$stopper?) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); $condition := nqp::decont($condition); $stopper := nqp::decont($stopper); #line 184 src/Raku/ast/base.rakumod # Walk the tree searching for matching nodes.; my @visit-queue := [$SELF]; my @result; my $collector := sub collector($node) { if nqp::isconcrete($stopper) { my $do-stop := $stopper($node); if nqp::istype($node, $type) && !$do-stop { unless $condition && !$condition($node) { nqp::push(@result, $node); } } unless $do-stop { nqp::push(@visit-queue, $node) } } else { if nqp::istype($node, $type) { unless $condition && !$condition($node) { nqp::push(@result, $node); } } nqp::push(@visit-queue, $node); } } while @visit-queue { nqp::shift(@visit-queue).visit-children($collector); } $SELF.IMPL-WRAP-LIST(@result) }); add-method(RakuAST::Node, 'visit', [RakuAST::Node, '', 0, 0, Code, '$callback', 0, 0, Bool, '$strict', 1, 1], anon sub visit ($SELF_CONT, $callback!, :$strict?) { my $SELF := nqp::decont($SELF_CONT); $callback := nqp::decont($callback); $strict := nqp::decont($strict); #line 218 src/Raku/ast/base.rakumod my @visit-queue; if $strict || $callback($SELF) { @visit-queue[0] := $SELF; } my $visitor := -> $node { if $callback($node) { nqp::push(@visit-queue, $node); } } while @visit-queue { nqp::shift(@visit-queue).visit-children($visitor); } Nil }); add-method(RakuAST::Node, 'visit-dfs', [RakuAST::Node, '', 0, 0, Code, '$callback', 0, 0, Bool, '$strict', 1, 1], anon sub visit-dfs ($SELF_CONT, $callback!, :$strict?) { my $SELF := nqp::decont($SELF_CONT); $callback := nqp::decont($callback); $strict := nqp::decont($strict); #line 234 src/Raku/ast/base.rakumod my $visitor; $visitor := -> $node { if $callback($node) { $node.visit-children($visitor); } } $SELF.visit-children($visitor) if $strict || $callback($SELF); Nil }); add-method(RakuAST::Node, 'IMPL-CAN-INTERPRET', [RakuAST::Node, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 245 src/Raku/ast/base.rakumod (Bool.WHO) }); add-method(RakuAST::Node, 'IMPL-INTERPRET', [RakuAST::Node, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 247 src/Raku/ast/base.rakumod nqp::die('Missing IMPL-INTERPRET implementation on ' ~ $SELF.HOW.name($SELF)) }); add-method(RakuAST::Node, 'IMPL-WRAP-LIST', [RakuAST::Node, '', 0, 0, Mu, '$vm-array', 0, 0], anon sub IMPL-WRAP-LIST ($SELF_CONT, $vm-array!) { my $SELF := nqp::decont($SELF_CONT); $vm-array := nqp::decont($vm-array); #line 251 src/Raku/ast/base.rakumod if nqp::istype($vm-array, List) { # It already is a list $vm-array } else { my $result := nqp::create(List); nqp::bindattr($result, List, '$!reified', $vm-array); $result } }); add-method(RakuAST::Node, 'IMPL-UNWRAP-LIST', [RakuAST::Node, '', 0, 0, Mu, '$list', 0, 0], anon sub IMPL-UNWRAP-LIST ($SELF_CONT, $list!) { my $SELF := nqp::decont($SELF_CONT); $list := nqp::decont($list); #line 263 src/Raku/ast/base.rakumod if nqp::islist($list) { # Wasn't wrapped anyway $list } elsif nqp::istype($list, List) { my $reified := nqp::getattr($list, List, '$!reified'); nqp::isconcrete($reified) ?? $reified !! $list.FLATTENABLE_LIST } else { nqp::list($list) } }); add-method(RakuAST::Node, 'IMPL-WRAP-MAP', [RakuAST::Node, '', 0, 0, Mu, '$vm-hash', 0, 0], anon sub IMPL-WRAP-MAP ($SELF_CONT, $vm-hash!) { my $SELF := nqp::decont($SELF_CONT); $vm-hash := nqp::decont($vm-hash); #line 279 src/Raku/ast/base.rakumod if nqp::istype($vm-hash, Map) { # It already is a map $vm-hash } else { my $result := nqp::create(Map); nqp::bindattr($result, Map, '$!storage', $vm-hash); $result } }); add-method(RakuAST::Node, 'IMPL-UNWRAP-MAP', [RakuAST::Node, '', 0, 0, Mu, '$map', 0, 0], anon sub IMPL-UNWRAP-MAP ($SELF_CONT, $map!) { my $SELF := nqp::decont($SELF_CONT); $map := nqp::decont($map); #line 291 src/Raku/ast/base.rakumod if nqp::ishash($map) { # Wasn't wrapped anyway $map } elsif nqp::istype($map, Map) { my $storage := nqp::getattr($map, Map, '$!storage'); nqp::isconcrete($storage) ?? $storage !! $map.FLATTENABLE_HASH } else { nqp::die("Cannot hashify " ~ $map.HOW.name($map)); } }); add-method(RakuAST::Node, 'dump-markers', [RakuAST::Node, '', 0, 0], anon sub dump-markers ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 307 src/Raku/ast/base.rakumod my @markers; @markers.push('⚓') if nqp::istype($SELF, RakuAST::Sinkable) && $SELF.sunk; @markers.push('▪') if nqp::istype($SELF, RakuAST::BlockStatementSensitive) && $SELF.is-block-statement; if nqp::isconcrete(nqp::getattr($SELF, RakuAST::Node, '$!origin')) { @markers.push('𝄞') if nqp::getattr($SELF, RakuAST::Node, '$!origin').is-key(); } nqp::join('', @markers) }); add-method(RakuAST::Node, 'dump-extras', [RakuAST::Node, '', 0, 0, int, '$indent', 0, 0], anon sub dump-extras ($SELF_CONT, $indent!) { my $SELF := nqp::decont($SELF_CONT); $indent := nqp::decont($indent); #line 320 src/Raku/ast/base.rakumod '' }); add-method(RakuAST::Node, 'dump-children', [RakuAST::Node, '', 0, 0, int, '$indent', 0, 0], anon sub dump-children ($SELF_CONT, $indent!) { my $SELF := nqp::decont($SELF_CONT); $indent := nqp::decont($indent); #line 322 src/Raku/ast/base.rakumod my @chunks; $SELF.visit-children(-> $child { @chunks.push($child.dump($indent)); }); nqp::join('', @chunks) }); add-method(RakuAST::Node, 'dump-origin', [RakuAST::Node, '', 0, 0], anon sub dump-origin ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 330 src/Raku/ast/base.rakumod my @chunks; if nqp::isconcrete(nqp::getattr($SELF, RakuAST::Node, '$!origin')) { my $from := nqp::getattr($SELF, RakuAST::Node, '$!origin').from; my $orig-source := nqp::getattr($SELF, RakuAST::Node, '$!origin').source; if nqp::getattr($SELF, RakuAST::Node, '$!origin').is-key { my @location := $orig-source.location-of-pos($from); @chunks.push(@location[2] ~ ':' ~ @location[0]); } my $src := nqp::escape(nqp::substr($orig-source.orig, $from, nqp::getattr($SELF, RakuAST::Node, '$!origin').to - $from)); if nqp::chars($src) > 50 { $src := nqp::substr($src, 0, 49) ~ '…'; } @chunks.push(' ⎡'); @chunks.push($src ~ '⎤'); } nqp::join('', @chunks) }); add-method(RakuAST::Node, 'dump', [RakuAST::Node, '', 0, 0, int, '$indent', 0, 1], anon sub dump ($SELF_CONT, $indent?) { my $SELF := nqp::decont($SELF_CONT); $indent := nqp::decont($indent); #line 350 src/Raku/ast/base.rakumod my @chunks := [ nqp::x(' ', $indent), nqp::substr($SELF.HOW.name($SELF), nqp::chars('RakuAST::')) ]; if (my $markers := $SELF.dump-markers()) { @chunks.push(' ' ~ $markers); } if (my $origin := $SELF.dump-origin()) { @chunks.push(' ' ~ $origin); } @chunks.push("\n"); if (my $extras := $SELF.dump-extras($indent + 2)) { @chunks.push($extras); } if (my $children := $SELF.dump-children($indent + 2)) { @chunks.push($children); } nqp::join('', @chunks) }); add-method(RakuAST::Node, 'mixin-role', [RakuAST::Node, '', 0, 0, Any, '$base', 0, 0, Any, '$role', 0, 0], anon sub mixin-role ($SELF_CONT, $base!, $role!) { my $SELF := nqp::decont($SELF_CONT); $base := nqp::decont($base); $role := nqp::decont($role); #line 374 src/Raku/ast/base.rakumod my $class := nqp::clone($base); $class.HOW.mixin($class, $role).BUILD_LEAST_DERIVED({}) }); add-method(RakuAST::Node, 'DEPARSE', [RakuAST::Node, '', 0, 0, Any, '@roles', 0, 0], anon sub DEPARSE ($SELF_CONT, *@roles) { my $SELF := nqp::decont($SELF_CONT); @roles := nqp::decont(@roles); #line 381 src/Raku/ast/base.rakumod my $class := my $core := nqp::gethllsym('Raku','DEPARSE'); for @roles { if $_.HOW.name($_) eq 'Str' { # XXX better way to detect HLL Str? $class := $SELF.mixin-role($class, $core.slang($_)); } elsif nqp::can($_.HOW,'pun') { # it's a role $class := $SELF.mixin-role($class, $_); } else { $class := $_; } } $class.deparse($SELF) }); add-method(RakuAST::Node, 'IMPL-SORTED-KEYS', [RakuAST::Node, '', 0, 0, Mu, '$hash', 0, 0], anon sub IMPL-SORTED-KEYS ($SELF_CONT, $hash!) { my $SELF := nqp::decont($SELF_CONT); $hash := nqp::decont($hash); #line 398 src/Raku/ast/base.rakumod # Due to these classes being pieced together at compile time we can't # reach the sorted_hash sub in the NQP setting, so it's copied here. my @keys; for $hash { nqp::push(@keys, $_.key); } my int $count := +@keys; my int $start := $count / 2 - 1; while $start >= 0 { $SELF.IMPL-SIFT-DOWN(@keys, $start, $count - 1); $start := $start - 1; } my int $end := +@keys - 1; while $end > 0 { my str $swap := @keys[$end]; @keys[$end] := @keys[0]; @keys[0] := $swap; $end := $end - 1; $SELF.IMPL-SIFT-DOWN(@keys, 0, $end); } return @keys; }); add-method(RakuAST::Node, 'IMPL-SIFT-DOWN', [RakuAST::Node, '', 0, 0, Mu, '$a', 0, 0, int, '$start', 0, 0, int, '$end', 0, 0], anon sub IMPL-SIFT-DOWN ($SELF_CONT, $a!, $start!, $end!) { my $SELF := nqp::decont($SELF_CONT); $a := nqp::decont($a); $start := nqp::decont($start); $end := nqp::decont($end); #line 425 src/Raku/ast/base.rakumod my @a := $a; my int $root := $start; while 2*$root + 1 <= $end { my $child := 2*$root + 1; my $swap := $root; if @a[$swap] gt @a[$child] { $swap := $child; } if $child + 1 <= $end && @a[$swap] ge @a[$child + 1] { $swap := $child + 1; } if $swap == $root { return; } else { my str $tmp := @a[$root]; @a[$root] := @a[$swap]; @a[$swap] := $tmp; $root := $swap; } } }); add-method(RakuAST::Node, 'IMPL-TEMPORARIZE-TOPIC', [RakuAST::Node, '', 0, 0, Mu, '$new-topic-qast', 0, 0, Mu, '$with-topic-qast', 0, 0], anon sub IMPL-TEMPORARIZE-TOPIC ($SELF_CONT, $new-topic-qast!, $with-topic-qast!) { my $SELF := nqp::decont($SELF_CONT); $new-topic-qast := nqp::decont($new-topic-qast); $with-topic-qast := nqp::decont($with-topic-qast); #line 450 src/Raku/ast/base.rakumod my $temporary := QAST::Node.unique('save_topic'); QAST::Stmt.new( :resultchild(2), QAST::Op.new( :op('bind'), QAST::Var.new( :name($temporary), :scope('local'), :decl('var') ), QAST::Var.new( :name('$_'), :scope('lexical') ) ), QAST::Op.new( :op('bind'), QAST::Var.new( :name('$_'), :scope('lexical') ), $new-topic-qast ), $with-topic-qast, QAST::Op.new( :op('bind'), QAST::Var.new( :name('$_'), :scope('lexical') ), QAST::Var.new( :name($temporary), :scope('local') ) ) ) }); add-method(RakuAST::Node, 'IMPL-SET-NODE', [RakuAST::Node, '', 0, 0, Mu, '$qast', 0, 0, Any, '$key', 1, 1], anon sub IMPL-SET-NODE ($SELF_CONT, $qast!, :$key?) { my $SELF := nqp::decont($SELF_CONT); $qast := nqp::decont($qast); $key := nqp::decont($key); #line 478 src/Raku/ast/base.rakumod my $orig := $SELF.origin; if nqp::isconcrete($orig) { if $key && !$orig.is-key { my $comp-unit := $*CU; if nqp::isconcrete($comp-unit) { my $key-node := $comp-unit.locate-node($orig.from, $orig.to, :key); $orig := $key-node.origin if nqp::isconcrete($key-node); } } $qast.node($orig.as-match); } $qast }); #line 3 src/Raku/ast/base.rakumod add-method(RakuAST::Node, 'origin', [], anon sub origin ($self) { nqp::getattr(nqp::decont($self), RakuAST::Node, '$!origin') }); compose(RakuAST::Node); parent(RakuAST::CompileTimeValue, RakuAST::Node); add-method(RakuAST::CompileTimeValue, 'compile-time-value', [RakuAST::CompileTimeValue, '', 0, 0], anon sub compile-time-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 498 src/Raku/ast/base.rakumod nqp::die('compile-time-value not implemented for ' ~ $SELF.HOW.name($SELF)) }); compose(RakuAST::CompileTimeValue); parent(RakuAST::CheckTime, RakuAST::Node); add-attribute(RakuAST::CheckTime, Mu, '$!sorries'); add-attribute(RakuAST::CheckTime, Mu, '$!worries'); add-method(RakuAST::CheckTime, 'clear-check-time-problems', [RakuAST::CheckTime, '', 0, 0], anon sub clear-check-time-problems ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 12 src/Raku/ast/checktime.rakumod nqp::bindattr($SELF, RakuAST::CheckTime, '$!sorries', Mu); nqp::bindattr($SELF, RakuAST::CheckTime, '$!worries', Mu); Nil }); add-method(RakuAST::CheckTime, 'has-check-time-problems', [RakuAST::CheckTime, '', 0, 0], anon sub has-check-time-problems ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 20 src/Raku/ast/checktime.rakumod nqp::getattr($SELF, RakuAST::CheckTime, '$!sorries') || nqp::getattr($SELF, RakuAST::CheckTime, '$!worries') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::CheckTime, 'sorries', [RakuAST::CheckTime, '', 0, 0], anon sub sorries ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 25 src/Raku/ast/checktime.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::CheckTime, '$!sorries') // []) }); add-method(RakuAST::CheckTime, 'worries', [RakuAST::CheckTime, '', 0, 0], anon sub worries ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 30 src/Raku/ast/checktime.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::CheckTime, '$!worries') // []) }); add-method(RakuAST::CheckTime, 'add-sorry', [RakuAST::CheckTime, '', 0, 0, Any, '$exception', 0, 0], anon sub add-sorry ($SELF_CONT, $exception!) { my $SELF := nqp::decont($SELF_CONT); $exception := nqp::decont($exception); #line 36 src/Raku/ast/checktime.rakumod nqp::push( nqp::getattr($SELF, RakuAST::CheckTime, '$!sorries') // nqp::bindattr($SELF,RakuAST::CheckTime,'$!sorries',[]), $exception ); Nil }); add-method(RakuAST::CheckTime, 'add-worry', [RakuAST::CheckTime, '', 0, 0, Any, '$exception', 0, 0], anon sub add-worry ($SELF_CONT, $exception!) { my $SELF := nqp::decont($SELF_CONT); $exception := nqp::decont($exception); #line 46 src/Raku/ast/checktime.rakumod nqp::push( nqp::getattr($SELF, RakuAST::CheckTime, '$!worries') // nqp::bindattr($SELF,RakuAST::CheckTime,'$!worries',[]), $exception ); Nil }); add-method(RakuAST::CheckTime, 'PERFORM-CHECK', [RakuAST::CheckTime, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 56 src/Raku/ast/checktime.rakumod nqp::die('Missing PERFORM-CHECK implementation for ' ~ $SELF.HOW.name($SELF)); }); compose(RakuAST::CheckTime); parent(RakuAST::SinkBoundary, RakuAST::Node); add-attribute(RakuAST::SinkBoundary, int, '$!sink-calculated'); add-method(RakuAST::SinkBoundary, 'calculate-sink', [RakuAST::SinkBoundary, '', 0, 0], anon sub calculate-sink ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 11 src/Raku/ast/sink.rakumod unless nqp::getattr_i($SELF, RakuAST::SinkBoundary, '$!sink-calculated') { $SELF.get-boundary-sink-propagator().propagate-sink($SELF.is-boundary-sunk(), :has-block-parent); nqp::bindattr_i($SELF, RakuAST::SinkBoundary, '$!sink-calculated', 1); } Nil }); add-method(RakuAST::SinkBoundary, 'sink-calculated', [RakuAST::SinkBoundary, '', 0, 0], anon sub sink-calculated ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 20 src/Raku/ast/sink.rakumod nqp::getattr_i($SELF, RakuAST::SinkBoundary, '$!sink-calculated') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::SinkBoundary, 'is-boundary-sunk', [RakuAST::SinkBoundary, '', 0, 0], anon sub is-boundary-sunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 29 src/Raku/ast/sink.rakumod nqp::die('Missing is-boundary-sunk implementation') }); add-method(RakuAST::SinkBoundary, 'get-boundary-sink-propagator', [RakuAST::SinkBoundary, '', 0, 0], anon sub get-boundary-sink-propagator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 34 src/Raku/ast/sink.rakumod nqp::die('Missing get-boundary-sink-propagator implementation') }); compose(RakuAST::SinkBoundary); parent(RakuAST::SinkPropagator, RakuAST::Node); add-method(RakuAST::SinkPropagator, 'propagate-sink', [RakuAST::SinkPropagator, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 45 src/Raku/ast/sink.rakumod nqp::die('Missing propagate-sink'); }); compose(RakuAST::SinkPropagator); parent(RakuAST::Sinkable, RakuAST::Node); add-attribute(RakuAST::Sinkable, int, '$!sunk'); add-method(RakuAST::Sinkable, 'mark-sunk', [RakuAST::Sinkable, '', 0, 0], anon sub mark-sunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 57 src/Raku/ast/sink.rakumod nqp::bindattr_i($SELF, RakuAST::Sinkable, '$!sunk', 1); }); add-method(RakuAST::Sinkable, 'sunk', [RakuAST::Sinkable, '', 0, 0], anon sub sunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 61 src/Raku/ast/sink.rakumod nqp::getattr_i($SELF, RakuAST::Sinkable, '$!sunk') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Sinkable, 'needs-sink-call', [RakuAST::Sinkable, '', 0, 0], anon sub needs-sink-call ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 65 src/Raku/ast/sink.rakumod (Bool.WHO) }); compose(RakuAST::Sinkable); parent(RakuAST::BlockStatementSensitive, RakuAST::Node); add-attribute(RakuAST::BlockStatementSensitive, int, '$!block-statement'); add-method(RakuAST::BlockStatementSensitive, 'mark-block-statement', [RakuAST::BlockStatementSensitive, '', 0, 0], anon sub mark-block-statement ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 76 src/Raku/ast/sink.rakumod nqp::bindattr_i($SELF, RakuAST::BlockStatementSensitive, '$!block-statement', 1); }); add-method(RakuAST::BlockStatementSensitive, 'is-block-statement', [RakuAST::BlockStatementSensitive, '', 0, 0], anon sub is-block-statement ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 80 src/Raku/ast/sink.rakumod nqp::getattr_i($SELF, RakuAST::BlockStatementSensitive, '$!block-statement') ?? (Bool.WHO) !! (Bool.WHO) }); compose(RakuAST::BlockStatementSensitive); parent(RakuAST::LexicalScope, RakuAST::CheckTime); parent(RakuAST::LexicalScope, RakuAST::Node); add-attribute(RakuAST::LexicalScope, List, '$!declarations-cache'); add-attribute(RakuAST::LexicalScope, Mu, '$!lexical-lookup-hash'); add-attribute(RakuAST::LexicalScope, List, '$!variables-cache'); add-attribute(RakuAST::LexicalScope, Mu, '$!generated-lexical-declarations'); add-attribute(RakuAST::LexicalScope, Mu, '$!generated-lexical-lookup-hash'); add-attribute(RakuAST::LexicalScope, int, '$!need-succeed-handler'); add-attribute(RakuAST::LexicalScope, Mu, '$!catch-handlers'); add-attribute(RakuAST::LexicalScope, Mu, '$!control-handlers'); add-method(RakuAST::LexicalScope, 'IMPL-QAST-DECLS', [RakuAST::LexicalScope, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECLS ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 22 src/Raku/ast/scoping.rakumod my $stmts := QAST::Stmts.new(); # Visit code objects that need to make a declaration entry. We don't # visit any code objects immediately under an ImmediateBlockUser (but # should visit their other nodes). my @code-todo := [$SELF]; while @code-todo { my $visit := @code-todo.shift; $visit.visit-children: -> $node { if nqp::istype($node, RakuAST::Code) { unless nqp::istype($visit, RakuAST::IMPL::ImmediateBlockUser) && $visit.IMPL-IMMEDIATELY-USES($node) { $stmts.push($node.IMPL-QAST-DECL-CODE($context)); } } elsif nqp::istype($node, RakuAST::Expression) { $node.IMPL-QAST-ADD-THUNK-DECL-CODE($context, $stmts); } unless nqp::istype($node, RakuAST::LexicalScope) { @code-todo.push($node); } } } # Visit declarations and produce declaration QAST. for $SELF.IMPL-UNWRAP-LIST($SELF.generated-lexical-declarations()) { $stmts.unshift($_.IMPL-QAST-DECL($context)) unless $_ =:= $SELF; } for $SELF.IMPL-UNWRAP-LIST($SELF.ast-lexical-declarations()) { $stmts.unshift($_.IMPL-QAST-DECL($context)) unless $_ =:= $SELF; } # If there's handler block declarations, add those. if nqp::getattr($SELF, RakuAST::LexicalScope, '$!catch-handlers') { $stmts.push(QAST::Op.new( :op('bind'), QAST::Var.new( :decl('var'), :name('__CATCH_HANDLER'), :scope('lexical') ), nqp::getattr($SELF, RakuAST::LexicalScope, '$!catch-handlers')[0].body.IMPL-CLOSURE-QAST($context) )); } if nqp::getattr($SELF, RakuAST::LexicalScope, '$!control-handlers') { $stmts.push(QAST::Op.new( :op('bind'), QAST::Var.new( :decl('var'), :name('__CONTROL_HANDLER'), :scope('lexical') ), nqp::getattr($SELF, RakuAST::LexicalScope, '$!control-handlers')[0].body.IMPL-CLOSURE-QAST($context) )); } $stmts }); add-method(RakuAST::LexicalScope, 'ast-lexical-declarations', [RakuAST::LexicalScope, '', 0, 0], anon sub ast-lexical-declarations ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 78 src/Raku/ast/scoping.rakumod unless nqp::isconcrete(nqp::getattr($SELF, RakuAST::LexicalScope, '$!declarations-cache')) { my @declarations; my @variables; $SELF.visit-dfs: -> $node { if nqp::istype($node, RakuAST::Declaration) && $node.is-simple-lexical-declaration { nqp::push(@declarations, $node); nqp::push(@variables, $node) unless nqp::istype($node, RakuAST::Routine); } elsif nqp::istype($node, RakuAST::Var::Lexical) || nqp::istype($node, RakuAST::Var::Dynamic) { nqp::push(@variables, $node); } if $node =:= $SELF || !nqp::istype($node, RakuAST::LexicalScope) { if nqp::istype($node, RakuAST::ImplicitDeclarations) { for $SELF.IMPL-UNWRAP-LIST($node.get-implicit-declarations()) -> $decl { if $decl.is-simple-lexical-declaration { nqp::push(@declarations, $decl); nqp::push(@variables, $decl); } } } 1 # visit children } else { 0 # it's an inner scope, don't visit its children } } nqp::bindattr($SELF, RakuAST::LexicalScope, '$!declarations-cache', @declarations); nqp::bindattr($SELF, RakuAST::LexicalScope, '$!variables-cache', @variables); } nqp::getattr($SELF, RakuAST::LexicalScope, '$!declarations-cache') }); add-method(RakuAST::LexicalScope, 'generated-lexical-declarations', [RakuAST::LexicalScope, '', 0, 0], anon sub generated-lexical-declarations ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 113 src/Raku/ast/scoping.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-declarations') // []) }); add-method(RakuAST::LexicalScope, 'lexical-declarations', [RakuAST::LexicalScope, '', 0, 0], anon sub lexical-declarations ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 117 src/Raku/ast/scoping.rakumod my $declarations := nqp::clone($SELF.IMPL-UNWRAP-LIST($SELF.ast-lexical-declarations)); for (nqp::getattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-declarations') // []) { nqp::push($declarations, $_); } $SELF.IMPL-WRAP-LIST($declarations) }); add-method(RakuAST::LexicalScope, 'add-generated-lexical-declaration', [RakuAST::LexicalScope, '', 0, 0, RakuAST::Declaration, '$declaration', 0, 0], anon sub add-generated-lexical-declaration ($SELF_CONT, $declaration!) { my $SELF := nqp::decont($SELF_CONT); $declaration := nqp::decont($declaration); #line 126 src/Raku/ast/scoping.rakumod unless nqp::getattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-declarations') { nqp::bindattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-declarations', []); } nqp::push(nqp::getattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-declarations'), $declaration); nqp::bindattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-lookup-hash', Mu); Nil }); add-method(RakuAST::LexicalScope, 'merge-generated-lexical-declaration', [RakuAST::LexicalScope, '', 0, 0, RakuAST::Declaration, '$declaration', 0, 0, RakuAST::Resolver, '$resolver', 1, 0], anon sub merge-generated-lexical-declaration ($SELF_CONT, $declaration!, :$resolver!) { my $SELF := nqp::decont($SELF_CONT); $declaration := nqp::decont($declaration); $resolver := nqp::decont($resolver); #line 135 src/Raku/ast/scoping.rakumod unless nqp::getattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-declarations') { nqp::bindattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-declarations', []); } for nqp::getattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-declarations') { if ($_.lexical-name // '') eq $declaration.lexical-name { if $_.compile-time-value =:= $declaration.compile-time-value { return Nil } else { $_.merge($declaration, :$resolver); return; } } } nqp::push(nqp::getattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-declarations'), $declaration); nqp::bindattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-lookup-hash', Mu); Nil }); add-method(RakuAST::LexicalScope, 'find-ast-lexical', [RakuAST::LexicalScope, '', 0, 0, Str, '$name', 0, 0], anon sub find-ast-lexical ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 157 src/Raku/ast/scoping.rakumod my %lookup := nqp::getattr($SELF, RakuAST::LexicalScope, '$!lexical-lookup-hash'); unless nqp::isconcrete(%lookup) { %lookup := {}; for $SELF.IMPL-UNWRAP-LIST($SELF.ast-lexical-declarations) { %lookup{$_.lexical-name} := $_; } nqp::bindattr($SELF, RakuAST::LexicalScope, '$!lexical-lookup-hash', %lookup); } %lookup{$name} // Nil }); add-method(RakuAST::LexicalScope, 'find-generated-lexical', [RakuAST::LexicalScope, '', 0, 0, Str, '$name', 0, 0], anon sub find-generated-lexical ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 171 src/Raku/ast/scoping.rakumod my %lookup := nqp::getattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-lookup-hash'); unless nqp::isconcrete(%lookup) { %lookup := {}; for $SELF.IMPL-UNWRAP-LIST($SELF.generated-lexical-declarations) { my $lexical-name := $_.lexical-name; %lookup{$lexical-name} := $_ if $lexical-name; } nqp::bindattr($SELF, RakuAST::LexicalScope, '$!generated-lexical-lookup-hash', %lookup); } %lookup{$name} // Nil }); add-method(RakuAST::LexicalScope, 'find-lexical', [RakuAST::LexicalScope, '', 0, 0, Str, '$name', 0, 0], anon sub find-lexical ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 187 src/Raku/ast/scoping.rakumod $SELF.find-ast-lexical($name) // $SELF.find-generated-lexical($name) }); add-method(RakuAST::LexicalScope, 'require-succeed-handler', [RakuAST::LexicalScope, '', 0, 0], anon sub require-succeed-handler ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 191 src/Raku/ast/scoping.rakumod nqp::bindattr_i($SELF, RakuAST::LexicalScope, '$!need-succeed-handler', 1); Nil }); add-method(RakuAST::LexicalScope, 'attach-catch-handler', [RakuAST::LexicalScope, '', 0, 0, RakuAST::Statement::Catch, '$catch', 0, 0], anon sub attach-catch-handler ($SELF_CONT, $catch!) { my $SELF := nqp::decont($SELF_CONT); $catch := nqp::decont($catch); #line 196 src/Raku/ast/scoping.rakumod if nqp::getattr($SELF, RakuAST::LexicalScope, '$!catch-handlers') { nqp::push(nqp::getattr($SELF, RakuAST::LexicalScope, '$!catch-handlers'), $catch); } else { nqp::bindattr($SELF, RakuAST::LexicalScope, '$!catch-handlers', [$catch]); } Nil }); add-method(RakuAST::LexicalScope, 'attach-control-handler', [RakuAST::LexicalScope, '', 0, 0, RakuAST::Statement::Control, '$control', 0, 0], anon sub attach-control-handler ($SELF_CONT, $control!) { my $SELF := nqp::decont($SELF_CONT); $control := nqp::decont($control); #line 206 src/Raku/ast/scoping.rakumod if nqp::getattr($SELF, RakuAST::LexicalScope, '$!control-handlers') { nqp::push(nqp::getattr($SELF, RakuAST::LexicalScope, '$!control-handlers'), $control); } else { nqp::bindattr($SELF, RakuAST::LexicalScope, '$!control-handlers', [$control]); } Nil }); add-method(RakuAST::LexicalScope, 'PERFORM-CHECK', [RakuAST::LexicalScope, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 216 src/Raku/ast/scoping.rakumod my %lookup; for $SELF.IMPL-UNWRAP-LIST($SELF.generated-lexical-declarations) { my $lexical-name := $_.lexical-name; if $lexical-name { if nqp::existskey(%lookup, $lexical-name) { $SELF.add-sorry: $resolver.build-exception: 'X::Redeclaration', :symbol($lexical-name); } else { %lookup{$lexical-name} := $_; } } } for $SELF.IMPL-UNWRAP-LIST($SELF.ast-lexical-declarations) { my $lexical-name := $_.lexical-name; if $lexical-name && ! $_ =:= $SELF { if nqp::existskey(%lookup, $lexical-name) { $SELF.add-sorry: $resolver.build-exception: 'X::Redeclaration', :symbol($lexical-name); } else { %lookup{$lexical-name} := $_; } } } # Check for variables that are declared after they have already been used. # That's possible with dynamics and with variables also declared in outer scope. my %declarations; while nqp::getattr($SELF, RakuAST::LexicalScope, '$!variables-cache') { my $var := nqp::pop(nqp::getattr($SELF, RakuAST::LexicalScope, '$!variables-cache')); if nqp::istype($var, RakuAST::Declaration) { %declarations{$var.lexical-name} := $var; } else { if $var.is-resolved && nqp::existskey(%declarations, $var.name) { my $decl := %declarations{$var.name}; $decl.add-sorry: $resolver.build-exception: $var.postdeclaration-exception-name, :symbol($decl.lexical-name); $resolver.add-node-with-check-time-problems($decl); } } } }); add-method(RakuAST::LexicalScope, 'IMPL-HAS-CATCH-HANDLER', [RakuAST::LexicalScope, '', 0, 0], anon sub IMPL-HAS-CATCH-HANDLER ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 267 src/Raku/ast/scoping.rakumod nqp::getattr($SELF, RakuAST::LexicalScope, '$!catch-handlers') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::LexicalScope, 'clear-handler-attachments', [RakuAST::LexicalScope, '', 0, 0], anon sub clear-handler-attachments ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 271 src/Raku/ast/scoping.rakumod nqp::bindattr_i($SELF, RakuAST::LexicalScope, '$!need-succeed-handler', 0); nqp::bindattr($SELF, RakuAST::LexicalScope, '$!catch-handlers', Mu); nqp::bindattr($SELF, RakuAST::LexicalScope, '$!control-handlers', Mu); Nil }); add-method(RakuAST::LexicalScope, 'IMPL-WRAP-SCOPE-HANDLER-QAST', [RakuAST::LexicalScope, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statements', 0, 0, Bool, '$is-handler', 1, 1], anon sub IMPL-WRAP-SCOPE-HANDLER-QAST ($SELF_CONT, $context!, $statements!, :$is-handler?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statements := nqp::decont($statements); $is-handler := nqp::decont($is-handler); #line 279 src/Raku/ast/scoping.rakumod # If it's an exception handler, add rethrow logic. if $is-handler { $statements := QAST::Stmts.new( # Set up a generic exception rethrow, so that exception handlers # from unwanted frames will get skipped if the code in our handler # throws an exception. QAST::Op.new( :op('handle'), $statements, 'CATCH', QAST::Op.new( :op('rethrow'), QAST::Op.new( :op('exception') ) ) ), # Otherwise, rethrow the exception if we reach the end of the handler # without `succeed`ing (that handler is wrapped outside of this one, # just below) QAST::Op.new( :op('rethrow'), QAST::Var.new( :name('EXCEPTION'), :scope('local') ) ) ); } # Now wrap our own handlers. if nqp::getattr_i($SELF, RakuAST::LexicalScope, '$!need-succeed-handler') || nqp::getattr($SELF, RakuAST::LexicalScope, '$!catch-handlers') || nqp::getattr($SELF, RakuAST::LexicalScope, '$!control-handlers') { my $handle := QAST::Op.new( :op('handle'), $statements ); if nqp::getattr_i($SELF, RakuAST::LexicalScope, '$!need-succeed-handler') { $handle.push('SUCCEED'); $handle.push(QAST::Op.new( :op('getpayload'), QAST::Op.new( :op('exception') ) )); } if nqp::getattr($SELF, RakuAST::LexicalScope, '$!catch-handlers') { $SELF.IMPL-ADD-HANDLER($handle, 'CATCH'); } if nqp::getattr($SELF, RakuAST::LexicalScope, '$!control-handlers') { $SELF.IMPL-ADD-HANDLER($handle, 'CONTROL'); } $handle } else { $statements } }); add-method(RakuAST::LexicalScope, 'IMPL-ADD-HANDLER', [RakuAST::LexicalScope, '', 0, 0, Mu, '$handle', 0, 0, str, '$handler', 0, 0], anon sub IMPL-ADD-HANDLER ($SELF_CONT, $handle!, $handler!) { my $SELF := nqp::decont($SELF_CONT); $handle := nqp::decont($handle); $handler := nqp::decont($handler); #line 325 src/Raku/ast/scoping.rakumod $handle.push($handler); $handle.push(QAST::Stmt.new( QAST::Op.new( :op('call'), QAST::Var.new( :name('__' ~ $handler ~ '_HANDLER'), :scope('lexical') ), QAST::Op.new( :op('exception') ) ), QAST::WVal.new( :value(Nil) ) )); }); compose(RakuAST::LexicalScope); parent(RakuAST::Declaration, RakuAST::Node); add-attribute(RakuAST::Declaration, str, '$!scope'); add-method(RakuAST::Declaration, 'default-scope', [RakuAST::Declaration, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 345 src/Raku/ast/scoping.rakumod nqp::die('default-scope is not implemented on ' ~ $SELF.HOW.name($SELF)) }); add-method(RakuAST::Declaration, 'allowed-scopes', [RakuAST::Declaration, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 350 src/Raku/ast/scoping.rakumod nqp::die('allowed-scopes is not implemented on ' ~ $SELF.HOW.name($SELF)) }); add-method(RakuAST::Declaration, 'scope', [RakuAST::Declaration, '', 0, 0], anon sub scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 355 src/Raku/ast/scoping.rakumod my str $scope := nqp::getattr_s($SELF, RakuAST::Declaration, '$!scope'); nqp::isnull_s($scope) || $scope eq '' ?? $SELF.default-scope !! $scope }); add-method(RakuAST::Declaration, 'replace-scope', [RakuAST::Declaration, '', 0, 0, str, '$scope', 0, 0], anon sub replace-scope ($SELF_CONT, $scope!) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); #line 364 src/Raku/ast/scoping.rakumod nqp::bindattr_s($SELF, RakuAST::Declaration, '$!scope', $scope eq '' ?? nqp::null_s !! $scope); Nil }); add-method(RakuAST::Declaration, 'is-lexical', [RakuAST::Declaration, '', 0, 0], anon sub is-lexical ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 371 src/Raku/ast/scoping.rakumod my str $scope := $SELF.scope; $scope eq 'my' || $scope eq 'state' }); add-method(RakuAST::Declaration, 'is-simple-lexical-declaration', [RakuAST::Declaration, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 380 src/Raku/ast/scoping.rakumod $SELF.is-lexical }); compose(RakuAST::Declaration); parent(RakuAST::ImplicitDeclarations, RakuAST::Node); add-attribute(RakuAST::ImplicitDeclarations, List, '$!implicit-declarations-cache'); add-method(RakuAST::ImplicitDeclarations, 'PRODUCE-IMPLICIT-DECLARATIONS', [RakuAST::ImplicitDeclarations, '', 0, 0], anon sub PRODUCE-IMPLICIT-DECLARATIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 400 src/Raku/ast/scoping.rakumod $SELF.IMPL-WRAP-LIST(nqp::list()) }); add-method(RakuAST::ImplicitDeclarations, 'get-implicit-declarations', [RakuAST::ImplicitDeclarations, '', 0, 0], anon sub get-implicit-declarations ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 405 src/Raku/ast/scoping.rakumod nqp::getattr($SELF, RakuAST::ImplicitDeclarations, '$!implicit-declarations-cache') // nqp::bindattr($SELF, RakuAST::ImplicitDeclarations, '$!implicit-declarations-cache', $SELF.PRODUCE-IMPLICIT-DECLARATIONS()) }); compose(RakuAST::ImplicitDeclarations); parent(RakuAST::Declaration::External, RakuAST::Declaration); add-attribute(RakuAST::Declaration::External, str, '$!lexical-name'); add-attribute(RakuAST::Declaration::External, Mu, '$!native-type'); add-method(RakuAST::Declaration::External, 'new', [RakuAST::Declaration::External, '', 0, 0, str, '$lexical-name', 1, 1, Mu, '$native-type', 1, 1], anon sub new ($SELF_CONT, :$lexical-name?, :$native-type?) { my $SELF := nqp::decont($SELF_CONT); $lexical-name := nqp::decont($lexical-name); $native-type := nqp::decont($native-type); #line 421 src/Raku/ast/scoping.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration::External, '$!lexical-name', $lexical-name); nqp::bindattr($obj, RakuAST::Declaration::External, '$!native-type', $native-type); $obj }); add-method(RakuAST::Declaration::External, 'IMPL-LOOKUP-QAST', [RakuAST::Declaration::External, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$rvalue', 1, 1], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!, :$rvalue?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $rvalue := nqp::decont($rvalue); #line 428 src/Raku/ast/scoping.rakumod my str $scope := 'lexical'; unless $rvalue { # Potentially l-value native lookups need a lexicalref. if nqp::objprimspec(nqp::getattr($SELF, RakuAST::Declaration::External, '$!native-type')) { $scope := 'lexicalref'; } } QAST::Var.new( :name(nqp::getattr_s($SELF, RakuAST::Declaration::External, '$!lexical-name')), :$scope, :returns(nqp::getattr($SELF, RakuAST::Declaration::External, '$!native-type')) ) }); add-method(RakuAST::Declaration::External, 'default-scope', [RakuAST::Declaration::External, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 439 src/Raku/ast/scoping.rakumod 'my' }); add-method(RakuAST::Declaration::External, 'allowed-scopes', [RakuAST::Declaration::External, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 441 src/Raku/ast/scoping.rakumod $SELF.IMPL-WRAP-LIST(['my']) }); add-method(RakuAST::Declaration::External, 'generate-lookup', [RakuAST::Declaration::External, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 443 src/Raku/ast/scoping.rakumod my $lookup := RakuAST::Var::Lexical.new(nqp::getattr_s($SELF, RakuAST::Declaration::External, '$!lexical-name')); $lookup.set-resolution($SELF); $lookup }); #line 418 src/Raku/ast/scoping.rakumod add-method(RakuAST::Declaration::External, 'lexical-name', [], anon sub lexical-name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Declaration::External, '$!lexical-name') }); compose(RakuAST::Declaration::External); parent(RakuAST::Declaration::Mergeable, Any); add-method(RakuAST::Declaration::Mergeable, 'is-stub', [RakuAST::Declaration::Mergeable, '', 0, 0], anon sub is-stub ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 451 src/Raku/ast/scoping.rakumod return (Bool.WHO) if nqp::istype($SELF, RakuAST::Declaration::LexicalPackage) && $SELF.package-is-stub; my $how := $SELF.type.HOW; my $name := $how.HOW.name($how); $name eq 'Perl6::Metamodel::PackageHOW' || $name eq 'KnowHOW' }); add-method(RakuAST::Declaration::Mergeable, 'merge', [RakuAST::Declaration::Mergeable, '', 0, 0, RakuAST::Declaration, '$other', 0, 0, RakuAST::Resolver, '$resolver', 1, 0], anon sub merge ($SELF_CONT, $other!, :$resolver!) { my $SELF := nqp::decont($SELF_CONT); $other := nqp::decont($other); $resolver := nqp::decont($resolver); #line 458 src/Raku/ast/scoping.rakumod my $target := $SELF.compile-time-value; my $source := $other.compile-time-value; my $loader := nqp::gethllsym('Raku', 'ModuleLoader'); if $other.is-stub { # Source is a stub. We can safely merge the symbols # from source into the target that's importing them. $loader.merge_globals($target.WHO, $source.WHO); } elsif $SELF.is-stub { # The tricky case: here the interesting package is the # one in the module. So we merge the other way around # and install that as the result. $loader.merge_globals($source.WHO, $target.WHO); $SELF.set-value($source); } elsif nqp::can($SELF, 'lexical-name') && nqp::eqat($SELF.lexical-name, '&', 0) { # There's already a symbol. However, we may be able to merge # if both are multis and have onlystar dispatchers. if nqp::can($target, 'is_dispatcher') && $target.is_dispatcher && nqp::can($source, 'is_dispatcher') && $source.is_dispatcher && $target.onlystar && $source.onlystar { # Replace installed one with a derived one, to avoid any # weird action at a distance. $target := $target.derive_dispatcher; $SELF.set-value($target); # Incorporate dispatchees of foreign proto, avoiding # duplicates. my %seen; for $target.dispatchees { %seen{$_.static_id} := $_; } for $source.dispatchees { unless nqp::existskey(%seen, $_.static_id) { $target.add_dispatchee($_); } } return; } # "Latest wins" semantics for functions $SELF.set-value($source); } else { $resolver.panic( $resolver.build-exception( 'X::Redeclaration', :symbol(nqp::can($SELF, 'lexical-name') ?? $SELF.lexical-name !! '') ) ); } }); add-method(RakuAST::Declaration::Mergeable, 'set-value', [RakuAST::Declaration::Mergeable, '', 0, 0, Mu, '$value', 0, 0], anon sub set-value ($SELF_CONT, $value!) { my $SELF := nqp::decont($SELF_CONT); $value := nqp::decont($value); #line 513 src/Raku/ast/scoping.rakumod nqp::die('set-value not implemented on ' ~ $SELF.HOW.name($SELF)); }); compose(RakuAST::Declaration::Mergeable); parent(RakuAST::Declaration::External::Constant, RakuAST::Declaration::External); parent(RakuAST::Declaration::External::Constant, RakuAST::CompileTimeValue); parent(RakuAST::Declaration::External::Constant, RakuAST::Declaration::Mergeable); add-attribute(RakuAST::Declaration::External::Constant, Mu, '$!compile-time-value'); add-method(RakuAST::Declaration::External::Constant, 'new', [RakuAST::Declaration::External::Constant, '', 0, 0, str, '$lexical-name', 1, 0, Mu, '$compile-time-value', 1, 0], anon sub new ($SELF_CONT, :$lexical-name!, :$compile-time-value!) { my $SELF := nqp::decont($SELF_CONT); $lexical-name := nqp::decont($lexical-name); $compile-time-value := nqp::decont($compile-time-value); #line 527 src/Raku/ast/scoping.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration::External, '$!lexical-name', $lexical-name); nqp::bindattr($obj, RakuAST::Declaration::External::Constant, '$!compile-time-value', $compile-time-value); $obj }); add-method(RakuAST::Declaration::External::Constant, 'set-value', [RakuAST::Declaration::External::Constant, '', 0, 0, Mu, '$compile-time-value', 0, 0], anon sub set-value ($SELF_CONT, $compile-time-value!) { my $SELF := nqp::decont($SELF_CONT); $compile-time-value := nqp::decont($compile-time-value); #line 535 src/Raku/ast/scoping.rakumod nqp::bindattr($SELF, RakuAST::Declaration::External::Constant, '$!compile-time-value', $compile-time-value); }); add-method(RakuAST::Declaration::External::Constant, 'type', [RakuAST::Declaration::External::Constant, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 540 src/Raku/ast/scoping.rakumod nqp::getattr($SELF, RakuAST::Declaration::External::Constant, '$!compile-time-value').WHAT }); add-method(RakuAST::Declaration::External::Constant, 'IMPL-LOOKUP-QAST', [RakuAST::Declaration::External::Constant, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$rvalue', 1, 1], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!, :$rvalue?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $rvalue := nqp::decont($rvalue); #line 542 src/Raku/ast/scoping.rakumod my $value := nqp::getattr($SELF, RakuAST::Declaration::External::Constant, '$!compile-time-value'); $context.ensure-sc($value); QAST::WVal.new( :$value ) }); #line 525 src/Raku/ast/scoping.rakumod add-method(RakuAST::Declaration::External::Constant, 'compile-time-value', [], anon sub compile-time-value ($self) { nqp::getattr(nqp::decont($self), RakuAST::Declaration::External::Constant, '$!compile-time-value') }); compose(RakuAST::Declaration::External::Constant); parent(RakuAST::Declaration::External::Setting, RakuAST::Declaration::External); parent(RakuAST::Declaration::External::Setting, RakuAST::CompileTimeValue); parent(RakuAST::Declaration::External::Setting, RakuAST::Declaration::Mergeable); add-attribute(RakuAST::Declaration::External::Setting, Mu, '$!compile-time-value'); add-method(RakuAST::Declaration::External::Setting, 'new', [RakuAST::Declaration::External::Setting, '', 0, 0, str, '$lexical-name', 1, 0, Mu, '$compile-time-value', 1, 0], anon sub new ($SELF_CONT, :$lexical-name!, :$compile-time-value!) { my $SELF := nqp::decont($SELF_CONT); $lexical-name := nqp::decont($lexical-name); $compile-time-value := nqp::decont($compile-time-value); #line 559 src/Raku/ast/scoping.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration::External, '$!lexical-name', $lexical-name); nqp::bindattr($obj, RakuAST::Declaration::External::Setting, '$!compile-time-value', $compile-time-value); $obj }); add-method(RakuAST::Declaration::External::Setting, 'set-value', [RakuAST::Declaration::External::Setting, '', 0, 0, Mu, '$compile-time-value', 0, 0], anon sub set-value ($SELF_CONT, $compile-time-value!) { my $SELF := nqp::decont($SELF_CONT); $compile-time-value := nqp::decont($compile-time-value); #line 567 src/Raku/ast/scoping.rakumod nqp::bindattr($SELF, RakuAST::Declaration::External::Setting, '$!compile-time-value', $compile-time-value); }); add-method(RakuAST::Declaration::External::Setting, 'type', [RakuAST::Declaration::External::Setting, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 572 src/Raku/ast/scoping.rakumod nqp::getattr($SELF, RakuAST::Declaration::External::Setting, '$!compile-time-value').WHAT }); #line 557 src/Raku/ast/scoping.rakumod add-method(RakuAST::Declaration::External::Setting, 'compile-time-value', [], anon sub compile-time-value ($self) { nqp::getattr(nqp::decont($self), RakuAST::Declaration::External::Setting, '$!compile-time-value') }); compose(RakuAST::Declaration::External::Setting); parent(RakuAST::Declaration::Import, RakuAST::Declaration::External::Constant); add-method(RakuAST::Declaration::Import, 'IMPL-QAST-DECL', [RakuAST::Declaration::Import, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 580 src/Raku/ast/scoping.rakumod my $value := $SELF.compile-time-value; $context.ensure-sc($value); QAST::Var.new( :scope('lexical'), :decl('static'), :name($SELF.lexical-name), :$value ) }); compose(RakuAST::Declaration::Import); parent(RakuAST::Declaration::LexicalPackage, RakuAST::Declaration); parent(RakuAST::Declaration::LexicalPackage, RakuAST::CompileTimeValue); parent(RakuAST::Declaration::LexicalPackage, RakuAST::Declaration::Mergeable); add-attribute(RakuAST::Declaration::LexicalPackage, str, '$!lexical-name'); add-attribute(RakuAST::Declaration::LexicalPackage, Mu, '$!compile-time-value'); add-attribute(RakuAST::Declaration::LexicalPackage, RakuAST::Package, '$!package'); add-method(RakuAST::Declaration::LexicalPackage, 'new', [RakuAST::Declaration::LexicalPackage, '', 0, 0, str, '$lexical-name', 1, 0, Mu, '$compile-time-value', 1, 0, RakuAST::Package, '$package', 1, 0], anon sub new ($SELF_CONT, :$lexical-name!, :$compile-time-value!, :$package!) { my $SELF := nqp::decont($SELF_CONT); $lexical-name := nqp::decont($lexical-name); $compile-time-value := nqp::decont($compile-time-value); $package := nqp::decont($package); #line 601 src/Raku/ast/scoping.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration::LexicalPackage, '$!lexical-name', $lexical-name); nqp::bindattr($obj, RakuAST::Declaration::LexicalPackage, '$!compile-time-value', $compile-time-value); nqp::bindattr($obj, RakuAST::Declaration::LexicalPackage, '$!package', $package); $obj }); add-method(RakuAST::Declaration::LexicalPackage, 'set-value', [RakuAST::Declaration::LexicalPackage, '', 0, 0, Mu, '$compile-time-value', 0, 0], anon sub set-value ($SELF_CONT, $compile-time-value!) { my $SELF := nqp::decont($SELF_CONT); $compile-time-value := nqp::decont($compile-time-value); #line 612 src/Raku/ast/scoping.rakumod nqp::bindattr($SELF, RakuAST::Declaration::LexicalPackage, '$!compile-time-value', $compile-time-value); }); add-method(RakuAST::Declaration::LexicalPackage, 'package-is-stub', [RakuAST::Declaration::LexicalPackage, '', 0, 0], anon sub package-is-stub ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 617 src/Raku/ast/scoping.rakumod nqp::getattr($SELF, RakuAST::Declaration::LexicalPackage, '$!package').is-stub }); add-method(RakuAST::Declaration::LexicalPackage, 'type', [RakuAST::Declaration::LexicalPackage, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 621 src/Raku/ast/scoping.rakumod nqp::getattr($SELF, RakuAST::Declaration::LexicalPackage, '$!compile-time-value').WHAT }); add-method(RakuAST::Declaration::LexicalPackage, 'IMPL-QAST-DECL', [RakuAST::Declaration::LexicalPackage, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 623 src/Raku/ast/scoping.rakumod $context.ensure-sc(nqp::getattr($SELF, RakuAST::Declaration::LexicalPackage, '$!compile-time-value')); QAST::Var.new( :scope('lexical'), :decl('static'), :name(nqp::getattr_s($SELF, RakuAST::Declaration::LexicalPackage, '$!lexical-name')), :value(nqp::getattr($SELF, RakuAST::Declaration::LexicalPackage, '$!compile-time-value')) ) }); add-method(RakuAST::Declaration::LexicalPackage, 'IMPL-LOOKUP-QAST', [RakuAST::Declaration::LexicalPackage, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$rvalue', 1, 1], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!, :$rvalue?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $rvalue := nqp::decont($rvalue); #line 631 src/Raku/ast/scoping.rakumod my $value := nqp::getattr($SELF, RakuAST::Declaration::LexicalPackage, '$!compile-time-value'); $context.ensure-sc($value); QAST::WVal.new( :$value ) }); #line 599 src/Raku/ast/scoping.rakumod add-method(RakuAST::Declaration::LexicalPackage, 'package', [], anon sub package ($self) { nqp::getattr(nqp::decont($self), RakuAST::Declaration::LexicalPackage, '$!package') }); #line 597 src/Raku/ast/scoping.rakumod add-method(RakuAST::Declaration::LexicalPackage, 'lexical-name', [], anon sub lexical-name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Declaration::LexicalPackage, '$!lexical-name') }); #line 598 src/Raku/ast/scoping.rakumod add-method(RakuAST::Declaration::LexicalPackage, 'compile-time-value', [], anon sub compile-time-value ($self) { nqp::getattr(nqp::decont($self), RakuAST::Declaration::LexicalPackage, '$!compile-time-value') }); compose(RakuAST::Declaration::LexicalPackage); parent(RakuAST::Declaration::ResolvedConstant, RakuAST::Declaration); parent(RakuAST::Declaration::ResolvedConstant, RakuAST::CompileTimeValue); add-attribute(RakuAST::Declaration::ResolvedConstant, Mu, '$!compile-time-value'); add-method(RakuAST::Declaration::ResolvedConstant, 'new', [RakuAST::Declaration::ResolvedConstant, '', 0, 0, Mu, '$compile-time-value', 1, 0], anon sub new ($SELF_CONT, :$compile-time-value!) { my $SELF := nqp::decont($SELF_CONT); $compile-time-value := nqp::decont($compile-time-value); #line 647 src/Raku/ast/scoping.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Declaration::ResolvedConstant, '$!compile-time-value', $compile-time-value); $obj }); add-method(RakuAST::Declaration::ResolvedConstant, 'type', [RakuAST::Declaration::ResolvedConstant, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 654 src/Raku/ast/scoping.rakumod nqp::getattr($SELF, RakuAST::Declaration::ResolvedConstant, '$!compile-time-value').WHAT }); add-method(RakuAST::Declaration::ResolvedConstant, 'IMPL-TO-QAST', [RakuAST::Declaration::ResolvedConstant, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 656 src/Raku/ast/scoping.rakumod $SELF.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::Declaration::ResolvedConstant, 'IMPL-LOOKUP-QAST', [RakuAST::Declaration::ResolvedConstant, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$rvalue', 1, 1], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!, :$rvalue?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $rvalue := nqp::decont($rvalue); #line 660 src/Raku/ast/scoping.rakumod my $value := nqp::getattr($SELF, RakuAST::Declaration::ResolvedConstant, '$!compile-time-value'); $context.ensure-sc($value); QAST::WVal.new( :$value ) }); add-method(RakuAST::Declaration::ResolvedConstant, 'default-scope', [RakuAST::Declaration::ResolvedConstant, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 666 src/Raku/ast/scoping.rakumod 'package' }); add-method(RakuAST::Declaration::ResolvedConstant, 'allowed-scopes', [RakuAST::Declaration::ResolvedConstant, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 668 src/Raku/ast/scoping.rakumod $SELF.IMPL-WRAP-LIST(['package']) }); add-method(RakuAST::Declaration::ResolvedConstant, 'IMPL-CAN-INTERPRET', [RakuAST::Declaration::ResolvedConstant, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 670 src/Raku/ast/scoping.rakumod (Bool.WHO) }); add-method(RakuAST::Declaration::ResolvedConstant, 'IMPL-INTERPRET', [RakuAST::Declaration::ResolvedConstant, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 674 src/Raku/ast/scoping.rakumod nqp::getattr($SELF, RakuAST::Declaration::ResolvedConstant, '$!compile-time-value') }); #line 645 src/Raku/ast/scoping.rakumod add-method(RakuAST::Declaration::ResolvedConstant, 'compile-time-value', [], anon sub compile-time-value ($self) { nqp::getattr(nqp::decont($self), RakuAST::Declaration::ResolvedConstant, '$!compile-time-value') }); compose(RakuAST::Declaration::ResolvedConstant); parent(RakuAST::Lookup, RakuAST::Node); add-attribute(RakuAST::Lookup, RakuAST::Declaration, '$!resolution'); add-method(RakuAST::Lookup, 'needs-resolution', [RakuAST::Lookup, '', 0, 0], anon sub needs-resolution ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 686 src/Raku/ast/scoping.rakumod (Bool.WHO) }); add-method(RakuAST::Lookup, 'is-resolved', [RakuAST::Lookup, '', 0, 0], anon sub is-resolved ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 688 src/Raku/ast/scoping.rakumod nqp::isconcrete(nqp::getattr($SELF, RakuAST::Lookup, '$!resolution')) ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Lookup, 'resolution', [RakuAST::Lookup, '', 0, 0], anon sub resolution ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 692 src/Raku/ast/scoping.rakumod nqp::isconcrete(nqp::getattr($SELF, RakuAST::Lookup, '$!resolution')) ?? nqp::getattr($SELF, RakuAST::Lookup, '$!resolution') !! nqp::die('This element has not been resolved. Type: ' ~ $SELF.HOW.name($SELF)) }); add-method(RakuAST::Lookup, 'set-resolution', [RakuAST::Lookup, '', 0, 0, RakuAST::Declaration, '$resolution', 0, 0], anon sub set-resolution ($SELF_CONT, $resolution!) { my $SELF := nqp::decont($SELF_CONT); $resolution := nqp::decont($resolution); #line 698 src/Raku/ast/scoping.rakumod nqp::bindattr($SELF, RakuAST::Lookup, '$!resolution', $resolution) }); add-method(RakuAST::Lookup, 'undeclared-symbol-details', [RakuAST::Lookup, '', 0, 0], anon sub undeclared-symbol-details ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 705 src/Raku/ast/scoping.rakumod Nil }); compose(RakuAST::Lookup); parent(RakuAST::UndeclaredSymbolDescription, Any); add-attribute(RakuAST::UndeclaredSymbolDescription, str, '$!name'); add-method(RakuAST::UndeclaredSymbolDescription, 'new', [RakuAST::UndeclaredSymbolDescription, '', 0, 0, str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 714 src/Raku/ast/scoping.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::UndeclaredSymbolDescription, '$!name', $name); $obj }); #line 712 src/Raku/ast/scoping.rakumod add-method(RakuAST::UndeclaredSymbolDescription, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::UndeclaredSymbolDescription, '$!name') }); compose(RakuAST::UndeclaredSymbolDescription); parent(RakuAST::UndeclaredSymbolDescription::Routine, RakuAST::UndeclaredSymbolDescription); add-method(RakuAST::UndeclaredSymbolDescription::Routine, 'IMPL-REPORT', [RakuAST::UndeclaredSymbolDescription::Routine, '', 0, 0, RakuAST::Lookup, '$node', 0, 0, Mu, '$types', 0, 0, Mu, '$routines', 0, 0, Mu, '$other', 0, 0], anon sub IMPL-REPORT ($SELF_CONT, $node!, $types!, $routines!, $other!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); $types := nqp::decont($types); $routines := nqp::decont($routines); $other := nqp::decont($other); #line 723 src/Raku/ast/scoping.rakumod nqp::bindkey($routines, $SELF.name, [-1]); }); compose(RakuAST::UndeclaredSymbolDescription::Routine); parent(RakuAST::ImplicitLookups, RakuAST::Node); add-attribute(RakuAST::ImplicitLookups, List, '$!implicit-lookups-cache'); add-method(RakuAST::ImplicitLookups, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::ImplicitLookups, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 742 src/Raku/ast/scoping.rakumod $SELF.IMPL-WRAP-LIST(nqp::list()) }); add-method(RakuAST::ImplicitLookups, 'get-implicit-lookups', [RakuAST::ImplicitLookups, '', 0, 0], anon sub get-implicit-lookups ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 747 src/Raku/ast/scoping.rakumod nqp::isconcrete($SELF) ?? nqp::getattr($SELF, RakuAST::ImplicitLookups, '$!implicit-lookups-cache') // nqp::bindattr($SELF, RakuAST::ImplicitLookups, '$!implicit-lookups-cache', $SELF.PRODUCE-IMPLICIT-LOOKUPS()) !! $SELF.IMPL-WRAP-LIST([]) }); add-method(RakuAST::ImplicitLookups, 'resolve-implicit-lookups-with', [RakuAST::ImplicitLookups, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-implicit-lookups-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 756 src/Raku/ast/scoping.rakumod for $SELF.IMPL-UNWRAP-LIST($SELF.get-implicit-lookups()) { # We use null to pad out lookup lists so that they always # have the same number of elements regardless of whether # some lookups can only be conditionally included in the list unless nqp::isnull($_) || $_.is-resolved { $_.resolve-with($resolver); } } }); compose(RakuAST::ImplicitLookups); parent(RakuAST::PackageInstaller, Any); add-method(RakuAST::PackageInstaller, 'IMPL-INSTALL-PACKAGE', [RakuAST::PackageInstaller, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, str, '$scope', 0, 0, RakuAST::Name, '$name', 0, 0, Mu, '$type-object', 0, 0, RakuAST::Package, '$current-package', 0, 0, Bool, '$no-lexical', 1, 1], anon sub IMPL-INSTALL-PACKAGE ($SELF_CONT, $resolver!, $scope!, $name!, $type-object!, $current-package!, :$no-lexical?) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $scope := nqp::decont($scope); $name := nqp::decont($name); $type-object := nqp::decont($type-object); $current-package := nqp::decont($current-package); $no-lexical := nqp::decont($no-lexical); #line 780 src/Raku/ast/scoping.rakumod my $target; my $final; my $lexical; my $pure-package-installation := nqp::istype($SELF, RakuAST::Package); my $illegal-pseudo-package := $name.contains-pseudo-package-illegal-for-declaration; $resolver.add-sorry: $resolver.build-exception: 'X::PseudoPackage::InDeclaration', pseudo-package => $illegal-pseudo-package, action => $SELF.dba ~ ' name' if $illegal-pseudo-package; if $name.is-identifier { $final := $name.canonicalize; unless $no-lexical { $lexical := $resolver.resolve-lexical-constant($final); if $pure-package-installation || !$lexical { $resolver.current-scope.merge-generated-lexical-declaration: :$resolver, $SELF.IMPL-GENERATE-LEXICAL-DECLARATION($final, $type-object); } } # If `our`-scoped, also put it into the current package. if $scope eq 'our' { $target := $current-package; my %stash := $resolver.IMPL-STASH-HASH($target); if nqp::existskey(%stash, $final) && !(%stash{$final} =:= $type-object || nqp::istype(%stash{$final}.HOW, Perl6::Metamodel::PackageHOW)) { $resolver.add-sorry: $resolver.build-exception: 'X::Redeclaration', :symbol($final); } } } else { my @parts := nqp::clone($SELF.IMPL-UNWRAP-LIST($name.parts)); $final := nqp::pop(@parts).name; my $first := @parts[0].name; my $resolved := $resolver.partially-resolve-name-constant(RakuAST::Name.new(|@parts)); if $resolved { # first parts of the name found $resolved := $SELF.IMPL-UNWRAP-LIST($resolved); $target := $resolved[0]; if $scope eq 'our' && nqp::elems(@parts) == 1 { # Upgrade lexically imported top level package to global ($resolver.get-global.WHO){$first} := $resolver.resolve-lexical($first).compile-time-value; } my $parts := $resolved[1]; @parts := $SELF.IMPL-UNWRAP-LIST($parts); $scope := 'our'; # Ensure we install the package into the parent stash if nqp::elems(@parts) { my $longname := $target.HOW.name($target); for @parts { $longname := $longname ~ '::' ~ $_.name; my $package := Perl6::Metamodel::PackageHOW.new_type(name => $longname); $package.HOW.compose($package); my %stash := $resolver.IMPL-STASH-HASH($target); %stash{$_.name} := $package; $target := $package; } } } else { my $first := nqp::shift(@parts).name; $target := Perl6::Metamodel::PackageHOW.new_type(name => $first); $target.HOW.compose($target); $resolver.current-scope.merge-generated-lexical-declaration: :$resolver, RakuAST::Declaration::LexicalPackage.new: :lexical-name($first), :compile-time-value($target), :package($pure-package-installation ?? $SELF !! $current-package); if $scope eq 'our' { # TODO conflicts my %stash := $resolver.IMPL-STASH-HASH($current-package); %stash{$first} := $target; } $scope := 'our'; # Ensure we install the package into the generated stub my $longname := $first; for @parts { $longname := $longname ~ '::' ~ $_.name; my $package := Perl6::Metamodel::PackageHOW.new_type(name => $longname); $package.HOW.compose($package); my %stash := $resolver.IMPL-STASH-HASH($target); %stash{$_.name} := $package; $target := $package; } } } my %stash := $resolver.IMPL-STASH-HASH($target); # upgrade a lexically imported package stub to package scope if it exists if $lexical { %stash{$final} := $lexical.compile-time-value; } if $scope eq 'our' { if nqp::existskey(%stash, $final) && !(%stash{$final} =:= $type-object) { nqp::setwho($type-object, %stash{$final}.WHO); } %stash{$final} := $type-object; } }); compose(RakuAST::PackageInstaller); parent(RakuAST::Attaching, RakuAST::Node); add-method(RakuAST::Attaching, 'attach', [RakuAST::Attaching, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 11 src/Raku/ast/attaching.rakumod nqp::die('attach not implemented for ' ~ $SELF.HOW.name($SELF)); }); compose(RakuAST::Attaching); parent(RakuAST::AttachTarget, RakuAST::Node); add-method(RakuAST::AttachTarget, 'attach-target-names', [RakuAST::AttachTarget, '', 0, 0], anon sub attach-target-names ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 22 src/Raku/ast/attaching.rakumod nqp::die('attach-target-names not implemented for ' ~ $SELF.HOW.name($SELF)); }); add-method(RakuAST::AttachTarget, 'clear-attachments', [RakuAST::AttachTarget, '', 0, 0], anon sub clear-attachments ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 28 src/Raku/ast/attaching.rakumod nqp::die('clear-attachments not implemented for ' ~ $SELF.HOW.name($SELF)); }); compose(RakuAST::AttachTarget); parent(RakuAST::BeginTime, RakuAST::Node); add-attribute(RakuAST::BeginTime, int, '$!begin-performed'); add-method(RakuAST::BeginTime, 'PERFORM-BEGIN', [RakuAST::BeginTime, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 10 src/Raku/ast/begintime.rakumod nqp::die('Missing PERFORM-BEGIN implementation in ' ~ $SELF.HOW.name($SELF)) }); add-method(RakuAST::BeginTime, 'is-begin-performed-before-children', [RakuAST::BeginTime, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 16 src/Raku/ast/begintime.rakumod (Bool.WHO) }); add-method(RakuAST::BeginTime, 'is-begin-performed-after-children', [RakuAST::BeginTime, '', 0, 0], anon sub is-begin-performed-after-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 17 src/Raku/ast/begintime.rakumod !$SELF.is-begin-performed-before-children }); add-method(RakuAST::BeginTime, 'ensure-begin-performed', [RakuAST::BeginTime, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, int, '$phase', 1, 1], anon sub ensure-begin-performed ($SELF_CONT, $resolver!, $context!, :$phase?) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $phase := nqp::decont($phase); #line 20 src/Raku/ast/begintime.rakumod if nqp::can($SELF, 'PERFORM-BEGIN-BEFORE-CHILDREN') || nqp::can($SELF, 'PERFORM-BEGIN-AFTER-CHILDREN') { if $phase == 0 && $SELF.is-begin-performed-before-children || $phase == 1 { unless nqp::getattr_i($SELF, RakuAST::BeginTime, '$!begin-performed') +& 1 { $SELF.PERFORM-BEGIN-BEFORE-CHILDREN($resolver, $context); nqp::bindattr_i($SELF, RakuAST::BeginTime, '$!begin-performed', nqp::getattr_i($SELF, RakuAST::BeginTime, '$!begin-performed') +| 1); } } if $phase == 0 && $SELF.is-begin-performed-after-children || $phase == 2 { unless nqp::getattr_i($SELF, RakuAST::BeginTime, '$!begin-performed') +& 2 { $SELF.PERFORM-BEGIN-AFTER-CHILDREN($resolver, $context); nqp::bindattr_i($SELF, RakuAST::BeginTime, '$!begin-performed', nqp::getattr_i($SELF, RakuAST::BeginTime, '$!begin-performed') +| 2); } } } else { unless nqp::getattr_i($SELF, RakuAST::BeginTime, '$!begin-performed') { $SELF.PERFORM-BEGIN($resolver, $context); nqp::bindattr_i($SELF, RakuAST::BeginTime, '$!begin-performed', 3); } } Nil }); add-method(RakuAST::BeginTime, 'begin-performed', [RakuAST::BeginTime, '', 0, 0], anon sub begin-performed ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 44 src/Raku/ast/begintime.rakumod nqp::getattr_i($SELF, RakuAST::BeginTime, '$!begin-performed') == 3 }); add-method(RakuAST::BeginTime, 'IMPL-BEGIN-TIME-EVALUATE', [RakuAST::BeginTime, '', 0, 0, RakuAST::Node, '$code', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-BEGIN-TIME-EVALUATE ($SELF_CONT, $code!, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $code := nqp::decont($code); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 50 src/Raku/ast/begintime.rakumod my $*IMPL-COMPILE-DYNAMICALLY := 1; $code.IMPL-CHECK($resolver, $context, (Bool.WHO)); if $code.IMPL-CAN-INTERPRET { $code.IMPL-INTERPRET(RakuAST::IMPL::InterpContext.new) } elsif nqp::istype($code, RakuAST::Code) { $code.meta-object; } elsif nqp::istype($code, RakuAST::Expression) { my $thunk := RakuAST::ExpressionThunk.new; $code.wrap-with-thunk($thunk); $thunk.IMPL-STUB-CODE($resolver, $context); $thunk.IMPL-QAST-BLOCK($context, :expression($code)); $thunk.meta-object()() } else { nqp::die('BEGIN time evaluation only supported for simple constructs so far') } }); add-method(RakuAST::BeginTime, 'IMPL-BEGIN-TIME-CALL', [RakuAST::BeginTime, '', 0, 0, RakuAST::Node, '$callee', 0, 0, RakuAST::ArgList, '$args', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-BEGIN-TIME-CALL ($SELF_CONT, $callee!, $args!, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $callee := nqp::decont($callee); $args := nqp::decont($args); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 74 src/Raku/ast/begintime.rakumod my $*IMPL-COMPILE-DYNAMICALLY := 1; if $callee.is-resolved && nqp::istype($callee.resolution, RakuAST::CompileTimeValue) && $args.IMPL-CAN-INTERPRET { my $resolved := $callee.resolution.compile-time-value; my @args := $args.IMPL-INTERPRET(RakuAST::IMPL::InterpContext.new); my @pos := @args[0]; my %named := @args[1]; return $resolved(|@pos, |%named); } else { nqp::die('BEGIN time calls only supported for simple constructs so far') } }); compose(RakuAST::BeginTime); parent(RakuAST::TraitTarget, Any); add-attribute(RakuAST::TraitTarget, Mu, '$!traits'); add-method(RakuAST::TraitTarget, 'set-traits', [RakuAST::TraitTarget, '', 0, 0, List, '$traits', 0, 0], anon sub set-traits ($SELF_CONT, $traits!) { my $SELF := nqp::decont($SELF_CONT); $traits := nqp::decont($traits); #line 6 src/Raku/ast/traits.rakumod my @traits; if $traits { for $SELF.IMPL-UNWRAP-LIST($traits) { unless nqp::istype($_, RakuAST::Trait) { nqp::die('The traits list can only contain RakuAST::Trait objects'); } nqp::push(@traits, $_); } } nqp::bindattr($SELF, RakuAST::TraitTarget, '$!traits', @traits); Nil }); add-method(RakuAST::TraitTarget, 'add-trait', [RakuAST::TraitTarget, '', 0, 0, RakuAST::Trait, '$trait', 0, 0], anon sub add-trait ($SELF_CONT, $trait!) { my $SELF := nqp::decont($SELF_CONT); $trait := nqp::decont($trait); #line 21 src/Raku/ast/traits.rakumod my $traits := nqp::getattr($SELF, RakuAST::TraitTarget, '$!traits'); unless nqp::islist($traits) { $traits := []; nqp::bindattr($SELF, RakuAST::TraitTarget, '$!traits', $traits); } nqp::push($traits, $trait); Nil }); add-method(RakuAST::TraitTarget, 'traits', [RakuAST::TraitTarget, '', 0, 0], anon sub traits ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 32 src/Raku/ast/traits.rakumod my $traits := nqp::getattr($SELF, RakuAST::TraitTarget, '$!traits'); $SELF.IMPL-WRAP-LIST(nqp::islist($traits) ?? $traits !! []) }); add-method(RakuAST::TraitTarget, 'apply-traits', [RakuAST::TraitTarget, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::TraitTarget, '$target', 0, 0, Any, '%named', 0, 0], anon sub apply-traits ($SELF_CONT, $resolver!, $context!, $target!, *%named) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $target := nqp::decont($target); %named := nqp::decont(%named); #line 38 src/Raku/ast/traits.rakumod if nqp::getattr($SELF, RakuAST::TraitTarget, '$!traits') { for nqp::getattr($SELF, RakuAST::TraitTarget, '$!traits') { $_.apply($resolver, $context, $target, |%named) unless $_.applied; } } Nil }); add-method(RakuAST::TraitTarget, 'visit-traits', [RakuAST::TraitTarget, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-traits ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 48 src/Raku/ast/traits.rakumod if nqp::getattr($SELF, RakuAST::TraitTarget, '$!traits') { for nqp::getattr($SELF, RakuAST::TraitTarget, '$!traits') { $visitor($_); } } }); compose(RakuAST::TraitTarget); parent(RakuAST::Trait, RakuAST::ImplicitLookups); add-attribute(RakuAST::Trait, int, '$!applied'); add-method(RakuAST::Trait, 'IMPL-TRAIT-NAME', [RakuAST::Trait, '', 0, 0], anon sub IMPL-TRAIT-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 63 src/Raku/ast/traits.rakumod nqp::die($SELF.HOW.name($SELF) ~ ' does not implement IMPL-TRAIT-NAME') }); add-method(RakuAST::Trait, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Trait, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 67 src/Raku/ast/traits.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical::Constant.new('&trait_mod:<' ~ $SELF.IMPL-TRAIT-NAME() ~ '>') ]) }); add-method(RakuAST::Trait, 'applied', [RakuAST::Trait, '', 0, 0], anon sub applied ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 74 src/Raku/ast/traits.rakumod nqp::getattr_i($SELF, RakuAST::Trait, '$!applied') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Trait, 'mark-applied', [RakuAST::Trait, '', 0, 0], anon sub mark-applied ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 81 src/Raku/ast/traits.rakumod nqp::bindattr_i($SELF, RakuAST::Trait, '$!applied', 1); Nil }); add-method(RakuAST::Trait, 'apply', [RakuAST::Trait, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::TraitTarget, '$target', 0, 0, Any, '%named', 0, 0], anon sub apply ($SELF_CONT, $resolver!, $context!, $target!, *%named) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $target := nqp::decont($target); %named := nqp::decont(%named); #line 88 src/Raku/ast/traits.rakumod unless $SELF.applied { $SELF.IMPL-CHECK($resolver, $context, (Bool.WHO)); my $decl-target := RakuAST::Declaration::ResolvedConstant.new: compile-time-value => $target.compile-time-value; my $args := $SELF.IMPL-TRAIT-ARGS($resolver, $decl-target); for %named { nqp::push( $SELF.IMPL-UNWRAP-LIST($args.args), RakuAST::ColonPair::Value.new(:key(nqp::iterkey_s($_)), :value(nqp::iterval($_))) ); } $args.IMPL-CHECK($resolver, $context, (Bool.WHO)); $target.IMPL-BEGIN-TIME-CALL( $SELF.get-implicit-lookups.AT-POS(0), $args, $resolver, $context ); $SELF.mark-applied; } }); compose(RakuAST::Trait); parent(RakuAST::Trait::Is, RakuAST::Trait); parent(RakuAST::Trait::Is, RakuAST::BeginTime); add-attribute(RakuAST::Trait::Is, RakuAST::Name, '$!name'); add-attribute(RakuAST::Trait::Is, RakuAST::Circumfix, '$!argument'); add-attribute(RakuAST::Trait::Is, RakuAST::Term::Name, '$!resolved-name'); add-method(RakuAST::Trait::Is, 'new', [RakuAST::Trait::Is, '', 0, 0, RakuAST::Name, '$name', 1, 0, RakuAST::Circumfix, '$argument', 1, 1], anon sub new ($SELF_CONT, :$name!, :$argument?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $argument := nqp::decont($argument); #line 121 src/Raku/ast/traits.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Trait::Is, '$!name', $name); nqp::bindattr($obj, RakuAST::Trait::Is, '$!argument', $argument // RakuAST::Circumfix); $obj }); add-method(RakuAST::Trait::Is, 'PERFORM-BEGIN', [RakuAST::Trait::Is, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 129 src/Raku/ast/traits.rakumod # See if the name resolves as a type and commit to that. my $resolution := $resolver.resolve-name-constant(nqp::getattr($SELF, RakuAST::Trait::Is, '$!name')); if nqp::istype($resolution, RakuAST::CompileTimeValue) && !nqp::isconcrete($resolution.compile-time-value) { my $resolved-name := RakuAST::Type::Simple.new(nqp::getattr($SELF, RakuAST::Trait::Is, '$!name')); $resolved-name.set-resolution($resolution); nqp::bindattr($SELF, RakuAST::Trait::Is, '$!resolved-name', $resolved-name); } Nil }); add-method(RakuAST::Trait::Is, 'IMPL-TRAIT-NAME', [RakuAST::Trait::Is, '', 0, 0], anon sub IMPL-TRAIT-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 142 src/Raku/ast/traits.rakumod 'is' }); add-method(RakuAST::Trait::Is, 'IMPL-TRAIT-ARGS', [RakuAST::Trait::Is, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::Node, '$target', 0, 0], anon sub IMPL-TRAIT-ARGS ($SELF_CONT, $resolver!, $target!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $target := nqp::decont($target); #line 144 src/Raku/ast/traits.rakumod my @args := [$target]; if nqp::getattr($SELF, RakuAST::Trait::Is, '$!resolved-name') { @args.push(nqp::getattr($SELF, RakuAST::Trait::Is, '$!resolved-name')); } else { my $key := nqp::getattr($SELF, RakuAST::Trait::Is, '$!name').canonicalize; @args.push( nqp::getattr($SELF, RakuAST::Trait::Is, '$!argument') ?? RakuAST::ColonPair::Value.new(:$key, :value(nqp::getattr($SELF, RakuAST::Trait::Is, '$!argument'))) !! RakuAST::ColonPair::True.new($key) ); } RakuAST::ArgList.new(|@args) }); add-method(RakuAST::Trait::Is, 'visit-children', [RakuAST::Trait::Is, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 160 src/Raku/ast/traits.rakumod $visitor(nqp::getattr($SELF, RakuAST::Trait::Is, '$!name')); $visitor(nqp::getattr($SELF, RakuAST::Trait::Is, '$!argument')) if nqp::getattr($SELF, RakuAST::Trait::Is, '$!argument'); }); #line 119 src/Raku/ast/traits.rakumod add-method(RakuAST::Trait::Is, 'resolved-name', [], anon sub resolved-name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Trait::Is, '$!resolved-name') }); #line 117 src/Raku/ast/traits.rakumod add-method(RakuAST::Trait::Is, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Trait::Is, '$!name') }); #line 118 src/Raku/ast/traits.rakumod add-method(RakuAST::Trait::Is, 'argument', [], anon sub argument ($self) { nqp::getattr(nqp::decont($self), RakuAST::Trait::Is, '$!argument') }); compose(RakuAST::Trait::Is); parent(RakuAST::Trait::Type, RakuAST::Trait); add-attribute(RakuAST::Trait::Type, RakuAST::Type, '$!type'); add-method(RakuAST::Trait::Type, 'new', [RakuAST::Trait::Type, '', 0, 0, RakuAST::Type, '$type', 0, 0], anon sub new ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 171 src/Raku/ast/traits.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Trait::Type, '$!type', $type); $obj }); add-method(RakuAST::Trait::Type, 'IMPL-TRAIT-ARGS', [RakuAST::Trait::Type, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::Node, '$target', 0, 0], anon sub IMPL-TRAIT-ARGS ($SELF_CONT, $resolver!, $target!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $target := nqp::decont($target); #line 177 src/Raku/ast/traits.rakumod RakuAST::ArgList.new($target, nqp::getattr($SELF, RakuAST::Trait::Type, '$!type')) }); add-method(RakuAST::Trait::Type, 'visit-children', [RakuAST::Trait::Type, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 181 src/Raku/ast/traits.rakumod $visitor(nqp::getattr($SELF, RakuAST::Trait::Type, '$!type')); }); #line 169 src/Raku/ast/traits.rakumod add-method(RakuAST::Trait::Type, 'type', [], anon sub type ($self) { nqp::getattr(nqp::decont($self), RakuAST::Trait::Type, '$!type') }); compose(RakuAST::Trait::Type); parent(RakuAST::Trait::Hides, RakuAST::Trait::Type); add-method(RakuAST::Trait::Hides, 'IMPL-TRAIT-NAME', [RakuAST::Trait::Hides, '', 0, 0], anon sub IMPL-TRAIT-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 190 src/Raku/ast/traits.rakumod 'hides' }); compose(RakuAST::Trait::Hides); parent(RakuAST::Trait::Does, RakuAST::Trait::Type); add-method(RakuAST::Trait::Does, 'IMPL-TRAIT-NAME', [RakuAST::Trait::Does, '', 0, 0], anon sub IMPL-TRAIT-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 197 src/Raku/ast/traits.rakumod 'does' }); compose(RakuAST::Trait::Does); parent(RakuAST::Trait::Of, RakuAST::Trait::Type); add-method(RakuAST::Trait::Of, 'IMPL-TRAIT-NAME', [RakuAST::Trait::Of, '', 0, 0], anon sub IMPL-TRAIT-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 204 src/Raku/ast/traits.rakumod 'of' }); compose(RakuAST::Trait::Of); parent(RakuAST::Trait::Returns, RakuAST::Trait::Type); add-method(RakuAST::Trait::Returns, 'IMPL-TRAIT-NAME', [RakuAST::Trait::Returns, '', 0, 0], anon sub IMPL-TRAIT-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 211 src/Raku/ast/traits.rakumod 'returns' }); compose(RakuAST::Trait::Returns); parent(RakuAST::Trait::Will, RakuAST::Trait); add-attribute(RakuAST::Trait::Will, str, '$!type'); add-attribute(RakuAST::Trait::Will, RakuAST::Expression, '$!expr'); add-method(RakuAST::Trait::Will, 'new', [RakuAST::Trait::Will, '', 0, 0, str, '$type', 0, 0, RakuAST::Expression, '$expr', 0, 0], anon sub new ($SELF_CONT, $type!, $expr!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); $expr := nqp::decont($expr); #line 221 src/Raku/ast/traits.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Trait::Will, '$!type', $type); nqp::bindattr($obj, RakuAST::Trait::Will, '$!expr', $expr); $obj }); add-method(RakuAST::Trait::Will, 'IMPL-TRAIT-NAME', [RakuAST::Trait::Will, '', 0, 0], anon sub IMPL-TRAIT-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 228 src/Raku/ast/traits.rakumod 'will' }); add-method(RakuAST::Trait::Will, 'IMPL-TRAIT-ARGS', [RakuAST::Trait::Will, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::Node, '$target', 0, 0], anon sub IMPL-TRAIT-ARGS ($SELF_CONT, $resolver!, $target!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $target := nqp::decont($target); #line 230 src/Raku/ast/traits.rakumod RakuAST::ArgList.new($target, RakuAST::ColonPair::Value.new(:key(nqp::getattr_s($SELF, RakuAST::Trait::Will, '$!type')), :value(nqp::getattr($SELF, RakuAST::Trait::Will, '$!expr')))) }); add-method(RakuAST::Trait::Will, 'visit-children', [RakuAST::Trait::Will, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 234 src/Raku/ast/traits.rakumod $visitor(nqp::getattr($SELF, RakuAST::Trait::Will, '$!expr')); }); #line 218 src/Raku/ast/traits.rakumod add-method(RakuAST::Trait::Will, 'type', [], anon sub type ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Trait::Will, '$!type') }); #line 219 src/Raku/ast/traits.rakumod add-method(RakuAST::Trait::Will, 'expr', [], anon sub expr ($self) { nqp::getattr(nqp::decont($self), RakuAST::Trait::Will, '$!expr') }); compose(RakuAST::Trait::Will); parent(RakuAST::Trait::Handles, RakuAST::Trait); add-attribute(RakuAST::Trait::Handles, RakuAST::Term, '$!term'); add-method(RakuAST::Trait::Handles, 'new', [RakuAST::Trait::Handles, '', 0, 0, RakuAST::Term, '$term', 0, 0], anon sub new ($SELF_CONT, $term!) { my $SELF := nqp::decont($SELF_CONT); $term := nqp::decont($term); #line 244 src/Raku/ast/traits.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Trait::Handles, '$!term', $term); $obj }); add-method(RakuAST::Trait::Handles, 'IMPL-TRAIT-NAME', [RakuAST::Trait::Handles, '', 0, 0], anon sub IMPL-TRAIT-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 250 src/Raku/ast/traits.rakumod 'handles' }); add-method(RakuAST::Trait::Handles, 'IMPL-TRAIT-ARGS', [RakuAST::Trait::Handles, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::Node, '$target', 0, 0], anon sub IMPL-TRAIT-ARGS ($SELF_CONT, $resolver!, $target!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $target := nqp::decont($target); #line 252 src/Raku/ast/traits.rakumod my $block := RakuAST::Block.new: body => RakuAST::Blockoid.new: RakuAST::StatementList.new: RakuAST::Statement::Expression.new: expression => nqp::getattr($SELF, RakuAST::Trait::Handles, '$!term'); RakuAST::ArgList.new($target, $block); }); add-method(RakuAST::Trait::Handles, 'visit-children', [RakuAST::Trait::Handles, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 261 src/Raku/ast/traits.rakumod $visitor(nqp::getattr($SELF, RakuAST::Trait::Handles, '$!term')); }); #line 242 src/Raku/ast/traits.rakumod add-method(RakuAST::Trait::Handles, 'term', [], anon sub term ($self) { nqp::getattr(nqp::decont($self), RakuAST::Trait::Handles, '$!term') }); compose(RakuAST::Trait::Handles); parent(RakuAST::Meta, RakuAST::CompileTimeValue); add-attribute(RakuAST::Meta, Mu, '$!cached-meta-object'); add-attribute(RakuAST::Meta, Bool, '$!meta-object-produced'); add-method(RakuAST::Meta, 'meta-object', [RakuAST::Meta, '', 0, 0], anon sub meta-object ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 11 src/Raku/ast/meta.rakumod unless nqp::getattr($SELF, RakuAST::Meta, '$!meta-object-produced') { nqp::bindattr($SELF, RakuAST::Meta, '$!cached-meta-object', $SELF.PRODUCE-META-OBJECT()); nqp::bindattr($SELF, RakuAST::Meta, '$!meta-object-produced', (Bool.WHO)); } nqp::getattr($SELF, RakuAST::Meta, '$!cached-meta-object') }); add-method(RakuAST::Meta, 'has-meta-object', [RakuAST::Meta, '', 0, 0], anon sub has-meta-object ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 20 src/Raku/ast/meta.rakumod nqp::getattr($SELF, RakuAST::Meta, '$!meta-object-produced') || (Bool.WHO) }); add-method(RakuAST::Meta, 'compile-time-value', [RakuAST::Meta, '', 0, 0], anon sub compile-time-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 24 src/Raku/ast/meta.rakumod $SELF.meta-object }); compose(RakuAST::Meta); parent(RakuAST::StubbyMeta, RakuAST::Meta); add-attribute(RakuAST::StubbyMeta, Mu, '$!cached-stubbed-meta-object'); add-attribute(RakuAST::StubbyMeta, Bool, '$!stubbed-meta-object-produced'); add-method(RakuAST::StubbyMeta, 'stubbed-meta-object', [RakuAST::StubbyMeta, '', 0, 0], anon sub stubbed-meta-object ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 41 src/Raku/ast/meta.rakumod unless nqp::getattr($SELF, RakuAST::StubbyMeta, '$!stubbed-meta-object-produced') { nqp::bindattr($SELF, RakuAST::StubbyMeta, '$!cached-stubbed-meta-object', $SELF.PRODUCE-STUBBED-META-OBJECT()); nqp::bindattr($SELF, RakuAST::StubbyMeta, '$!stubbed-meta-object-produced', (Bool.WHO)); } nqp::getattr($SELF, RakuAST::StubbyMeta, '$!cached-stubbed-meta-object') }); add-method(RakuAST::StubbyMeta, 'has-stubbed-meta-object', [RakuAST::StubbyMeta, '', 0, 0], anon sub has-stubbed-meta-object ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 50 src/Raku/ast/meta.rakumod nqp::getattr($SELF, RakuAST::StubbyMeta, '$!cached-stubbed-meta-object') || (Bool.WHO) }); add-method(RakuAST::StubbyMeta, 'meta-object', [RakuAST::StubbyMeta, '', 0, 0], anon sub meta-object ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 54 src/Raku/ast/meta.rakumod # Ensure we have the stubbed meta-object first, then delegate to our # parent to produce the full meta-object. $SELF.stubbed-meta-object(); nqp::findmethod(RakuAST::Meta, 'meta-object')($SELF) }); add-method(RakuAST::StubbyMeta, 'compile-time-value', [RakuAST::StubbyMeta, '', 0, 0], anon sub compile-time-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 61 src/Raku/ast/meta.rakumod $SELF.stubbed-meta-object }); compose(RakuAST::StubbyMeta); parent(RakuAST::Doc, RakuAST::Node); add-method(RakuAST::Doc, 'must-define', [RakuAST::Doc, '', 0, 0, str, '$method', 0, 0], anon sub must-define ($SELF_CONT, $method!) { my $SELF := nqp::decont($SELF_CONT); $method := nqp::decont($method); #line 5 src/Raku/ast/doc-block.rakumod nqp::die($SELF.HOW.name($SELF) ~ " must define a '$method' method"); }); add-method(RakuAST::Doc, 'cannot-be-instantiated', [RakuAST::Doc, '', 0, 0], anon sub cannot-be-instantiated ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 8 src/Raku/ast/doc-block.rakumod nqp::die($SELF.HOW.name($SELF) ~ " cannot be instantiated"); }); add-method(RakuAST::Doc, 'new', [RakuAST::Doc, '', 0, 0, Any, '@_', 0, 0, Any, '%_', 0, 0], anon sub new ($SELF_CONT, *@_, *%_) { my $SELF := nqp::decont($SELF_CONT); @_ := nqp::decont(@_); %_ := nqp::decont(%_); #line 12 src/Raku/ast/doc-block.rakumod $SELF.cannot-be-instantiated }); add-method(RakuAST::Doc, 'visit-children', [RakuAST::Doc, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 13 src/Raku/ast/doc-block.rakumod $SELF.must-define("visit-children") }); compose(RakuAST::Doc); parent(RakuAST::Doc::Paragraph, RakuAST::Doc); add-attribute(RakuAST::Doc::Paragraph, List, '$!atoms'); add-method(RakuAST::Doc::Paragraph, 'new', [RakuAST::Doc::Paragraph, '', 0, 0, Any, '@atoms', 0, 0], anon sub new ($SELF_CONT, *@atoms) { my $SELF := nqp::decont($SELF_CONT); @atoms := nqp::decont(@atoms); #line 22 src/Raku/ast/doc-block.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Doc::Paragraph, '$!atoms', @atoms); $obj }); add-method(RakuAST::Doc::Paragraph, 'visit-children', [RakuAST::Doc::Paragraph, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 28 src/Raku/ast/doc-block.rakumod for nqp::getattr($SELF, RakuAST::Doc::Paragraph, '$!atoms') { if nqp::istype($_,RakuAST::Node) { $visitor($_); } } }); add-method(RakuAST::Doc::Paragraph, 'add-atom', [RakuAST::Doc::Paragraph, '', 0, 0, Any, '$atom', 0, 0], anon sub add-atom ($SELF_CONT, $atom!) { my $SELF := nqp::decont($SELF_CONT); $atom := nqp::decont($atom); #line 36 src/Raku/ast/doc-block.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Doc::Paragraph, '$!atoms'), $atom) }); add-method(RakuAST::Doc::Paragraph, 'atoms', [RakuAST::Doc::Paragraph, '', 0, 0], anon sub atoms ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 37 src/Raku/ast/doc-block.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Doc::Paragraph, '$!atoms')) }); compose(RakuAST::Doc::Paragraph); parent(RakuAST::Doc::Block, RakuAST::Doc); parent(RakuAST::Doc::Block, RakuAST::CheckTime); add-attribute(RakuAST::Doc::Block, str, '$!margin'); add-attribute(RakuAST::Doc::Block, str, '$!type'); add-attribute(RakuAST::Doc::Block, int, '$!level'); add-attribute(RakuAST::Doc::Block, Hash, '$!config'); add-attribute(RakuAST::Doc::Block, List, '$!paragraphs'); add-attribute(RakuAST::Doc::Block, int, '$!status'); add-attribute(RakuAST::Doc::Block, int, '$!pod-index'); add-attribute(RakuAST::Doc::Block, Mu, '$!resolved-config'); add-method(RakuAST::Doc::Block, 'new', [RakuAST::Doc::Block, '', 0, 0, Str, '$margin', 1, 1, Str, '$type', 1, 0, Int, '$level', 1, 1, Hash, '$config', 1, 1, List, '$paragraphs', 1, 1, Bool, '$directive', 1, 1, Bool, '$for', 1, 1, Bool, '$abbreviated', 1, 1], anon sub new ($SELF_CONT, :$margin?, :$type!, :$level?, :$config?, :$paragraphs?, :$directive?, :$for?, :$abbreviated?) { my $SELF := nqp::decont($SELF_CONT); $margin := nqp::decont($margin); $type := nqp::decont($type); $level := nqp::decont($level); $config := nqp::decont($config); $paragraphs := nqp::decont($paragraphs); $directive := nqp::decont($directive); $for := nqp::decont($for); $abbreviated := nqp::decont($abbreviated); #line 62 src/Raku/ast/doc-block.rakumod my $obj := nqp::create($SELF); $obj.set-margin($margin); $obj.set-type($type); $obj.set-level($level); $obj.set-config($config); $obj.set-paragraphs($paragraphs); my int $status := $directive ?? 3 !! $abbreviated ?? 2 !! $for ?? 1 !! 0; nqp::bindattr_i($obj,RakuAST::Doc::Block,'$!status',$status); if nqp::isconcrete($*LEGACY-POD-INDEX) { nqp::bindattr_i($obj,RakuAST::Doc::Block, '$!pod-index', $*LEGACY-POD-INDEX++); } else { nqp::bindattr_i($obj,RakuAST::Doc::Block,'$!pod-index',-1); } $obj }); add-method(RakuAST::Doc::Block, 'set-margin', [RakuAST::Doc::Block, '', 0, 0, Str, '$margin', 0, 0], anon sub set-margin ($SELF_CONT, $margin!) { my $SELF := nqp::decont($SELF_CONT); $margin := nqp::decont($margin); #line 84 src/Raku/ast/doc-block.rakumod nqp::bindattr_s($SELF, RakuAST::Doc::Block, '$!margin', $margin // ""); Nil }); add-method(RakuAST::Doc::Block, 'set-type', [RakuAST::Doc::Block, '', 0, 0, Str, '$type', 0, 0], anon sub set-type ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 89 src/Raku/ast/doc-block.rakumod nqp::bindattr_s($SELF, RakuAST::Doc::Block, '$!type', $type // nqp::die("Must specify a type")); Nil }); add-method(RakuAST::Doc::Block, 'set-level', [RakuAST::Doc::Block, '', 0, 0, Int, '$level', 0, 0], anon sub set-level ($SELF_CONT, $level!) { my $SELF := nqp::decont($SELF_CONT); $level := nqp::decont($level); #line 95 src/Raku/ast/doc-block.rakumod nqp::bindattr_i($SELF, RakuAST::Doc::Block, '$!level', $level // 0); Nil }); add-method(RakuAST::Doc::Block, 'level', [RakuAST::Doc::Block, '', 0, 0], anon sub level ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 99 src/Raku/ast/doc-block.rakumod nqp::getattr_i($SELF, RakuAST::Doc::Block, '$!level') ?? ~nqp::getattr_i($SELF, RakuAST::Doc::Block, '$!level') !! "" }); add-method(RakuAST::Doc::Block, 'set-config', [RakuAST::Doc::Block, '', 0, 0, Any, '$config', 0, 0], anon sub set-config ($SELF_CONT, $config!) { my $SELF := nqp::decont($SELF_CONT); $config := nqp::decont($config); #line 101 src/Raku/ast/doc-block.rakumod nqp::bindattr($SELF, RakuAST::Doc::Block, '$!config', $config ?? $SELF.IMPL-UNWRAP-MAP($config) !! nqp::hash); Nil }); add-method(RakuAST::Doc::Block, 'add-config', [RakuAST::Doc::Block, '', 0, 0, Str, '$key', 0, 0, Any, '$value', 0, 0], anon sub add-config ($SELF_CONT, $key!, $value!) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); $value := nqp::decont($value); #line 106 src/Raku/ast/doc-block.rakumod nqp::bindkey(nqp::getattr($SELF, RakuAST::Doc::Block, '$!config'), $key, $value) }); add-method(RakuAST::Doc::Block, 'config', [RakuAST::Doc::Block, '', 0, 0], anon sub config ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 109 src/Raku/ast/doc-block.rakumod $SELF.IMPL-WRAP-MAP(nqp::getattr($SELF, RakuAST::Doc::Block, '$!config')) }); add-method(RakuAST::Doc::Block, 'set-paragraphs', [RakuAST::Doc::Block, '', 0, 0, Any, '$paragraphs', 0, 0], anon sub set-paragraphs ($SELF_CONT, $paragraphs!) { my $SELF := nqp::decont($SELF_CONT); $paragraphs := nqp::decont($paragraphs); #line 111 src/Raku/ast/doc-block.rakumod nqp::bindattr($SELF, RakuAST::Doc::Block, '$!paragraphs', $paragraphs ?? $SELF.IMPL-UNWRAP-LIST($paragraphs) !! nqp::list); Nil }); add-method(RakuAST::Doc::Block, 'add-paragraph', [RakuAST::Doc::Block, '', 0, 0, Any, '$paragraph', 0, 0, Any, '$at-start', 1, 1], anon sub add-paragraph ($SELF_CONT, $paragraph!, :$at-start?) { my $SELF := nqp::decont($SELF_CONT); $paragraph := nqp::decont($paragraph); $at-start := nqp::decont($at-start); #line 118 src/Raku/ast/doc-block.rakumod $at-start ?? nqp::unshift(nqp::getattr($SELF, RakuAST::Doc::Block, '$!paragraphs'), $paragraph) !! nqp::push( nqp::getattr($SELF, RakuAST::Doc::Block, '$!paragraphs'), $paragraph) }); add-method(RakuAST::Doc::Block, 'paragraphs', [RakuAST::Doc::Block, '', 0, 0], anon sub paragraphs ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 123 src/Raku/ast/doc-block.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Doc::Block, '$!paragraphs')) }); add-method(RakuAST::Doc::Block, 'delimited', [RakuAST::Doc::Block, '', 0, 0], anon sub delimited ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 125 src/Raku/ast/doc-block.rakumod nqp::getattr_i($SELF, RakuAST::Doc::Block, '$!status') == 0 }); add-method(RakuAST::Doc::Block, 'for', [RakuAST::Doc::Block, '', 0, 0], anon sub for ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 126 src/Raku/ast/doc-block.rakumod nqp::getattr_i($SELF, RakuAST::Doc::Block, '$!status') == 1 }); add-method(RakuAST::Doc::Block, 'abbreviated', [RakuAST::Doc::Block, '', 0, 0], anon sub abbreviated ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 127 src/Raku/ast/doc-block.rakumod nqp::getattr_i($SELF, RakuAST::Doc::Block, '$!status') >= 2 }); add-method(RakuAST::Doc::Block, 'directive', [RakuAST::Doc::Block, '', 0, 0], anon sub directive ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 128 src/Raku/ast/doc-block.rakumod nqp::getattr_i($SELF, RakuAST::Doc::Block, '$!status') == 3 }); add-method(RakuAST::Doc::Block, 'visit-children', [RakuAST::Doc::Block, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 130 src/Raku/ast/doc-block.rakumod for nqp::getattr($SELF, RakuAST::Doc::Block, '$!paragraphs') { if nqp::istype($_,RakuAST::Doc::Block) { my $*INNER-BLOCK := (Bool.WHO); $visitor($_); } elsif nqp::istype($_,RakuAST::Node) { $visitor($_); } } }); add-method(RakuAST::Doc::Block, 'PERFORM-CHECK', [RakuAST::Doc::Block, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 145 src/Raku/ast/doc-block.rakumod my $failed := $SELF.literalize-config; if nqp::eqaddr($failed,RakuAST::Node::CannotLiteralize) { $SELF.add-sorry: $resolver.build-exception: 'X::AdHoc', payload => "'$failed' is not constant in configuration"; } # in an outermost block unless $*INNER-BLOCK { my $cu := $resolver.find-attach-target('compunit'); if nqp::getattr_s($SELF, RakuAST::Doc::Block, '$!type') eq 'data' { my $store := $cu.data-content; my $data := $SELF.Str.trim-trailing; (my $key := nqp::getattr($SELF, RakuAST::Doc::Block, '$!config')) ?? $store.ASSIGN-KEY($key, $data) !! $store.push($data); } $cu.set-pod-content(nqp::getattr_i($SELF, RakuAST::Doc::Block, '$!pod-index'), $SELF.podify); } (Bool.WHO) }); #line 46 src/Raku/ast/doc-block.rakumod add-method(RakuAST::Doc::Block, 'type', [], anon sub type ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Doc::Block, '$!type') }); #line 45 src/Raku/ast/doc-block.rakumod add-method(RakuAST::Doc::Block, 'margin', [], anon sub margin ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Doc::Block, '$!margin') }); compose(RakuAST::Doc::Block); parent(RakuAST::Doc::Markup, RakuAST::Doc); add-attribute(RakuAST::Doc::Markup, str, '$!letter'); add-attribute(RakuAST::Doc::Markup, str, '$!opener'); add-attribute(RakuAST::Doc::Markup, str, '$!closer'); add-attribute(RakuAST::Doc::Markup, List, '$!atoms'); add-attribute(RakuAST::Doc::Markup, List, '$!meta'); add-method(RakuAST::Doc::Markup, 'new', [RakuAST::Doc::Markup, '', 0, 0, Any, '$letter', 1, 0, Any, '$opener', 1, 1, Any, '$closer', 1, 1, Any, '$atoms', 1, 1, Any, '$meta', 1, 1], anon sub new ($SELF_CONT, :$letter!, :$opener?, :$closer?, :$atoms?, :$meta?) { my $SELF := nqp::decont($SELF_CONT); $letter := nqp::decont($letter); $opener := nqp::decont($opener); $closer := nqp::decont($closer); $atoms := nqp::decont($atoms); $meta := nqp::decont($meta); #line 181 src/Raku/ast/doc-block.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Doc::Markup, '$!letter', $letter // nqp::die("Must specify a letter")); $obj.set-opener($opener // '<'); $obj.set-closer($closer // '>'); $obj.set-atoms($atoms); $obj.set-meta($meta); $obj }); add-method(RakuAST::Doc::Markup, 'visit-children', [RakuAST::Doc::Markup, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 193 src/Raku/ast/doc-block.rakumod for nqp::getattr($SELF, RakuAST::Doc::Markup, '$!atoms') { if nqp::istype($_,RakuAST::Node) { $visitor($_); } } for nqp::getattr($SELF, RakuAST::Doc::Markup, '$!meta') { if nqp::istype($_,RakuAST::Node) { $visitor($_); } } }); add-method(RakuAST::Doc::Markup, 'set-opener', [RakuAST::Doc::Markup, '', 0, 0, str, '$opener', 0, 0], anon sub set-opener ($SELF_CONT, $opener!) { my $SELF := nqp::decont($SELF_CONT); $opener := nqp::decont($opener); #line 206 src/Raku/ast/doc-block.rakumod nqp::bindattr_s($SELF,RakuAST::Doc::Markup,'$!opener',$opener); Nil }); add-method(RakuAST::Doc::Markup, 'set-closer', [RakuAST::Doc::Markup, '', 0, 0, str, '$closer', 0, 0], anon sub set-closer ($SELF_CONT, $closer!) { my $SELF := nqp::decont($SELF_CONT); $closer := nqp::decont($closer); #line 211 src/Raku/ast/doc-block.rakumod nqp::bindattr_s($SELF,RakuAST::Doc::Markup,'$!closer',$closer); Nil }); add-method(RakuAST::Doc::Markup, 'set-atoms', [RakuAST::Doc::Markup, '', 0, 0, Any, '$atoms', 0, 1], anon sub set-atoms ($SELF_CONT, $atoms?) { my $SELF := nqp::decont($SELF_CONT); $atoms := nqp::decont($atoms); #line 216 src/Raku/ast/doc-block.rakumod nqp::bindattr($SELF, RakuAST::Doc::Markup, '$!atoms', $atoms ?? $SELF.IMPL-UNWRAP-LIST($atoms) !! []); Nil }); add-method(RakuAST::Doc::Markup, 'add-atom', [RakuAST::Doc::Markup, '', 0, 0, Any, '$atom', 0, 0], anon sub add-atom ($SELF_CONT, $atom!) { my $SELF := nqp::decont($SELF_CONT); $atom := nqp::decont($atom); #line 221 src/Raku/ast/doc-block.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Doc::Markup, '$!atoms'), $atom) }); add-method(RakuAST::Doc::Markup, 'atoms', [RakuAST::Doc::Markup, '', 0, 0], anon sub atoms ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 222 src/Raku/ast/doc-block.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Doc::Markup, '$!atoms')) }); add-method(RakuAST::Doc::Markup, 'set-meta', [RakuAST::Doc::Markup, '', 0, 0, Any, '$meta', 0, 1], anon sub set-meta ($SELF_CONT, $meta?) { my $SELF := nqp::decont($SELF_CONT); $meta := nqp::decont($meta); #line 224 src/Raku/ast/doc-block.rakumod nqp::bindattr($SELF, RakuAST::Doc::Markup, '$!meta', $meta ?? $SELF.IMPL-UNWRAP-LIST($meta) !! []); Nil }); add-method(RakuAST::Doc::Markup, 'add-meta', [RakuAST::Doc::Markup, '', 0, 0, Any, '$meta', 0, 0], anon sub add-meta ($SELF_CONT, $meta!) { my $SELF := nqp::decont($SELF_CONT); $meta := nqp::decont($meta); #line 229 src/Raku/ast/doc-block.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Doc::Markup, '$!meta'), $meta) }); add-method(RakuAST::Doc::Markup, 'meta', [RakuAST::Doc::Markup, '', 0, 0], anon sub meta ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 230 src/Raku/ast/doc-block.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Doc::Markup, '$!meta')) }); #line 176 src/Raku/ast/doc-block.rakumod add-method(RakuAST::Doc::Markup, 'opener', [], anon sub opener ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Doc::Markup, '$!opener') }); #line 175 src/Raku/ast/doc-block.rakumod add-method(RakuAST::Doc::Markup, 'letter', [], anon sub letter ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Doc::Markup, '$!letter') }); #line 177 src/Raku/ast/doc-block.rakumod add-method(RakuAST::Doc::Markup, 'closer', [], anon sub closer ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Doc::Markup, '$!closer') }); compose(RakuAST::Doc::Markup); parent(RakuAST::Doc::Declarator, RakuAST::Doc); parent(RakuAST::Doc::Declarator, RakuAST::CheckTime); add-attribute(RakuAST::Doc::Declarator, RakuAST::Doc::DeclaratorTarget, '$!WHEREFORE'); add-attribute(RakuAST::Doc::Declarator, List, '$!leading'); add-attribute(RakuAST::Doc::Declarator, List, '$!trailing'); add-attribute(RakuAST::Doc::Declarator, int, '$!pod-index'); add-attribute(RakuAST::Doc::Declarator, List, '$!paragraphs'); add-method(RakuAST::Doc::Declarator, 'new', [RakuAST::Doc::Declarator, '', 0, 0, Any, '$WHEREFORE', 1, 1, Any, '$leading', 1, 1, Any, '$trailing', 1, 1], anon sub new ($SELF_CONT, :$WHEREFORE?, :$leading?, :$trailing?) { my $SELF := nqp::decont($SELF_CONT); $WHEREFORE := nqp::decont($WHEREFORE); $leading := nqp::decont($leading); $trailing := nqp::decont($trailing); #line 12 src/Raku/ast/doc-declarator.rakumod my $obj := nqp::create($SELF); $obj.set-WHEREFORE($WHEREFORE); $obj.set-leading($leading); $obj.set-trailing($trailing); if nqp::isconcrete($*LEGACY-POD-INDEX) { nqp::bindattr_i($obj,RakuAST::Doc::Declarator, '$!pod-index', $*LEGACY-POD-INDEX++); } else { nqp::bindattr_i($obj,RakuAST::Doc::Declarator,'$!pod-index',-1); } $obj }); add-method(RakuAST::Doc::Declarator, 'visit-children', [RakuAST::Doc::Declarator, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 28 src/Raku/ast/doc-declarator.rakumod $visitor(nqp::getattr($SELF, RakuAST::Doc::Declarator, '$!WHEREFORE')) unless nqp::eqaddr(nqp::getattr($SELF, RakuAST::Doc::Declarator, '$!WHEREFORE').WHY,$SELF); }); add-method(RakuAST::Doc::Declarator, 'set-WHEREFORE', [RakuAST::Doc::Declarator, '', 0, 0, Mu, '$WHEREFORE', 0, 0], anon sub set-WHEREFORE ($SELF_CONT, $WHEREFORE!) { my $SELF := nqp::decont($SELF_CONT); $WHEREFORE := nqp::decont($WHEREFORE); #line 32 src/Raku/ast/doc-declarator.rakumod nqp::bindattr($SELF, RakuAST::Doc::Declarator, '$!WHEREFORE', $WHEREFORE); Nil }); add-method(RakuAST::Doc::Declarator, 'set-leading', [RakuAST::Doc::Declarator, '', 0, 0, Any, '$leading', 0, 0], anon sub set-leading ($SELF_CONT, $leading!) { my $SELF := nqp::decont($SELF_CONT); $leading := nqp::decont($leading); #line 38 src/Raku/ast/doc-declarator.rakumod nqp::bindattr($SELF, RakuAST::Doc::Declarator, '$!leading', $leading ?? $SELF.IMPL-UNWRAP-LIST($leading) !! []); Nil }); add-method(RakuAST::Doc::Declarator, 'add-leading', [RakuAST::Doc::Declarator, '', 0, 0, Any, '$doc', 0, 0], anon sub add-leading ($SELF_CONT, $doc!) { my $SELF := nqp::decont($SELF_CONT); $doc := nqp::decont($doc); #line 43 src/Raku/ast/doc-declarator.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Doc::Declarator, '$!leading'), $doc) }); add-method(RakuAST::Doc::Declarator, 'leading', [RakuAST::Doc::Declarator, '', 0, 0], anon sub leading ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 44 src/Raku/ast/doc-declarator.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Doc::Declarator, '$!leading')) }); add-method(RakuAST::Doc::Declarator, 'set-trailing', [RakuAST::Doc::Declarator, '', 0, 0, Any, '$trailing', 0, 0], anon sub set-trailing ($SELF_CONT, $trailing!) { my $SELF := nqp::decont($SELF_CONT); $trailing := nqp::decont($trailing); #line 46 src/Raku/ast/doc-declarator.rakumod nqp::bindattr($SELF, RakuAST::Doc::Declarator, '$!trailing', $trailing ?? $SELF.IMPL-UNWRAP-LIST($trailing) !! []); Nil }); add-method(RakuAST::Doc::Declarator, 'add-trailing', [RakuAST::Doc::Declarator, '', 0, 0, Any, '$doc', 0, 0], anon sub add-trailing ($SELF_CONT, $doc!) { my $SELF := nqp::decont($SELF_CONT); $doc := nqp::decont($doc); #line 51 src/Raku/ast/doc-declarator.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Doc::Declarator, '$!trailing'), $doc) }); add-method(RakuAST::Doc::Declarator, 'trailing', [RakuAST::Doc::Declarator, '', 0, 0], anon sub trailing ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 52 src/Raku/ast/doc-declarator.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Doc::Declarator, '$!trailing')) }); add-method(RakuAST::Doc::Declarator, 'PERFORM-CHECK', [RakuAST::Doc::Declarator, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 55 src/Raku/ast/doc-declarator.rakumod if nqp::getattr($SELF, RakuAST::Doc::Declarator, '$!WHEREFORE') { my $meta := nqp::getattr($SELF, RakuAST::Doc::Declarator, '$!WHEREFORE').meta-object; if $meta.HOW.name($meta) ne 'Any' { $resolver.find-attach-target('compunit').set-pod-content( nqp::getattr_i($SELF, RakuAST::Doc::Declarator, '$!pod-index'), $SELF.podify($meta) ); } } else { $SELF.add-worry: $resolver.build-exception: 'X::Syntax::Doc::Declarator::MissingDeclarand'; } (Bool.WHO) }); #line 6 src/Raku/ast/doc-declarator.rakumod add-method(RakuAST::Doc::Declarator, 'WHEREFORE', [], anon sub WHEREFORE ($self) { nqp::getattr(nqp::decont($self), RakuAST::Doc::Declarator, '$!WHEREFORE') }); compose(RakuAST::Doc::Declarator); parent(RakuAST::Doc::DeclaratorTarget, Any); add-attribute(RakuAST::Doc::DeclaratorTarget, RakuAST::Doc::Declarator, '$!WHY'); add-method(RakuAST::Doc::DeclaratorTarget, 'declarator-docs', [RakuAST::Doc::DeclaratorTarget, '', 0, 0, Any, '$leading', 1, 1, Any, '$trailing', 1, 1], anon sub declarator-docs ($SELF_CONT, :$leading?, :$trailing?) { my $SELF := nqp::decont($SELF_CONT); $leading := nqp::decont($leading); $trailing := nqp::decont($trailing); #line 78 src/Raku/ast/doc-declarator.rakumod nqp::bindattr($SELF, RakuAST::Doc::DeclaratorTarget, '$!WHY', RakuAST::Doc::Declarator.new(:WHEREFORE($SELF), :$leading, :$trailing) ); $SELF }); add-method(RakuAST::Doc::DeclaratorTarget, 'set-WHY', [RakuAST::Doc::DeclaratorTarget, '', 0, 0, RakuAST::Doc::Declarator, '$WHY', 0, 0], anon sub set-WHY ($SELF_CONT, $WHY!) { my $SELF := nqp::decont($SELF_CONT); $WHY := nqp::decont($WHY); #line 85 src/Raku/ast/doc-declarator.rakumod if $WHY { nqp::bindattr($SELF, RakuAST::Doc::DeclaratorTarget, '$!WHY', $WHY); $WHY.set-WHEREFORE($SELF); } Nil }); add-method(RakuAST::Doc::DeclaratorTarget, 'cut-WHY', [RakuAST::Doc::DeclaratorTarget, '', 0, 0], anon sub cut-WHY ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 93 src/Raku/ast/doc-declarator.rakumod my $WHY := nqp::getattr($SELF,RakuAST::Doc::DeclaratorTarget,'$!WHY'); nqp::bindattr($SELF,RakuAST::Doc::DeclaratorTarget,'$!WHY', RakuAST::Doc::Declarator); $WHY }); add-method(RakuAST::Doc::DeclaratorTarget, 'set-leading', [RakuAST::Doc::DeclaratorTarget, '', 0, 0, Any, '$doc', 0, 0], anon sub set-leading ($SELF_CONT, $doc!) { my $SELF := nqp::decont($SELF_CONT); $doc := nqp::decont($doc); #line 100 src/Raku/ast/doc-declarator.rakumod (my $WHY := $SELF.WHY) ?? $WHY.set-leading($doc) !! $SELF.set-WHY(RakuAST::Doc::Declarator.new( WHEREFORE => $SELF, leading => $doc )); Nil }); add-method(RakuAST::Doc::DeclaratorTarget, 'add-leading', [RakuAST::Doc::DeclaratorTarget, '', 0, 0, Any, '$doc', 0, 0], anon sub add-leading ($SELF_CONT, $doc!) { my $SELF := nqp::decont($SELF_CONT); $doc := nqp::decont($doc); #line 109 src/Raku/ast/doc-declarator.rakumod (my $WHY := $SELF.WHY) ?? $WHY.add-leading($doc) !! $SELF.set-WHY(RakuAST::Doc::Declarator.new( WHEREFORE => $SELF, leading => $doc )); Nil }); add-method(RakuAST::Doc::DeclaratorTarget, 'set-trailing', [RakuAST::Doc::DeclaratorTarget, '', 0, 0, Any, '$doc', 0, 0], anon sub set-trailing ($SELF_CONT, $doc!) { my $SELF := nqp::decont($SELF_CONT); $doc := nqp::decont($doc); #line 118 src/Raku/ast/doc-declarator.rakumod (my $WHY := $SELF.WHY) ?? $WHY.set-trailing($doc) !! $SELF.set-WHY(RakuAST::Doc::Declarator.new( WHEREFORE => $SELF, trailing => $doc )); Nil }); add-method(RakuAST::Doc::DeclaratorTarget, 'add-trailing', [RakuAST::Doc::DeclaratorTarget, '', 0, 0, Any, '$doc', 0, 0], anon sub add-trailing ($SELF_CONT, $doc!) { my $SELF := nqp::decont($SELF_CONT); $doc := nqp::decont($doc); #line 127 src/Raku/ast/doc-declarator.rakumod (my $WHY := $SELF.WHY) ?? $WHY.add-trailing($doc) !! $SELF.set-WHY(RakuAST::Doc::Declarator.new( WHEREFORE => $SELF, trailing => $doc )); Nil }); #line 74 src/Raku/ast/doc-declarator.rakumod add-method(RakuAST::Doc::DeclaratorTarget, 'WHY', [], anon sub WHY ($self) { nqp::getattr(nqp::decont($self), RakuAST::Doc::DeclaratorTarget, '$!WHY') }); compose(RakuAST::Doc::DeclaratorTarget); parent(RakuAST::Blorst, RakuAST::Node); add-method(RakuAST::Blorst, 'as-block', [RakuAST::Blorst, '', 0, 0], anon sub as-block ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 6 src/Raku/ast/statements.rakumod nqp::die("RakuAST::Blorst classes must define 'as-block'. " ~ $SELF.HOW.name($SELF) ~ " does not.") }); compose(RakuAST::Blorst); parent(RakuAST::Contextualizable, RakuAST::Node); compose(RakuAST::Contextualizable); parent(RakuAST::Label, RakuAST::Declaration); parent(RakuAST::Label, RakuAST::ImplicitLookups); parent(RakuAST::Label, RakuAST::Meta); add-attribute(RakuAST::Label, str, '$!name'); add-method(RakuAST::Label, 'new', [RakuAST::Label, '', 0, 0, str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 24 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Label, '$!name', $name); $obj }); add-method(RakuAST::Label, 'default-scope', [RakuAST::Label, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 30 src/Raku/ast/statements.rakumod 'my' }); add-method(RakuAST::Label, 'allowed-scopes', [RakuAST::Label, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 32 src/Raku/ast/statements.rakumod ['my'] }); add-method(RakuAST::Label, 'lexical-name', [RakuAST::Label, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 34 src/Raku/ast/statements.rakumod nqp::getattr_s($SELF, RakuAST::Label, '$!name') }); add-method(RakuAST::Label, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Label, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 36 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Label')), ]) }); add-method(RakuAST::Label, 'PRODUCE-META-OBJECT', [RakuAST::Label, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 42 src/Raku/ast/statements.rakumod my $label-type := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; # TODO line, prematch, postmatch $label-type.new(:name(nqp::getattr_s($SELF, RakuAST::Label, '$!name')), :line(0), :prematch(''), :postmatch('')) }); add-method(RakuAST::Label, 'IMPL-QAST-DECL', [RakuAST::Label, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 49 src/Raku/ast/statements.rakumod QAST::Var.new( :scope('lexical'), :decl('static'), :name(nqp::getattr_s($SELF, RakuAST::Label, '$!name')), :value($SELF.meta-object) ) }); add-method(RakuAST::Label, 'IMPL-LOOKUP-QAST', [RakuAST::Label, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$rvalue', 1, 1], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!, :$rvalue?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $rvalue := nqp::decont($rvalue); #line 56 src/Raku/ast/statements.rakumod my $label := $SELF.meta-object; $context.ensure-sc($label); QAST::WVal.new( :value($label) ) }); #line 22 src/Raku/ast/statements.rakumod add-method(RakuAST::Label, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Label, '$!name') }); compose(RakuAST::Label); parent(RakuAST::Statement, RakuAST::Blorst); add-attribute(RakuAST::Statement, Mu, '$!labels'); add-attribute(RakuAST::Statement, int, '$!trace'); add-attribute(RakuAST::Statement, int, '$!statement-id'); add-attribute(RakuAST::Statement, Mu, '$!doc-blocks'); add-method(RakuAST::Statement, 'set-labels', [RakuAST::Statement, '', 0, 0, List, '$labels', 0, 0], anon sub set-labels ($SELF_CONT, $labels!) { my $SELF := nqp::decont($SELF_CONT); $labels := nqp::decont($labels); #line 76 src/Raku/ast/statements.rakumod nqp::bindattr($SELF, RakuAST::Statement, '$!labels', $labels ?? $SELF.IMPL-UNWRAP-LIST($labels) !! []); Nil }); add-method(RakuAST::Statement, 'add-label', [RakuAST::Statement, '', 0, 0, RakuAST::Label, '$label', 0, 0], anon sub add-label ($SELF_CONT, $label!) { my $SELF := nqp::decont($SELF_CONT); $label := nqp::decont($label); #line 81 src/Raku/ast/statements.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Statement, '$!labels'), $label); Nil }); add-method(RakuAST::Statement, 'labels', [RakuAST::Statement, '', 0, 0], anon sub labels ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 85 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Statement, '$!labels')) }); add-method(RakuAST::Statement, 'attach-doc-blocks', [RakuAST::Statement, '', 0, 0], anon sub attach-doc-blocks ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 88 src/Raku/ast/statements.rakumod my @collected := $*DOC-BLOCKS-COLLECTED; if nqp::elems(@collected) { nqp::bindattr($SELF, RakuAST::Statement, '$!doc-blocks', @collected); $*DOC-BLOCKS-COLLECTED := []; } }); add-method(RakuAST::Statement, 'add-to-statements', [RakuAST::Statement, '', 0, 0, Any, '$statements', 0, 0], anon sub add-to-statements ($SELF_CONT, $statements!) { my $SELF := nqp::decont($SELF_CONT); $statements := nqp::decont($statements); #line 98 src/Raku/ast/statements.rakumod if nqp::getattr($SELF, RakuAST::Statement, '$!doc-blocks') { for nqp::getattr($SELF, RakuAST::Statement, '$!doc-blocks') { $statements.add-doc-block($_); } } $statements.add-statement($SELF); Nil }); add-method(RakuAST::Statement, 'set-statement-id', [RakuAST::Statement, '', 0, 0, int, '$statement-id', 0, 0], anon sub set-statement-id ($SELF_CONT, $statement-id!) { my $SELF := nqp::decont($SELF_CONT); $statement-id := nqp::decont($statement-id); #line 108 src/Raku/ast/statements.rakumod nqp::bindattr_i($SELF, RakuAST::Statement, '$!statement-id', $statement-id); }); add-method(RakuAST::Statement, 'set-trace', [RakuAST::Statement, '', 0, 0, Bool, '$trace', 0, 0], anon sub set-trace ($SELF_CONT, $trace!) { my $SELF := nqp::decont($SELF_CONT); $trace := nqp::decont($trace); #line 112 src/Raku/ast/statements.rakumod nqp::bindattr_i($SELF, RakuAST::Statement, '$!trace', $trace ?? 1 !! 0); }); add-method(RakuAST::Statement, 'visit-labels', [RakuAST::Statement, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-labels ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 116 src/Raku/ast/statements.rakumod for nqp::getattr($SELF, RakuAST::Statement, '$!labels') { $visitor($_); } Nil }); add-method(RakuAST::Statement, 'IMPL-DISCARD-RESULT', [RakuAST::Statement, '', 0, 0], anon sub IMPL-DISCARD-RESULT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 123 src/Raku/ast/statements.rakumod (Bool.WHO) }); add-method(RakuAST::Statement, 'IMPL-WRAP-WHEN-OR-DEFAULT', [RakuAST::Statement, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$qast', 0, 0], anon sub IMPL-WRAP-WHEN-OR-DEFAULT ($SELF_CONT, $context!, $qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $qast := nqp::decont($qast); #line 127 src/Raku/ast/statements.rakumod my $succeed-qast := QAST::Op.new( :op('call'), :name('&succeed'), $qast ); QAST::Op.new( :op('handle'), $succeed-qast, 'PROCEED', QAST::Op.new( :op('getpayload'), QAST::Op.new( :op('exception') ) ) ) }); add-method(RakuAST::Statement, 'as-block', [RakuAST::Statement, '', 0, 0], anon sub as-block ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 140 src/Raku/ast/statements.rakumod RakuAST::Block.new: :body(RakuAST::Blockoid.new: RakuAST::StatementList.new: $SELF) }); #line 68 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement, 'trace', [], anon sub trace ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Statement, '$!trace') }); #line 69 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement, 'statement-id', [], anon sub statement-id ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Statement, '$!statement-id') }); compose(RakuAST::Statement); parent(RakuAST::ImplicitBlockSemanticsProvider, RakuAST::Node); add-method(RakuAST::ImplicitBlockSemanticsProvider, 'apply-implicit-block-semantics', [RakuAST::ImplicitBlockSemanticsProvider, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 152 src/Raku/ast/statements.rakumod nqp::die('apply-implicit-block-semantics not implemented by ' ~ $SELF.HOW.name($SELF)); }); compose(RakuAST::ImplicitBlockSemanticsProvider); parent(RakuAST::ForLoopImplementation, RakuAST::Node); add-method(RakuAST::ForLoopImplementation, 'IMPL-FOR-QAST', [RakuAST::ForLoopImplementation, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$mode', 0, 0, str, '$after-mode', 0, 0, Mu, '$source-qast', 0, 0, Mu, '$body-qast', 0, 0, RakuAST::Label, '$label', 0, 1], anon sub IMPL-FOR-QAST ($SELF_CONT, $context!, $mode!, $after-mode!, $source-qast!, $body-qast!, $label?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $mode := nqp::decont($mode); $after-mode := nqp::decont($after-mode); $source-qast := nqp::decont($source-qast); $body-qast := nqp::decont($body-qast); $label := nqp::decont($label); #line 161 src/Raku/ast/statements.rakumod # TODO various optimized forms are possible here $SELF.IMPL-TO-QAST-GENERAL($context, $mode, $after-mode, $source-qast, $body-qast, $label // RakuAST::Label) }); add-method(RakuAST::ForLoopImplementation, 'IMPL-TO-QAST-GENERAL', [RakuAST::ForLoopImplementation, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$mode', 0, 0, str, '$after-mode', 0, 0, Mu, '$source-qast', 0, 0, Mu, '$body-qast', 0, 0, RakuAST::Label, '$label', 0, 0], anon sub IMPL-TO-QAST-GENERAL ($SELF_CONT, $context!, $mode!, $after-mode!, $source-qast!, $body-qast!, $label!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $mode := nqp::decont($mode); $after-mode := nqp::decont($after-mode); $source-qast := nqp::decont($source-qast); $body-qast := nqp::decont($body-qast); $label := nqp::decont($label); #line 170 src/Raku/ast/statements.rakumod # Bind the source into a temporary. my $for-list-name := QAST::Node.unique('for-list'); my $bind-source := QAST::Op.new( :op('bind'), QAST::Var.new( :name($for-list-name), :scope('local'), :decl('var') ), $source-qast ); # Produce the map call. my $map-call := QAST::Op.new( :op('if'), QAST::Op.new( :op('iscont'), QAST::Var.new( :name($for-list-name), :scope('local') ) ), QAST::Op.new( :op, :name, QAST::Var.new( :name($for-list-name), :scope('local') ), $body-qast, QAST::IVal.new( :value(1), :named('item') ) ), QAST::Op.new( :op, :name, QAST::Op.new( :op, :name($mode), QAST::Var.new( :name($for-list-name), :scope('local') ) ), $body-qast ) ); if $label { my $label-qast := $label.IMPL-LOOKUP-QAST($context); $label-qast.named('label'); $map-call[1].push($label-qast); $map-call[2].push($label-qast); } # Apply after mode to the map result, and we're done. $SELF.IMPL-SET-NODE( QAST::Stmts.new( $bind-source, QAST::Op.new( :op, :name($after-mode), $map-call )), :key) }); compose(RakuAST::ForLoopImplementation); parent(RakuAST::StatementList, RakuAST::SinkPropagator); parent(RakuAST::StatementList, RakuAST::ImplicitLookups); add-attribute(RakuAST::StatementList, List, '$!statements'); add-attribute(RakuAST::StatementList, int, '$!is-sunk'); add-attribute(RakuAST::StatementList, Mu, '$!code-statements'); add-method(RakuAST::StatementList, 'new', [RakuAST::StatementList, '', 0, 0, Any, '@statements', 0, 0, Bool, '$trace', 1, 1], anon sub new ($SELF_CONT, *@statements, :$trace?) { my $SELF := nqp::decont($SELF_CONT); @statements := nqp::decont(@statements); $trace := nqp::decont($trace); #line 222 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::StatementList, '$!statements',@statements); nqp::bindattr_i($obj, RakuAST::StatementList, '$!is-sunk', 0); # make sure any code statements are known in the internal code-only list my @code; nqp::bindattr($obj, RakuAST::StatementList, '$!code-statements', @code); for @statements { unless nqp::istype($_,RakuAST::Doc::Block) { nqp::push(@code,$_); } } $obj }); add-method(RakuAST::StatementList, 'add-doc-block', [RakuAST::StatementList, '', 0, 0, RakuAST::Statement, '$doc-block', 0, 0], anon sub add-doc-block ($SELF_CONT, $doc-block!) { my $SELF := nqp::decont($SELF_CONT); $doc-block := nqp::decont($doc-block); #line 239 src/Raku/ast/statements.rakumod nqp::push(nqp::getattr($SELF, RakuAST::StatementList, '$!statements'), $doc-block); }); add-method(RakuAST::StatementList, 'add-statement', [RakuAST::StatementList, '', 0, 0, RakuAST::Statement, '$statement', 0, 0], anon sub add-statement ($SELF_CONT, $statement!) { my $SELF := nqp::decont($SELF_CONT); $statement := nqp::decont($statement); #line 242 src/Raku/ast/statements.rakumod nqp::push( nqp::getattr($SELF, RakuAST::StatementList, '$!statements'), $statement); nqp::push(nqp::getattr($SELF, RakuAST::StatementList, '$!code-statements'), $statement); }); add-method(RakuAST::StatementList, 'statements', [RakuAST::StatementList, '', 0, 0], anon sub statements ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 246 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::StatementList, '$!statements')) }); add-method(RakuAST::StatementList, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::StatementList, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 250 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Blob')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Nil')), ]) }); add-method(RakuAST::StatementList, 'IMPL-TO-QAST', [RakuAST::StatementList, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '$immediate', 1, 1], anon sub IMPL-TO-QAST ($SELF_CONT, $context!, :$immediate?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $immediate := nqp::decont($immediate); #line 257 src/Raku/ast/statements.rakumod my $stmts := $SELF.IMPL-SET-NODE(QAST::Stmts.new, :key); my @statements := $SELF.code-statements; my $Nil := $SELF.get-implicit-lookups.AT-POS(1); for @statements { my $qast := $_.IMPL-TO-QAST($context); my $stmt-orig := $_.origin; if nqp::isconcrete($stmt-orig) && $stmt-orig.is-key { $qast := QAST::Stmt.new( :node($stmt-orig.as-match), $qast ); } if $_.trace && nqp::isconcrete($stmt-orig) && !$*CU.precompilation-mode { my $Blob := $SELF.get-implicit-lookups.AT-POS(0).compile-time-value; $context.ensure-sc($Blob); my $line := $stmt-orig.source.original-line($stmt-orig.from); my $file := $stmt-orig.source.original-file; my $code := nqp::substr($stmt-orig.source.orig, $stmt-orig.from, $stmt-orig.to - $stmt-orig.from); if $code ne 'use trace' { my $id := $_.statement-id; $stmts.push(QAST::Op.new( :op, QAST::Op.new(:op), QAST::Op.new( :op('encode'), QAST::SVal.new(:value("$id ($file line $line)\n$code\n")), QAST::SVal.new(:value('utf8')), QAST::Op.new( :op('callmethod'), :name('new'), QAST::WVal.new( :value($Blob) ) ) ) )); } } $stmts.push($qast); } if !nqp::elems(@statements) { $stmts.push($Nil.IMPL-TO-QAST($context)); } else { my $last-stmt := @statements[nqp::elems(@statements) - 1]; if nqp::getattr_i($SELF, RakuAST::StatementList, '$!is-sunk') || $last-stmt.IMPL-DISCARD-RESULT { $stmts.push($Nil.IMPL-TO-QAST($context)); } else { my $last := $stmts[nqp::elems($stmts) - 1]; $last.final(1); $stmts.returns($last.returns); } } $stmts }); add-method(RakuAST::StatementList, 'propagate-sink', [RakuAST::StatementList, '', 0, 0, Bool, '$is-sunk', 0, 0, Bool, '$has-block-parent', 1, 1], anon sub propagate-sink ($SELF_CONT, $is-sunk!, :$has-block-parent?) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); $has-block-parent := nqp::decont($has-block-parent); #line 313 src/Raku/ast/statements.rakumod # Sink all statements, with the possible exception of the last one (only if # we are not sunk). my @statements := $SELF.code-statements; my int $i := 0; my int $n := nqp::elems(@statements); my int $wanted-statement := $is-sunk ?? -1 !! $n - 1; while $i < $n { my $cur-statement := @statements[$i]; $cur-statement.apply-sink($i == $wanted-statement ?? (Bool.WHO) !! (Bool.WHO)); if $has-block-parent && nqp::istype($cur-statement, RakuAST::BlockStatementSensitive) { $cur-statement.mark-block-statement(); } $i++; } nqp::bindattr_i($SELF, RakuAST::StatementList, '$!is-sunk', $is-sunk ?? 1 !! 0); Nil }); add-method(RakuAST::StatementList, 'visit-children', [RakuAST::StatementList, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 332 src/Raku/ast/statements.rakumod for nqp::getattr($SELF, RakuAST::StatementList, '$!statements') { $visitor($_); } }); add-method(RakuAST::StatementList, 'is-empty', [RakuAST::StatementList, '', 0, 0], anon sub is-empty ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 338 src/Raku/ast/statements.rakumod nqp::elems($SELF.code-statements) == 0 ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::StatementList, 'IMPL-IS-SINGLE-EXPRESSION', [RakuAST::StatementList, '', 0, 0], anon sub IMPL-IS-SINGLE-EXPRESSION ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 342 src/Raku/ast/statements.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::StatementList, '$!statements')) == 1 && nqp::istype(nqp::getattr($SELF, RakuAST::StatementList, '$!statements')[0], RakuAST::Statement::Expression) }); add-method(RakuAST::StatementList, 'IMPL-CAN-INTERPRET', [RakuAST::StatementList, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 347 src/Raku/ast/statements.rakumod for $SELF.code-statements { return (Bool.WHO) unless $_.IMPL-CAN-INTERPRET; } (Bool.WHO) }); add-method(RakuAST::StatementList, 'IMPL-INTERPRET', [RakuAST::StatementList, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 354 src/Raku/ast/statements.rakumod my $result; my @statements := $SELF.code-statements; for @statements { $result := $_.IMPL-INTERPRET($ctx); } nqp::getattr_i($SELF, RakuAST::StatementList, '$!is-sunk') || !@statements || @statements[nqp::elems(@statements) - 1].IMPL-DISCARD-RESULT ?? $SELF.get-implicit-lookups.AT-POS(1).compile-time-value !! $result }); #line 220 src/Raku/ast/statements.rakumod add-method(RakuAST::StatementList, 'code-statements', [], anon sub code-statements ($self) { nqp::getattr(nqp::decont($self), RakuAST::StatementList, '$!code-statements') }); compose(RakuAST::StatementList); parent(RakuAST::SemiList, RakuAST::StatementList); parent(RakuAST::SemiList, RakuAST::ImplicitLookups); add-method(RakuAST::SemiList, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::SemiList, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 374 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical.new('&infix:<,>'), ]) }); add-method(RakuAST::SemiList, 'IMPL-TO-QAST', [RakuAST::SemiList, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 380 src/Raku/ast/statements.rakumod my @statements := $SELF.code-statements; my int $n := nqp::elems(@statements); if $n == 1 { nqp::atpos(@statements, 0).IMPL-TO-QAST($context) } else { my $name := $SELF.get-implicit-lookups.AT-POS(0).resolution.lexical-name; my $list := QAST::Op.new(:op('call'), :$name); for @statements { $list.push($_.IMPL-TO-QAST($context)); } $list } }); add-method(RakuAST::SemiList, 'IMPL-INTERPRET', [RakuAST::SemiList, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 397 src/Raku/ast/statements.rakumod my @statements := $SELF.code-statements; my int $n := nqp::elems(@statements); if $n == 1 { nqp::atpos(@statements, 0).IMPL-INTERPRET($ctx) } else { my @list; for @statements { nqp::push(@list, $_.IMPL-INTERPRET($ctx)); } $SELF.IMPL-WRAP-LIST(@list) } }); compose(RakuAST::SemiList); parent(RakuAST::StatementSequence, RakuAST::StatementList); parent(RakuAST::StatementSequence, RakuAST::ImplicitLookups); parent(RakuAST::StatementSequence, RakuAST::Contextualizable); add-method(RakuAST::StatementSequence, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::StatementSequence, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 422 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical.new('&infix:<,>'), ]) }); add-method(RakuAST::StatementSequence, 'IMPL-TO-QAST', [RakuAST::StatementSequence, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 428 src/Raku/ast/statements.rakumod my @statements; for $SELF.code-statements { @statements.push($_) unless nqp::istype($_,RakuAST::Statement::Empty); } my int $n := nqp::elems(@statements); if $n == 1 { nqp::atpos(@statements, 0).IMPL-TO-QAST($context) } elsif $n == 0 { my $name := $SELF.get-implicit-lookups.AT-POS(0).resolution.lexical-name; QAST::Op.new(:op('call'), :$name); } else { my $stmts := $SELF.IMPL-SET-NODE(QAST::Stmts.new, :key); for @statements { $stmts.push($_.IMPL-TO-QAST($context)); } $stmts } }); compose(RakuAST::StatementSequence); parent(RakuAST::ProducesNil, RakuAST::ImplicitLookups); add-method(RakuAST::ProducesNil, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::ProducesNil, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 458 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Nil')), ]) }); add-method(RakuAST::ProducesNil, 'IMPL-TO-QAST', [RakuAST::ProducesNil, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 464 src/Raku/ast/statements.rakumod $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context) }); compose(RakuAST::ProducesNil); parent(RakuAST::Statement::Empty, RakuAST::Statement); parent(RakuAST::Statement::Empty, RakuAST::ProducesNil); add-method(RakuAST::Statement::Empty, 'new', [RakuAST::Statement::Empty, '', 0, 0, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $labels := nqp::decont($labels); #line 475 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Empty, 'visit-children', [RakuAST::Statement::Empty, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 481 src/Raku/ast/statements.rakumod $SELF.visit-labels($visitor); }); compose(RakuAST::Statement::Empty); parent(RakuAST::Statement::Expression, RakuAST::Statement); parent(RakuAST::Statement::Expression, RakuAST::SinkPropagator); parent(RakuAST::Statement::Expression, RakuAST::Sinkable); parent(RakuAST::Statement::Expression, RakuAST::BlockStatementSensitive); parent(RakuAST::Statement::Expression, RakuAST::BeginTime); add-attribute(RakuAST::Statement::Expression, RakuAST::Expression, '$!expression'); add-attribute(RakuAST::Statement::Expression, RakuAST::StatementModifier::Condition, '$!condition-modifier'); add-attribute(RakuAST::Statement::Expression, RakuAST::StatementModifier::Loop, '$!loop-modifier'); add-method(RakuAST::Statement::Expression, 'new', [RakuAST::Statement::Expression, '', 0, 0, RakuAST::Expression, '$expression', 1, 0, List, '$labels', 1, 1, RakuAST::StatementModifier::Condition, '$condition-modifier', 1, 1, RakuAST::StatementModifier::Loop, '$loop-modifier', 1, 1], anon sub new ($SELF_CONT, :$expression!, :$labels?, :$condition-modifier?, :$loop-modifier?) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); $labels := nqp::decont($labels); $condition-modifier := nqp::decont($condition-modifier); $loop-modifier := nqp::decont($loop-modifier); #line 502 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); $obj.set-expression($expression); $obj.set-labels($labels); nqp::bindattr($obj, RakuAST::Statement::Expression, '$!condition-modifier', $condition-modifier // RakuAST::StatementModifier::Condition); nqp::bindattr($obj, RakuAST::Statement::Expression, '$!loop-modifier', $loop-modifier // RakuAST::StatementModifier::Loop); $obj }); add-method(RakuAST::Statement::Expression, 'set-expression', [RakuAST::Statement::Expression, '', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub set-expression ($SELF_CONT, $expression!) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); #line 513 src/Raku/ast/statements.rakumod nqp::bindattr($SELF, RakuAST::Statement::Expression, '$!expression', $expression // RakuAST::Expression); Nil }); add-method(RakuAST::Statement::Expression, 'replace-condition-modifier', [RakuAST::Statement::Expression, '', 0, 0, RakuAST::StatementModifier::Condition, '$condition-modifier', 0, 0], anon sub replace-condition-modifier ($SELF_CONT, $condition-modifier!) { my $SELF := nqp::decont($SELF_CONT); $condition-modifier := nqp::decont($condition-modifier); #line 519 src/Raku/ast/statements.rakumod nqp::bindattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier', $condition-modifier); Nil }); add-method(RakuAST::Statement::Expression, 'replace-loop-modifier', [RakuAST::Statement::Expression, '', 0, 0, RakuAST::StatementModifier::Loop, '$loop-modifier', 0, 0], anon sub replace-loop-modifier ($SELF_CONT, $loop-modifier!) { my $SELF := nqp::decont($SELF_CONT); $loop-modifier := nqp::decont($loop-modifier); #line 525 src/Raku/ast/statements.rakumod nqp::bindattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier', $loop-modifier); Nil }); add-method(RakuAST::Statement::Expression, 'IMPL-TO-QAST', [RakuAST::Statement::Expression, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 531 src/Raku/ast/statements.rakumod # If there is a condition modifier, and the expression is a block # with either an explicit signature or a placeholder signature, # we should compile it immediate in order that the arity is set # right and things like `{ say $^x } if $y` work. Blocks with no # signature aren't handled this way, since the $_ should not be # counted. my $qast; if nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier') && nqp::istype(nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression'), RakuAST::Block) && (nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').signature || nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').placeholder-signature) { $qast := nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier').IMPL-WRAP-QAST($context, nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').IMPL-TO-QAST($context, :immediate)); } else { $qast := nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').IMPL-TO-QAST($context); if $SELF.sunk && nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').needs-sink-call { $qast := QAST::Op.new( :op('p6sink'), $qast ); } $qast := nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier').IMPL-WRAP-QAST($context, $qast) if nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier') && !nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier'); } if nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier') { my $sink := $SELF.IMPL-DISCARD-RESULT; $qast := nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier').IMPL-WRAP-QAST($context, $qast, :$sink); } $qast }); add-method(RakuAST::Statement::Expression, 'IMPL-DISCARD-RESULT', [RakuAST::Statement::Expression, '', 0, 0], anon sub IMPL-DISCARD-RESULT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 558 src/Raku/ast/statements.rakumod ( $SELF.is-block-statement && nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier') && !nqp::istype(nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier'), RakuAST::StatementModifier::Given) || $SELF.sunk ) ?? 1 !! 0 }); add-method(RakuAST::Statement::Expression, 'propagate-sink', [RakuAST::Statement::Expression, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 567 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').apply-sink($is-sunk); nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier').apply-sink((Bool.WHO)) if nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier'); nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier').apply-sink((Bool.WHO)) if nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier'); }); add-method(RakuAST::Statement::Expression, 'mark-block-statement', [RakuAST::Statement::Expression, '', 0, 0], anon sub mark-block-statement ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 573 src/Raku/ast/statements.rakumod nqp::findmethod(RakuAST::BlockStatementSensitive, 'mark-block-statement')($SELF); if nqp::istype(nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression'), RakuAST::BlockStatementSensitive) { nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').mark-block-statement(); } }); add-method(RakuAST::Statement::Expression, 'PERFORM-BEGIN', [RakuAST::Statement::Expression, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 580 src/Raku/ast/statements.rakumod if nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier') { my $thunk := nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier').expression-thunk; if $thunk { # only need to thunk the condition if we also have a loop thunk if nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier') { #nqp::die('have loop and condition modifier ' ~ self.dump); my $thunk := nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier').expression-thunk; nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').wrap-with-thunk($thunk); $thunk.ensure-begin-performed($resolver, $context); } nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').wrap-with-thunk($thunk); $thunk.ensure-begin-performed($resolver, $context); } } }); add-method(RakuAST::Statement::Expression, 'visit-children', [RakuAST::Statement::Expression, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 597 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression')); $visitor(nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier')) if nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier'); $visitor(nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier')) if nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier'); $SELF.visit-labels($visitor); }); add-method(RakuAST::Statement::Expression, 'IMPL-CAN-INTERPRET', [RakuAST::Statement::Expression, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 604 src/Raku/ast/statements.rakumod !nqp::getattr($SELF, RakuAST::Statement::Expression, '$!condition-modifier') && !nqp::getattr($SELF, RakuAST::Statement::Expression, '$!loop-modifier') && nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').IMPL-CAN-INTERPRET }); add-method(RakuAST::Statement::Expression, 'IMPL-INTERPRET', [RakuAST::Statement::Expression, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 608 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Expression, '$!expression').IMPL-INTERPRET($ctx) }); #line 498 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Expression, 'loop-modifier', [], anon sub loop-modifier ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Expression, '$!loop-modifier') }); #line 496 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Expression, 'expression', [], anon sub expression ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Expression, '$!expression') }); #line 497 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Expression, 'condition-modifier', [], anon sub condition-modifier ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Expression, '$!condition-modifier') }); compose(RakuAST::Statement::Expression); parent(RakuAST::IMPL::ImmediateBlockUser, RakuAST::Node); add-method(RakuAST::IMPL::ImmediateBlockUser, 'IMPL-IMMEDIATELY-USES', [RakuAST::IMPL::ImmediateBlockUser, '', 0, 0, RakuAST::Node, '$node', 0, 0], anon sub IMPL-IMMEDIATELY-USES ($SELF_CONT, $node!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); #line 618 src/Raku/ast/statements.rakumod (Bool.WHO) }); compose(RakuAST::IMPL::ImmediateBlockUser); parent(RakuAST::Statement::IfWith, RakuAST::Statement); parent(RakuAST::Statement::IfWith, RakuAST::ImplicitLookups); parent(RakuAST::Statement::IfWith, RakuAST::SinkPropagator); parent(RakuAST::Statement::IfWith, RakuAST::IMPL::ImmediateBlockUser); parent(RakuAST::Statement::IfWith, RakuAST::ImplicitBlockSemanticsProvider); add-attribute(RakuAST::Statement::IfWith, RakuAST::Expression, '$!condition'); add-attribute(RakuAST::Statement::IfWith, RakuAST::Expression, '$!then'); add-attribute(RakuAST::Statement::IfWith, List, '$!elsifs'); add-attribute(RakuAST::Statement::IfWith, RakuAST::Block, '$!else'); add-method(RakuAST::Statement::IfWith, 'new', [RakuAST::Statement::IfWith, '', 0, 0, RakuAST::Expression, '$condition', 1, 0, RakuAST::Expression, '$then', 1, 0, List, '$elsifs', 1, 1, RakuAST::Block, '$else', 1, 1, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$condition!, :$then!, :$elsifs?, :$else?, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $condition := nqp::decont($condition); $then := nqp::decont($then); $elsifs := nqp::decont($elsifs); $else := nqp::decont($else); $labels := nqp::decont($labels); #line 640 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj,RakuAST::Statement::IfWith,'$!condition',$condition); nqp::bindattr($obj,RakuAST::Statement::IfWith,'$!then',$then); $obj.set-elsifs($elsifs); $obj.set-else($else); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::IfWith, 'set-elsifs', [RakuAST::Statement::IfWith, '', 0, 0, Any, '$elsifs', 0, 0], anon sub set-elsifs ($SELF_CONT, $elsifs!) { my $SELF := nqp::decont($SELF_CONT); $elsifs := nqp::decont($elsifs); #line 650 src/Raku/ast/statements.rakumod nqp::bindattr($SELF,RakuAST::Statement::IfWith,'$!elsifs', $elsifs ?? $SELF.IMPL-UNWRAP-LIST($elsifs) !! [] ); Nil }); add-method(RakuAST::Statement::IfWith, 'elsifs', [RakuAST::Statement::IfWith, '', 0, 0], anon sub elsifs ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 656 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!elsifs')) }); add-method(RakuAST::Statement::IfWith, 'set-else', [RakuAST::Statement::IfWith, '', 0, 0, Any, '$else', 0, 0], anon sub set-else ($SELF_CONT, $else!) { my $SELF := nqp::decont($SELF_CONT); $else := nqp::decont($else); #line 658 src/Raku/ast/statements.rakumod nqp::bindattr($SELF,RakuAST::Statement::IfWith,'$!else', $else // RakuAST::Block); }); add-method(RakuAST::Statement::IfWith, 'apply-implicit-block-semantics', [RakuAST::Statement::IfWith, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 663 src/Raku/ast/statements.rakumod my int $last-was-with; if $SELF.IMPL-QAST-TYPE eq 'with' { $last-was-with := 1; nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!then').set-implicit-topic((Bool.WHO), :required); } else { nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!then').set-implicit-topic((Bool.WHO), :local); } for nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!elsifs') { $_.apply-implicit-block-semantics(); $last-was-with := $_.IMPL-QAST-TYPE eq 'with'; } if nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else') { if $last-was-with { nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else').set-implicit-topic((Bool.WHO), :required); } else { nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else').set-implicit-topic((Bool.WHO), :local); } } }); add-method(RakuAST::Statement::IfWith, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Statement::IfWith, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 686 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST: nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else') ?? [] !! [RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Empty'))] }); add-method(RakuAST::Statement::IfWith, 'IMPL-TO-QAST', [RakuAST::Statement::IfWith, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 692 src/Raku/ast/statements.rakumod # Start with the else (or Empty). my $cur-end; if nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else') { $cur-end := nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else').IMPL-TO-QAST($context, :immediate); } else { $cur-end := $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context); } # Add the branches. my int $i := nqp::elems(nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!elsifs')); while $i-- > 0 { my $branch := nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!elsifs')[$i]; $cur-end := QAST::Op.new( :op($branch.IMPL-QAST-TYPE), $branch.condition.IMPL-TO-QAST($context), $branch.then.IMPL-TO-QAST($context, :immediate), $cur-end ); } # Finally, the initial condition. QAST::Op.new( :op($SELF.IMPL-QAST-TYPE), nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!condition').IMPL-TO-QAST($context), nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!then').IMPL-TO-QAST($context, :immediate), $cur-end ) }); add-method(RakuAST::Statement::IfWith, 'propagate-sink', [RakuAST::Statement::IfWith, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 724 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!condition').apply-sink((Bool.WHO)); nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!then').body.apply-sink($is-sunk); for nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!elsifs') { $_.condition.apply-sink((Bool.WHO)); $_.then.body.apply-sink($is-sunk); } if nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else') { nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else').body.apply-sink($is-sunk); } }); add-method(RakuAST::Statement::IfWith, 'visit-children', [RakuAST::Statement::IfWith, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 736 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!condition')); $visitor(nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!then')); for nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!elsifs') { $visitor($_.condition); $visitor($_.then); } if nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else') { $visitor(nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!else')); } $SELF.visit-labels($visitor); }); add-method(RakuAST::Statement::IfWith, 'IMPL-IMMEDIATELY-USES', [RakuAST::Statement::IfWith, '', 0, 0, RakuAST::Node, '$node', 0, 0], anon sub IMPL-IMMEDIATELY-USES ($SELF_CONT, $node!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); #line 749 src/Raku/ast/statements.rakumod return (Bool.WHO) if $node =:= nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!condition'); for nqp::getattr($SELF, RakuAST::Statement::IfWith, '$!elsifs') { return (Bool.WHO) if $node =:= $_.condition; } (Bool.WHO) }); #line 630 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::IfWith, 'then', [], anon sub then ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::IfWith, '$!then') }); #line 632 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::IfWith, 'else', [], anon sub else ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::IfWith, '$!else') }); #line 629 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::IfWith, 'condition', [], anon sub condition ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::IfWith, '$!condition') }); compose(RakuAST::Statement::IfWith); parent(RakuAST::Statement::If, RakuAST::Statement::IfWith); add-method(RakuAST::Statement::If, 'IMPL-QAST-TYPE', [RakuAST::Statement::If, '', 0, 0], anon sub IMPL-QAST-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 762 src/Raku/ast/statements.rakumod 'if' }); compose(RakuAST::Statement::If); parent(RakuAST::Statement::With, RakuAST::Statement::IfWith); add-method(RakuAST::Statement::With, 'IMPL-QAST-TYPE', [RakuAST::Statement::With, '', 0, 0], anon sub IMPL-QAST-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 769 src/Raku/ast/statements.rakumod 'with' }); compose(RakuAST::Statement::With); parent(RakuAST::Statement::Elsif, Any); add-attribute(RakuAST::Statement::Elsif, RakuAST::Expression, '$!condition'); add-attribute(RakuAST::Statement::Elsif, RakuAST::Expression, '$!then'); add-method(RakuAST::Statement::Elsif, 'new', [RakuAST::Statement::Elsif, '', 0, 0, RakuAST::Expression, '$condition', 1, 0, RakuAST::Expression, '$then', 1, 0], anon sub new ($SELF_CONT, :$condition!, :$then!) { my $SELF := nqp::decont($SELF_CONT); $condition := nqp::decont($condition); $then := nqp::decont($then); #line 778 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Elsif, '$!condition', $condition); nqp::bindattr($obj, RakuAST::Statement::Elsif, '$!then', $then); $obj }); add-method(RakuAST::Statement::Elsif, 'apply-implicit-block-semantics', [RakuAST::Statement::Elsif, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 785 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Elsif, '$!then').set-implicit-topic((Bool.WHO), :local); }); add-method(RakuAST::Statement::Elsif, 'IMPL-QAST-TYPE', [RakuAST::Statement::Elsif, '', 0, 0], anon sub IMPL-QAST-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 789 src/Raku/ast/statements.rakumod 'if' }); #line 776 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Elsif, 'then', [], anon sub then ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Elsif, '$!then') }); #line 775 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Elsif, 'condition', [], anon sub condition ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Elsif, '$!condition') }); compose(RakuAST::Statement::Elsif); parent(RakuAST::Statement::Orwith, RakuAST::Statement::Elsif); add-method(RakuAST::Statement::Orwith, 'IMPL-QAST-TYPE', [RakuAST::Statement::Orwith, '', 0, 0], anon sub IMPL-QAST-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 797 src/Raku/ast/statements.rakumod 'with' }); add-method(RakuAST::Statement::Orwith, 'apply-implicit-block-semantics', [RakuAST::Statement::Orwith, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 799 src/Raku/ast/statements.rakumod $SELF.then.set-implicit-topic((Bool.WHO), :required); }); compose(RakuAST::Statement::Orwith); parent(RakuAST::Statement::Unless, RakuAST::Statement); parent(RakuAST::Statement::Unless, RakuAST::ImplicitLookups); parent(RakuAST::Statement::Unless, RakuAST::SinkPropagator); parent(RakuAST::Statement::Unless, RakuAST::IMPL::ImmediateBlockUser); parent(RakuAST::Statement::Unless, RakuAST::ImplicitBlockSemanticsProvider); add-attribute(RakuAST::Statement::Unless, RakuAST::Expression, '$!condition'); add-attribute(RakuAST::Statement::Unless, RakuAST::Block, '$!body'); add-method(RakuAST::Statement::Unless, 'new', [RakuAST::Statement::Unless, '', 0, 0, RakuAST::Expression, '$condition', 1, 0, RakuAST::Block, '$body', 1, 0, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$condition!, :$body!, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $condition := nqp::decont($condition); $body := nqp::decont($body); $labels := nqp::decont($labels); #line 815 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Unless, '$!condition', $condition); nqp::bindattr($obj, RakuAST::Statement::Unless, '$!body', $body); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Unless, 'apply-implicit-block-semantics', [RakuAST::Statement::Unless, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 823 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Unless, '$!body').set-implicit-topic((Bool.WHO), :local); }); add-method(RakuAST::Statement::Unless, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Statement::Unless, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 827 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Empty')), ]) }); add-method(RakuAST::Statement::Unless, 'IMPL-TO-QAST', [RakuAST::Statement::Unless, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 833 src/Raku/ast/statements.rakumod QAST::Op.new( :op('unless'), nqp::getattr($SELF, RakuAST::Statement::Unless, '$!condition').IMPL-TO-QAST($context), nqp::getattr($SELF, RakuAST::Statement::Unless, '$!body').IMPL-TO-QAST($context, :immediate), $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context) ) }); add-method(RakuAST::Statement::Unless, 'propagate-sink', [RakuAST::Statement::Unless, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 842 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Unless, '$!condition').apply-sink((Bool.WHO)); nqp::getattr($SELF, RakuAST::Statement::Unless, '$!body').body.apply-sink($is-sunk); }); add-method(RakuAST::Statement::Unless, 'visit-children', [RakuAST::Statement::Unless, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 847 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Unless, '$!condition')); $visitor(nqp::getattr($SELF, RakuAST::Statement::Unless, '$!body')); $SELF.visit-labels($visitor); }); add-method(RakuAST::Statement::Unless, 'IMPL-IMMEDIATELY-USES', [RakuAST::Statement::Unless, '', 0, 0, RakuAST::Node, '$node', 0, 0], anon sub IMPL-IMMEDIATELY-USES ($SELF_CONT, $node!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); #line 853 src/Raku/ast/statements.rakumod $node =:= nqp::getattr($SELF, RakuAST::Statement::Unless, '$!body') }); #line 812 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Unless, 'condition', [], anon sub condition ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Unless, '$!condition') }); #line 813 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Unless, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Unless, '$!body') }); compose(RakuAST::Statement::Unless); parent(RakuAST::Statement::Without, RakuAST::Statement); parent(RakuAST::Statement::Without, RakuAST::ImplicitLookups); parent(RakuAST::Statement::Without, RakuAST::SinkPropagator); parent(RakuAST::Statement::Without, RakuAST::IMPL::ImmediateBlockUser); parent(RakuAST::Statement::Without, RakuAST::ImplicitBlockSemanticsProvider); add-attribute(RakuAST::Statement::Without, RakuAST::Expression, '$!condition'); add-attribute(RakuAST::Statement::Without, RakuAST::Block, '$!body'); add-method(RakuAST::Statement::Without, 'new', [RakuAST::Statement::Without, '', 0, 0, RakuAST::Expression, '$condition', 1, 0, RakuAST::Block, '$body', 1, 0, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$condition!, :$body!, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $condition := nqp::decont($condition); $body := nqp::decont($body); $labels := nqp::decont($labels); #line 869 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Without, '$!condition', $condition); nqp::bindattr($obj, RakuAST::Statement::Without, '$!body', $body); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Without, 'apply-implicit-block-semantics', [RakuAST::Statement::Without, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 877 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Without, '$!body').set-implicit-topic((Bool.WHO), :required); }); add-method(RakuAST::Statement::Without, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Statement::Without, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 881 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Empty')), ]) }); add-method(RakuAST::Statement::Without, 'IMPL-TO-QAST', [RakuAST::Statement::Without, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 887 src/Raku/ast/statements.rakumod QAST::Op.new( :op('without'), nqp::getattr($SELF, RakuAST::Statement::Without, '$!condition').IMPL-TO-QAST($context), nqp::getattr($SELF, RakuAST::Statement::Without, '$!body').IMPL-TO-QAST($context, :immediate), $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context) ) }); add-method(RakuAST::Statement::Without, 'propagate-sink', [RakuAST::Statement::Without, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 896 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Without, '$!condition').apply-sink((Bool.WHO)); nqp::getattr($SELF, RakuAST::Statement::Without, '$!body').body.apply-sink($is-sunk); }); add-method(RakuAST::Statement::Without, 'visit-children', [RakuAST::Statement::Without, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 901 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Without, '$!condition')); $visitor(nqp::getattr($SELF, RakuAST::Statement::Without, '$!body')); $SELF.visit-labels($visitor); }); add-method(RakuAST::Statement::Without, 'IMPL-IMMEDIATELY-USES', [RakuAST::Statement::Without, '', 0, 0, RakuAST::Node, '$node', 0, 0], anon sub IMPL-IMMEDIATELY-USES ($SELF_CONT, $node!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); #line 907 src/Raku/ast/statements.rakumod $node =:= nqp::getattr($SELF, RakuAST::Statement::Without, '$!body') }); #line 866 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Without, 'condition', [], anon sub condition ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Without, '$!condition') }); #line 867 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Without, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Without, '$!body') }); compose(RakuAST::Statement::Without); parent(RakuAST::Statement::Loop, RakuAST::Statement); parent(RakuAST::Statement::Loop, RakuAST::ImplicitLookups); parent(RakuAST::Statement::Loop, RakuAST::Sinkable); parent(RakuAST::Statement::Loop, RakuAST::SinkPropagator); parent(RakuAST::Statement::Loop, RakuAST::BlockStatementSensitive); parent(RakuAST::Statement::Loop, RakuAST::IMPL::ImmediateBlockUser); parent(RakuAST::Statement::Loop, RakuAST::ImplicitBlockSemanticsProvider); add-attribute(RakuAST::Statement::Loop, RakuAST::Expression, '$!setup'); add-attribute(RakuAST::Statement::Loop, RakuAST::Expression, '$!condition'); add-attribute(RakuAST::Statement::Loop, RakuAST::Block, '$!body'); add-attribute(RakuAST::Statement::Loop, RakuAST::Expression, '$!increment'); add-method(RakuAST::Statement::Loop, 'new', [RakuAST::Statement::Loop, '', 0, 0, RakuAST::Block, '$body', 1, 0, RakuAST::Expression, '$condition', 1, 1, RakuAST::Expression, '$setup', 1, 1, RakuAST::Expression, '$increment', 1, 1, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$body!, :$condition?, :$setup?, :$increment?, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $body := nqp::decont($body); $condition := nqp::decont($condition); $setup := nqp::decont($setup); $increment := nqp::decont($increment); $labels := nqp::decont($labels); #line 937 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Loop, '$!body', $body); nqp::bindattr($obj, RakuAST::Statement::Loop, '$!condition', $condition); nqp::bindattr($obj, RakuAST::Statement::Loop, '$!setup', $setup); nqp::bindattr($obj, RakuAST::Statement::Loop, '$!increment', $increment); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Loop, 'negate', [RakuAST::Statement::Loop, '', 0, 0], anon sub negate ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 948 src/Raku/ast/statements.rakumod (Bool.WHO) }); add-method(RakuAST::Statement::Loop, 'repeat', [RakuAST::Statement::Loop, '', 0, 0], anon sub repeat ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 951 src/Raku/ast/statements.rakumod (Bool.WHO) }); add-method(RakuAST::Statement::Loop, 'apply-implicit-block-semantics', [RakuAST::Statement::Loop, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 953 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Loop, '$!body').set-implicit-topic((Bool.WHO), :local); }); add-method(RakuAST::Statement::Loop, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Statement::Loop, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 957 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Nil')) ]) }); add-method(RakuAST::Statement::Loop, 'IMPL-DISCARD-RESULT', [RakuAST::Statement::Loop, '', 0, 0], anon sub IMPL-DISCARD-RESULT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 963 src/Raku/ast/statements.rakumod $SELF.is-block-statement || $SELF.sunk }); add-method(RakuAST::Statement::Loop, 'IMPL-TO-QAST', [RakuAST::Statement::Loop, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 967 src/Raku/ast/statements.rakumod if $SELF.IMPL-DISCARD-RESULT { # Select correct node type for the loop and produce it. my str $op := $SELF.repeat ?? ($SELF.negate ?? 'repeat_until' !! 'repeat_while') !! ($SELF.negate ?? 'until' !! 'while'); my $loop-qast := QAST::Op.new( :$op, nqp::getattr($SELF, RakuAST::Statement::Loop, '$!condition') ?? nqp::getattr($SELF, RakuAST::Statement::Loop, '$!condition').IMPL-TO-QAST($context) !! QAST::IVal.new( :value(1) ), nqp::getattr($SELF, RakuAST::Statement::Loop, '$!body').IMPL-TO-QAST($context, :immediate), ); if nqp::getattr($SELF, RakuAST::Statement::Loop, '$!increment') { $loop-qast.push(nqp::getattr($SELF, RakuAST::Statement::Loop, '$!increment').IMPL-TO-QAST($context)); } # Add a label if there is one. my @labels := $SELF.IMPL-UNWRAP-LIST($SELF.labels); if @labels { my $label-qast := @labels[0].IMPL-LOOKUP-QAST($context); $label-qast.named('label'); $loop-qast.push($label-qast); } # Prepend setup code and evaluate to Nil if not sunk. my $wrapper := $SELF.IMPL-SET-NODE(QAST::Stmt.new(), :key); if nqp::getattr($SELF, RakuAST::Statement::Loop, '$!setup') { $wrapper.push(nqp::getattr($SELF, RakuAST::Statement::Loop, '$!setup').IMPL-TO-QAST($context)); } $wrapper.push($loop-qast); unless $SELF.sunk { $wrapper.push( $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context) ); } $wrapper } else { nqp::die('Compilation of lazy loops NYI') } }); add-method(RakuAST::Statement::Loop, 'propagate-sink', [RakuAST::Statement::Loop, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 1009 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Loop, '$!condition').apply-sink((Bool.WHO)) if nqp::getattr($SELF, RakuAST::Statement::Loop, '$!condition'); nqp::getattr($SELF, RakuAST::Statement::Loop, '$!body').body.apply-sink($SELF.IMPL-DISCARD-RESULT ?? (Bool.WHO) !! (Bool.WHO)); nqp::getattr($SELF, RakuAST::Statement::Loop, '$!setup').apply-sink((Bool.WHO)) if nqp::getattr($SELF, RakuAST::Statement::Loop, '$!setup'); nqp::getattr($SELF, RakuAST::Statement::Loop, '$!increment').apply-sink((Bool.WHO)) if nqp::getattr($SELF, RakuAST::Statement::Loop, '$!increment'); }); add-method(RakuAST::Statement::Loop, 'visit-children', [RakuAST::Statement::Loop, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1016 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Loop, '$!setup')) if nqp::getattr($SELF, RakuAST::Statement::Loop, '$!setup'); $visitor(nqp::getattr($SELF, RakuAST::Statement::Loop, '$!condition')) if nqp::getattr($SELF, RakuAST::Statement::Loop, '$!condition'); $visitor(nqp::getattr($SELF, RakuAST::Statement::Loop, '$!increment')) if nqp::getattr($SELF, RakuAST::Statement::Loop, '$!increment'); $visitor(nqp::getattr($SELF, RakuAST::Statement::Loop, '$!body')); $SELF.visit-labels($visitor); }); add-method(RakuAST::Statement::Loop, 'IMPL-IMMEDIATELY-USES', [RakuAST::Statement::Loop, '', 0, 0, RakuAST::Node, '$node', 0, 0], anon sub IMPL-IMMEDIATELY-USES ($SELF_CONT, $node!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); #line 1024 src/Raku/ast/statements.rakumod $node =:= nqp::getattr($SELF, RakuAST::Statement::Loop, '$!body') }); #line 924 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Loop, 'setup', [], anon sub setup ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Loop, '$!setup') }); #line 933 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Loop, 'increment', [], anon sub increment ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Loop, '$!increment') }); #line 927 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Loop, 'condition', [], anon sub condition ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Loop, '$!condition') }); #line 930 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Loop, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Loop, '$!body') }); compose(RakuAST::Statement::Loop); parent(RakuAST::Statement::Loop::While, RakuAST::Statement::Loop); compose(RakuAST::Statement::Loop::While); parent(RakuAST::Statement::Loop::Until, RakuAST::Statement::Loop); add-method(RakuAST::Statement::Loop::Until, 'negate', [RakuAST::Statement::Loop::Until, '', 0, 0], anon sub negate ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1038 src/Raku/ast/statements.rakumod (Bool.WHO) }); compose(RakuAST::Statement::Loop::Until); parent(RakuAST::Statement::Loop::RepeatWhile, RakuAST::Statement::Loop); add-method(RakuAST::Statement::Loop::RepeatWhile, 'repeat', [RakuAST::Statement::Loop::RepeatWhile, '', 0, 0], anon sub repeat ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1045 src/Raku/ast/statements.rakumod (Bool.WHO) }); compose(RakuAST::Statement::Loop::RepeatWhile); parent(RakuAST::Statement::Loop::RepeatUntil, RakuAST::Statement::Loop); add-method(RakuAST::Statement::Loop::RepeatUntil, 'negate', [RakuAST::Statement::Loop::RepeatUntil, '', 0, 0], anon sub negate ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1052 src/Raku/ast/statements.rakumod (Bool.WHO) }); add-method(RakuAST::Statement::Loop::RepeatUntil, 'repeat', [RakuAST::Statement::Loop::RepeatUntil, '', 0, 0], anon sub repeat ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1053 src/Raku/ast/statements.rakumod (Bool.WHO) }); compose(RakuAST::Statement::Loop::RepeatUntil); parent(RakuAST::Statement::For, RakuAST::Statement); parent(RakuAST::Statement::For, RakuAST::ForLoopImplementation); parent(RakuAST::Statement::For, RakuAST::Sinkable); parent(RakuAST::Statement::For, RakuAST::SinkPropagator); parent(RakuAST::Statement::For, RakuAST::BlockStatementSensitive); parent(RakuAST::Statement::For, RakuAST::ImplicitBlockSemanticsProvider); add-attribute(RakuAST::Statement::For, RakuAST::Expression, '$!source'); add-attribute(RakuAST::Statement::For, RakuAST::Block, '$!body'); add-attribute(RakuAST::Statement::For, RakuAST::Block, '$!otherwise'); add-attribute(RakuAST::Statement::For, str, '$!mode'); add-method(RakuAST::Statement::For, 'new', [RakuAST::Statement::For, '', 0, 0, RakuAST::Expression, '$source', 1, 0, RakuAST::Block, '$body', 1, 0, RakuAST::Block, '$otherwise', 1, 1, str, '$mode', 1, 1, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$source!, :$body!, :$otherwise?, :$mode?, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $source := nqp::decont($source); $body := nqp::decont($body); $otherwise := nqp::decont($otherwise); $mode := nqp::decont($mode); $labels := nqp::decont($labels); #line 1083 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::For, '$!source', $source); nqp::bindattr($obj, RakuAST::Statement::For, '$!body', $body); nqp::bindattr($obj, RakuAST::Statement::For, '$!otherwise', $otherwise); nqp::bindattr_s($obj, RakuAST::Statement::For, '$!mode', $mode || 'serial'); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::For, 'replace-mode', [RakuAST::Statement::For, '', 0, 0, str, '$mode', 0, 0], anon sub replace-mode ($SELF_CONT, $mode!) { my $SELF := nqp::decont($SELF_CONT); $mode := nqp::decont($mode); #line 1093 src/Raku/ast/statements.rakumod nqp::bindattr_s($SELF, RakuAST::Statement::For, '$!mode', $mode); Nil }); add-method(RakuAST::Statement::For, 'replace-otherwise', [RakuAST::Statement::For, '', 0, 0, RakuAST::Block, '$otherwise', 0, 0], anon sub replace-otherwise ($SELF_CONT, $otherwise!) { my $SELF := nqp::decont($SELF_CONT); $otherwise := nqp::decont($otherwise); #line 1098 src/Raku/ast/statements.rakumod nqp::bindattr($SELF, RakuAST::Statement::For, '$!otherwise', $otherwise); Nil }); add-method(RakuAST::Statement::For, 'IMPL-DISCARD-RESULT', [RakuAST::Statement::For, '', 0, 0], anon sub IMPL-DISCARD-RESULT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1103 src/Raku/ast/statements.rakumod $SELF.is-block-statement || $SELF.sunk }); add-method(RakuAST::Statement::For, 'propagate-sink', [RakuAST::Statement::For, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 1107 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::For, '$!source').apply-sink((Bool.WHO)); nqp::getattr($SELF, RakuAST::Statement::For, '$!body').body.apply-sink($SELF.IMPL-DISCARD-RESULT ?? (Bool.WHO) !! (Bool.WHO)); }); add-method(RakuAST::Statement::For, 'apply-implicit-block-semantics', [RakuAST::Statement::For, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1112 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::For, '$!body').set-implicit-topic((Bool.WHO), :required); }); add-method(RakuAST::Statement::For, 'IMPL-TO-QAST', [RakuAST::Statement::For, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1116 src/Raku/ast/statements.rakumod # Figure out the execution mode modifiers to apply. my str $mode := nqp::getattr_s($SELF, RakuAST::Statement::For, '$!mode'); my str $after-mode := ''; if nqp::getattr($SELF, RakuAST::Statement::For, '$!otherwise') { $mode := 'serial'; $after-mode := 'eager'; } elsif $mode eq 'lazy' { $mode := 'serial'; $after-mode := 'lazy'; } else { $after-mode := $SELF.IMPL-DISCARD-RESULT ?? 'sink' !! 'eager'; } # Delegate to the for loop compilation helper (which we pass various # attributes to in order to make it callable for the statement modifier # form also). my @labels := $SELF.IMPL-UNWRAP-LIST($SELF.labels); my $qast := $SELF.IMPL-FOR-QAST( $context, $mode, $after-mode, nqp::getattr($SELF, RakuAST::Statement::For, '$!source').IMPL-TO-QAST($context), nqp::getattr($SELF, RakuAST::Statement::For, '$!body').IMPL-TO-QAST($context), @labels ?? @labels[0] !! RakuAST::Label ); nqp::getattr($SELF, RakuAST::Statement::For, '$!otherwise') ?? QAST::Op.new(:op, $qast, QAST::Op.new(:op, nqp::getattr($SELF, RakuAST::Statement::For, '$!otherwise').IMPL-TO-QAST($context) ) ) !! $qast }); add-method(RakuAST::Statement::For, 'visit-children', [RakuAST::Statement::For, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1156 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::For, '$!source')); $visitor(nqp::getattr($SELF, RakuAST::Statement::For, '$!body')); $visitor(nqp::getattr($SELF, RakuAST::Statement::For, '$!otherwise')) if nqp::getattr($SELF, RakuAST::Statement::For, '$!otherwise'); $SELF.visit-labels($visitor); }); #line 1066 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::For, 'source', [], anon sub source ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::For, '$!source') }); #line 1072 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::For, 'otherwise', [], anon sub otherwise ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::For, '$!otherwise') }); #line 1075 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::For, 'mode', [], anon sub mode ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Statement::For, '$!mode') }); #line 1069 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::For, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::For, '$!body') }); compose(RakuAST::Statement::For); parent(RakuAST::Statement::Given, RakuAST::Statement); parent(RakuAST::Statement::Given, RakuAST::SinkPropagator); parent(RakuAST::Statement::Given, RakuAST::ImplicitBlockSemanticsProvider); add-attribute(RakuAST::Statement::Given, RakuAST::Expression, '$!source'); add-attribute(RakuAST::Statement::Given, RakuAST::Block, '$!body'); add-method(RakuAST::Statement::Given, 'new', [RakuAST::Statement::Given, '', 0, 0, RakuAST::Expression, '$source', 1, 0, RakuAST::Block, '$body', 1, 0, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$source!, :$body!, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $source := nqp::decont($source); $body := nqp::decont($body); $labels := nqp::decont($labels); #line 1176 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Given, '$!source', $source); nqp::bindattr($obj, RakuAST::Statement::Given, '$!body', $body); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Given, 'propagate-sink', [RakuAST::Statement::Given, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 1184 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Given, '$!source').apply-sink((Bool.WHO)); nqp::getattr($SELF, RakuAST::Statement::Given, '$!body').body.apply-sink($is-sunk); }); add-method(RakuAST::Statement::Given, 'apply-implicit-block-semantics', [RakuAST::Statement::Given, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1189 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Given, '$!body').set-implicit-topic((Bool.WHO), :required); }); add-method(RakuAST::Statement::Given, 'IMPL-TO-QAST', [RakuAST::Statement::Given, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1193 src/Raku/ast/statements.rakumod QAST::Op.new( :op('call'), nqp::getattr($SELF, RakuAST::Statement::Given, '$!body').IMPL-TO-QAST($context), nqp::getattr($SELF, RakuAST::Statement::Given, '$!source').IMPL-TO-QAST($context) ) }); add-method(RakuAST::Statement::Given, 'visit-children', [RakuAST::Statement::Given, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1201 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Given, '$!source')); $visitor(nqp::getattr($SELF, RakuAST::Statement::Given, '$!body')); $SELF.visit-labels($visitor); }); #line 1171 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Given, 'source', [], anon sub source ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Given, '$!source') }); #line 1174 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Given, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Given, '$!body') }); compose(RakuAST::Statement::Given); parent(RakuAST::Statement::When, RakuAST::Statement); parent(RakuAST::Statement::When, RakuAST::SinkPropagator); parent(RakuAST::Statement::When, RakuAST::ImplicitBlockSemanticsProvider); parent(RakuAST::Statement::When, RakuAST::ImplicitLookups); parent(RakuAST::Statement::When, RakuAST::Attaching); add-attribute(RakuAST::Statement::When, RakuAST::Expression, '$!condition'); add-attribute(RakuAST::Statement::When, RakuAST::Block, '$!body'); add-method(RakuAST::Statement::When, 'new', [RakuAST::Statement::When, '', 0, 0, RakuAST::Expression, '$condition', 1, 0, RakuAST::Block, '$body', 1, 0, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$condition!, :$body!, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $condition := nqp::decont($condition); $body := nqp::decont($body); $labels := nqp::decont($labels); #line 1220 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::When, '$!condition', $condition); nqp::bindattr($obj, RakuAST::Statement::When, '$!body', $body); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::When, 'apply-implicit-block-semantics', [RakuAST::Statement::When, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1228 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::When, '$!body').set-implicit-topic((Bool.WHO)); }); add-method(RakuAST::Statement::When, 'propagate-sink', [RakuAST::Statement::When, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 1232 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::When, '$!condition').apply-sink((Bool.WHO)); nqp::getattr($SELF, RakuAST::Statement::When, '$!body').body.apply-sink((Bool.WHO)); # Used as enclosing block outcome }); add-method(RakuAST::Statement::When, 'attach', [RakuAST::Statement::When, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1237 src/Raku/ast/statements.rakumod my $block := $resolver.find-attach-target('block') // $resolver.find-attach-target('compunit'); if $block { $block.require-succeed-handler(); } else { nqp::die('when found no enclosing block to attach to'); } }); add-method(RakuAST::Statement::When, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Statement::When, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1248 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical.new('$_'), ]) }); add-method(RakuAST::Statement::When, 'IMPL-TO-QAST', [RakuAST::Statement::When, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1254 src/Raku/ast/statements.rakumod my $sm-qast := QAST::Op.new( :op('callmethod'), :name('ACCEPTS'), nqp::getattr($SELF, RakuAST::Statement::When, '$!condition').IMPL-TO-QAST($context), $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context) ); QAST::Op.new( :op('if'), $sm-qast, $SELF.IMPL-WRAP-WHEN-OR-DEFAULT($context, QAST::Op.new( :op('call'), nqp::getattr($SELF, RakuAST::Statement::When, '$!body').IMPL-TO-QAST($context) ) )) }); add-method(RakuAST::Statement::When, 'visit-children', [RakuAST::Statement::When, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1268 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::When, '$!condition')); $visitor(nqp::getattr($SELF, RakuAST::Statement::When, '$!body')); $SELF.visit-labels($visitor); }); #line 1217 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::When, 'condition', [], anon sub condition ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::When, '$!condition') }); #line 1218 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::When, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::When, '$!body') }); compose(RakuAST::Statement::When); parent(RakuAST::Statement::Whenever, RakuAST::Statement); parent(RakuAST::Statement::Whenever, RakuAST::SinkPropagator); parent(RakuAST::Statement::Whenever, RakuAST::ImplicitBlockSemanticsProvider); add-attribute(RakuAST::Statement::Whenever, RakuAST::Expression, '$!trigger'); add-attribute(RakuAST::Statement::Whenever, RakuAST::Block, '$!body'); add-method(RakuAST::Statement::Whenever, 'new', [RakuAST::Statement::Whenever, '', 0, 0, RakuAST::Expression, '$trigger', 1, 0, RakuAST::Block, '$body', 1, 0, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$trigger!, :$body!, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $trigger := nqp::decont($trigger); $body := nqp::decont($body); $labels := nqp::decont($labels); #line 1288 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj,RakuAST::Statement::Whenever,'$!trigger',$trigger); nqp::bindattr($obj,RakuAST::Statement::Whenever,'$!body',$body); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Whenever, 'propagate-sink', [RakuAST::Statement::Whenever, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 1296 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Whenever, '$!trigger').apply-sink((Bool.WHO)); nqp::getattr($SELF, RakuAST::Statement::Whenever, '$!body').body.apply-sink($is-sunk); }); add-method(RakuAST::Statement::Whenever, 'apply-implicit-block-semantics', [RakuAST::Statement::Whenever, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1301 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Whenever, '$!body').set-implicit-topic((Bool.WHO), :required); }); add-method(RakuAST::Statement::Whenever, 'IMPL-TO-QAST', [RakuAST::Statement::Whenever, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1305 src/Raku/ast/statements.rakumod QAST::Op.new(:op, :name<&WHENEVER>, QAST::Op.new(:op, nqp::getattr($SELF, RakuAST::Statement::Whenever, '$!trigger').IMPL-TO-QAST($context) ), nqp::getattr($SELF, RakuAST::Statement::Whenever, '$!body').IMPL-TO-QAST($context) ) }); add-method(RakuAST::Statement::Whenever, 'visit-children', [RakuAST::Statement::Whenever, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1314 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Whenever, '$!trigger')); $visitor(nqp::getattr($SELF, RakuAST::Statement::Whenever, '$!body')); $SELF.visit-labels($visitor); }); #line 1281 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Whenever, 'trigger', [], anon sub trigger ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Whenever, '$!trigger') }); #line 1282 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Whenever, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Whenever, '$!body') }); compose(RakuAST::Statement::Whenever); parent(RakuAST::Statement::Default, RakuAST::Statement); parent(RakuAST::Statement::Default, RakuAST::SinkPropagator); parent(RakuAST::Statement::Default, RakuAST::ImplicitBlockSemanticsProvider); parent(RakuAST::Statement::Default, RakuAST::Attaching); add-attribute(RakuAST::Statement::Default, RakuAST::Block, '$!body'); add-method(RakuAST::Statement::Default, 'new', [RakuAST::Statement::Default, '', 0, 0, RakuAST::Block, '$body', 1, 0, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$body!, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $body := nqp::decont($body); $labels := nqp::decont($labels); #line 1330 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Default, '$!body', $body); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Default, 'apply-implicit-block-semantics', [RakuAST::Statement::Default, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1337 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Default, '$!body').set-implicit-topic(1); }); add-method(RakuAST::Statement::Default, 'propagate-sink', [RakuAST::Statement::Default, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 1341 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::Default, '$!body').body.apply-sink((Bool.WHO)); # Used as enclosing block outcome }); add-method(RakuAST::Statement::Default, 'attach', [RakuAST::Statement::Default, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1345 src/Raku/ast/statements.rakumod my $block := $resolver.find-attach-target('block') // $resolver.find-attach-target('compunit'); if $block { $block.require-succeed-handler(); } else { nqp::die('default found no enclosing block to attach to'); } }); add-method(RakuAST::Statement::Default, 'IMPL-TO-QAST', [RakuAST::Statement::Default, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1356 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-WHEN-OR-DEFAULT($context, QAST::Op.new( :op('call'), nqp::getattr($SELF, RakuAST::Statement::Default, '$!body').IMPL-TO-QAST($context) ) ) }); add-method(RakuAST::Statement::Default, 'visit-children', [RakuAST::Statement::Default, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1362 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Default, '$!body')); $SELF.visit-labels($visitor); }); #line 1328 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Default, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Default, '$!body') }); compose(RakuAST::Statement::Default); parent(RakuAST::Statement::ExceptionHandler, RakuAST::Statement); parent(RakuAST::Statement::ExceptionHandler, RakuAST::SinkPropagator); parent(RakuAST::Statement::ExceptionHandler, RakuAST::ImplicitBlockSemanticsProvider); parent(RakuAST::Statement::ExceptionHandler, RakuAST::ProducesNil); add-attribute(RakuAST::Statement::ExceptionHandler, RakuAST::Block, '$!body'); add-method(RakuAST::Statement::ExceptionHandler, 'new', [RakuAST::Statement::ExceptionHandler, '', 0, 0, RakuAST::Block, '$body', 1, 0], anon sub new ($SELF_CONT, :$body!) { my $SELF := nqp::decont($SELF_CONT); $body := nqp::decont($body); #line 1377 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::ExceptionHandler, '$!body', $body); $obj.set-labels(Mu); $obj }); add-method(RakuAST::Statement::ExceptionHandler, 'apply-implicit-block-semantics', [RakuAST::Statement::ExceptionHandler, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1384 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::ExceptionHandler, '$!body').set-implicit-topic((Bool.WHO), :exception); nqp::getattr($SELF, RakuAST::Statement::ExceptionHandler, '$!body').set-fresh-variables(:match, :exception); }); add-method(RakuAST::Statement::ExceptionHandler, 'propagate-sink', [RakuAST::Statement::ExceptionHandler, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 1389 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Statement::ExceptionHandler, '$!body').body.apply-sink((Bool.WHO)); }); add-method(RakuAST::Statement::ExceptionHandler, 'visit-children', [RakuAST::Statement::ExceptionHandler, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1393 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::ExceptionHandler, '$!body')); $SELF.visit-labels($visitor); }); #line 1375 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::ExceptionHandler, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::ExceptionHandler, '$!body') }); compose(RakuAST::Statement::ExceptionHandler); parent(RakuAST::Statement::Catch, RakuAST::Statement::ExceptionHandler); parent(RakuAST::Statement::Catch, RakuAST::Attaching); add-method(RakuAST::Statement::Catch, 'attach', [RakuAST::Statement::Catch, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1404 src/Raku/ast/statements.rakumod my $block := $resolver.find-attach-target('block') // $resolver.find-attach-target('compunit'); if $block { $block.attach-catch-handler($SELF); } else { nqp::die('CATCH found no enclosing block to attach to'); } }); compose(RakuAST::Statement::Catch); parent(RakuAST::Statement::Control, RakuAST::Statement::ExceptionHandler); parent(RakuAST::Statement::Control, RakuAST::Attaching); add-method(RakuAST::Statement::Control, 'attach', [RakuAST::Statement::Control, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1421 src/Raku/ast/statements.rakumod my $block := $resolver.find-attach-target('block') // $resolver.find-attach-target('compunit'); if $block { $block.attach-control-handler($SELF); } else { nqp::die('CONTROL found no enclosing block to attach to'); } }); compose(RakuAST::Statement::Control); parent(RakuAST::Categorical, Any); add-attribute(RakuAST::Categorical, Str, '$!category'); add-attribute(RakuAST::Categorical, Str, '$!opname'); add-attribute(RakuAST::Categorical, Str, '$!subname'); add-attribute(RakuAST::Categorical, RakuAST::Declaration, '$!declarand'); add-method(RakuAST::Categorical, 'new', [RakuAST::Categorical, '', 0, 0, Str, '$category', 1, 0, Str, '$opname', 1, 0, Str, '$subname', 1, 0, RakuAST::Declaration, '$declarand', 1, 0], anon sub new ($SELF_CONT, :$category!, :$opname!, :$subname!, :$declarand!) { my $SELF := nqp::decont($SELF_CONT); $category := nqp::decont($category); $opname := nqp::decont($opname); $subname := nqp::decont($subname); $declarand := nqp::decont($declarand); #line 1439 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Categorical, '$!category', $category); nqp::bindattr($obj, RakuAST::Categorical, '$!opname', $opname); nqp::bindattr($obj, RakuAST::Categorical, '$!subname', $subname); nqp::bindattr($obj, RakuAST::Categorical, '$!declarand', $declarand); $obj }); add-method(RakuAST::Categorical, 'canname', [RakuAST::Categorical, '', 0, 0], anon sub canname ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1448 src/Raku/ast/statements.rakumod nqp::getattr($SELF, RakuAST::Categorical, '$!category') ~ ':sym' ~ RakuAST::ColonPairish.IMPL-QUOTE-VALUE(nqp::getattr($SELF, RakuAST::Categorical, '$!opname')); }); #line 1436 src/Raku/ast/statements.rakumod add-method(RakuAST::Categorical, 'subname', [], anon sub subname ($self) { nqp::getattr(nqp::decont($self), RakuAST::Categorical, '$!subname') }); #line 1435 src/Raku/ast/statements.rakumod add-method(RakuAST::Categorical, 'opname', [], anon sub opname ($self) { nqp::getattr(nqp::decont($self), RakuAST::Categorical, '$!opname') }); #line 1437 src/Raku/ast/statements.rakumod add-method(RakuAST::Categorical, 'declarand', [], anon sub declarand ($self) { nqp::getattr(nqp::decont($self), RakuAST::Categorical, '$!declarand') }); #line 1434 src/Raku/ast/statements.rakumod add-method(RakuAST::Categorical, 'category', [], anon sub category ($self) { nqp::getattr(nqp::decont($self), RakuAST::Categorical, '$!category') }); compose(RakuAST::Categorical); parent(RakuAST::ModuleLoading, Any); add-attribute(RakuAST::ModuleLoading, List, '$!categoricals'); add-method(RakuAST::ModuleLoading, 'categoricals', [RakuAST::ModuleLoading, '', 0, 0], anon sub categoricals ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1456 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::ModuleLoading, '$!categoricals')) }); add-method(RakuAST::ModuleLoading, 'IMPL-LOAD-MODULE', [RakuAST::ModuleLoading, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::Name, '$module-name', 0, 0], anon sub IMPL-LOAD-MODULE ($SELF_CONT, $resolver!, $module-name!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $module-name := nqp::decont($module-name); #line 1460 src/Raku/ast/statements.rakumod # Build dependency specification for the module. my $dependency-specification := $resolver.resolve-name-constant( RakuAST::Name.from-identifier-parts('CompUnit', 'DependencySpecification') ).compile-time-value; my $opts := nqp::hash(); for $module-name.colonpairs { $opts{$_.key} := $_.simple-compile-time-quote-value; } my $spec := $dependency-specification.new( :short-name($module-name.canonicalize(:colonpairs((Bool.WHO)))), :from($opts // 'Perl6'), :auth-matcher($opts // (Bool.WHO)), :api-matcher($opts // (Bool.WHO)), :version-matcher($opts // (Bool.WHO)), ); # Load it using the registry. my $registry := $resolver.resolve-name-constant( RakuAST::Name.from-identifier-parts('CompUnit', 'RepositoryRegistry') ).compile-time-value; my $comp-unit := $registry.head.need($spec); my $globalish := $comp-unit.handle.globalish-package; $SELF.IMPL-IMPORT-ONE($resolver, $SELF.IMPL-STASH-HASH($globalish)); $comp-unit }); add-method(RakuAST::ModuleLoading, 'IMPL-IMPORT', [RakuAST::ModuleLoading, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, Mu, '$handle', 0, 0, Mu, '$arglist', 0, 0], anon sub IMPL-IMPORT ($SELF_CONT, $resolver!, $handle!, $arglist!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $handle := nqp::decont($handle); $arglist := nqp::decont($arglist); #line 1487 src/Raku/ast/statements.rakumod my $EXPORT := $handle.export-package; if nqp::isconcrete($EXPORT) { $EXPORT := $EXPORT.FLATTENABLE_HASH(); # TODO deal with non-default imports due to tags my @to-import := ['MANDATORY']; my @positional-imports; if nqp::isconcrete($arglist) { my $Pair := $resolver.setting-constant('Pair'); for $arglist -> $tag { if nqp::istype($tag, $Pair) { my str $tag-name := nqp::unbox_s($tag.key); unless nqp::existskey($EXPORT, $tag-name) { # TODO X::Import::NoSuchTag nqp::die('No such tag') } nqp::push(@to-import, $tag-name); } else { nqp::push(@positional-imports, $tag); } } } else { nqp::push(@to-import, 'DEFAULT'); } for @to-import -> str $tag { if nqp::existskey($EXPORT, $tag) { $SELF.IMPL-IMPORT-ONE($resolver, $SELF.IMPL-STASH-HASH($EXPORT{$tag}.WHO)); } } my &EXPORT := $handle.export-sub; if nqp::isconcrete(&EXPORT) { my $result := &EXPORT(|@positional-imports); if nqp::istype($result, Map) { my $storage := $result.hash.FLATTENABLE_HASH(); $SELF.IMPL-IMPORT-ONE( $resolver, $storage, :need-decont(!(nqp::what($result) =:= Map)), ); } else { nqp::die("&EXPORT sub did not return a Map"); } } } }); add-method(RakuAST::ModuleLoading, 'IMPL-IMPORT-ONE', [RakuAST::ModuleLoading, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, Mu, '$stash', 0, 0, Bool, '$need-decont', 1, 1], anon sub IMPL-IMPORT-ONE ($SELF_CONT, $resolver!, $stash!, :$need-decont?) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $stash := nqp::decont($stash); $need-decont := nqp::decont($need-decont); #line 1537 src/Raku/ast/statements.rakumod my $target-scope := $resolver.current-scope; for $SELF.IMPL-SORTED-KEYS($stash) -> $key { next if $key eq 'EXPORT'; my $value := $stash{$key}; if $need-decont && nqp::islt_i(nqp::index('$&', nqp::substr($key,0,1)),0) { $value := nqp::decont($value); } my $declarand := RakuAST::Declaration::Import.new: :lexical-name($key), :compile-time-value($value); $target-scope.merge-generated-lexical-declaration: $declarand, :$resolver; my $categorical := $key ~~ /^ '&' (\w+) [ ':<' (.+) '>' | ':«' (.+) '»' ] $/; if $categorical { nqp::push(nqp::getattr($SELF, RakuAST::ModuleLoading, '$!categoricals'), RakuAST::Categorical.new( :category($categorical[0]), :opname($categorical[1]), :subname(nqp::substr($key, 1)), :$declarand )); } } }); add-method(RakuAST::ModuleLoading, 'IMPL-STASH-HASH', [RakuAST::ModuleLoading, '', 0, 0, Mu, '$pkg', 0, 0], anon sub IMPL-STASH-HASH ($SELF_CONT, $pkg!) { my $SELF := nqp::decont($SELF_CONT); $pkg := nqp::decont($pkg); #line 1561 src/Raku/ast/statements.rakumod my $hash := $pkg; unless nqp::ishash($hash) { $hash := $hash.FLATTENABLE_HASH(); } $hash }); compose(RakuAST::ModuleLoading); parent(RakuAST::Statement::Use, RakuAST::Statement); parent(RakuAST::Statement::Use, RakuAST::BeginTime); parent(RakuAST::Statement::Use, RakuAST::ProducesNil); parent(RakuAST::Statement::Use, RakuAST::ModuleLoading); add-attribute(RakuAST::Statement::Use, RakuAST::Name, '$!module-name'); add-attribute(RakuAST::Statement::Use, RakuAST::Expression, '$!argument'); add-method(RakuAST::Statement::Use, 'new', [RakuAST::Statement::Use, '', 0, 0, RakuAST::Name, '$module-name', 1, 0, RakuAST::Expression, '$argument', 1, 1, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$module-name!, :$argument?, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $module-name := nqp::decont($module-name); $argument := nqp::decont($argument); $labels := nqp::decont($labels); #line 1580 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Use, '$!module-name', $module-name); nqp::bindattr($obj, RakuAST::ModuleLoading, '$!categoricals', []); nqp::bindattr($obj, RakuAST::Statement::Use, '$!argument', $argument // RakuAST::Expression); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Use, 'PERFORM-BEGIN', [RakuAST::Statement::Use, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1590 src/Raku/ast/statements.rakumod # Evaluate the argument to the module load, if any. my $arglist := nqp::getattr($SELF, RakuAST::Statement::Use, '$!argument') ?? $SELF.IMPL-BEGIN-TIME-EVALUATE(nqp::getattr($SELF, RakuAST::Statement::Use, '$!argument'), $resolver, $context).List.FLATTENABLE_LIST !! Nil; my $comp-unit := $SELF.IMPL-LOAD-MODULE($resolver, nqp::getattr($SELF, RakuAST::Statement::Use, '$!module-name')); $SELF.IMPL-IMPORT($resolver, $comp-unit.handle, $arglist); }); add-method(RakuAST::Statement::Use, 'visit-children', [RakuAST::Statement::Use, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1600 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Use, '$!module-name')); $visitor(nqp::getattr($SELF, RakuAST::Statement::Use, '$!argument')) if nqp::getattr($SELF, RakuAST::Statement::Use, '$!argument'); $SELF.visit-labels($visitor); }); #line 1577 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Use, 'module-name', [], anon sub module-name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Use, '$!module-name') }); #line 1578 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Use, 'argument', [], anon sub argument ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Use, '$!argument') }); compose(RakuAST::Statement::Use); parent(RakuAST::Statement::Need, RakuAST::Statement); parent(RakuAST::Statement::Need, RakuAST::BeginTime); parent(RakuAST::Statement::Need, RakuAST::ProducesNil); parent(RakuAST::Statement::Need, RakuAST::ModuleLoading); add-attribute(RakuAST::Statement::Need, List, '$!module-names'); add-method(RakuAST::Statement::Need, 'new', [RakuAST::Statement::Need, '', 0, 0, List, '$module-names', 1, 0, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$module-names!, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $module-names := nqp::decont($module-names); $labels := nqp::decont($labels); #line 1616 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Need, '$!module-names', $SELF.IMPL-UNWRAP-LIST($module-names)); nqp::bindattr($obj, RakuAST::ModuleLoading, '$!categoricals', []); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Need, 'PERFORM-BEGIN', [RakuAST::Statement::Need, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1625 src/Raku/ast/statements.rakumod for nqp::getattr($SELF, RakuAST::Statement::Need, '$!module-names') { $SELF.IMPL-LOAD-MODULE($resolver, $_); } }); add-method(RakuAST::Statement::Need, 'module-names', [RakuAST::Statement::Need, '', 0, 0], anon sub module-names ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1631 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Statement::Need, '$!module-names')) }); add-method(RakuAST::Statement::Need, 'visit-children', [RakuAST::Statement::Need, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1633 src/Raku/ast/statements.rakumod for nqp::getattr($SELF, RakuAST::Statement::Need, '$!module-names') { $visitor($_); } $SELF.visit-labels($visitor); }); compose(RakuAST::Statement::Need); parent(RakuAST::Statement::Import, RakuAST::Statement); parent(RakuAST::Statement::Import, RakuAST::BeginTime); parent(RakuAST::Statement::Import, RakuAST::ProducesNil); parent(RakuAST::Statement::Import, RakuAST::ModuleLoading); parent(RakuAST::Statement::Import, RakuAST::Lookup); parent(RakuAST::Statement::Import, RakuAST::ImplicitLookups); add-attribute(RakuAST::Statement::Import, RakuAST::Name, '$!module-name'); add-attribute(RakuAST::Statement::Import, RakuAST::Expression, '$!argument'); add-method(RakuAST::Statement::Import, 'new', [RakuAST::Statement::Import, '', 0, 0, RakuAST::Name, '$module-name', 1, 0, RakuAST::Expression, '$argument', 1, 1, List, '$labels', 1, 1], anon sub new ($SELF_CONT, :$module-name!, :$argument?, :$labels?) { my $SELF := nqp::decont($SELF_CONT); $module-name := nqp::decont($module-name); $argument := nqp::decont($argument); $labels := nqp::decont($labels); #line 1653 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Import, '$!module-name', $module-name); nqp::bindattr($obj, RakuAST::ModuleLoading, '$!categoricals', []); nqp::bindattr($obj, RakuAST::Statement::Import, '$!argument', $argument // RakuAST::Expression); $obj.set-labels($labels); $obj }); add-method(RakuAST::Statement::Import, 'resolve-with', [RakuAST::Statement::Import, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1663 src/Raku/ast/statements.rakumod my $resolved := $resolver.resolve-name-constant(nqp::getattr($SELF, RakuAST::Statement::Import, '$!module-name')); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Statement::Import, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Statement::Import, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1671 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier-parts('CompUnit', 'Handle')), ]) }); add-method(RakuAST::Statement::Import, 'PERFORM-BEGIN', [RakuAST::Statement::Import, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1677 src/Raku/ast/statements.rakumod # Evaluate the argument to the import, if any. my $arglist := nqp::getattr($SELF, RakuAST::Statement::Import, '$!argument') ?? $SELF.IMPL-BEGIN-TIME-EVALUATE(nqp::getattr($SELF, RakuAST::Statement::Import, '$!argument'), $resolver, $context).List.FLATTENABLE_LIST !! Nil; my $module := $SELF.resolution.compile-time-value; my $CompUnitHandle := $SELF.get-implicit-lookups().AT-POS(0).compile-time-value; my $handle := $CompUnitHandle.from-unit($module.WHO); $SELF.IMPL-IMPORT($resolver, $handle, $arglist); }); add-method(RakuAST::Statement::Import, 'visit-children', [RakuAST::Statement::Import, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1689 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Import, '$!module-name')); $visitor(nqp::getattr($SELF, RakuAST::Statement::Import, '$!argument')) if nqp::getattr($SELF, RakuAST::Statement::Import, '$!argument'); $SELF.visit-labels($visitor); }); #line 1650 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Import, 'module-name', [], anon sub module-name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Import, '$!module-name') }); #line 1651 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Import, 'argument', [], anon sub argument ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Import, '$!argument') }); compose(RakuAST::Statement::Import); parent(RakuAST::Statement::Require, RakuAST::Statement); parent(RakuAST::Statement::Require, RakuAST::ImplicitLookups); add-attribute(RakuAST::Statement::Require, RakuAST::Name, '$!module-name'); add-method(RakuAST::Statement::Require, 'new', [RakuAST::Statement::Require, '', 0, 0, RakuAST::Name, '$module-name', 1, 0], anon sub new ($SELF_CONT, :$module-name!) { my $SELF := nqp::decont($SELF_CONT); $module-name := nqp::decont($module-name); #line 1703 src/Raku/ast/statements.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Statement::Require, '$!module-name', $module-name); $obj }); add-method(RakuAST::Statement::Require, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Statement::Require, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1709 src/Raku/ast/statements.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier-parts('CompUnit', 'DependencySpecification')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier-parts('CompUnit', 'RepositoryRegistry')), ]) }); add-method(RakuAST::Statement::Require, 'IMPL-TO-QAST', [RakuAST::Statement::Require, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1716 src/Raku/ast/statements.rakumod my $lookups := $SELF.get-implicit-lookups; my $depspec := $lookups.AT-POS(0).compile-time-value; my $registry := $lookups.AT-POS(1).compile-time-value; my $short-name := QAST::SVal.new(:value(nqp::getattr($SELF, RakuAST::Statement::Require, '$!module-name').canonicalize)); $short-name.named('short-name'); my $spec := QAST::Op.new( :op('callmethod'), :name('new'), QAST::WVal.new(:value($depspec)), $short-name, ); my $compunit_past := QAST::Op.new( :op('callmethod'), :name('need'), QAST::Op.new( :op('callmethod'), :name('head'), QAST::WVal.new(:value($registry)), ), $spec, ); }); add-method(RakuAST::Statement::Require, 'visit-children', [RakuAST::Statement::Require, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1738 src/Raku/ast/statements.rakumod $visitor(nqp::getattr($SELF, RakuAST::Statement::Require, '$!module-name')); }); #line 1701 src/Raku/ast/statements.rakumod add-method(RakuAST::Statement::Require, 'module-name', [], anon sub module-name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Statement::Require, '$!module-name') }); compose(RakuAST::Statement::Require); parent(OperatorProperties, Any); add-attribute(OperatorProperties, str, '$!precedence'); add-attribute(OperatorProperties, str, '$!sub-precedence'); add-attribute(OperatorProperties, str, '$!associative'); add-attribute(OperatorProperties, str, '$!thunky'); add-attribute(OperatorProperties, str, '$!dba'); add-attribute(OperatorProperties, str, '$!next-term'); add-attribute(OperatorProperties, int, '$!iffy'); add-attribute(OperatorProperties, int, '$!diffy'); add-attribute(OperatorProperties, int, '$!fiddly'); add-attribute(OperatorProperties, int, '$!adverb'); add-attribute(OperatorProperties, int, '$!ternary'); add-method(OperatorProperties, 'new', [OperatorProperties, '', 0, 0, str, '$precedence', 1, 1, str, '$sub-precedence', 1, 1, str, '$associative', 1, 1, str, '$thunky', 1, 1, str, '$dba', 1, 1, str, '$next-term', 1, 1, int, '$iffy', 1, 1, int, '$diffy', 1, 1, int, '$fiddly', 1, 1, int, '$adverb', 1, 1, int, '$ternary', 1, 1], anon sub new ($SELF_CONT, :$precedence?, :$sub-precedence?, :$associative?, :$thunky?, :$dba?, :$next-term?, :$iffy?, :$diffy?, :$fiddly?, :$adverb?, :$ternary?) { my $SELF := nqp::decont($SELF_CONT); $precedence := nqp::decont($precedence); $sub-precedence := nqp::decont($sub-precedence); $associative := nqp::decont($associative); $thunky := nqp::decont($thunky); $dba := nqp::decont($dba); $next-term := nqp::decont($next-term); $iffy := nqp::decont($iffy); $diffy := nqp::decont($diffy); $fiddly := nqp::decont($fiddly); $adverb := nqp::decont($adverb); $ternary := nqp::decont($ternary); #line 43 src/Raku/ast/operator-properties.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj,OperatorProperties,'$!precedence', $precedence // (nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!precedence') !! "")); nqp::bindattr_s($obj,OperatorProperties,'$!sub-precedence', $sub-precedence // (nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!sub-precedence') !! "")); nqp::bindattr_s($obj,OperatorProperties,'$!associative', $associative // (nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!associative') !! "")); nqp::bindattr_s($obj,OperatorProperties,'$!thunky', $thunky // (nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!thunky') !! "")); nqp::bindattr_s($obj,OperatorProperties,'$!dba', $dba // (nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!dba') !! "")); nqp::bindattr_s($obj,OperatorProperties,'$!next-term', $next-term // (nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!next-term') !! "")); nqp::bindattr_i($obj,OperatorProperties,'$!iffy', $iffy // (nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!iffy') !! 0)); nqp::bindattr_i($obj,OperatorProperties,'$!diffy', $diffy // (nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!diffy') !! 0)); nqp::bindattr_i($obj,OperatorProperties,'$!fiddly', $fiddly // (nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!fiddly') !! 0)); nqp::bindattr_i($obj,OperatorProperties,'$!adverb', $adverb // (nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!adverb') !! 0)); nqp::bindattr_i($obj,OperatorProperties,'$!ternary', $ternary // (nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!ternary') !! 0)); $obj }); add-method(OperatorProperties, 'new-compat', [OperatorProperties, '', 0, 0, str, '$prec', 1, 1, str, '$sub', 1, 1, str, '$assoc', 1, 1, str, '$thunky', 1, 1, str, '$dba', 1, 1, str, '$nextterm', 1, 1, int, '$iffy', 1, 1, int, '$diffy', 1, 1, int, '$fiddly', 1, 1, int, '$adverb', 1, 1, int, '$ternary', 1, 1, Any, '%_', 0, 0], anon sub new-compat ($SELF_CONT, :$prec?, :$sub?, :$assoc?, :$thunky?, :$dba?, :$nextterm?, :$iffy?, :$diffy?, :$fiddly?, :$adverb?, :$ternary?, *%_) { my $SELF := nqp::decont($SELF_CONT); $prec := nqp::decont($prec); $sub := nqp::decont($sub); $assoc := nqp::decont($assoc); $thunky := nqp::decont($thunky); $dba := nqp::decont($dba); $nextterm := nqp::decont($nextterm); $iffy := nqp::decont($iffy); $diffy := nqp::decont($diffy); $fiddly := nqp::decont($fiddly); $adverb := nqp::decont($adverb); $ternary := nqp::decont($ternary); %_ := nqp::decont(%_); #line 86 src/Raku/ast/operator-properties.rakumod $SELF.new( :precedence($prec), :sub-precedence($sub), :associative($assoc), :$thunky, :$dba, :next-term($nextterm), :$iffy, :$diffy, :$fiddly, :$adverb, :$ternary ) }); add-method(OperatorProperties, 'associative-reversed', [OperatorProperties, '', 0, 0], anon sub associative-reversed ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 103 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!associative') eq 'left' ?? $SELF.new(:associative, :dba("reversed " ~ nqp::getattr_s($SELF, OperatorProperties, '$!dba'))) !! nqp::getattr_s($SELF, OperatorProperties, '$!associative') eq 'right' ?? $SELF.new(:associative, :dba("reversed " ~ nqp::getattr_s($SELF, OperatorProperties, '$!dba'))) !! $SELF !! $SELF }); add-method(OperatorProperties, 'raku', [OperatorProperties, '', 0, 0], anon sub raku ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 114 src/Raku/ast/operator-properties.rakumod my str $name := $SELF.HOW.name($SELF); return $name unless nqp::isconcrete($SELF); my $parts := nqp::list_s; nqp::push_s($parts,':precedence("' ~ nqp::getattr_s($SELF, OperatorProperties, '$!precedence') ~ '")') if nqp::getattr_s($SELF, OperatorProperties, '$!precedence'); nqp::push_s($parts,':sub-precedence("' ~ nqp::getattr_s($SELF, OperatorProperties, '$!sub-precedence') ~ '")') if nqp::getattr_s($SELF, OperatorProperties, '$!sub-precedence'); nqp::push_s($parts,':associative("' ~ nqp::getattr_s($SELF, OperatorProperties, '$!associative') ~ '")') if nqp::getattr_s($SELF, OperatorProperties, '$!associative'); nqp::push_s($parts,':thunky("' ~ nqp::getattr_s($SELF, OperatorProperties, '$!thunky') ~ '")') if nqp::getattr_s($SELF, OperatorProperties, '$!thunky'); nqp::push_s($parts,':dba("' ~ nqp::getattr_s($SELF, OperatorProperties, '$!dba') ~ '")') if nqp::getattr_s($SELF, OperatorProperties, '$!dba'); nqp::push_s($parts,':next-term("' ~ nqp::getattr_s($SELF, OperatorProperties, '$!next-term') ~ '")') if nqp::getattr_s($SELF, OperatorProperties, '$!next-term'); nqp::push_s($parts,':iffy') if nqp::getattr_i($SELF, OperatorProperties, '$!iffy'); nqp::push_s($parts,':diffy') if nqp::getattr_i($SELF, OperatorProperties, '$!diffy'); nqp::push_s($parts,':fiddly') if nqp::getattr_i($SELF, OperatorProperties, '$!fiddly'); nqp::push_s($parts,':adverb') if nqp::getattr_i($SELF, OperatorProperties, '$!adverb'); nqp::push_s($parts,':ternary') if nqp::getattr_i($SELF, OperatorProperties, '$!ternary'); $name ~ '.new: ' ~ nqp::join(', ',$parts) }); add-method(OperatorProperties, 'bracket-openers', [OperatorProperties, '', 0, 0], anon sub bracket-openers ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 146 src/Raku/ast/operator-properties.rakumod my constant OPENERS := "\x0028\x003C\x005B\x007B\x00AB\x0F3A\x0F3C\x169B\x2018\x201A" ~ "\x201B\x201C\x201E\x201F\x2039\x2045\x207D\x208D\x2208\x2209" ~ "\x220A\x2215\x223C\x2243\x2252\x2254\x2264\x2266\x2268\x226A" ~ "\x226E\x2270\x2272\x2274\x2276\x2278\x227A\x227C\x227E\x2280" ~ "\x2282\x2284\x2286\x2288\x228A\x228F\x2291\x2298\x22A2\x22A6" ~ "\x22A8\x22A9\x22AB\x22B0\x22B2\x22B4\x22B6\x22C9\x22CB\x22D0" ~ "\x22D6\x22D8\x22DA\x22DC\x22DE\x22E0\x22E2\x22E4\x22E6\x22E8" ~ "\x22EA\x22EC\x22F0\x22F2\x22F3\x22F4\x22F6\x22F7\x2308\x230A" ~ "\x23B4\x2768\x276A\x276C\x276E\x2770\x2772\x2774\x27C3\x27C5" ~ "\x27D5\x27DD\x27E2\x27E4\x27E6\x27E8\x27EA\x27EC\x27EE\x2983" ~ "\x2985\x2987\x2989\x298B\x298D\x298F\x2991\x2993\x2995\x2997" ~ "\x29C0\x29C4\x29CF\x29D1\x29D4\x29D8\x29DA\x29F8\x29FC\x2A2B" ~ "\x2A2D\x2A34\x2A3C\x2A64\x2A79\x2A7D\x2A7F\x2A81\x2A83\x2A8B" ~ "\x2A91\x2A93\x2A95\x2A97\x2A99\x2A9B\x2AA1\x2AA6\x2AA8\x2AAA" ~ "\x2AAC\x2AAF\x2AB3\x2ABB\x2ABD\x2ABF\x2AC1\x2AC3\x2AC5\x2ACD" ~ "\x2ACF\x2AD1\x2AD3\x2AD5\x2AEC\x2AF7\x2AF9\x2E02\x2E04\x2E09" ~ "\x2E0C\x2E1C\x2E20\x2E22\x2E24\x2E26\x2E28\x3008\x3008\x300A" ~ "\x300C\x300E\x3010\x3014\x3016\x3018\x301A\x301D\xFE17\xFE35" ~ "\xFE37\xFE39\xFE3B\xFE3D\xFE3F\xFE41\xFE43\xFE47\xFE59\xFE5B" ~ "\xFE5D\xFF08\xFF1C\xFF3B\xFF5B\xFF5F\xFF62" ; }); add-method(OperatorProperties, 'bracket-closers', [OperatorProperties, '', 0, 0], anon sub bracket-closers ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 172 src/Raku/ast/operator-properties.rakumod my constant CLOSERS := "\x0029\x003E\x005D\x007D\x00BB\x0F3B\x0F3D\x169C\x2019\x2019" ~ "\x2019\x201D\x201D\x201D\x203A\x2046\x207E\x208E\x220B\x220C" ~ "\x220D\x29F5\x223D\x22CD\x2253\x2255\x2265\x2267\x2269\x226B" ~ "\x226F\x2271\x2273\x2275\x2277\x2279\x227B\x227D\x227F\x2281" ~ "\x2283\x2285\x2287\x2289\x228B\x2290\x2292\x29B8\x22A3\x2ADE" ~ "\x2AE4\x2AE3\x2AE5\x22B1\x22B3\x22B5\x22B7\x22CA\x22CC\x22D1" ~ "\x22D7\x22D9\x22DB\x22DD\x22DF\x22E1\x22E3\x22E5\x22E7\x22E9" ~ "\x22EB\x22ED\x22F1\x22FA\x22FB\x22FC\x22FD\x22FE\x2309\x230B" ~ "\x23B5\x2769\x276B\x276D\x276F\x2771\x2773\x2775\x27C4\x27C6" ~ "\x27D6\x27DE\x27E3\x27E5\x27E7\x27E9\x27EB\x27ED\x27EF\x2984" ~ "\x2986\x2988\x298A\x298C\x2990\x298E\x2992\x2994\x2996\x2998" ~ "\x29C1\x29C5\x29D0\x29D2\x29D5\x29D9\x29DB\x29F9\x29FD\x2A2C" ~ "\x2A2E\x2A35\x2A3D\x2A65\x2A7A\x2A7E\x2A80\x2A82\x2A84\x2A8C" ~ "\x2A92\x2A94\x2A96\x2A98\x2A9A\x2A9C\x2AA2\x2AA7\x2AA9\x2AAB" ~ "\x2AAD\x2AB0\x2AB4\x2ABC\x2ABE\x2AC0\x2AC2\x2AC4\x2AC6\x2ACE" ~ "\x2AD0\x2AD2\x2AD4\x2AD6\x2AED\x2AF8\x2AFA\x2E03\x2E05\x2E0A" ~ "\x2E0D\x2E1D\x2E21\x2E23\x2E25\x2E27\x2E29\x3009\x3009\x300B" ~ "\x300D\x300F\x3011\x3015\x3017\x3019\x301B\x301E\xFE18\xFE36" ~ "\xFE38\xFE3A\xFE3C\xFE3E\xFE40\xFE42\xFE44\xFE48\xFE5A\xFE5C" ~ "\xFE5E\xFF09\xFF1E\xFF3D\xFF5D\xFF60\xFF63" ; }); add-method(OperatorProperties, 'bracket-closer-for-opener', [OperatorProperties, '', 0, 0, str, '$opener', 0, 0], anon sub bracket-closer-for-opener ($SELF_CONT, $opener!) { my $SELF := nqp::decont($SELF_CONT); $opener := nqp::decont($opener); #line 198 src/Raku/ast/operator-properties.rakumod (my int $index := nqp::index($SELF.bracket-openers,$opener)) < 0 ?? Nil !! nqp::substr($SELF.bracket-closers,$index,1) }); add-method(OperatorProperties, 'bracket-opener-for-closer', [OperatorProperties, '', 0, 0, str, '$closer', 0, 0], anon sub bracket-opener-for-closer ($SELF_CONT, $closer!) { my $SELF := nqp::decont($SELF_CONT); $closer := nqp::decont($closer); #line 207 src/Raku/ast/operator-properties.rakumod (my int $index := nqp::index($SELF.bracket-closers,$closer)) < 0 ?? Nil !! nqp::substr($SELF.bracket-openers,$index,1) }); add-method(OperatorProperties, 'reserved-operators-lookup', [OperatorProperties, '', 0, 0], anon sub reserved-operators-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 217 src/Raku/ast/operator-properties.rakumod my constant RESERVED := nqp::hash( 'infix:sym<=>', "", 'infix:sym<:=>', "", 'infix:sym<::=>', "", 'infix:sym<~~>', "(consider implementing an ACCEPTS method)", 'prefix:sym<|>', "" ) }); add-method(OperatorProperties, 'is-reserved-operator', [OperatorProperties, '', 0, 0, str, '$operator', 0, 0], anon sub is-reserved-operator ($SELF_CONT, $operator!) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 228 src/Raku/ast/operator-properties.rakumod nqp::existskey($SELF.reserved-operators-lookup,$operator) }); add-method(OperatorProperties, 'reserved-operator-hint', [OperatorProperties, '', 0, 0, str, '$operator', 0, 0], anon sub reserved-operator-hint ($SELF_CONT, $operator!) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 233 src/Raku/ast/operator-properties.rakumod nqp::atkey($SELF.reserved-operators-lookup,$operator) }); add-method(OperatorProperties, 'precedence', [OperatorProperties, '', 0, 0], anon sub precedence ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 243 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!precedence') !! "" }); add-method(OperatorProperties, 'sub-precedence', [OperatorProperties, '', 0, 0], anon sub sub-precedence ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 244 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!sub-precedence') !! "" }); add-method(OperatorProperties, 'associative', [OperatorProperties, '', 0, 0], anon sub associative ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 245 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!associative') !! "" }); add-method(OperatorProperties, 'thunky', [OperatorProperties, '', 0, 0], anon sub thunky ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 246 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!thunky') !! "" }); add-method(OperatorProperties, 'dba', [OperatorProperties, '', 0, 0], anon sub dba ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 247 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!dba') !! "" }); add-method(OperatorProperties, 'next-term', [OperatorProperties, '', 0, 0], anon sub next-term ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 248 src/Raku/ast/operator-properties.rakumod (nqp::isconcrete($SELF) ?? nqp::getattr_s($SELF, OperatorProperties, '$!next-term') !! "") || 'termish' }); add-method(OperatorProperties, 'iffy', [OperatorProperties, '', 0, 0], anon sub iffy ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 252 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!iffy') !! 0 }); add-method(OperatorProperties, 'diffy', [OperatorProperties, '', 0, 0], anon sub diffy ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 253 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!diffy') !! 0 }); add-method(OperatorProperties, 'fiddly', [OperatorProperties, '', 0, 0], anon sub fiddly ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 254 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!fiddly') !! 0 }); add-method(OperatorProperties, 'adverb', [OperatorProperties, '', 0, 0], anon sub adverb ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 255 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!adverb') !! 0 }); add-method(OperatorProperties, 'ternary', [OperatorProperties, '', 0, 0], anon sub ternary ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 256 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? nqp::getattr_i($SELF, OperatorProperties, '$!ternary') !! 0 }); add-method(OperatorProperties, 'chain', [OperatorProperties, '', 0, 0], anon sub chain ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 259 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) && nqp::getattr_s($SELF, OperatorProperties, '$!associative') eq 'chain' }); add-method(OperatorProperties, 'short-circuit', [OperatorProperties, '', 0, 0], anon sub short-circuit ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 262 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) && nqp::getattr_s($SELF, OperatorProperties, '$!thunky') ne "" }); add-method(OperatorProperties, 'sub-or-precedence', [OperatorProperties, '', 0, 0], anon sub sub-or-precedence ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 265 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? (nqp::getattr_s($SELF, OperatorProperties, '$!sub-precedence') || nqp::getattr_s($SELF, OperatorProperties, '$!precedence')) !! "" }); add-method(OperatorProperties, 'not-reducable', [OperatorProperties, '', 0, 0], anon sub not-reducable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 271 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? "" !! nqp::getattr_i($SELF, OperatorProperties, '$!fiddly') ?? "fiddly" !! nqp::getattr_i($SELF, OperatorProperties, '$!diffy') && nqp::getattr_s($SELF, OperatorProperties, '$!associative') eq 'chain' ?? "diffy and not chaining" !! "" }); add-method(OperatorProperties, 'reducer-name', [OperatorProperties, '', 0, 0], anon sub reducer-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 282 src/Raku/ast/operator-properties.rakumod if nqp::isconcrete($SELF) { if nqp::iseq_s(nqp::getattr_s($SELF, OperatorProperties, '$!precedence'),'f=') { '&METAOP_REDUCE_LISTINFIX' } else { my $associative := nqp::getattr_s($SELF, OperatorProperties, '$!associative'); nqp::chars($associative) ?? nqp::iseq_s($associative,'chain') ?? '&METAOP_REDUCE_CHAIN' !! nqp::iseq_s($associative,'list') ?? '&METAOP_REDUCE_LIST' !! nqp::iseq_s($associative,'right') ?? '&METAOP_REDUCE_RIGHT' !! '&METAOP_REDUCE_LEFT' # assume 'left' or 'non' !! '&METAOP_REDUCE_LEFT' } } else { '&METAOP_REDUCE_LEFT' } }); add-method(OperatorProperties, 'prec', [OperatorProperties, '', 0, 0, str, '$key', 0, 1], anon sub prec ($SELF_CONT, $key?) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); #line 306 src/Raku/ast/operator-properties.rakumod if nqp::isconcrete($SELF) { if $key { nqp::atkey($SELF.prec,$key) } else { my $hash := nqp::hash; nqp::bindkey($hash,'prec',nqp::getattr_s($SELF, OperatorProperties, '$!precedence')) if nqp::getattr_s($SELF, OperatorProperties, '$!precedence'); nqp::bindkey($hash,'sub',nqp::getattr_s($SELF, OperatorProperties, '$!sub-precedence')) if nqp::getattr_s($SELF, OperatorProperties, '$!sub-precedence'); nqp::bindkey($hash,'assoc',nqp::getattr_s($SELF, OperatorProperties, '$!associative')) if nqp::getattr_s($SELF, OperatorProperties, '$!associative'); nqp::bindkey($hash,'thunky',nqp::getattr_s($SELF, OperatorProperties, '$!thunky')) if nqp::getattr_s($SELF, OperatorProperties, '$!thunky'); nqp::bindkey($hash,'dba',nqp::getattr_s($SELF, OperatorProperties, '$!dba')) if nqp::getattr_s($SELF, OperatorProperties, '$!dba'); nqp::bindkey($hash,'nextterm',nqp::getattr_s($SELF, OperatorProperties, '$!next-term')) if nqp::getattr_s($SELF, OperatorProperties, '$!next-term'); nqp::bindkey($hash,'iffy',nqp::getattr_i($SELF, OperatorProperties, '$!iffy')) if nqp::getattr_i($SELF, OperatorProperties, '$!iffy'); nqp::bindkey($hash,'diffy',nqp::getattr_i($SELF, OperatorProperties, '$!diffy')) if nqp::getattr_i($SELF, OperatorProperties, '$!diffy'); nqp::bindkey($hash,'fiddly',nqp::getattr_i($SELF, OperatorProperties, '$!fiddly')) if nqp::getattr_i($SELF, OperatorProperties, '$!fiddly'); nqp::bindkey($hash,'adverb',nqp::getattr_i($SELF, OperatorProperties, '$!adverb')) if nqp::getattr_i($SELF, OperatorProperties, '$!adverb'); nqp::bindkey($hash,'ternary',nqp::getattr_i($SELF, OperatorProperties, '$!ternary')) if nqp::getattr_i($SELF, OperatorProperties, '$!ternary'); $hash } } # called on type object else { if $key { $key eq 'prec' || $key eq 'assoc' || $key eq 'thunky' ?? "" !! $key eq 'iffy' ?? 0 !! nqp::null } else { nqp::hash } } }); add-method(OperatorProperties, 'known-category', [OperatorProperties, '', 0, 0, str, '$category', 0, 0], anon sub known-category ($SELF_CONT, $category!) { my $SELF := nqp::decont($SELF_CONT); $category := nqp::decont($category); #line 344 src/Raku/ast/operator-properties.rakumod my constant CATEGORIES := nqp::hash( 'infix',1, 'prefix',1, 'postfix',1, 'postcircumfix',1, 'circumfix',1 ); nqp::existskey(CATEGORIES,$category) }); add-method(OperatorProperties, 'equiv', [OperatorProperties, '', 0, 0, str, '$associative', 0, 0], anon sub equiv ($SELF_CONT, $associative!) { my $SELF := nqp::decont($SELF_CONT); $associative := nqp::decont($associative); #line 354 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? $SELF.new( associative => nqp::isnull_s($associative) ?? nqp::getattr_s($SELF, OperatorProperties, '$!associative') !! $associative ) !! $SELF.new }); add-method(OperatorProperties, 'tighter', [OperatorProperties, '', 0, 0, str, '$associative', 0, 0], anon sub tighter ($SELF_CONT, $associative!) { my $SELF := nqp::decont($SELF_CONT); $associative := nqp::decont($associative); #line 363 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? $SELF.new( precedence => nqp::join('@=',nqp::split('=',nqp::getattr_s($SELF, OperatorProperties, '$!precedence'))), associative => nqp::isnull_s($associative) ?? nqp::getattr_s($SELF, OperatorProperties, '$!associative') !! $associative ) !! nqp::die("No precedence found to be tighter for") }); add-method(OperatorProperties, 'looser', [OperatorProperties, '', 0, 0, str, '$associative', 0, 0], anon sub looser ($SELF_CONT, $associative!) { my $SELF := nqp::decont($SELF_CONT); $associative := nqp::decont($associative); #line 373 src/Raku/ast/operator-properties.rakumod nqp::isconcrete($SELF) ?? $SELF.new( precedence => nqp::join(':=',nqp::split('=',nqp::getattr_s($SELF, OperatorProperties, '$!precedence'))), associative => nqp::isnull_s($associative) ?? nqp::getattr_s($SELF, OperatorProperties, '$!associative') !! $associative ) !! nqp::die("No precedence found to be looser for") }); add-method(OperatorProperties, 'properties-for-group', [OperatorProperties, '', 0, 0, str, '$group', 0, 0], anon sub properties-for-group ($SELF_CONT, $group!) { my $SELF := nqp::decont($SELF_CONT); $group := nqp::decont($group); #line 399 src/Raku/ast/operator-properties.rakumod my constant PROPERTIES := nqp::hash( 'default-infix', nqp::hash( 'precedence','t=', 'associative', 'left' ), 'default-prefix', nqp::hash( 'precedence','v=', 'associative', 'unary' ), 'default-postfix', nqp::hash( 'precedence','x=', 'associative', 'unary' ), 'default-postcircumfix', nqp::hash( 'precedence','y=' ), 'default-circumfix', nqp::hash(), 'methodcall', nqp::hash( 'precedence','y=', 'associative','unary', 'fiddly', 1 ), 'autoincrement', nqp::hash( 'precedence','x=', 'associative','unary' ), 'exponentiation', nqp::hash( 'precedence','w=', 'associative','right' ), 'symbolic-unary', nqp::hash( 'precedence','v=', 'associative','unary' ), 'dotty-infix', nqp::hash( 'precedence','v=', 'associative','left', 'next-term','dottyopish', 'sub-precedence','z=', 'fiddly',1 ), 'multiplicative', nqp::hash( 'precedence','u=', 'associative','left' ), 'multiplicative-iffy', nqp::hash( 'precedence','u=', 'associative','left', 'iffy',1 ), 'additive', nqp::hash( 'precedence','t=', 'associative','left' ), 'additive-iffy', nqp::hash( 'precedence','t=', 'associative','left', 'iffy',1 ), 'replication-x', nqp::hash( 'precedence','s=', 'associative','left' ), 'replication-xx', nqp::hash( 'precedence','s=', 'associative','left', 'thunky','t.' ), 'concatenation', nqp::hash( 'precedence','r=', 'associative','left' ), 'junctive-and', nqp::hash( 'precedence','q=', 'associative','list' ), 'junctive-and-iffy', nqp::hash( 'precedence','q=', 'associative','list', 'iffy',1 ), 'junctive-or', nqp::hash( 'precedence','p=', 'associative','list' ), 'junctive-or-iffy', nqp::hash( 'precedence','p=', 'associative','list', 'iffy',1 ), 'named-unary', nqp::hash( 'precedence','o=', 'associative','unary' ), 'structural', nqp::hash( 'precedence','n=', 'associative','non', 'diffy',1 ), 'chaining', nqp::hash( 'precedence','m=', 'associative','chain', 'iffy',1, 'diffy',1 ), 'tight-and', nqp::hash( 'precedence','l=', 'associative','left', 'thunky','.t', 'iffy',1 ), 'tight-or', nqp::hash( 'precedence','k=', 'associative','left', 'thunky','.t', 'iffy',1 ), 'tight-defor', nqp::hash( 'precedence','k=', 'associative','left', 'thunky','.t' ), 'tight-xor', nqp::hash( 'precedence','k=', 'associative','list', 'thunky','..t', 'iffy',1 ), 'tight-minmax', nqp::hash( 'precedence','k=', 'associative','list' ), 'ternary', nqp::hash( 'precedence','j=', 'associative','right', 'thunky','.tt', 'fiddly',1, 'ternary',1 ), 'conditional-ff', nqp::hash( 'precedence','j=', 'associative','right', 'thunky','tt', 'iffy',1 ), 'item-assignment', nqp::hash( 'precedence','i=', 'associative','right' ), 'adverb', nqp::hash( 'precedence','i=', 'associative','unary', 'adverb',1 ), 'list-assignment', nqp::hash( 'precedence','i=', 'associative','right', 'fiddly',1, 'sub-precedence','e=' ), 'loose-unary', nqp::hash( 'precedence','h=', 'associative','unary' ), 'comma', nqp::hash( 'precedence','g=', 'associative','list', 'next-term','nulltermish' ), 'list-infix', nqp::hash( 'precedence','f=', 'associative','list' ), 'list-prefix', nqp::hash( 'precedence','e=', 'associative','right' ), 'loose-and', nqp::hash( 'precedence','d=', 'associative','left', 'thunky','.t', 'iffy',1 ), 'loose-andthen', nqp::hash( 'precedence','d=', 'associative','list', 'thunky','.b' ), 'loose-or', nqp::hash( 'precedence','c=', 'associative','left', 'thunky','.t', 'iffy',1 ), 'loose-xor', nqp::hash( 'precedence','c=', 'associative','list', 'thunky','.t', 'iffy',1 ), 'loose-orelse', nqp::hash( 'precedence','c=', 'associative','list', 'thunky','.b' ), 'sequencer', nqp::hash( 'precedence','b=', 'associative','list' ) ); # Convert raw properties into an object my %value := nqp::ifnull( nqp::atkey(PROPERTIES,$group), nqp::hash() ); nqp::ishash(%value) ?? nqp::bindkey( # first time PROPERTIES, $group, OperatorProperties.new(|%value, :dba($group)) ) !! %value # already instantiated }); add-method(OperatorProperties, 'produce', [OperatorProperties, '', 0, 0, Any, '$hash', 0, 0, str, '$key', 0, 0], anon sub produce ($SELF_CONT, $hash!, $key!) { my $SELF := nqp::decont($SELF_CONT); $hash := nqp::decont($hash); $key := nqp::decont($key); #line 560 src/Raku/ast/operator-properties.rakumod # Get current setting or default my $properties := nqp::ifnull( nqp::atkey($hash,$key), nqp::atkey($hash,$key := '') ); # If not yet an instance, create an instance and update in the # hash if the operator is a built-in. if nqp::isstr($properties) { $properties := $SELF.properties-for-group($properties); nqp::bindkey($hash,$key,$properties) if nqp::existskey($hash,$key); } $properties }); add-method(OperatorProperties, 'infix', [OperatorProperties, '', 0, 0, str, '$operator', 0, 1], anon sub infix ($SELF_CONT, $operator?) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 580 src/Raku/ast/operator-properties.rakumod my constant PROPERTIES := nqp::hash( '', 'default-infix', '.', 'dotty-infix', '.=', 'dotty-infix', '*', 'multiplicative', '×', 'multiplicative', '/', 'multiplicative', 'div', 'multiplicative', 'gcd', 'multiplicative', 'lcm', 'multiplicative', '%', 'multiplicative', 'mod', 'multiplicative', '+&', 'multiplicative', '~&', 'multiplicative', '+<', 'multiplicative', '+>', 'multiplicative', '~<', 'multiplicative', '~>', 'multiplicative', '%%', 'multiplicative-iffy', '?&', 'multiplicative-iffy', '+', 'additive', '-', 'additive', '−', 'additive', '+|', 'additive', '+^', 'additive', '~|', 'additive', '~^', 'additive', '?|', 'additive-iffy', '?^', 'additive-iffy', '**', 'exponentiation', 'x', 'replication-x', 'xx', 'replication-xx', '~', 'concatenation', '(&)', 'junctive-and', '∩', 'junctive-and', '(.)', 'junctive-and', '⊍', 'junctive-and', '&', 'junctive-and-iffy', '(+)', 'junctive-or', '⊎', 'junctive-or', '(|)', 'junctive-or', '∪', 'junctive-or', '(-)', 'junctive-or', '∖', 'junctive-or', '(^)', 'junctive-or', '⊖', 'junctive-or', '|', 'junctive-or-iffy', '^', 'junctive-or-iffy', '..', 'structural', '^..', 'structural', '..^', 'structural', '^..^', 'structural', '<=>', 'structural', 'leg', 'structural', 'cmp', 'structural', 'unicmp', 'structural', 'coll', 'structural', 'but', 'structural', 'does', 'structural', '>', 'chaining', '<', 'chaining', '>=', 'chaining', '<=', 'chaining', '(<)', 'chaining', '⊂', 'chaining', '(>)', 'chaining', '⊃', 'chaining', '(<=)', 'chaining', '⊆', 'chaining', '(>=)', 'chaining', '⊇', 'chaining', '(<+)', 'chaining', '≼', 'chaining', '(>+)', 'chaining', '≽', 'chaining', '==', 'chaining', '=~=', 'chaining', '≅', 'chaining', '!=', 'chaining', 'eq', 'chaining', 'ne', 'chaining', 'le', 'chaining', 'ge', 'chaining', 'lt', 'chaining', 'gt', 'chaining', '=:=', 'chaining', '===', 'chaining', 'eqv', 'chaining', 'before', 'chaining', 'after', 'chaining', '~~', 'chaining', '!~', 'chaining', # dummy for p5ism '!~~', 'chaining', '(elem)', 'chaining', '∈', 'chaining', '(cont)', 'chaining', '∋', 'chaining', '(==)', 'chaining', '≡', 'chaining', '∉', 'chaining', '∌', 'chaining', '⊄', 'chaining', '⊅', 'chaining', '≢', 'chaining', '⊈', 'chaining', '⊉', 'chaining', '&&', 'tight-and', '||', 'tight-or', '//', 'tight-defor', '^^', 'tight-xor', 'min', 'tight-minmax', 'max', 'tight-minmax', '?? !!', 'ternary', # dummy for $a ?? 42 !! 666 'ff', 'conditional-ff', '^ff', 'conditional-ff', 'ff^', 'conditional-ff', '^ff^', 'conditional-ff', 'fff', 'conditional-ff', '^fff', 'conditional-ff', 'fff^', 'conditional-ff', '^fff^', 'conditional-ff', '=~', 'item-assignment', # alt for = ~foo '$=', 'item-assignment', # dummy for $a = 42 '=>', 'item-assignment', '⇒', 'item-assignment', '⚛=', 'item-assignment', '⚛+=', 'item-assignment', '⚛-=', 'item-assignment', '⚛−=', 'item-assignment', '=', 'list-assignment', '@=', 'list-assignment', # dummy for @a = 1,2,3 ':=', 'list-assignment', ':', 'comma', # dummy for chop 42: ',', 'comma', 'X', 'list-infix', 'Z', 'list-infix', '...', 'list-infix', '…', 'list-infix', '...^', 'list-infix', '…^', 'list-infix', '^...', 'list-infix', '^…', 'list-infix', '^...^', 'list-infix', '^…^', 'list-infix', 'minmax', 'list-infix', 'and', 'loose-and', 'andthen', 'loose-andthen', 'notandthen', 'loose-andthen', 'or', 'loose-or', 'xor', 'loose-xor', 'orelse', 'loose-orelse', # dummy, for parsing Raku code only '==>', 'sequencer', '==>>', 'sequencer', '<==', 'sequencer', '<<==', 'sequencer', ); $SELF.produce(PROPERTIES, $operator // '') }); add-method(OperatorProperties, 'prefix', [OperatorProperties, '', 0, 0, str, '$operator', 0, 1], anon sub prefix ($SELF_CONT, $operator?) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 775 src/Raku/ast/operator-properties.rakumod my constant PROPERTIES := nqp::hash( '', 'default-prefix', '++', 'autoincrement', '--', 'autoincrement', '++⚛', 'autoincrement', '--⚛', 'autoincrement', '+', 'symbolic-unary', '~', 'symbolic-unary', '-', 'symbolic-unary', '?', 'symbolic-unary', '!', 'symbolic-unary', '|', 'symbolic-unary', '+^', 'symbolic-unary', '~^', 'symbolic-unary', '?^', 'symbolic-unary', '^', 'symbolic-unary', '⚛', 'symbolic-unary', '//', 'symbolic-unary', 'so', 'loose-unary', 'not', 'loose-unary', ); $SELF.produce(PROPERTIES, $operator // '') }); add-method(OperatorProperties, 'postfix', [OperatorProperties, '', 0, 0, str, '$operator', 0, 1], anon sub postfix ($SELF_CONT, $operator?) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 805 src/Raku/ast/operator-properties.rakumod my constant PROPERTIES := nqp::hash( '', 'default-postfix', ':', 'adverb', # dummy for %h:exists '()', 'methodcall', # term() '.', 'methodcall', '!', 'methodcall', '.^', 'methodcall', '.?', 'methodcall', '.&', 'methodcall', '.=', 'methodcall', 'i', 'methodcall', 'ⁿ', 'autoincrement', # power '+', 'autoincrement', # vulgar '++', 'autoincrement', '--', 'autoincrement', '⚛++', 'autoincrement', '⚛--', 'autoincrement', ); $SELF.produce(PROPERTIES, $operator // '') }); add-method(OperatorProperties, 'postcircumfix', [OperatorProperties, '', 0, 0, str, '$operator', 0, 1], anon sub postcircumfix ($SELF_CONT, $operator?) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 833 src/Raku/ast/operator-properties.rakumod my constant PROPERTIES := nqp::hash( '', 'default-postcircumfix', '< >', 'methodcall', '<< >>', 'methodcall', '« »', 'methodcall', '[ ]', 'methodcall', '[; ]', 'methodcall', '{ }', 'methodcall', '{; }', 'methodcall', ); $SELF.produce(PROPERTIES, $operator // '') }); add-method(OperatorProperties, 'circumfix', [OperatorProperties, '', 0, 0, str, '$operator', 0, 1], anon sub circumfix ($SELF_CONT, $operator?) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 850 src/Raku/ast/operator-properties.rakumod my constant PROPERTIES := nqp::hash( '', 'default-circumfix', '< >', 'methodcall', '<< >>', 'methodcall', '« »', 'methodcall', '[ ]', 'methodcall', '{ }', 'methodcall', ); $SELF.produce(PROPERTIES, $operator // '') }); compose(OperatorProperties); parent(RakuAST::CaptureSource, RakuAST::Node); compose(RakuAST::CaptureSource); parent(RakuAST::Expression, RakuAST::IMPL::ImmediateBlockUser); add-attribute(RakuAST::Expression, Mu, '$!thunks'); add-method(RakuAST::Expression, 'wrap-with-thunk', [RakuAST::Expression, '', 0, 0, RakuAST::ExpressionThunk, '$thunk', 0, 0], anon sub wrap-with-thunk ($SELF_CONT, $thunk!) { my $SELF := nqp::decont($SELF_CONT); $thunk := nqp::decont($thunk); #line 17 src/Raku/ast/expressions.rakumod $thunk.set-next(nqp::getattr($SELF, RakuAST::Expression, '$!thunks')) if nqp::getattr($SELF, RakuAST::Expression, '$!thunks'); nqp::bindattr($SELF, RakuAST::Expression, '$!thunks', $thunk); Nil }); add-method(RakuAST::Expression, 'dump-extras', [RakuAST::Expression, '', 0, 0, int, '$indent', 0, 0], anon sub dump-extras ($SELF_CONT, $indent!) { my $SELF := nqp::decont($SELF_CONT); $indent := nqp::decont($indent); #line 23 src/Raku/ast/expressions.rakumod my $prefix := nqp::x(' ', $indent); my @chunks; $SELF.visit-thunks(-> $thunk { @chunks.push("$prefix🧠 " ~ $thunk.thunk-kind ~ " " ~ $thunk.thunk-details ~ "\n"); $thunk.visit-children(-> $child { @chunks.push($child.dump($indent + 2)); }); }); nqp::join('', @chunks) }); add-method(RakuAST::Expression, 'IMPL-QAST-ADD-THUNK-DECL-CODE', [RakuAST::Expression, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$target', 0, 0], anon sub IMPL-QAST-ADD-THUNK-DECL-CODE ($SELF_CONT, $context!, $target!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $target := nqp::decont($target); #line 35 src/Raku/ast/expressions.rakumod if nqp::getattr($SELF, RakuAST::Expression, '$!thunks') { nqp::getattr($SELF, RakuAST::Expression, '$!thunks').IMPL-THUNK-CODE-QAST($context, $target, $SELF); } }); add-method(RakuAST::Expression, 'IMPL-TO-QAST', [RakuAST::Expression, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%opts', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!, *%opts) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %opts := nqp::decont(%opts); #line 41 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::Expression, '$!thunks') ?? nqp::getattr($SELF, RakuAST::Expression, '$!thunks').IMPL-THUNK-VALUE-QAST($context) !! $SELF.IMPL-EXPR-QAST($context, |%opts) }); add-method(RakuAST::Expression, 'IMPL-EXPR-QAST', [RakuAST::Expression, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 47 src/Raku/ast/expressions.rakumod nqp::die('Missing IMPL-EXPR-QAST method on ' ~ $SELF.HOW.name($SELF)) }); add-method(RakuAST::Expression, 'visit-thunks', [RakuAST::Expression, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-thunks ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 51 src/Raku/ast/expressions.rakumod my $cur-thunk := nqp::getattr($SELF, RakuAST::Expression, '$!thunks'); while $cur-thunk { $visitor($cur-thunk); $cur-thunk := $cur-thunk.next; } }); add-method(RakuAST::Expression, 'outer-most-thunk', [RakuAST::Expression, '', 0, 0], anon sub outer-most-thunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 59 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::Expression, '$!thunks') }); add-method(RakuAST::Expression, 'IMPL-CURRY', [RakuAST::Expression, '', 0, 0], anon sub IMPL-CURRY ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 64 src/Raku/ast/expressions.rakumod my $thunk := RakuAST::CurryThunk.new($SELF.DEPARSE); $SELF.wrap-with-thunk($thunk); $thunk }); add-method(RakuAST::Expression, 'IMPL-CURRIED', [RakuAST::Expression, '', 0, 0], anon sub IMPL-CURRIED ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 70 src/Raku/ast/expressions.rakumod my $cur-thunk := nqp::getattr($SELF, RakuAST::Expression, '$!thunks'); while $cur-thunk { return $cur-thunk if nqp::istype($cur-thunk, RakuAST::CurryThunk); $cur-thunk := $cur-thunk.next; } (Bool.WHO) }); add-method(RakuAST::Expression, 'IMPL-UNCURRY', [RakuAST::Expression, '', 0, 0], anon sub IMPL-UNCURRY ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 79 src/Raku/ast/expressions.rakumod my $prev-thunk; my $cur-thunk := nqp::getattr($SELF, RakuAST::Expression, '$!thunks'); while $cur-thunk { if nqp::istype($cur-thunk, RakuAST::CurryThunk) { my $params := $cur-thunk.IMPL-PARAMS; if $prev-thunk { $prev-thunk.set-next($cur-thunk.next); } else { nqp::bindattr($SELF, RakuAST::Expression, '$!thunks', $cur-thunk.next); } return $params; } $prev-thunk := $cur-thunk; $cur-thunk := $cur-thunk.next; } nqp::die("UNCURRY didn't find a CurryThunk"); }); add-method(RakuAST::Expression, 'IMPL-IMMEDIATELY-USES', [RakuAST::Expression, '', 0, 0, RakuAST::Code, '$node', 0, 0], anon sub IMPL-IMMEDIATELY-USES ($SELF_CONT, $node!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); #line 99 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::Expression, '$!thunks') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Expression, 'IMPL-ADJUST-QAST-FOR-LVALUE', [RakuAST::Expression, '', 0, 0, Mu, '$qast', 0, 0], anon sub IMPL-ADJUST-QAST-FOR-LVALUE ($SELF_CONT, $qast!) { my $SELF := nqp::decont($SELF_CONT); $qast := nqp::decont($qast); #line 103 src/Raku/ast/expressions.rakumod $qast }); compose(RakuAST::Expression); parent(RakuAST::OperatorProperties, Any); add-method(RakuAST::OperatorProperties, 'properties', [RakuAST::OperatorProperties, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 115 src/Raku/ast/expressions.rakumod my $properties; if nqp::can($SELF,'is-resolved') { # This feels very much like a hack, and should probably be # changed at some time. Perhaps when we get a "parse time" # stage? $SELF.resolve-with($*R) if !$SELF.is-resolved && $*R; if $SELF.is-resolved { my $resolution := $SELF.resolution; $properties := $resolution.compile-time-value.op_props if nqp::istype($resolution,RakuAST::CompileTimeValue); } } nqp::isconcrete($properties) ?? $properties !! $SELF.default-operator-properties }); compose(RakuAST::OperatorProperties); parent(RakuAST::Infixish, RakuAST::ImplicitLookups); add-method(RakuAST::Infixish, 'IMPL-LIST-INFIX-QAST', [RakuAST::Infixish, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operands', 0, 0], anon sub IMPL-LIST-INFIX-QAST ($SELF_CONT, $context!, $operands!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operands := nqp::decont($operands); #line 144 src/Raku/ast/expressions.rakumod nqp::die('Cannot compile ' ~ $SELF.HOW.name($SELF) ~ ' as a list infix'); }); add-method(RakuAST::Infixish, 'IMPL-INFIX-COMPILE', [RakuAST::Infixish, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '$left', 0, 0, RakuAST::Expression, '$right', 0, 0], anon sub IMPL-INFIX-COMPILE ($SELF_CONT, $context!, $left!, $right!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left := nqp::decont($left); $right := nqp::decont($right); #line 152 src/Raku/ast/expressions.rakumod $SELF.IMPL-INFIX-QAST: $context, $left.IMPL-TO-QAST($context), $right.IMPL-TO-QAST($context) }); add-method(RakuAST::Infixish, 'IMPL-THUNK-ARGUMENTS', [RakuAST::Infixish, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '@operands', 0, 0], anon sub IMPL-THUNK-ARGUMENTS ($SELF_CONT, $resolver!, $context!, *@operands) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); @operands := nqp::decont(@operands); #line 158 src/Raku/ast/expressions.rakumod }); add-method(RakuAST::Infixish, 'IMPL-CURRIES', [RakuAST::Infixish, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 165 src/Raku/ast/expressions.rakumod 0 }); compose(RakuAST::Infixish); parent(RakuAST::Infix, RakuAST::Infixish); parent(RakuAST::Infix, RakuAST::OperatorProperties); parent(RakuAST::Infix, RakuAST::Lookup); add-attribute(RakuAST::Infix, str, '$!operator'); add-method(RakuAST::Infix, 'new', [RakuAST::Infix, '', 0, 0, str, '$operator', 0, 0], anon sub new ($SELF_CONT, $operator!) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 177 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Infix, '$!operator', $operator); $obj }); add-method(RakuAST::Infix, 'default-operator-properties', [RakuAST::Infix, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 183 src/Raku/ast/expressions.rakumod OperatorProperties.infix(nqp::getattr_s($SELF, RakuAST::Infix, '$!operator')) }); add-method(RakuAST::Infix, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Infix, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 187 src/Raku/ast/expressions.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Match')), ]) }); add-method(RakuAST::Infix, 'resolve-with', [RakuAST::Infix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 193 src/Raku/ast/expressions.rakumod my $resolved := $resolver.resolve-infix(nqp::getattr_s($SELF, RakuAST::Infix, '$!operator')); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Infix, 'reducer-name', [RakuAST::Infix, '', 0, 0], anon sub reducer-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 201 src/Raku/ast/expressions.rakumod $SELF.properties.reducer-name }); add-method(RakuAST::Infix, 'IMPL-THUNK-ARGUMENT', [RakuAST::Infix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '$expression', 0, 0, str, '$type', 0, 0], anon sub IMPL-THUNK-ARGUMENT ($SELF_CONT, $resolver!, $context!, $expression!, $type!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $expression := nqp::decont($expression); $type := nqp::decont($type); #line 204 src/Raku/ast/expressions.rakumod if $type eq 'b' && !nqp::istype($expression, RakuAST::Code) { my $thunk := RakuAST::BlockThunk.new; $thunk.IMPL-CHECK($resolver, $context, (Bool.WHO)); $expression.wrap-with-thunk($thunk); } elsif $type eq 't' && !nqp::istype($expression, RakuAST::Code) { my $thunk := RakuAST::ExpressionThunk.new; $thunk.IMPL-CHECK($resolver, $context, (Bool.WHO)); $expression.wrap-with-thunk($thunk); } # TODO implement other thunk types }); add-method(RakuAST::Infix, 'IMPL-THUNK-ARGUMENTS', [RakuAST::Infix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '@operands', 0, 0], anon sub IMPL-THUNK-ARGUMENTS ($SELF_CONT, $resolver!, $context!, *@operands) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); @operands := nqp::decont(@operands); #line 219 src/Raku/ast/expressions.rakumod if ( nqp::getattr_s($SELF, RakuAST::Infix, '$!operator') eq 'xx' || nqp::getattr_s($SELF, RakuAST::Infix, '$!operator') eq 'andthen' || nqp::getattr_s($SELF, RakuAST::Infix, '$!operator') eq 'orelse' || nqp::getattr_s($SELF, RakuAST::Infix, '$!operator') eq 'notandthen' || nqp::getattr_s($SELF, RakuAST::Infix, '$!operator') eq 'with' || nqp::getattr_s($SELF, RakuAST::Infix, '$!operator') eq 'without' ) { my $thunky := $SELF.properties.thunky; my $i := 0; for @operands { my $type := nqp::substr($thunky, $i, $i + 1); if $type && $type ne '.' { $SELF.IMPL-THUNK-ARGUMENT($resolver, $context, $_, $type); } $i++ if $i < nqp::chars($thunky) - 1; } } }); add-method(RakuAST::Infix, 'IMPL-CURRIES', [RakuAST::Infix, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 237 src/Raku/ast/expressions.rakumod # Lookup of infix operators and whether either left / right side # will curry: # 0 = do not curry # 1 = curry Whatever only # 2 = curry WhateverCode only # 3 = curry both Whatever and WhateverCode (default) my constant CURRIED := nqp::hash( '...' , 0, '…' , 0, '...^' , 0, '…^' , 0, '^...' , 0, '^…' , 0, '^...^' , 0, '^…^' , 0, '=' , 0, ':=' , 0, '&&', , 0, '||', , 0, '~~' , 1, '∘' , 1, 'o' , 1, '..' , 2, '..^' , 2, '^..' , 2, '^..^' , 2, 'xx' , 2, ); CURRIED{nqp::getattr_s($SELF, RakuAST::Infix, '$!operator')} // 3 }); add-method(RakuAST::Infix, 'IMPL-INFIX-COMPILE', [RakuAST::Infix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '$left', 0, 0, RakuAST::Expression, '$right', 0, 0], anon sub IMPL-INFIX-COMPILE ($SELF_CONT, $context!, $left!, $right!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left := nqp::decont($left); $right := nqp::decont($right); #line 270 src/Raku/ast/expressions.rakumod # Hash value is negation flag my constant OP-SMARTMATCH := nqp::hash( '~~', 0, '!~~', 1 ); my str $op := nqp::getattr_s($SELF, RakuAST::Infix, '$!operator'); if $op eq ':=' { if $left.can-be-bound-to { $left.IMPL-BIND-QAST($context, $right.IMPL-TO-QAST($context)) } else { nqp::die('Cannot compile bind to ' ~ $left.HOW.name($left)); } } elsif nqp::existskey(OP-SMARTMATCH, $op) && (!nqp::istype($right, RakuAST::Var) || (nqp::istype($right, RakuAST::Var::Lexical) && $right.is-topic)) { $SELF.IMPL-SMARTMATCH-QAST($context, $left, $right, nqp::atkey(OP-SMARTMATCH, $op)); } else { $SELF.IMPL-INFIX-QAST: $context, $op eq '=' ?? $left.IMPL-ADJUST-QAST-FOR-LVALUE($left.IMPL-TO-QAST($context)) !! $left.IMPL-TO-QAST($context), $right.IMPL-TO-QAST($context) } }); add-method(RakuAST::Infix, 'IMPL-INFIX-QAST', [RakuAST::Infix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$left-qast', 0, 0, Mu, '$right-qast', 0, 0], anon sub IMPL-INFIX-QAST ($SELF_CONT, $context!, $left-qast!, $right-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left-qast := nqp::decont($left-qast); $right-qast := nqp::decont($right-qast); #line 301 src/Raku/ast/expressions.rakumod # Operators that map directly into a QAST op my constant QAST-OP := nqp::hash( '||', 'unless', 'or', 'unless', '&&', 'if', 'and', 'if', '^^', 'xor', 'xor', 'xor', '//', 'defor' ); (my str $op := QAST-OP{nqp::getattr_s($SELF, RakuAST::Infix, '$!operator')}) # Directly mapping ?? QAST::Op.new(:$op, $left-qast, $right-qast) # Otherwise, it's called by finding the lexical sub to call, and # compiling it as chaining if required. !! QAST::Op.new( :op($SELF.properties.chain ?? 'chain' !! 'call'), :name($SELF.resolution.lexical-name), $left-qast, $right-qast ) }); add-method(RakuAST::Infix, 'IMPL-SMARTMATCH-QAST', [RakuAST::Infix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '$left', 0, 0, RakuAST::Expression, '$right', 0, 0, int, '$negate', 0, 0], anon sub IMPL-SMARTMATCH-QAST ($SELF_CONT, $context!, $left!, $right!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left := nqp::decont($left); $right := nqp::decont($right); $negate := nqp::decont($negate); #line 329 src/Raku/ast/expressions.rakumod # Handle cases of s/// or m// separately. For a non-negating smartmatch this case could've been reduced to # plain topic localization except that we must ensure a False returned when there is no match. if nqp::istype($right, RakuAST::RegexThunk) && (!nqp::can($right, 'match-immediately') || $right.match-immediately) { my $match-type := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; my $result-local := QAST::Node.unique('!sm-result'); my $rhs := $right.IMPL-EXPR-QAST($context); return $SELF.IMPL-TEMPORARIZE-TOPIC( $left.IMPL-TO-QAST($context), $negate ?? QAST::Op.new( :op, :name, $rhs) !! QAST::Op.new( :op, $rhs, QAST::WVal.new( :value((Bool.WHO)) ))); } my $accepts-call; if $negate { $accepts-call := QAST::Op.new( :op, :name, QAST::Op.new( :op('callmethod'), :name('ACCEPTS'), $right.IMPL-TO-QAST($context), QAST::Var.new(:name<$_>, :scope))); } else { my $rhs-local := QAST::Node.unique('!sm-rhs'); $accepts-call := QAST::Op.new( :op('callmethod'), :name('ACCEPTS'), QAST::Var.new( :name($rhs-local), :scope ), QAST::Var.new(:name<$_>, :scope)); $accepts-call := QAST::Op.new( :op, QAST::Op.new( :op, QAST::Op.new( :op, QAST::Var.new( :name($rhs-local), :scope, :decl ), $right.IMPL-TO-QAST($context), ), QAST::WVal.new( :value(Regex) )), $accepts-call, QAST::Op.new( :op, :name, $accepts-call )); } $SELF.IMPL-TEMPORARIZE-TOPIC( $left.IMPL-TO-QAST($context), $accepts-call ) }); add-method(RakuAST::Infix, 'IMPL-LIST-INFIX-QAST', [RakuAST::Infix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operands', 0, 0], anon sub IMPL-LIST-INFIX-QAST ($SELF_CONT, $context!, $operands!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operands := nqp::decont($operands); #line 380 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; my $op := QAST::Op.new( :op('call'), :$name ); for $operands { $op.push($_); } $op }); add-method(RakuAST::Infix, 'IMPL-HOP-INFIX-QAST', [RakuAST::Infix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-INFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 389 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; QAST::Var.new( :scope('lexical'), :$name ) }); add-method(RakuAST::Infix, 'IMPL-CAN-INTERPRET', [RakuAST::Infix, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 394 src/Raku/ast/expressions.rakumod nqp::istype($SELF.resolution,RakuAST::CompileTimeValue) && !$SELF.properties.short-circuit && !$SELF.properties.chain }); add-method(RakuAST::Infix, 'IMPL-INTERPRET', [RakuAST::Infix, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0, List, '$operands', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!, $operands!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); $operands := nqp::decont($operands); #line 400 src/Raku/ast/expressions.rakumod my $op := $SELF.resolution.compile-time-value; my @operands; for $SELF.IMPL-UNWRAP-LIST($operands) { nqp::push(@operands, $_.IMPL-INTERPRET($ctx)); } $op(|@operands) }); add-method(RakuAST::Infix, 'dump-markers', [RakuAST::Infix, '', 0, 0], anon sub dump-markers ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 409 src/Raku/ast/expressions.rakumod '【' ~ nqp::getattr_s($SELF, RakuAST::Infix, '$!operator') ~ '】' }); #line 175 src/Raku/ast/expressions.rakumod add-method(RakuAST::Infix, 'operator', [], anon sub operator ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Infix, '$!operator') }); compose(RakuAST::Infix); parent(RakuAST::Feed, RakuAST::Infix); parent(RakuAST::Feed, RakuAST::BeginTime); add-method(RakuAST::Feed, 'new', [RakuAST::Feed, '', 0, 0, str, '$operator', 0, 0], anon sub new ($SELF_CONT, $operator!) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 418 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Infix, '$!operator', $operator); $obj }); add-method(RakuAST::Feed, 'PERFORM-BEGIN', [RakuAST::Feed, '', 0, 0, Resolver, '$resolver', 0, 0, Context, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 424 src/Raku/ast/expressions.rakumod my $operator := nqp::getattr_s($SELF, RakuAST::Infix, '$!operator'); if $operator eq "==>>" || $operator eq "<<==" { $SELF.add-sorry: $resolver.build-exception: 'X::Comp::NYI', :feature($operator ~ " feed operator"); } }); add-method(RakuAST::Feed, 'IMPL-LIST-INFIX-QAST', [RakuAST::Feed, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operands', 0, 0], anon sub IMPL-LIST-INFIX-QAST ($SELF_CONT, $context!, $operands!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operands := nqp::decont($operands); #line 433 src/Raku/ast/expressions.rakumod my @stages; my $operator := nqp::getattr_s($SELF, RakuAST::Infix, '$!operator'); if $operator eq "==>" { for $operands { @stages.push: $_; } } else { # "<<==" and "==>>" are NYI for $operands { @stages.unshift: $_; } } # Check what's in each stage and make a chain of blocks # that call each other. They'll return lazy things, which # will be passed in as var-arg parts to other things. The # first thing is just considered the result. my $result := @stages.shift; for @stages { my $stage := $_; # Wrap current result in a block, so it's thunked and can be # called at the right point. $result := QAST::Block.new( $result ); # Check what we have. XXX Real first step should be looking # for @(*) since if we find that it overrides all other things. # But that's todo...soon. :-) if nqp::istype($stage, QAST::Op) && $stage.op eq 'call' { # It's a call. Stick a call to the current supplier in # as its last argument. $stage.push(QAST::Op.new( :op('call'), $result )); } elsif nqp::istype($stage, QAST::Var) { # It's a variable. We need code that gets the results, pushes # them onto the variable and then returns them (since this # could well be a tap. my $tmp := QAST::Node.unique('feed_tmp'); $stage := QAST::Stmts.new( QAST::Op.new( :op('bind'), QAST::Var.new( :scope('local'), :name($tmp), :decl('var') ), QAST::Op.new( :op('callmethod'), :name('list'), QAST::Op.new( :op('call'), $result ) ), ), QAST::Op.new( :op('callmethod'), :name('append'), $stage, QAST::Var.new( :scope('local'), :name($tmp) ) ), QAST::Var.new( :scope('local'), :name($tmp) ) ); $stage := QAST::Op.new( :op('locallifetime'), $stage, $tmp ); } else { my str $error := "Only routine calls or variables that can '.append' may appear on either side of feed operators."; if nqp::istype($stage, QAST::Children) && nqp::istype($stage[0], QAST::Var) { if nqp::istype($stage, QAST::Op) && $stage.op eq 'ifnull' && nqp::eqat($stage[0].name, '&', 0) { $error := "A feed may not sink values into a code object. Did you mean a call like '" ~ nqp::substr($stage[0].name, 1) ~ "()' instead?"; } # Looks like an array, yet we wound up here (which we # wouldn't if it was an ordinary array. Assume it's # a shaped array definition throwing a spanner into the # works. elsif nqp::eqat($stage[0].name, '@', 0) { $error := "Cannot feed into shaped arrays, as one cannot '.append' to them."; } } $_.PRECURSOR.panic($error); } $result := $stage; } $result }); compose(RakuAST::Feed); parent(RakuAST::FlipFlop, RakuAST::Infix); parent(RakuAST::FlipFlop, RakuAST::ImplicitLookups); add-attribute(RakuAST::FlipFlop, Bool, '$!excludes-min'); add-attribute(RakuAST::FlipFlop, Bool, '$!excludes-max'); add-attribute(RakuAST::FlipFlop, Bool, '$!one-only'); add-attribute(RakuAST::FlipFlop, str, '$!state-id'); add-attribute(RakuAST::FlipFlop, RakuAST::VarDeclaration::Implicit::State, '$!state-var'); add-method(RakuAST::FlipFlop, 'new', [RakuAST::FlipFlop, '', 0, 0, str, '$operator', 0, 0], anon sub new ($SELF_CONT, $operator!) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 527 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Infix, '$!operator', $operator); nqp::bindattr($obj, RakuAST::FlipFlop, '$!excludes-min', nqp::eqat($operator,'^',0) ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::FlipFlop, '$!excludes-max', nqp::eqat($operator,'^',-1) ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::FlipFlop, '$!one-only', nqp::index($operator,'fff') == -1 ?? (Bool.WHO) !! (Bool.WHO)); my $state-id := QAST::Node.unique('FLIPFLOP_STATE__'); nqp::bindattr_s($obj, RakuAST::FlipFlop, '$!state-id', $state-id); my $state-var := RakuAST::VarDeclaration::Implicit::State.new( '!' ~ $state-id, :init-to-zero(1) ); nqp::bindattr($obj, RakuAST::FlipFlop, '$!state-var', $state-var); $obj }); add-method(RakuAST::FlipFlop, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::FlipFlop, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 547 src/Raku/ast/expressions.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Nil')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('True')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('False')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Int')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Whatever')) ]) }); add-method(RakuAST::FlipFlop, 'IMPL-CURRIES', [RakuAST::FlipFlop, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 557 src/Raku/ast/expressions.rakumod 0 }); add-method(RakuAST::FlipFlop, 'IMPL-INFIX-COMPILE', [RakuAST::FlipFlop, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '$left', 0, 0, RakuAST::Expression, '$right', 0, 0], anon sub IMPL-INFIX-COMPILE ($SELF_CONT, $context!, $left!, $right!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left := nqp::decont($left); $right := nqp::decont($right); #line 560 src/Raku/ast/expressions.rakumod $SELF.IMPL-INFIX-QAST: $context, $left.IMPL-TO-QAST($context), $right.IMPL-TO-QAST($context) }); add-method(RakuAST::FlipFlop, 'IMPL-INFIX-QAST', [RakuAST::FlipFlop, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$lhs', 0, 0, Mu, '$rhs', 0, 0], anon sub IMPL-INFIX-QAST ($SELF_CONT, $context!, $lhs!, $rhs!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $lhs := nqp::decont($lhs); $rhs := nqp::decont($rhs); #line 569 src/Raku/ast/expressions.rakumod # Need various constants. my $Int := $SELF.get-implicit-lookups.AT-POS(3).compile-time-value; my $Int-zero := $Int.new(0); my $Int-one := $Int.new(1); $context.ensure-sc($Int-zero); $context.ensure-sc($Int-one); my $zero := QAST::Want.new( QAST::WVal.new(:value($Int-zero), :returns($Int-zero.WHAT)), 'Ii', QAST::IVal.new(:value(0)) ); my $one := QAST::Want.new( QAST::WVal.new(:value($Int-one), :returns($Int-one.WHAT)), 'Ii', QAST::IVal.new(:value(1)) ); my $nil := QAST::WVal.new( :value($SELF.get-implicit-lookups.AT-POS(0).compile-time-value) ); my $true := QAST::WVal.new( :value($SELF.get-implicit-lookups.AT-POS(1).compile-time-value) ); my $false := QAST::WVal.new( :value($SELF.get-implicit-lookups.AT-POS(2).compile-time-value) ); my $topic := QAST::Var.new( :name<$_>, :scope ); # Twiddle to make special-case RHS * work. my $Whatever := $SELF.get-implicit-lookups.AT-POS(4).compile-time-value; if nqp::istype($rhs.returns, $Whatever) { $rhs := $false; } my $id := nqp::getattr_s($SELF, RakuAST::FlipFlop, '$!state-id'); my $state := '!' ~ $id; # Evaluate LHS and RHS. Note that in one-only mode, we use # the state bit to decide which side to evaluate. my $ff-code := QAST::Stmts.new( QAST::Op.new( :op('bind'), QAST::Var.new( :name($id ~ '_lhs'), :scope('local'), :decl('var') ), (nqp::getattr($SELF, RakuAST::FlipFlop, '$!one-only') ?? QAST::Op.new( :op('if'), QAST::Var.new( :name($state), :scope('lexical') ), $false, QAST::Op.new( :op('call'), :name('&infix:<~~>'), $topic, $lhs ) ) !! QAST::Op.new( :op('call'), :name('&infix:<~~>'), $topic, $lhs ) ), ), QAST::Op.new( :op('bind'), QAST::Var.new( :name($id ~ '_rhs'), :scope('local'), :decl('var') ), (nqp::getattr($SELF, RakuAST::FlipFlop, '$!one-only') ?? QAST::Op.new( :op('if'), QAST::Var.new( :name($state), :scope('lexical') ), QAST::Op.new( :op('call'), :name('&infix:<~~>'), $topic, $rhs ), $false ) !! QAST::Op.new( :op('call'), :name('&infix:<~~>'), $topic, $rhs ) ) ) ); # Now decide what to do based on current state and current # results. $ff-code.push(QAST::Op.new( :op('if'), QAST::Var.new( :name($state), :scope('lexical') ), # State is currently true. Check RHS. If it's false, then we # increment the sequence count. If it's true, then we reset, # the state to zero and and what we return depends on $excludes-max. QAST::Op.new( :op('if'), QAST::Var.new( :name($id ~ '_rhs'), :scope('local') ), (nqp::getattr($SELF, RakuAST::FlipFlop, '$!excludes-max') ?? QAST::Stmts.new( QAST::Op.new( :op('p6store'), QAST::Var.new( :name($state), :scope('lexical') ), $zero ), $nil ) !! QAST::Stmts.new( QAST::Op.new( :op('bind'), QAST::Var.new( :name($id ~ '_orig'), :scope('local'), :decl('var') ), QAST::Op.new( :op('call'), :name('&prefix:<++>'), QAST::Var.new( :name($state), :scope('lexical') ) ) ), QAST::Op.new( :op('p6store'), QAST::Var.new( :name($state), :scope('lexical') ), $zero ), QAST::Op.new( :op('decont'), QAST::Var.new( :name($id ~ '_orig'), :scope('local') ) ) )), QAST::Stmts.new( QAST::Op.new( :op('call'), :name('&prefix:<++>'), QAST::Var.new( :name($state), :scope('lexical') ) ) ) ), # State is currently false. Check LHS. If it's false, then we # stay in a false state. If it's true, then we flip the bit, # but only if the RHS is not also true. We return a result # based on $excludes-min. QAST::Op.new( :op('if'), QAST::Var.new( :name($id ~ '_lhs'), :scope('local') ), QAST::Op.new( :op('if'), QAST::Var.new( :name($id ~ '_rhs'), :scope('local') ), nqp::getattr($SELF, RakuAST::FlipFlop, '$!excludes-min') || nqp::getattr($SELF, RakuAST::FlipFlop, '$!excludes-max') ?? $nil !! $one, QAST::Stmts.new( QAST::Op.new( :op('p6store'), QAST::Var.new( :name($state), :scope('lexical') ), $one ), nqp::getattr($SELF, RakuAST::FlipFlop, '$!excludes-min') ?? $nil !! $one ) ), $nil ) )); QAST::Op.new( :op('locallifetime'), $ff-code, $id ~ '_lhs', $id ~ '_rhs' ); }); add-method(RakuAST::FlipFlop, 'visit-children', [RakuAST::FlipFlop, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 698 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::FlipFlop, '$!state-var')) }); #line 524 src/Raku/ast/expressions.rakumod add-method(RakuAST::FlipFlop, 'state-id', [], anon sub state-id ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::FlipFlop, '$!state-id') }); #line 522 src/Raku/ast/expressions.rakumod add-method(RakuAST::FlipFlop, 'one-only', [], anon sub one-only ($self) { nqp::getattr(nqp::decont($self), RakuAST::FlipFlop, '$!one-only') }); #line 520 src/Raku/ast/expressions.rakumod add-method(RakuAST::FlipFlop, 'excludes-min', [], anon sub excludes-min ($self) { nqp::getattr(nqp::decont($self), RakuAST::FlipFlop, '$!excludes-min') }); #line 521 src/Raku/ast/expressions.rakumod add-method(RakuAST::FlipFlop, 'excludes-max', [], anon sub excludes-max ($self) { nqp::getattr(nqp::decont($self), RakuAST::FlipFlop, '$!excludes-max') }); compose(RakuAST::FlipFlop); parent(RakuAST::Assignment, RakuAST::Infix); add-attribute(RakuAST::Assignment, int, '$!item'); add-attribute(RakuAST::Assignment, OperatorProperties, '$!properties'); add-method(RakuAST::Assignment, 'new', [RakuAST::Assignment, '', 0, 0, Bool, '$item', 1, 1], anon sub new ($SELF_CONT, :$item?) { my $SELF := nqp::decont($SELF_CONT); $item := nqp::decont($item); #line 714 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj,RakuAST::Infix,'$!operator','='); nqp::bindattr_i($obj,RakuAST::Assignment,'$!item',$item ?? 1 !! 0); nqp::bindattr($obj,RakuAST::Assignment,'$!properties', OperatorProperties.infix($item ?? '$=' !! '@=')); $obj }); add-method(RakuAST::Assignment, 'item', [RakuAST::Assignment, '', 0, 0], anon sub item ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 722 src/Raku/ast/expressions.rakumod nqp::getattr_i($SELF, RakuAST::Assignment, '$!item') ?? (Bool.WHO) !! (Bool.WHO) }); #line 712 src/Raku/ast/expressions.rakumod add-method(RakuAST::Assignment, 'properties', [], anon sub properties ($self) { nqp::getattr(nqp::decont($self), RakuAST::Assignment, '$!properties') }); compose(RakuAST::Assignment); parent(RakuAST::BracketedInfix, RakuAST::Infixish); add-attribute(RakuAST::BracketedInfix, RakuAST::Infixish, '$!infix'); add-method(RakuAST::BracketedInfix, 'new', [RakuAST::BracketedInfix, '', 0, 0, RakuAST::Infixish, '$infix', 0, 0], anon sub new ($SELF_CONT, $infix!) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); #line 731 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::BracketedInfix, '$!infix', $infix); $obj }); add-method(RakuAST::BracketedInfix, 'properties', [RakuAST::BracketedInfix, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 737 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::BracketedInfix, '$!infix').properties }); add-method(RakuAST::BracketedInfix, 'visit-children', [RakuAST::BracketedInfix, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 739 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::BracketedInfix, '$!infix')); }); add-method(RakuAST::BracketedInfix, 'reducer-name', [RakuAST::BracketedInfix, '', 0, 0], anon sub reducer-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 743 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::BracketedInfix, '$!infix').reducer-name }); add-method(RakuAST::BracketedInfix, 'IMPL-INFIX-COMPILE', [RakuAST::BracketedInfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '$left', 0, 0, RakuAST::Expression, '$right', 0, 0], anon sub IMPL-INFIX-COMPILE ($SELF_CONT, $context!, $left!, $right!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left := nqp::decont($left); $right := nqp::decont($right); #line 746 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::BracketedInfix, '$!infix').IMPL-INFIX-COMPILE($context, $left, $right) }); add-method(RakuAST::BracketedInfix, 'IMPL-INFIX-QAST', [RakuAST::BracketedInfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$left-qast', 0, 0, Mu, '$right-qast', 0, 0], anon sub IMPL-INFIX-QAST ($SELF_CONT, $context!, $left-qast!, $right-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left-qast := nqp::decont($left-qast); $right-qast := nqp::decont($right-qast); #line 750 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::BracketedInfix, '$!infix').IMPL-INFIX-QAST($context, $left-qast, $right-qast) }); add-method(RakuAST::BracketedInfix, 'IMPL-HOP-INFIX-QAST', [RakuAST::BracketedInfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-INFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 754 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::BracketedInfix, '$!infix').IMPL-HOP-INFIX-QAST($context) }); #line 729 src/Raku/ast/expressions.rakumod add-method(RakuAST::BracketedInfix, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::BracketedInfix, '$!infix') }); compose(RakuAST::BracketedInfix); parent(RakuAST::FunctionInfix, RakuAST::Infixish); add-attribute(RakuAST::FunctionInfix, RakuAST::Expression, '$!function'); add-method(RakuAST::FunctionInfix, 'new', [RakuAST::FunctionInfix, '', 0, 0, RakuAST::Expression, '$function', 0, 0], anon sub new ($SELF_CONT, $function!) { my $SELF := nqp::decont($SELF_CONT); $function := nqp::decont($function); #line 765 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::FunctionInfix, '$!function', $function); $obj }); add-method(RakuAST::FunctionInfix, 'visit-children', [RakuAST::FunctionInfix, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 771 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::FunctionInfix, '$!function')); }); add-method(RakuAST::FunctionInfix, 'properties', [RakuAST::FunctionInfix, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 775 src/Raku/ast/expressions.rakumod # Should check if operator properties can be derived from $!function, # and should default to: OperatorProperties.infix('+') }); add-method(RakuAST::FunctionInfix, 'reducer-name', [RakuAST::FunctionInfix, '', 0, 0], anon sub reducer-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 781 src/Raku/ast/expressions.rakumod '&METAOP_REDUCE_LEFT' }); add-method(RakuAST::FunctionInfix, 'IMPL-INFIX-QAST', [RakuAST::FunctionInfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$left-qast', 0, 0, Mu, '$right-qast', 0, 0], anon sub IMPL-INFIX-QAST ($SELF_CONT, $context!, $left-qast!, $right-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left-qast := nqp::decont($left-qast); $right-qast := nqp::decont($right-qast); #line 783 src/Raku/ast/expressions.rakumod QAST::Op.new: :op('call'), nqp::getattr($SELF, RakuAST::FunctionInfix, '$!function').IMPL-TO-QAST($context), $left-qast, $right-qast }); add-method(RakuAST::FunctionInfix, 'IMPL-HOP-INFIX-QAST', [RakuAST::FunctionInfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-INFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 790 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::FunctionInfix, '$!function').IMPL-TO-QAST($context) }); #line 763 src/Raku/ast/expressions.rakumod add-method(RakuAST::FunctionInfix, 'function', [], anon sub function ($self) { nqp::getattr(nqp::decont($self), RakuAST::FunctionInfix, '$!function') }); compose(RakuAST::FunctionInfix); parent(RakuAST::MetaInfix, RakuAST::Infixish); parent(RakuAST::MetaInfix, RakuAST::CheckTime); add-method(RakuAST::MetaInfix, 'IMPL-HOP-INFIX', [RakuAST::MetaInfix, '', 0, 0], anon sub IMPL-HOP-INFIX ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 803 src/Raku/ast/expressions.rakumod $SELF.get-implicit-lookups().AT-POS(0).resolution.compile-time-value()( $SELF.infix.resolution.compile-time-value ) }); add-method(RakuAST::MetaInfix, 'PERFORM-CHECK', [RakuAST::MetaInfix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 812 src/Raku/ast/expressions.rakumod $SELF.properties.fiddly ?? $SELF.add-sorry( $resolver.build-exception("X::Syntax::CannotMeta", meta => "negate", operator => $SELF.infix.operator, dba => $SELF.properties.dba, reason => "too fiddly" ) ) !! (Bool.WHO) }); add-method(RakuAST::MetaInfix, 'IMPL-CURRIES', [RakuAST::MetaInfix, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 825 src/Raku/ast/expressions.rakumod $SELF.infix.IMPL-CURRIES }); compose(RakuAST::MetaInfix); parent(RakuAST::MetaInfix::Assign, RakuAST::MetaInfix); add-attribute(RakuAST::MetaInfix::Assign, RakuAST::Infixish, '$!infix'); add-method(RakuAST::MetaInfix::Assign, 'new', [RakuAST::MetaInfix::Assign, '', 0, 0, RakuAST::Infixish, '$infix', 0, 0], anon sub new ($SELF_CONT, $infix!) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); #line 834 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::MetaInfix::Assign, '$!infix', $infix); $obj }); add-method(RakuAST::MetaInfix::Assign, 'visit-children', [RakuAST::MetaInfix::Assign, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 840 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::MetaInfix::Assign, '$!infix')); }); add-method(RakuAST::MetaInfix::Assign, 'PERFORM-CHECK', [RakuAST::MetaInfix::Assign, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 847 src/Raku/ast/expressions.rakumod my $properties := $SELF.properties; $properties.fiddly || $properties.diffy ?? $SELF.add-sorry( $resolver.build-exception("X::Syntax::CannotMeta", meta => "assign", operator => $SELF.infixx.operator, reason => "too fiddly or diffy" ) ) !! (Bool.WHO) }); add-method(RakuAST::MetaInfix::Assign, 'properties', [RakuAST::MetaInfix::Assign, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 860 src/Raku/ast/expressions.rakumod OperatorProperties.infix('$=') }); add-method(RakuAST::MetaInfix::Assign, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::MetaInfix::Assign, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 862 src/Raku/ast/expressions.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('&METAOP_ASSIGN')), ]) }); add-method(RakuAST::MetaInfix::Assign, 'IMPL-CURRIES', [RakuAST::MetaInfix::Assign, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 868 src/Raku/ast/expressions.rakumod 0 }); add-method(RakuAST::MetaInfix::Assign, 'IMPL-INFIX-QAST', [RakuAST::MetaInfix::Assign, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$left-qast', 0, 0, Mu, '$right-qast', 0, 0], anon sub IMPL-INFIX-QAST ($SELF_CONT, $context!, $left-qast!, $right-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left-qast := nqp::decont($left-qast); $right-qast := nqp::decont($right-qast); #line 870 src/Raku/ast/expressions.rakumod if nqp::istype(nqp::getattr($SELF, RakuAST::MetaInfix::Assign, '$!infix'), RakuAST::Infix) && nqp::getattr($SELF, RakuAST::MetaInfix::Assign, '$!infix').properties.short-circuit { # TODO case-analyzed assignments my $temp := QAST::Node.unique('meta_assign'); my $bind-lhs := QAST::Op.new( :op, QAST::Var.new(:decl('var'), :scope('local'), :name($temp)), $left-qast ); # Compile the short-circuit ones "inside out", so we can avoid the # assignment. QAST::Stmt.new( $bind-lhs, nqp::getattr($SELF, RakuAST::MetaInfix::Assign, '$!infix').IMPL-INFIX-QAST( $context, QAST::Var.new( :scope('local'), :name($temp) ), QAST::Op.new( :op('assign'), QAST::Var.new( :scope('local'), :name($temp) ), $right-qast ) ) ) } else { QAST::Op.new(:op, $SELF.IMPL-HOP-INFIX-QAST($context) , $left-qast, $right-qast ) } }); add-method(RakuAST::MetaInfix::Assign, 'IMPL-HOP-INFIX-QAST', [RakuAST::MetaInfix::Assign, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-INFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 901 src/Raku/ast/expressions.rakumod QAST::Op.new: :op('callstatic'), :name('&METAOP_ASSIGN'), nqp::getattr($SELF, RakuAST::MetaInfix::Assign, '$!infix').IMPL-HOP-INFIX-QAST($context) }); #line 832 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaInfix::Assign, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaInfix::Assign, '$!infix') }); compose(RakuAST::MetaInfix::Assign); parent(RakuAST::MetaInfix::Negate, RakuAST::MetaInfix); add-attribute(RakuAST::MetaInfix::Negate, RakuAST::Infixish, '$!infix'); add-method(RakuAST::MetaInfix::Negate, 'new', [RakuAST::MetaInfix::Negate, '', 0, 0, RakuAST::Infixish, '$infix', 0, 0], anon sub new ($SELF_CONT, $infix!) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); #line 914 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::MetaInfix::Negate, '$!infix', $infix); $obj }); add-method(RakuAST::MetaInfix::Negate, 'visit-children', [RakuAST::MetaInfix::Negate, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 920 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::MetaInfix::Negate, '$!infix')); }); add-method(RakuAST::MetaInfix::Negate, 'PERFORM-CHECK', [RakuAST::MetaInfix::Negate, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 927 src/Raku/ast/expressions.rakumod $SELF.properties.iffy || $SELF.add-sorry: $resolver.build-exception: "X::Syntax::CannotMeta", meta => "negate", operator => $SELF.infix.operator, dba => $SELF.properties.dba, reason => "not iffy enough" }); add-method(RakuAST::MetaInfix::Negate, 'properties', [RakuAST::MetaInfix::Negate, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 937 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::MetaInfix::Negate, '$!infix').properties }); add-method(RakuAST::MetaInfix::Negate, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::MetaInfix::Negate, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 939 src/Raku/ast/expressions.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('&METAOP_NEGATE')), ]) }); add-method(RakuAST::MetaInfix::Negate, 'IMPL-INFIX-QAST', [RakuAST::MetaInfix::Negate, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$left-qast', 0, 0, Mu, '$right-qast', 0, 0], anon sub IMPL-INFIX-QAST ($SELF_CONT, $context!, $left-qast!, $right-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left-qast := nqp::decont($left-qast); $right-qast := nqp::decont($right-qast); #line 945 src/Raku/ast/expressions.rakumod QAST::Op.new(:op, QAST::Op.new(:op, nqp::getattr($SELF, RakuAST::MetaInfix::Negate, '$!infix').IMPL-INFIX-QAST($context, $left-qast, $right-qast) ) ) }); add-method(RakuAST::MetaInfix::Negate, 'IMPL-HOP-INFIX-QAST', [RakuAST::MetaInfix::Negate, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-INFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 953 src/Raku/ast/expressions.rakumod QAST::Op.new(:op, :name<&METAOP_NEGATE>, nqp::getattr($SELF, RakuAST::MetaInfix::Negate, '$!infix').IMPL-HOP-INFIX-QAST($context) ) }); #line 912 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaInfix::Negate, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaInfix::Negate, '$!infix') }); compose(RakuAST::MetaInfix::Negate); parent(RakuAST::MetaInfix::Reverse, RakuAST::MetaInfix); add-attribute(RakuAST::MetaInfix::Reverse, RakuAST::Infixish, '$!infix'); add-attribute(RakuAST::MetaInfix::Reverse, OperatorProperties, '$!properties'); add-method(RakuAST::MetaInfix::Reverse, 'new', [RakuAST::MetaInfix::Reverse, '', 0, 0, RakuAST::Infixish, '$infix', 0, 0], anon sub new ($SELF_CONT, $infix!) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); #line 967 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::MetaInfix::Reverse, '$!infix', $infix); nqp::bindattr($obj, RakuAST::MetaInfix::Reverse, '$!properties', $infix.properties.associative-reversed); $obj }); add-method(RakuAST::MetaInfix::Reverse, 'visit-children', [RakuAST::MetaInfix::Reverse, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 975 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::MetaInfix::Reverse, '$!infix')); }); add-method(RakuAST::MetaInfix::Reverse, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::MetaInfix::Reverse, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 979 src/Raku/ast/expressions.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('&METAOP_REVERSE')), ]) }); add-method(RakuAST::MetaInfix::Reverse, 'IMPL-INFIX-QAST', [RakuAST::MetaInfix::Reverse, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$left-qast', 0, 0, Mu, '$right-qast', 0, 0], anon sub IMPL-INFIX-QAST ($SELF_CONT, $context!, $left-qast!, $right-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left-qast := nqp::decont($left-qast); $right-qast := nqp::decont($right-qast); #line 985 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::MetaInfix::Reverse, '$!infix').IMPL-INFIX-QAST($context, $right-qast, $left-qast) }); add-method(RakuAST::MetaInfix::Reverse, 'IMPL-HOP-INFIX-QAST', [RakuAST::MetaInfix::Reverse, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-INFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 989 src/Raku/ast/expressions.rakumod QAST::Op.new: :op('callstatic'), :name('&METAOP_REVERSE'), nqp::getattr($SELF, RakuAST::MetaInfix::Reverse, '$!infix').IMPL-HOP-INFIX-QAST($context) }); #line 965 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaInfix::Reverse, 'properties', [], anon sub properties ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaInfix::Reverse, '$!properties') }); #line 964 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaInfix::Reverse, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaInfix::Reverse, '$!infix') }); compose(RakuAST::MetaInfix::Reverse); parent(RakuAST::MetaInfix::Cross, RakuAST::MetaInfix); add-attribute(RakuAST::MetaInfix::Cross, RakuAST::Infixish, '$!infix'); add-method(RakuAST::MetaInfix::Cross, 'new', [RakuAST::MetaInfix::Cross, '', 0, 0, RakuAST::Infixish, '$infix', 0, 0], anon sub new ($SELF_CONT, $infix!) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); #line 1002 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::MetaInfix::Cross, '$!infix', $infix); $obj }); add-method(RakuAST::MetaInfix::Cross, 'visit-children', [RakuAST::MetaInfix::Cross, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1008 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::MetaInfix::Cross, '$!infix')); }); add-method(RakuAST::MetaInfix::Cross, 'properties', [RakuAST::MetaInfix::Cross, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1012 src/Raku/ast/expressions.rakumod OperatorProperties.infix('X') }); add-method(RakuAST::MetaInfix::Cross, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::MetaInfix::Cross, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1014 src/Raku/ast/expressions.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('&METAOP_CROSS')), ]) }); add-method(RakuAST::MetaInfix::Cross, 'IMPL-LIST-INFIX-QAST', [RakuAST::MetaInfix::Cross, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operands', 0, 0], anon sub IMPL-LIST-INFIX-QAST ($SELF_CONT, $context!, $operands!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operands := nqp::decont($operands); #line 1020 src/Raku/ast/expressions.rakumod my $op := QAST::Op.new( :op('call'), $SELF.IMPL-HOP-INFIX-QAST($context) ); for $operands { $op.push($_); } $op }); add-method(RakuAST::MetaInfix::Cross, 'IMPL-HOP-INFIX-QAST', [RakuAST::MetaInfix::Cross, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-INFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1028 src/Raku/ast/expressions.rakumod QAST::Op.new: :op('callstatic'), :name('&METAOP_CROSS'), nqp::getattr($SELF, RakuAST::MetaInfix::Cross, '$!infix').IMPL-HOP-INFIX-QAST($context), QAST::Var.new( :name(nqp::getattr($SELF, RakuAST::MetaInfix::Cross, '$!infix').reducer-name), :scope('lexical') ) }); #line 1000 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaInfix::Cross, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaInfix::Cross, '$!infix') }); compose(RakuAST::MetaInfix::Cross); parent(RakuAST::MetaInfix::Zip, RakuAST::MetaInfix); add-attribute(RakuAST::MetaInfix::Zip, RakuAST::Infixish, '$!infix'); add-method(RakuAST::MetaInfix::Zip, 'new', [RakuAST::MetaInfix::Zip, '', 0, 0, RakuAST::Infixish, '$infix', 0, 0], anon sub new ($SELF_CONT, $infix!) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); #line 1042 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::MetaInfix::Zip, '$!infix', $infix); $obj }); add-method(RakuAST::MetaInfix::Zip, 'visit-children', [RakuAST::MetaInfix::Zip, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1048 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::MetaInfix::Zip, '$!infix')); }); add-method(RakuAST::MetaInfix::Zip, 'properties', [RakuAST::MetaInfix::Zip, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1052 src/Raku/ast/expressions.rakumod OperatorProperties.infix('Z') }); add-method(RakuAST::MetaInfix::Zip, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::MetaInfix::Zip, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1054 src/Raku/ast/expressions.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('&METAOP_ZIP')), ]) }); add-method(RakuAST::MetaInfix::Zip, 'IMPL-LIST-INFIX-QAST', [RakuAST::MetaInfix::Zip, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operands', 0, 0], anon sub IMPL-LIST-INFIX-QAST ($SELF_CONT, $context!, $operands!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operands := nqp::decont($operands); #line 1060 src/Raku/ast/expressions.rakumod my $op := QAST::Op.new( :op('call'), $SELF.IMPL-HOP-INFIX-QAST($context) ); for $operands { $op.push($_); } $op }); add-method(RakuAST::MetaInfix::Zip, 'IMPL-HOP-INFIX-QAST', [RakuAST::MetaInfix::Zip, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-INFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1068 src/Raku/ast/expressions.rakumod QAST::Op.new: :op('callstatic'), :name('&METAOP_ZIP'), nqp::getattr($SELF, RakuAST::MetaInfix::Zip, '$!infix').IMPL-HOP-INFIX-QAST($context), QAST::Var.new( :name(nqp::getattr($SELF, RakuAST::MetaInfix::Zip, '$!infix').reducer-name), :scope('lexical') ) }); #line 1040 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaInfix::Zip, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaInfix::Zip, '$!infix') }); compose(RakuAST::MetaInfix::Zip); parent(RakuAST::MetaInfix::Hyper, RakuAST::MetaInfix); add-attribute(RakuAST::MetaInfix::Hyper, RakuAST::Infixish, '$!infix'); add-attribute(RakuAST::MetaInfix::Hyper, Bool, '$!dwim-left'); add-attribute(RakuAST::MetaInfix::Hyper, Bool, '$!dwim-right'); add-method(RakuAST::MetaInfix::Hyper, 'new', [RakuAST::MetaInfix::Hyper, '', 0, 0, RakuAST::Infixish, '$infix', 1, 0, Bool, '$dwim-left', 1, 1, Bool, '$dwim-right', 1, 1], anon sub new ($SELF_CONT, :$infix!, :$dwim-left?, :$dwim-right?) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); $dwim-left := nqp::decont($dwim-left); $dwim-right := nqp::decont($dwim-right); #line 1084 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::MetaInfix::Hyper, '$!infix', $infix); nqp::bindattr($obj, RakuAST::MetaInfix::Hyper, '$!dwim-left', $dwim-left ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::MetaInfix::Hyper, '$!dwim-right', $dwim-right ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::MetaInfix::Hyper, 'visit-children', [RakuAST::MetaInfix::Hyper, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1094 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::MetaInfix::Hyper, '$!infix')); }); add-method(RakuAST::MetaInfix::Hyper, 'properties', [RakuAST::MetaInfix::Hyper, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1098 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::MetaInfix::Hyper, '$!infix').properties }); add-method(RakuAST::MetaInfix::Hyper, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::MetaInfix::Hyper, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1100 src/Raku/ast/expressions.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('&METAOP_HYPER')), ]) }); add-method(RakuAST::MetaInfix::Hyper, 'IMPL-INFIX-QAST', [RakuAST::MetaInfix::Hyper, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$left-qast', 0, 0, Mu, '$right-qast', 0, 0], anon sub IMPL-INFIX-QAST ($SELF_CONT, $context!, $left-qast!, $right-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $left-qast := nqp::decont($left-qast); $right-qast := nqp::decont($right-qast); #line 1106 src/Raku/ast/expressions.rakumod QAST::Op.new: :op('call'), $SELF.IMPL-HOP-INFIX-QAST($context), $left-qast, $right-qast }); add-method(RakuAST::MetaInfix::Hyper, 'IMPL-HOP-INFIX-QAST', [RakuAST::MetaInfix::Hyper, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-INFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1114 src/Raku/ast/expressions.rakumod my $call := QAST::Op.new: :op('callstatic'), :name('&METAOP_HYPER'), nqp::getattr($SELF, RakuAST::MetaInfix::Hyper, '$!infix').IMPL-HOP-INFIX-QAST($context); if nqp::getattr($SELF, RakuAST::MetaInfix::Hyper, '$!dwim-left') { $call.push: QAST::WVal.new: :value((Bool.WHO)), :named('dwim-left'); } if nqp::getattr($SELF, RakuAST::MetaInfix::Hyper, '$!dwim-right') { $call.push: QAST::WVal.new: :value((Bool.WHO)), :named('dwim-right'); } $call }); add-method(RakuAST::MetaInfix::Hyper, 'IMPL-HOP-INFIX', [RakuAST::MetaInfix::Hyper, '', 0, 0], anon sub IMPL-HOP-INFIX ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1127 src/Raku/ast/expressions.rakumod $SELF.get-implicit-lookups().AT-POS(0).resolution.compile-time-value()( $SELF.infix.resolution.compile-time-value, :dwim-left(nqp::getattr($SELF, RakuAST::MetaInfix::Hyper, '$!dwim-left')), :dwim-right(nqp::getattr($SELF, RakuAST::MetaInfix::Hyper, '$!dwim-right')) ) }); #line 1080 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaInfix::Hyper, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaInfix::Hyper, '$!infix') }); #line 1082 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaInfix::Hyper, 'dwim-right', [], anon sub dwim-right ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaInfix::Hyper, '$!dwim-right') }); #line 1081 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaInfix::Hyper, 'dwim-left', [], anon sub dwim-left ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaInfix::Hyper, '$!dwim-left') }); compose(RakuAST::MetaInfix::Hyper); parent(RakuAST::WhateverApplicable, Any); add-method(RakuAST::WhateverApplicable, 'IMPL-SHOULD-CURRY-DIRECTLY', [RakuAST::WhateverApplicable, '', 0, 0], anon sub IMPL-SHOULD-CURRY-DIRECTLY ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1148 src/Raku/ast/expressions.rakumod return (Bool.WHO) unless nqp::bitand_i($SELF.operator.IMPL-CURRIES, 1); return (Bool.WHO) unless $SELF.IMPL-CUSTOM-SHOULD-CURRY-CONDITIONS; for $SELF.IMPL-UNWRAP-LIST($SELF.operands) { return (Bool.WHO) if nqp::istype($_, RakuAST::Term::Whatever) } (Bool.WHO) }); add-method(RakuAST::WhateverApplicable, 'IMPL-OPERANDS-SHOULD-CURRY-DIRECTLY', [RakuAST::WhateverApplicable, '', 0, 0], anon sub IMPL-OPERANDS-SHOULD-CURRY-DIRECTLY ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1157 src/Raku/ast/expressions.rakumod my $should-so := (Bool.WHO); for $SELF.IMPL-UNWRAP-LIST($SELF.operands) { $should-so := $should-so || (nqp::istype($_, RakuAST::WhateverApplicable) && $_.IMPL-SHOULD-CURRY-DIRECTLY) || (nqp::istype($_, RakuAST::Circumfix::Parentheses) && $_.IMPL-CONTAINS-SINGULAR-CURRYABLE-EXPRESSION) } $should-so }); add-method(RakuAST::WhateverApplicable, 'IMPL-CUSTOM-SHOULD-CURRY-CONDITIONS', [RakuAST::WhateverApplicable, '', 0, 0], anon sub IMPL-CUSTOM-SHOULD-CURRY-CONDITIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1167 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::WhateverApplicable, 'IMPL-ALL-CHILDREN-THAT-SHOULD-CURRY', [RakuAST::WhateverApplicable, '', 0, 0], anon sub IMPL-ALL-CHILDREN-THAT-SHOULD-CURRY ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1170 src/Raku/ast/expressions.rakumod return [] unless nqp::bitand_i($SELF.operator.IMPL-CURRIES, 2); # Calculate self-based gaurds for $stopper only once my $self-is-xx := nqp::istype($SELF, RakuAST::ApplyInfix) && (my $operator := $SELF.operator) && nqp::istype($operator, RakuAST::Infix) && $operator.operator eq 'xx'; my $condition := -> $n { $n.IMPL-SHOULD-CURRY-DIRECTLY || $n.IMPL-OPERANDS-SHOULD-CURRY-DIRECTLY }; my $stopper := -> $n { nqp::istype($n, RakuAST::Block) || nqp::istype($n, RakuAST::Postcircumfix::ArrayIndex) || nqp::istype($n, RakuAST::Call) || nqp::istype($n, RakuAST::VarDeclaration::Simple) || (nqp::istype($n, RakuAST::WhateverApplicable) && !nqp::bitand_i($n.operator.IMPL-CURRIES, 2)) || ($self-is-xx && nqp::istype($n, RakuAST::ApplyInfix) && $n.IMPL-SHOULD-CURRY-DIRECTLY) } $SELF.IMPL-UNWRAP-LIST($SELF.find-nodes-exclusive(RakuAST::WhateverApplicable, :$condition, :$stopper)) }); add-method(RakuAST::WhateverApplicable, 'IMPL-SHOULD-CURRY-ACROSS-ALL-CHILDREN', [RakuAST::WhateverApplicable, '', 0, 0], anon sub IMPL-SHOULD-CURRY-ACROSS-ALL-CHILDREN ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1190 src/Raku/ast/expressions.rakumod $SELF.IMPL-SHOULD-CURRY-DIRECTLY || $SELF.IMPL-OPERANDS-SHOULD-CURRY-DIRECTLY || nqp::elems($SELF.IMPL-ALL-CHILDREN-THAT-SHOULD-CURRY) > 0 }); add-method(RakuAST::WhateverApplicable, 'IMPL-CURRY-ACROSS-ALL-CHILDREN', [RakuAST::WhateverApplicable, '', 0, 0, Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::CurryThunk, '$curried', 0, 0], anon sub IMPL-CURRY-ACROSS-ALL-CHILDREN ($SELF_CONT, $resolver!, $context!, $curried!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $curried := nqp::decont($curried); #line 1197 src/Raku/ast/expressions.rakumod my $operator-curries := $SELF.operator.IMPL-CURRIES; my @curryable-children := $SELF.IMPL-ALL-CHILDREN-THAT-SHOULD-CURRY; @curryable-children.unshift($SELF) if $SELF.IMPL-SHOULD-CURRY-DIRECTLY || $SELF.IMPL-OPERANDS-SHOULD-CURRY-DIRECTLY; while @curryable-children { my $child := @curryable-children.shift; my $child-curries := $child.operator.IMPL-CURRIES; my $child-curries-whatever := nqp::bitand_i($child-curries, 1); my $child-curries-whatevercode := nqp::bitand_i($child-curries, 2); # We might have already visited this node and resolved the RakuAST::Term::Whatever nodes to the # respective $whatevercode_arg parameter target. If so, move on! next unless $child.IMPL-SHOULD-CURRY-DIRECTLY || $child.IMPL-OPERANDS-SHOULD-CURRY-DIRECTLY; # Each of these has their own small specificities, such as the name of the class/attribute to bind into # but they follow the same patterns. # For ApplyInfix and ApplyListInfix # - For all $child.operands, inspect each to determine whether we should should curry across all of their # (curryable) children. # - Otherwise, check to determine if this is operand is a curryable whatever *. If so, call IMPL-ADD-PARAM # to create a new '$whatevercode_arg_*' parameter and then bind the lookup to the target of that parameter # into the location that previously held the curryable *. # For ApplyPrefix and ApplyPostfix # - Same procedure as above, except we only check for direct curryability rather than whether there are curryable children. # Instead we utilize their respective PERFORM-BEGIN-AFTER-CHILDREN routines to finalize relevant currables. if nqp::istype($child, RakuAST::ApplyListInfix) { my @operands := $SELF.IMPL-UNWRAP-LIST($SELF.operands); my $index := -1; for @operands { my $operand := $_; $index++; # it needs to count every time so that we write into the appropriate slot in @operands if $child-curries-whatevercode && ((nqp::istype($operand, RakuAST::WhateverApplicable) && $operand.IMPL-SHOULD-CURRY-ACROSS-ALL-CHILDREN) || ($child-curries-whatever && nqp::istype($operand, RakuAST::Circumfix::Parentheses) && (my $curryable-expression := $operand.IMPL-CONTAINS-SINGULAR-CURRYABLE-EXPRESSION) && $curryable-expression.IMPL-SHOULD-CURRY-ACROSS-ALL-CHILDREN)) { ($curryable-expression // $operand).IMPL-CURRY-ACROSS-ALL-CHILDREN($resolver, $context, $curried); } next unless $child-curries-whatever && nqp::istype($operand, RakuAST::Term::Whatever); @operands[$index] := $curried.IMPL-ADD-PARAM($resolver, $context).target.generate-lookup; } nqp::bindattr($child, RakuAST::ApplyListInfix, '$!operands', @operands); } elsif nqp::istype($child, RakuAST::ApplyInfix) { for "left", "right" { my $operand := $child."$_"(); if $child-curries-whatevercode && ((nqp::istype($operand, RakuAST::WhateverApplicable) && $operand.IMPL-SHOULD-CURRY-ACROSS-ALL-CHILDREN) || ($child-curries-whatever && nqp::istype($operand, RakuAST::Circumfix::Parentheses) && (my $curryable-expression := $operand.IMPL-CONTAINS-SINGULAR-CURRYABLE-EXPRESSION) && $curryable-expression.IMPL-SHOULD-CURRY-ACROSS-ALL-CHILDREN)) { ($curryable-expression // $operand).IMPL-CURRY-ACROSS-ALL-CHILDREN($resolver, $context, $curried); } next unless $child-curries-whatever && nqp::istype($operand, RakuAST::Term::Whatever); $child."set-$_"($curried.IMPL-ADD-PARAM($resolver, $context).target.generate-lookup); } } elsif nqp::istype($child, RakuAST::ApplyPostfix) { next unless $child-curries-whatever && nqp::istype($child.operand, RakuAST::Term::Whatever); nqp::bindattr($child, RakuAST::ApplyPostfix, '$!operand', $curried.IMPL-ADD-PARAM($resolver, $context).target.generate-lookup); } elsif nqp::istype($child, RakuAST::ApplyPrefix) { next unless $child-curries-whatever && nqp::istype($child.operand, RakuAST::Term::Whatever); nqp::bindattr($child, RakuAST::ApplyPrefix, '$!operand', $curried.IMPL-ADD-PARAM($resolver, $context).target.generate-lookup); } } }); compose(RakuAST::WhateverApplicable); parent(RakuAST::ApplyInfix, RakuAST::Expression); parent(RakuAST::ApplyInfix, RakuAST::BeginTime); parent(RakuAST::ApplyInfix, RakuAST::CheckTime); parent(RakuAST::ApplyInfix, RakuAST::WhateverApplicable); add-attribute(RakuAST::ApplyInfix, RakuAST::Infixish, '$!infix'); add-attribute(RakuAST::ApplyInfix, RakuAST::ArgList, '$!args'); add-method(RakuAST::ApplyInfix, 'new', [RakuAST::ApplyInfix, '', 0, 0, RakuAST::Infixish, '$infix', 1, 0, RakuAST::Expression, '$left', 1, 0, RakuAST::Expression, '$right', 1, 0], anon sub new ($SELF_CONT, :$infix!, :$left!, :$right!) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); $left := nqp::decont($left); $right := nqp::decont($right); #line 1290 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj,RakuAST::ApplyInfix,'$!infix',$infix); nqp::bindattr($obj,RakuAST::ApplyInfix,'$!args',RakuAST::ArgList.new); $obj.set-left($left); $obj.set-right($right); $obj }); add-method(RakuAST::ApplyInfix, 'left', [RakuAST::ApplyInfix, '', 0, 0], anon sub left ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1299 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args').arg-at-pos(0) }); add-method(RakuAST::ApplyInfix, 'set-left', [RakuAST::ApplyInfix, '', 0, 0, RakuAST::Expression, '$left', 0, 0], anon sub set-left ($SELF_CONT, $left!) { my $SELF := nqp::decont($SELF_CONT); $left := nqp::decont($left); #line 1300 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args').set-arg-at-pos(0, $left); }); add-method(RakuAST::ApplyInfix, 'right', [RakuAST::ApplyInfix, '', 0, 0], anon sub right ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1303 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args').arg-at-pos(1) }); add-method(RakuAST::ApplyInfix, 'set-right', [RakuAST::ApplyInfix, '', 0, 0, RakuAST::Expression, '$right', 0, 0], anon sub set-right ($SELF_CONT, $right!) { my $SELF := nqp::decont($SELF_CONT); $right := nqp::decont($right); #line 1304 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args').set-arg-at-pos(1, $right); }); add-method(RakuAST::ApplyInfix, 'add-colonpair', [RakuAST::ApplyInfix, '', 0, 0, RakuAST::ColonPair, '$pair', 0, 0], anon sub add-colonpair ($SELF_CONT, $pair!) { my $SELF := nqp::decont($SELF_CONT); $pair := nqp::decont($pair); #line 1307 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args').push($pair); Nil }); add-method(RakuAST::ApplyInfix, 'operands', [RakuAST::ApplyInfix, '', 0, 0], anon sub operands ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1311 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args').IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args').args) }); add-method(RakuAST::ApplyInfix, 'operator', [RakuAST::ApplyInfix, '', 0, 0], anon sub operator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1312 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!infix') }); add-method(RakuAST::ApplyInfix, 'is-begin-performed-before-children', [RakuAST::ApplyInfix, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1314 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::ApplyInfix, 'is-begin-performed-after-children', [RakuAST::ApplyInfix, '', 0, 0], anon sub is-begin-performed-after-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1315 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::ApplyInfix, 'PERFORM-BEGIN-BEFORE-CHILDREN', [RakuAST::ApplyInfix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-BEFORE-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1317 src/Raku/ast/expressions.rakumod my $curried; if $SELF.IMPL-SHOULD-CURRY-ACROSS-ALL-CHILDREN { $curried := $SELF.IMPL-CURRY; $SELF.IMPL-CURRY-ACROSS-ALL-CHILDREN($resolver, $context, $curried); } # There is a chance that we didn't actually meet the conditions to curry inside of IMPL-CURRY-ACROSS-ALL-CHILDREN. # If no actual params have been set, we can assume that this happened. $SELF.IMPL-UNCURRY if $curried && nqp::elems($curried.IMPL-PARAMS) == 0; }); add-method(RakuAST::ApplyInfix, 'PERFORM-BEGIN-AFTER-CHILDREN', [RakuAST::ApplyInfix, '', 0, 0, Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-AFTER-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1328 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!infix').IMPL-THUNK-ARGUMENTS($resolver, $context, $SELF.left, $SELF.right); }); add-method(RakuAST::ApplyInfix, 'PERFORM-CHECK', [RakuAST::ApplyInfix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1335 src/Raku/ast/expressions.rakumod my $infix := nqp::getattr($SELF, RakuAST::ApplyInfix, '$!infix'); my $left := $SELF.left; my $right := $SELF.right; # handle op= if nqp::eqaddr($infix.WHAT,RakuAST::MetaInfix::Assign) { my str $operator := $infix.infix.operator; if $operator eq ',' || $operator eq 'xx' { my $sigil := (try $left.sigil) // ''; if $sigil eq '$' || $sigil eq '@' { $SELF.add-worry: $resolver.build-exception: 'X::AdHoc', payload => "Using $operator on a " ~ ($sigil eq '$' ?? 'scalar' !! 'array') ~ " is probably NOT what you want, as it will create\n" ~ "a self-referential structure with little meaning"; } } } # a "normal" infix op elsif nqp::istype($infix,RakuAST::Infix) { if $infix.operator eq ':=' && !$left.can-be-bound-to { $SELF.add-sorry: $resolver.build-exception: 'X::Bind'; } } (Bool.WHO) }); add-method(RakuAST::ApplyInfix, 'IMPL-EXPR-QAST', [RakuAST::ApplyInfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1366 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!infix').IMPL-INFIX-COMPILE($context, $SELF.left, $SELF.right) }); add-method(RakuAST::ApplyInfix, 'visit-children', [RakuAST::ApplyInfix, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1370 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::ApplyInfix, '$!infix')); $visitor(nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args')) }); add-method(RakuAST::ApplyInfix, 'IMPL-CAN-INTERPRET', [RakuAST::ApplyInfix, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1375 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!infix').IMPL-CAN-INTERPRET && nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args').IMPL-CAN-INTERPRET }); add-method(RakuAST::ApplyInfix, 'IMPL-INTERPRET', [RakuAST::ApplyInfix, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 1379 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyInfix, '$!infix').IMPL-INTERPRET($ctx, $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::ApplyInfix, '$!args').args) ); }); #line 1286 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyInfix, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyInfix, '$!infix') }); #line 1287 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyInfix, 'args', [], anon sub args ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyInfix, '$!args') }); compose(RakuAST::ApplyInfix); parent(RakuAST::ApplyListInfix, RakuAST::Expression); parent(RakuAST::ApplyListInfix, RakuAST::BeginTime); parent(RakuAST::ApplyListInfix, RakuAST::WhateverApplicable); add-attribute(RakuAST::ApplyListInfix, RakuAST::Infixish, '$!infix'); add-attribute(RakuAST::ApplyListInfix, List, '$!operands'); add-method(RakuAST::ApplyListInfix, 'new', [RakuAST::ApplyListInfix, '', 0, 0, RakuAST::Infixish, '$infix', 1, 0, List, '$operands', 1, 0], anon sub new ($SELF_CONT, :$infix!, :$operands!) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); $operands := nqp::decont($operands); #line 1393 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ApplyListInfix, '$!infix', $infix); nqp::bindattr($obj, RakuAST::ApplyListInfix, '$!operands', my $list := []); for $SELF.IMPL-UNWRAP-LIST($operands) { if nqp::istype($_, RakuAST::ColonPairs) { for $_.colonpairs { nqp::push($list, $_); } } else { nqp::push($list, $_); } } $obj }); add-method(RakuAST::ApplyListInfix, 'operands', [RakuAST::ApplyListInfix, '', 0, 0], anon sub operands ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1410 src/Raku/ast/expressions.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!operands')) }); add-method(RakuAST::ApplyListInfix, 'operator', [RakuAST::ApplyListInfix, '', 0, 0], anon sub operator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1411 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!infix') }); add-method(RakuAST::ApplyListInfix, 'IMPL-EXPR-QAST', [RakuAST::ApplyListInfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1413 src/Raku/ast/expressions.rakumod my @operands; for nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!operands') { @operands.push($_.IMPL-TO-QAST($context)); } nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!infix').IMPL-LIST-INFIX-QAST: $context, @operands; }); add-method(RakuAST::ApplyListInfix, 'visit-children', [RakuAST::ApplyListInfix, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1421 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!infix')); for nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!operands') { $visitor($_); } }); add-method(RakuAST::ApplyListInfix, 'IMPL-CUSTOM-SHOULD-CURRY-CONDITIONS', [RakuAST::ApplyListInfix, '', 0, 0], anon sub IMPL-CUSTOM-SHOULD-CURRY-CONDITIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1428 src/Raku/ast/expressions.rakumod # Anything but a ',' !(nqp::istype(nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!infix'), RakuAST::Infix) && nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!infix').operator eq ',') }); add-method(RakuAST::ApplyListInfix, 'PERFORM-BEGIN', [RakuAST::ApplyListInfix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1433 src/Raku/ast/expressions.rakumod my $curried; if $SELF.IMPL-SHOULD-CURRY-ACROSS-ALL-CHILDREN { $curried := $SELF.IMPL-CURRY; $SELF.IMPL-CURRY-ACROSS-ALL-CHILDREN($resolver, $context, $curried); } # There is a chance that we didn't actually meet the conditions to curry inside of IMPL-CURRY-ACROSS-ALL-CHILDREN. # If no actual params have been set, we can assume that this happened. $SELF.IMPL-UNCURRY if $curried && nqp::elems($curried.IMPL-PARAMS) == 0; nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!infix').IMPL-THUNK-ARGUMENTS($resolver, $context, |$SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!operands'))); }); add-method(RakuAST::ApplyListInfix, 'IMPL-CAN-INTERPRET', [RakuAST::ApplyListInfix, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1446 src/Raku/ast/expressions.rakumod if nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!infix').IMPL-CAN-INTERPRET { for $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!operands')) { return (Bool.WHO) unless $_.IMPL-CAN-INTERPRET; } (Bool.WHO) } else { (Bool.WHO) } }); add-method(RakuAST::ApplyListInfix, 'IMPL-INTERPRET', [RakuAST::ApplyListInfix, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 1458 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!infix').IMPL-INTERPRET($ctx, nqp::getattr($SELF, RakuAST::ApplyListInfix, '$!operands')) }); #line 1390 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyListInfix, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyListInfix, '$!infix') }); compose(RakuAST::ApplyListInfix); parent(RakuAST::DottyInfixish, RakuAST::Node); parent(RakuAST::DottyInfixish, RakuAST::OperatorProperties); add-method(RakuAST::DottyInfixish, 'new', [RakuAST::DottyInfixish, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1471 src/Raku/ast/expressions.rakumod nqp::create($SELF) }); compose(RakuAST::DottyInfixish); parent(RakuAST::DottyInfix::Call, RakuAST::DottyInfixish); add-method(RakuAST::DottyInfix::Call, 'IMPL-DOTTY-INFIX-QAST', [RakuAST::DottyInfix::Call, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$lhs-qast', 0, 0, RakuAST::Postfixish, '$rhs-ast', 0, 0], anon sub IMPL-DOTTY-INFIX-QAST ($SELF_CONT, $context!, $lhs-qast!, $rhs-ast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $lhs-qast := nqp::decont($lhs-qast); $rhs-ast := nqp::decont($rhs-ast); #line 1480 src/Raku/ast/expressions.rakumod $rhs-ast.IMPL-POSTFIX-QAST($context, $lhs-qast) }); add-method(RakuAST::DottyInfix::Call, 'default-operator-properties', [RakuAST::DottyInfix::Call, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1484 src/Raku/ast/expressions.rakumod OperatorProperties.infix('.') }); compose(RakuAST::DottyInfix::Call); parent(RakuAST::DottyInfix::CallAssign, RakuAST::DottyInfixish); add-method(RakuAST::DottyInfix::CallAssign, 'default-operator-properties', [RakuAST::DottyInfix::CallAssign, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1494 src/Raku/ast/expressions.rakumod OperatorProperties.infix('.=') }); add-method(RakuAST::DottyInfix::CallAssign, 'IMPL-DOTTY-INFIX-QAST', [RakuAST::DottyInfix::CallAssign, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$lhs-qast', 0, 0, RakuAST::Postfixish, '$rhs-ast', 0, 0], anon sub IMPL-DOTTY-INFIX-QAST ($SELF_CONT, $context!, $lhs-qast!, $rhs-ast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $lhs-qast := nqp::decont($lhs-qast); $rhs-ast := nqp::decont($rhs-ast); #line 1499 src/Raku/ast/expressions.rakumod # Store the target in a temporary, so we only evaluate it once. my $temp := QAST::Node.unique('meta_assign'); my $bind-lhs := QAST::Op.new( :op('bind'), QAST::Var.new( :decl('var'), :scope('local'), :name($temp) ), $lhs-qast ); # Emit the assignment. # TODO case analyze these QAST::Stmt.new( $bind-lhs, QAST::Op.new( :op('assign'), QAST::Var.new( :scope('local'), :name($temp) ), $rhs-ast.IMPL-POSTFIX-QAST( $context, QAST::Var.new( :scope('local'), :name($temp) ), ) ) ) }); compose(RakuAST::DottyInfix::CallAssign); parent(RakuAST::ApplyDottyInfix, RakuAST::Expression); add-attribute(RakuAST::ApplyDottyInfix, RakuAST::DottyInfixish, '$!infix'); add-attribute(RakuAST::ApplyDottyInfix, RakuAST::Expression, '$!left'); add-attribute(RakuAST::ApplyDottyInfix, RakuAST::Postfixish, '$!right'); add-method(RakuAST::ApplyDottyInfix, 'new', [RakuAST::ApplyDottyInfix, '', 0, 0, RakuAST::DottyInfixish, '$infix', 1, 0, RakuAST::Expression, '$left', 1, 0, RakuAST::Postfixish, '$right', 1, 0], anon sub new ($SELF_CONT, :$infix!, :$left!, :$right!) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); $left := nqp::decont($left); $right := nqp::decont($right); #line 1535 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ApplyDottyInfix, '$!infix', $infix); nqp::bindattr($obj, RakuAST::ApplyDottyInfix, '$!left', $left); nqp::bindattr($obj, RakuAST::ApplyDottyInfix, '$!right', $right); $obj }); add-method(RakuAST::ApplyDottyInfix, 'properties', [RakuAST::ApplyDottyInfix, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1543 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyDottyInfix, '$!infix').properties }); add-method(RakuAST::ApplyDottyInfix, 'IMPL-EXPR-QAST', [RakuAST::ApplyDottyInfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1545 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyDottyInfix, '$!infix').IMPL-DOTTY-INFIX-QAST: $context, nqp::getattr($SELF, RakuAST::ApplyDottyInfix, '$!left').IMPL-TO-QAST($context), nqp::getattr($SELF, RakuAST::ApplyDottyInfix, '$!right') }); add-method(RakuAST::ApplyDottyInfix, 'visit-children', [RakuAST::ApplyDottyInfix, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1551 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::ApplyDottyInfix, '$!left')); $visitor(nqp::getattr($SELF, RakuAST::ApplyDottyInfix, '$!infix')); $visitor(nqp::getattr($SELF, RakuAST::ApplyDottyInfix, '$!right')); }); #line 1532 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyDottyInfix, 'right', [], anon sub right ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyDottyInfix, '$!right') }); #line 1531 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyDottyInfix, 'left', [], anon sub left ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyDottyInfix, '$!left') }); #line 1530 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyDottyInfix, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyDottyInfix, '$!infix') }); compose(RakuAST::ApplyDottyInfix); parent(RakuAST::Prefixish, RakuAST::Node); add-attribute(RakuAST::Prefixish, List, '$!colonpairs'); add-method(RakuAST::Prefixish, 'add-colonpair', [RakuAST::Prefixish, '', 0, 0, RakuAST::ColonPair, '$pair', 0, 0], anon sub add-colonpair ($SELF_CONT, $pair!) { my $SELF := nqp::decont($SELF_CONT); $pair := nqp::decont($pair); #line 1567 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::Prefixish, '$!colonpairs').push: $pair; }); add-method(RakuAST::Prefixish, 'visit-colonpairs', [RakuAST::Prefixish, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-colonpairs ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1571 src/Raku/ast/expressions.rakumod for nqp::getattr($SELF, RakuAST::Prefixish, '$!colonpairs') { $visitor($_); } }); add-method(RakuAST::Prefixish, 'IMPL-ADD-COLONPAIRS-TO-OP', [RakuAST::Prefixish, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$op', 0, 0], anon sub IMPL-ADD-COLONPAIRS-TO-OP ($SELF_CONT, $context!, $op!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $op := nqp::decont($op); #line 1577 src/Raku/ast/expressions.rakumod for nqp::getattr($SELF, RakuAST::Prefixish, '$!colonpairs') { my $val-ast := $_.named-arg-value.IMPL-TO-QAST($context); $val-ast.named($_.named-arg-name); $op.push($val-ast); } }); add-method(RakuAST::Prefixish, 'IMPL-CURRIES', [RakuAST::Prefixish, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1585 src/Raku/ast/expressions.rakumod 3 }); #line 1565 src/Raku/ast/expressions.rakumod add-method(RakuAST::Prefixish, 'colonpairs', [], anon sub colonpairs ($self) { nqp::getattr(nqp::decont($self), RakuAST::Prefixish, '$!colonpairs') }); compose(RakuAST::Prefixish); parent(RakuAST::Prefix, RakuAST::Prefixish); parent(RakuAST::Prefix, RakuAST::OperatorProperties); parent(RakuAST::Prefix, RakuAST::Lookup); add-attribute(RakuAST::Prefix, str, '$!operator'); add-method(RakuAST::Prefix, 'new', [RakuAST::Prefix, '', 0, 0, str, '$operator', 0, 0], anon sub new ($SELF_CONT, $operator!) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); #line 1596 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Prefix, '$!operator', $operator); nqp::bindattr($obj, RakuAST::Prefixish, '$!colonpairs', []); $obj }); add-method(RakuAST::Prefix, 'default-operator-properties', [RakuAST::Prefix, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1603 src/Raku/ast/expressions.rakumod OperatorProperties.prefix(nqp::getattr_s($SELF, RakuAST::Prefix, '$!operator')) }); add-method(RakuAST::Prefix, 'resolve-with', [RakuAST::Prefix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1607 src/Raku/ast/expressions.rakumod my $resolved := $resolver.resolve-prefix(nqp::getattr_s($SELF, RakuAST::Prefix, '$!operator')); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Prefix, 'IMPL-PREFIX-QAST', [RakuAST::Prefix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-PREFIX-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 1615 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; my $op := QAST::Op.new( :op('call'), :$name, $operand-qast ); $SELF.IMPL-ADD-COLONPAIRS-TO-OP($context, $op); $op }); add-method(RakuAST::Prefix, 'IMPL-HOP-PREFIX-QAST', [RakuAST::Prefix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-HOP-PREFIX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1622 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; QAST::Var.new( :scope('lexical'), :$name ) }); #line 1594 src/Raku/ast/expressions.rakumod add-method(RakuAST::Prefix, 'operator', [], anon sub operator ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Prefix, '$!operator') }); compose(RakuAST::Prefix); parent(RakuAST::MetaPrefix::Hyper, RakuAST::Prefixish); add-attribute(RakuAST::MetaPrefix::Hyper, RakuAST::Prefix, '$!prefix'); add-method(RakuAST::MetaPrefix::Hyper, 'new', [RakuAST::MetaPrefix::Hyper, '', 0, 0, RakuAST::Prefix, '$prefix', 0, 0], anon sub new ($SELF_CONT, $prefix!) { my $SELF := nqp::decont($SELF_CONT); $prefix := nqp::decont($prefix); #line 1634 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::MetaPrefix::Hyper, '$!prefix', $prefix); nqp::bindattr($obj, RakuAST::Prefixish, '$!colonpairs', []); $obj }); add-method(RakuAST::MetaPrefix::Hyper, 'IMPL-PREFIX-QAST', [RakuAST::MetaPrefix::Hyper, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-PREFIX-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 1641 src/Raku/ast/expressions.rakumod my $op := QAST::Op.new: :op('call'), QAST::Op.new( :op('callstatic'), :name('&METAOP_HYPER_PREFIX'), nqp::getattr($SELF, RakuAST::MetaPrefix::Hyper, '$!prefix').IMPL-HOP-PREFIX-QAST($context) ), $operand-qast; $SELF.IMPL-ADD-COLONPAIRS-TO-OP($context, $op); $op }); add-method(RakuAST::MetaPrefix::Hyper, 'visit-children', [RakuAST::MetaPrefix::Hyper, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1653 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::MetaPrefix::Hyper, '$!prefix')); }); add-method(RakuAST::MetaPrefix::Hyper, 'properties', [RakuAST::MetaPrefix::Hyper, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1657 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::MetaPrefix::Hyper, '$!prefix').properties }); #line 1632 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaPrefix::Hyper, 'prefix', [], anon sub prefix ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaPrefix::Hyper, '$!prefix') }); compose(RakuAST::MetaPrefix::Hyper); parent(RakuAST::Termish, RakuAST::Expression); parent(RakuAST::Termish, RakuAST::CaptureSource); compose(RakuAST::Termish); parent(RakuAST::Term, RakuAST::Termish); compose(RakuAST::Term); parent(RakuAST::ApplyPrefix, RakuAST::Termish); parent(RakuAST::ApplyPrefix, RakuAST::BeginTime); parent(RakuAST::ApplyPrefix, RakuAST::WhateverApplicable); add-attribute(RakuAST::ApplyPrefix, RakuAST::Prefixish, '$!prefix'); add-attribute(RakuAST::ApplyPrefix, RakuAST::Expression, '$!operand'); add-method(RakuAST::ApplyPrefix, 'new', [RakuAST::ApplyPrefix, '', 0, 0, Any, '$prefix', 1, 0, Any, '$operand', 1, 0], anon sub new ($SELF_CONT, :$prefix!, :$operand!) { my $SELF := nqp::decont($SELF_CONT); $prefix := nqp::decont($prefix); $operand := nqp::decont($operand); #line 1680 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ApplyPrefix, '$!prefix', $prefix); nqp::bindattr($obj, RakuAST::ApplyPrefix, '$!operand', $operand); $obj }); add-method(RakuAST::ApplyPrefix, 'add-colonpair', [RakuAST::ApplyPrefix, '', 0, 0, RakuAST::ColonPair, '$pair', 0, 0], anon sub add-colonpair ($SELF_CONT, $pair!) { my $SELF := nqp::decont($SELF_CONT); $pair := nqp::decont($pair); #line 1687 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyPrefix, '$!prefix').add-colonpair($pair); }); add-method(RakuAST::ApplyPrefix, 'operands', [RakuAST::ApplyPrefix, '', 0, 0], anon sub operands ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1691 src/Raku/ast/expressions.rakumod [nqp::getattr($SELF, RakuAST::ApplyPrefix, '$!operand')] }); add-method(RakuAST::ApplyPrefix, 'operator', [RakuAST::ApplyPrefix, '', 0, 0], anon sub operator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1692 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyPrefix, '$!prefix') }); add-method(RakuAST::ApplyPrefix, 'is-begin-performed-before-children', [RakuAST::ApplyPrefix, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1694 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::ApplyPrefix, 'is-begin-performed-after-children', [RakuAST::ApplyPrefix, '', 0, 0], anon sub is-begin-performed-after-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1695 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::ApplyPrefix, 'PERFORM-BEGIN-BEFORE-CHILDREN', [RakuAST::ApplyPrefix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-BEFORE-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1697 src/Raku/ast/expressions.rakumod if $SELF.IMPL-SHOULD-CURRY-DIRECTLY { nqp::bindattr($SELF, RakuAST::ApplyPrefix, '$!operand', $SELF.IMPL-CURRY.IMPL-ADD-PARAM($resolver, $context).target.generate-lookup); } }); add-method(RakuAST::ApplyPrefix, 'PERFORM-BEGIN-AFTER-CHILDREN', [RakuAST::ApplyPrefix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-AFTER-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1704 src/Raku/ast/expressions.rakumod my $operand := nqp::getattr($SELF, RakuAST::ApplyPrefix, '$!operand'); if nqp::bitand_i(nqp::getattr($SELF, RakuAST::ApplyPrefix, '$!prefix').IMPL-CURRIES, 2) { if $operand.IMPL-CURRIED { my @params := $operand.IMPL-UNCURRY; my $curried := $SELF.IMPL-CURRY; for @params { $curried.IMPL-ADD-PARAM($resolver, $context, :name($_.target.lexical-name)); } } elsif nqp::istype($operand, RakuAST::Circumfix::Parentheses) && (my $expression := $operand.IMPL-SINGULAR-CURRIED-EXPRESSION) { my @params := $expression.IMPL-UNCURRY; my $curried := $SELF.IMPL-CURRY; for @params { $curried.IMPL-ADD-PARAM($resolver, $context, :name($_.target.lexical-name)); } } } }); add-method(RakuAST::ApplyPrefix, 'IMPL-EXPR-QAST', [RakuAST::ApplyPrefix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1726 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyPrefix, '$!prefix').IMPL-PREFIX-QAST($context, nqp::getattr($SELF, RakuAST::ApplyPrefix, '$!operand').IMPL-TO-QAST($context)) }); add-method(RakuAST::ApplyPrefix, 'visit-children', [RakuAST::ApplyPrefix, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1730 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::ApplyPrefix, '$!prefix')); $visitor(nqp::getattr($SELF, RakuAST::ApplyPrefix, '$!operand')); }); #line 1677 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyPrefix, 'prefix', [], anon sub prefix ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyPrefix, '$!prefix') }); #line 1678 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyPrefix, 'operand', [], anon sub operand ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyPrefix, '$!operand') }); compose(RakuAST::ApplyPrefix); parent(RakuAST::Postfixish, RakuAST::Node); parent(RakuAST::Postfixish, RakuAST::OperatorProperties); add-attribute(RakuAST::Postfixish, List, '$!colonpairs'); add-method(RakuAST::Postfixish, 'set-colonpairs', [RakuAST::Postfixish, '', 0, 0, List, '$pairs', 0, 0], anon sub set-colonpairs ($SELF_CONT, $pairs!) { my $SELF := nqp::decont($SELF_CONT); $pairs := nqp::decont($pairs); #line 1746 src/Raku/ast/expressions.rakumod my @pairs; if $pairs { for $SELF.IMPL-UNWRAP-LIST($pairs) { nqp::push(@pairs,$_); } } nqp::bindattr($SELF,RakuAST::Postfixish,'$!colonpairs',@pairs); }); add-method(RakuAST::Postfixish, 'add-colonpair', [RakuAST::Postfixish, '', 0, 0, RakuAST::ColonPair, '$pair', 0, 0], anon sub add-colonpair ($SELF_CONT, $pair!) { my $SELF := nqp::decont($SELF_CONT); $pair := nqp::decont($pair); #line 1756 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::Postfixish, '$!colonpairs').push: $pair; }); add-method(RakuAST::Postfixish, 'visit-colonpairs', [RakuAST::Postfixish, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-colonpairs ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1760 src/Raku/ast/expressions.rakumod for nqp::getattr($SELF, RakuAST::Postfixish, '$!colonpairs') { $visitor($_); } }); add-method(RakuAST::Postfixish, 'IMPL-ADD-COLONPAIRS-TO-OP', [RakuAST::Postfixish, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$op', 0, 0], anon sub IMPL-ADD-COLONPAIRS-TO-OP ($SELF_CONT, $context!, $op!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $op := nqp::decont($op); #line 1766 src/Raku/ast/expressions.rakumod for nqp::getattr($SELF, RakuAST::Postfixish, '$!colonpairs') { my $val-ast := $_.named-arg-value.IMPL-TO-QAST($context); $val-ast.named($_.named-arg-name); $op.push($val-ast); } }); add-method(RakuAST::Postfixish, 'IMPL-CURRIES', [RakuAST::Postfixish, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1778 src/Raku/ast/expressions.rakumod 0 }); add-method(RakuAST::Postfixish, 'can-be-used-with-hyper', [RakuAST::Postfixish, '', 0, 0], anon sub can-be-used-with-hyper ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1780 src/Raku/ast/expressions.rakumod (Bool.WHO) }); #line 1744 src/Raku/ast/expressions.rakumod add-method(RakuAST::Postfixish, 'colonpairs', [], anon sub colonpairs ($self) { nqp::getattr(nqp::decont($self), RakuAST::Postfixish, '$!colonpairs') }); compose(RakuAST::Postfixish); parent(RakuAST::Postfix, RakuAST::Postfixish); parent(RakuAST::Postfix, RakuAST::Lookup); add-attribute(RakuAST::Postfix, str, '$!operator'); add-method(RakuAST::Postfix, 'new', [RakuAST::Postfix, '', 0, 0, str, '$operator', 1, 0, List, '$colonpairs', 1, 1], anon sub new ($SELF_CONT, :$operator!, :$colonpairs?) { my $SELF := nqp::decont($SELF_CONT); $operator := nqp::decont($operator); $colonpairs := nqp::decont($colonpairs); #line 1790 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Postfix, '$!operator', $operator); $obj.set-colonpairs($colonpairs); $obj }); add-method(RakuAST::Postfix, 'default-operator-properties', [RakuAST::Postfix, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1797 src/Raku/ast/expressions.rakumod OperatorProperties.postfix(nqp::getattr_s($SELF, RakuAST::Postfix, '$!operator')) }); add-method(RakuAST::Postfix, 'resolve-with', [RakuAST::Postfix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1801 src/Raku/ast/expressions.rakumod my $resolved := $resolver.resolve-postfix(nqp::getattr_s($SELF, RakuAST::Postfix, '$!operator')); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Postfix, 'IMPL-POSTFIX-QAST', [RakuAST::Postfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 1812 src/Raku/ast/expressions.rakumod my $op := QAST::Op.new( :op('call'), :name($SELF.resolution.lexical-name), $operand-qast ); $SELF.IMPL-ADD-COLONPAIRS-TO-OP($context, $op); $op }); add-method(RakuAST::Postfix, 'can-be-used-with-hyper', [RakuAST::Postfix, '', 0, 0], anon sub can-be-used-with-hyper ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1820 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::Postfix, 'IMPL-POSTFIX-HYPER-QAST', [RakuAST::Postfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-HYPER-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 1822 src/Raku/ast/expressions.rakumod QAST::Op.new: :op('callstatic'), :name('&METAOP_HYPER_POSTFIX_ARGS'), $operand-qast, $SELF.resolution.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::Postfix, 'IMPL-CURRIES', [RakuAST::Postfix, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1829 src/Raku/ast/expressions.rakumod 3 }); #line 1788 src/Raku/ast/expressions.rakumod add-method(RakuAST::Postfix, 'operator', [], anon sub operator ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Postfix, '$!operator') }); compose(RakuAST::Postfix); parent(RakuAST::Postfix::Literal, RakuAST::Postfixish); parent(RakuAST::Postfix::Literal, RakuAST::Lookup); add-attribute(RakuAST::Postfix::Literal, Mu, '$!value'); add-method(RakuAST::Postfix::Literal, 'new', [RakuAST::Postfix::Literal, '', 0, 0, Mu, '$value', 0, 0], anon sub new ($SELF_CONT, $value!) { my $SELF := nqp::decont($SELF_CONT); $value := nqp::decont($value); #line 1839 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Postfix::Literal, '$!value', $value); # NOTE: these can never have colonpairs nqp::bindattr($obj, RakuAST::Postfixish, '$!colonpairs', []); $obj }); add-method(RakuAST::Postfix::Literal, 'IMPL-POSTFIX-QAST', [RakuAST::Postfix::Literal, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 1847 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; $context.ensure-sc(nqp::getattr($SELF, RakuAST::Postfix::Literal, '$!value')); QAST::Op.new: :op('call'), :$name, $operand-qast, QAST::WVal.new( :value(nqp::getattr($SELF, RakuAST::Postfix::Literal, '$!value')) ) }); add-method(RakuAST::Postfix::Literal, 'can-be-used-with-hyper', [RakuAST::Postfix::Literal, '', 0, 0], anon sub can-be-used-with-hyper ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1856 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::Postfix::Literal, 'IMPL-CURRIES', [RakuAST::Postfix::Literal, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1858 src/Raku/ast/expressions.rakumod 3 }); compose(RakuAST::Postfix::Literal); parent(RakuAST::Postfix::Power, RakuAST::Postfix::Literal); add-method(RakuAST::Postfix::Power, 'properties', [RakuAST::Postfix::Power, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1866 src/Raku/ast/expressions.rakumod OperatorProperties.postfix('ⁿ') }); add-method(RakuAST::Postfix::Power, 'resolve-with', [RakuAST::Postfix::Power, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1870 src/Raku/ast/expressions.rakumod my $resolved := $resolver.resolve-postfix('ⁿ'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Postfix::Power, 'power', [RakuAST::Postfix::Power, '', 0, 0], anon sub power ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1878 src/Raku/ast/expressions.rakumod nqp::getattr($SELF,RakuAST::Postfix::Literal,'$!value') }); compose(RakuAST::Postfix::Power); parent(RakuAST::Postfix::Vulgar, RakuAST::Postfix::Literal); add-method(RakuAST::Postfix::Vulgar, 'properties', [RakuAST::Postfix::Vulgar, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1886 src/Raku/ast/expressions.rakumod OperatorProperties.postfix('+') }); add-method(RakuAST::Postfix::Vulgar, 'resolve-with', [RakuAST::Postfix::Vulgar, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1890 src/Raku/ast/expressions.rakumod # Note that we're trying to resolve it here as an infix +, because # that's what this actually does (and there is no &postfix:<+> sub) my $resolved := $resolver.resolve-infix('+'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Postfix::Vulgar, 'vulgar', [RakuAST::Postfix::Vulgar, '', 0, 0], anon sub vulgar ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1900 src/Raku/ast/expressions.rakumod nqp::getattr($SELF,RakuAST::Postfix::Literal,'$!value') }); compose(RakuAST::Postfix::Vulgar); parent(RakuAST::Postcircumfix, RakuAST::Postfixish); compose(RakuAST::Postcircumfix); parent(RakuAST::Postcircumfix::ArrayIndex, RakuAST::Postcircumfix); parent(RakuAST::Postcircumfix::ArrayIndex, RakuAST::Lookup); add-attribute(RakuAST::Postcircumfix::ArrayIndex, RakuAST::SemiList, '$!index'); add-attribute(RakuAST::Postcircumfix::ArrayIndex, RakuAST::Expression, '$!assignee'); add-method(RakuAST::Postcircumfix::ArrayIndex, 'new', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0, RakuAST::SemiList, '$index', 1, 0, RakuAST::Expression, '$assignee', 1, 1, List, '$colonpairs', 1, 1], anon sub new ($SELF_CONT, :$index!, :$assignee?, :$colonpairs?) { my $SELF := nqp::decont($SELF_CONT); $index := nqp::decont($index); $assignee := nqp::decont($assignee); $colonpairs := nqp::decont($colonpairs); #line 1923 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Postcircumfix::ArrayIndex, '$!index', $index); nqp::bindattr($obj, RakuAST::Postcircumfix::ArrayIndex, '$!assignee', $assignee // RakuAST::Expression); $obj.set-colonpairs($colonpairs); $obj }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'set-assignee', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0, RakuAST::Expression, '$assignee', 0, 0], anon sub set-assignee ($SELF_CONT, $assignee!) { my $SELF := nqp::decont($SELF_CONT); $assignee := nqp::decont($assignee); #line 1931 src/Raku/ast/expressions.rakumod nqp::bindattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!assignee', $assignee); }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'can-be-bound-to', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1935 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'resolve-with', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1939 src/Raku/ast/expressions.rakumod my $resolved := $resolver.resolve-lexical( nqp::elems(nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!index').code-statements) > 1 ?? '&postcircumfix:<[; ]>' !! '&postcircumfix:<[ ]>'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'default-operator-properties', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1950 src/Raku/ast/expressions.rakumod OperatorProperties.postcircumfix('[ ]') }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'visit-children', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1954 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!index')); $visitor(nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!assignee')) if nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!assignee'); $SELF.visit-colonpairs($visitor); }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'IMPL-CURRIES', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1960 src/Raku/ast/expressions.rakumod 3 }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'IMPL-POSTFIX-QAST', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 1962 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; my $op := QAST::Op.new( :op('call'), :$name, $operand-qast ); $op.push(nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!index').IMPL-TO-QAST($context)) unless nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!index').is-empty; $op.push(nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!assignee').IMPL-TO-QAST($context)) if nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!assignee'); $SELF.IMPL-ADD-COLONPAIRS-TO-OP($context, $op); $op }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'IMPL-BIND-POSTFIX-QAST', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '$operand', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-POSTFIX-QAST ($SELF_CONT, $context!, $operand!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand := nqp::decont($operand); $source-qast := nqp::decont($source-qast); #line 1972 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; my $op := QAST::Op.new( :op('call'), :$name, $operand.IMPL-TO-QAST($context) ); $op.push(nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!index').IMPL-TO-QAST($context)) unless nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!index').is-empty; my $bind := $source-qast; $bind.named('BIND'); $op.push($bind); $op }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'can-be-used-with-hyper', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0], anon sub can-be-used-with-hyper ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1982 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::Postcircumfix::ArrayIndex, 'IMPL-POSTFIX-HYPER-QAST', [RakuAST::Postcircumfix::ArrayIndex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-HYPER-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 1984 src/Raku/ast/expressions.rakumod QAST::Op.new: :op('callstatic'), :name('&METAOP_HYPER_POSTFIX_ARGS'), $operand-qast, nqp::getattr($SELF, RakuAST::Postcircumfix::ArrayIndex, '$!index').IMPL-TO-QAST($context), $SELF.resolution.IMPL-LOOKUP-QAST($context) }); #line 1916 src/Raku/ast/expressions.rakumod add-method(RakuAST::Postcircumfix::ArrayIndex, 'index', [], anon sub index ($self) { nqp::getattr(nqp::decont($self), RakuAST::Postcircumfix::ArrayIndex, '$!index') }); #line 1917 src/Raku/ast/expressions.rakumod add-method(RakuAST::Postcircumfix::ArrayIndex, 'assignee', [], anon sub assignee ($self) { nqp::getattr(nqp::decont($self), RakuAST::Postcircumfix::ArrayIndex, '$!assignee') }); compose(RakuAST::Postcircumfix::ArrayIndex); parent(RakuAST::Postcircumfix::HashIndex, RakuAST::Postcircumfix); parent(RakuAST::Postcircumfix::HashIndex, RakuAST::Lookup); add-attribute(RakuAST::Postcircumfix::HashIndex, RakuAST::SemiList, '$!index'); add-method(RakuAST::Postcircumfix::HashIndex, 'new', [RakuAST::Postcircumfix::HashIndex, '', 0, 0, RakuAST::SemiList, '$index', 1, 0, List, '$colonpairs', 1, 1], anon sub new ($SELF_CONT, :$index!, :$colonpairs?) { my $SELF := nqp::decont($SELF_CONT); $index := nqp::decont($index); $colonpairs := nqp::decont($colonpairs); #line 2000 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj,RakuAST::Postcircumfix::HashIndex,'$!index',$index); $obj.set-colonpairs($colonpairs); $obj }); add-method(RakuAST::Postcircumfix::HashIndex, 'can-be-bound-to', [RakuAST::Postcircumfix::HashIndex, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2007 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::Postcircumfix::HashIndex, 'resolve-with', [RakuAST::Postcircumfix::HashIndex, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 2011 src/Raku/ast/expressions.rakumod my $resolved := $resolver.resolve-lexical( nqp::elems(nqp::getattr($SELF, RakuAST::Postcircumfix::HashIndex, '$!index').code-statements) > 1 ?? '&postcircumfix:<{; }>' !! '&postcircumfix:<{ }>'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Postcircumfix::HashIndex, 'visit-children', [RakuAST::Postcircumfix::HashIndex, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2022 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::Postcircumfix::HashIndex, '$!index')); $SELF.visit-colonpairs($visitor); }); add-method(RakuAST::Postcircumfix::HashIndex, 'default-operator-properties', [RakuAST::Postcircumfix::HashIndex, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2027 src/Raku/ast/expressions.rakumod OperatorProperties.postcircumfix('{ }') }); add-method(RakuAST::Postcircumfix::HashIndex, 'IMPL-CURRIES', [RakuAST::Postcircumfix::HashIndex, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2031 src/Raku/ast/expressions.rakumod 3 }); add-method(RakuAST::Postcircumfix::HashIndex, 'IMPL-POSTFIX-QAST', [RakuAST::Postcircumfix::HashIndex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 2033 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; my $op := QAST::Op.new( :op('call'), :$name, $operand-qast ); $op.push(nqp::getattr($SELF, RakuAST::Postcircumfix::HashIndex, '$!index').IMPL-TO-QAST($context)) unless nqp::getattr($SELF, RakuAST::Postcircumfix::HashIndex, '$!index').is-empty; $SELF.IMPL-ADD-COLONPAIRS-TO-OP($context, $op); $op }); add-method(RakuAST::Postcircumfix::HashIndex, 'IMPL-BIND-POSTFIX-QAST', [RakuAST::Postcircumfix::HashIndex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '$operand', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-POSTFIX-QAST ($SELF_CONT, $context!, $operand!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand := nqp::decont($operand); $source-qast := nqp::decont($source-qast); #line 2042 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; my $op := QAST::Op.new( :op('call'), :$name, $operand.IMPL-TO-QAST($context) ); $op.push(nqp::getattr($SELF, RakuAST::Postcircumfix::HashIndex, '$!index').IMPL-TO-QAST($context)) unless nqp::getattr($SELF, RakuAST::Postcircumfix::HashIndex, '$!index').is-empty; $SELF.IMPL-ADD-COLONPAIRS-TO-OP($context, $op); my $bind := $source-qast; $bind.named('BIND'); $op.push($bind); $op }); #line 1998 src/Raku/ast/expressions.rakumod add-method(RakuAST::Postcircumfix::HashIndex, 'index', [], anon sub index ($self) { nqp::getattr(nqp::decont($self), RakuAST::Postcircumfix::HashIndex, '$!index') }); compose(RakuAST::Postcircumfix::HashIndex); parent(RakuAST::Postcircumfix::LiteralHashIndex, RakuAST::Postcircumfix); parent(RakuAST::Postcircumfix::LiteralHashIndex, RakuAST::Lookup); add-attribute(RakuAST::Postcircumfix::LiteralHashIndex, RakuAST::QuotedString, '$!index'); add-attribute(RakuAST::Postcircumfix::LiteralHashIndex, RakuAST::Expression, '$!assignee'); add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'new', [RakuAST::Postcircumfix::LiteralHashIndex, '', 0, 0, RakuAST::QuotedString, '$index', 1, 0, RakuAST::Expression, '$assignee', 1, 1, List, '$colonpairs', 1, 1], anon sub new ($SELF_CONT, :$index!, :$assignee?, :$colonpairs?) { my $SELF := nqp::decont($SELF_CONT); $index := nqp::decont($index); $assignee := nqp::decont($assignee); $colonpairs := nqp::decont($colonpairs); #line 2066 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Postcircumfix::LiteralHashIndex, '$!index', $index); nqp::bindattr($obj, RakuAST::Postcircumfix::LiteralHashIndex, '$!assignee', $assignee // RakuAST::Expression); $obj.set-colonpairs($colonpairs); $obj }); add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'set-assignee', [RakuAST::Postcircumfix::LiteralHashIndex, '', 0, 0, RakuAST::Expression, '$assignee', 0, 0], anon sub set-assignee ($SELF_CONT, $assignee!) { my $SELF := nqp::decont($SELF_CONT); $assignee := nqp::decont($assignee); #line 2074 src/Raku/ast/expressions.rakumod nqp::bindattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!assignee', $assignee); }); add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'can-be-bound-to', [RakuAST::Postcircumfix::LiteralHashIndex, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2078 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'resolve-with', [RakuAST::Postcircumfix::LiteralHashIndex, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 2082 src/Raku/ast/expressions.rakumod my $resolved := $resolver.resolve-lexical('&postcircumfix:<{ }>'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'visit-children', [RakuAST::Postcircumfix::LiteralHashIndex, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2090 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!index')); $visitor(nqp::getattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!assignee')) if nqp::getattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!assignee'); $SELF.visit-colonpairs($visitor); }); add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'default-operator-properties', [RakuAST::Postcircumfix::LiteralHashIndex, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2096 src/Raku/ast/expressions.rakumod OperatorProperties.postcircumfix('< >') }); add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'IMPL-CURRIES', [RakuAST::Postcircumfix::LiteralHashIndex, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2100 src/Raku/ast/expressions.rakumod 3 }); add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'IMPL-POSTFIX-QAST', [RakuAST::Postcircumfix::LiteralHashIndex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 2102 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; my $op := QAST::Op.new( :op('call'), :$name, $operand-qast ); $op.push(nqp::getattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!index').IMPL-TO-QAST($context)) unless nqp::getattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!index').is-empty-words; $op.push(nqp::getattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!assignee').IMPL-TO-QAST($context)) if nqp::getattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!assignee'); $SELF.IMPL-ADD-COLONPAIRS-TO-OP($context, $op); $op }); add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'IMPL-BIND-POSTFIX-QAST', [RakuAST::Postcircumfix::LiteralHashIndex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Expression, '$operand', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-POSTFIX-QAST ($SELF_CONT, $context!, $operand!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand := nqp::decont($operand); $source-qast := nqp::decont($source-qast); #line 2112 src/Raku/ast/expressions.rakumod my $name := $SELF.resolution.lexical-name; my $op := QAST::Op.new( :op('call'), :$name, $operand.IMPL-TO-QAST($context) ); $op.push(nqp::getattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!index').IMPL-TO-QAST($context)) unless nqp::getattr($SELF, RakuAST::Postcircumfix::LiteralHashIndex, '$!index').is-empty-words; $SELF.IMPL-ADD-COLONPAIRS-TO-OP($context, $op); my $bind := $source-qast; $bind.named('BIND'); $op.push($bind); $op }); #line 2059 src/Raku/ast/expressions.rakumod add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'index', [], anon sub index ($self) { nqp::getattr(nqp::decont($self), RakuAST::Postcircumfix::LiteralHashIndex, '$!index') }); #line 2060 src/Raku/ast/expressions.rakumod add-method(RakuAST::Postcircumfix::LiteralHashIndex, 'assignee', [], anon sub assignee ($self) { nqp::getattr(nqp::decont($self), RakuAST::Postcircumfix::LiteralHashIndex, '$!assignee') }); compose(RakuAST::Postcircumfix::LiteralHashIndex); parent(RakuAST::MetaPostfix::Hyper, RakuAST::Postfixish); parent(RakuAST::MetaPostfix::Hyper, RakuAST::CheckTime); add-attribute(RakuAST::MetaPostfix::Hyper, RakuAST::Postfixish, '$!postfix'); add-method(RakuAST::MetaPostfix::Hyper, 'new', [RakuAST::MetaPostfix::Hyper, '', 0, 0, RakuAST::Postfixish, '$postfix', 0, 0], anon sub new ($SELF_CONT, $postfix!) { my $SELF := nqp::decont($SELF_CONT); $postfix := nqp::decont($postfix); #line 2131 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::MetaPostfix::Hyper, '$!postfix', $postfix); # NOTE: can not have colonpairs specified nqp::bindattr($obj, RakuAST::Postfixish, '$!colonpairs', []); $obj }); add-method(RakuAST::MetaPostfix::Hyper, 'PERFORM-CHECK', [RakuAST::MetaPostfix::Hyper, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 2139 src/Raku/ast/expressions.rakumod unless nqp::getattr($SELF, RakuAST::MetaPostfix::Hyper, '$!postfix').can-be-used-with-hyper { $SELF.add-sorry: $resolver.build-exception: 'X::AdHoc', payload => 'Cannot hyper this postfix'; } }); add-method(RakuAST::MetaPostfix::Hyper, 'IMPL-POSTFIX-QAST', [RakuAST::MetaPostfix::Hyper, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 2147 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::MetaPostfix::Hyper, '$!postfix').IMPL-POSTFIX-HYPER-QAST($context, $operand-qast) }); add-method(RakuAST::MetaPostfix::Hyper, 'visit-children', [RakuAST::MetaPostfix::Hyper, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2151 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::MetaPostfix::Hyper, '$!postfix')); $SELF.visit-colonpairs($visitor); }); add-method(RakuAST::MetaPostfix::Hyper, 'default-operator-properties', [RakuAST::MetaPostfix::Hyper, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2156 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::MetaPostfix::Hyper, '$!postfix').properties }); #line 2129 src/Raku/ast/expressions.rakumod add-method(RakuAST::MetaPostfix::Hyper, 'postfix', [], anon sub postfix ($self) { nqp::getattr(nqp::decont($self), RakuAST::MetaPostfix::Hyper, '$!postfix') }); compose(RakuAST::MetaPostfix::Hyper); parent(RakuAST::ApplyPostfix, RakuAST::Termish); parent(RakuAST::ApplyPostfix, RakuAST::BeginTime); parent(RakuAST::ApplyPostfix, RakuAST::WhateverApplicable); add-attribute(RakuAST::ApplyPostfix, RakuAST::Postfixish, '$!postfix'); add-attribute(RakuAST::ApplyPostfix, RakuAST::Expression, '$!operand'); add-method(RakuAST::ApplyPostfix, 'new', [RakuAST::ApplyPostfix, '', 0, 0, RakuAST::Postfixish, '$postfix', 1, 0, RakuAST::Expression, '$operand', 1, 0], anon sub new ($SELF_CONT, :$postfix!, :$operand!) { my $SELF := nqp::decont($SELF_CONT); $postfix := nqp::decont($postfix); $operand := nqp::decont($operand); #line 2170 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ApplyPostfix, '$!postfix', $postfix); if nqp::istype($operand, RakuAST::Circumfix::Parentheses) && $operand.semilist.IMPL-IS-SINGLE-EXPRESSION { my $statement := $SELF.IMPL-UNWRAP-LIST($operand.semilist.code-statements)[0]; $operand := $statement.expression unless $statement.condition-modifier || $statement.loop-modifier; } nqp::bindattr($obj, RakuAST::ApplyPostfix, '$!operand', $operand); $obj }); add-method(RakuAST::ApplyPostfix, 'add-colonpair', [RakuAST::ApplyPostfix, '', 0, 0, RakuAST::ColonPair, '$pair', 0, 0], anon sub add-colonpair ($SELF_CONT, $pair!) { my $SELF := nqp::decont($SELF_CONT); $pair := nqp::decont($pair); #line 2186 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix').add-colonpair($pair); }); add-method(RakuAST::ApplyPostfix, 'operands', [RakuAST::ApplyPostfix, '', 0, 0], anon sub operands ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2190 src/Raku/ast/expressions.rakumod [nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!operand')] }); add-method(RakuAST::ApplyPostfix, 'operator', [RakuAST::ApplyPostfix, '', 0, 0], anon sub operator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2191 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix') }); add-method(RakuAST::ApplyPostfix, 'can-be-bound-to', [RakuAST::ApplyPostfix, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2193 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix').can-be-bound-to }); add-method(RakuAST::ApplyPostfix, 'on-topic', [RakuAST::ApplyPostfix, '', 0, 0], anon sub on-topic ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2197 src/Raku/ast/expressions.rakumod nqp::istype(nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!operand'),RakuAST::Var::Lexical) && nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!operand').name eq '$_' }); add-method(RakuAST::ApplyPostfix, 'is-begin-performed-before-children', [RakuAST::ApplyPostfix, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2201 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::ApplyPostfix, 'is-begin-performed-after-children', [RakuAST::ApplyPostfix, '', 0, 0], anon sub is-begin-performed-after-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2202 src/Raku/ast/expressions.rakumod (Bool.WHO) }); add-method(RakuAST::ApplyPostfix, 'PERFORM-BEGIN-BEFORE-CHILDREN', [RakuAST::ApplyPostfix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-BEFORE-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 2204 src/Raku/ast/expressions.rakumod if $SELF.IMPL-SHOULD-CURRY-DIRECTLY { nqp::bindattr($SELF, RakuAST::ApplyPostfix, '$!operand', $SELF.IMPL-CURRY.IMPL-ADD-PARAM($resolver, $context).target.generate-lookup); } }); add-method(RakuAST::ApplyPostfix, 'PERFORM-BEGIN-AFTER-CHILDREN', [RakuAST::ApplyPostfix, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-AFTER-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 2211 src/Raku/ast/expressions.rakumod my $operand := nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!operand'); # This should only really happens in special circumstances, such as (* ~ *).uc. if nqp::bitand_i(nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix').IMPL-CURRIES, 2) { if $operand.IMPL-CURRIED { my $params := $operand.IMPL-UNCURRY; if nqp::elems($params) > 0 { my $curried := $SELF.IMPL-CURRY; for $params { $curried.IMPL-ADD-PARAM($resolver, $context, :name($_.target.lexical-name)); } } } } }); add-method(RakuAST::ApplyPostfix, 'IMPL-EXPR-QAST', [RakuAST::ApplyPostfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2227 src/Raku/ast/expressions.rakumod my $postfix-ast := nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix').IMPL-POSTFIX-QAST($context, nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!operand').IMPL-TO-QAST($context)); # Method calls may be to a foreign language, and thus return # values may need type mapping into Raku land. nqp::istype(nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix'), RakuAST::Call::Methodish) ?? QAST::Op.new(:op, $postfix-ast) !! $postfix-ast }); add-method(RakuAST::ApplyPostfix, 'IMPL-BIND-QAST', [RakuAST::ApplyPostfix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 2236 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix').IMPL-BIND-POSTFIX-QAST($context, nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!operand'), $source-qast) }); add-method(RakuAST::ApplyPostfix, 'visit-children', [RakuAST::ApplyPostfix, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2240 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!operand')); $visitor(nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix')); }); add-method(RakuAST::ApplyPostfix, 'IMPL-CAN-INTERPRET', [RakuAST::ApplyPostfix, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2245 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!operand').IMPL-CAN-INTERPRET && nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix').IMPL-CAN-INTERPRET }); add-method(RakuAST::ApplyPostfix, 'IMPL-INTERPRET', [RakuAST::ApplyPostfix, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 2247 src/Raku/ast/expressions.rakumod nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!postfix').IMPL-INTERPRET($ctx, -> { nqp::getattr($SELF, RakuAST::ApplyPostfix, '$!operand').IMPL-INTERPRET($ctx) }) }); #line 2167 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyPostfix, 'postfix', [], anon sub postfix ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyPostfix, '$!postfix') }); #line 2168 src/Raku/ast/expressions.rakumod add-method(RakuAST::ApplyPostfix, 'operand', [], anon sub operand ($self) { nqp::getattr(nqp::decont($self), RakuAST::ApplyPostfix, '$!operand') }); compose(RakuAST::ApplyPostfix); parent(RakuAST::Ternary, RakuAST::Expression); add-attribute(RakuAST::Ternary, RakuAST::Expression, '$!condition'); add-attribute(RakuAST::Ternary, RakuAST::Expression, '$!then'); add-attribute(RakuAST::Ternary, RakuAST::Expression, '$!else'); add-method(RakuAST::Ternary, 'new', [RakuAST::Ternary, '', 0, 0, RakuAST::Expression, '$condition', 1, 0, RakuAST::Expression, '$then', 1, 0, RakuAST::Expression, '$else', 1, 0], anon sub new ($SELF_CONT, :$condition!, :$then!, :$else!) { my $SELF := nqp::decont($SELF_CONT); $condition := nqp::decont($condition); $then := nqp::decont($then); $else := nqp::decont($else); #line 2264 src/Raku/ast/expressions.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Ternary, '$!condition', $condition); nqp::bindattr($obj, RakuAST::Ternary, '$!then', $then); nqp::bindattr($obj, RakuAST::Ternary, '$!else', $else); $obj }); add-method(RakuAST::Ternary, 'IMPL-EXPR-QAST', [RakuAST::Ternary, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2272 src/Raku/ast/expressions.rakumod QAST::Op.new( :op('if'), nqp::getattr($SELF, RakuAST::Ternary, '$!condition').IMPL-TO-QAST($context), nqp::getattr($SELF, RakuAST::Ternary, '$!then').IMPL-TO-QAST($context), nqp::getattr($SELF, RakuAST::Ternary, '$!else').IMPL-TO-QAST($context), ) }); add-method(RakuAST::Ternary, 'visit-children', [RakuAST::Ternary, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2281 src/Raku/ast/expressions.rakumod $visitor(nqp::getattr($SELF, RakuAST::Ternary, '$!condition')); $visitor(nqp::getattr($SELF, RakuAST::Ternary, '$!then')); $visitor(nqp::getattr($SELF, RakuAST::Ternary, '$!else')); }); add-method(RakuAST::Ternary, 'properties', [RakuAST::Ternary, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2287 src/Raku/ast/expressions.rakumod OperatorProperties.infix('?? !!') }); #line 2260 src/Raku/ast/expressions.rakumod add-method(RakuAST::Ternary, 'then', [], anon sub then ($self) { nqp::getattr(nqp::decont($self), RakuAST::Ternary, '$!then') }); #line 2261 src/Raku/ast/expressions.rakumod add-method(RakuAST::Ternary, 'else', [], anon sub else ($self) { nqp::getattr(nqp::decont($self), RakuAST::Ternary, '$!else') }); #line 2259 src/Raku/ast/expressions.rakumod add-method(RakuAST::Ternary, 'condition', [], anon sub condition ($self) { nqp::getattr(nqp::decont($self), RakuAST::Ternary, '$!condition') }); compose(RakuAST::Ternary); parent(RakuAST::Pragma, RakuAST::Statement); parent(RakuAST::Pragma, RakuAST::BeginTime); parent(RakuAST::Pragma, RakuAST::ProducesNil); add-attribute(RakuAST::Pragma, Str, '$!name'); add-attribute(RakuAST::Pragma, RakuAST::Expression, '$!argument'); add-attribute(RakuAST::Pragma, int, '$!off'); add-method(RakuAST::Pragma, 'new', [RakuAST::Pragma, '', 0, 0, Str, '$name', 1, 0, RakuAST::Expression, '$argument', 1, 1, Any, '$off', 1, 1], anon sub new ($SELF_CONT, :$name!, :$argument?, :$off?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $argument := nqp::decont($argument); $off := nqp::decont($off); #line 10 src/Raku/ast/pragma.rakumod my $obj := nqp::create($SELF); nqp::bindattr( $obj, RakuAST::Pragma, '$!name', $name // ""); nqp::bindattr( $obj, RakuAST::Pragma, '$!argument', $argument // RakuAST::Expression); nqp::bindattr_i($obj, RakuAST::Pragma, '$!off', $off ?? 1 !! 0); $obj }); add-method(RakuAST::Pragma, 'IS-NYI', [RakuAST::Pragma, '', 0, 0, Str, '$name', 0, 0], anon sub IS-NYI ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 19 src/Raku/ast/pragma.rakumod my constant NYI-PRAGMAS := nqp::hash( 'internals', 1, 'invocant', 1, 'parameters', 1, ); nqp::existskey(NYI-PRAGMAS, $name) }); add-method(RakuAST::Pragma, 'KNOWN-PRAGMAS', [RakuAST::Pragma, '', 0, 0], anon sub KNOWN-PRAGMAS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 29 src/Raku/ast/pragma.rakumod # 0 means specific handling required, 1 means just (un)set pragma # by that name my constant KNOWN-PRAGMAS := nqp::hash( 'attributes', 0, 'dynamic-scope', 0, 'fatal', 1, 'internals', 1, 'invocant', 0, 'isms', 0, 'lib', 0, 'MONKEY', 0, # 'MONKEY-BARS', 1, # 'MONKEY-BRAINS', 1, # 'MONKEY-BUSINESS', 1, 'MONKEY-GUTS', 1, 'MONKEY-SEE-NO-EVAL', 1, # 'MONKEY-SHINE', 1, # 'MONKEY-TRAP', 1, 'MONKEY-TYPING', 1, # 'MONKEY-WRENCH', 1, 'nqp', 1, 'parameters', 0, 'precompilation', 0, 'soft', 0, 'strict', 1, 'trace', 1, 'variables', 0, 'worries', 1, ); }); add-method(RakuAST::Pragma, 'IS-PRAGMA', [RakuAST::Pragma, '', 0, 0, Str, '$name', 0, 0], anon sub IS-PRAGMA ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 61 src/Raku/ast/pragma.rakumod nqp::existskey($SELF.KNOWN-PRAGMAS, $name) }); add-method(RakuAST::Pragma, 'KNOWN-ISMS', [RakuAST::Pragma, '', 0, 0], anon sub KNOWN-ISMS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 65 src/Raku/ast/pragma.rakumod my constant ISMS := nqp::hash( 'Perl5', 'p5isms', 'C++', 'c++isms', ) }); add-method(RakuAST::Pragma, 'IS-ISM', [RakuAST::Pragma, '', 0, 0, Str, '$name', 0, 0], anon sub IS-ISM ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 72 src/Raku/ast/pragma.rakumod nqp::existskey($SELF.KNOWN-ISMS, $name) }); add-method(RakuAST::Pragma, 'PERFORM-BEGIN', [RakuAST::Pragma, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 79 src/Raku/ast/pragma.rakumod my $name := nqp::getattr($SELF, RakuAST::Pragma, '$!name'); my $LANG := $*LANG; my int $on := nqp::not_i(nqp::getattr_i($SELF, RakuAST::Pragma, '$!off')); my $arglist := nqp::getattr($SELF, RakuAST::Pragma, '$!argument') ?? $SELF.IMPL-BEGIN-TIME-EVALUATE( nqp::getattr($SELF, RakuAST::Pragma, '$!argument'), $resolver, $context ).List.FLATTENABLE_LIST !! Nil; if $SELF.IS-NYI($name) { $resolver.build-exception( 'X::NYI', :feature(($on ?? 'use' !! 'no') ~ " $name"), ).throw; } elsif $SELF.KNOWN-PRAGMAS{$name} { nqp::islist($arglist) ?? $resolver.build-exception('X::Pragma::NoArgs', :$name).throw !! $LANG.set_pragma($name eq 'nqp' ?? 'MONKEY-GUTS' !! $name, $on) } elsif $name eq 'MONKEY' { $LANG.set_pragma($_.key, $on) if nqp::eqat($_.key,'MONKEY',0) for $SELF.KNOWN-PRAGMAS; } elsif $name eq 'lib' { if nqp::getattr_i($SELF, RakuAST::Pragma, '$!off') { $resolver.build-exception( 'X::Pragma::CannotWhat', :what, :$name ).throw; } elsif try $*CU.precompilation-mode { $resolver.build-exception( 'X::Pragma::CannotPrecomp', :what("'use lib'") ).throw; } elsif $*PKGDECL { $resolver.build-exception('X::Package::UseLib', :what($*PKGDECL)); } elsif nqp::islist($arglist) { my $Registry := $resolver.resolve-name-constant( RakuAST::Name.from-identifier-parts( 'CompUnit', 'RepositoryRegistry' ) ).compile-time-value; my $IO-Path := $resolver.resolve-name-constant( RakuAST::Name.from-identifier-parts('IO', 'Path') ).compile-time-value; for $arglist -> $arg { if $arg { $Registry.use-repository($Registry.repository-for-spec( nqp::istype($arg,$IO-Path) ?? $arg.absolute !! $arg )); } else { $resolver.build-exception('X::LibEmpty').throw; } } } else { $resolver.build-exception('X::LibNone').throw; } } elsif $name eq 'precompilation' { if nqp::getattr_i($SELF, RakuAST::Pragma, '$!off') && $*CU.precompilation-mode { nqp::ifnull( nqp::atkey(nqp::getenvhash, 'RAKUDO_PRECOMP_WITH'), 0 ) ?? nqp::exit(0) !! $resolver.build-exception( 'X::Pragma::CannotPrecomp', :what, :$name ).throw; } } elsif $name eq 'isms' { if nqp::islist($arglist) { for $arglist -> $ism { (my $pragma := $SELF.KNOWN-ISMS{$ism}) ?? $LANG.set_pragma($pragma, $on) !! $resolver.build-exception( "X::Ism::Unknown", :name($ism) ).throw; } } else { $LANG.set_pragma($_.value, $on) for $SELF.KNOWN-ISMS; } } elsif $name eq 'soft' { nqp::islist($arglist) ?? $resolver.build-exception( 'X::NYI', :feature("Arguments to '{$on ?? 'use' !! 'no' } soft'"), ).throw !! $LANG.set_pragma($name, $on); } elsif $name eq 'attributes' || $name eq 'invocant' || $name eq 'parameters' || $name eq 'variables' { $resolver.build-exception( 'X::Pragma::CannotWhat', :what, :$name ).throw unless $on; $resolver.build-exception( 'X::Pragma::MustOneOf', :$name, :alternatives(':D, :U or :_') ).throw unless $arglist; my $Pair := $resolver.resolve-name-constant( RakuAST::Name.from-identifier('Pair') ); my $Bool := $resolver.resolve-name-constant( RakuAST::Name.from-identifier('Bool') ); my $type; for $arglist -> $arg { if $type { $resolver.build-exception( 'X::Pragma::OnlyOne', :$name ).throw; } elsif nqp::istype($arg,$Pair) { my $value := $arg.value; if nqp::istype($value,$Bool) && $value { $type := $arg.key; if $type eq 'D' || $type eq 'U' { $LANG.set_pragma($name, $type); next; } elsif $type eq '_' { # XXX shouldn't know this nqp::deletekey($*LANG.slangs,$name); next; } } $resolver.build-exception( 'X::InvalidTypeSmiley', :name($arg.key) ).throw; } $resolver.build-exception( 'X::Pragma::UnknownArg', :$name, :$arg ).throw; } } elsif $name eq 'dynamic-scope' { if nqp::islist($arglist) && nqp::elems($arglist) { # Just some variables. my %dyn; for $arglist { %dyn{$_} := 1; } $LANG.set_pragma('dynamic-scope', sub ($var) { %dyn{$var} || 0 }); } else { # All variables. $LANG.set_pragma('dynamic-scope', sub ($var) { 1 }); } } else { $resolver.build-exception("X::Pragma::Unknown",:$name).throw; } }); #line 8 src/Raku/ast/pragma.rakumod add-method(RakuAST::Pragma, 'off', [], anon sub off ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Pragma, '$!off') }); #line 6 src/Raku/ast/pragma.rakumod add-method(RakuAST::Pragma, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Pragma, '$!name') }); #line 7 src/Raku/ast/pragma.rakumod add-method(RakuAST::Pragma, 'argument', [], anon sub argument ($self) { nqp::getattr(nqp::decont($self), RakuAST::Pragma, '$!argument') }); compose(RakuAST::Pragma); parent(RakuAST::NamedArg, RakuAST::Node); add-method(RakuAST::NamedArg, 'named-arg-name', [RakuAST::NamedArg, '', 0, 0], anon sub named-arg-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 5 src/Raku/ast/pair.rakumod nqp::die('named-arg-name not implemented') }); add-method(RakuAST::NamedArg, 'named-arg-value', [RakuAST::NamedArg, '', 0, 0], anon sub named-arg-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 6 src/Raku/ast/pair.rakumod nqp::die('named-arg-value not implemented') }); compose(RakuAST::NamedArg); parent(RakuAST::FatArrow, RakuAST::Term); parent(RakuAST::FatArrow, RakuAST::ImplicitLookups); parent(RakuAST::FatArrow, RakuAST::NamedArg); add-attribute(RakuAST::FatArrow, Str, '$!key'); add-attribute(RakuAST::FatArrow, RakuAST::Term, '$!value'); add-method(RakuAST::FatArrow, 'new', [RakuAST::FatArrow, '', 0, 0, Str, '$key', 1, 0, RakuAST::Term, '$value', 1, 0], anon sub new ($SELF_CONT, :$key!, :$value!) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); $value := nqp::decont($value); #line 18 src/Raku/ast/pair.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::FatArrow, '$!key', $key); nqp::bindattr($obj, RakuAST::FatArrow, '$!value', $value); $obj }); add-method(RakuAST::FatArrow, 'set-key', [RakuAST::FatArrow, '', 0, 0, Str, '$key', 0, 0], anon sub set-key ($SELF_CONT, $key!) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); #line 25 src/Raku/ast/pair.rakumod nqp::bindattr($SELF, RakuAST::FatArrow, '$!key', $key); }); add-method(RakuAST::FatArrow, 'named-arg-name', [RakuAST::FatArrow, '', 0, 0], anon sub named-arg-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 29 src/Raku/ast/pair.rakumod nqp::getattr($SELF, RakuAST::FatArrow, '$!key') }); add-method(RakuAST::FatArrow, 'named-arg-value', [RakuAST::FatArrow, '', 0, 0], anon sub named-arg-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 31 src/Raku/ast/pair.rakumod nqp::getattr($SELF, RakuAST::FatArrow, '$!value') }); add-method(RakuAST::FatArrow, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::FatArrow, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 33 src/Raku/ast/pair.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Pair')), ]) }); add-method(RakuAST::FatArrow, 'IMPL-EXPR-QAST', [RakuAST::FatArrow, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 39 src/Raku/ast/pair.rakumod my $pair-type := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; my $key := nqp::getattr($SELF, RakuAST::FatArrow, '$!key'); $context.ensure-sc($key); QAST::Op.new( :op('callmethod'), :name('new'), QAST::WVal.new( :value($pair-type) ), QAST::WVal.new( :value($key) ), nqp::getattr($SELF, RakuAST::FatArrow, '$!value').IMPL-TO-QAST($context) ) }); add-method(RakuAST::FatArrow, 'visit-children', [RakuAST::FatArrow, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 52 src/Raku/ast/pair.rakumod $visitor(nqp::getattr($SELF, RakuAST::FatArrow, '$!value')); }); #line 16 src/Raku/ast/pair.rakumod add-method(RakuAST::FatArrow, 'value', [], anon sub value ($self) { nqp::getattr(nqp::decont($self), RakuAST::FatArrow, '$!value') }); #line 15 src/Raku/ast/pair.rakumod add-method(RakuAST::FatArrow, 'key', [], anon sub key ($self) { nqp::getattr(nqp::decont($self), RakuAST::FatArrow, '$!key') }); compose(RakuAST::FatArrow); parent(RakuAST::ColonPairish, Any); add-method(RakuAST::ColonPairish, 'IMPL-QUOTE-VALUE', [RakuAST::ColonPairish, '', 0, 0, Any, '$v', 0, 0], anon sub IMPL-QUOTE-VALUE ($SELF_CONT, $v!) { my $SELF := nqp::decont($SELF_CONT); $v := nqp::decont($v); #line 59 src/Raku/ast/pair.rakumod if $v ~~ /<[ < > ]>/ && !($v ~~ /<[ « » $ \\ " ' ]>/) { '«' ~ $v ~ '»' } else { my $new := ''; my int $e := nqp::chars($v); my int $i := -1; while ++$i < $e { my $ch := nqp::substr($v,$i,1); $new := $new ~ '\\' if $ch eq '<' || $ch eq '>'; $new := $new ~ $ch; } '<' ~ $new ~ '>'; } }); compose(RakuAST::ColonPairish); parent(RakuAST::ColonPair, RakuAST::ColonPairish); parent(RakuAST::ColonPair, RakuAST::Term); parent(RakuAST::ColonPair, RakuAST::ImplicitLookups); parent(RakuAST::ColonPair, RakuAST::NamedArg); add-attribute(RakuAST::ColonPair, Str, '$!key'); add-method(RakuAST::ColonPair, 'value', [RakuAST::ColonPair, '', 0, 0], anon sub value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 86 src/Raku/ast/pair.rakumod nqp::die($SELF.HOW.name($SELF) ~ ' does not implement value') }); add-method(RakuAST::ColonPair, 'set-key', [RakuAST::ColonPair, '', 0, 0, Str, '$key', 0, 0], anon sub set-key ($SELF_CONT, $key!) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); #line 88 src/Raku/ast/pair.rakumod nqp::bindattr($SELF, RakuAST::ColonPair, '$!key', $key); }); add-method(RakuAST::ColonPair, 'named-arg-name', [RakuAST::ColonPair, '', 0, 0], anon sub named-arg-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 92 src/Raku/ast/pair.rakumod nqp::getattr($SELF, RakuAST::ColonPair, '$!key') }); add-method(RakuAST::ColonPair, 'named-arg-value', [RakuAST::ColonPair, '', 0, 0], anon sub named-arg-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 94 src/Raku/ast/pair.rakumod $SELF.value }); add-method(RakuAST::ColonPair, 'properties', [RakuAST::ColonPair, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 96 src/Raku/ast/pair.rakumod OperatorProperties.postfix(':') }); add-method(RakuAST::ColonPair, 'canonicalize', [RakuAST::ColonPair, '', 0, 0], anon sub canonicalize ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 98 src/Raku/ast/pair.rakumod my $value := $SELF.simple-compile-time-quote-value; $value := $SELF.value.IMPL-INTERPRET(RakuAST::IMPL::InterpContext.new) if !$value && $SELF.value.IMPL-CAN-INTERPRET; nqp::getattr($SELF, RakuAST::ColonPair, '$!key') ~ ($value ?? $SELF.IMPL-QUOTE-VALUE($value) !! $SELF.value.DEPARSE) }); add-method(RakuAST::ColonPair, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::ColonPair, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 105 src/Raku/ast/pair.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Pair')), ]) }); add-method(RakuAST::ColonPair, 'IMPL-EXPR-QAST', [RakuAST::ColonPair, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 111 src/Raku/ast/pair.rakumod my $pair-type := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; my $key := nqp::getattr($SELF, RakuAST::ColonPair, '$!key'); $context.ensure-sc($key); QAST::Op.new( :op('callmethod'), :name('new'), QAST::WVal.new( :value($pair-type) ), QAST::WVal.new( :value($key) ), $SELF.IMPL-VALUE-QAST($context) ) }); add-method(RakuAST::ColonPair, 'IMPL-VALUE-QAST', [RakuAST::ColonPair, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-VALUE-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 124 src/Raku/ast/pair.rakumod $SELF.value.IMPL-TO-QAST($context) }); #line 84 src/Raku/ast/pair.rakumod add-method(RakuAST::ColonPair, 'key', [], anon sub key ($self) { nqp::getattr(nqp::decont($self), RakuAST::ColonPair, '$!key') }); compose(RakuAST::ColonPair); parent(RakuAST::ColonPairs, RakuAST::Node); add-attribute(RakuAST::ColonPairs, Mu, '$!colonpairs'); add-method(RakuAST::ColonPairs, 'new', [RakuAST::ColonPairs, '', 0, 0, Any, '$a', 0, 0, Any, '$b', 0, 0], anon sub new ($SELF_CONT, $a!, $b!) { my $SELF := nqp::decont($SELF_CONT); $a := nqp::decont($a); $b := nqp::decont($b); #line 136 src/Raku/ast/pair.rakumod my $obj := nqp::create($SELF); if nqp::istype($a, RakuAST::ColonPairs) { nqp::bindattr($obj, RakuAST::ColonPairs, '$!colonpairs', $a.colonpairs); } else { nqp::bindattr($obj, RakuAST::ColonPairs, '$!colonpairs', [$a]); } nqp::push($obj.colonpairs, $b); $obj }); #line 134 src/Raku/ast/pair.rakumod add-method(RakuAST::ColonPairs, 'colonpairs', [], anon sub colonpairs ($self) { nqp::getattr(nqp::decont($self), RakuAST::ColonPairs, '$!colonpairs') }); compose(RakuAST::ColonPairs); parent(RakuAST::QuotePair, RakuAST::ColonPair); compose(RakuAST::QuotePair); parent(RakuAST::ColonPair::True, RakuAST::QuotePair); add-method(RakuAST::ColonPair::True, 'new', [RakuAST::ColonPair::True, '', 0, 0, Str, '$key', 0, 0], anon sub new ($SELF_CONT, $key!) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); #line 157 src/Raku/ast/pair.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ColonPair, '$!key', $key); $obj }); add-method(RakuAST::ColonPair::True, 'canonicalize', [RakuAST::ColonPair::True, '', 0, 0], anon sub canonicalize ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 163 src/Raku/ast/pair.rakumod nqp::getattr($SELF, RakuAST::ColonPair, '$!key') }); add-method(RakuAST::ColonPair::True, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::ColonPair::True, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 167 src/Raku/ast/pair.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Pair')) ]) }); add-method(RakuAST::ColonPair::True, 'value', [RakuAST::ColonPair::True, '', 0, 0], anon sub value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 173 src/Raku/ast/pair.rakumod RakuAST::Declaration::ResolvedConstant.new(compile-time-value => (Bool.WHO)) }); add-method(RakuAST::ColonPair::True, 'simple-compile-time-quote-value', [RakuAST::ColonPair::True, '', 0, 0], anon sub simple-compile-time-quote-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 177 src/Raku/ast/pair.rakumod (Bool.WHO) }); add-method(RakuAST::ColonPair::True, 'IMPL-VALUE-QAST', [RakuAST::ColonPair::True, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-VALUE-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 179 src/Raku/ast/pair.rakumod my $value := (Bool.WHO); $context.ensure-sc($value); QAST::WVal.new( :$value ) }); add-method(RakuAST::ColonPair::True, 'IMPL-CAN-INTERPRET', [RakuAST::ColonPair::True, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 185 src/Raku/ast/pair.rakumod (Bool.WHO) }); add-method(RakuAST::ColonPair::True, 'IMPL-INTERPRET', [RakuAST::ColonPair::True, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 187 src/Raku/ast/pair.rakumod $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value.new( $SELF.key, (Bool.WHO) ) }); compose(RakuAST::ColonPair::True); parent(RakuAST::ColonPair::False, RakuAST::QuotePair); add-method(RakuAST::ColonPair::False, 'new', [RakuAST::ColonPair::False, '', 0, 0, Str, '$key', 0, 0], anon sub new ($SELF_CONT, $key!) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); #line 198 src/Raku/ast/pair.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ColonPair, '$!key', $key); $obj }); add-method(RakuAST::ColonPair::False, 'canonicalize', [RakuAST::ColonPair::False, '', 0, 0], anon sub canonicalize ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 204 src/Raku/ast/pair.rakumod "!" ~ nqp::getattr($SELF, RakuAST::ColonPair, '$!key') }); add-method(RakuAST::ColonPair::False, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::ColonPair::False, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 208 src/Raku/ast/pair.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Pair')) ]) }); add-method(RakuAST::ColonPair::False, 'value', [RakuAST::ColonPair::False, '', 0, 0], anon sub value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 214 src/Raku/ast/pair.rakumod RakuAST::Declaration::ResolvedConstant.new(compile-time-value => (Bool.WHO)) }); add-method(RakuAST::ColonPair::False, 'simple-compile-time-quote-value', [RakuAST::ColonPair::False, '', 0, 0], anon sub simple-compile-time-quote-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 218 src/Raku/ast/pair.rakumod (Bool.WHO) }); add-method(RakuAST::ColonPair::False, 'IMPL-VALUE-QAST', [RakuAST::ColonPair::False, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-VALUE-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 220 src/Raku/ast/pair.rakumod my $value := (Bool.WHO); $context.ensure-sc($value); QAST::WVal.new( :$value ) }); add-method(RakuAST::ColonPair::False, 'IMPL-CAN-INTERPRET', [RakuAST::ColonPair::False, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 226 src/Raku/ast/pair.rakumod (Bool.WHO) }); add-method(RakuAST::ColonPair::False, 'IMPL-INTERPRET', [RakuAST::ColonPair::False, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 228 src/Raku/ast/pair.rakumod $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value.new( $SELF.key, (Bool.WHO) ) }); compose(RakuAST::ColonPair::False); parent(RakuAST::ColonPair::Number, RakuAST::QuotePair); add-attribute(RakuAST::ColonPair::Number, RakuAST::IntLiteral, '$!value'); add-method(RakuAST::ColonPair::Number, 'new', [RakuAST::ColonPair::Number, '', 0, 0, Str, '$key', 1, 0, RakuAST::IntLiteral, '$value', 1, 1], anon sub new ($SELF_CONT, :$key!, :$value?) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); $value := nqp::decont($value); #line 241 src/Raku/ast/pair.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ColonPair, '$!key', $key); nqp::bindattr($obj, RakuAST::ColonPair::Number, '$!value', $value); $obj }); add-method(RakuAST::ColonPair::Number, 'simple-compile-time-quote-value', [RakuAST::ColonPair::Number, '', 0, 0], anon sub simple-compile-time-quote-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 248 src/Raku/ast/pair.rakumod nqp::getattr($SELF, RakuAST::ColonPair::Number, '$!value').value }); add-method(RakuAST::ColonPair::Number, 'visit-children', [RakuAST::ColonPair::Number, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 250 src/Raku/ast/pair.rakumod $visitor(nqp::getattr($SELF, RakuAST::ColonPair::Number, '$!value')); }); add-method(RakuAST::ColonPair::Number, 'IMPL-CAN-INTERPRET', [RakuAST::ColonPair::Number, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 254 src/Raku/ast/pair.rakumod (Bool.WHO) }); add-method(RakuAST::ColonPair::Number, 'IMPL-INTERPRET', [RakuAST::ColonPair::Number, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 256 src/Raku/ast/pair.rakumod $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value.new( $SELF.key, nqp::getattr($SELF, RakuAST::ColonPair::Number, '$!value') ) }); #line 239 src/Raku/ast/pair.rakumod add-method(RakuAST::ColonPair::Number, 'value', [], anon sub value ($self) { nqp::getattr(nqp::decont($self), RakuAST::ColonPair::Number, '$!value') }); compose(RakuAST::ColonPair::Number); parent(RakuAST::ColonPair::Value, RakuAST::QuotePair); add-attribute(RakuAST::ColonPair::Value, RakuAST::Expression, '$!value'); add-method(RakuAST::ColonPair::Value, 'new', [RakuAST::ColonPair::Value, '', 0, 0, Str, '$key', 1, 0, RakuAST::Expression, '$value', 1, 0], anon sub new ($SELF_CONT, :$key!, :$value!) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); $value := nqp::decont($value); #line 269 src/Raku/ast/pair.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ColonPair, '$!key', $key); nqp::bindattr($obj, RakuAST::ColonPair::Value, '$!value', $value); $obj }); add-method(RakuAST::ColonPair::Value, 'visit-children', [RakuAST::ColonPair::Value, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 276 src/Raku/ast/pair.rakumod $visitor(nqp::getattr($SELF, RakuAST::ColonPair::Value, '$!value')); }); add-method(RakuAST::ColonPair::Value, 'simple-compile-time-quote-value', [RakuAST::ColonPair::Value, '', 0, 0], anon sub simple-compile-time-quote-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 280 src/Raku/ast/pair.rakumod # TODO various cases we can handle here if nqp::istype($SELF.value, RakuAST::QuotedString) { $SELF.value.literal-value } else { Nil } }); add-method(RakuAST::ColonPair::Value, 'IMPL-CAN-INTERPRET', [RakuAST::ColonPair::Value, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 290 src/Raku/ast/pair.rakumod nqp::getattr($SELF, RakuAST::ColonPair::Value, '$!value').IMPL-CAN-INTERPRET }); add-method(RakuAST::ColonPair::Value, 'IMPL-INTERPRET', [RakuAST::ColonPair::Value, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 292 src/Raku/ast/pair.rakumod $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value.new( $SELF.key, nqp::getattr($SELF, RakuAST::ColonPair::Value, '$!value').IMPL-INTERPRET($ctx) ) }); #line 267 src/Raku/ast/pair.rakumod add-method(RakuAST::ColonPair::Value, 'value', [], anon sub value ($self) { nqp::getattr(nqp::decont($self), RakuAST::ColonPair::Value, '$!value') }); compose(RakuAST::ColonPair::Value); parent(RakuAST::ColonPair::Variable, RakuAST::ColonPair); add-attribute(RakuAST::ColonPair::Variable, RakuAST::Var, '$!value'); add-method(RakuAST::ColonPair::Variable, 'new', [RakuAST::ColonPair::Variable, '', 0, 0, Str, '$key', 1, 0, RakuAST::Var, '$value', 1, 1], anon sub new ($SELF_CONT, :$key!, :$value?) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); $value := nqp::decont($value); #line 305 src/Raku/ast/pair.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ColonPair, '$!key', $key); nqp::bindattr($obj, RakuAST::ColonPair::Variable, '$!value', $value); $obj }); add-method(RakuAST::ColonPair::Variable, 'visit-children', [RakuAST::ColonPair::Variable, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 312 src/Raku/ast/pair.rakumod $visitor(nqp::getattr($SELF, RakuAST::ColonPair::Variable, '$!value')); }); #line 303 src/Raku/ast/pair.rakumod add-method(RakuAST::ColonPair::Variable, 'value', [], anon sub value ($self) { nqp::getattr(nqp::decont($self), RakuAST::ColonPair::Variable, '$!value') }); compose(RakuAST::ColonPair::Variable); parent(RakuAST::Circumfix, RakuAST::Term); parent(RakuAST::Circumfix, RakuAST::Contextualizable); compose(RakuAST::Circumfix); parent(RakuAST::Circumfix::Parentheses, RakuAST::Circumfix); add-attribute(RakuAST::Circumfix::Parentheses, RakuAST::SemiList, '$!semilist'); add-method(RakuAST::Circumfix::Parentheses, 'new', [RakuAST::Circumfix::Parentheses, '', 0, 0, RakuAST::SemiList, '$semilist', 0, 0], anon sub new ($SELF_CONT, $semilist!) { my $SELF := nqp::decont($SELF_CONT); $semilist := nqp::decont($semilist); #line 12 src/Raku/ast/circumfix.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Circumfix::Parentheses, '$!semilist', $semilist); $obj }); add-method(RakuAST::Circumfix::Parentheses, 'IMPL-CONTAINS-SINGULAR-CURRYABLE-EXPRESSION', [RakuAST::Circumfix::Parentheses, '', 0, 0], anon sub IMPL-CONTAINS-SINGULAR-CURRYABLE-EXPRESSION ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 22 src/Raku/ast/circumfix.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist').IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist').statements)) == 1 && (my $statement-expression := nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist').statements.AT-POS(0)) && nqp::istype($statement-expression, RakuAST::Statement::Expression) && (my $expression := $statement-expression.expression) && nqp::istype($expression, RakuAST::WhateverApplicable) && $expression.IMPL-SHOULD-CURRY-DIRECTLY ?? $expression !! Nil }); add-method(RakuAST::Circumfix::Parentheses, 'IMPL-SINGULAR-CURRIED-EXPRESSION', [RakuAST::Circumfix::Parentheses, '', 0, 0], anon sub IMPL-SINGULAR-CURRIED-EXPRESSION ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 33 src/Raku/ast/circumfix.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist').IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist').statements)) == 1 && (my $statement-expression := nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist').statements.AT-POS(0)) && nqp::istype($statement-expression, RakuAST::Statement::Expression) && (my $expression := $statement-expression.expression) && nqp::istype($expression, RakuAST::WhateverApplicable) && $expression.IMPL-CURRIED ?? $expression !! Nil }); add-method(RakuAST::Circumfix::Parentheses, 'IMPL-EXPR-QAST', [RakuAST::Circumfix::Parentheses, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 44 src/Raku/ast/circumfix.rakumod nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist').IMPL-TO-QAST($context) }); add-method(RakuAST::Circumfix::Parentheses, 'visit-children', [RakuAST::Circumfix::Parentheses, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 48 src/Raku/ast/circumfix.rakumod $visitor(nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist')); }); add-method(RakuAST::Circumfix::Parentheses, 'IMPL-CAN-INTERPRET', [RakuAST::Circumfix::Parentheses, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 52 src/Raku/ast/circumfix.rakumod nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist').IMPL-CAN-INTERPRET }); add-method(RakuAST::Circumfix::Parentheses, 'IMPL-INTERPRET', [RakuAST::Circumfix::Parentheses, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 56 src/Raku/ast/circumfix.rakumod nqp::getattr($SELF, RakuAST::Circumfix::Parentheses, '$!semilist').IMPL-INTERPRET($ctx) }); #line 10 src/Raku/ast/circumfix.rakumod add-method(RakuAST::Circumfix::Parentheses, 'semilist', [], anon sub semilist ($self) { nqp::getattr(nqp::decont($self), RakuAST::Circumfix::Parentheses, '$!semilist') }); compose(RakuAST::Circumfix::Parentheses); parent(RakuAST::Circumfix::ArrayComposer, RakuAST::Circumfix); parent(RakuAST::Circumfix::ArrayComposer, RakuAST::Lookup); parent(RakuAST::Circumfix::ArrayComposer, RakuAST::ColonPairish); add-attribute(RakuAST::Circumfix::ArrayComposer, RakuAST::SemiList, '$!semilist'); add-method(RakuAST::Circumfix::ArrayComposer, 'new', [RakuAST::Circumfix::ArrayComposer, '', 0, 0, RakuAST::SemiList, '$semilist', 0, 0], anon sub new ($SELF_CONT, $semilist!) { my $SELF := nqp::decont($SELF_CONT); $semilist := nqp::decont($semilist); #line 69 src/Raku/ast/circumfix.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Circumfix::ArrayComposer, '$!semilist', $semilist); $obj }); add-method(RakuAST::Circumfix::ArrayComposer, 'canonicalize', [RakuAST::Circumfix::ArrayComposer, '', 0, 0], anon sub canonicalize ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 75 src/Raku/ast/circumfix.rakumod my @statements := $SELF.semilist.code-statements; if nqp::elems(@statements) == 1 { $SELF.IMPL-QUOTE-VALUE(@statements[0].expression.literal-value) } else { my @parts; for @statements { nqp::die('canonicalize NYI for non-simple colonpairs: ' ~ $_.HOW.name($_)) unless nqp::istype($_, RakuAST::Statement::Expression); nqp::push(@parts, "'" ~ $_.expression.literal-value ~ "'"); } '[' ~ nqp::join('; ', @parts) ~ ']' } }); add-method(RakuAST::Circumfix::ArrayComposer, 'resolve-with', [RakuAST::Circumfix::ArrayComposer, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 91 src/Raku/ast/circumfix.rakumod my $resolved := $resolver.resolve-lexical('&circumfix:<[ ]>'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Circumfix::ArrayComposer, 'IMPL-EXPR-QAST', [RakuAST::Circumfix::ArrayComposer, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 99 src/Raku/ast/circumfix.rakumod my $name := $SELF.resolution.lexical-name; QAST::Op.new( :op('call'), :$name, nqp::getattr($SELF, RakuAST::Circumfix::ArrayComposer, '$!semilist').IMPL-TO-QAST($context) ) }); add-method(RakuAST::Circumfix::ArrayComposer, 'visit-children', [RakuAST::Circumfix::ArrayComposer, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 107 src/Raku/ast/circumfix.rakumod $visitor(nqp::getattr($SELF, RakuAST::Circumfix::ArrayComposer, '$!semilist')); }); add-method(RakuAST::Circumfix::ArrayComposer, 'IMPL-CAN-INTERPRET', [RakuAST::Circumfix::ArrayComposer, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 111 src/Raku/ast/circumfix.rakumod my @statements := $SELF.semilist.code-statements; nqp::elems(@statements) == 1 && @statements[0].IMPL-CAN-INTERPRET }); add-method(RakuAST::Circumfix::ArrayComposer, 'IMPL-INTERPRET', [RakuAST::Circumfix::ArrayComposer, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 116 src/Raku/ast/circumfix.rakumod my @statements := $SELF.semilist.code-statements; my $result := @statements[0].IMPL-INTERPRET($ctx); Array.new($result) }); #line 67 src/Raku/ast/circumfix.rakumod add-method(RakuAST::Circumfix::ArrayComposer, 'semilist', [], anon sub semilist ($self) { nqp::getattr(nqp::decont($self), RakuAST::Circumfix::ArrayComposer, '$!semilist') }); compose(RakuAST::Circumfix::ArrayComposer); parent(RakuAST::Circumfix::HashComposer, RakuAST::Circumfix); parent(RakuAST::Circumfix::HashComposer, RakuAST::Lookup); add-attribute(RakuAST::Circumfix::HashComposer, RakuAST::Expression, '$!expression'); add-attribute(RakuAST::Circumfix::HashComposer, int, '$!object-hash'); add-method(RakuAST::Circumfix::HashComposer, 'new', [RakuAST::Circumfix::HashComposer, '', 0, 0, RakuAST::Expression, '$expression', 0, 1, int, '$object-hash', 1, 1], anon sub new ($SELF_CONT, $expression?, :$object-hash?) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); $object-hash := nqp::decont($object-hash); #line 135 src/Raku/ast/circumfix.rakumod my $obj := nqp::create($SELF); $obj.set-expression($expression); nqp::bindattr_i($obj, RakuAST::Circumfix::HashComposer, '$!object-hash', $object-hash ?? 1 !! 0); $obj }); add-method(RakuAST::Circumfix::HashComposer, 'set-expression', [RakuAST::Circumfix::HashComposer, '', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub set-expression ($SELF_CONT, $expression!) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); #line 142 src/Raku/ast/circumfix.rakumod nqp::bindattr($SELF, RakuAST::Circumfix::HashComposer, '$!expression', $expression // RakuAST::Expression); Nil }); add-method(RakuAST::Circumfix::HashComposer, 'resolve-with', [RakuAST::Circumfix::HashComposer, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 148 src/Raku/ast/circumfix.rakumod my $resolved := nqp::getattr_i($SELF, RakuAST::Circumfix::HashComposer, '$!object-hash') ?? $resolver.resolve-lexical('&circumfix:<:{ }>') !! $resolver.resolve-lexical('&circumfix:<{ }>'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Circumfix::HashComposer, 'IMPL-EXPR-QAST', [RakuAST::Circumfix::HashComposer, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 158 src/Raku/ast/circumfix.rakumod my $name := $SELF.resolution.lexical-name; my $expression := nqp::getattr($SELF, RakuAST::Circumfix::HashComposer, '$!expression'); my $op := QAST::Op.new(:op, :$name); if $expression { $op.push($expression.IMPL-TO-QAST($context)) } $op }); add-method(RakuAST::Circumfix::HashComposer, 'visit-children', [RakuAST::Circumfix::HashComposer, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 169 src/Raku/ast/circumfix.rakumod $visitor(nqp::getattr($SELF, RakuAST::Circumfix::HashComposer, '$!expression')) if nqp::getattr($SELF, RakuAST::Circumfix::HashComposer, '$!expression'); }); #line 133 src/Raku/ast/circumfix.rakumod add-method(RakuAST::Circumfix::HashComposer, 'object-hash', [], anon sub object-hash ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Circumfix::HashComposer, '$!object-hash') }); #line 132 src/Raku/ast/circumfix.rakumod add-method(RakuAST::Circumfix::HashComposer, 'expression', [], anon sub expression ($self) { nqp::getattr(nqp::decont($self), RakuAST::Circumfix::HashComposer, '$!expression') }); compose(RakuAST::Circumfix::HashComposer); parent(RakuAST::ArgList, RakuAST::CaptureSource); add-attribute(RakuAST::ArgList, List, '$!args'); add-attribute(RakuAST::ArgList, RakuAST::Expression, '$!invocant'); add-method(RakuAST::ArgList, 'new', [RakuAST::ArgList, '', 0, 0, Any, '@args', 0, 0], anon sub new ($SELF_CONT, *@args) { my $SELF := nqp::decont($SELF_CONT); @args := nqp::decont(@args); #line 8 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ArgList, '$!args', []); for @args { $obj.push: $_; } $obj }); add-method(RakuAST::ArgList, 'from-comma-list', [RakuAST::ArgList, '', 0, 0, RakuAST::ApplyListInfix, '$comma-apply', 0, 0], anon sub from-comma-list ($SELF_CONT, $comma-apply!) { my $SELF := nqp::decont($SELF_CONT); $comma-apply := nqp::decont($comma-apply); #line 17 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ArgList, '$!args', []); for $SELF.IMPL-UNWRAP-LIST($comma-apply.operands) { $obj.push: $_; } $obj }); add-method(RakuAST::ArgList, 'from-invocant-list', [RakuAST::ArgList, '', 0, 0, RakuAST::ApplyListInfix, '$colon-apply', 0, 0], anon sub from-invocant-list ($SELF_CONT, $colon-apply!) { my $SELF := nqp::decont($SELF_CONT); $colon-apply := nqp::decont($colon-apply); #line 26 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ArgList, '$!args', []); my @args := nqp::clone($SELF.IMPL-UNWRAP-LIST($colon-apply.operands)); nqp::bindattr($obj, RakuAST::ArgList, '$!invocant', nqp::shift(@args)); for @args { $obj.push: $_; } $obj }); add-method(RakuAST::ArgList, 'arg-at-pos', [RakuAST::ArgList, '', 0, 0, int, '$pos', 0, 0], anon sub arg-at-pos ($SELF_CONT, $pos!) { my $SELF := nqp::decont($SELF_CONT); $pos := nqp::decont($pos); #line 37 src/Raku/ast/call.rakumod nqp::atpos(nqp::getattr($SELF, RakuAST::ArgList, '$!args'),$pos) }); add-method(RakuAST::ArgList, 'set-arg-at-pos', [RakuAST::ArgList, '', 0, 0, int, '$pos', 0, 0, RakuAST::Expression, '$arg', 0, 0], anon sub set-arg-at-pos ($SELF_CONT, $pos!, $arg!) { my $SELF := nqp::decont($SELF_CONT); $pos := nqp::decont($pos); $arg := nqp::decont($arg); #line 38 src/Raku/ast/call.rakumod nqp::bindpos(nqp::getattr($SELF, RakuAST::ArgList, '$!args'),$pos,$arg); Nil }); add-method(RakuAST::ArgList, 'push', [RakuAST::ArgList, '', 0, 0, Any, '$arg', 0, 0], anon sub push ($SELF_CONT, $arg!) { my $SELF := nqp::decont($SELF_CONT); $arg := nqp::decont($arg); #line 43 src/Raku/ast/call.rakumod if nqp::istype($arg, RakuAST::ColonPairs) { for $arg.colonpairs { $SELF.push: $_ } } else { nqp::push(nqp::getattr($SELF, RakuAST::ArgList, '$!args'), $arg) } }); add-method(RakuAST::ArgList, 'has-args', [RakuAST::ArgList, '', 0, 0], anon sub has-args ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 54 src/Raku/ast/call.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::ArgList, '$!args')) }); add-method(RakuAST::ArgList, 'args', [RakuAST::ArgList, '', 0, 0], anon sub args ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 56 src/Raku/ast/call.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::ArgList, '$!args')) }); add-method(RakuAST::ArgList, 'visit-children', [RakuAST::ArgList, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 60 src/Raku/ast/call.rakumod my @args := nqp::getattr($SELF, RakuAST::ArgList, '$!args'); $visitor(nqp::getattr($SELF, RakuAST::ArgList, '$!invocant')) if nqp::getattr($SELF, RakuAST::ArgList, '$!invocant'); for @args { $visitor($_); } }); add-method(RakuAST::ArgList, 'IMPL-ADD-QAST-ARGS', [RakuAST::ArgList, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Op, '$call', 0, 0], anon sub IMPL-ADD-QAST-ARGS ($SELF_CONT, $context!, $call!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $call := nqp::decont($call); #line 68 src/Raku/ast/call.rakumod # We need to remove duplicate named args, so make a first pass through to # collect those. my %named-counts; for nqp::getattr($SELF, RakuAST::ArgList, '$!args') -> $arg { if nqp::istype($arg, RakuAST::NamedArg) { %named-counts{$arg.named-arg-name}++; } } # Now emit code to compile and pass each argument. for nqp::getattr($SELF, RakuAST::ArgList, '$!args') -> $arg { if $SELF.IMPL-IS-FLATTENING($arg) { # Flattening argument; evaluate it once and pass the array and hash # flattening parts. my $temp := QAST::Node.unique('flattening_'); $call.push(QAST::Op.new( :op('callmethod'), :name('FLATTENABLE_LIST'), QAST::Op.new( :op('bind'), QAST::Var.new( :name($temp), :scope('local'), :decl('var') ), $arg.operand.IMPL-TO-QAST($context) ), :flat(1) )); $call.push(QAST::Op.new( :op('callmethod'), :name('FLATTENABLE_HASH'), QAST::Var.new( :name($temp), :scope('local') ), :flat(1), :named(1) )); } elsif nqp::istype($arg, RakuAST::NamedArg) { my $name := $arg.named-arg-name; if %named-counts{$name} == 1 { # It's the final appearance of this name, so emit it as the # named argument. my $val-ast := $arg.named-arg-value.IMPL-TO-QAST($context); $val-ast.named($name); $call.push($val-ast); } else { # It's a discarded value. If it has side-effects, then we # must evaluate those. my $value := $arg.named-arg-value; unless $value.pure { $call.push(QAST::Stmts.new( :flat, $value.IMPL-TO-QAST($context), QAST::Op.new( :op('list') ) # flattens to nothing )); } %named-counts{$name}--; } } else { # Positional argument. $call.push($arg.IMPL-TO-QAST($context)) } } }); add-method(RakuAST::ArgList, 'IMPL-IS-ONE-POS-ARG', [RakuAST::ArgList, '', 0, 0], anon sub IMPL-IS-ONE-POS-ARG ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 129 src/Raku/ast/call.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::ArgList, '$!args')) == 1 && !nqp::istype(nqp::getattr($SELF, RakuAST::ArgList, '$!args')[0], RakuAST::NamedArg) && !$SELF.IMPL-IS-FLATTENING(nqp::getattr($SELF, RakuAST::ArgList, '$!args')[0]) }); add-method(RakuAST::ArgList, 'IMPL-IS-FLATTENING', [RakuAST::ArgList, '', 0, 0, RakuAST::Node, '$arg', 0, 0], anon sub IMPL-IS-FLATTENING ($SELF_CONT, $arg!) { my $SELF := nqp::decont($SELF_CONT); $arg := nqp::decont($arg); #line 135 src/Raku/ast/call.rakumod nqp::istype($arg, RakuAST::ApplyPrefix) && nqp::istype($arg.prefix, RakuAST::Prefix) && $arg.prefix.operator eq '|' }); add-method(RakuAST::ArgList, 'IMPL-CAN-INTERPRET', [RakuAST::ArgList, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 141 src/Raku/ast/call.rakumod for nqp::getattr($SELF, RakuAST::ArgList, '$!args') -> $arg { if $SELF.IMPL-IS-FLATTENING($arg) { # Flattening args not implemented in the interpreter # (possible, maybe some ordering subtleties). return (Bool.WHO); } elsif nqp::istype($arg, RakuAST::NamedArg) { return (Bool.WHO) unless $arg.named-arg-value.IMPL-CAN-INTERPRET; } else { return (Bool.WHO) unless $arg.IMPL-CAN-INTERPRET; } } (Bool.WHO) }); add-method(RakuAST::ArgList, 'IMPL-INTERPRET', [RakuAST::ArgList, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 158 src/Raku/ast/call.rakumod my @pos; my %named; for nqp::getattr($SELF, RakuAST::ArgList, '$!args') -> $arg { if nqp::istype($arg, RakuAST::NamedArg) { %named{$arg.named-arg-name} := $arg.named-arg-value.IMPL-INTERPRET($ctx); } else { nqp::push(@pos, $arg.IMPL-INTERPRET($ctx)); } } [@pos, %named] }); add-method(RakuAST::ArgList, 'IMPL-HAS-ONLY-COMPILE-TIME-VALUES', [RakuAST::ArgList, '', 0, 0], anon sub IMPL-HAS-ONLY-COMPILE-TIME-VALUES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 172 src/Raku/ast/call.rakumod for nqp::getattr($SELF, RakuAST::ArgList, '$!args') -> $arg { return (Bool.WHO) unless nqp::istype($arg, RakuAST::CompileTimeValue); } (Bool.WHO) }); add-method(RakuAST::ArgList, 'IMPL-COMPILE-TIME-VALUES', [RakuAST::ArgList, '', 0, 0], anon sub IMPL-COMPILE-TIME-VALUES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 179 src/Raku/ast/call.rakumod my @pos; my %named; for nqp::getattr($SELF, RakuAST::ArgList, '$!args') -> $arg { if nqp::istype($arg, RakuAST::NamedArg) { %named{$arg.named-arg-name} := $arg.named-arg-value.compile-time-value; } else { nqp::push(@pos, $arg.compile-time-value); } } [@pos, %named] }); #line 6 src/Raku/ast/call.rakumod add-method(RakuAST::ArgList, 'invocant', [], anon sub invocant ($self) { nqp::getattr(nqp::decont($self), RakuAST::ArgList, '$!invocant') }); compose(RakuAST::ArgList); parent(RakuAST::Call, Any); add-attribute(RakuAST::Call, RakuAST::ArgList, '$!args'); add-method(RakuAST::Call, 'add-colonpair', [RakuAST::Call, '', 0, 0, RakuAST::ColonPair, '$pair', 0, 0], anon sub add-colonpair ($SELF_CONT, $pair!) { my $SELF := nqp::decont($SELF_CONT); $pair := nqp::decont($pair); #line 199 src/Raku/ast/call.rakumod nqp::getattr($SELF, RakuAST::Call, '$!args').push($pair); Nil }); #line 197 src/Raku/ast/call.rakumod add-method(RakuAST::Call, 'args', [], anon sub args ($self) { nqp::getattr(nqp::decont($self), RakuAST::Call, '$!args') }); compose(RakuAST::Call); parent(RakuAST::Call::Name, RakuAST::Term); parent(RakuAST::Call::Name, RakuAST::Call); parent(RakuAST::Call::Name, RakuAST::Lookup); add-attribute(RakuAST::Call::Name, RakuAST::Name, '$!name'); add-attribute(RakuAST::Call::Name, Mu, '$!package'); add-method(RakuAST::Call::Name, 'new', [RakuAST::Call::Name, '', 0, 0, RakuAST::Name, '$name', 1, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$name!, :$args?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $args := nqp::decont($args); #line 214 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Call::Name, '$!name', $name); nqp::bindattr($obj, RakuAST::Call, '$!args', $args // RakuAST::ArgList.new); $obj }); add-method(RakuAST::Call::Name, 'visit-children', [RakuAST::Call::Name, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 221 src/Raku/ast/call.rakumod $visitor(nqp::getattr($SELF, RakuAST::Call::Name, '$!name')); $visitor($SELF.args); }); add-method(RakuAST::Call::Name, 'properties', [RakuAST::Call::Name, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 230 src/Raku/ast/call.rakumod OperatorProperties.prefix }); add-method(RakuAST::Call::Name, 'needs-resolution', [RakuAST::Call::Name, '', 0, 0], anon sub needs-resolution ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 232 src/Raku/ast/call.rakumod nqp::getattr($SELF, RakuAST::Call::Name, '$!name').is-identifier }); add-method(RakuAST::Call::Name, 'resolve-with', [RakuAST::Call::Name, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 234 src/Raku/ast/call.rakumod nqp::bindattr($SELF, RakuAST::Call::Name, '$!package', $resolver.current-package); my $resolved := $resolver.resolve-name(nqp::getattr($SELF, RakuAST::Call::Name, '$!name'), :sigil('&')); if $resolved { $SELF.set-resolution($resolved); } elsif nqp::getattr($SELF, RakuAST::Call::Name, '$!name').is-package-lookup { my $name := nqp::getattr($SELF, RakuAST::Call::Name, '$!name').base-name; if $name.canonicalize { $resolved := $resolver.resolve-name($name); if $resolved { my $v := $resolved.compile-time-value; $SELF.set-resolution($resolved); } } } Nil }); add-method(RakuAST::Call::Name, 'undeclared-symbol-details', [RakuAST::Call::Name, '', 0, 0], anon sub undeclared-symbol-details ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 253 src/Raku/ast/call.rakumod RakuAST::UndeclaredSymbolDescription::Routine.new(nqp::getattr($SELF, RakuAST::Call::Name, '$!name').canonicalize()) }); add-method(RakuAST::Call::Name, 'IMPL-EXPR-QAST', [RakuAST::Call::Name, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 257 src/Raku/ast/call.rakumod my $call := QAST::Op.new( :op('call') ); if nqp::getattr($SELF, RakuAST::Call::Name, '$!name').is-identifier { $call.name($SELF.resolution.lexical-name); } else { if my $op := nqp::getattr($SELF, RakuAST::Call::Name, '$!name').IMPL-IS-NQP-OP { return RakuAST::Nqp.new($op, $SELF.args).IMPL-TO-QAST($context); } elsif nqp::getattr($SELF, RakuAST::Call::Name, '$!name').is-package-lookup { return $SELF.is-resolved ?? nqp::getattr($SELF, RakuAST::Call::Name, '$!name').IMPL-QAST-PACKAGE-LOOKUP( $context, nqp::getattr($SELF, RakuAST::Call::Name, '$!package'), :lexical($SELF.resolution) ) !! nqp::getattr($SELF, RakuAST::Call::Name, '$!name').IMPL-QAST-PACKAGE-LOOKUP( $context, nqp::getattr($SELF, RakuAST::Call::Name, '$!package') ); } elsif nqp::getattr($SELF, RakuAST::Call::Name, '$!name').is-indirect-lookup { return nqp::getattr($SELF, RakuAST::Call::Name, '$!name').IMPL-QAST-INDIRECT-LOOKUP($context); } else { $call.push( $SELF.is-resolved ?? $SELF.resolution.IMPL-LOOKUP-QAST($context) !! nqp::getattr($SELF, RakuAST::Call::Name, '$!name').IMPL-QAST-PACKAGE-LOOKUP( $context, nqp::getattr($SELF, RakuAST::Call::Name, '$!package'), :sigil<&>, :global-fallback, ) ); } } $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call }); add-method(RakuAST::Call::Name, 'IMPL-CAN-INTERPRET', [RakuAST::Call::Name, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 298 src/Raku/ast/call.rakumod ( (my $op := nqp::getattr($SELF, RakuAST::Call::Name, '$!name').IMPL-IS-NQP-OP) && ($op eq 'hash' || $op eq 'list_s' || $op eq 'atpos_s') || nqp::getattr($SELF, RakuAST::Call::Name, '$!name').is-identifier && $SELF.is-resolved && nqp::istype($SELF.resolution, RakuAST::CompileTimeValue) ) && $SELF.args.IMPL-CAN-INTERPRET }); add-method(RakuAST::Call::Name, 'IMPL-INTERPRET', [RakuAST::Call::Name, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 307 src/Raku/ast/call.rakumod my $op := nqp::getattr($SELF, RakuAST::Call::Name, '$!name').IMPL-IS-NQP-OP; if $op eq 'hash' { my @args := $SELF.args.IMPL-INTERPRET($ctx)[0]; my $result := nqp::hash; while @args { my $key := nqp::shift(@args); my $val := nqp::shift(@args); $result{$key} := $val; } $result } elsif $op eq 'list_s' { my @args := $SELF.args.IMPL-INTERPRET($ctx)[0]; my $result := nqp::list_s; for @args { nqp::push_s($result, $_); } $result } elsif $op eq 'atpos_s' { my @args := $SELF.args.IMPL-INTERPRET($ctx)[0]; nqp::atpos_s(@args[0], @args[1]); } else { my $resolved := $SELF.resolution.compile-time-value; my @args := $SELF.args.IMPL-INTERPRET($ctx); my @pos := @args[0]; my %named := @args[1]; $resolved(|@pos, |%named); } }); #line 211 src/Raku/ast/call.rakumod add-method(RakuAST::Call::Name, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Call::Name, '$!name') }); compose(RakuAST::Call::Name); parent(RakuAST::Call::Name::WithoutParentheses, RakuAST::Call::Name); compose(RakuAST::Call::Name::WithoutParentheses); parent(RakuAST::Call::Term, RakuAST::Call); parent(RakuAST::Call::Term, RakuAST::Postfixish); add-method(RakuAST::Call::Term, 'new', [RakuAST::Call::Term, '', 0, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$args?) { my $SELF := nqp::decont($SELF_CONT); $args := nqp::decont($args); #line 350 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Call, '$!args', $args // RakuAST::ArgList.new); $obj }); add-method(RakuAST::Call::Term, 'visit-children', [RakuAST::Call::Term, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 356 src/Raku/ast/call.rakumod $visitor($SELF.args); }); add-method(RakuAST::Call::Term, 'default-operator-properties', [RakuAST::Call::Term, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 360 src/Raku/ast/call.rakumod OperatorProperties.postfix('()') }); add-method(RakuAST::Call::Term, 'IMPL-POSTFIX-QAST', [RakuAST::Call::Term, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$callee-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $callee-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $callee-qast := nqp::decont($callee-qast); #line 364 src/Raku/ast/call.rakumod my $call := QAST::Op.new( :op('call'), $callee-qast ); $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call }); add-method(RakuAST::Call::Term, 'IMPL-CAN-INTERPRET', [RakuAST::Call::Term, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 370 src/Raku/ast/call.rakumod $SELF.args.IMPL-CAN-INTERPRET }); add-method(RakuAST::Call::Term, 'IMPL-INTERPRET', [RakuAST::Call::Term, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0, Code, '$operand', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!, $operand!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); $operand := nqp::decont($operand); #line 374 src/Raku/ast/call.rakumod my $code := $operand(); my @args := $SELF.args.IMPL-INTERPRET($ctx); my @pos := @args[0]; my %named := @args[1]; $code(|@pos, |%named) }); compose(RakuAST::Call::Term); parent(RakuAST::Call::Methodish, RakuAST::Call); parent(RakuAST::Call::Methodish, RakuAST::Postfixish); add-method(RakuAST::Call::Methodish, 'IMPL-CURRIES', [RakuAST::Call::Methodish, '', 0, 0], anon sub IMPL-CURRIES ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 388 src/Raku/ast/call.rakumod 3 }); compose(RakuAST::Call::Methodish); parent(RakuAST::Call::Method, RakuAST::Call::Methodish); parent(RakuAST::Call::Method, RakuAST::CheckTime); parent(RakuAST::Call::Method, RakuAST::ImplicitLookups); add-attribute(RakuAST::Call::Method, RakuAST::Name, '$!name'); add-method(RakuAST::Call::Method, 'new', [RakuAST::Call::Method, '', 0, 0, RakuAST::Name, '$name', 1, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$name!, :$args?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $args := nqp::decont($args); #line 400 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Call::Method, '$!name', $name); nqp::bindattr($obj, RakuAST::Call, '$!args', $args // RakuAST::ArgList.new); $obj }); add-method(RakuAST::Call::Method, 'visit-children', [RakuAST::Call::Method, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 407 src/Raku/ast/call.rakumod $visitor(nqp::getattr($SELF, RakuAST::Call::Method, '$!name')); $visitor($SELF.args); }); add-method(RakuAST::Call::Method, 'default-operator-properties', [RakuAST::Call::Method, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 412 src/Raku/ast/call.rakumod OperatorProperties.postfix('.') }); add-method(RakuAST::Call::Method, 'macroish', [RakuAST::Call::Method, '', 0, 0], anon sub macroish ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 416 src/Raku/ast/call.rakumod nqp::getattr($SELF, RakuAST::Call::Method, '$!name').is-identifier && (my $name := nqp::getattr($SELF, RakuAST::Call::Method, '$!name').canonicalize) && nqp::istrue($SELF.IMPL-SPECIAL-OP($name)) }); add-method(RakuAST::Call::Method, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Call::Method, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 422 src/Raku/ast/call.rakumod my $name := nqp::getattr($SELF, RakuAST::Call::Method, '$!name').canonicalize; my @lookups := []; if $name { my @parts := nqp::split('::', $name); if nqp::elems(@parts) > 1 { @parts.pop; @lookups.push: # joining @parts with '::' gives use the qualifying type of the name RakuAST::Type::Simple.new: RakuAST::Name.from-identifier: nqp::join('::', @parts); } } $SELF.IMPL-WRAP-LIST(@lookups) }); add-method(RakuAST::Call::Method, 'IMPL-SPECIAL-OP', [RakuAST::Call::Method, '', 0, 0, str, '$name', 0, 0], anon sub IMPL-SPECIAL-OP ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 436 src/Raku/ast/call.rakumod my constant SPECIAL-OPS := nqp::hash( 'WHAT', 'what', 'HOW', 'how', 'WHO', 'who', 'VAR', 'p6var', 'REPR', 'p6reprname', 'DEFINITE', 'p6definite', ); SPECIAL-OPS{$name} }); add-method(RakuAST::Call::Method, 'IMPL-POSTFIX-QAST', [RakuAST::Call::Method, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $invocant-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $invocant-qast := nqp::decont($invocant-qast); #line 448 src/Raku/ast/call.rakumod my $name := nqp::getattr($SELF, RakuAST::Call::Method, '$!name').canonicalize; if $name { my @parts := nqp::split('::', $name); if nqp::elems(@parts) == 1 { my $op := $SELF.IMPL-SPECIAL-OP($name); if $op { # Not really a method call, just using that syntax. QAST::Op.new(:$op, $invocant-qast) } else { # A standard method call. my $call := QAST::Op.new(:op('callmethod'), :$name, $invocant-qast); $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call } } else { # TODO: In base behavior, the attempt to dispatch is performed before determining whether the type # actually exists in this scope (throwing a X::Method::InvalidQualifier). # The resolution below will die if the type object cannot be found, deviating from base. my $Qualified := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; $context.ensure-sc($Qualified); $name := @parts[ nqp::elems(@parts)-1 ]; my $call := QAST::Op.new(:op('callmethod'), :name('dispatch:<::>'), $invocant-qast, QAST::SVal.new(:value($name)), QAST::WVal.new(:value($Qualified))); $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call } } else { nqp::die('Qualified method calls NYI'); } }); add-method(RakuAST::Call::Method, 'can-be-used-with-hyper', [RakuAST::Call::Method, '', 0, 0], anon sub can-be-used-with-hyper ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 481 src/Raku/ast/call.rakumod !$SELF.macroish }); add-method(RakuAST::Call::Method, 'IMPL-POSTFIX-HYPER-QAST', [RakuAST::Call::Method, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-HYPER-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 483 src/Raku/ast/call.rakumod # TODO later expand this to the qualified case my $name := nqp::getattr($SELF, RakuAST::Call::Method, '$!name').canonicalize; my $call := QAST::Op.new: :op('callmethod'), :name('dispatch:'), $operand-qast, QAST::SVal.new( :value('') ), QAST::SVal.new( :value($name) ); $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call }); add-method(RakuAST::Call::Method, 'IMPL-CAN-INTERPRET', [RakuAST::Call::Method, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 495 src/Raku/ast/call.rakumod nqp::getattr($SELF, RakuAST::Call::Method, '$!name').is-identifier && $SELF.args.IMPL-CAN-INTERPRET }); add-method(RakuAST::Call::Method, 'IMPL-INTERPRET', [RakuAST::Call::Method, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0, Mu, '$invocant-compiler', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!, $invocant-compiler!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); $invocant-compiler := nqp::decont($invocant-compiler); #line 497 src/Raku/ast/call.rakumod my $invocant := $invocant-compiler(); my $name := nqp::getattr($SELF, RakuAST::Call::Method, '$!name').canonicalize; if $name eq 'WHAT' { $invocant.WHAT } elsif $name eq 'HOW' { $invocant.HOW } elsif $name eq 'WHO' { $invocant.WHO } elsif $name eq 'VAR' { my $var := nqp::create(Scalar); nqp::bindattr_s($var, Scalar, '$!value', $invocant); $var } elsif $name eq 'REPR' { nqp::box_s(nqp::reprname($invocant), Str) } elsif $name eq 'DEFINITE' { nqp::isconcrete($invocant) ?? (Bool.WHO) !! (Bool.WHO) } else { my @args := $SELF.args.IMPL-INTERPRET($ctx); my @pos := @args[0]; my %named := @args[1]; $invocant."$name"(|@pos, |%named) } }); add-method(RakuAST::Call::Method, 'PERFORM-CHECK', [RakuAST::Call::Method, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 531 src/Raku/ast/call.rakumod if $SELF.macroish && $SELF.args.has-args { $SELF.add-sorry: $resolver.build-exception: 'X::Syntax::Argument::MOPMacro', macro => nqp::getattr($SELF, RakuAST::Call::Method, '$!name').canonicalize; } }); #line 398 src/Raku/ast/call.rakumod add-method(RakuAST::Call::Method, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Call::Method, '$!name') }); compose(RakuAST::Call::Method); parent(RakuAST::Call::QuotedMethod, RakuAST::Call::Methodish); add-attribute(RakuAST::Call::QuotedMethod, RakuAST::QuotedString, '$!name'); add-method(RakuAST::Call::QuotedMethod, 'new', [RakuAST::Call::QuotedMethod, '', 0, 0, RakuAST::QuotedString, '$name', 1, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$name!, :$args?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $args := nqp::decont($args); #line 546 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Call::QuotedMethod, '$!name', $name); nqp::bindattr($obj, RakuAST::Call, '$!args', $args // RakuAST::ArgList.new); $obj }); add-method(RakuAST::Call::QuotedMethod, 'visit-children', [RakuAST::Call::QuotedMethod, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 553 src/Raku/ast/call.rakumod $visitor(nqp::getattr($SELF, RakuAST::Call::QuotedMethod, '$!name')); $visitor($SELF.args); }); add-method(RakuAST::Call::QuotedMethod, 'default-operator-properties', [RakuAST::Call::QuotedMethod, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 558 src/Raku/ast/call.rakumod OperatorProperties.postfix('.') }); add-method(RakuAST::Call::QuotedMethod, 'IMPL-POSTFIX-QAST', [RakuAST::Call::QuotedMethod, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $invocant-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $invocant-qast := nqp::decont($invocant-qast); #line 562 src/Raku/ast/call.rakumod my $name-qast := QAST::Op.new( :op, nqp::getattr($SELF, RakuAST::Call::QuotedMethod, '$!name').IMPL-TO-QAST($context) ); my $call := QAST::Op.new( :op('callmethod'), $invocant-qast, $name-qast ); $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call }); #line 544 src/Raku/ast/call.rakumod add-method(RakuAST::Call::QuotedMethod, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Call::QuotedMethod, '$!name') }); compose(RakuAST::Call::QuotedMethod); parent(RakuAST::Call::PrivateMethod, RakuAST::Call::Methodish); parent(RakuAST::Call::PrivateMethod, RakuAST::Lookup); parent(RakuAST::Call::PrivateMethod, RakuAST::ImplicitLookups); add-attribute(RakuAST::Call::PrivateMethod, RakuAST::Name, '$!name'); add-attribute(RakuAST::Call::PrivateMethod, Mu, '$!package'); add-method(RakuAST::Call::PrivateMethod, 'new', [RakuAST::Call::PrivateMethod, '', 0, 0, RakuAST::Name, '$name', 1, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$name!, :$args?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $args := nqp::decont($args); #line 579 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Call::PrivateMethod, '$!name', $name); nqp::bindattr($obj, RakuAST::Call, '$!args', $args // RakuAST::ArgList.new); $obj }); add-method(RakuAST::Call::PrivateMethod, 'visit-children', [RakuAST::Call::PrivateMethod, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 586 src/Raku/ast/call.rakumod $visitor(nqp::getattr($SELF, RakuAST::Call::PrivateMethod, '$!name')); $visitor($SELF.args); }); add-method(RakuAST::Call::PrivateMethod, 'default-operator-properties', [RakuAST::Call::PrivateMethod, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 591 src/Raku/ast/call.rakumod OperatorProperties.postfix('!') }); add-method(RakuAST::Call::PrivateMethod, 'needs-resolution', [RakuAST::Call::PrivateMethod, '', 0, 0], anon sub needs-resolution ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 595 src/Raku/ast/call.rakumod (Bool.WHO) }); add-method(RakuAST::Call::PrivateMethod, 'resolve-with', [RakuAST::Call::PrivateMethod, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 597 src/Raku/ast/call.rakumod nqp::bindattr($SELF, RakuAST::Call::PrivateMethod, '$!package', $resolver.current-package); Nil }); add-method(RakuAST::Call::PrivateMethod, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Call::PrivateMethod, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 602 src/Raku/ast/call.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical::Constant.new('::?CLASS'), ]); }); add-method(RakuAST::Call::PrivateMethod, 'IMPL-POSTFIX-QAST', [RakuAST::Call::PrivateMethod, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $invocant-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $invocant-qast := nqp::decont($invocant-qast); #line 608 src/Raku/ast/call.rakumod if nqp::getattr($SELF, RakuAST::Call::PrivateMethod, '$!name').is-identifier { my $name := $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Call::PrivateMethod, '$!name').parts)[0].name; my $call := QAST::Op.new( :op('callmethod'), :name('dispatch:'), $invocant-qast, RakuAST::StrLiteral.new($name).IMPL-EXPR-QAST($context), nqp::getattr($SELF, RakuAST::Call::PrivateMethod, '$!package').HOW.archetypes.parametric ?? $SELF.get-implicit-lookups.AT-POS(0).IMPL-EXPR-QAST($context) !! QAST::WVal.new(:value(nqp::getattr($SELF, RakuAST::Call::PrivateMethod, '$!package'))), ); $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call } else { nqp::die('Qualified private method calls NYI'); } }); #line 576 src/Raku/ast/call.rakumod add-method(RakuAST::Call::PrivateMethod, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Call::PrivateMethod, '$!name') }); compose(RakuAST::Call::PrivateMethod); parent(RakuAST::Call::MetaMethod, RakuAST::Call::Methodish); add-attribute(RakuAST::Call::MetaMethod, str, '$!name'); add-method(RakuAST::Call::MetaMethod, 'new', [RakuAST::Call::MetaMethod, '', 0, 0, str, '$name', 1, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$name!, :$args?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $args := nqp::decont($args); #line 635 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Call::MetaMethod, '$!name', $name); nqp::bindattr($obj, RakuAST::Call, '$!args', $args // RakuAST::ArgList.new); $obj }); add-method(RakuAST::Call::MetaMethod, 'visit-children', [RakuAST::Call::MetaMethod, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 642 src/Raku/ast/call.rakumod $visitor($SELF.args); }); add-method(RakuAST::Call::MetaMethod, 'default-operator-properties', [RakuAST::Call::MetaMethod, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 646 src/Raku/ast/call.rakumod OperatorProperties.postfix('.^') }); add-method(RakuAST::Call::MetaMethod, 'IMPL-POSTFIX-QAST', [RakuAST::Call::MetaMethod, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $invocant-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $invocant-qast := nqp::decont($invocant-qast); #line 650 src/Raku/ast/call.rakumod my $call := QAST::Op.new( :op('p6callmethodhow'), :name(nqp::getattr_s($SELF, RakuAST::Call::MetaMethod, '$!name')), $invocant-qast ); $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call }); #line 633 src/Raku/ast/call.rakumod add-method(RakuAST::Call::MetaMethod, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Call::MetaMethod, '$!name') }); compose(RakuAST::Call::MetaMethod); parent(RakuAST::Call::MaybeMethod, RakuAST::Call::Methodish); add-attribute(RakuAST::Call::MaybeMethod, str, '$!name'); add-method(RakuAST::Call::MaybeMethod, 'new', [RakuAST::Call::MaybeMethod, '', 0, 0, str, '$name', 1, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$name!, :$args?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $args := nqp::decont($args); #line 663 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Call::MaybeMethod, '$!name', $name); nqp::bindattr($obj, RakuAST::Call, '$!args', $args // RakuAST::ArgList.new); $obj }); add-method(RakuAST::Call::MaybeMethod, 'visit-children', [RakuAST::Call::MaybeMethod, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 670 src/Raku/ast/call.rakumod $visitor($SELF.args); }); add-method(RakuAST::Call::MaybeMethod, 'default-operator-properties', [RakuAST::Call::MaybeMethod, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 674 src/Raku/ast/call.rakumod OperatorProperties.postfix('.?') }); add-method(RakuAST::Call::MaybeMethod, 'IMPL-POSTFIX-QAST', [RakuAST::Call::MaybeMethod, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $invocant-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $invocant-qast := nqp::decont($invocant-qast); #line 678 src/Raku/ast/call.rakumod my $call := QAST::Op.new( :op('callmethod'), :name('dispatch:<.?>'), $invocant-qast, QAST::SVal.new(:value(nqp::getattr_s($SELF, RakuAST::Call::MaybeMethod, '$!name'))) ); $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call }); #line 661 src/Raku/ast/call.rakumod add-method(RakuAST::Call::MaybeMethod, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Call::MaybeMethod, '$!name') }); compose(RakuAST::Call::MaybeMethod); parent(RakuAST::Call::VarMethod, RakuAST::Call::Methodish); parent(RakuAST::Call::VarMethod, RakuAST::Lookup); add-attribute(RakuAST::Call::VarMethod, RakuAST::Name, '$!name'); add-method(RakuAST::Call::VarMethod, 'new', [RakuAST::Call::VarMethod, '', 0, 0, RakuAST::Name, '$name', 1, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$name!, :$args?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $args := nqp::decont($args); #line 696 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Call::VarMethod, '$!name', $name); nqp::bindattr($obj, RakuAST::Call, '$!args', $args // RakuAST::ArgList.new); $obj }); add-method(RakuAST::Call::VarMethod, 'can-be-used-with-hyper', [RakuAST::Call::VarMethod, '', 0, 0], anon sub can-be-used-with-hyper ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 703 src/Raku/ast/call.rakumod (Bool.WHO) }); add-method(RakuAST::Call::VarMethod, 'visit-children', [RakuAST::Call::VarMethod, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 705 src/Raku/ast/call.rakumod $visitor(nqp::getattr($SELF, RakuAST::Call::VarMethod, '$!name')); $visitor($SELF.args); }); add-method(RakuAST::Call::VarMethod, 'default-operator-properties', [RakuAST::Call::VarMethod, '', 0, 0], anon sub default-operator-properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 710 src/Raku/ast/call.rakumod OperatorProperties.postfix('.&') }); add-method(RakuAST::Call::VarMethod, 'needs-resolution', [RakuAST::Call::VarMethod, '', 0, 0], anon sub needs-resolution ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 714 src/Raku/ast/call.rakumod nqp::getattr($SELF, RakuAST::Call::VarMethod, '$!name').is-identifier }); add-method(RakuAST::Call::VarMethod, 'resolve-with', [RakuAST::Call::VarMethod, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 716 src/Raku/ast/call.rakumod my $resolved := $resolver.resolve-name(nqp::getattr($SELF, RakuAST::Call::VarMethod, '$!name'), :sigil('&')); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Call::VarMethod, 'undeclared-symbol-details', [RakuAST::Call::VarMethod, '', 0, 0], anon sub undeclared-symbol-details ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 724 src/Raku/ast/call.rakumod RakuAST::UndeclaredSymbolDescription::Routine.new(nqp::getattr($SELF, RakuAST::Call::VarMethod, '$!name').canonicalize()) }); add-method(RakuAST::Call::VarMethod, 'IMPL-POSTFIX-QAST', [RakuAST::Call::VarMethod, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-qast', 0, 0], anon sub IMPL-POSTFIX-QAST ($SELF_CONT, $context!, $invocant-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $invocant-qast := nqp::decont($invocant-qast); #line 728 src/Raku/ast/call.rakumod my $call := QAST::Op.new(:op, $invocant-qast); if nqp::getattr($SELF, RakuAST::Call::VarMethod, '$!name').is-identifier { $call.name($SELF.resolution.lexical-name); } else { nqp::die('compiling complex call names NYI') } $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call }); add-method(RakuAST::Call::VarMethod, 'IMPL-POSTFIX-HYPER-QAST', [RakuAST::Call::VarMethod, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$operand-qast', 0, 0], anon sub IMPL-POSTFIX-HYPER-QAST ($SELF_CONT, $context!, $operand-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $operand-qast := nqp::decont($operand-qast); #line 740 src/Raku/ast/call.rakumod my $name := nqp::getattr($SELF, RakuAST::Call::VarMethod, '$!name').canonicalize; my $call := QAST::Op.new: :op('callmethod'), :name('dispatch:'), $operand-qast, $SELF.resolution.IMPL-LOOKUP-QAST($context), QAST::SVal.new( :value('dispatch:') ), $SELF.resolution.IMPL-LOOKUP-QAST($context); $SELF.args.IMPL-ADD-QAST-ARGS($context, $call); $call }); #line 694 src/Raku/ast/call.rakumod add-method(RakuAST::Call::VarMethod, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Call::VarMethod, '$!name') }); compose(RakuAST::Call::VarMethod); parent(RakuAST::Stub, RakuAST::ImplicitLookups); add-attribute(RakuAST::Stub, RakuAST::ArgList, '$!args'); add-method(RakuAST::Stub, 'new', [RakuAST::Stub, '', 0, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$args?) { my $SELF := nqp::decont($SELF_CONT); $args := nqp::decont($args); #line 759 src/Raku/ast/call.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Stub, '$!args', $args); $obj }); add-method(RakuAST::Stub, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Stub, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 765 src/Raku/ast/call.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Simple.new( RakuAST::Name.from-identifier-parts('X','StubCode') ) ]) }); add-method(RakuAST::Stub, 'IMPL-TO-QAST', [RakuAST::Stub, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 773 src/Raku/ast/call.rakumod my $qast := QAST::Op.new( :op, :name, $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context) ); if nqp::getattr($SELF, RakuAST::Stub, '$!args') { my @args := $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Stub, '$!args').args); if nqp::elems(@args) { my $value := @args[0].IMPL-EXPR-QAST($context); $value.named("message"); nqp::push($qast, $value); } } QAST::Op.new( :op, :name('&' ~ $SELF.IMPL-FUNC-NAME), $qast ) }); #line 757 src/Raku/ast/call.rakumod add-method(RakuAST::Stub, 'args', [], anon sub args ($self) { nqp::getattr(nqp::decont($self), RakuAST::Stub, '$!args') }); compose(RakuAST::Stub); parent(RakuAST::Stub::Fail, RakuAST::Stub); add-method(RakuAST::Stub::Fail, 'name', [RakuAST::Stub::Fail, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 798 src/Raku/ast/call.rakumod '...' }); add-method(RakuAST::Stub::Fail, 'IMPL-FUNC-NAME', [RakuAST::Stub::Fail, '', 0, 0], anon sub IMPL-FUNC-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 799 src/Raku/ast/call.rakumod 'fail' }); compose(RakuAST::Stub::Fail); parent(RakuAST::Stub::Warn, RakuAST::Stub); add-method(RakuAST::Stub::Warn, 'name', [RakuAST::Stub::Warn, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 806 src/Raku/ast/call.rakumod '???' }); add-method(RakuAST::Stub::Warn, 'IMPL-FUNC-NAME', [RakuAST::Stub::Warn, '', 0, 0], anon sub IMPL-FUNC-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 807 src/Raku/ast/call.rakumod 'warn' }); compose(RakuAST::Stub::Warn); parent(RakuAST::Stub::Die, RakuAST::Stub); add-method(RakuAST::Stub::Die, 'name', [RakuAST::Stub::Die, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 814 src/Raku/ast/call.rakumod '!!!' }); add-method(RakuAST::Stub::Die, 'IMPL-FUNC-NAME', [RakuAST::Stub::Die, '', 0, 0], anon sub IMPL-FUNC-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 815 src/Raku/ast/call.rakumod 'die' }); compose(RakuAST::Stub::Die); parent(RakuAST::Nqp, RakuAST::Expression); add-attribute(RakuAST::Nqp, Str, '$!op'); add-attribute(RakuAST::Nqp, RakuAST::ArgList, '$!args'); add-method(RakuAST::Nqp, 'new', [RakuAST::Nqp, '', 0, 0, Str, '$op', 0, 0, Any, '@args', 0, 0], anon sub new ($SELF_CONT, $op!, *@args) { my $SELF := nqp::decont($SELF_CONT); $op := nqp::decont($op); @args := nqp::decont(@args); #line 8 src/Raku/ast/nqp.rakumod nqp::die('RakuAST::Nqp does not support nqp::const. Use RakuAST::Nqp::Const') if $op eq 'const'; my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Nqp, '$!op', $op); my $args; if nqp::elems(@args) == 1 { my $it := @args[0]; if nqp::istype($it, RakuAST::ArgList) { nqp::bindattr($obj, RakuAST::Nqp, '$!args', $it); $args := nqp::getattr(@args[0], RakuAST::ArgList, '$!args'); } elsif nqp::istype($it, List) { $it.elems; # reify $obj.set-args($args := nqp::getattr($it, List, '$!reified')); } else { $obj.set-args($args := @args); } } else { $obj.set-args($args := @args); } # We want to make use of nqp ops as simple as possible, so # we automatically convert common types to their RakuAST # equivalents. my int $i := 0; my int $n := nqp::elems($args); while $i < $n { my $arg := $args[$i]; if nqp::istype($arg,Str) { $args[$i] := RakuAST::StrLiteral.new($arg); } elsif nqp::istype($arg,Int) { $args[$i] := RakuAST::IntLiteral.new($arg); } ++$i; } $obj }); add-method(RakuAST::Nqp, 'set-args', [RakuAST::Nqp, '', 0, 0, Any, '$args', 0, 0], anon sub set-args ($SELF_CONT, $args!) { my $SELF := nqp::decont($SELF_CONT); $args := nqp::decont($args); #line 53 src/Raku/ast/nqp.rakumod my $arglist := nqp::create(RakuAST::ArgList); nqp::bindattr($arglist, RakuAST::ArgList, '$!args', $args); nqp::bindattr($SELF, RakuAST::Nqp, '$!args', $arglist); }); add-method(RakuAST::Nqp, 'visit-children', [RakuAST::Nqp, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 59 src/Raku/ast/nqp.rakumod my @args := nqp::getattr($SELF.args, RakuAST::ArgList, '$!args'); for @args { $visitor($_); } }); add-method(RakuAST::Nqp, 'IMPL-EXPR-QAST', [RakuAST::Nqp, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 66 src/Raku/ast/nqp.rakumod my $call := QAST::Op.new(:op(nqp::getattr($SELF, RakuAST::Nqp, '$!op'))); nqp::getattr($SELF, RakuAST::Nqp, '$!args').IMPL-ADD-QAST-ARGS($context, $call); # We generally want to send unboxed string/int values in for dispatch # arguments (although leave normal ones alone); we can't really # know which are which, but if we're writing out an `nqp::op` # just assume that they should all be unboxed; most situations # will see the dispatch op generated anyway. my int $i := 0; my int $n := nqp::elems($call.list); while $i < $n { my $arg := $call[$i]; if nqp::istype($arg, QAST::Want) && ($arg[1] eq 'Ss' || $arg[1] eq 'Ii') { $call[$i] := $arg[2]; } $i++; } $call }); #line 5 src/Raku/ast/nqp.rakumod add-method(RakuAST::Nqp, 'op', [], anon sub op ($self) { nqp::getattr(nqp::decont($self), RakuAST::Nqp, '$!op') }); #line 6 src/Raku/ast/nqp.rakumod add-method(RakuAST::Nqp, 'args', [], anon sub args ($self) { nqp::getattr(nqp::decont($self), RakuAST::Nqp, '$!args') }); compose(RakuAST::Nqp); parent(RakuAST::Nqp::Const, RakuAST::Expression); add-attribute(RakuAST::Nqp::Const, Str, '$!name'); add-method(RakuAST::Nqp::Const, 'new', [RakuAST::Nqp::Const, '', 0, 0, Str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 94 src/Raku/ast/nqp.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Nqp::Const, '$!name', $name); $obj }); add-method(RakuAST::Nqp::Const, 'IMPL-EXPR-QAST', [RakuAST::Nqp::Const, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 100 src/Raku/ast/nqp.rakumod QAST::Op.new(:op, :name(nqp::getattr($SELF, RakuAST::Nqp::Const, '$!name'))); }); #line 92 src/Raku/ast/nqp.rakumod add-method(RakuAST::Nqp::Const, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Nqp::Const, '$!name') }); compose(RakuAST::Nqp::Const); parent(RakuAST::Term::Name, RakuAST::Term); parent(RakuAST::Term::Name, RakuAST::Lookup); add-attribute(RakuAST::Term::Name, RakuAST::Name, '$!name'); add-attribute(RakuAST::Term::Name, Mu, '$!package'); add-method(RakuAST::Term::Name, 'new', [RakuAST::Term::Name, '', 0, 0, RakuAST::Name, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 11 src/Raku/ast/term.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Term::Name, '$!name', $name); $obj }); add-method(RakuAST::Term::Name, 'attach', [RakuAST::Term::Name, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 17 src/Raku/ast/term.rakumod my $package := $resolver.find-attach-target('package'); nqp::bindattr($SELF, RakuAST::Term::Name, '$!package', $package); }); add-method(RakuAST::Term::Name, 'resolve-with', [RakuAST::Term::Name, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 22 src/Raku/ast/term.rakumod my $resolved := $resolver.resolve-name(nqp::getattr($SELF, RakuAST::Term::Name, '$!name')); if $resolved { $SELF.set-resolution($resolved); } elsif nqp::getattr($SELF, RakuAST::Term::Name, '$!name').is-package-lookup { my $name := nqp::getattr($SELF, RakuAST::Term::Name, '$!name').base-name; if $name.canonicalize { $resolved := $resolver.resolve-name($name); if $resolved { my $v := $resolved.compile-time-value; $SELF.set-resolution($resolved); } } } Nil }); add-method(RakuAST::Term::Name, 'IMPL-EXPR-QAST', [RakuAST::Term::Name, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 40 src/Raku/ast/term.rakumod if nqp::getattr($SELF, RakuAST::Term::Name, '$!name').is-pseudo-package { nqp::getattr($SELF, RakuAST::Term::Name, '$!name').IMPL-QAST-PSEUDO-PACKAGE-LOOKUP($context); } elsif nqp::getattr($SELF, RakuAST::Term::Name, '$!name').is-package-lookup { return $SELF.is-resolved ?? nqp::getattr($SELF, RakuAST::Term::Name, '$!name').IMPL-QAST-PACKAGE-LOOKUP( $context, nqp::getattr($SELF, RakuAST::Term::Name, '$!package'), :lexical($SELF.resolution) ) !! nqp::getattr($SELF, RakuAST::Term::Name, '$!name').IMPL-QAST-PACKAGE-LOOKUP( $context, nqp::getattr($SELF, RakuAST::Term::Name, '$!package') ); } elsif nqp::getattr($SELF, RakuAST::Term::Name, '$!name').is-indirect-lookup { return nqp::getattr($SELF, RakuAST::Term::Name, '$!name').IMPL-QAST-INDIRECT-LOOKUP($context); } else { $SELF.resolution.IMPL-LOOKUP-QAST($context) } }); add-method(RakuAST::Term::Name, 'visit-children', [RakuAST::Term::Name, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 64 src/Raku/ast/term.rakumod $visitor(nqp::getattr($SELF, RakuAST::Term::Name, '$!name')); }); #line 8 src/Raku/ast/term.rakumod add-method(RakuAST::Term::Name, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Term::Name, '$!name') }); compose(RakuAST::Term::Name); parent(RakuAST::Term::True, Any); add-method(RakuAST::Term::True, 'new', [RakuAST::Term::True, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 71 src/Raku/ast/term.rakumod RakuAST::Term::Name.new(RakuAST::Name.from-identifier("True")) }); compose(RakuAST::Term::True); parent(RakuAST::Term::False, Any); add-method(RakuAST::Term::False, 'new', [RakuAST::Term::False, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 78 src/Raku/ast/term.rakumod RakuAST::Term::Name.new(RakuAST::Name.from-identifier("False")) }); compose(RakuAST::Term::False); parent(RakuAST::Term::Self, RakuAST::Term); parent(RakuAST::Term::Self, RakuAST::Lookup); parent(RakuAST::Term::Self, RakuAST::CheckTime); add-method(RakuAST::Term::Self, 'new', [RakuAST::Term::Self, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 89 src/Raku/ast/term.rakumod nqp::create($SELF) }); add-method(RakuAST::Term::Self, 'resolve-with', [RakuAST::Term::Self, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 93 src/Raku/ast/term.rakumod my $resolved := $resolver.resolve-lexical('self'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Term::Self, 'PERFORM-CHECK', [RakuAST::Term::Self, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 101 src/Raku/ast/term.rakumod unless $SELF.is-resolved { $SELF.add-sorry: $resolver.build-exception: 'X::Syntax::Self::WithoutObject'; } }); add-method(RakuAST::Term::Self, 'IMPL-EXPR-QAST', [RakuAST::Term::Self, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 108 src/Raku/ast/term.rakumod $SELF.resolution.IMPL-LOOKUP-QAST($context) }); compose(RakuAST::Term::Self); parent(RakuAST::Term::TopicCall, RakuAST::Term); parent(RakuAST::Term::TopicCall, RakuAST::ImplicitLookups); add-attribute(RakuAST::Term::TopicCall, RakuAST::Postfixish, '$!call'); add-method(RakuAST::Term::TopicCall, 'new', [RakuAST::Term::TopicCall, '', 0, 0, RakuAST::Postfixish, '$call', 0, 0], anon sub new ($SELF_CONT, $call!) { my $SELF := nqp::decont($SELF_CONT); $call := nqp::decont($call); #line 120 src/Raku/ast/term.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Term::TopicCall, '$!call', $call); $obj }); add-method(RakuAST::Term::TopicCall, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Term::TopicCall, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 126 src/Raku/ast/term.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical.new('$_'), ]) }); add-method(RakuAST::Term::TopicCall, 'IMPL-EXPR-QAST', [RakuAST::Term::TopicCall, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 132 src/Raku/ast/term.rakumod nqp::getattr($SELF, RakuAST::Term::TopicCall, '$!call').IMPL-POSTFIX-QAST( $context, $SELF.get-implicit-lookups.AT-POS(0).resolution.IMPL-LOOKUP-QAST($context) ) }); add-method(RakuAST::Term::TopicCall, 'visit-children', [RakuAST::Term::TopicCall, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 139 src/Raku/ast/term.rakumod $visitor(nqp::getattr($SELF, RakuAST::Term::TopicCall, '$!call')); }); #line 118 src/Raku/ast/term.rakumod add-method(RakuAST::Term::TopicCall, 'call', [], anon sub call ($self) { nqp::getattr(nqp::decont($self), RakuAST::Term::TopicCall, '$!call') }); compose(RakuAST::Term::TopicCall); parent(RakuAST::Term::Named, RakuAST::Term); parent(RakuAST::Term::Named, RakuAST::Lookup); add-attribute(RakuAST::Term::Named, str, '$!name'); add-method(RakuAST::Term::Named, 'new', [RakuAST::Term::Named, '', 0, 0, str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 151 src/Raku/ast/term.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Term::Named, '$!name', $name); $obj }); add-method(RakuAST::Term::Named, 'resolve-with', [RakuAST::Term::Named, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 157 src/Raku/ast/term.rakumod my $resolved := $resolver.resolve-term(nqp::getattr_s($SELF, RakuAST::Term::Named, '$!name')); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Term::Named, 'IMPL-EXPR-QAST', [RakuAST::Term::Named, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 165 src/Raku/ast/term.rakumod QAST::Op.new( :op('call'), :name($SELF.resolution.lexical-name) ) }); #line 149 src/Raku/ast/term.rakumod add-method(RakuAST::Term::Named, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Term::Named, '$!name') }); compose(RakuAST::Term::Named); parent(RakuAST::Term::EmptySet, RakuAST::Term); parent(RakuAST::Term::EmptySet, RakuAST::Lookup); add-method(RakuAST::Term::EmptySet, 'new', [RakuAST::Term::EmptySet, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 175 src/Raku/ast/term.rakumod nqp::create($SELF) }); add-method(RakuAST::Term::EmptySet, 'resolve-with', [RakuAST::Term::EmptySet, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 179 src/Raku/ast/term.rakumod my $resolved := $resolver.resolve-lexical('&set'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Term::EmptySet, 'IMPL-EXPR-QAST', [RakuAST::Term::EmptySet, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 187 src/Raku/ast/term.rakumod QAST::Op.new( :op('call'), :name($SELF.resolution.lexical-name) ) }); compose(RakuAST::Term::EmptySet); parent(RakuAST::Term::Rand, RakuAST::Term); parent(RakuAST::Term::Rand, RakuAST::Lookup); add-method(RakuAST::Term::Rand, 'new', [RakuAST::Term::Rand, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 197 src/Raku/ast/term.rakumod nqp::create($SELF) }); add-method(RakuAST::Term::Rand, 'resolve-with', [RakuAST::Term::Rand, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 201 src/Raku/ast/term.rakumod my $resolved := $resolver.resolve-lexical('&rand'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Term::Rand, 'IMPL-EXPR-QAST', [RakuAST::Term::Rand, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 209 src/Raku/ast/term.rakumod QAST::Op.new( :op('call'), :name($SELF.resolution.lexical-name) ) }); compose(RakuAST::Term::Rand); parent(RakuAST::Term::Whatever, RakuAST::Term); parent(RakuAST::Term::Whatever, RakuAST::Attaching); add-attribute(RakuAST::Term::Whatever, RakuAST::CompUnit, '$!enclosing-comp-unit'); add-method(RakuAST::Term::Whatever, 'new', [RakuAST::Term::Whatever, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 221 src/Raku/ast/term.rakumod nqp::create($SELF) }); add-method(RakuAST::Term::Whatever, 'attach', [RakuAST::Term::Whatever, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 225 src/Raku/ast/term.rakumod my $compunit := $resolver.find-attach-target('compunit'); $compunit.ensure-singleton-whatever($resolver); nqp::bindattr($SELF, RakuAST::Term::Whatever, '$!enclosing-comp-unit', $compunit); }); add-method(RakuAST::Term::Whatever, 'IMPL-EXPR-QAST', [RakuAST::Term::Whatever, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 231 src/Raku/ast/term.rakumod my $whatever := nqp::getattr($SELF, RakuAST::Term::Whatever, '$!enclosing-comp-unit').singleton-whatever(); $context.ensure-sc($whatever); QAST::WVal.new( :value($whatever), :returns($whatever) ) }); compose(RakuAST::Term::Whatever); parent(RakuAST::WhateverCode::Argument, RakuAST::Term); parent(RakuAST::WhateverCode::Argument, RakuAST::Lookup); add-attribute(RakuAST::WhateverCode::Argument, RakuAST::Name, '$!name'); add-method(RakuAST::WhateverCode::Argument, 'new', [RakuAST::WhateverCode::Argument, '', 0, 0, RakuAST::Name, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 246 src/Raku/ast/term.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::WhateverCode::Argument, '$!name', $name); $obj }); add-method(RakuAST::WhateverCode::Argument, 'resolve-with', [RakuAST::WhateverCode::Argument, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 252 src/Raku/ast/term.rakumod my $resolved := $resolver.resolve-name(nqp::getattr($SELF, RakuAST::WhateverCode::Argument, '$!name')); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::WhateverCode::Argument, 'IMPL-EXPR-QAST', [RakuAST::WhateverCode::Argument, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 260 src/Raku/ast/term.rakumod $SELF.resolution.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::WhateverCode::Argument, 'dump-markers', [RakuAST::WhateverCode::Argument, '', 0, 0], anon sub dump-markers ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 264 src/Raku/ast/term.rakumod '🔆' }); compose(RakuAST::WhateverCode::Argument); parent(RakuAST::Term::HyperWhatever, RakuAST::Term); parent(RakuAST::Term::HyperWhatever, RakuAST::Attaching); add-attribute(RakuAST::Term::HyperWhatever, RakuAST::CompUnit, '$!enclosing-comp-unit'); add-method(RakuAST::Term::HyperWhatever, 'new', [RakuAST::Term::HyperWhatever, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 276 src/Raku/ast/term.rakumod nqp::create($SELF) }); add-method(RakuAST::Term::HyperWhatever, 'attach', [RakuAST::Term::HyperWhatever, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 280 src/Raku/ast/term.rakumod my $compunit := $resolver.find-attach-target('compunit'); $compunit.ensure-singleton-hyper-whatever($resolver); nqp::bindattr($SELF, RakuAST::Term::HyperWhatever, '$!enclosing-comp-unit', $compunit); }); add-method(RakuAST::Term::HyperWhatever, 'IMPL-EXPR-QAST', [RakuAST::Term::HyperWhatever, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 286 src/Raku/ast/term.rakumod my $whatever := nqp::getattr($SELF, RakuAST::Term::HyperWhatever, '$!enclosing-comp-unit').singleton-hyper-whatever(); $context.ensure-sc($whatever); QAST::WVal.new( :value($whatever) ) }); compose(RakuAST::Term::HyperWhatever); parent(RakuAST::Term::Capture, RakuAST::Term); add-attribute(RakuAST::Term::Capture, RakuAST::CaptureSource, '$!source'); add-method(RakuAST::Term::Capture, 'new', [RakuAST::Term::Capture, '', 0, 0, RakuAST::CaptureSource, '$source', 0, 0], anon sub new ($SELF_CONT, $source!) { my $SELF := nqp::decont($SELF_CONT); $source := nqp::decont($source); #line 299 src/Raku/ast/term.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Term::Capture, '$!source', $source); $obj }); add-method(RakuAST::Term::Capture, 'IMPL-EXPR-QAST', [RakuAST::Term::Capture, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 305 src/Raku/ast/term.rakumod my $op := QAST::Op.new( :op('callmethod'), :name('from-args'), QAST::WVal.new( :value(Capture) ), ); if nqp::istype(nqp::getattr($SELF, RakuAST::Term::Capture, '$!source'), RakuAST::ArgList) { nqp::getattr($SELF, RakuAST::Term::Capture, '$!source').IMPL-ADD-QAST-ARGS($context, $op); } else { $op.push(nqp::getattr($SELF, RakuAST::Term::Capture, '$!source').IMPL-TO-QAST($context)); } $op }); add-method(RakuAST::Term::Capture, 'visit-children', [RakuAST::Term::Capture, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 320 src/Raku/ast/term.rakumod $visitor(nqp::getattr($SELF, RakuAST::Term::Capture, '$!source')); }); #line 297 src/Raku/ast/term.rakumod add-method(RakuAST::Term::Capture, 'source', [], anon sub source ($self) { nqp::getattr(nqp::decont($self), RakuAST::Term::Capture, '$!source') }); compose(RakuAST::Term::Capture); parent(RakuAST::Term::Reduce, RakuAST::Term); parent(RakuAST::Term::Reduce, RakuAST::CheckTime); parent(RakuAST::Term::Reduce, RakuAST::ImplicitLookups); add-attribute(RakuAST::Term::Reduce, RakuAST::Infixish, '$!infix'); add-attribute(RakuAST::Term::Reduce, RakuAST::ArgList, '$!args'); add-attribute(RakuAST::Term::Reduce, Bool, '$!triangle'); add-method(RakuAST::Term::Reduce, 'new', [RakuAST::Term::Reduce, '', 0, 0, RakuAST::Infixish, '$infix', 1, 0, RakuAST::ArgList, '$args', 1, 0, Bool, '$triangle', 1, 1], anon sub new ($SELF_CONT, :$infix!, :$args!, :$triangle?) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); $args := nqp::decont($args); $triangle := nqp::decont($triangle); #line 335 src/Raku/ast/term.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Term::Reduce, '$!infix', $infix); nqp::bindattr($obj, RakuAST::Term::Reduce, '$!args', $args); nqp::bindattr($obj, RakuAST::Term::Reduce, '$!triangle', $triangle ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Term::Reduce, 'PERFORM-CHECK', [RakuAST::Term::Reduce, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 346 src/Raku/ast/term.rakumod (my $reason := $SELF.properties.not-reducable) ?? $SELF.add-sorry( $resolver.build-exception("X::Syntax::CannotMeta", meta => "reduce", operator => $SELF.infix.operator, dba => $SELF.properties.dba, reason => $reason ) ) !! (Bool.WHO) }); add-method(RakuAST::Term::Reduce, 'properties', [RakuAST::Term::Reduce, '', 0, 0], anon sub properties ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 359 src/Raku/ast/term.rakumod nqp::getattr($SELF, RakuAST::Term::Reduce, '$!infix').properties }); add-method(RakuAST::Term::Reduce, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Term::Reduce, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 361 src/Raku/ast/term.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical.new('&infix:<,>'), ]) }); add-method(RakuAST::Term::Reduce, 'IMPL-EXPR-QAST', [RakuAST::Term::Reduce, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 367 src/Raku/ast/term.rakumod # Make a call to form the meta-op. # TODO Cache it using a dispatcher when UNIT/SETTING operator my $form-meta := QAST::Op.new( :op, :name(nqp::getattr($SELF, RakuAST::Term::Reduce, '$!infix').reducer-name), nqp::getattr($SELF, RakuAST::Term::Reduce, '$!infix').IMPL-HOP-INFIX-QAST($context)); if nqp::getattr($SELF, RakuAST::Term::Reduce, '$!triangle') { $form-meta.push(QAST::WVal.new( :value((Bool.WHO)) )); } # Invoke it with the arguments. if nqp::getattr($SELF, RakuAST::Term::Reduce, '$!args').IMPL-IS-ONE-POS-ARG { # One-arg rule case, so just extract the argument my $arg := $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Term::Reduce, '$!args').args)[0]; QAST::Op.new( :op, $form-meta, $arg.IMPL-TO-QAST($context) ) } else { # Form a List of the argumnets and pass it to the reducer # TODO thunk case my $name := $SELF.get-implicit-lookups.AT-POS(0).resolution.lexical-name; my $form-list := QAST::Op.new(:op('call'), :$name); nqp::getattr($SELF, RakuAST::Term::Reduce, '$!args').IMPL-ADD-QAST-ARGS($context, $form-list); QAST::Op.new( :op, $form-meta, $form-list ) } }); add-method(RakuAST::Term::Reduce, 'visit-children', [RakuAST::Term::Reduce, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 394 src/Raku/ast/term.rakumod $visitor(nqp::getattr($SELF, RakuAST::Term::Reduce, '$!infix')); $visitor(nqp::getattr($SELF, RakuAST::Term::Reduce, '$!args')); }); #line 333 src/Raku/ast/term.rakumod add-method(RakuAST::Term::Reduce, 'triangle', [], anon sub triangle ($self) { nqp::getattr(nqp::decont($self), RakuAST::Term::Reduce, '$!triangle') }); #line 331 src/Raku/ast/term.rakumod add-method(RakuAST::Term::Reduce, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::Term::Reduce, '$!infix') }); #line 332 src/Raku/ast/term.rakumod add-method(RakuAST::Term::Reduce, 'args', [], anon sub args ($self) { nqp::getattr(nqp::decont($self), RakuAST::Term::Reduce, '$!args') }); compose(RakuAST::Term::Reduce); parent(RakuAST::Term::RadixNumber, RakuAST::Term); add-attribute(RakuAST::Term::RadixNumber, Int, '$!radix'); add-attribute(RakuAST::Term::RadixNumber, RakuAST::Circumfix, '$!value'); add-attribute(RakuAST::Term::RadixNumber, Bool, '$!multi-part'); add-method(RakuAST::Term::RadixNumber, 'new', [RakuAST::Term::RadixNumber, '', 0, 0, Int, '$radix', 1, 0, RakuAST::Circumfix, '$value', 1, 0, Bool, '$multi-part', 1, 1], anon sub new ($SELF_CONT, :$radix!, :$value!, :$multi-part?) { my $SELF := nqp::decont($SELF_CONT); $radix := nqp::decont($radix); $value := nqp::decont($value); $multi-part := nqp::decont($multi-part); #line 409 src/Raku/ast/term.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Term::RadixNumber, '$!radix', $radix); nqp::bindattr($obj, RakuAST::Term::RadixNumber, '$!value', $value); nqp::bindattr($obj, RakuAST::Term::RadixNumber, '$!multi-part', $multi-part ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Term::RadixNumber, 'IMPL-EXPR-QAST', [RakuAST::Term::RadixNumber, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 418 src/Raku/ast/term.rakumod $context.ensure-sc(nqp::getattr($SELF, RakuAST::Term::RadixNumber, '$!radix')); QAST::Op.new: :op('call'), :name(nqp::getattr($SELF, RakuAST::Term::RadixNumber, '$!multi-part') ?? '&UNBASE_BRACKET' !! '&UNBASE'), QAST::WVal.new( :value(nqp::getattr($SELF, RakuAST::Term::RadixNumber, '$!radix')) ), nqp::getattr($SELF, RakuAST::Term::RadixNumber, '$!value').IMPL-TO-QAST($context) }); add-method(RakuAST::Term::RadixNumber, 'visit-children', [RakuAST::Term::RadixNumber, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 426 src/Raku/ast/term.rakumod $visitor(nqp::getattr($SELF, RakuAST::Term::RadixNumber, '$!value')); }); #line 406 src/Raku/ast/term.rakumod add-method(RakuAST::Term::RadixNumber, 'value', [], anon sub value ($self) { nqp::getattr(nqp::decont($self), RakuAST::Term::RadixNumber, '$!value') }); #line 405 src/Raku/ast/term.rakumod add-method(RakuAST::Term::RadixNumber, 'radix', [], anon sub radix ($self) { nqp::getattr(nqp::decont($self), RakuAST::Term::RadixNumber, '$!radix') }); #line 407 src/Raku/ast/term.rakumod add-method(RakuAST::Term::RadixNumber, 'multi-part', [], anon sub multi-part ($self) { nqp::getattr(nqp::decont($self), RakuAST::Term::RadixNumber, '$!multi-part') }); compose(RakuAST::Term::RadixNumber); parent(RakuAST::Name, RakuAST::ImplicitLookups); parent(RakuAST::Name, RakuAST::Attaching); add-attribute(RakuAST::Name, List, '$!parts'); add-attribute(RakuAST::Name, List, '$!colonpairs'); add-attribute(RakuAST::Name, Mu, '$!setting'); add-method(RakuAST::Name, 'new', [RakuAST::Name, '', 0, 0, Any, '@parts', 0, 0], anon sub new ($SELF_CONT, *@parts) { my $SELF := nqp::decont($SELF_CONT); @parts := nqp::decont(@parts); #line 11 src/Raku/ast/name.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Name, '$!parts', @parts); nqp::bindattr($obj, RakuAST::Name, '$!colonpairs', []); $obj }); add-method(RakuAST::Name, 'attach', [RakuAST::Name, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 18 src/Raku/ast/name.rakumod # Might be needed for resolving CORE:: in dynamically compiled frames nqp::bindattr($SELF, RakuAST::Name, '$!setting', $resolver.setting); }); add-method(RakuAST::Name, 'from-identifier', [RakuAST::Name, '', 0, 0, Str, '$identifier', 0, 0], anon sub from-identifier ($SELF_CONT, $identifier!) { my $SELF := nqp::decont($SELF_CONT); $identifier := nqp::decont($identifier); #line 23 src/Raku/ast/name.rakumod $SELF.new(RakuAST::Name::Part::Simple.new($identifier)) }); add-method(RakuAST::Name, 'from-identifier-parts', [RakuAST::Name, '', 0, 0, Any, '@identifiers', 0, 0], anon sub from-identifier-parts ($SELF_CONT, *@identifiers) { my $SELF := nqp::decont($SELF_CONT); @identifiers := nqp::decont(@identifiers); #line 27 src/Raku/ast/name.rakumod my @parts; for @identifiers { unless nqp::istype($_, Str) || nqp::isstr($_) { nqp::die('Expected identifier parts to be Str, but got ' ~ $_.HOW.name($_)); } @parts.push(RakuAST::Name::Part::Simple.new($_)); } $SELF.new(|@parts) }); add-method(RakuAST::Name, 'add-colonpair', [RakuAST::Name, '', 0, 0, RakuAST::ColonPairish, '$pair', 0, 0], anon sub add-colonpair ($SELF_CONT, $pair!) { my $SELF := nqp::decont($SELF_CONT); $pair := nqp::decont($pair); #line 38 src/Raku/ast/name.rakumod nqp::getattr($SELF, RakuAST::Name, '$!colonpairs').push: $pair; }); add-method(RakuAST::Name, 'parts', [RakuAST::Name, '', 0, 0], anon sub parts ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 42 src/Raku/ast/name.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Name, '$!parts')) }); add-method(RakuAST::Name, 'is-multi-part', [RakuAST::Name, '', 0, 0], anon sub is-multi-part ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 46 src/Raku/ast/name.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) > 1 }); add-method(RakuAST::Name, 'is-identifier', [RakuAST::Name, '', 0, 0], anon sub is-identifier ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 50 src/Raku/ast/name.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) == 1 && ( nqp::istype(nqp::getattr($SELF, RakuAST::Name, '$!parts')[0], RakuAST::Name::Part::Simple) || nqp::istype(nqp::getattr($SELF, RakuAST::Name, '$!parts')[0], RakuAST::Name::Part::Expression) && nqp::getattr($SELF, RakuAST::Name, '$!parts')[0].has-compile-time-name ) }); add-method(RakuAST::Name, 'is-empty', [RakuAST::Name, '', 0, 0], anon sub is-empty ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 57 src/Raku/ast/name.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) == 0 || (nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) == 1 && nqp::getattr($SELF, RakuAST::Name, '$!parts')[0].name eq '') }); add-method(RakuAST::Name, 'is-simple', [RakuAST::Name, '', 0, 0], anon sub is-simple ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 62 src/Raku/ast/name.rakumod for nqp::getattr($SELF, RakuAST::Name, '$!parts') { return (Bool.WHO) unless nqp::istype($_, RakuAST::Name::Part::Simple); } (Bool.WHO) }); add-method(RakuAST::Name, 'simple-identifier', [RakuAST::Name, '', 0, 0], anon sub simple-identifier ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 72 src/Raku/ast/name.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) == 1 && nqp::istype((my $obj := nqp::getattr($SELF, RakuAST::Name, '$!parts')[0]),RakuAST::Name::Part::Simple) && $obj.name }); add-method(RakuAST::Name, 'is-package-lookup', [RakuAST::Name, '', 0, 0], anon sub is-package-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 78 src/Raku/ast/name.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) && nqp::istype(nqp::getattr($SELF, RakuAST::Name, '$!parts')[nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) - 1],RakuAST::Name::Part::Empty) }); add-method(RakuAST::Name, 'base-name', [RakuAST::Name, '', 0, 0], anon sub base-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 83 src/Raku/ast/name.rakumod my @parts := nqp::clone(nqp::getattr($SELF, RakuAST::Name, '$!parts')); @parts.pop if $SELF.is-package-lookup; RakuAST::Name.new(|@parts) }); add-method(RakuAST::Name, 'is-indirect-lookup', [RakuAST::Name, '', 0, 0], anon sub is-indirect-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 89 src/Raku/ast/name.rakumod for nqp::getattr($SELF, RakuAST::Name, '$!parts') { return (Bool.WHO) if nqp::istype($_, RakuAST::Name::Part::Expression); } }); add-method(RakuAST::Name, 'has-colonpair', [RakuAST::Name, '', 0, 0, Any, '$key', 0, 0], anon sub has-colonpair ($SELF_CONT, $key!) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); #line 95 src/Raku/ast/name.rakumod for nqp::getattr($SELF, RakuAST::Name, '$!colonpairs') { return (Bool.WHO) if $_.key eq $key; } (Bool.WHO) }); add-method(RakuAST::Name, 'without-colonpair', [RakuAST::Name, '', 0, 0, Any, '$key', 0, 0], anon sub without-colonpair ($SELF_CONT, $key!) { my $SELF := nqp::decont($SELF_CONT); $key := nqp::decont($key); #line 102 src/Raku/ast/name.rakumod my @parts := nqp::clone(nqp::getattr($SELF, RakuAST::Name, '$!parts')); my $type := RakuAST::Name.new(|@parts); for nqp::getattr($SELF, RakuAST::Name, '$!colonpairs') { $type.add-colonpair($_) if !nqp::istype($_, RakuAST::ColonPair) || $_.key ne $key; } $type }); add-method(RakuAST::Name, 'without-colonpairs', [RakuAST::Name, '', 0, 0], anon sub without-colonpairs ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 111 src/Raku/ast/name.rakumod my @parts := nqp::clone(nqp::getattr($SELF, RakuAST::Name, '$!parts')); my $type := RakuAST::Name.new(|@parts); for nqp::getattr($SELF, RakuAST::Name, '$!colonpairs') { $type.add-colonpair($_) unless nqp::istype($_, RakuAST::ColonPair); } $type }); add-method(RakuAST::Name, 'visit-children', [RakuAST::Name, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 121 src/Raku/ast/name.rakumod if nqp::isconcrete($SELF) { for nqp::getattr($SELF, RakuAST::Name, '$!parts') { $_.visit-children($visitor); } for nqp::getattr($SELF, RakuAST::Name, '$!colonpairs') { $visitor($_); } } }); add-method(RakuAST::Name, 'canonicalize', [RakuAST::Name, '', 0, 0, Any, '$colonpairs', 1, 1], anon sub canonicalize ($SELF_CONT, :$colonpairs?) { my $SELF := nqp::decont($SELF_CONT); $colonpairs := nqp::decont($colonpairs); #line 132 src/Raku/ast/name.rakumod my $canon-parts := nqp::list_s(); for nqp::getattr($SELF, RakuAST::Name, '$!parts') { if nqp::istype($_, RakuAST::Name::Part::Simple) { nqp::push_s($canon-parts, $_.name); } elsif nqp::istype($_, RakuAST::Name::Part::Empty) { nqp::push_s($canon-parts, ''); } elsif nqp::istype($_, RakuAST::Name::Part::Expression) { if $_.has-compile-time-name { nqp::push_s($canon-parts, $_.name); } else { nqp::push_s($canon-parts, '') if nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) == 1; nqp::push_s($canon-parts, '(' ~ $_.expr.DEPARSE ~ ')'); } } else { nqp::die('canonicalize NYI for non-simple name part ' ~ $_.HOW.name($_)); } } my $name := nqp::join('::', $canon-parts); unless nqp::isconcrete($colonpairs) && !$colonpairs { for nqp::getattr($SELF, RakuAST::Name, '$!colonpairs') { if nqp::istype($_, RakuAST::ColonPairish) { $name := $name ~ ':' ~ $_.canonicalize; } else { nqp::die('canonicalize NYI for non-simple colonpairs: ' ~ $_.HOW.name($_)); } } } $name }); add-method(RakuAST::Name, 'is-pseudo-package', [RakuAST::Name, '', 0, 0], anon sub is-pseudo-package ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 168 src/Raku/ast/name.rakumod nqp::istype(nqp::getattr($SELF, RakuAST::Name, '$!parts')[0], RakuAST::Name::Part::Simple) && nqp::getattr($SELF, RakuAST::Name, '$!parts')[0].is-pseudo-package || nqp::istype(nqp::getattr($SELF, RakuAST::Name, '$!parts')[0], RakuAST::Name::Part::Empty) }); add-method(RakuAST::Name, 'qualified-with', [RakuAST::Name, '', 0, 0, RakuAST::Name, '$target', 0, 0], anon sub qualified-with ($SELF_CONT, $target!) { my $SELF := nqp::decont($SELF_CONT); $target := nqp::decont($target); #line 173 src/Raku/ast/name.rakumod my $qualified := nqp::clone($SELF); my @parts := nqp::clone(nqp::getattr($target, RakuAST::Name, '$!parts')); for nqp::getattr($SELF, RakuAST::Name, '$!parts') { nqp::push(@parts, $_); } nqp::bindattr($qualified, RakuAST::Name, '$!parts', @parts); $qualified }); add-method(RakuAST::Name, 'contains-pseudo-package-illegal-for-declaration', [RakuAST::Name, '', 0, 0], anon sub contains-pseudo-package-illegal-for-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 183 src/Raku/ast/name.rakumod return 'GLOBAL' if $SELF.is-identifier && nqp::getattr($SELF, RakuAST::Name, '$!parts')[0].name eq 'GLOBAL'; for nqp::getattr($SELF, RakuAST::Name, '$!parts') { return $_.name if $_.is-pseudo-package || nqp::istype($_, RakuAST::Name::Part::Simple) && $_.name eq 'PROCESS'; } Nil }); add-method(RakuAST::Name, 'dump-markers', [RakuAST::Name, '', 0, 0], anon sub dump-markers ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 193 src/Raku/ast/name.rakumod '【' ~ $SELF.canonicalize ~ '】' }); add-method(RakuAST::Name, 'IMPL-IS-NQP-OP', [RakuAST::Name, '', 0, 0], anon sub IMPL-IS-NQP-OP ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 197 src/Raku/ast/name.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) == 2 && nqp::istype(nqp::getattr($SELF, RakuAST::Name, '$!parts')[0], RakuAST::Name::Part::Simple) && nqp::getattr($SELF, RakuAST::Name, '$!parts')[0].name eq 'nqp' ?? nqp::getattr($SELF, RakuAST::Name, '$!parts')[1].name !! '' }); add-method(RakuAST::Name, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Name, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 203 src/Raku/ast/name.rakumod $SELF.IMPL-WRAP-LIST( $SELF.is-simple && !$SELF.is-pseudo-package ?? [] !! [ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('&INDIRECT_NAME_LOOKUP')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('PseudoStash')), ] ) }); add-method(RakuAST::Name, 'IMPL-QAST-PSEUDO-PACKAGE-LOOKUP', [RakuAST::Name, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$sigil', 1, 1], anon sub IMPL-QAST-PSEUDO-PACKAGE-LOOKUP ($SELF_CONT, $context!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $sigil := nqp::decont($sigil); #line 214 src/Raku/ast/name.rakumod my $final := nqp::getattr($SELF, RakuAST::Name, '$!parts')[nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) - 1]; my $PseudoStash-lookup := $SELF.get-implicit-lookups.AT-POS(1); my $result; if $*IMPL-COMPILE-DYNAMICALLY && nqp::getattr($SELF, RakuAST::Name, '$!parts')[0].name eq 'CORE' { nqp::shift(nqp::getattr($SELF, RakuAST::Name, '$!parts')); #FIXME don't modify please my $PseudoStash := $PseudoStash-lookup.resolution.compile-time-value; my $stash := nqp::create($PseudoStash); my $found-ctx := nqp::getattr($SELF, RakuAST::Name, '$!setting'); nqp::bindattr($stash, Map, '$!storage', nqp::ctxlexpad($found-ctx)), nqp::bindattr($stash, $PseudoStash, '$!ctx', $found-ctx), nqp::bindattr_i($stash, $PseudoStash, '$!mode', STATIC_CHAIN), nqp::setwho(Perl6::Metamodel::ModuleHOW.new_type(:name('CORE')), $stash); $context.ensure-sc($stash); $result := QAST::WVal.new(:value($stash)); } else { $result := QAST::Op.new( :op, :name, $PseudoStash-lookup.IMPL-TO-QAST($context) ); } my $first := 1; for nqp::getattr($SELF, RakuAST::Name, '$!parts') { if $first { # don't call .WHO on the pseudo package itself, index into it instead $first := 0; } else { # get the Stash from all real packages $result := QAST::Op.new( :op('who'), $result ); } $result := $_.IMPL-QAST-PSEUDO-PACKAGE-LOOKUP-PART($context, $result, $_ =:= $final, :$sigil); } $result }); add-method(RakuAST::Name, 'IMPL-QAST-PACKAGE-LOOKUP', [RakuAST::Name, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$start-package', 0, 0, RakuAST::Declaration, '$lexical', 1, 1, str, '$sigil', 1, 1, Bool, '$global-fallback', 1, 1], anon sub IMPL-QAST-PACKAGE-LOOKUP ($SELF_CONT, $context!, $start-package!, :$lexical?, :$sigil?, :$global-fallback?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $start-package := nqp::decont($start-package); $lexical := nqp::decont($lexical); $sigil := nqp::decont($sigil); $global-fallback := nqp::decont($global-fallback); #line 250 src/Raku/ast/name.rakumod my $result := QAST::WVal.new(:value($start-package)); my $final := nqp::getattr($SELF, RakuAST::Name, '$!parts')[nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) - 1]; my int $first := 0; if nqp::istype(nqp::getattr($SELF, RakuAST::Name, '$!parts')[0], RakuAST::Name::Part::Simple) && nqp::getattr($SELF, RakuAST::Name, '$!parts')[0].name eq 'GLOBAL' { $result := QAST::Op.new(:op, QAST::SVal.new(:value)); $first := 1; } elsif $lexical { $first := 1; $result := $lexical.IMPL-LOOKUP-QAST($context); return QAST::Op.new(:op, $result); } if $SELF.is-pseudo-package { $result := $SELF.IMPL-QAST-PSEUDO-PACKAGE-LOOKUP($context, :$sigil); } else { for nqp::getattr($SELF, RakuAST::Name, '$!parts') { if $first { # skip GLOBAL or lexically found first part, already taken care of $first := 0; } else { # get the Stash from all real packages # We do .WHO on the current package, followed by the index into it. $result := QAST::Op.new( :op('who'), $result ); $result := $_.IMPL-QAST-PACKAGE-LOOKUP-PART($context, $result, $_ =:= $final, :$sigil, :$global-fallback); } } } $result }); add-method(RakuAST::Name, 'IMPL-QAST-INDIRECT-LOOKUP', [RakuAST::Name, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$sigil', 1, 1], anon sub IMPL-QAST-INDIRECT-LOOKUP ($SELF_CONT, $context!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $sigil := nqp::decont($sigil); #line 281 src/Raku/ast/name.rakumod my $final := nqp::getattr($SELF, RakuAST::Name, '$!parts')[nqp::elems(nqp::getattr($SELF, RakuAST::Name, '$!parts')) - 1]; my $lookups := $SELF.get-implicit-lookups; my $result := QAST::Op.new( :op, $lookups.AT-POS(0).IMPL-TO-QAST($context), QAST::Op.new( :op, :name, $lookups.AT-POS(1).IMPL-TO-QAST($context), ), ); nqp::push($result, QAST::SVal.new(:value($sigil))) if $sigil; for nqp::getattr($SELF, RakuAST::Name, '$!parts') { nqp::push($result, $_.IMPL-QAST-INDIRECT-LOOKUP-PART($context, $result, $_ =:= $final)); } $result }); #line 8 src/Raku/ast/name.rakumod add-method(RakuAST::Name, 'colonpairs', [], anon sub colonpairs ($self) { nqp::getattr(nqp::decont($self), RakuAST::Name, '$!colonpairs') }); compose(RakuAST::Name); parent(RakuAST::Name::Part, Any); add-method(RakuAST::Name::Part, 'is-pseudo-package', [RakuAST::Name::Part, '', 0, 0], anon sub is-pseudo-package ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 303 src/Raku/ast/name.rakumod (Bool.WHO) }); add-method(RakuAST::Name::Part, 'visit-children', [RakuAST::Name::Part, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 307 src/Raku/ast/name.rakumod }); compose(RakuAST::Name::Part); parent(RakuAST::Name::Part::Simple, RakuAST::Name::Part); add-attribute(RakuAST::Name::Part::Simple, str, '$!name'); add-method(RakuAST::Name::Part::Simple, 'new', [RakuAST::Name::Part::Simple, '', 0, 0, Str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 317 src/Raku/ast/name.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Name::Part::Simple, '$!name', $name); $obj }); add-method(RakuAST::Name::Part::Simple, 'is-pseudo-package', [RakuAST::Name::Part::Simple, '', 0, 0], anon sub is-pseudo-package ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 323 src/Raku/ast/name.rakumod my $name := nqp::getattr_s($SELF, RakuAST::Name::Part::Simple, '$!name'); $name eq 'CALLER' || $name eq 'CALLERS' || $name eq 'CLIENT' || $name eq 'DYNAMIC' || $name eq 'CORE' || $name eq 'LEXICAL' || $name eq 'MY' || $name eq 'OUR' || $name eq 'OUTER' || $name eq 'OUTERS' || $name eq 'SETTING' || $name eq 'UNIT' || $name eq 'COMPILING' # seems to be reserved }); add-method(RakuAST::Name::Part::Simple, 'IMPL-QAST-PACKAGE-LOOKUP-PART', [RakuAST::Name::Part::Simple, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$stash-qast', 0, 0, Int, '$is-final', 0, 0, str, '$sigil', 1, 1, Bool, '$global-fallback', 1, 1], anon sub IMPL-QAST-PACKAGE-LOOKUP-PART ($SELF_CONT, $context!, $stash-qast!, $is-final!, :$sigil?, :$global-fallback?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $stash-qast := nqp::decont($stash-qast); $is-final := nqp::decont($is-final); $sigil := nqp::decont($sigil); $global-fallback := nqp::decont($global-fallback); #line 340 src/Raku/ast/name.rakumod my $op := QAST::Op.new( :op('callmethod'), :name($is-final ?? 'AT-KEY' !! 'package_at_key'), $stash-qast, QAST::SVal.new( :value($is-final && $sigil ?? $sigil ~ nqp::getattr_s($SELF, RakuAST::Name::Part::Simple, '$!name') !! nqp::getattr_s($SELF, RakuAST::Name::Part::Simple, '$!name')) ) ); $op.push(QAST::WVal.new(:value((Bool.WHO)), :named)) if $is-final && $global-fallback; $op }); add-method(RakuAST::Name::Part::Simple, 'IMPL-QAST-PSEUDO-PACKAGE-LOOKUP-PART', [RakuAST::Name::Part::Simple, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$stash-qast', 0, 0, Int, '$is-final', 0, 0, str, '$sigil', 1, 1], anon sub IMPL-QAST-PSEUDO-PACKAGE-LOOKUP-PART ($SELF_CONT, $context!, $stash-qast!, $is-final!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $stash-qast := nqp::decont($stash-qast); $is-final := nqp::decont($is-final); $sigil := nqp::decont($sigil); #line 351 src/Raku/ast/name.rakumod QAST::Op.new( :op('call'), :name('&postcircumfix:<{ }>'), $stash-qast, QAST::SVal.new( :value($is-final && $sigil ?? $sigil ~ nqp::getattr_s($SELF, RakuAST::Name::Part::Simple, '$!name') !! nqp::getattr_s($SELF, RakuAST::Name::Part::Simple, '$!name')) ) ) }); add-method(RakuAST::Name::Part::Simple, 'IMPL-QAST-INDIRECT-LOOKUP-PART', [RakuAST::Name::Part::Simple, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$stash-qast', 0, 0, Int, '$is-final', 0, 0, str, '$sigil', 1, 1], anon sub IMPL-QAST-INDIRECT-LOOKUP-PART ($SELF_CONT, $context!, $stash-qast!, $is-final!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $stash-qast := nqp::decont($stash-qast); $is-final := nqp::decont($is-final); $sigil := nqp::decont($sigil); #line 360 src/Raku/ast/name.rakumod QAST::SVal.new( :value($is-final && $sigil ?? $sigil ~ nqp::getattr_s($SELF, RakuAST::Name::Part::Simple, '$!name') !! nqp::getattr_s($SELF, RakuAST::Name::Part::Simple, '$!name')) ) }); #line 315 src/Raku/ast/name.rakumod add-method(RakuAST::Name::Part::Simple, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Name::Part::Simple, '$!name') }); compose(RakuAST::Name::Part::Simple); parent(RakuAST::Name::Part::Expression, RakuAST::Name::Part); add-attribute(RakuAST::Name::Part::Expression, RakuAST::Expression, '$!expr'); add-method(RakuAST::Name::Part::Expression, 'new', [RakuAST::Name::Part::Expression, '', 0, 0, RakuAST::Expression, '$expr', 0, 0], anon sub new ($SELF_CONT, $expr!) { my $SELF := nqp::decont($SELF_CONT); $expr := nqp::decont($expr); #line 370 src/Raku/ast/name.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Name::Part::Expression, '$!expr', $expr); $obj }); add-method(RakuAST::Name::Part::Expression, 'IMPL-QAST-PSEUDO-PACKAGE-LOOKUP-PART', [RakuAST::Name::Part::Expression, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$stash-qast', 0, 0, Int, '$is-final', 0, 0, str, '$sigil', 1, 1], anon sub IMPL-QAST-PSEUDO-PACKAGE-LOOKUP-PART ($SELF_CONT, $context!, $stash-qast!, $is-final!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $stash-qast := nqp::decont($stash-qast); $is-final := nqp::decont($is-final); $sigil := nqp::decont($sigil); #line 376 src/Raku/ast/name.rakumod QAST::Op.new( :op('call'), :name('&postcircumfix:<{ }>'), $stash-qast, nqp::getattr($SELF, RakuAST::Name::Part::Expression, '$!expr').IMPL-TO-QAST($context), ) }); add-method(RakuAST::Name::Part::Expression, 'IMPL-QAST-PACKAGE-LOOKUP-PART', [RakuAST::Name::Part::Expression, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$stash-qast', 0, 0, Int, '$is-final', 0, 0, str, '$sigil', 1, 1, Bool, '$global-fallback', 1, 1], anon sub IMPL-QAST-PACKAGE-LOOKUP-PART ($SELF_CONT, $context!, $stash-qast!, $is-final!, :$sigil?, :$global-fallback?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $stash-qast := nqp::decont($stash-qast); $is-final := nqp::decont($is-final); $sigil := nqp::decont($sigil); $global-fallback := nqp::decont($global-fallback); #line 385 src/Raku/ast/name.rakumod QAST::Op.new( :op('callmethod'), :name($is-final ?? 'AT-KEY' !! 'package_at_key'), $stash-qast, nqp::getattr($SELF, RakuAST::Name::Part::Expression, '$!expr').IMPL-TO-QAST($context), ) }); add-method(RakuAST::Name::Part::Expression, 'IMPL-QAST-INDIRECT-LOOKUP-PART', [RakuAST::Name::Part::Expression, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$stash-qast', 0, 0, Int, '$is-final', 0, 0, str, '$sigil', 1, 1], anon sub IMPL-QAST-INDIRECT-LOOKUP-PART ($SELF_CONT, $context!, $stash-qast!, $is-final!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $stash-qast := nqp::decont($stash-qast); $is-final := nqp::decont($is-final); $sigil := nqp::decont($sigil); #line 394 src/Raku/ast/name.rakumod nqp::getattr($SELF, RakuAST::Name::Part::Expression, '$!expr').IMPL-TO-QAST($context) }); add-method(RakuAST::Name::Part::Expression, 'visit-children', [RakuAST::Name::Part::Expression, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 398 src/Raku/ast/name.rakumod $visitor(nqp::getattr($SELF, RakuAST::Name::Part::Expression, '$!expr')); }); add-method(RakuAST::Name::Part::Expression, 'has-compile-time-name', [RakuAST::Name::Part::Expression, '', 0, 0], anon sub has-compile-time-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 402 src/Raku/ast/name.rakumod nqp::defined(nqp::getattr($SELF, RakuAST::Name::Part::Expression, '$!expr').literalize) }); add-method(RakuAST::Name::Part::Expression, 'name', [RakuAST::Name::Part::Expression, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 406 src/Raku/ast/name.rakumod nqp::getattr($SELF, RakuAST::Name::Part::Expression, '$!expr').literalize // nqp::die('Name ' ~ nqp::getattr($SELF, RakuAST::Name::Part::Expression, '$!expr').DEPARSE ~ ' is not compile-time known') }); #line 368 src/Raku/ast/name.rakumod add-method(RakuAST::Name::Part::Expression, 'expr', [], anon sub expr ($self) { nqp::getattr(nqp::decont($self), RakuAST::Name::Part::Expression, '$!expr') }); compose(RakuAST::Name::Part::Expression); parent(RakuAST::Name::Part::Empty, RakuAST::Name::Part); add-method(RakuAST::Name::Part::Empty, 'new', [RakuAST::Name::Part::Empty, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 415 src/Raku/ast/name.rakumod nqp::create($SELF); }); add-method(RakuAST::Name::Part::Empty, 'IMPL-QAST-PSEUDO-PACKAGE-LOOKUP-PART', [RakuAST::Name::Part::Empty, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$stash-qast', 0, 0, Int, '$is-final', 0, 0, str, '$sigil', 1, 1], anon sub IMPL-QAST-PSEUDO-PACKAGE-LOOKUP-PART ($SELF_CONT, $context!, $stash-qast!, $is-final!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $stash-qast := nqp::decont($stash-qast); $is-final := nqp::decont($is-final); $sigil := nqp::decont($sigil); #line 419 src/Raku/ast/name.rakumod $stash-qast }); add-method(RakuAST::Name::Part::Empty, 'IMPL-QAST-PACKAGE-LOOKUP-PART', [RakuAST::Name::Part::Empty, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$stash-qast', 0, 0, Int, '$is-final', 0, 0, str, '$sigil', 1, 1, Bool, '$global-fallback', 1, 1], anon sub IMPL-QAST-PACKAGE-LOOKUP-PART ($SELF_CONT, $context!, $stash-qast!, $is-final!, :$sigil?, :$global-fallback?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $stash-qast := nqp::decont($stash-qast); $is-final := nqp::decont($is-final); $sigil := nqp::decont($sigil); $global-fallback := nqp::decont($global-fallback); #line 423 src/Raku/ast/name.rakumod $stash-qast }); add-method(RakuAST::Name::Part::Empty, 'name', [RakuAST::Name::Part::Empty, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 427 src/Raku/ast/name.rakumod "" }); compose(RakuAST::Name::Part::Empty); parent(RakuAST::Type, RakuAST::Term); parent(RakuAST::Type, RakuAST::Meta); add-method(RakuAST::Type, 'is-known-to-be', [RakuAST::Type, '', 0, 0, Mu, '$type', 0, 0], anon sub is-known-to-be ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 8 src/Raku/ast/type.rakumod nqp::die('Expected a type object') if nqp::isconcrete($type); if nqp::istype($SELF, RakuAST::Lookup) && $SELF.is-resolved { my $resolution := $SELF.resolution; if nqp::istype($resolution, RakuAST::CompileTimeValue) { return nqp::istype($resolution.compile-time-value, $type); } } 0 }); add-method(RakuAST::Type, 'is-known-to-be-exactly', [RakuAST::Type, '', 0, 0, Mu, '$type', 0, 0], anon sub is-known-to-be-exactly ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 18 src/Raku/ast/type.rakumod nqp::die('Expected a type object') if nqp::isconcrete($type); if nqp::istype($SELF, RakuAST::Lookup) && $SELF.is-resolved { my $resolution := $SELF.resolution; if nqp::istype($resolution, RakuAST::CompileTimeValue) { return $resolution.compile-time-value =:= $type; } } 0 }); add-method(RakuAST::Type, 'dba', [RakuAST::Type, '', 0, 0], anon sub dba ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 29 src/Raku/ast/type.rakumod 'type' }); add-method(RakuAST::Type, 'IMPL-BASE-TYPE', [RakuAST::Type, '', 0, 0], anon sub IMPL-BASE-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 31 src/Raku/ast/type.rakumod $SELF }); add-method(RakuAST::Type, 'IMPL-TARGET-TYPE', [RakuAST::Type, '', 0, 0], anon sub IMPL-TARGET-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 35 src/Raku/ast/type.rakumod $SELF }); compose(RakuAST::Type); parent(RakuAST::Type::Simple, RakuAST::Type); parent(RakuAST::Type::Simple, RakuAST::Lookup); add-attribute(RakuAST::Type::Simple, RakuAST::Name, '$!name'); add-method(RakuAST::Type::Simple, 'new', [RakuAST::Type::Simple, '', 0, 0, RakuAST::Name, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 47 src/Raku/ast/type.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Type::Simple, '$!name', $name); $obj }); add-method(RakuAST::Type::Simple, 'resolve-with', [RakuAST::Type::Simple, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 53 src/Raku/ast/type.rakumod my $resolved := $resolver.resolve-name-constant(nqp::getattr($SELF, RakuAST::Type::Simple, '$!name')); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Type::Simple, 'PRODUCE-META-OBJECT', [RakuAST::Type::Simple, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 61 src/Raku/ast/type.rakumod $SELF.resolution.compile-time-value }); add-method(RakuAST::Type::Simple, 'IMPL-EXPR-QAST', [RakuAST::Type::Simple, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 65 src/Raku/ast/type.rakumod my $value := $SELF.resolution.compile-time-value; if $value.HOW.archetypes.generic { QAST::Var.new( :name(nqp::getattr($SELF, RakuAST::Type::Simple, '$!name').canonicalize), :scope('lexical') ) } else { $context.ensure-sc($value); QAST::WVal.new( :$value ) } }); add-method(RakuAST::Type::Simple, 'IMPL-CAN-INTERPRET', [RakuAST::Type::Simple, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 76 src/Raku/ast/type.rakumod $SELF.is-resolved && nqp::istype($SELF.resolution, RakuAST::CompileTimeValue) }); add-method(RakuAST::Type::Simple, 'IMPL-INTERPRET', [RakuAST::Type::Simple, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 80 src/Raku/ast/type.rakumod $SELF.resolution.compile-time-value }); add-method(RakuAST::Type::Simple, 'visit-children', [RakuAST::Type::Simple, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 84 src/Raku/ast/type.rakumod $visitor(nqp::getattr($SELF, RakuAST::Type::Simple, '$!name')); }); #line 45 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Simple, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Simple, '$!name') }); compose(RakuAST::Type::Simple); parent(RakuAST::Type::Setting, RakuAST::Type::Simple); add-method(RakuAST::Type::Setting, 'resolve-with', [RakuAST::Type::Setting, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 94 src/Raku/ast/type.rakumod my $resolved := $resolver.resolve-name-constant-in-setting($SELF.name); if $resolved { $SELF.set-resolution($resolved); } Nil }); compose(RakuAST::Type::Setting); parent(RakuAST::Type::Derived, RakuAST::Type); parent(RakuAST::Type::Derived, RakuAST::Lookup); add-attribute(RakuAST::Type::Derived, RakuAST::Type, '$!base-type'); add-method(RakuAST::Type::Derived, 'resolve-with', [RakuAST::Type::Derived, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 109 src/Raku/ast/type.rakumod nqp::getattr($SELF, RakuAST::Type::Derived, '$!base-type').resolve-with($resolver); $SELF.set-resolution($SELF); Nil }); add-method(RakuAST::Type::Derived, 'IMPL-BASE-TYPE', [RakuAST::Type::Derived, '', 0, 0], anon sub IMPL-BASE-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 115 src/Raku/ast/type.rakumod nqp::istype(nqp::getattr($SELF, RakuAST::Type::Derived, '$!base-type'), RakuAST::Type::Derived) ?? nqp::getattr($SELF, RakuAST::Type::Derived, '$!base-type').IMPL-BASE-TYPE !! nqp::getattr($SELF, RakuAST::Type::Derived, '$!base-type') }); #line 107 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Derived, 'base-type', [], anon sub base-type ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Derived, '$!base-type') }); compose(RakuAST::Type::Derived); parent(RakuAST::Type::Coercion, RakuAST::Type::Derived); parent(RakuAST::Type::Coercion, RakuAST::Declaration); add-attribute(RakuAST::Type::Coercion, RakuAST::Type, '$!constraint'); add-method(RakuAST::Type::Coercion, 'new', [RakuAST::Type::Coercion, '', 0, 0, RakuAST::Type, '$base-type', 1, 0, Mu, '$constraint', 1, 1], anon sub new ($SELF_CONT, :$base-type!, :$constraint?) { my $SELF := nqp::decont($SELF_CONT); $base-type := nqp::decont($base-type); $constraint := nqp::decont($constraint); #line 126 src/Raku/ast/type.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Type::Derived, '$!base-type', $base-type); nqp::bindattr($obj, RakuAST::Type::Coercion, '$!constraint', $constraint // RakuAST::Type::Setting.new( RakuAST::Name.from-identifier("Any") ) ); $obj }); add-method(RakuAST::Type::Coercion, 'PRODUCE-META-OBJECT', [RakuAST::Type::Coercion, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 137 src/Raku/ast/type.rakumod Perl6::Metamodel::CoercionHOW.new_type( $SELF.base-type.compile-time-value, nqp::getattr($SELF, RakuAST::Type::Coercion, '$!constraint').meta-object, ); }); add-method(RakuAST::Type::Coercion, 'IMPL-EXPR-QAST', [RakuAST::Type::Coercion, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 144 src/Raku/ast/type.rakumod my $value := $SELF.meta-object; $context.ensure-sc($value); QAST::WVal.new( :$value ) }); add-method(RakuAST::Type::Coercion, 'IMPL-CAN-INTERPRET', [RakuAST::Type::Coercion, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 150 src/Raku/ast/type.rakumod nqp::istype($SELF.base-type, RakuAST::CompileTimeValue) && nqp::istype(nqp::getattr($SELF, RakuAST::Type::Coercion, '$!constraint'), RakuAST::CompileTimeValue) }); add-method(RakuAST::Type::Coercion, 'IMPL-INTERPRET', [RakuAST::Type::Coercion, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 155 src/Raku/ast/type.rakumod $SELF.meta-object }); add-method(RakuAST::Type::Coercion, 'visit-children', [RakuAST::Type::Coercion, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 159 src/Raku/ast/type.rakumod $visitor($SELF.base-type); $visitor(nqp::getattr($SELF, RakuAST::Type::Coercion, '$!constraint')); }); add-method(RakuAST::Type::Coercion, 'is-simple-lexical-declaration', [RakuAST::Type::Coercion, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 164 src/Raku/ast/type.rakumod (Bool.WHO) }); add-method(RakuAST::Type::Coercion, 'IMPL-TARGET-TYPE', [RakuAST::Type::Coercion, '', 0, 0], anon sub IMPL-TARGET-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 168 src/Raku/ast/type.rakumod my $base-type := $SELF.base-type; nqp::istype($base-type, RakuAST::Type::Coercion) ?? $base-type.IMPL-TARGET-TYPE !! $base-type }); #line 124 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Coercion, 'constraint', [], anon sub constraint ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Coercion, '$!constraint') }); compose(RakuAST::Type::Coercion); parent(RakuAST::Type::Definedness, RakuAST::Type::Derived); parent(RakuAST::Type::Definedness, RakuAST::Declaration); add-attribute(RakuAST::Type::Definedness, Bool, '$!definite'); add-method(RakuAST::Type::Definedness, 'new', [RakuAST::Type::Definedness, '', 0, 0, RakuAST::Type, '$base-type', 1, 0, Bool, '$definite', 1, 0], anon sub new ($SELF_CONT, :$base-type!, :$definite!) { my $SELF := nqp::decont($SELF_CONT); $base-type := nqp::decont($base-type); $definite := nqp::decont($definite); #line 180 src/Raku/ast/type.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Type::Derived, '$!base-type', $base-type); nqp::bindattr($obj, RakuAST::Type::Definedness, '$!definite', $definite ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Type::Definedness, 'PRODUCE-META-OBJECT', [RakuAST::Type::Definedness, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 187 src/Raku/ast/type.rakumod Perl6::Metamodel::DefiniteHOW.new_type( :base_type($SELF.base-type.compile-time-value), :definite(nqp::getattr($SELF, RakuAST::Type::Definedness, '$!definite')), ); }); add-method(RakuAST::Type::Definedness, 'IMPL-EXPR-QAST', [RakuAST::Type::Definedness, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 194 src/Raku/ast/type.rakumod my $value := $SELF.meta-object; $context.ensure-sc($value); QAST::WVal.new( :$value ) }); add-method(RakuAST::Type::Definedness, 'IMPL-CAN-INTERPRET', [RakuAST::Type::Definedness, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 200 src/Raku/ast/type.rakumod nqp::istype($SELF.base-type, RakuAST::CompileTimeValue) }); add-method(RakuAST::Type::Definedness, 'IMPL-INTERPRET', [RakuAST::Type::Definedness, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 204 src/Raku/ast/type.rakumod $SELF.meta-object }); add-method(RakuAST::Type::Definedness, 'is-simple-lexical-declaration', [RakuAST::Type::Definedness, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 208 src/Raku/ast/type.rakumod (Bool.WHO) }); add-method(RakuAST::Type::Definedness, 'visit-children', [RakuAST::Type::Definedness, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 212 src/Raku/ast/type.rakumod $visitor($SELF.base-type); }); #line 178 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Definedness, 'definite', [], anon sub definite ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Definedness, '$!definite') }); compose(RakuAST::Type::Definedness); parent(RakuAST::Type::Capture, RakuAST::Type); parent(RakuAST::Type::Capture, RakuAST::Declaration); add-attribute(RakuAST::Type::Capture, RakuAST::Name, '$!name'); add-method(RakuAST::Type::Capture, 'new', [RakuAST::Type::Capture, '', 0, 0, RakuAST::Name, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 223 src/Raku/ast/type.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Type::Capture, '$!name', $name); $obj }); add-method(RakuAST::Type::Capture, 'lexical-name', [RakuAST::Type::Capture, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 229 src/Raku/ast/type.rakumod nqp::getattr($SELF, RakuAST::Type::Capture, '$!name').canonicalize }); add-method(RakuAST::Type::Capture, 'generate-lookup', [RakuAST::Type::Capture, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 233 src/Raku/ast/type.rakumod my $lookup := RakuAST::Term::Name.new(nqp::getattr($SELF, RakuAST::Type::Capture, '$!name')); $lookup.set-resolution($SELF); $lookup }); add-method(RakuAST::Type::Capture, 'default-scope', [RakuAST::Type::Capture, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 239 src/Raku/ast/type.rakumod 'my' }); add-method(RakuAST::Type::Capture, 'allowed-scopes', [RakuAST::Type::Capture, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 241 src/Raku/ast/type.rakumod $SELF.IMPL-WRAP-LIST(['my']) }); add-method(RakuAST::Type::Capture, 'PRODUCE-META-OBJECT', [RakuAST::Type::Capture, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 243 src/Raku/ast/type.rakumod Perl6::Metamodel::GenericHOW.new_type( :name(nqp::getattr($SELF, RakuAST::Type::Capture, '$!name').canonicalize), ); }); add-method(RakuAST::Type::Capture, 'IMPL-EXPR-QAST', [RakuAST::Type::Capture, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 249 src/Raku/ast/type.rakumod $SELF.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::Type::Capture, 'IMPL-QAST-DECL', [RakuAST::Type::Capture, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 253 src/Raku/ast/type.rakumod QAST::Var.new( :decl('var'), :scope('lexical'), :name(nqp::getattr($SELF, RakuAST::Type::Capture, '$!name').canonicalize) ) }); add-method(RakuAST::Type::Capture, 'IMPL-BIND-QAST', [RakuAST::Type::Capture, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 257 src/Raku/ast/type.rakumod QAST::Op.new( :op('bind'), QAST::Var.new( :scope('lexical'), :name(nqp::getattr($SELF, RakuAST::Type::Capture, '$!name').canonicalize) ), QAST::Op.new(:op('what'), $source-qast) ) }); add-method(RakuAST::Type::Capture, 'IMPL-LOOKUP-QAST', [RakuAST::Type::Capture, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 265 src/Raku/ast/type.rakumod QAST::Var.new( :name(nqp::getattr($SELF, RakuAST::Type::Capture, '$!name').canonicalize), :scope('lexical') ) }); add-method(RakuAST::Type::Capture, 'IMPL-CAN-INTERPRET', [RakuAST::Type::Capture, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 269 src/Raku/ast/type.rakumod (Bool.WHO) }); add-method(RakuAST::Type::Capture, 'IMPL-INTERPRET', [RakuAST::Type::Capture, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 273 src/Raku/ast/type.rakumod $SELF.meta-object }); add-method(RakuAST::Type::Capture, 'visit-children', [RakuAST::Type::Capture, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 277 src/Raku/ast/type.rakumod $visitor(nqp::getattr($SELF, RakuAST::Type::Capture, '$!name')); }); #line 221 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Capture, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Capture, '$!name') }); compose(RakuAST::Type::Capture); parent(RakuAST::Type::Parameterized, RakuAST::Type::Derived); parent(RakuAST::Type::Parameterized, RakuAST::Declaration); add-attribute(RakuAST::Type::Parameterized, RakuAST::ArgList, '$!args'); add-method(RakuAST::Type::Parameterized, 'new', [RakuAST::Type::Parameterized, '', 0, 0, RakuAST::Type, '$base-type', 1, 0, RakuAST::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$base-type!, :$args?) { my $SELF := nqp::decont($SELF_CONT); $base-type := nqp::decont($base-type); $args := nqp::decont($args); #line 288 src/Raku/ast/type.rakumod nqp::die('need a base-type, not ' ~ $base-type.dump) if !nqp::istype($base-type, RakuAST::Type); my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Type::Derived, '$!base-type', $base-type); nqp::bindattr($obj, RakuAST::Type::Parameterized, '$!args', $args // RakuAST::ArgList.new); $obj }); add-method(RakuAST::Type::Parameterized, 'visit-children', [RakuAST::Type::Parameterized, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 297 src/Raku/ast/type.rakumod $visitor($SELF.base-type); $visitor(nqp::getattr($SELF, RakuAST::Type::Parameterized, '$!args')); }); add-method(RakuAST::Type::Parameterized, 'PRODUCE-META-OBJECT', [RakuAST::Type::Parameterized, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 302 src/Raku/ast/type.rakumod if !nqp::getattr($SELF, RakuAST::Type::Parameterized, '$!args').args { $SELF.base-type.compile-time-value } elsif nqp::getattr($SELF, RakuAST::Type::Parameterized, '$!args').IMPL-HAS-ONLY-COMPILE-TIME-VALUES { my $args := nqp::getattr($SELF, RakuAST::Type::Parameterized, '$!args').IMPL-COMPILE-TIME-VALUES; my @pos := $args[0]; my %named := $args[1]; my $ptype := $SELF.IMPL-BASE-TYPE.compile-time-value; $ptype.HOW.parameterize($ptype, |@pos, |%named) } else { my $args := nqp::getattr($SELF, RakuAST::Type::Parameterized, '$!args').args; if nqp::istype($args.AT-POS(0), RakuAST::QuotedString) { my $is-only-quoted-string := 0; my $arg-count := 0; for $SELF.IMPL-UNWRAP-LIST($args) { $is-only-quoted-string := nqp::istype($_, RakuAST::QuotedString) ?? 1 !! 0; $arg-count++; last unless $is-only-quoted-string; } if $is-only-quoted-string { my @literals; for $SELF.IMPL-UNWRAP-LIST($args) { my $literal := $_.literal-value; if nqp::isconcrete($literal) { @literals.push: $literal; } } unless nqp::elems(@literals) == $arg-count { nqp::die('Not all RakuAST::QuotedString objects have literal values'); } my $ptype := $SELF.IMPL-BASE-TYPE.compile-time-value; $ptype.HOW.parameterize($ptype, |@literals); } } else { nqp::die('Cannot do compile time parameterization with these args'); } } }); add-method(RakuAST::Type::Parameterized, 'IMPL-EXPR-QAST', [RakuAST::Type::Parameterized, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 344 src/Raku/ast/type.rakumod if !nqp::getattr($SELF, RakuAST::Type::Parameterized, '$!args').args { QAST::WVal.new( :value($SELF.base-type.compile-time-value) ) } elsif nqp::getattr($SELF, RakuAST::Type::Parameterized, '$!args').IMPL-HAS-ONLY-COMPILE-TIME-VALUES { my $value := $SELF.meta-object; $context.ensure-sc($value); QAST::WVal.new( :$value ) } else { my $ptype := $SELF.base-type.compile-time-value; my $ptref := QAST::WVal.new( :value($ptype) ); my $qast := QAST::Op.new(:op, :name, QAST::Op.new(:op, $ptref), $ptref); nqp::getattr($SELF, RakuAST::Type::Parameterized, '$!args').IMPL-ADD-QAST-ARGS($context, $qast); $qast } }); add-method(RakuAST::Type::Parameterized, 'IMPL-CAN-INTERPRET', [RakuAST::Type::Parameterized, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 362 src/Raku/ast/type.rakumod nqp::istype($SELF.base-type, RakuAST::CompileTimeValue) && nqp::getattr($SELF, RakuAST::Type::Parameterized, '$!args').IMPL-CAN-INTERPRET }); add-method(RakuAST::Type::Parameterized, 'IMPL-INTERPRET', [RakuAST::Type::Parameterized, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 367 src/Raku/ast/type.rakumod $SELF.meta-object }); add-method(RakuAST::Type::Parameterized, 'is-simple-lexical-declaration', [RakuAST::Type::Parameterized, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 371 src/Raku/ast/type.rakumod (Bool.WHO) }); #line 286 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Parameterized, 'args', [], anon sub args ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Parameterized, '$!args') }); compose(RakuAST::Type::Parameterized); parent(RakuAST::Type::Enum, RakuAST::Type); parent(RakuAST::Type::Enum, RakuAST::Declaration); parent(RakuAST::Type::Enum, RakuAST::BeginTime); parent(RakuAST::Type::Enum, RakuAST::TraitTarget); parent(RakuAST::Type::Enum, RakuAST::Attaching); parent(RakuAST::Type::Enum, RakuAST::PackageInstaller); parent(RakuAST::Type::Enum, RakuAST::ImplicitLookups); parent(RakuAST::Type::Enum, RakuAST::Doc::DeclaratorTarget); add-attribute(RakuAST::Type::Enum, RakuAST::Name, '$!name'); add-attribute(RakuAST::Type::Enum, RakuAST::Expression, '$!term'); add-attribute(RakuAST::Type::Enum, RakuAST::Type, '$!of'); add-attribute(RakuAST::Type::Enum, Mu, '$!current-package'); add-attribute(RakuAST::Type::Enum, Mu, '$!base-type'); add-method(RakuAST::Type::Enum, 'new', [RakuAST::Type::Enum, '', 0, 0, str, '$scope', 1, 1, RakuAST::Name, '$name', 1, 1, RakuAST::Type, '$of', 1, 1, List, '$traits', 1, 1, RakuAST::Expression, '$term', 1, 0, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$scope?, :$name?, :$of?, :$traits?, :$term!, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $name := nqp::decont($name); $of := nqp::decont($of); $traits := nqp::decont($traits); $term := nqp::decont($term); $WHY := nqp::decont($WHY); #line 400 src/Raku/ast/type.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr($obj, RakuAST::Type::Enum, '$!name', $name // RakuAST::Name.from-identifier('')); nqp::bindattr($obj, RakuAST::Type::Enum, '$!of', $of); $obj.set-traits($traits); nqp::bindattr($obj, RakuAST::Type::Enum, '$!term', $term); $obj.set-WHY($WHY); $obj }); add-method(RakuAST::Type::Enum, 'default-scope', [RakuAST::Type::Enum, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 412 src/Raku/ast/type.rakumod 'our' }); add-method(RakuAST::Type::Enum, 'allowed-scopes', [RakuAST::Type::Enum, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 414 src/Raku/ast/type.rakumod $SELF.IMPL-WRAP-LIST(['my', 'our']) }); add-method(RakuAST::Type::Enum, 'dba', [RakuAST::Type::Enum, '', 0, 0], anon sub dba ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 416 src/Raku/ast/type.rakumod 'enum' }); add-method(RakuAST::Type::Enum, 'lexical-name', [RakuAST::Type::Enum, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 418 src/Raku/ast/type.rakumod nqp::getattr($SELF, RakuAST::Type::Enum, '$!name').canonicalize }); add-method(RakuAST::Type::Enum, 'generate-lookup', [RakuAST::Type::Enum, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 420 src/Raku/ast/type.rakumod my $lookup := RakuAST::Term::Name.new(nqp::getattr($SELF, RakuAST::Type::Enum, '$!name')); $lookup.set-resolution($SELF); $lookup }); add-method(RakuAST::Type::Enum, 'visit-children', [RakuAST::Type::Enum, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 426 src/Raku/ast/type.rakumod $visitor(nqp::getattr($SELF, RakuAST::Type::Enum, '$!name')); $visitor(nqp::getattr($SELF, RakuAST::Type::Enum, '$!term')); $visitor(nqp::getattr($SELF, RakuAST::Type::Enum, '$!of')) if nqp::getattr($SELF, RakuAST::Type::Enum, '$!of'); $visitor($SELF.WHY) if $SELF.WHY; }); add-method(RakuAST::Type::Enum, 'attach', [RakuAST::Type::Enum, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 433 src/Raku/ast/type.rakumod nqp::bindattr($SELF, RakuAST::Type::Enum, '$!current-package', $resolver.current-package); }); add-method(RakuAST::Type::Enum, 'is-lexical', [RakuAST::Type::Enum, '', 0, 0], anon sub is-lexical ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 437 src/Raku/ast/type.rakumod (Bool.WHO) }); add-method(RakuAST::Type::Enum, 'is-simple-lexical-declaration', [RakuAST::Type::Enum, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 438 src/Raku/ast/type.rakumod (Bool.WHO) }); add-method(RakuAST::Type::Enum, 'IMPL-EXPR-QAST', [RakuAST::Type::Enum, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 440 src/Raku/ast/type.rakumod my $qast := QAST::Op.new(:op('call'), :name('&ENUM_VALUES'), nqp::getattr($SELF, RakuAST::Type::Enum, '$!term').IMPL-EXPR-QAST($context)); QAST::Want.new( $qast, 'v', QAST::Op.new(:op('null')) ) }); add-method(RakuAST::Type::Enum, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Type::Enum, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 449 src/Raku/ast/type.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Pair')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('List')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Stringy')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Numeric')) ]) }); add-method(RakuAST::Type::Enum, 'IMPL-GENERATE-LEXICAL-DECLARATION', [RakuAST::Type::Enum, '', 0, 0, RakuAST::Name, '$name', 0, 0, Mu, '$type-object', 0, 0], anon sub IMPL-GENERATE-LEXICAL-DECLARATION ($SELF_CONT, $name!, $type-object!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $type-object := nqp::decont($type-object); #line 458 src/Raku/ast/type.rakumod RakuAST::VarDeclaration::Implicit::Constant.new: :name($name), :value($type-object), :scope($SELF.scope); }); add-method(RakuAST::Type::Enum, 'PERFORM-BEGIN', [RakuAST::Type::Enum, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 465 src/Raku/ast/type.rakumod my $lookups := $SELF.get-implicit-lookups; my $Pair := $lookups.AT-POS(0).resolution.compile-time-value; my $List := $lookups.AT-POS(1).resolution.compile-time-value; my $Stringy := $lookups.AT-POS(2).resolution.compile-time-value; my $Numeric := $lookups.AT-POS(3).resolution.compile-time-value; my $base-type; my $has-base-type := (Bool.WHO); if nqp::getattr($SELF, RakuAST::Type::Enum, '$!of') { $base-type := nqp::getattr($SELF, RakuAST::Type::Enum, '$!of').compile-time-value; $has-base-type := (Bool.WHO); } my %values := nqp::hash; my $cur-val := nqp::box_i(-1, Int); # Boxed to support .succ my $evaluated := $SELF.IMPL-BEGIN-TIME-EVALUATE(nqp::getattr($SELF, RakuAST::Type::Enum, '$!term'), $resolver, $context); my $is-settings-list := nqp::istype($evaluated, $List); if nqp::istype($evaluated, $Pair) { if !$has-base-type { # No need for type checking when we are going to get the base-type from the value %values{$evaluated.key} := $evaluated.value; $base-type := $evaluated.value.WHAT; } else { unless nqp::istype($evaluated.value, nqp::getattr($SELF, RakuAST::Type::Enum, '$!base-type')) { nqp::die("Incorrect value type provided. Expected '" ~ nqp::getattr($SELF, RakuAST::Type::Enum, '$!base-type').raku ~ "' but got '" ~ $evaluated.value.WHAT.raku ~ "'"); } %values{$evaluated.key} := $evaluated.value; } } elsif nqp::istype($evaluated, Str) { # TODO: What do we actually want to do when base-type is defined but they only provide a single Str? # Base just ignores and uses Int # A single string enum will always have 0, but we use $cur-val to keep it boxed %values{$evaluated} := $cur-val.succ; $base-type := Int; } elsif nqp::istype($evaluated, List) || $is-settings-list { my @items := $SELF.IMPL-UNWRAP-LIST($evaluated); if nqp::elems(@items) == 0 { # For empty enums, just default to Int $base-type := Int; } else { for @items { if nqp::istype($_, $Pair) { $cur-val := $_.value; if !$has-base-type { $base-type := $cur-val.WHAT; $has-base-type := (Bool.WHO); } else { # Should be a panic or a throw, right? unless nqp::istype($cur-val, nqp::getattr($SELF, RakuAST::Type::Enum, '$!base-type')) { nqp::die("Incorrect value type provided. Expected '" ~ nqp::getattr($SELF, RakuAST::Type::Enum, '$!base-type').raku ~ "' but got '" ~ $cur-val.WHAT.raku ~ "'"); } } %values{$_.key} := $cur-val; } elsif nqp::istype($_, Str) { if !$has-base-type { # TODO: Again, uncertain what to do when user provides a base type but then only hands a list of Str $base-type := Int; $has-base-type := (Bool.WHO); } %values{$_} := ($cur-val := $cur-val.succ); } } } } # Make $!base-type available, then we can produce the meta-object and add and apply traits nqp::bindattr($SELF, RakuAST::Type::Enum, '$!base-type', $base-type); my $meta := $SELF.meta-object; my $enumeration-kind; if nqp::istype($meta, $Numeric) { $enumeration-kind := nqp::istype($meta, $Stringy) ?? 'NumericStringyEnumeration' # allomorphs !! 'NumericEnumeration'; } elsif nqp::istype($meta, $Stringy) { $enumeration-kind := 'StringyEnumeration'; } $SELF.add-trait(RakuAST::Trait::Does.new( RakuAST::Type::Simple.new(RakuAST::Name.from-identifier('Enumeration')) )); if $enumeration-kind { $SELF.add-trait(RakuAST::Trait::Does.new( RakuAST::Type::Simple.new(RakuAST::Name.from-identifier($enumeration-kind)) )); } $SELF.apply-traits($resolver, $context, $SELF); $meta.HOW.compose($meta); # Don't install an anonymous enum my $anonymous := !nqp::getattr($SELF, RakuAST::Type::Enum, '$!name').canonicalize; if !$anonymous { $SELF.IMPL-INSTALL-PACKAGE( $resolver, $SELF.scope, nqp::getattr($SELF, RakuAST::Type::Enum, '$!name'), $meta, nqp::getattr($SELF, RakuAST::Type::Enum, '$!current-package') ); } # Create type objects for each value and install into proper scop my %stash := $resolver.IMPL-STASH-HASH($anonymous ?? nqp::getattr($SELF, RakuAST::Type::Enum, '$!current-package') !! $meta); my $index := 0; for %values -> $pair { my $key := $pair.key; my $value := $pair.value; if !nqp::defined($value) { nqp::die("Using a type object as a value for an enum not yet implemented. Sorry."); } my $val-meta := nqp::rebless(nqp::clone($value), $meta); nqp::bindattr($val-meta, $meta, '$!key', $key); nqp::bindattr($val-meta, $meta, '$!value', $value); nqp::bindattr_i($val-meta, $meta, '$!index', $index++); $context.ensure-sc($val-meta); $meta.HOW.add_enum_value($meta, $val-meta); # Make sure it is not already defined, eg 'enum Day' or 'class Day::Foo {}; enum Day' # TODO: Base allows both. First raises a 'Potential Difficulties', second succeeds silently. # But perhaps 6.e and moving forward, we could make the logic below the default behavior. # if nqp::existskey(%stash, $key) { # nqp::die("Redeclaration of symbol '" ~ $key ~ "'."); # } unless $anonymous && $SELF.scope eq 'my' { %stash{$key} := $val-meta; } # Declare these values into the lexical scope # TODO: Bind an X::PoisonedAlias when a lexical already exists # (Which is tricky, because base only does it when there is a clash in the current lexpad...) $resolver.current-scope.add-generated-lexical-declaration: RakuAST::VarDeclaration::Implicit::Constant.new( :name($key), :scope($SELF.scope), :value($val-meta) ); } $meta.HOW.compose_values($meta); }); add-method(RakuAST::Type::Enum, 'PRODUCE-META-OBJECT', [RakuAST::Type::Enum, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 601 src/Raku/ast/type.rakumod Perl6::Metamodel::EnumHOW.new_type( :name(nqp::getattr($SELF, RakuAST::Type::Enum, '$!name').canonicalize), :base_type(nqp::getattr($SELF, RakuAST::Type::Enum, '$!base-type')) ) }); #line 387 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Enum, 'term', [], anon sub term ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Enum, '$!term') }); #line 388 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Enum, 'of', [], anon sub of ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Enum, '$!of') }); #line 386 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Enum, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Enum, '$!name') }); compose(RakuAST::Type::Enum); parent(RakuAST::Type::Subset, RakuAST::Type); parent(RakuAST::Type::Subset, RakuAST::Declaration); parent(RakuAST::Type::Subset, RakuAST::BeginTime); parent(RakuAST::Type::Subset, RakuAST::TraitTarget); parent(RakuAST::Type::Subset, RakuAST::StubbyMeta); parent(RakuAST::Type::Subset, RakuAST::Attaching); parent(RakuAST::Type::Subset, RakuAST::PackageInstaller); parent(RakuAST::Type::Subset, RakuAST::Doc::DeclaratorTarget); add-attribute(RakuAST::Type::Subset, RakuAST::Name, '$!name'); add-attribute(RakuAST::Type::Subset, RakuAST::Trait::Of, '$!of'); add-attribute(RakuAST::Type::Subset, RakuAST::Expression, '$!where'); add-attribute(RakuAST::Type::Subset, Mu, '$!current-package'); add-attribute(RakuAST::Type::Subset, Mu, '$!block'); add-method(RakuAST::Type::Subset, 'new', [RakuAST::Type::Subset, '', 0, 0, str, '$scope', 1, 1, RakuAST::Name, '$name', 1, 0, RakuAST::Trait::Of, '$of', 1, 1, RakuAST::Expression, '$where', 1, 1, List, '$traits', 1, 1, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$scope?, :$name!, :$of?, :$where?, :$traits?, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $name := nqp::decont($name); $of := nqp::decont($of); $where := nqp::decont($where); $traits := nqp::decont($traits); $WHY := nqp::decont($WHY); #line 632 src/Raku/ast/type.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr($obj, RakuAST::Type::Subset, '$!name', $name); nqp::bindattr($obj, RakuAST::Type::Subset, '$!of', $of) if $of; if $where { # The $!where attribute is for deparsing, the $!block attribute # is for the actual action. nqp::bindattr($obj, RakuAST::Type::Subset, '$!where', $where); nqp::bindattr($obj, RakuAST::Type::Subset, '$!block', $where); } $obj.set-traits($traits) if $traits; $obj.set-WHY($WHY); $obj }); add-method(RakuAST::Type::Subset, 'set-traits', [RakuAST::Type::Subset, '', 0, 0, Any, '$traits', 0, 0], anon sub set-traits ($SELF_CONT, $traits!) { my $SELF := nqp::decont($SELF_CONT); $traits := nqp::decont($traits); #line 648 src/Raku/ast/type.rakumod for $SELF.IMPL-UNWRAP-LIST($traits) { nqp::istype($_, RakuAST::Trait::Of) ?? nqp::getattr($SELF, RakuAST::Type::Subset, '$!of') ?? nqp::die("Cannot declare more than one 'of' trait per subset") !! nqp::bindattr($SELF, RakuAST::Type::Subset, '$!of', $_) !! $SELF.add-trait($_); } }); add-method(RakuAST::Type::Subset, 'default-scope', [RakuAST::Type::Subset, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 658 src/Raku/ast/type.rakumod 'our' }); add-method(RakuAST::Type::Subset, 'allowed-scopes', [RakuAST::Type::Subset, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 660 src/Raku/ast/type.rakumod $SELF.IMPL-WRAP-LIST(['my', 'our']) }); add-method(RakuAST::Type::Subset, 'dba', [RakuAST::Type::Subset, '', 0, 0], anon sub dba ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 662 src/Raku/ast/type.rakumod 'subset' }); add-method(RakuAST::Type::Subset, 'lexical-name', [RakuAST::Type::Subset, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 664 src/Raku/ast/type.rakumod nqp::getattr($SELF, RakuAST::Type::Subset, '$!name').canonicalize }); add-method(RakuAST::Type::Subset, 'generate-lookup', [RakuAST::Type::Subset, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 666 src/Raku/ast/type.rakumod my $lookup := RakuAST::Term::Name.new(nqp::getattr($SELF, RakuAST::Type::Subset, '$!name')); $lookup.set-resolution($SELF); $lookup }); add-method(RakuAST::Type::Subset, 'attach', [RakuAST::Type::Subset, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 672 src/Raku/ast/type.rakumod nqp::bindattr($SELF, RakuAST::Type::Subset, '$!current-package', $resolver.current-package); }); add-method(RakuAST::Type::Subset, 'visit-children', [RakuAST::Type::Subset, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 676 src/Raku/ast/type.rakumod $visitor(nqp::getattr($SELF, RakuAST::Type::Subset, '$!name')); $visitor(nqp::getattr($SELF, RakuAST::Type::Subset, '$!block')) if nqp::getattr($SELF, RakuAST::Type::Subset, '$!block'); # External constants break if visited with missing IMPL-QAST-DECL. # Adding a sensible IMPL-QAST-DECL results in lexical declarations # for things like Int, which will break if added more than once. $visitor(nqp::getattr($SELF, RakuAST::Type::Subset, '$!of')) if nqp::getattr($SELF, RakuAST::Type::Subset, '$!of') && !nqp::istype(nqp::getattr($SELF, RakuAST::Type::Subset, '$!of'), RakuAST::Declaration::External::Constant); $visitor($SELF.WHY) if $SELF.WHY; }); add-method(RakuAST::Type::Subset, 'is-lexical', [RakuAST::Type::Subset, '', 0, 0], anon sub is-lexical ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 688 src/Raku/ast/type.rakumod (Bool.WHO) }); add-method(RakuAST::Type::Subset, 'is-simple-lexical-declaration', [RakuAST::Type::Subset, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 689 src/Raku/ast/type.rakumod (Bool.WHO) }); add-method(RakuAST::Type::Subset, 'IMPL-EXPR-QAST', [RakuAST::Type::Subset, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 691 src/Raku/ast/type.rakumod my $value := $SELF.meta-object; $context.ensure-sc($value); QAST::WVal.new( :$value ) }); add-method(RakuAST::Type::Subset, 'IMPL-GENERATE-LEXICAL-DECLARATION', [RakuAST::Type::Subset, '', 0, 0, RakuAST::Name, '$name', 0, 0, Mu, '$type-object', 0, 0], anon sub IMPL-GENERATE-LEXICAL-DECLARATION ($SELF_CONT, $name!, $type-object!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $type-object := nqp::decont($type-object); #line 697 src/Raku/ast/type.rakumod RakuAST::VarDeclaration::Implicit::Constant.new: :name($name), :value($type-object), :scope($SELF.scope); }); add-method(RakuAST::Type::Subset, 'is-begin-performed-after-children', [RakuAST::Type::Subset, '', 0, 0], anon sub is-begin-performed-after-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 704 src/Raku/ast/type.rakumod (Bool.WHO) }); add-method(RakuAST::Type::Subset, 'PERFORM-BEGIN-AFTER-CHILDREN', [RakuAST::Type::Subset, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-AFTER-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 706 src/Raku/ast/type.rakumod $SELF.apply-traits($resolver, $context, $SELF); my $block := nqp::getattr($SELF, RakuAST::Type::Subset, '$!block'); if $block && !$block.IMPL-CURRIED && (!nqp::istype($block, RakuAST::Code) || nqp::istype($block, RakuAST::RegexThunk ) ) { $block := RakuAST::Block.new( body => RakuAST::Blockoid.new( RakuAST::StatementList.new( RakuAST::Statement::Expression.new( expression => RakuAST::ApplyPostfix.new( operand => RakuAST::ApplyPostfix.new( operand => nqp::getattr($SELF, RakuAST::Type::Subset, '$!block'), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('ACCEPTS'), args => RakuAST::ArgList.new( RakuAST::Var::Lexical.new('$_'), ), ), ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('Bool'), ), ), ), ), ), ); nqp::bindattr($SELF, RakuAST::Type::Subset, '$!block', $block); $block.IMPL-CHECK($resolver, $context, (Bool.WHO)); } # set up the meta object my $package := nqp::getattr($SELF, RakuAST::Type::Subset, '$!current-package'); my $type := $SELF.stubbed-meta-object; $type.HOW.set_name( $type, nqp::getattr($SELF, RakuAST::Type::Subset, '$!name').qualified-with( RakuAST::Name.from-identifier-parts( |nqp::split('::', $package.HOW.name($package)) ) ).canonicalize(:colonpairs(0)) ) unless nqp::eqaddr($package, $resolver.get-global); # Update the Stash's name, too. nqp::bindattr_s($type.WHO, Stash, '$!longname', $type.HOW.name($type)); $SELF.IMPL-INSTALL-PACKAGE( $resolver, $SELF.scope, nqp::getattr($SELF, RakuAST::Type::Subset, '$!name'), $type, $package ); }); add-method(RakuAST::Type::Subset, 'PRODUCE-STUBBED-META-OBJECT', [RakuAST::Type::Subset, '', 0, 0], anon sub PRODUCE-STUBBED-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 761 src/Raku/ast/type.rakumod Perl6::Metamodel::SubsetHOW.new_type( :name(nqp::getattr($SELF, RakuAST::Type::Subset, '$!name').canonicalize), :refinee(Any), :refinement(Any) ) }); add-method(RakuAST::Type::Subset, 'PRODUCE-META-OBJECT', [RakuAST::Type::Subset, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 769 src/Raku/ast/type.rakumod my $type := $SELF.stubbed-meta-object; my $block := nqp::getattr($SELF, RakuAST::Type::Subset, '$!block'); $type.HOW.set_of($type, nqp::getattr($SELF, RakuAST::Type::Subset, '$!of').type.meta-object) if nqp::getattr($SELF, RakuAST::Type::Subset, '$!of'); $type.HOW.set_where($type, $block ?? $block.IMPL-CURRIED ?? $block.IMPL-CURRIED.meta-object !! $block.compile-time-value !! Mu ); $type }); #line 621 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Subset, 'where', [], anon sub where ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Subset, '$!where') }); #line 620 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Subset, 'of', [], anon sub of ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Subset, '$!of') }); #line 619 src/Raku/ast/type.rakumod add-method(RakuAST::Type::Subset, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Type::Subset, '$!name') }); compose(RakuAST::Type::Subset); parent(RakuAST::Initializer, RakuAST::Node); add-attribute(RakuAST::Initializer, RakuAST::ExpressionThunk, '$!thunk'); add-method(RakuAST::Initializer, 'is-binding', [RakuAST::Initializer, '', 0, 0], anon sub is-binding ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 8 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); add-method(RakuAST::Initializer, 'IMPL-COMPILE-TIME-VALUE', [RakuAST::Initializer, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-compiler', 1, 1], anon sub IMPL-COMPILE-TIME-VALUE ($SELF_CONT, $resolver!, $context!, :$invocant-compiler?) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $invocant-compiler := nqp::decont($invocant-compiler); #line 12 src/Raku/ast/variable-declaration.rakumod RakuAST::BeginTime.IMPL-BEGIN-TIME-EVALUATE($SELF.expression, $resolver, $context); }); add-method(RakuAST::Initializer, 'IMPL-THUNK-EXPRESSION', [RakuAST::Initializer, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-THUNK-EXPRESSION ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 16 src/Raku/ast/variable-declaration.rakumod my $expression := $SELF.expression; my $thunk := Nil; unless (nqp::istype($expression, RakuAST::Code)) { $thunk := $expression.outer-most-thunk; unless ($thunk) { $thunk := RakuAST::ExpressionThunk.new; $expression.wrap-with-thunk($thunk); $thunk.IMPL-STUB-CODE($resolver, $context); } nqp::bindattr($SELF, RakuAST::Initializer, '$!thunk', $thunk); } }); add-method(RakuAST::Initializer, 'IMPL-QAST-DECL', [RakuAST::Initializer, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 30 src/Raku/ast/variable-declaration.rakumod my $expression := $SELF.expression; nqp::istype($expression, RakuAST::Code) ?? $expression.IMPL-TO-QAST($context) !! nqp::getattr($SELF, RakuAST::Initializer, '$!thunk').IMPL-QAST-BLOCK($context, :expression($expression)) }); compose(RakuAST::Initializer); parent(RakuAST::Initializer::Assign, RakuAST::Initializer); add-attribute(RakuAST::Initializer::Assign, RakuAST::Expression, '$!expression'); add-method(RakuAST::Initializer::Assign, 'new', [RakuAST::Initializer::Assign, '', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub new ($SELF_CONT, $expression!) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); #line 44 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); $obj.set-expression($expression); $obj }); add-method(RakuAST::Initializer::Assign, 'set-expression', [RakuAST::Initializer::Assign, '', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub set-expression ($SELF_CONT, $expression!) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); #line 50 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::Initializer::Assign, '$!expression', $expression // RakuAST::Expression); }); add-method(RakuAST::Initializer::Assign, 'visit-children', [RakuAST::Initializer::Assign, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 55 src/Raku/ast/variable-declaration.rakumod $visitor(nqp::getattr($SELF, RakuAST::Initializer::Assign, '$!expression')); }); add-method(RakuAST::Initializer::Assign, 'IMPL-TO-QAST', [RakuAST::Initializer::Assign, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-qast', 1, 1], anon sub IMPL-TO-QAST ($SELF_CONT, $context!, :$invocant-qast?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $invocant-qast := nqp::decont($invocant-qast); #line 59 src/Raku/ast/variable-declaration.rakumod nqp::getattr($SELF, RakuAST::Initializer::Assign, '$!expression').IMPL-TO-QAST($context) }); #line 42 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::Initializer::Assign, 'expression', [], anon sub expression ($self) { nqp::getattr(nqp::decont($self), RakuAST::Initializer::Assign, '$!expression') }); compose(RakuAST::Initializer::Assign); parent(RakuAST::Initializer::Bind, RakuAST::Initializer); add-attribute(RakuAST::Initializer::Bind, RakuAST::Expression, '$!expression'); add-method(RakuAST::Initializer::Bind, 'new', [RakuAST::Initializer::Bind, '', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub new ($SELF_CONT, $expression!) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); #line 70 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); $obj.set-expression($expression); $obj }); add-method(RakuAST::Initializer::Bind, 'set-expression', [RakuAST::Initializer::Bind, '', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub set-expression ($SELF_CONT, $expression!) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); #line 76 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::Initializer::Bind, '$!expression', $expression // RakuAST::Expression); Nil }); add-method(RakuAST::Initializer::Bind, 'is-binding', [RakuAST::Initializer::Bind, '', 0, 0], anon sub is-binding ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 82 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); add-method(RakuAST::Initializer::Bind, 'visit-children', [RakuAST::Initializer::Bind, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 84 src/Raku/ast/variable-declaration.rakumod $visitor(nqp::getattr($SELF, RakuAST::Initializer::Bind, '$!expression')); }); add-method(RakuAST::Initializer::Bind, 'IMPL-TO-QAST', [RakuAST::Initializer::Bind, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-qast', 1, 1], anon sub IMPL-TO-QAST ($SELF_CONT, $context!, :$invocant-qast?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $invocant-qast := nqp::decont($invocant-qast); #line 88 src/Raku/ast/variable-declaration.rakumod nqp::getattr($SELF, RakuAST::Initializer::Bind, '$!expression').IMPL-TO-QAST($context) }); #line 68 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::Initializer::Bind, 'expression', [], anon sub expression ($self) { nqp::getattr(nqp::decont($self), RakuAST::Initializer::Bind, '$!expression') }); compose(RakuAST::Initializer::Bind); parent(RakuAST::Initializer::CallAssign, RakuAST::Initializer); add-attribute(RakuAST::Initializer::CallAssign, RakuAST::Postfixish, '$!postfixish'); add-method(RakuAST::Initializer::CallAssign, 'new', [RakuAST::Initializer::CallAssign, '', 0, 0, RakuAST::Postfixish, '$postfixish', 0, 0], anon sub new ($SELF_CONT, $postfixish!) { my $SELF := nqp::decont($SELF_CONT); $postfixish := nqp::decont($postfixish); #line 99 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Initializer::CallAssign, '$!postfixish', $postfixish); $obj }); add-method(RakuAST::Initializer::CallAssign, 'visit-children', [RakuAST::Initializer::CallAssign, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 105 src/Raku/ast/variable-declaration.rakumod $visitor(nqp::getattr($SELF, RakuAST::Initializer::CallAssign, '$!postfixish')); }); add-method(RakuAST::Initializer::CallAssign, 'IMPL-TO-QAST', [RakuAST::Initializer::CallAssign, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-qast', 1, 1], anon sub IMPL-TO-QAST ($SELF_CONT, $context!, :$invocant-qast?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $invocant-qast := nqp::decont($invocant-qast); #line 109 src/Raku/ast/variable-declaration.rakumod nqp::getattr($SELF, RakuAST::Initializer::CallAssign, '$!postfixish').IMPL-POSTFIX-QAST($context, $invocant-qast) }); add-method(RakuAST::Initializer::CallAssign, 'IMPL-COMPILE-TIME-VALUE', [RakuAST::Initializer::CallAssign, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$invocant-compiler', 1, 1], anon sub IMPL-COMPILE-TIME-VALUE ($SELF_CONT, $resolver!, $context!, :$invocant-compiler?) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $invocant-compiler := nqp::decont($invocant-compiler); #line 115 src/Raku/ast/variable-declaration.rakumod $SELF.postfixish.IMPL-INTERPRET(RakuAST::IMPL::InterpContext.new, $invocant-compiler) }); add-method(RakuAST::Initializer::CallAssign, 'IMPL-THUNK-EXPRESSION', [RakuAST::Initializer::CallAssign, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-THUNK-EXPRESSION ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 119 src/Raku/ast/variable-declaration.rakumod Nil }); add-method(RakuAST::Initializer::CallAssign, 'IMPL-QAST-DECL', [RakuAST::Initializer::CallAssign, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 123 src/Raku/ast/variable-declaration.rakumod QAST::Op.new(:op) }); #line 97 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::Initializer::CallAssign, 'postfixish', [], anon sub postfixish ($self) { nqp::getattr(nqp::decont($self), RakuAST::Initializer::CallAssign, '$!postfixish') }); compose(RakuAST::Initializer::CallAssign); parent(RakuAST::ContainerCreator, Any); add-attribute(RakuAST::ContainerCreator, Mu, '$!container-base-type'); add-attribute(RakuAST::ContainerCreator, Bool, '$!forced-dynamic'); add-method(RakuAST::ContainerCreator, 'IMPL-SET-CONTAINER-BASE-TYPE', [RakuAST::ContainerCreator, '', 0, 0, Mu, '$type', 0, 0], anon sub IMPL-SET-CONTAINER-BASE-TYPE ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 132 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::ContainerCreator, '$!container-base-type', $type); }); add-method(RakuAST::ContainerCreator, 'IMPL-HAS-CONTAINER-BASE-TYPE', [RakuAST::ContainerCreator, '', 0, 0], anon sub IMPL-HAS-CONTAINER-BASE-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 136 src/Raku/ast/variable-declaration.rakumod !nqp::eqaddr(nqp::getattr($SELF, RakuAST::ContainerCreator, '$!container-base-type'), Mu) }); add-method(RakuAST::ContainerCreator, 'IMPL-CONTAINER-BASE-TYPE', [RakuAST::ContainerCreator, '', 0, 0], anon sub IMPL-CONTAINER-BASE-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 140 src/Raku/ast/variable-declaration.rakumod nqp::getattr($SELF, RakuAST::ContainerCreator, '$!container-base-type') }); add-method(RakuAST::ContainerCreator, 'IMPL-CONTAINER-DESCRIPTOR', [RakuAST::ContainerCreator, '', 0, 0, Mu, '$of', 0, 0], anon sub IMPL-CONTAINER-DESCRIPTOR ($SELF_CONT, $of!) { my $SELF := nqp::decont($SELF_CONT); $of := nqp::decont($of); #line 144 src/Raku/ast/variable-declaration.rakumod # If it's a natively typed scalar, no container. my str $sigil := $SELF.sigil; my int $is-native := nqp::objprimspec($of); if $sigil eq '$' && $is-native { return Nil; } # Form container descriptor. my $default := $SELF.type ?? $of !! Any; my int $dynamic := $SELF.twigil eq '*' ?? 1 !! $SELF.forced-dynamic ?? 1 !! 0; ( nqp::eqaddr($of, Mu) ?? ContainerDescriptor::Untyped !! ContainerDescriptor ).new(:$of, :$default, :$dynamic, :name($SELF.lexical-name)) }); add-method(RakuAST::ContainerCreator, 'IMPL-CONTAINER-TYPE', [RakuAST::ContainerCreator, '', 0, 0, Mu, '$of', 0, 0, Mu, '$key-type', 1, 1], anon sub IMPL-CONTAINER-TYPE ($SELF_CONT, $of!, :$key-type?) { my $SELF := nqp::decont($SELF_CONT); $of := nqp::decont($of); $key-type := nqp::decont($key-type); #line 162 src/Raku/ast/variable-declaration.rakumod # Form the container type. my str $sigil := $SELF.sigil; my $container-type; if nqp::eqaddr(nqp::getattr($SELF, RakuAST::ContainerCreator, '$!container-base-type'), Mu) { if $sigil eq '@' { my $container-base-type := nqp::objprimspec($of) ?? array !! Array; $container-type := $SELF.type ?? $container-base-type.HOW.parameterize($container-base-type, $of) !! Array; } elsif $sigil eq '%' { $container-type := $key-type =:= NQPMu ?? $SELF.type ?? Hash.HOW.parameterize(Hash, $of) !! Hash !! Hash.HOW.parameterize( Hash, $SELF.type ?? $of !! nqp::getattr($SELF, RakuAST::ContainerCreator, '$!container-base-type'), $key-type ) } else { $container-type := $of } $container-type } else { $SELF.type ?? nqp::getattr($SELF, RakuAST::ContainerCreator, '$!container-base-type').HOW.parameterize(nqp::getattr($SELF, RakuAST::ContainerCreator, '$!container-base-type'), $of) !! nqp::getattr($SELF, RakuAST::ContainerCreator, '$!container-base-type') } }); add-method(RakuAST::ContainerCreator, 'IMPL-CONTAINER', [RakuAST::ContainerCreator, '', 0, 0, Mu, '$of', 0, 0, Mu, '$cont-desc', 0, 0], anon sub IMPL-CONTAINER ($SELF_CONT, $of!, $cont-desc!) { my $SELF := nqp::decont($SELF_CONT); $of := nqp::decont($of); $cont-desc := nqp::decont($cont-desc); #line 196 src/Raku/ast/variable-declaration.rakumod # Form the container. my $default := $SELF.type ?? $of !! Any; my str $sigil := $SELF.sigil; my $container-base-type; my $container-type; if nqp::eqaddr(nqp::getattr($SELF, RakuAST::ContainerCreator, '$!container-base-type'), Mu) { if $sigil eq '@' { $container-base-type := nqp::objprimspec($of) ?? array !! Array; $container-type := $SELF.type ?? $container-base-type.HOW.parameterize($container-base-type, $of) !! Array; } elsif $sigil eq '%' { $container-base-type := Hash; $container-type := $SELF.type ?? Hash.HOW.parameterize(Hash, $of) !! Hash; } else { if nqp::objprimspec($of) { nqp::die("Natively typed state variables not yet implemented") if $SELF.scope eq 'state'; return nqp::null; } $container-base-type := Scalar; $container-type := Scalar; } my $container := nqp::create($container-type); try nqp::bindattr($container, $container-base-type, '$!descriptor', $cont-desc); unless $sigil eq '@' || $sigil eq '%' { nqp::bindattr($container, $container-base-type, '$!value', $default); } $container } else { nqp::getattr($SELF, RakuAST::ContainerCreator, '$!container-base-type') } }); #line 130 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::ContainerCreator, 'forced-dynamic', [], anon sub forced-dynamic ($self) { nqp::getattr(nqp::decont($self), RakuAST::ContainerCreator, '$!forced-dynamic') }); compose(RakuAST::ContainerCreator); parent(RakuAST::TraitTarget::Variable, RakuAST::TraitTarget); parent(RakuAST::TraitTarget::Variable, RakuAST::Meta); parent(RakuAST::TraitTarget::Variable, RakuAST::ImplicitLookups); parent(RakuAST::TraitTarget::Variable, RakuAST::BeginTime); add-attribute(RakuAST::TraitTarget::Variable, str, '$!name'); add-attribute(RakuAST::TraitTarget::Variable, str, '$!scope'); add-attribute(RakuAST::TraitTarget::Variable, Mu, '$!cont'); add-attribute(RakuAST::TraitTarget::Variable, Mu, '$!code-object'); add-attribute(RakuAST::TraitTarget::Variable, Mu, '$!slash'); add-method(RakuAST::TraitTarget::Variable, 'new', [RakuAST::TraitTarget::Variable, '', 0, 0, str, '$name', 0, 0, str, '$scope', 0, 0, Mu, '$cont', 0, 0, Mu, '$code-object', 0, 0, Mu, '$slash', 0, 0], anon sub new ($SELF_CONT, $name!, $scope!, $cont!, $code-object!, $slash!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $scope := nqp::decont($scope); $cont := nqp::decont($cont); $code-object := nqp::decont($code-object); $slash := nqp::decont($slash); #line 249 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::TraitTarget::Variable, '$!name', $name); nqp::bindattr_s($obj, RakuAST::TraitTarget::Variable, '$!scope', $scope); nqp::bindattr($obj, RakuAST::TraitTarget::Variable, '$!cont', $cont); nqp::bindattr($obj, RakuAST::TraitTarget::Variable, '$!code-object', $code-object); nqp::bindattr($obj, RakuAST::TraitTarget::Variable, '$!slash', $slash); $obj }); add-method(RakuAST::TraitTarget::Variable, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::TraitTarget::Variable, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 259 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Variable')), ]) }); add-method(RakuAST::TraitTarget::Variable, 'PERFORM-BEGIN', [RakuAST::TraitTarget::Variable, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 265 src/Raku/ast/variable-declaration.rakumod }); add-method(RakuAST::TraitTarget::Variable, 'PRODUCE-META-OBJECT', [RakuAST::TraitTarget::Variable, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 268 src/Raku/ast/variable-declaration.rakumod my $Variable := $SELF.get-implicit-lookups.AT-POS(0).compile-time-value; my $varvar := nqp::create($Variable); nqp::bindattr_s($varvar, $Variable, '$!name', nqp::getattr_s($SELF, RakuAST::TraitTarget::Variable, '$!name')); nqp::bindattr_s($varvar, $Variable, '$!scope', nqp::getattr_s($SELF, RakuAST::TraitTarget::Variable, '$!scope')); nqp::bindattr($varvar, $Variable, '$!var', nqp::getattr($SELF, RakuAST::TraitTarget::Variable, '$!cont')); nqp::bindattr($varvar, $Variable, '$!block', nqp::getattr($SELF, RakuAST::TraitTarget::Variable, '$!code-object')); nqp::bindattr($varvar, $Variable, '$!slash', nqp::getattr($SELF, RakuAST::TraitTarget::Variable, '$!slash')); nqp::assign( nqp::getattr($varvar, $Variable, '$!implicit-lexical-usage'), (Bool.WHO)); $varvar }); compose(RakuAST::TraitTarget::Variable); parent(RakuAST::VarDeclaration::Constant, RakuAST::Declaration); parent(RakuAST::VarDeclaration::Constant, RakuAST::TraitTarget); parent(RakuAST::VarDeclaration::Constant, RakuAST::Attaching); parent(RakuAST::VarDeclaration::Constant, RakuAST::BeginTime); parent(RakuAST::VarDeclaration::Constant, RakuAST::CheckTime); parent(RakuAST::VarDeclaration::Constant, RakuAST::CompileTimeValue); parent(RakuAST::VarDeclaration::Constant, RakuAST::ImplicitLookups); parent(RakuAST::VarDeclaration::Constant, RakuAST::Term); add-attribute(RakuAST::VarDeclaration::Constant, str, '$!name'); add-attribute(RakuAST::VarDeclaration::Constant, RakuAST::Initializer, '$!initializer'); add-attribute(RakuAST::VarDeclaration::Constant, RakuAST::Type, '$!type'); add-attribute(RakuAST::VarDeclaration::Constant, Mu, '$!value'); add-attribute(RakuAST::VarDeclaration::Constant, Mu, '$!package'); add-method(RakuAST::VarDeclaration::Constant, 'new', [RakuAST::VarDeclaration::Constant, '', 0, 0, str, '$scope', 1, 1, RakuAST::Type, '$type', 1, 1, str, '$name', 1, 0, RakuAST::Initializer, '$initializer', 1, 0, List, '$traits', 1, 1], anon sub new ($SELF_CONT, :$scope?, :$type?, :$name!, :$initializer!, :$traits?) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $type := nqp::decont($type); $name := nqp::decont($name); $initializer := nqp::decont($initializer); $traits := nqp::decont($traits); #line 306 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Constant,'$!name',$name); nqp::bindattr($obj, RakuAST::VarDeclaration::Constant, '$!initializer', $initializer // RakuAST::Initializer); nqp::bindattr($obj, RakuAST::VarDeclaration::Constant, '$!type', $type // RakuAST::Type); $obj.set-traits($traits) if $traits; $obj }); add-method(RakuAST::VarDeclaration::Constant, 'lexical-name', [RakuAST::VarDeclaration::Constant, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 318 src/Raku/ast/variable-declaration.rakumod nqp::getattr_s($SELF, RakuAST::VarDeclaration::Constant, '$!name') }); add-method(RakuAST::VarDeclaration::Constant, 'default-scope', [RakuAST::VarDeclaration::Constant, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 319 src/Raku/ast/variable-declaration.rakumod 'our' }); add-method(RakuAST::VarDeclaration::Constant, 'allowed-scopes', [RakuAST::VarDeclaration::Constant, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 320 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-WRAP-LIST(['my', 'our']) }); add-method(RakuAST::VarDeclaration::Constant, 'is-simple-lexical-declaration', [RakuAST::VarDeclaration::Constant, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 321 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Constant, 'needs-sink-call', [RakuAST::VarDeclaration::Constant, '', 0, 0], anon sub needs-sink-call ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 322 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Constant, 'attach', [RakuAST::VarDeclaration::Constant, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 324 src/Raku/ast/variable-declaration.rakumod if $SELF.scope eq 'our' { # There is always a package, even if it's just GLOBALish nqp::bindattr( $SELF, RakuAST::VarDeclaration::Constant, '$!package', $resolver.current-package ); } }); add-method(RakuAST::VarDeclaration::Constant, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::VarDeclaration::Constant, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 334 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!type') ?? [nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!type')] !! []) }); add-method(RakuAST::VarDeclaration::Constant, 'visit-children', [RakuAST::VarDeclaration::Constant, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 338 src/Raku/ast/variable-declaration.rakumod $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!type')) if nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!type'); $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!initializer')) if nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!initializer'); $SELF.visit-traits($visitor); }); add-method(RakuAST::VarDeclaration::Constant, 'PERFORM-BEGIN', [RakuAST::VarDeclaration::Constant, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 347 src/Raku/ast/variable-declaration.rakumod my $value := nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!initializer').IMPL-COMPILE-TIME-VALUE( $resolver, $context, :invocant-compiler(-> { nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!type').IMPL-BASE-TYPE.meta-object })); $value := Map.new($value) if nqp::eqat(nqp::getattr_s($SELF, RakuAST::VarDeclaration::Constant, '$!name'),'%',0) && nqp::istype($value,List); nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!initializer').IMPL-THUNK-EXPRESSION($resolver, $context); nqp::bindattr($SELF, RakuAST::VarDeclaration::Constant, '$!value', $value); if $SELF.scope eq 'our' { my $name := nqp::getattr_s($SELF, RakuAST::VarDeclaration::Constant, '$!name'); if nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!package').WHO.EXISTS-KEY($name) { nqp::die("already have an 'our constant $name' in the package"); } } $SELF.apply-traits( $resolver, $context, $SELF, :SYMBOL(RakuAST::StrLiteral.new(nqp::getattr_s($SELF, RakuAST::VarDeclaration::Constant, '$!name'))) ); }); add-method(RakuAST::VarDeclaration::Constant, 'PERFORM-CHECK', [RakuAST::VarDeclaration::Constant, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 371 src/Raku/ast/variable-declaration.rakumod if nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!type') { my $type := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; unless nqp::istype(nqp::what(nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!value')), $type) { my $name := nqp::getattr_s($SELF, RakuAST::VarDeclaration::Constant, '$!name'); $SELF.add-sorry: $resolver.build-exception: 'X::Comp::TypeCheck', operation => 'constant declaration of ' ~ ($name || ''), expected => $type, got => nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!value'); return (Bool.WHO); } } (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Constant, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Constant, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 389 src/Raku/ast/variable-declaration.rakumod my $value := nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!value'); $context.ensure-sc($value); my $constant := QAST::Stmts.new( nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!initializer').IMPL-QAST-DECL($context), QAST::Var.new( :decl('static'), :scope('lexical'), :name(nqp::getattr_s($SELF, RakuAST::VarDeclaration::Constant, '$!name')), :value(nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!value')) ) ); if $SELF.scope eq 'our' { $context.ensure-sc(nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!package')); QAST::Op.new( :op('callmethod'), :name('BIND-KEY'), QAST::Op.new(:op('who'), QAST::WVal.new(:value(nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!package')))), QAST::SVal.new(:value(nqp::getattr_s($SELF, RakuAST::VarDeclaration::Constant, '$!name'))), $constant ) } else { $constant } }); add-method(RakuAST::VarDeclaration::Constant, 'compile-time-value', [RakuAST::VarDeclaration::Constant, '', 0, 0], anon sub compile-time-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 412 src/Raku/ast/variable-declaration.rakumod nqp::getattr($SELF, RakuAST::VarDeclaration::Constant, '$!value') }); add-method(RakuAST::VarDeclaration::Constant, 'IMPL-LOOKUP-QAST', [RakuAST::VarDeclaration::Constant, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 414 src/Raku/ast/variable-declaration.rakumod QAST::Var.new(:name(nqp::getattr_s($SELF, RakuAST::VarDeclaration::Constant, '$!name')), :scope) }); add-method(RakuAST::VarDeclaration::Constant, 'IMPL-EXPR-QAST', [RakuAST::VarDeclaration::Constant, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 418 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::VarDeclaration::Constant, 'IMPL-TO-QAST', [RakuAST::VarDeclaration::Constant, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 422 src/Raku/ast/variable-declaration.rakumod QAST::Var.new(:name(nqp::getattr_s($SELF, RakuAST::VarDeclaration::Constant, '$!name')), :scope); }); #line 296 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Constant, 'type', [], anon sub type ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Constant, '$!type') }); #line 294 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Constant, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::VarDeclaration::Constant, '$!name') }); #line 295 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Constant, 'initializer', [], anon sub initializer ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Constant, '$!initializer') }); compose(RakuAST::VarDeclaration::Constant); parent(RakuAST::VarDeclaration::Simple, RakuAST::Declaration); parent(RakuAST::VarDeclaration::Simple, RakuAST::ImplicitLookups); parent(RakuAST::VarDeclaration::Simple, RakuAST::TraitTarget); parent(RakuAST::VarDeclaration::Simple, RakuAST::ContainerCreator); parent(RakuAST::VarDeclaration::Simple, RakuAST::Meta); parent(RakuAST::VarDeclaration::Simple, RakuAST::Attaching); parent(RakuAST::VarDeclaration::Simple, RakuAST::BeginTime); parent(RakuAST::VarDeclaration::Simple, RakuAST::CheckTime); parent(RakuAST::VarDeclaration::Simple, RakuAST::Term); parent(RakuAST::VarDeclaration::Simple, RakuAST::Doc::DeclaratorTarget); add-attribute(RakuAST::VarDeclaration::Simple, RakuAST::Type, '$!type'); add-attribute(RakuAST::VarDeclaration::Simple, RakuAST::Name, '$!desigilname'); add-attribute(RakuAST::VarDeclaration::Simple, str, '$!sigil'); add-attribute(RakuAST::VarDeclaration::Simple, str, '$!twigil'); add-attribute(RakuAST::VarDeclaration::Simple, str, '$!storage-name'); add-attribute(RakuAST::VarDeclaration::Simple, RakuAST::Initializer, '$!initializer'); add-attribute(RakuAST::VarDeclaration::Simple, RakuAST::SemiList, '$!shape'); add-attribute(RakuAST::VarDeclaration::Simple, RakuAST::Package, '$!attribute-package'); add-attribute(RakuAST::VarDeclaration::Simple, RakuAST::Method, '$!accessor'); add-attribute(RakuAST::VarDeclaration::Simple, RakuAST::Type, '$!conflicting-type'); add-attribute(RakuAST::VarDeclaration::Simple, Mu, '$!container-initializer'); add-attribute(RakuAST::VarDeclaration::Simple, Mu, '$!package'); add-method(RakuAST::VarDeclaration::Simple, 'new', [RakuAST::VarDeclaration::Simple, '', 0, 0, str, '$scope', 1, 1, RakuAST::Name, '$desigilname', 1, 0, str, '$sigil', 1, 1, str, '$twigil', 1, 1, RakuAST::Type, '$type', 1, 1, List, '$traits', 1, 1, RakuAST::Initializer, '$initializer', 1, 1, RakuAST::SemiList, '$shape', 1, 1, Bool, '$forced-dynamic', 1, 1, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$scope?, :$desigilname!, :$sigil?, :$twigil?, :$type?, :$traits?, :$initializer?, :$shape?, :$forced-dynamic?, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $desigilname := nqp::decont($desigilname); $sigil := nqp::decont($sigil); $twigil := nqp::decont($twigil); $type := nqp::decont($type); $traits := nqp::decont($traits); $initializer := nqp::decont($initializer); $shape := nqp::decont($shape); $forced-dynamic := nqp::decont($forced-dynamic); $WHY := nqp::decont($WHY); #line 465 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); if $desigilname.is-empty { nqp::die('Cannot use RakuAST::VarDeclaration::Simple to declare an anonymous variable; use RakuAST::VarDeclaration::Anonymous'); } nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr($obj, RakuAST::VarDeclaration::Simple, '$!desigilname', $desigilname); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Simple, '$!sigil', $sigil); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Simple, '$!twigil', $twigil || ''); nqp::bindattr($obj, RakuAST::VarDeclaration::Simple, '$!type', $type // RakuAST::Type); nqp::bindattr($obj, RakuAST::VarDeclaration::Simple, '$!shape', $shape // RakuAST::SemiList); $obj.set-traits($traits); nqp::bindattr($obj, RakuAST::VarDeclaration::Simple, '$!initializer', $initializer // RakuAST::Initializer); nqp::bindattr($obj, RakuAST::VarDeclaration::Simple, '$!accessor', RakuAST::Method); nqp::bindattr($obj, RakuAST::ContainerCreator, '$!forced-dynamic', $forced-dynamic ?? (Bool.WHO) !! (Bool.WHO)); if $WHY { $scope && $scope eq 'has' ?? $obj.set-WHY($WHY) !! nqp::die("Declarator doc only supported on scope 'has'"); } $obj }); add-method(RakuAST::VarDeclaration::Simple, 'set-initializer', [RakuAST::VarDeclaration::Simple, '', 0, 0, RakuAST::Initializer, '$initializer', 0, 0], anon sub set-initializer ($SELF_CONT, $initializer!) { my $SELF := nqp::decont($SELF_CONT); $initializer := nqp::decont($initializer); #line 497 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer', $initializer // RakuAST::Initializer); }); add-method(RakuAST::VarDeclaration::Simple, 'name', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 502 src/Raku/ast/variable-declaration.rakumod $SELF.sigil ~ $SELF.twigil ~ nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!desigilname').canonicalize; }); add-method(RakuAST::VarDeclaration::Simple, 'lexical-name', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 506 src/Raku/ast/variable-declaration.rakumod $SELF.twigil eq '.' ?? $SELF.sigil ~ '!' ~ $SELF.desigilname.canonicalize !! $SELF.name }); add-method(RakuAST::VarDeclaration::Simple, 'set-type', [RakuAST::VarDeclaration::Simple, '', 0, 0, Any, '$type', 0, 0], anon sub set-type ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 510 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::VarDeclaration::Simple, '$!type', $type); }); add-method(RakuAST::VarDeclaration::Simple, 'generate-lookup', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 515 src/Raku/ast/variable-declaration.rakumod if $SELF.is-lexical { my $lookup := RakuAST::Var::Lexical.new($SELF.name); $lookup.set-resolution($SELF); $lookup } else { nqp::die('Cannot generate lookup of simple var for scope ' ~ $SELF.scope); } }); add-method(RakuAST::VarDeclaration::Simple, 'can-be-bound-to', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 526 src/Raku/ast/variable-declaration.rakumod # Must be lexical and non-native. if $SELF.scope eq 'my' || $SELF.scope eq 'state' { my str $sigil := $SELF.sigil; return (Bool.WHO) if $sigil eq '@' || $sigil eq '%'; return (Bool.WHO) unless nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type'); return (Bool.WHO) unless nqp::objprimspec( $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value ); } (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Simple, 'visit-children', [RakuAST::VarDeclaration::Simple, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 539 src/Raku/ast/variable-declaration.rakumod $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type')) if nqp::isconcrete(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type')); $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer')) if nqp::isconcrete(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer')); $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape')) if nqp::isconcrete(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape')); $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!accessor')) if nqp::isconcrete(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!accessor')); $SELF.visit-traits($visitor); $visitor($SELF.WHY) if $SELF.WHY; }); add-method(RakuAST::VarDeclaration::Simple, 'default-scope', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 548 src/Raku/ast/variable-declaration.rakumod 'my' }); add-method(RakuAST::VarDeclaration::Simple, 'allowed-scopes', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 552 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-WRAP-LIST(['my', 'state', 'our', 'has', 'HAS']) }); add-method(RakuAST::VarDeclaration::Simple, 'is-lexical', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub is-lexical ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 556 src/Raku/ast/variable-declaration.rakumod # Overridden here because our-scoped variables are really lexical aliases. my str $scope := $SELF.scope; $scope eq 'my' || $scope eq 'state' || $scope eq 'our' }); add-method(RakuAST::VarDeclaration::Simple, 'attach', [RakuAST::VarDeclaration::Simple, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 562 src/Raku/ast/variable-declaration.rakumod my str $scope := $SELF.scope; if $scope eq 'has' || $scope eq 'HAS' || $SELF.twigil eq '.' { my $attribute-package := $resolver.find-attach-target('package'); if $attribute-package { nqp::bindattr($SELF, RakuAST::VarDeclaration::Simple, '$!attribute-package', $attribute-package); } else { # TODO check-time error } } elsif $scope eq 'our' || nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!desigilname').is-multi-part { my $package := $resolver.current-package; # There is always a package, even if it's just GLOBALish nqp::bindattr($SELF, RakuAST::VarDeclaration::Simple, '$!package', $package); } }); add-method(RakuAST::VarDeclaration::Simple, 'PERFORM-BEGIN', [RakuAST::VarDeclaration::Simple, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 582 src/Raku/ast/variable-declaration.rakumod my str $scope := $SELF.scope; if nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!attribute-package') && ($scope eq 'has' || $scope eq 'HAS') { nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!attribute-package').ATTACH-ATTRIBUTE($SELF); } # Process traits for `is Type` and `of Type`, which get special # handling by the compiler. my @late-traits; my @traits := $SELF.IMPL-UNWRAP-LIST($SELF.traits); for @traits { if nqp::istype($_, RakuAST::Trait::Of) { nqp::bindattr($SELF, RakuAST::VarDeclaration::Simple, '$!conflicting-type', nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type')) if nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type'); nqp::bindattr($SELF, RakuAST::VarDeclaration::Simple, '$!type', $_.type); next; } elsif nqp::istype($_, RakuAST::Trait::Is) { my $type := $_.resolved-name; # an actual type if nqp::isconcrete($type) && !$_.argument && $type.is-resolved { $SELF.IMPL-SET-CONTAINER-BASE-TYPE($type.resolution.compile-time-value); next; } } nqp::push(@late-traits, $_); } # Apply any traits. $SELF.set-traits($SELF.IMPL-WRAP-LIST(@late-traits)); if $scope eq 'has' || $scope eq 'HAS' { if nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape') || $SELF.IMPL-HAS-CONTAINER-BASE-TYPE { my $args := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape') ?? RakuAST::ArgList.new( RakuAST::ColonPair::Value.new(:key, :value(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape'))) ) !! RakuAST::ArgList.new; my $of := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type') ?? $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value !! Mu; my $container-initializer-ast := RakuAST::ApplyPostfix.new( operand => RakuAST::Declaration::ResolvedConstant.new( :compile-time-value( nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape') && $SELF.sigil eq '%' ?? $SELF.IMPL-CONTAINER-TYPE($of, :key-type(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape').code-statements[0].expression.compile-time-value)) !! $SELF.IMPL-CONTAINER-TYPE($of) ) ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('new'), :$args ) ); my $thunk := RakuAST::BlockThunk.new(:expression($container-initializer-ast)); $container-initializer-ast.wrap-with-thunk($thunk); $thunk.ensure-begin-performed($resolver, $context); $resolver.current-scope.add-generated-lexical-declaration( RakuAST::VarDeclaration::Implicit::Block.new(:block($thunk)) ); nqp::bindattr($SELF, RakuAST::VarDeclaration::Simple, '$!container-initializer', $thunk.meta-object); } if nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer') { my $initializer := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer'); my $method := RakuAST::Method.new( :signature(RakuAST::Signature.new( :parameters([ RakuAST::Parameter.new( target => RakuAST::ParameterTarget::Var.new('$_') ) ]) )), :body(RakuAST::Blockoid.new( RakuAST::StatementList.new( !nqp::istype($initializer,RakuAST::Initializer::CallAssign) ?? RakuAST::Statement::Expression.new(:expression($initializer.expression)) !! RakuAST::Statement::Expression.new(:expression( RakuAST::ApplyPostfix.new( operand => nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type'), postfix => $initializer.postfixish ) )) ) ) ), ); nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!attribute-package').add-generated-lexical-declaration($method); $SELF.add-trait(RakuAST::Trait::Will.new('build', $method)); } # For attributes our meta-object is an appropriate Attribute instance $SELF.apply-traits($resolver, $context, $SELF); my $meta-object := $SELF.meta-object; if $SELF.scope eq 'HAS' && $meta-object.type.REPR eq 'CArray' && nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape') { my @dimensions := nqp::list_i(); my $shape := $SELF.IMPL-BEGIN-TIME-EVALUATE(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape'), $resolver, $context); my $elems := nqp::unbox_i($SELF.IMPL-BEGIN-TIME-EVALUATE(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape'), $resolver, $context)); nqp::push_i(@dimensions, $elems); nqp::bindattr($meta-object, $meta-object.WHAT, '$!dimensions', @dimensions); } } else { # For other variables the meta-object is just the container, but we # need instances of Variable my $meta := $SELF.meta-object; my $target := RakuAST::TraitTarget::Variable.new($SELF.name, nqp::getattr($SELF, RakuAST::Declaration, '$!scope'), $meta, Mu, Mu); # Get around RakuAST compiler deconting all arguments: nqp::bindattr($target, RakuAST::TraitTarget::Variable, '$!cont', $meta); $target.IMPL-CHECK($resolver, $context, (Bool.WHO)); if $SELF.twigil eq '.' { my $variable-access := RakuAST::Var::Lexical.new($SELF.name); $variable-access.set-resolution($SELF); my $accessor := RakuAST::Method.new( :scope, :name(RakuAST::Name.from-identifier($SELF.desigilname.canonicalize)), :body(RakuAST::Blockoid.new( RakuAST::StatementList.new( RakuAST::Statement::Expression.new(:expression($variable-access)), ), )), ); nqp::bindattr($SELF, RakuAST::VarDeclaration::Simple, '$!accessor', $accessor); $accessor.IMPL-CHECK($resolver, $context, (Bool.WHO)); } $SELF.apply-traits($resolver, $context, $target); } }); add-method(RakuAST::VarDeclaration::Simple, 'PERFORM-CHECK', [RakuAST::VarDeclaration::Simple, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 716 src/Raku/ast/variable-declaration.rakumod $SELF.add-sorry( $resolver.build-exception: 'X::Dynamic::Package', :symbol($SELF.name) ) if $SELF.twigil eq '*' && $SELF.desigilname.is-multi-part; $SELF.add-sorry( $resolver.build-exception: 'X::Syntax::Variable::ConflictingTypes', :outer(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!conflicting-type').compile-time-value), :inner(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type').compile-time-value) ) if nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!conflicting-type'); my $type := $SELF.type; if nqp::istype($type,RakuAST::Type::Simple) { my $initializer := $SELF.initializer; if nqp::istype($initializer,RakuAST::Initializer::Assign) || nqp::istype($initializer,RakuAST::Initializer::Bind) { my $expression := $initializer.expression; if nqp::istype($expression,RakuAST::Literal) { my $vartype := $type.PRODUCE-META-OBJECT; if nqp::objprimspec($vartype) { $vartype := $vartype.HOW.mro($vartype)[1]; } my $value := $expression.compile-time-value; if !nqp::istype($value,$vartype) && nqp::istype($vartype,$resolver.resolve-name-constant-in-setting(RakuAST::Name.from-identifier('Numeric')).compile-time-value) { $SELF.add-sorry: $resolver.build-exception: 'X::Syntax::Number::LiteralType', :varname($SELF.name), :$vartype, :$value; } } } } }); add-method(RakuAST::VarDeclaration::Simple, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 752 src/Raku/ast/variable-declaration.rakumod my @lookups; my str $scope := $SELF.scope; # If we have a type, we need to resolve that. Otherwise assume Mu @lookups.push(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type') || nqp::null); # If we're has/HAS scope, we need Nil to evaluate to. @lookups.push($scope eq 'has' || $scope eq 'HAS' ?? RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Nil')) !! nqp::null ); $SELF.IMPL-WRAP-LIST(@lookups) }); add-method(RakuAST::VarDeclaration::Simple, 'PRODUCE-META-OBJECT', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 767 src/Raku/ast/variable-declaration.rakumod # If it's our-scoped, then container is vivified via. package access. my str $scope := $SELF.scope; # Calculate the type. my $of := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type') ?? (nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type').is-resolved ?? nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type') !! $SELF.get-implicit-lookups.AT-POS(0) ).resolution.compile-time-value !! Mu; my $descriptor := $SELF.IMPL-CONTAINER-DESCRIPTOR($of); # `my %h{Any}` creates this shape declaration: # # shape => RakuAST::SemiList.new( # RakuAST::Statement::Expression.new( # expression => RakuAST::Type::Simple.new( <-- shape type # RakuAST::Name.from-identifier("Any") # ) # ) # ) my $object-hash := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape') && $SELF.sigil eq '%'; my $type := $SELF.IMPL-CONTAINER-TYPE( $of, :key-type($object-hash ?? nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape').code-statements[0].expression.compile-time-value !! NQPMu ) ); # If it's has scoped, we'll need to build an attribute. if $scope eq 'has' || $scope eq 'HAS' { my $meta-object := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!attribute-package').attribute-type.new( name => $SELF.sigil ~ '!' ~ $SELF.desigilname.canonicalize, type => $type, has_accessor => $SELF.twigil eq '.', container_descriptor => $descriptor, auto_viv_container => $SELF.IMPL-CONTAINER($of, $descriptor), package => nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!attribute-package').compile-time-value, container_initializer => nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!container-initializer'), ); nqp::bindattr_i($meta-object,$meta-object.WHAT,'$!inlined',1) if $scope eq 'HAS'; $meta-object } # An "our" that is already installed elsif $scope eq 'our' && nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!package').WHO.EXISTS-KEY($SELF.name) { nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!package').WHO.AT-KEY($SELF.name) } # An object hash, type is ok already elsif $object-hash { nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!package').WHO.BIND-KEY($SELF.name, $type) if $scope eq 'our'; $type } # Otherwise, it's lexically scoped, so the meta-object is just the # container, if any. else { my $container := $SELF.IMPL-CONTAINER($of, $descriptor); nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!package').WHO.BIND-KEY($SELF.name, $container) if $scope eq 'our'; $container } }); add-method(RakuAST::VarDeclaration::Simple, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Simple, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 834 src/Raku/ast/variable-declaration.rakumod my str $scope := $SELF.scope; my $of := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; if $scope eq 'my' && !nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!desigilname').is-multi-part { # Lexically scoped my str $sigil := $SELF.sigil; if $sigil eq '$' && nqp::objprimspec($of) { # Natively typed; just declare it. QAST::Var.new( :scope('lexical'), :decl('var'), :name($SELF.name), :returns($of) ) } elsif nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer') && nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer').is-binding { # Will be bound on first use, so just a declaration. QAST::Var.new( :scope('lexical'), :decl('var'), :name($SELF.name) ) } else { # Need to vivify the object. Note: maybe we want to drop the # contvar, though we'll need an alternative for BEGIN. my $container := $SELF.meta-object; $context.ensure-sc($container); my $qast := QAST::Var.new( :scope('lexical'), :decl('contvar'), :name($SELF.name), :value($container) ); if nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape') || $SELF.IMPL-HAS-CONTAINER-BASE-TYPE { my $value := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape') && $SELF.sigil eq '%' ?? $SELF.IMPL-CONTAINER-TYPE($of, :key-type(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape').code-statements[0].expression.compile-time-value)) !! $SELF.IMPL-CONTAINER-TYPE($of); $context.ensure-sc($value); $qast := QAST::Op.new( :op('bind'), $qast, QAST::Op.new( :op('callmethod'), :name('new'), QAST::WVal.new( :$value ) ) ); if nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape') { my $shape_ast := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!shape').IMPL-TO-QAST($context); $shape_ast.named('shape'); $qast[1].push($shape_ast); } } $qast } } elsif $scope eq 'our' || nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!desigilname').is-multi-part { # Package scoped lexical alias. We want to bind the lexical to # a lookup in the package. my $container := $SELF.meta-object; $context.ensure-sc($container); my $lookup := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!desigilname').IMPL-QAST-PACKAGE-LOOKUP($context, nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!package'), :sigil(nqp::getattr_s($SELF, RakuAST::VarDeclaration::Simple, '$!sigil')), :global-fallback); $lookup.name('VIVIFY-KEY'); QAST::Op.new( :op('bind'), QAST::Var.new( :scope('lexical'), :decl('contvar'), :name($SELF.name), :returns($of), :value($container) ), $lookup ) } elsif $scope eq 'has' || $scope eq 'HAS' { # No declaration to install QAST::Op.new( :op('null') ) } elsif $scope eq 'state' { # Lexically scoped state variable my str $sigil := $SELF.sigil; if $sigil eq '$' && nqp::objprimspec($of) { nqp::die("Natively typed state variables not yet implemented"); } elsif nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer') && nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer').is-binding { # Will be bound on first use, so just a declaration. QAST::Var.new(:scope('lexical'), :decl('var'), :name($SELF.name)) } else { # Need to vivify the object. my $container := $SELF.meta-object; $context.ensure-sc($container); QAST::Var.new( :scope('lexical'), :decl('statevar'), :name($SELF.name), :value($container) ) } } else { nqp::die("Don't know how to compile $scope scope variable"); } }); add-method(RakuAST::VarDeclaration::Simple, 'IMPL-TO-QAST', [RakuAST::VarDeclaration::Simple, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 922 src/Raku/ast/variable-declaration.rakumod my str $scope := $SELF.scope; my $lookups := $SELF.get-implicit-lookups; my str $name := $SELF.name; if $scope eq 'my' || $scope eq 'state' || $scope eq 'our' { my str $sigil := $SELF.sigil; my $var-access := QAST::Var.new( :$name, :scope ); my $of := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type') ?? $lookups.AT-POS(0).resolution.compile-time-value !! Mu; if $sigil eq '$' && (my int $prim-spec := nqp::objprimspec($of)) { # Natively typed value. Need to initialize it to a default # in the absence of an initializer. my $init; if nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer') { if nqp::istype(nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer'), RakuAST::Initializer::Assign) { $init := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer').expression.IMPL-TO-QAST($context); } else { nqp::die('Can only compile an assign initializer on a native'); } } elsif $prim-spec == 1 || ($prim-spec >= 4 && $prim-spec <= 10) { $init := QAST::IVal.new( :value(0) ); } elsif $prim-spec == 2 { $init := QAST::NVal.new( :value(0e0) ); } else { $init := QAST::SVal.new( :value('') ); } QAST::Op.new( :op('bind'), $var-access, $init ) } # Reference type value with an initializer elsif nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer') { my $init-qast := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer').IMPL-TO-QAST($context, :invocant-qast($var-access)); my $perform-init-qast; if nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!initializer').is-binding { # TODO type checking of source my $source := $sigil eq '@' || $sigil eq '%' ?? QAST::Op.new( :op('decont'), $init-qast) !! $init-qast; $perform-init-qast := QAST::Op.new( :op('bind'), $var-access, $source ); } else { # Assignment. Case-analyze by sigil. if $sigil eq '@' || $sigil eq '%' { # Call STORE method, passing :INITIALIZE to indicate # it's the initialization for immutable types. $perform-init-qast := QAST::Op.new( :op('callmethod'), :name('STORE'), $var-access, $init-qast, QAST::WVal.new( :named('INITIALIZE'), :value((Bool.WHO)) ) ); } else { # Scalar assignment. $perform-init-qast := QAST::Op.new( :op('p6assign'), $var-access, $init-qast ); } } if $scope eq 'state' { QAST::Op.new( :op('if'), QAST::Op.new( :op('p6stateinit') ), $perform-init-qast, $var-access ) } else { $perform-init-qast } } # Just a declaration; compile into an access to the variable. else { $var-access } } elsif $scope eq 'has' || $scope eq 'HAS' { # These just evaluate to Nil $lookups.AT-POS(1).IMPL-TO-QAST($context) } else { nqp::die("Don't know how to compile initialization for scope $scope"); } }); add-method(RakuAST::VarDeclaration::Simple, 'IMPL-LOOKUP-QAST', [RakuAST::VarDeclaration::Simple, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$rvalue', 1, 1], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!, :$rvalue?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $rvalue := nqp::decont($rvalue); #line 1015 src/Raku/ast/variable-declaration.rakumod my str $scope := $SELF.scope; if $scope eq 'my' || $scope eq 'state' || $scope eq 'our' { my str $scope := 'lexical'; unless $rvalue { # Potentially l-value native lookups need a lexicalref. if $SELF.sigil eq '$' && $SELF.scope ne 'our' { my $of := nqp::getattr($SELF, RakuAST::VarDeclaration::Simple, '$!type') ?? $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value !! Mu; if nqp::objprimspec($of) { $scope := 'lexicalref'; } return QAST::Var.new( :name($SELF.name), :$scope, :returns($of) ); } } QAST::Var.new( :name($SELF.name), :$scope ) } elsif $scope eq 'has' || $scope eq 'HAS' { nqp::die('Cannot compile lookup of attributes yet') } else { nqp::die("Cannot compile lookup of scope $scope") } }); add-method(RakuAST::VarDeclaration::Simple, 'IMPL-BIND-QAST', [RakuAST::VarDeclaration::Simple, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 1041 src/Raku/ast/variable-declaration.rakumod my str $scope := $SELF.scope; nqp::die('Can only compile bind to my-scoped variables') unless $scope eq 'my' || $scope eq 'state'; QAST::Op.new( :op('bind'), QAST::Var.new( :name($SELF.name), :scope('lexical') ), $source-qast ) }); add-method(RakuAST::VarDeclaration::Simple, 'IMPL-EXPR-QAST', [RakuAST::VarDeclaration::Simple, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1051 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::VarDeclaration::Simple, 'needs-sink-call', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub needs-sink-call ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1055 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Simple, 'dump-markers', [RakuAST::VarDeclaration::Simple, '', 0, 0], anon sub dump-markers ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1057 src/Raku/ast/variable-declaration.rakumod '【' ~ $SELF.name ~ '】' }); #line 441 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Simple, 'type', [], anon sub type ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Simple, '$!type') }); #line 444 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Simple, 'twigil', [], anon sub twigil ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::VarDeclaration::Simple, '$!twigil') }); #line 443 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Simple, 'sigil', [], anon sub sigil ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::VarDeclaration::Simple, '$!sigil') }); #line 447 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Simple, 'shape', [], anon sub shape ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Simple, '$!shape') }); #line 446 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Simple, 'initializer', [], anon sub initializer ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Simple, '$!initializer') }); #line 442 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Simple, 'desigilname', [], anon sub desigilname ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Simple, '$!desigilname') }); compose(RakuAST::VarDeclaration::Simple); parent(RakuAST::VarDeclaration::Auto, RakuAST::VarDeclaration::Simple); compose(RakuAST::VarDeclaration::Auto); parent(RakuAST::VarDeclaration::Signature, RakuAST::Declaration); parent(RakuAST::VarDeclaration::Signature, RakuAST::ImplicitLookups); parent(RakuAST::VarDeclaration::Signature, RakuAST::TraitTarget); parent(RakuAST::VarDeclaration::Signature, RakuAST::CheckTime); parent(RakuAST::VarDeclaration::Signature, RakuAST::Attaching); parent(RakuAST::VarDeclaration::Signature, RakuAST::BeginTime); parent(RakuAST::VarDeclaration::Signature, RakuAST::Term); add-attribute(RakuAST::VarDeclaration::Signature, RakuAST::Signature, '$!signature'); add-attribute(RakuAST::VarDeclaration::Signature, RakuAST::Type, '$!type'); add-attribute(RakuAST::VarDeclaration::Signature, RakuAST::Initializer, '$!initializer'); add-attribute(RakuAST::VarDeclaration::Signature, RakuAST::Package, '$!attribute-package'); add-attribute(RakuAST::VarDeclaration::Signature, Mu, '$!package'); add-method(RakuAST::VarDeclaration::Signature, 'new', [RakuAST::VarDeclaration::Signature, '', 0, 0, RakuAST::Signature, '$signature', 1, 0, RakuAST::Type, '$type', 1, 1, RakuAST::Initializer, '$initializer', 1, 1, str, '$scope', 1, 1], anon sub new ($SELF_CONT, :$signature!, :$type?, :$initializer?, :$scope?) { my $SELF := nqp::decont($SELF_CONT); $signature := nqp::decont($signature); $type := nqp::decont($type); $initializer := nqp::decont($initializer); $scope := nqp::decont($scope); #line 1083 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::VarDeclaration::Signature, '$!signature', $signature); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr($obj, RakuAST::VarDeclaration::Signature, '$!type', $type // RakuAST::Type); nqp::bindattr($obj, RakuAST::VarDeclaration::Signature, '$!initializer', $initializer // RakuAST::Initializer); $obj }); add-method(RakuAST::VarDeclaration::Signature, 'visit-children', [RakuAST::VarDeclaration::Signature, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1093 src/Raku/ast/variable-declaration.rakumod $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!signature')); my $type := nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!type'); $visitor($type) if nqp::isconcrete($type); my $initializer := nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!initializer'); $visitor($initializer) if nqp::isconcrete($initializer); $SELF.visit-traits($visitor); }); add-method(RakuAST::VarDeclaration::Signature, 'default-scope', [RakuAST::VarDeclaration::Signature, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1102 src/Raku/ast/variable-declaration.rakumod 'my' }); add-method(RakuAST::VarDeclaration::Signature, 'allowed-scopes', [RakuAST::VarDeclaration::Signature, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1106 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-WRAP-LIST(['my', 'state', 'our', 'has', 'HAS']) }); add-method(RakuAST::VarDeclaration::Signature, 'is-simple-lexical-declaration', [RakuAST::VarDeclaration::Signature, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1110 src/Raku/ast/variable-declaration.rakumod # The ParameterTargets in our signature will take care of declarations (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Signature, 'is-lexical', [RakuAST::VarDeclaration::Signature, '', 0, 0], anon sub is-lexical ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1115 src/Raku/ast/variable-declaration.rakumod # Overridden here because our-scoped variables are really lexical aliases. my str $scope := $SELF.scope; $scope eq 'my' || $scope eq 'state' || $scope eq 'our' }); add-method(RakuAST::VarDeclaration::Signature, 'attach', [RakuAST::VarDeclaration::Signature, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1121 src/Raku/ast/variable-declaration.rakumod my str $scope := $SELF.scope; if $scope eq 'has' || $scope eq 'HAS' { my $attribute-package := $resolver.find-attach-target('package'); if $attribute-package { nqp::bindattr($SELF, RakuAST::VarDeclaration::Signature, '$!attribute-package', $attribute-package); for $SELF.IMPL-UNWRAP-LIST($SELF.signature.parameters) { #TODO this should probably live in the target's attach method if $_.target && nqp::istype($_.target, RakuAST::ParameterTarget::Var) { $_.target.replace-scope($scope); nqp::bindattr($_.target, RakuAST::ParameterTarget::Var, '$!attribute-package', $attribute-package); } } } else { # TODO check-time error } } elsif $scope eq 'our' { my $package := $resolver.current-package; # There is always a package, even if it's just GLOBALish nqp::bindattr($SELF, RakuAST::VarDeclaration::Signature, '$!package', $package); } }); add-method(RakuAST::VarDeclaration::Signature, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::VarDeclaration::Signature, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1149 src/Raku/ast/variable-declaration.rakumod my @lookups; # If it's our-scoped, we need the package to bind it from. my str $scope := $SELF.scope; if $scope eq 'our' { @lookups.push(RakuAST::Var::Compiler::Lookup.new('$?PACKAGE')); } # If we have a type, we need to resolve that. elsif nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!type') { @lookups.push(nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!type')); } # If we're has/HAS scope, we need Nil to evaluate to. if $scope eq 'has' || $scope eq 'HAS' { @lookups.push(RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Nil'))); } $SELF.IMPL-WRAP-LIST(@lookups) }); add-method(RakuAST::VarDeclaration::Signature, 'is-begin-performed-before-children', [RakuAST::VarDeclaration::Signature, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1167 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Signature, 'PERFORM-BEGIN', [RakuAST::VarDeclaration::Signature, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1169 src/Raku/ast/variable-declaration.rakumod my $traits := $SELF.IMPL-UNWRAP-LIST($SELF.traits); my $scope := $SELF.scope; for $SELF.IMPL-UNWRAP-LIST($SELF.signature.parameters) -> $param { for $traits { $param.target.replace-scope($scope); $param.target.add-trait(nqp::clone($_)) if $param.target; } } }); add-method(RakuAST::VarDeclaration::Signature, 'PERFORM-CHECK', [RakuAST::VarDeclaration::Signature, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1180 src/Raku/ast/variable-declaration.rakumod # tell the parameter targets to create containers my @params := $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!signature').parameters); my $type := nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!type'); my $of := $type ?? $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value !! Mu; for @params { $_.target.set-container-type($type, $of) if $type; } }); add-method(RakuAST::VarDeclaration::Signature, 'IMPL-TO-QAST', [RakuAST::VarDeclaration::Signature, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1194 src/Raku/ast/variable-declaration.rakumod if nqp::isconcrete(nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!initializer')) { if nqp::istype(nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!initializer'), RakuAST::Initializer::Assign) { my $list := QAST::Op.new( :op('call'), :name('&infix:<,>') ); my @params := $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!signature').parameters); for @params { $list.push: $_.target.IMPL-LOOKUP-QAST($context); } my $init-qast := nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!initializer').IMPL-TO-QAST($context); $list := QAST::Op.new( :op('p6store'), $list, $init-qast); return $list; } elsif nqp::istype(nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!initializer'), RakuAST::Initializer::Bind) { my $signature := nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!signature').meta-object; $context.ensure-sc($signature); my $init-qast := nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!initializer').IMPL-TO-QAST($context); my $list := QAST::Op.new( :op('p6bindcaptosig'), QAST::WVal.new( :value($signature) ), QAST::Op.new( :op('callmethod'), :name('Capture'), $init-qast ) ); return $list; } else { nqp::die('Not yet supported signature initializer: ' ~ nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!initializer').HOW.name(nqp::getattr($SELF, RakuAST::VarDeclaration::Signature, '$!initializer'))); } } QAST::Op.new(:op); }); add-method(RakuAST::VarDeclaration::Signature, 'IMPL-EXPR-QAST', [RakuAST::VarDeclaration::Signature, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1229 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-TO-QAST($context) }); add-method(RakuAST::VarDeclaration::Signature, 'needs-sink-call', [RakuAST::VarDeclaration::Signature, '', 0, 0], anon sub needs-sink-call ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1233 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); #line 1077 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Signature, 'type', [], anon sub type ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Signature, '$!type') }); #line 1076 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Signature, 'signature', [], anon sub signature ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Signature, '$!signature') }); #line 1078 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Signature, 'initializer', [], anon sub initializer ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Signature, '$!initializer') }); compose(RakuAST::VarDeclaration::Signature); parent(RakuAST::VarDeclaration::Anonymous, RakuAST::VarDeclaration::Simple); add-method(RakuAST::VarDeclaration::Anonymous, 'new', [RakuAST::VarDeclaration::Anonymous, '', 0, 0, str, '$sigil', 1, 0, RakuAST::Type, '$type', 1, 1, RakuAST::Initializer, '$initializer', 1, 1, str, '$scope', 1, 1], anon sub new ($SELF_CONT, :$sigil!, :$type?, :$initializer?, :$scope?) { my $SELF := nqp::decont($SELF_CONT); $sigil := nqp::decont($sigil); $type := nqp::decont($type); $initializer := nqp::decont($initializer); $scope := nqp::decont($scope); #line 1241 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::VarDeclaration::Simple, '$!desigilname', $SELF.IMPL-GENERATE-NAME()); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Simple, '$!sigil', $sigil); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Simple, '$!twigil', ''); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr($obj, RakuAST::VarDeclaration::Simple, '$!type', $type // RakuAST::Type); nqp::bindattr($obj, RakuAST::VarDeclaration::Simple, '$!initializer', $initializer // RakuAST::Initializer); $obj }); add-method(RakuAST::VarDeclaration::Anonymous, 'IMPL-GENERATE-NAME', [RakuAST::VarDeclaration::Anonymous, '', 0, 0], anon sub IMPL-GENERATE-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1254 src/Raku/ast/variable-declaration.rakumod RakuAST::Name.from-identifier(QAST::Node.unique('ANON_VAR')) }); add-method(RakuAST::VarDeclaration::Anonymous, 'desigilname', [RakuAST::VarDeclaration::Anonymous, '', 0, 0], anon sub desigilname ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1258 src/Raku/ast/variable-declaration.rakumod RakuAST::Name.from-identifier('') }); add-method(RakuAST::VarDeclaration::Anonymous, 'generate-lookup', [RakuAST::VarDeclaration::Anonymous, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1262 src/Raku/ast/variable-declaration.rakumod nqp::die('Cannot generate lookup of an anonymous variable'); }); add-method(RakuAST::VarDeclaration::Anonymous, 'allowed-scopes', [RakuAST::VarDeclaration::Anonymous, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1266 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-WRAP-LIST(['my', 'state']) }); compose(RakuAST::VarDeclaration::Anonymous); parent(RakuAST::VarDeclaration::Term, RakuAST::Declaration); parent(RakuAST::VarDeclaration::Term, RakuAST::Term); add-attribute(RakuAST::VarDeclaration::Term, RakuAST::Type, '$!type'); add-attribute(RakuAST::VarDeclaration::Term, RakuAST::Name, '$!name'); add-attribute(RakuAST::VarDeclaration::Term, RakuAST::Initializer, '$!initializer'); add-method(RakuAST::VarDeclaration::Term, 'new', [RakuAST::VarDeclaration::Term, '', 0, 0, str, '$scope', 1, 1, RakuAST::Type, '$type', 1, 1, RakuAST::Name, '$name', 1, 0, RakuAST::Initializer, '$initializer', 1, 0], anon sub new ($SELF_CONT, :$scope?, :$type?, :$name!, :$initializer!) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $type := nqp::decont($type); $name := nqp::decont($name); $initializer := nqp::decont($initializer); #line 1281 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr($obj, RakuAST::VarDeclaration::Term, '$!type', $type // RakuAST::Type); nqp::bindattr($obj, RakuAST::VarDeclaration::Term, '$!name', $name); nqp::bindattr($obj, RakuAST::VarDeclaration::Term, '$!initializer', $initializer // RakuAST::Initializer); $obj }); add-method(RakuAST::VarDeclaration::Term, 'lexical-name', [RakuAST::VarDeclaration::Term, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1291 src/Raku/ast/variable-declaration.rakumod nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!name').canonicalize }); add-method(RakuAST::VarDeclaration::Term, 'generate-lookup', [RakuAST::VarDeclaration::Term, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1295 src/Raku/ast/variable-declaration.rakumod my $lookup := RakuAST::Term::Name.new(nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!name')); $lookup.set-resolution($SELF); $lookup }); add-method(RakuAST::VarDeclaration::Term, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Term, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1301 src/Raku/ast/variable-declaration.rakumod QAST::Var.new( :decl('var'), :scope('lexical'), :name(nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!name').canonicalize) ) }); add-method(RakuAST::VarDeclaration::Term, 'IMPL-TO-QAST', [RakuAST::VarDeclaration::Term, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1305 src/Raku/ast/variable-declaration.rakumod my $init-qast := nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!initializer').IMPL-TO-QAST($context); if nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!type') && !nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!type').is-known-to-be-exactly(Mu) { $init-qast := QAST::Op.new( :op('p6bindassert'), $init-qast, nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!type').IMPL-TO-QAST($context) ); } QAST::Op.new( :op('bind'), $SELF.IMPL-LOOKUP-QAST($context), $init-qast ) }); add-method(RakuAST::VarDeclaration::Term, 'IMPL-LOOKUP-QAST', [RakuAST::VarDeclaration::Term, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1317 src/Raku/ast/variable-declaration.rakumod QAST::Var.new( :name(nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!name').canonicalize), :scope('lexical') ) }); add-method(RakuAST::VarDeclaration::Term, 'IMPL-EXPR-QAST', [RakuAST::VarDeclaration::Term, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1321 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::VarDeclaration::Term, 'default-scope', [RakuAST::VarDeclaration::Term, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1325 src/Raku/ast/variable-declaration.rakumod 'my' }); add-method(RakuAST::VarDeclaration::Term, 'allowed-scopes', [RakuAST::VarDeclaration::Term, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1327 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-WRAP-LIST(['my']) }); add-method(RakuAST::VarDeclaration::Term, 'needs-sink-call', [RakuAST::VarDeclaration::Term, '', 0, 0], anon sub needs-sink-call ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1329 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Term, 'visit-children', [RakuAST::VarDeclaration::Term, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1331 src/Raku/ast/variable-declaration.rakumod $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!type')) if nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!type'); $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!name')); $visitor(nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!initializer')) if nqp::getattr($SELF, RakuAST::VarDeclaration::Term, '$!initializer'); }); #line 1276 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Term, 'type', [], anon sub type ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Term, '$!type') }); #line 1277 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Term, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Term, '$!name') }); #line 1278 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Term, 'initializer', [], anon sub initializer ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Term, '$!initializer') }); compose(RakuAST::VarDeclaration::Term); parent(RakuAST::VarDeclaration::Implicit, RakuAST::Declaration); add-attribute(RakuAST::VarDeclaration::Implicit, str, '$!name'); add-method(RakuAST::VarDeclaration::Implicit, 'new', [RakuAST::VarDeclaration::Implicit, '', 0, 0, str, '$name', 1, 0, str, '$scope', 1, 1], anon sub new ($SELF_CONT, :$name!, :$scope?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $scope := nqp::decont($scope); #line 1344 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Implicit, '$!name', $name); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); $obj }); add-method(RakuAST::VarDeclaration::Implicit, 'lexical-name', [RakuAST::VarDeclaration::Implicit, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1351 src/Raku/ast/variable-declaration.rakumod nqp::getattr_s($SELF, RakuAST::VarDeclaration::Implicit, '$!name') }); add-method(RakuAST::VarDeclaration::Implicit, 'default-scope', [RakuAST::VarDeclaration::Implicit, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1355 src/Raku/ast/variable-declaration.rakumod 'my' }); add-method(RakuAST::VarDeclaration::Implicit, 'generate-lookup', [RakuAST::VarDeclaration::Implicit, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1359 src/Raku/ast/variable-declaration.rakumod my $lookup := RakuAST::Var::Lexical.new(nqp::getattr_s($SELF, RakuAST::VarDeclaration::Implicit, '$!name')); $lookup.set-resolution($SELF); $lookup }); add-method(RakuAST::VarDeclaration::Implicit, 'IMPL-TO-QAST', [RakuAST::VarDeclaration::Implicit, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1365 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::VarDeclaration::Implicit, 'IMPL-LOOKUP-QAST', [RakuAST::VarDeclaration::Implicit, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$rvalue', 1, 1], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!, :$rvalue?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $rvalue := nqp::decont($rvalue); #line 1369 src/Raku/ast/variable-declaration.rakumod QAST::Var.new( :name(nqp::getattr_s($SELF, RakuAST::VarDeclaration::Implicit, '$!name')), :scope('lexical') ) }); #line 1342 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Implicit, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::VarDeclaration::Implicit, '$!name') }); compose(RakuAST::VarDeclaration::Implicit); parent(RakuAST::VarDeclaration::Implicit::Special, RakuAST::VarDeclaration::Implicit); parent(RakuAST::VarDeclaration::Implicit::Special, RakuAST::Meta); add-method(RakuAST::VarDeclaration::Implicit::Special, 'PRODUCE-META-OBJECT', [RakuAST::VarDeclaration::Implicit::Special, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1380 src/Raku/ast/variable-declaration.rakumod # Reuse the container descriptor for the common cases that we expect # to have. my constant COMMON := nqp::list( nqp::hash(), nqp::hash( # 6.c '$_', ContainerDescriptor.new(:of(Mu), :default(Any), :dynamic, :name('$_')), '$/', ContainerDescriptor.new(:of(Mu), :default(Nil), :dynamic, :name('$/')), '$!', ContainerDescriptor.new(:of(Mu), :default(Nil), :dynamic, :name('$!')) ), nqp::hash( # 6.d '$_', ContainerDescriptor.new(:of(Mu), :default(Any), :!dynamic, :name('$_')), '$/', ContainerDescriptor.new(:of(Mu), :default(Nil), :dynamic, :name('$/')), '$!', ContainerDescriptor.new(:of(Mu), :default(Nil), :dynamic, :name('$!')) ), nqp::hash( # 6.e '$_', ContainerDescriptor.new(:of(Mu), :default(Any), :!dynamic, :name('$_')), '$/', ContainerDescriptor.new(:of(Mu), :default(Nil), :dynamic, :name('$/')), '$!', ContainerDescriptor.new(:of(Mu), :default(Nil), :dynamic, :name('$!')) ) ); my $cont-desc := COMMON[nqp::getcomp('Raku').language_revision]{$SELF.name} // ContainerDescriptor.new(:of(Mu), :default(Any), :!dynamic, :name($SELF.name)); my $container := nqp::create(Scalar); nqp::bindattr($container, Scalar, '$!descriptor', $cont-desc); nqp::bindattr($container, Scalar, '$!value', $cont-desc.default); $container }); add-method(RakuAST::VarDeclaration::Implicit::Special, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Implicit::Special, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1409 src/Raku/ast/variable-declaration.rakumod my $container := $SELF.meta-object; $context.ensure-sc($container); QAST::Var.new( :scope('lexical'), :decl('contvar'), :name($SELF.name), :value($container) ) }); add-method(RakuAST::VarDeclaration::Implicit::Special, 'can-be-bound-to', [RakuAST::VarDeclaration::Implicit::Special, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1418 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Implicit::Special, 'IMPL-BIND-QAST', [RakuAST::VarDeclaration::Implicit::Special, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 1420 src/Raku/ast/variable-declaration.rakumod QAST::Op.new( :op('bind'), QAST::Var.new( :name($SELF.name), :scope('lexical') ), $source-qast ) }); compose(RakuAST::VarDeclaration::Implicit::Special); parent(RakuAST::VarDeclaration::Implicit::BlockTopic, RakuAST::VarDeclaration::Implicit); add-attribute(RakuAST::VarDeclaration::Implicit::BlockTopic, Bool, '$!parameter'); add-attribute(RakuAST::VarDeclaration::Implicit::BlockTopic, Bool, '$!required'); add-attribute(RakuAST::VarDeclaration::Implicit::BlockTopic, Bool, '$!exception'); add-method(RakuAST::VarDeclaration::Implicit::BlockTopic, 'new', [RakuAST::VarDeclaration::Implicit::BlockTopic, '', 0, 0, Bool, '$parameter', 1, 1, Bool, '$required', 1, 1, Bool, '$exception', 1, 1], anon sub new ($SELF_CONT, :$parameter?, :$required?, :$exception?) { my $SELF := nqp::decont($SELF_CONT); $parameter := nqp::decont($parameter); $required := nqp::decont($required); $exception := nqp::decont($exception); #line 1440 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Implicit, '$!name', '$_'); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', 'my'); nqp::bindattr($obj, RakuAST::VarDeclaration::Implicit::BlockTopic, '$!parameter', $parameter // (Bool.WHO)); nqp::bindattr($obj, RakuAST::VarDeclaration::Implicit::BlockTopic, '$!required', $required // (Bool.WHO)); nqp::bindattr($obj, RakuAST::VarDeclaration::Implicit::BlockTopic, '$!exception', $exception // (Bool.WHO)); $obj }); add-method(RakuAST::VarDeclaration::Implicit::BlockTopic, 'set-parameter', [RakuAST::VarDeclaration::Implicit::BlockTopic, '', 0, 0, Bool, '$parameter', 0, 0], anon sub set-parameter ($SELF_CONT, $parameter!) { my $SELF := nqp::decont($SELF_CONT); $parameter := nqp::decont($parameter); #line 1453 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::VarDeclaration::Implicit::BlockTopic, '$!parameter', $parameter); Nil }); add-method(RakuAST::VarDeclaration::Implicit::BlockTopic, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Implicit::BlockTopic, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1459 src/Raku/ast/variable-declaration.rakumod if nqp::getattr($SELF, RakuAST::VarDeclaration::Implicit::BlockTopic, '$!exception') { QAST::Stmts.new( QAST::Var.new( :decl('param'), :scope('local'), :name('EXCEPTION') ), QAST::Op.new( :op('bind'), QAST::Var.new( :decl('var'), :scope('lexical'), :name('$_') ), QAST::Op.new( :op('call'), :name('&EXCEPTION'), QAST::Var.new( :scope('local'), :name('EXCEPTION') ) ) ), QAST::Op.new( :op('p6assign'), QAST::Op.new( :op('getlexouter'), QAST::SVal.new( :value('$!') ) ), QAST::Var.new( :scope('lexical'), :name('$_') ) ) ) } elsif nqp::getattr($SELF, RakuAST::VarDeclaration::Implicit::BlockTopic, '$!parameter') { my $param := QAST::Var.new( :decl('param'), :scope('lexical'), :name('$_') ); unless nqp::getattr($SELF, RakuAST::VarDeclaration::Implicit::BlockTopic, '$!required') { $param.default(QAST::Op.new( :op('getlexouter'), QAST::SVal.new( :value('$_') ) )); } $param } else { QAST::Op.new: :op('bind'), QAST::Var.new( :decl('var'), :scope('lexical'), :name('$_') ), QAST::Op.new( :op('getlexouter'), QAST::SVal.new( :value('$_') ) ) } }); #line 1437 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Implicit::BlockTopic, 'required', [], anon sub required ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Implicit::BlockTopic, '$!required') }); #line 1436 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Implicit::BlockTopic, 'parameter', [], anon sub parameter ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Implicit::BlockTopic, '$!parameter') }); #line 1438 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Implicit::BlockTopic, 'exception', [], anon sub exception ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Implicit::BlockTopic, '$!exception') }); compose(RakuAST::VarDeclaration::Implicit::BlockTopic); parent(RakuAST::VarDeclaration::Implicit::Constant, RakuAST::VarDeclaration::Implicit); parent(RakuAST::VarDeclaration::Implicit::Constant, RakuAST::TraitTarget); parent(RakuAST::VarDeclaration::Implicit::Constant, RakuAST::BeginTime); parent(RakuAST::VarDeclaration::Implicit::Constant, RakuAST::Meta); parent(RakuAST::VarDeclaration::Implicit::Constant, RakuAST::CompileTimeValue); parent(RakuAST::VarDeclaration::Implicit::Constant, RakuAST::Declaration::Mergeable); add-attribute(RakuAST::VarDeclaration::Implicit::Constant, Mu, '$!value'); add-method(RakuAST::VarDeclaration::Implicit::Constant, 'new', [RakuAST::VarDeclaration::Implicit::Constant, '', 0, 0, str, '$name', 1, 0, Mu, '$value', 1, 0, str, '$scope', 1, 1], anon sub new ($SELF_CONT, :$name!, :$value!, :$scope?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $value := nqp::decont($value); $scope := nqp::decont($scope); #line 1506 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Implicit, '$!name', $name); nqp::bindattr($obj, RakuAST::VarDeclaration::Implicit::Constant, '$!value', $value); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); $obj }); add-method(RakuAST::VarDeclaration::Implicit::Constant, 'compile-time-value', [RakuAST::VarDeclaration::Implicit::Constant, '', 0, 0], anon sub compile-time-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1514 src/Raku/ast/variable-declaration.rakumod nqp::getattr($SELF, RakuAST::VarDeclaration::Implicit::Constant, '$!value') }); add-method(RakuAST::VarDeclaration::Implicit::Constant, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Implicit::Constant, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1516 src/Raku/ast/variable-declaration.rakumod $context.ensure-sc(nqp::getattr($SELF, RakuAST::VarDeclaration::Implicit::Constant, '$!value')); QAST::Var.new( :decl('static'), :scope('lexical'), :name($SELF.name), :value(nqp::getattr($SELF, RakuAST::VarDeclaration::Implicit::Constant, '$!value')) ) }); add-method(RakuAST::VarDeclaration::Implicit::Constant, 'PRODUCE-META-OBJECT', [RakuAST::VarDeclaration::Implicit::Constant, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1521 src/Raku/ast/variable-declaration.rakumod $SELF.compile-time-value }); add-method(RakuAST::VarDeclaration::Implicit::Constant, 'PERFORM-BEGIN', [RakuAST::VarDeclaration::Implicit::Constant, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1525 src/Raku/ast/variable-declaration.rakumod $SELF.apply-traits($resolver, $context, $SELF, :SYMBOL(RakuAST::StrLiteral.new($SELF.name))); }); #line 1504 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Implicit::Constant, 'value', [], anon sub value ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Implicit::Constant, '$!value') }); compose(RakuAST::VarDeclaration::Implicit::Constant); parent(RakuAST::VarDeclaration::Implicit::Block, RakuAST::Declaration); add-attribute(RakuAST::VarDeclaration::Implicit::Block, Mu, '$!block'); add-method(RakuAST::VarDeclaration::Implicit::Block, 'new', [RakuAST::VarDeclaration::Implicit::Block, '', 0, 0, Mu, '$block', 1, 0, str, '$scope', 1, 1], anon sub new ($SELF_CONT, :$block!, :$scope?) { my $SELF := nqp::decont($SELF_CONT); $block := nqp::decont($block); $scope := nqp::decont($scope); #line 1536 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::VarDeclaration::Implicit::Block, '$!block', $block); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); $obj }); add-method(RakuAST::VarDeclaration::Implicit::Block, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Implicit::Block, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1543 src/Raku/ast/variable-declaration.rakumod nqp::getattr($SELF, RakuAST::VarDeclaration::Implicit::Block, '$!block').IMPL-QAST-DECL-CODE($context); }); add-method(RakuAST::VarDeclaration::Implicit::Block, 'lexical-name', [RakuAST::VarDeclaration::Implicit::Block, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1547 src/Raku/ast/variable-declaration.rakumod '' }); #line 1534 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Implicit::Block, 'block', [], anon sub block ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Implicit::Block, '$!block') }); compose(RakuAST::VarDeclaration::Implicit::Block); parent(RakuAST::VarDeclaration::Implicit::Self, RakuAST::VarDeclaration::Implicit); add-method(RakuAST::VarDeclaration::Implicit::Self, 'new', [RakuAST::VarDeclaration::Implicit::Self, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1554 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Implicit, '$!name', 'self'); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', 'my'); $obj }); add-method(RakuAST::VarDeclaration::Implicit::Self, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Implicit::Self, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1561 src/Raku/ast/variable-declaration.rakumod QAST::Var.new( :decl('var'), :scope('lexical'), :name($SELF.name) ) }); compose(RakuAST::VarDeclaration::Implicit::Self); parent(RakuAST::VarDeclaration::Implicit::Cursor, RakuAST::VarDeclaration::Implicit); add-method(RakuAST::VarDeclaration::Implicit::Cursor, 'new', [RakuAST::VarDeclaration::Implicit::Cursor, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1570 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Implicit, '$!name', '$¢'); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', 'my'); $obj }); add-method(RakuAST::VarDeclaration::Implicit::Cursor, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Implicit::Cursor, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1577 src/Raku/ast/variable-declaration.rakumod QAST::Var.new( :decl('var'), :scope('lexical'), :name($SELF.name) ) }); compose(RakuAST::VarDeclaration::Implicit::Cursor); parent(RakuAST::VarDeclaration::Implicit::Routine, RakuAST::VarDeclaration::Implicit); add-method(RakuAST::VarDeclaration::Implicit::Routine, 'new', [RakuAST::VarDeclaration::Implicit::Routine, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1586 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Implicit, '$!name', '&?ROUTINE'); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', 'my'); $obj }); add-method(RakuAST::VarDeclaration::Implicit::Routine, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Implicit::Routine, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1593 src/Raku/ast/variable-declaration.rakumod # We cannot just put the AST node's meta-object into a WVal for this, because # we may be running a clone of that object. QAST::Op.new: :op('bind'), QAST::Var.new( :decl('var'), :scope('lexical'), :name($SELF.name) ), QAST::Op.new( :op('getcodeobj'), QAST::Op.new( :op('curcode') ) ) }); compose(RakuAST::VarDeclaration::Implicit::Routine); parent(RakuAST::VarDeclaration::Implicit::State, RakuAST::VarDeclaration::Implicit); parent(RakuAST::VarDeclaration::Implicit::State, RakuAST::ImplicitLookups); parent(RakuAST::VarDeclaration::Implicit::State, RakuAST::Meta); add-attribute(RakuAST::VarDeclaration::Implicit::State, int, '$!init-to-zero'); add-method(RakuAST::VarDeclaration::Implicit::State, 'new', [RakuAST::VarDeclaration::Implicit::State, '', 0, 0, str, '$name', 0, 0, int, '$init-to-zero', 1, 1], anon sub new ($SELF_CONT, $name!, :$init-to-zero?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $init-to-zero := nqp::decont($init-to-zero); #line 1611 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Implicit, '$!name', $name); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', 'state'); nqp::bindattr_i($obj, RakuAST::VarDeclaration::Implicit::State, '$!init-to-zero', $init-to-zero // 0); $obj }); add-method(RakuAST::VarDeclaration::Implicit::State, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::VarDeclaration::Implicit::State, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1619 src/Raku/ast/variable-declaration.rakumod my @lookups := nqp::getattr_i($SELF, RakuAST::VarDeclaration::Implicit::State, '$!init-to-zero') ?? [ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Int')) ] !! []; $SELF.IMPL-WRAP-LIST(@lookups) }); add-method(RakuAST::VarDeclaration::Implicit::State, 'PRODUCE-META-OBJECT', [RakuAST::VarDeclaration::Implicit::State, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1626 src/Raku/ast/variable-declaration.rakumod my str $name := nqp::getattr_s($SELF, RakuAST::VarDeclaration::Implicit, '$!name'); # Create a container descriptor and attach it to a Scalar container, then set it to Int.new(0) my $descriptor := ContainerDescriptor.new(:of(Mu), :default(Any), :!dynamic, :$name); my $container := nqp::create(Scalar); nqp::bindattr($container, Scalar, '$!descriptor', $descriptor); if nqp::getattr_i($SELF, RakuAST::VarDeclaration::Implicit::State, '$!init-to-zero') { my $Int := $SELF.get-implicit-lookups.AT-POS(0).compile-time-value; nqp::bindattr($container, Scalar, '$!value', nqp::box_i(0, $Int)); } else { nqp::bindattr($container, Scalar, '$!value', $descriptor.default); } $container }); add-method(RakuAST::VarDeclaration::Implicit::State, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Implicit::State, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1643 src/Raku/ast/variable-declaration.rakumod my $container := $SELF.meta-object; $context.ensure-sc($container); QAST::Var.new: :decl, :scope, :name($SELF.name), :value($container) }); compose(RakuAST::VarDeclaration::Implicit::State); parent(RakuAST::VarDeclaration::Implicit::Doc, RakuAST::VarDeclaration::Implicit); parent(RakuAST::VarDeclaration::Implicit::Doc, RakuAST::Attaching); parent(RakuAST::VarDeclaration::Implicit::Doc, RakuAST::CheckTime); add-attribute(RakuAST::VarDeclaration::Implicit::Doc, Mu, '$!value'); add-attribute(RakuAST::VarDeclaration::Implicit::Doc, Mu, '$!cu'); add-method(RakuAST::VarDeclaration::Implicit::Doc, 'new', [RakuAST::VarDeclaration::Implicit::Doc, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1659 src/Raku/ast/variable-declaration.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Implicit, '$!name', $SELF.name); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', 'my'); $obj }); add-method(RakuAST::VarDeclaration::Implicit::Doc, 'attach', [RakuAST::VarDeclaration::Implicit::Doc, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1667 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::VarDeclaration::Implicit::Doc, '$!cu', $resolver.find-attach-target('compunit')); }); add-method(RakuAST::VarDeclaration::Implicit::Doc, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Implicit::Doc, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1672 src/Raku/ast/variable-declaration.rakumod my $value := nqp::getattr($SELF, RakuAST::VarDeclaration::Implicit::Doc, '$!value'); $context.ensure-sc($value); QAST::Op.new: :op('bind'), QAST::Var.new(:decl('static'), :scope('lexical'), :name( nqp::getattr_s($SELF, RakuAST::VarDeclaration::Implicit, '$!name') )), QAST::WVal.new(:$value); }); #line 1656 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Implicit::Doc, 'value', [], anon sub value ($self) { nqp::getattr(nqp::decont($self), RakuAST::VarDeclaration::Implicit::Doc, '$!value') }); compose(RakuAST::VarDeclaration::Implicit::Doc); parent(RakuAST::VarDeclaration::Implicit::Doc::Pod, RakuAST::VarDeclaration::Implicit::Doc); add-method(RakuAST::VarDeclaration::Implicit::Doc::Pod, 'name', [RakuAST::VarDeclaration::Implicit::Doc::Pod, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1688 src/Raku/ast/variable-declaration.rakumod '$=pod' }); add-method(RakuAST::VarDeclaration::Implicit::Doc::Pod, 'PERFORM-CHECK', [RakuAST::VarDeclaration::Implicit::Doc::Pod, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1693 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::VarDeclaration::Implicit::Doc, '$!value', nqp::getattr( $SELF,RakuAST::VarDeclaration::Implicit::Doc,'$!cu' ).pod-content ); }); compose(RakuAST::VarDeclaration::Implicit::Doc::Pod); parent(RakuAST::VarDeclaration::Implicit::Doc::Data, RakuAST::VarDeclaration::Implicit::Doc); add-method(RakuAST::VarDeclaration::Implicit::Doc::Data, 'name', [RakuAST::VarDeclaration::Implicit::Doc::Data, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1706 src/Raku/ast/variable-declaration.rakumod '$=data' }); add-method(RakuAST::VarDeclaration::Implicit::Doc::Data, 'PERFORM-CHECK', [RakuAST::VarDeclaration::Implicit::Doc::Data, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1711 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::VarDeclaration::Implicit::Doc, '$!value', nqp::ifnull( nqp::getattr( $SELF,RakuAST::VarDeclaration::Implicit::Doc,'$!cu' ).data-content, Mu ) ); }); compose(RakuAST::VarDeclaration::Implicit::Doc::Data); parent(RakuAST::VarDeclaration::Implicit::Doc::Finish, RakuAST::VarDeclaration::Implicit::Doc); add-method(RakuAST::VarDeclaration::Implicit::Doc::Finish, 'name', [RakuAST::VarDeclaration::Implicit::Doc::Finish, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1727 src/Raku/ast/variable-declaration.rakumod '$=finish' }); add-method(RakuAST::VarDeclaration::Implicit::Doc::Finish, 'PERFORM-CHECK', [RakuAST::VarDeclaration::Implicit::Doc::Finish, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1732 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::VarDeclaration::Implicit::Doc, '$!value', nqp::getattr( $SELF,RakuAST::VarDeclaration::Implicit::Doc,'$!cu' ).finish-content, ); }); compose(RakuAST::VarDeclaration::Implicit::Doc::Finish); parent(RakuAST::VarDeclaration::Implicit::Doc::Rakudoc, RakuAST::VarDeclaration::Implicit::Doc); add-method(RakuAST::VarDeclaration::Implicit::Doc::Rakudoc, 'name', [RakuAST::VarDeclaration::Implicit::Doc::Rakudoc, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1745 src/Raku/ast/variable-declaration.rakumod '$=rakudoc' }); add-method(RakuAST::VarDeclaration::Implicit::Doc::Rakudoc, 'fetch-blocks', [RakuAST::VarDeclaration::Implicit::Doc::Rakudoc, '', 0, 0, RakuAST::StatementList, '$statement-list', 0, 0], anon sub fetch-blocks ($SELF_CONT, $statement-list!) { my $SELF := nqp::decont($SELF_CONT); $statement-list := nqp::decont($statement-list); #line 1747 src/Raku/ast/variable-declaration.rakumod for nqp::getattr( $statement-list,RakuAST::StatementList,'$!statements' ) { if nqp::istype($_,RakuAST::Doc::Block) { nqp::push($*RAKUDOC,$_); } elsif nqp::istype($_,RakuAST::Statement::Expression) { my $expression := $_.expression; if nqp::istype($expression,RakuAST::Doc::DeclaratorTarget) && $expression.WHY { nqp::push($*RAKUDOC,$expression); } } elsif nqp::istype($_,RakuAST::Blockoid) { $SELF.fetch-blocks($_.statement-list); } } }); add-method(RakuAST::VarDeclaration::Implicit::Doc::Rakudoc, 'PERFORM-CHECK', [RakuAST::VarDeclaration::Implicit::Doc::Rakudoc, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1770 src/Raku/ast/variable-declaration.rakumod my $*RAKUDOC := []; $SELF.fetch-blocks( nqp::getattr( $SELF,RakuAST::VarDeclaration::Implicit::Doc,'$!cu' ).statement-list ); nqp::bindattr($SELF, RakuAST::VarDeclaration::Implicit::Doc, '$!value', $SELF.IMPL-WRAP-LIST($*RAKUDOC) ); }); compose(RakuAST::VarDeclaration::Implicit::Doc::Rakudoc); parent(RakuAST::VarDeclaration::Placeholder, RakuAST::Declaration); parent(RakuAST::VarDeclaration::Placeholder, RakuAST::Attaching); parent(RakuAST::VarDeclaration::Placeholder, RakuAST::Term); parent(RakuAST::VarDeclaration::Placeholder, RakuAST::BeginTime); parent(RakuAST::VarDeclaration::Placeholder, RakuAST::CheckTime); add-attribute(RakuAST::VarDeclaration::Placeholder, Bool, '$!already-declared'); add-method(RakuAST::VarDeclaration::Placeholder, 'lexical-name', [RakuAST::VarDeclaration::Placeholder, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1794 src/Raku/ast/variable-declaration.rakumod nqp::die('Missing lexical-name implementation') }); add-method(RakuAST::VarDeclaration::Placeholder, 'generate-parameter', [RakuAST::VarDeclaration::Placeholder, '', 0, 0], anon sub generate-parameter ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1796 src/Raku/ast/variable-declaration.rakumod nqp::die('Missing generate-parameter implementation') }); add-method(RakuAST::VarDeclaration::Placeholder, 'attach', [RakuAST::VarDeclaration::Placeholder, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1800 src/Raku/ast/variable-declaration.rakumod my $owner := $resolver.find-attach-target('block'); if $owner { $owner.add-placeholder-parameter($SELF); } }); add-method(RakuAST::VarDeclaration::Placeholder, 'default-scope', [RakuAST::VarDeclaration::Placeholder, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1807 src/Raku/ast/variable-declaration.rakumod 'my' }); add-method(RakuAST::VarDeclaration::Placeholder, 'allowed-scopes', [RakuAST::VarDeclaration::Placeholder, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1809 src/Raku/ast/variable-declaration.rakumod ['my'] }); add-method(RakuAST::VarDeclaration::Placeholder, 'generate-lookup', [RakuAST::VarDeclaration::Placeholder, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1811 src/Raku/ast/variable-declaration.rakumod my $lookup := RakuAST::Var::Lexical.new($SELF.lexical-name); $lookup.set-resolution($SELF); $lookup }); add-method(RakuAST::VarDeclaration::Placeholder, 'is-simple-lexical-declaration', [RakuAST::VarDeclaration::Placeholder, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1817 src/Raku/ast/variable-declaration.rakumod (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Placeholder, 'PERFORM-BEGIN', [RakuAST::VarDeclaration::Placeholder, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1821 src/Raku/ast/variable-declaration.rakumod $resolver.find-attach-target('block').add-generated-lexical-declaration($SELF) unless nqp::getattr($SELF, RakuAST::VarDeclaration::Placeholder, '$!already-declared'); }); add-method(RakuAST::VarDeclaration::Placeholder, 'PERFORM-CHECK', [RakuAST::VarDeclaration::Placeholder, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1829 src/Raku/ast/variable-declaration.rakumod my $signature := $resolver.find-attach-target('block').signature; if $signature.parameters-initialized { # @_ and %_ are only real placeholders if they were not # already defined in the signature, so we need to check # there before pulling the plug my $name := $SELF.lexical-name; if $name eq '@_' || $name eq '%_' { return (Bool.WHO) if $signature.IMPL-HAS-PARAMETER($name); } $SELF.add-sorry: $resolver.build-exception: 'X::Signature::Placeholder', precursor => 1, placeholder => $name; return (Bool.WHO); } (Bool.WHO) }); add-method(RakuAST::VarDeclaration::Placeholder, 'IMPL-ALREADY-DECLARED', [RakuAST::VarDeclaration::Placeholder, '', 0, 0, Bool, '$declared', 0, 0], anon sub IMPL-ALREADY-DECLARED ($SELF_CONT, $declared!) { my $SELF := nqp::decont($SELF_CONT); $declared := nqp::decont($declared); #line 1848 src/Raku/ast/variable-declaration.rakumod nqp::bindattr($SELF, RakuAST::VarDeclaration::Placeholder, '$!already-declared', $declared ?? (Bool.WHO) !! (Bool.WHO)); }); add-method(RakuAST::VarDeclaration::Placeholder, 'IMPL-TO-QAST', [RakuAST::VarDeclaration::Placeholder, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1852 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::VarDeclaration::Placeholder, 'IMPL-EXPR-QAST', [RakuAST::VarDeclaration::Placeholder, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1856 src/Raku/ast/variable-declaration.rakumod $SELF.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::VarDeclaration::Placeholder, 'IMPL-LOOKUP-QAST', [RakuAST::VarDeclaration::Placeholder, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$rvalue', 1, 1], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!, :$rvalue?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $rvalue := nqp::decont($rvalue); #line 1860 src/Raku/ast/variable-declaration.rakumod QAST::Var.new( :name($SELF.lexical-name), :scope('lexical') ) }); add-method(RakuAST::VarDeclaration::Placeholder, 'IMPL-QAST-DECL', [RakuAST::VarDeclaration::Placeholder, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1864 src/Raku/ast/variable-declaration.rakumod QAST::Var.new( :decl('var'), :scope('lexical'), :name($SELF.lexical-name) ) }); compose(RakuAST::VarDeclaration::Placeholder); parent(RakuAST::VarDeclaration::Placeholder::Positional, RakuAST::VarDeclaration::Placeholder); add-attribute(RakuAST::VarDeclaration::Placeholder::Positional, str, '$!lexical-name'); add-method(RakuAST::VarDeclaration::Placeholder::Positional, 'new', [RakuAST::VarDeclaration::Placeholder::Positional, '', 0, 0, str, '$declared-name', 0, 0], anon sub new ($SELF_CONT, $declared-name!) { my $SELF := nqp::decont($SELF_CONT); $declared-name := nqp::decont($declared-name); #line 1875 src/Raku/ast/variable-declaration.rakumod if nqp::substr($declared-name, 1, 1) eq '^' { nqp::die('Should construct a ' ~ $SELF.HOW.name($SELF) ~ ' without the ^ twigil'); } my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Placeholder::Positional, '$!lexical-name', $declared-name); $obj }); add-method(RakuAST::VarDeclaration::Placeholder::Positional, 'generate-parameter', [RakuAST::VarDeclaration::Placeholder::Positional, '', 0, 0], anon sub generate-parameter ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1885 src/Raku/ast/variable-declaration.rakumod RakuAST::Parameter.new: target => RakuAST::ParameterTarget::Var.new($SELF.lexical-name) }); #line 1873 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Placeholder::Positional, 'lexical-name', [], anon sub lexical-name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::VarDeclaration::Placeholder::Positional, '$!lexical-name') }); compose(RakuAST::VarDeclaration::Placeholder::Positional); parent(RakuAST::VarDeclaration::Placeholder::Named, RakuAST::VarDeclaration::Placeholder); add-attribute(RakuAST::VarDeclaration::Placeholder::Named, str, '$!lexical-name'); add-method(RakuAST::VarDeclaration::Placeholder::Named, 'new', [RakuAST::VarDeclaration::Placeholder::Named, '', 0, 0, str, '$declared-name', 0, 0], anon sub new ($SELF_CONT, $declared-name!) { my $SELF := nqp::decont($SELF_CONT); $declared-name := nqp::decont($declared-name); #line 1897 src/Raku/ast/variable-declaration.rakumod if nqp::substr($declared-name, 1, 1) eq ':' { nqp::die('Should construct a ' ~ $SELF.HOW.name($SELF) ~ ' without the : twigil'); } my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::VarDeclaration::Placeholder::Named, '$!lexical-name', $declared-name); $obj }); add-method(RakuAST::VarDeclaration::Placeholder::Named, 'generate-parameter', [RakuAST::VarDeclaration::Placeholder::Named, '', 0, 0], anon sub generate-parameter ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1907 src/Raku/ast/variable-declaration.rakumod RakuAST::Parameter.new: target => RakuAST::ParameterTarget::Var.new($SELF.lexical-name), names => [nqp::substr($SELF.lexical-name, 1)], optional => 0 }); #line 1895 src/Raku/ast/variable-declaration.rakumod add-method(RakuAST::VarDeclaration::Placeholder::Named, 'lexical-name', [], anon sub lexical-name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::VarDeclaration::Placeholder::Named, '$!lexical-name') }); compose(RakuAST::VarDeclaration::Placeholder::Named); parent(RakuAST::VarDeclaration::Placeholder::SlurpyArray, RakuAST::VarDeclaration::Placeholder); add-method(RakuAST::VarDeclaration::Placeholder::SlurpyArray, 'lexical-name', [RakuAST::VarDeclaration::Placeholder::SlurpyArray, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1919 src/Raku/ast/variable-declaration.rakumod '@_' }); add-method(RakuAST::VarDeclaration::Placeholder::SlurpyArray, 'generate-parameter', [RakuAST::VarDeclaration::Placeholder::SlurpyArray, '', 0, 0], anon sub generate-parameter ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1921 src/Raku/ast/variable-declaration.rakumod RakuAST::Parameter.new: target => RakuAST::ParameterTarget::Var.new($SELF.lexical-name), slurpy => RakuAST::Parameter::Slurpy::Flattened }); compose(RakuAST::VarDeclaration::Placeholder::SlurpyArray); parent(RakuAST::VarDeclaration::Placeholder::SlurpyHash, RakuAST::VarDeclaration::Placeholder); add-method(RakuAST::VarDeclaration::Placeholder::SlurpyHash, 'lexical-name', [RakuAST::VarDeclaration::Placeholder::SlurpyHash, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1932 src/Raku/ast/variable-declaration.rakumod '%_' }); add-method(RakuAST::VarDeclaration::Placeholder::SlurpyHash, 'generate-parameter', [RakuAST::VarDeclaration::Placeholder::SlurpyHash, '', 0, 0], anon sub generate-parameter ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1934 src/Raku/ast/variable-declaration.rakumod RakuAST::Parameter.new: target => RakuAST::ParameterTarget::Var.new($SELF.lexical-name), slurpy => RakuAST::Parameter::Slurpy::Flattened }); compose(RakuAST::VarDeclaration::Placeholder::SlurpyHash); parent(RakuAST::Var, RakuAST::Term); add-method(RakuAST::Var, 'sigil', [RakuAST::Var, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 5 src/Raku/ast/variable-access.rakumod '' }); compose(RakuAST::Var); parent(RakuAST::Var::Lexical, RakuAST::Var); parent(RakuAST::Var::Lexical, RakuAST::Lookup); add-attribute(RakuAST::Var::Lexical, str, '$!sigil'); add-attribute(RakuAST::Var::Lexical, str, '$!twigil'); add-attribute(RakuAST::Var::Lexical, RakuAST::Name, '$!desigilname'); add-method(RakuAST::Var::Lexical, 'new', [RakuAST::Var::Lexical, '', 0, 0, str, '$name', 0, 1, Str, '$sigil', 1, 1, Str, '$twigil', 1, 1, RakuAST::Name, '$desigilname', 1, 1], anon sub new ($SELF_CONT, $name?, :$sigil?, :$twigil?, :$desigilname?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $sigil := nqp::decont($sigil); $twigil := nqp::decont($twigil); $desigilname := nqp::decont($desigilname); #line 17 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); if $name { nqp::bindattr_s($obj, RakuAST::Var::Lexical, '$!sigil', nqp::substr($name, 0, 1)); nqp::bindattr_s($obj, RakuAST::Var::Lexical, '$!twigil', ''); nqp::bindattr($obj, RakuAST::Var::Lexical, '$!desigilname', RakuAST::Name.from-identifier(nqp::substr($name, 1))) } else { nqp::bindattr_s($obj, RakuAST::Var::Lexical, '$!sigil', $sigil); nqp::bindattr_s($obj, RakuAST::Var::Lexical, '$!twigil', $twigil); nqp::bindattr($obj, RakuAST::Var::Lexical, '$!desigilname', $desigilname); } $obj }); add-method(RakuAST::Var::Lexical, 'postdeclaration-exception-name', [RakuAST::Var::Lexical, '', 0, 0], anon sub postdeclaration-exception-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 33 src/Raku/ast/variable-access.rakumod 'X::Redeclaration::Outer' }); add-method(RakuAST::Var::Lexical, 'name', [RakuAST::Var::Lexical, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 35 src/Raku/ast/variable-access.rakumod (nqp::getattr_s($SELF, RakuAST::Var::Lexical, '$!sigil') // '') ~ (nqp::getattr_s($SELF, RakuAST::Var::Lexical, '$!twigil') // '') ~ nqp::getattr($SELF, RakuAST::Var::Lexical, '$!desigilname').canonicalize }); add-method(RakuAST::Var::Lexical, 'can-be-bound-to', [RakuAST::Var::Lexical, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 39 src/Raku/ast/variable-access.rakumod $SELF.is-resolved ?? $SELF.resolution.can-be-bound-to !! (Bool.WHO) }); add-method(RakuAST::Var::Lexical, 'resolve-with', [RakuAST::Var::Lexical, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 43 src/Raku/ast/variable-access.rakumod my $resolved := $resolver.resolve-lexical($SELF.name); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Var::Lexical, 'undeclared-symbol-details', [RakuAST::Var::Lexical, '', 0, 0], anon sub undeclared-symbol-details ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 51 src/Raku/ast/variable-access.rakumod nqp::getattr_s($SELF, RakuAST::Var::Lexical, '$!sigil') eq '&' ?? RakuAST::UndeclaredSymbolDescription::Routine.new($SELF.name) !! Nil }); add-method(RakuAST::Var::Lexical, 'is-topic', [RakuAST::Var::Lexical, '', 0, 0], anon sub is-topic ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 57 src/Raku/ast/variable-access.rakumod $SELF.name eq '$_' }); add-method(RakuAST::Var::Lexical, 'IMPL-IS-META-OP', [RakuAST::Var::Lexical, '', 0, 0], anon sub IMPL-IS-META-OP ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 61 src/Raku/ast/variable-access.rakumod (nqp::getattr_s($SELF, RakuAST::Var::Lexical, '$!sigil') eq '&' || nqp::getattr_s($SELF, RakuAST::Var::Lexical, '$!sigil') eq '') && nqp::elems(nqp::getattr($SELF, RakuAST::Var::Lexical, '$!desigilname').colonpairs) == 1 && nqp::istype(nqp::getattr($SELF, RakuAST::Var::Lexical, '$!desigilname').colonpairs[0], RakuAST::QuotedString) }); add-method(RakuAST::Var::Lexical, 'IMPL-EXPR-QAST', [RakuAST::Var::Lexical, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 67 src/Raku/ast/variable-access.rakumod $SELF.resolution.IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::Var::Lexical, 'IMPL-BIND-QAST', [RakuAST::Var::Lexical, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 71 src/Raku/ast/variable-access.rakumod $SELF.resolution.IMPL-BIND-QAST($context, $source-qast) }); add-method(RakuAST::Var::Lexical, 'IMPL-CAN-INTERPRET', [RakuAST::Var::Lexical, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 75 src/Raku/ast/variable-access.rakumod $SELF.is-resolved && nqp::istype($SELF.resolution, RakuAST::CompileTimeValue) }); add-method(RakuAST::Var::Lexical, 'IMPL-INTERPRET', [RakuAST::Var::Lexical, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 79 src/Raku/ast/variable-access.rakumod $SELF.resolution.compile-time-value }); add-method(RakuAST::Var::Lexical, 'dump-markers', [RakuAST::Var::Lexical, '', 0, 0], anon sub dump-markers ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 83 src/Raku/ast/variable-access.rakumod '【' ~ $SELF.name ~ '】' }); #line 14 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Lexical, 'twigil', [], anon sub twigil ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Var::Lexical, '$!twigil') }); #line 13 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Lexical, 'sigil', [], anon sub sigil ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Var::Lexical, '$!sigil') }); #line 15 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Lexical, 'desigilname', [], anon sub desigilname ($self) { nqp::getattr(nqp::decont($self), RakuAST::Var::Lexical, '$!desigilname') }); compose(RakuAST::Var::Lexical); parent(RakuAST::Var::Lexical::Constant, RakuAST::Var::Lexical); add-method(RakuAST::Var::Lexical::Constant, 'resolve-with', [RakuAST::Var::Lexical::Constant, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 93 src/Raku/ast/variable-access.rakumod my $resolved := $resolver.resolve-lexical-constant($SELF.name); if $resolved { $SELF.set-resolution($resolved); } Nil }); compose(RakuAST::Var::Lexical::Constant); parent(RakuAST::Var::Lexical::Setting, RakuAST::Var::Lexical); parent(RakuAST::Var::Lexical::Setting, RakuAST::Lookup); add-method(RakuAST::Var::Lexical::Setting, 'resolve-with', [RakuAST::Var::Lexical::Setting, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 108 src/Raku/ast/variable-access.rakumod my $resolved := $resolver.resolve-lexical-constant-in-setting($SELF.name); if $resolved { $SELF.set-resolution($resolved); } Nil }); compose(RakuAST::Var::Lexical::Setting); parent(RakuAST::Var::Dynamic, RakuAST::Var); parent(RakuAST::Var::Dynamic, RakuAST::Lookup); parent(RakuAST::Var::Dynamic, RakuAST::CheckTime); add-attribute(RakuAST::Var::Dynamic, str, '$!name'); add-method(RakuAST::Var::Dynamic, 'new', [RakuAST::Var::Dynamic, '', 0, 0, str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 125 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Var::Dynamic, '$!name', $name); $obj }); add-method(RakuAST::Var::Dynamic, 'sigil', [RakuAST::Var::Dynamic, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 131 src/Raku/ast/variable-access.rakumod nqp::substr(nqp::getattr_s($SELF, RakuAST::Var::Dynamic, '$!name'), 0, 1) }); add-method(RakuAST::Var::Dynamic, 'can-be-bound-to', [RakuAST::Var::Dynamic, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 133 src/Raku/ast/variable-access.rakumod (Bool.WHO) }); add-method(RakuAST::Var::Dynamic, 'needs-resolution', [RakuAST::Var::Dynamic, '', 0, 0], anon sub needs-resolution ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 135 src/Raku/ast/variable-access.rakumod (Bool.WHO) }); add-method(RakuAST::Var::Dynamic, 'resolve-with', [RakuAST::Var::Dynamic, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 137 src/Raku/ast/variable-access.rakumod my $resolved := $resolver.resolve-lexical(nqp::getattr_s($SELF, RakuAST::Var::Dynamic, '$!name'), :current-scope-only); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Var::Dynamic, 'postdeclaration-exception-name', [RakuAST::Var::Dynamic, '', 0, 0], anon sub postdeclaration-exception-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 145 src/Raku/ast/variable-access.rakumod 'X::Dynamic::Postdeclaration' }); add-method(RakuAST::Var::Dynamic, 'PERFORM-CHECK', [RakuAST::Var::Dynamic, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 147 src/Raku/ast/variable-access.rakumod $SELF.add-sorry( $resolver.build-exception: 'X::Dynamic::Package', :symbol(nqp::getattr_s($SELF, RakuAST::Var::Dynamic, '$!name')) ) if nqp::index(nqp::getattr_s($SELF, RakuAST::Var::Dynamic, '$!name'), '::') >= 0; }); add-method(RakuAST::Var::Dynamic, 'IMPL-EXPR-QAST', [RakuAST::Var::Dynamic, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 154 src/Raku/ast/variable-access.rakumod # If it's resolved in the current scope, just a lexical access. if $SELF.is-resolved { my $name := $SELF.resolution.lexical-name; QAST::Var.new( :$name, :scope ) } else { my $with-star := QAST::SVal.new( :value(nqp::getattr_s($SELF, RakuAST::Var::Dynamic, '$!name')) ); my $without-star := QAST::SVal.new( :value(nqp::replace(nqp::getattr_s($SELF, RakuAST::Var::Dynamic, '$!name'), 1, 1, '')) ); QAST::Op.new( :op('ifnull'), QAST::Op.new( :op('getlexdyn'), $with-star), QAST::Op.new( :op('callstatic'), :name('&DYNAMIC-FALLBACK'), $with-star, $without-star ) ) } }); add-method(RakuAST::Var::Dynamic, 'IMPL-BIND-QAST', [RakuAST::Var::Dynamic, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 174 src/Raku/ast/variable-access.rakumod # If it's resolved in the current scope, just a lexical bind. if $SELF.is-resolved { my $name := $SELF.resolution.lexical-name; QAST::Op.new( :op('bind'), QAST::Var.new( :$name, :scope ), $source-qast ) } else { my $complain := QAST::Op.new( :op('die_s'), QAST::SVal.new( :value('Dynamic variable ' ~ nqp::getattr_s($SELF, RakuAST::Var::Dynamic, '$!name') ~ ' not found') ) ); QAST::Op.new( :op('bind'), QAST::VarWithFallback.new( :name(nqp::getattr_s($SELF, RakuAST::Var::Dynamic, '$!name')), :scope('contextual'), :fallback($complain) ), $source-qast ) } }); #line 123 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Dynamic, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Var::Dynamic, '$!name') }); compose(RakuAST::Var::Dynamic); parent(RakuAST::Var::Attribute, RakuAST::Var); parent(RakuAST::Var::Attribute, RakuAST::ImplicitLookups); parent(RakuAST::Var::Attribute, RakuAST::Attaching); add-attribute(RakuAST::Var::Attribute, str, '$!name'); add-attribute(RakuAST::Var::Attribute, RakuAST::Package, '$!package'); add-method(RakuAST::Var::Attribute, 'new', [RakuAST::Var::Attribute, '', 0, 0, str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 209 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Var::Attribute, '$!name', $name); $obj }); add-method(RakuAST::Var::Attribute, 'sigil', [RakuAST::Var::Attribute, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 215 src/Raku/ast/variable-access.rakumod nqp::substr(nqp::getattr_s($SELF, RakuAST::Var::Attribute, '$!name'), 0, 1) }); add-method(RakuAST::Var::Attribute, 'can-be-bound-to', [RakuAST::Var::Attribute, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 217 src/Raku/ast/variable-access.rakumod my $package := nqp::getattr($SELF, RakuAST::Var::Attribute, '$!package').meta-object; my $attr-type := $package.HOW.get_attribute_for_usage($package, nqp::getattr_s($SELF, RakuAST::Var::Attribute, '$!name')).type; nqp::objprimspec($attr-type) ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Var::Attribute, 'attach', [RakuAST::Var::Attribute, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 223 src/Raku/ast/variable-access.rakumod my $package := $resolver.find-attach-target('package'); if $package { # We can't check attributes exist until we compose the # package, since they may come from roles. Thus we need to # attach them to the package. $package.ATTACH-ATTRIBUTE-USAGE($SELF); nqp::bindattr($SELF, RakuAST::Var::Attribute, '$!package', $package); } else { # TODO check-time error } }); add-method(RakuAST::Var::Attribute, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Var::Attribute, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 237 src/Raku/ast/variable-access.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Term::Self.new, RakuAST::Var::Compiler::Lookup.new('$?CLASS'), ]) }); add-method(RakuAST::Var::Attribute, 'IMPL-QAST-PACKAGE-LOOKUP', [RakuAST::Var::Attribute, '', 0, 0, RakuAST::Impl::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-PACKAGE-LOOKUP ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 244 src/Raku/ast/variable-access.rakumod my $class := $SELF.get-implicit-lookups.AT-POS(1); if $class.is-resolved && nqp::istype($class.resolution, RakuAST::CompileTimeValue) { my $type-object := $class.resolution.compile-time-value; my $how := $type-object.HOW; unless nqp::can($how, 'archetypes') && nqp::can($how.archetypes, 'generic') && $how.archetypes.generic { return QAST::WVal.new(:value($type-object)) } } return QAST::Var.new(:scope, :name('$?CLASS')) }); add-method(RakuAST::Var::Attribute, 'IMPL-EXPR-QAST', [RakuAST::Var::Attribute, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 257 src/Raku/ast/variable-access.rakumod my $package := nqp::getattr($SELF, RakuAST::Var::Attribute, '$!package').meta-object; my $attr-type := $package.HOW.get_attribute_for_usage($package, nqp::getattr_s($SELF, RakuAST::Var::Attribute, '$!name')).type; QAST::Var.new( :scope(nqp::objprimspec($attr-type) ?? 'attributeref' !! 'attribute'), :name(nqp::getattr_s($SELF, RakuAST::Var::Attribute, '$!name')), :returns($attr-type), $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context), $SELF.IMPL-QAST-PACKAGE-LOOKUP($context), ) }); add-method(RakuAST::Var::Attribute, 'IMPL-BIND-QAST', [RakuAST::Var::Attribute, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 268 src/Raku/ast/variable-access.rakumod my $package := nqp::getattr($SELF, RakuAST::Var::Attribute, '$!package').meta-object; my $attr-type := $package.HOW.get_attribute_for_usage($package, nqp::getattr_s($SELF, RakuAST::Var::Attribute, '$!name')).type; unless nqp::eqaddr($attr-type, Mu) { $context.ensure-sc($attr-type); $source-qast := QAST::Op.new( :op('p6bindassert'), $source-qast, QAST::WVal.new( :value($attr-type) ) ); } QAST::Op.new( :op('bind'), QAST::Var.new( :scope('attribute'), :name(nqp::getattr_s($SELF, RakuAST::Var::Attribute, '$!name')), :returns($attr-type), $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context), $SELF.IMPL-QAST-PACKAGE-LOOKUP($context), ), $source-qast ) }); #line 206 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Attribute, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Var::Attribute, '$!name') }); compose(RakuAST::Var::Attribute); parent(RakuAST::Var::Compiler, RakuAST::Var); compose(RakuAST::Var::Compiler); parent(RakuAST::Var::Compiler::File, RakuAST::Var::Compiler); add-attribute(RakuAST::Var::Compiler::File, Str, '$!file'); add-method(RakuAST::Var::Compiler::File, 'new', [RakuAST::Var::Compiler::File, '', 0, 0, Str, '$file', 0, 0], anon sub new ($SELF_CONT, $file!) { my $SELF := nqp::decont($SELF_CONT); $file := nqp::decont($file); #line 301 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Var::Compiler::File, '$!file', $file); $obj }); add-method(RakuAST::Var::Compiler::File, 'sigil', [RakuAST::Var::Compiler::File, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 307 src/Raku/ast/variable-access.rakumod '$' }); add-method(RakuAST::Var::Compiler::File, 'IMPL-EXPR-QAST', [RakuAST::Var::Compiler::File, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 309 src/Raku/ast/variable-access.rakumod my $value := nqp::getattr($SELF, RakuAST::Var::Compiler::File, '$!file'); $context.ensure-sc($value); QAST::WVal.new( :$value ) }); add-method(RakuAST::Var::Compiler::File, 'IMPL-CAN-INTERPRET', [RakuAST::Var::Compiler::File, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 315 src/Raku/ast/variable-access.rakumod (Bool.WHO) }); add-method(RakuAST::Var::Compiler::File, 'IMPL-INTERPRET', [RakuAST::Var::Compiler::File, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 317 src/Raku/ast/variable-access.rakumod nqp::getattr($SELF, RakuAST::Var::Compiler::File, '$!file') }); #line 299 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Compiler::File, 'file', [], anon sub file ($self) { nqp::getattr(nqp::decont($self), RakuAST::Var::Compiler::File, '$!file') }); compose(RakuAST::Var::Compiler::File); parent(RakuAST::Var::Compiler::Line, RakuAST::Var::Compiler); add-attribute(RakuAST::Var::Compiler::Line, Int, '$!line'); add-method(RakuAST::Var::Compiler::Line, 'new', [RakuAST::Var::Compiler::Line, '', 0, 0, Int, '$line', 0, 0], anon sub new ($SELF_CONT, $line!) { my $SELF := nqp::decont($SELF_CONT); $line := nqp::decont($line); #line 326 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Var::Compiler::Line, '$!line', $line); $obj }); add-method(RakuAST::Var::Compiler::Line, 'sigil', [RakuAST::Var::Compiler::Line, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 332 src/Raku/ast/variable-access.rakumod '$' }); add-method(RakuAST::Var::Compiler::Line, 'IMPL-EXPR-QAST', [RakuAST::Var::Compiler::Line, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 334 src/Raku/ast/variable-access.rakumod my $value := nqp::getattr($SELF, RakuAST::Var::Compiler::Line, '$!line'); $context.ensure-sc($value); QAST::WVal.new( :$value ) }); add-method(RakuAST::Var::Compiler::Line, 'IMPL-CAN-INTERPRET', [RakuAST::Var::Compiler::Line, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 340 src/Raku/ast/variable-access.rakumod (Bool.WHO) }); add-method(RakuAST::Var::Compiler::Line, 'IMPL-INTERPRET', [RakuAST::Var::Compiler::Line, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 342 src/Raku/ast/variable-access.rakumod nqp::getattr($SELF, RakuAST::Var::Compiler::Line, '$!line') }); #line 324 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Compiler::Line, 'line', [], anon sub line ($self) { nqp::getattr(nqp::decont($self), RakuAST::Var::Compiler::Line, '$!line') }); compose(RakuAST::Var::Compiler::Line); parent(RakuAST::Var::Compiler::Block, RakuAST::Var::Compiler); add-method(RakuAST::Var::Compiler::Block, 'IMPL-EXPR-QAST', [RakuAST::Var::Compiler::Block, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 348 src/Raku/ast/variable-access.rakumod QAST::Op.new( :op('getcodeobj'), QAST::Op.new( :op('curcode') ) ) }); compose(RakuAST::Var::Compiler::Block); parent(RakuAST::Var::Compiler::Routine, RakuAST::Var::Compiler); parent(RakuAST::Var::Compiler::Routine, RakuAST::Var::Lexical); parent(RakuAST::Var::Compiler::Routine, RakuAST::Attaching); add-method(RakuAST::Var::Compiler::Routine, 'new', [RakuAST::Var::Compiler::Routine, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 358 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Var::Lexical, '$!sigil', '&'); nqp::bindattr_s($obj, RakuAST::Var::Lexical, '$!twigil', '?'); nqp::bindattr($obj, RakuAST::Var::Lexical, '$!desigilname', RakuAST::Name.from-identifier('ROUTINE')); $obj }); add-method(RakuAST::Var::Compiler::Routine, 'attach', [RakuAST::Var::Compiler::Routine, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 366 src/Raku/ast/variable-access.rakumod my $routine := $resolver.find-attach-target('routine'); if nqp::isconcrete($routine) { $routine.set-need-routine-variable(); } }); add-method(RakuAST::Var::Compiler::Routine, 'resolve-with', [RakuAST::Var::Compiler::Routine, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 373 src/Raku/ast/variable-access.rakumod my $resolved := $resolver.resolve-lexical('&?ROUTINE'); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Var::Compiler::Routine, 'IMPL-EXPR-QAST', [RakuAST::Var::Compiler::Routine, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 381 src/Raku/ast/variable-access.rakumod QAST::Var.new(:name<&?ROUTINE>, :scope) }); compose(RakuAST::Var::Compiler::Routine); parent(RakuAST::Var::Compiler::Lookup, RakuAST::Var::Compiler); parent(RakuAST::Var::Compiler::Lookup, RakuAST::Lookup); add-attribute(RakuAST::Var::Compiler::Lookup, str, '$!name'); add-method(RakuAST::Var::Compiler::Lookup, 'new', [RakuAST::Var::Compiler::Lookup, '', 0, 0, str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 394 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Var::Compiler::Lookup, '$!name', $name); $obj }); add-method(RakuAST::Var::Compiler::Lookup, 'sigil', [RakuAST::Var::Compiler::Lookup, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 400 src/Raku/ast/variable-access.rakumod nqp::substr(nqp::getattr_s($SELF, RakuAST::Var::Compiler::Lookup, '$!name'), 0, 1) }); add-method(RakuAST::Var::Compiler::Lookup, 'resolve-with', [RakuAST::Var::Compiler::Lookup, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 402 src/Raku/ast/variable-access.rakumod my $resolved := $resolver.resolve-lexical(nqp::getattr_s($SELF, RakuAST::Var::Compiler::Lookup, '$!name')); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Var::Compiler::Lookup, 'IMPL-EXPR-QAST', [RakuAST::Var::Compiler::Lookup, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 410 src/Raku/ast/variable-access.rakumod $SELF.resolution.IMPL-LOOKUP-QAST($context) }); #line 392 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Compiler::Lookup, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Var::Compiler::Lookup, '$!name') }); compose(RakuAST::Var::Compiler::Lookup); parent(RakuAST::Var::Doc, RakuAST::Var); add-attribute(RakuAST::Var::Doc, str, '$!name'); add-method(RakuAST::Var::Doc, 'new', [RakuAST::Var::Doc, '', 0, 0, Str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 421 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Var::Doc, '$!name', $name); $obj }); add-method(RakuAST::Var::Doc, 'sigil', [RakuAST::Var::Doc, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 426 src/Raku/ast/variable-access.rakumod '$' }); add-method(RakuAST::Var::Doc, 'twigil', [RakuAST::Var::Doc, '', 0, 0], anon sub twigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 427 src/Raku/ast/variable-access.rakumod '=' }); add-method(RakuAST::Var::Doc, 'IMPL-EXPR-QAST', [RakuAST::Var::Doc, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 429 src/Raku/ast/variable-access.rakumod QAST::Var.new(:name($SELF.sigil ~ $SELF.twigil ~ nqp::getattr_s($SELF, RakuAST::Var::Doc, '$!name')), :scope) }); #line 419 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Doc, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Var::Doc, '$!name') }); compose(RakuAST::Var::Doc); parent(RakuAST::Var::PositionalCapture, RakuAST::Var); parent(RakuAST::Var::PositionalCapture, RakuAST::ImplicitLookups); add-attribute(RakuAST::Var::PositionalCapture, Int, '$!index'); add-method(RakuAST::Var::PositionalCapture, 'new', [RakuAST::Var::PositionalCapture, '', 0, 0, Int, '$index', 0, 0], anon sub new ($SELF_CONT, $index!) { my $SELF := nqp::decont($SELF_CONT); $index := nqp::decont($index); #line 441 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Var::PositionalCapture, '$!index', $index); $obj }); add-method(RakuAST::Var::PositionalCapture, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Var::PositionalCapture, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 447 src/Raku/ast/variable-access.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical.new('&postcircumfix:<[ ]>'), RakuAST::Var::Lexical.new('$/'), ]) }); add-method(RakuAST::Var::PositionalCapture, 'IMPL-EXPR-QAST', [RakuAST::Var::PositionalCapture, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 454 src/Raku/ast/variable-access.rakumod my $lookups := $SELF.get-implicit-lookups; my $index := nqp::getattr($SELF, RakuAST::Var::PositionalCapture, '$!index'); $context.ensure-sc($index); QAST::Op.new( :op('call'), :name($lookups.AT-POS(0).resolution.lexical-name), $lookups.AT-POS(1).IMPL-TO-QAST($context), QAST::WVal.new( :value($index) ) ) }); #line 439 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::PositionalCapture, 'index', [], anon sub index ($self) { nqp::getattr(nqp::decont($self), RakuAST::Var::PositionalCapture, '$!index') }); compose(RakuAST::Var::PositionalCapture); parent(RakuAST::Var::NamedCapture, RakuAST::Var); parent(RakuAST::Var::NamedCapture, RakuAST::ImplicitLookups); add-attribute(RakuAST::Var::NamedCapture, RakuAST::QuotedString, '$!index'); add-method(RakuAST::Var::NamedCapture, 'new', [RakuAST::Var::NamedCapture, '', 0, 0, RakuAST::QuotedString, '$index', 0, 0], anon sub new ($SELF_CONT, $index!) { my $SELF := nqp::decont($SELF_CONT); $index := nqp::decont($index); #line 474 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Var::NamedCapture, '$!index', $index); $obj }); add-method(RakuAST::Var::NamedCapture, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Var::NamedCapture, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 480 src/Raku/ast/variable-access.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical.new('&postcircumfix:<{ }>'), RakuAST::Var::Lexical.new('$/'), ]) }); add-method(RakuAST::Var::NamedCapture, 'IMPL-EXPR-QAST', [RakuAST::Var::NamedCapture, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 487 src/Raku/ast/variable-access.rakumod my $lookups := $SELF.get-implicit-lookups; my $op := QAST::Op.new( :op('call'), :name($lookups.AT-POS(0).resolution.lexical-name), $lookups.AT-POS(1).IMPL-TO-QAST($context), ); $op.push(nqp::getattr($SELF, RakuAST::Var::NamedCapture, '$!index').IMPL-TO-QAST($context)) unless nqp::getattr($SELF, RakuAST::Var::NamedCapture, '$!index').is-empty-words; $op }); add-method(RakuAST::Var::NamedCapture, 'visit-children', [RakuAST::Var::NamedCapture, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 498 src/Raku/ast/variable-access.rakumod $visitor(nqp::getattr($SELF, RakuAST::Var::NamedCapture, '$!index')); }); #line 472 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::NamedCapture, 'index', [], anon sub index ($self) { nqp::getattr(nqp::decont($self), RakuAST::Var::NamedCapture, '$!index') }); compose(RakuAST::Var::NamedCapture); parent(RakuAST::Var::Package, RakuAST::Var); parent(RakuAST::Var::Package, RakuAST::Lookup); add-attribute(RakuAST::Var::Package, str, '$!sigil'); add-attribute(RakuAST::Var::Package, RakuAST::Name, '$!name'); add-method(RakuAST::Var::Package, 'new', [RakuAST::Var::Package, '', 0, 0, RakuAST::Name, '$name', 1, 0, Any, '$sigil', 1, 1], anon sub new ($SELF_CONT, :$name!, :$sigil?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $sigil := nqp::decont($sigil); #line 511 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Var::Package, '$!name', $name); nqp::bindattr_s($obj, RakuAST::Var::Package, '$!sigil', $sigil); $obj }); add-method(RakuAST::Var::Package, 'sigil', [RakuAST::Var::Package, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 518 src/Raku/ast/variable-access.rakumod nqp::getattr_s($SELF, RakuAST::Var::Package, '$!sigil') }); add-method(RakuAST::Var::Package, 'can-be-bound-to', [RakuAST::Var::Package, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 520 src/Raku/ast/variable-access.rakumod $SELF.is-resolved ?? $SELF.resolution.can-be-bound-to !! nqp::getattr($SELF, RakuAST::Var::Package, '$!name').is-pseudo-package }); add-method(RakuAST::Var::Package, 'resolve-with', [RakuAST::Var::Package, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 524 src/Raku/ast/variable-access.rakumod my @parts := $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Var::Package, '$!name').parts); my $resolved := $resolver.resolve-name(RakuAST::Name.new(@parts[0])); if $resolved { $SELF.set-resolution($resolved); } Nil }); add-method(RakuAST::Var::Package, 'IMPL-EXPR-QAST', [RakuAST::Var::Package, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 533 src/Raku/ast/variable-access.rakumod my str $sigil := nqp::getattr_s($SELF, RakuAST::Var::Package, '$!sigil'); if nqp::getattr($SELF, RakuAST::Var::Package, '$!name').is-simple { if nqp::getattr($SELF, RakuAST::Var::Package, '$!name').is-pseudo-package { nqp::getattr($SELF, RakuAST::Var::Package, '$!name').IMPL-QAST-PSEUDO-PACKAGE-LOOKUP($context, :$sigil); } else { my @parts := nqp::clone($SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Var::Package, '$!name').parts)); my $final := @parts[nqp::elems(@parts) - 1]; my $result; if $SELF.is-resolved { my $name := $SELF.resolution.lexical-name; nqp::shift(@parts); $result := nqp::istype($SELF.resolution, RakuAST::CompileTimeValue) ?? QAST::WVal.new(:value($SELF.resolution.compile-time-value)) !! QAST::Var.new(:$name, :scope); } else { $result := QAST::Op.new(:op, QAST::SVal.new(:value)); } for @parts { $result := QAST::Op.new( :op('who'), $result ); $result := $_.IMPL-QAST-PACKAGE-LOOKUP-PART($context, $result, $_ =:= $final, :$sigil); } $result } } else { nqp::getattr($SELF, RakuAST::Var::Package, '$!name').IMPL-QAST-INDIRECT-LOOKUP($context, :$sigil) } }); add-method(RakuAST::Var::Package, 'IMPL-ADJUST-QAST-FOR-LVALUE', [RakuAST::Var::Package, '', 0, 0, Mu, '$qast', 0, 0], anon sub IMPL-ADJUST-QAST-FOR-LVALUE ($SELF_CONT, $qast!) { my $SELF := nqp::decont($SELF_CONT); $qast := nqp::decont($qast); #line 565 src/Raku/ast/variable-access.rakumod my $last := $qast.list[-1]; $qast.pop if nqp::istype($last, QAST::SpecialArg) && $last.named eq 'global_fallback'; $qast }); add-method(RakuAST::Var::Package, 'IMPL-BIND-QAST', [RakuAST::Var::Package, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Node, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 571 src/Raku/ast/variable-access.rakumod my $qast := nqp::getattr($SELF, RakuAST::Var::Package, '$!name').IMPL-QAST-PSEUDO-PACKAGE-LOOKUP($context, :sigil(nqp::getattr_s($SELF, RakuAST::Var::Package, '$!sigil'))); $source-qast.named('BIND'); $qast.push($source-qast); $qast }); add-method(RakuAST::Var::Package, 'visit-children', [RakuAST::Var::Package, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 578 src/Raku/ast/variable-access.rakumod $visitor(nqp::getattr($SELF, RakuAST::Var::Package, '$!name')); }); #line 509 src/Raku/ast/variable-access.rakumod add-method(RakuAST::Var::Package, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Var::Package, '$!name') }); compose(RakuAST::Var::Package); parent(RakuAST::Var::Slang, RakuAST::Var); parent(RakuAST::Var::Slang, RakuAST::ImplicitLookups); add-attribute(RakuAST::Var::Slang, Mu, '$!grammar'); add-attribute(RakuAST::Var::Slang, Mu, '$!actions'); add-method(RakuAST::Var::Slang, 'new', [RakuAST::Var::Slang, '', 0, 0, Mu, '$grammar', 1, 0, Mu, '$actions', 1, 0], anon sub new ($SELF_CONT, :$grammar!, :$actions!) { my $SELF := nqp::decont($SELF_CONT); $grammar := nqp::decont($grammar); $actions := nqp::decont($actions); #line 590 src/Raku/ast/variable-access.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Var::Slang, '$!grammar', $grammar); nqp::bindattr($obj, RakuAST::Var::Slang, '$!actions', $actions); $obj }); add-method(RakuAST::Var::Slang, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Var::Slang, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 597 src/Raku/ast/variable-access.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Slang')), ]) }); add-method(RakuAST::Var::Slang, 'sigil', [RakuAST::Var::Slang, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 603 src/Raku/ast/variable-access.rakumod '$' }); add-method(RakuAST::Var::Slang, 'IMPL-EXPR-QAST', [RakuAST::Var::Slang, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 605 src/Raku/ast/variable-access.rakumod my $qast := QAST::Op.new( :op, :name, :returns($SELF.get-implicit-lookups.AT-POS(1)), QAST::Var.new( :name, :scope )); my $g := nqp::getattr($SELF, RakuAST::Var::Slang, '$!grammar'); $context.ensure-sc($g); my $a := nqp::getattr($SELF, RakuAST::Var::Slang, '$!actions'); if !nqp::isnull($g) { my $wval := QAST::WVal.new( :value($g) ); $wval.named('grammar'); $qast.push($wval); $wval := QAST::WVal.new( :value($a) ); $wval.named('actions'); $qast.push($wval); } $qast }); compose(RakuAST::Var::Slang); parent(RakuAST::Contextualizer, RakuAST::Term); add-attribute(RakuAST::Contextualizer, RakuAST::Contextualizable, '$!target'); add-method(RakuAST::Contextualizer, 'new', [RakuAST::Contextualizer, '', 0, 0, RakuAST::Contextualizable, '$target', 0, 0], anon sub new ($SELF_CONT, $target!) { my $SELF := nqp::decont($SELF_CONT); $target := nqp::decont($target); #line 8 src/Raku/ast/contextualizer.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Contextualizer, '$!target', $target); $obj }); add-method(RakuAST::Contextualizer, 'IMPL-EXPR-QAST', [RakuAST::Contextualizer, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 14 src/Raku/ast/contextualizer.rakumod # TODO 6.c semantics with $/ QAST::Op.new( :op('callmethod'), :name($SELF.IMPL-METHOD), nqp::getattr($SELF, RakuAST::Contextualizer, '$!target').IMPL-TO-QAST($context) ) }); add-method(RakuAST::Contextualizer, 'visit-children', [RakuAST::Contextualizer, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 22 src/Raku/ast/contextualizer.rakumod $visitor(nqp::getattr($SELF, RakuAST::Contextualizer, '$!target')); }); #line 6 src/Raku/ast/contextualizer.rakumod add-method(RakuAST::Contextualizer, 'target', [], anon sub target ($self) { nqp::getattr(nqp::decont($self), RakuAST::Contextualizer, '$!target') }); compose(RakuAST::Contextualizer); parent(RakuAST::Contextualizer::Item, RakuAST::Contextualizer); add-method(RakuAST::Contextualizer::Item, 'IMPL-METHOD', [RakuAST::Contextualizer::Item, '', 0, 0], anon sub IMPL-METHOD ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 31 src/Raku/ast/contextualizer.rakumod 'item' }); add-method(RakuAST::Contextualizer::Item, 'sigil', [RakuAST::Contextualizer::Item, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 32 src/Raku/ast/contextualizer.rakumod '$' }); compose(RakuAST::Contextualizer::Item); parent(RakuAST::Contextualizer::List, RakuAST::Contextualizer); add-method(RakuAST::Contextualizer::List, 'IMPL-METHOD', [RakuAST::Contextualizer::List, '', 0, 0], anon sub IMPL-METHOD ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 39 src/Raku/ast/contextualizer.rakumod 'cache' }); add-method(RakuAST::Contextualizer::List, 'sigil', [RakuAST::Contextualizer::List, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 40 src/Raku/ast/contextualizer.rakumod '@' }); compose(RakuAST::Contextualizer::List); parent(RakuAST::Contextualizer::Hash, RakuAST::Contextualizer); add-method(RakuAST::Contextualizer::Hash, 'IMPL-METHOD', [RakuAST::Contextualizer::Hash, '', 0, 0], anon sub IMPL-METHOD ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 47 src/Raku/ast/contextualizer.rakumod 'hash' }); add-method(RakuAST::Contextualizer::Hash, 'sigil', [RakuAST::Contextualizer::Hash, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 48 src/Raku/ast/contextualizer.rakumod '%' }); compose(RakuAST::Contextualizer::Hash); parent(RakuAST::Blockoid, RakuAST::SinkPropagator); add-attribute(RakuAST::Blockoid, RakuAST::StatementList, '$!statement-list'); add-method(RakuAST::Blockoid, 'new', [RakuAST::Blockoid, '', 0, 0, RakuAST::StatementList, '$statement-list', 0, 1], anon sub new ($SELF_CONT, $statement-list?) { my $SELF := nqp::decont($SELF_CONT); $statement-list := nqp::decont($statement-list); #line 7 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Blockoid, '$!statement-list', $statement-list // RakuAST::StatementList.new); $obj }); add-method(RakuAST::Blockoid, 'propagate-sink', [RakuAST::Blockoid, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 14 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::Blockoid, '$!statement-list').propagate-sink($is-sunk, :has-block-parent((Bool.WHO))) }); add-method(RakuAST::Blockoid, 'IMPL-TO-QAST', [RakuAST::Blockoid, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '$immediate', 1, 1], anon sub IMPL-TO-QAST ($SELF_CONT, $context!, :$immediate?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $immediate := nqp::decont($immediate); #line 18 src/Raku/ast/code.rakumod my $stmts := nqp::getattr($SELF, RakuAST::Blockoid, '$!statement-list').IMPL-TO-QAST($context); if nqp::elems($stmts.list) == 0 { $stmts.push(QAST::WVal.new( :value(Nil) )); } $stmts }); add-method(RakuAST::Blockoid, 'visit-children', [RakuAST::Blockoid, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 26 src/Raku/ast/code.rakumod $visitor(nqp::getattr($SELF, RakuAST::Blockoid, '$!statement-list')); }); add-method(RakuAST::Blockoid, 'IMPL-CAN-INTERPRET', [RakuAST::Blockoid, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 30 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::Blockoid, '$!statement-list').IMPL-CAN-INTERPRET }); add-method(RakuAST::Blockoid, 'IMPL-INTERPRET', [RakuAST::Blockoid, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 34 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::Blockoid, '$!statement-list').IMPL-INTERPRET($ctx) }); #line 5 src/Raku/ast/code.rakumod add-method(RakuAST::Blockoid, 'statement-list', [], anon sub statement-list ($self) { nqp::getattr(nqp::decont($self), RakuAST::Blockoid, '$!statement-list') }); compose(RakuAST::Blockoid); parent(RakuAST::OnlyStar, RakuAST::Blockoid); parent(RakuAST::OnlyStar, RakuAST::Term); add-method(RakuAST::OnlyStar, 'new', [RakuAST::OnlyStar, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 43 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Blockoid, '$!statement-list', RakuAST::StatementList.new); $obj }); add-method(RakuAST::OnlyStar, 'IMPL-TO-QAST', [RakuAST::OnlyStar, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '$immediate', 1, 1], anon sub IMPL-TO-QAST ($SELF_CONT, $context!, :$immediate?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $immediate := nqp::decont($immediate); #line 50 src/Raku/ast/code.rakumod QAST::Op.new( :op('dispatch'), QAST::SVal.new( :value('boot-resume') ), QAST::IVal.new( :value(nqp::const::DISP_ONLYSTAR) )); }); compose(RakuAST::OnlyStar); parent(RakuAST::Code, RakuAST::Attaching); add-attribute(RakuAST::Code, Bool, '$!custom-args'); add-attribute(RakuAST::Code, Mu, '$!qast-block'); add-attribute(RakuAST::Code, str, '$!cuid'); add-attribute(RakuAST::Code, RakuAST::Resolver, '$!resolver'); add-method(RakuAST::Code, 'attach', [RakuAST::Code, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 68 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Code, '$!resolver', $resolver.clone); }); add-method(RakuAST::Code, 'set-custom-args', [RakuAST::Code, '', 0, 0], anon sub set-custom-args ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 72 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Code, '$!custom-args', (Bool.WHO)); }); add-method(RakuAST::Code, 'IMPL-CLOSURE-QAST', [RakuAST::Code, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Bool, '$regex', 1, 1], anon sub IMPL-CLOSURE-QAST ($SELF_CONT, $context!, :$regex?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $regex := nqp::decont($regex); #line 76 src/Raku/ast/code.rakumod my $code-obj := $SELF.meta-object; $context.ensure-sc($code-obj); my $clone := QAST::Op.new( :op('callmethod'), :name('clone'), QAST::WVal.new( :value($code-obj) ) ); $SELF.IMPL-TWEAK-REGEX-CLONE($context, $clone) if $regex; QAST::Op.new( :op('p6capturelex'), $clone ) }); add-method(RakuAST::Code, 'IMPL-QAST-BLOCK', [RakuAST::Code, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-QAST-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 88 src/Raku/ast/code.rakumod unless (nqp::getattr($SELF, RakuAST::Code, '$!qast-block')) { $SELF.IMPL-FINISH-CODE-OBJECT($context, :$blocktype, :$expression); } nqp::getattr($SELF, RakuAST::Code, '$!qast-block') }); add-method(RakuAST::Code, 'IMPL-FINISH-CODE-OBJECT', [RakuAST::Code, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-FINISH-CODE-OBJECT ($SELF_CONT, $context!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 96 src/Raku/ast/code.rakumod my $block := $SELF.IMPL-QAST-FORM-BLOCK($context, :$blocktype, :$expression); $SELF.IMPL-LINK-META-OBJECT($context, $block); nqp::bindattr($SELF, RakuAST::Code, '$!qast-block', $block); }); add-method(RakuAST::Code, 'IMPL-STUB-CODE', [RakuAST::Code, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-STUB-CODE ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 102 src/Raku/ast/code.rakumod # Not all objects of certain subclasses will be attached properly, # so get that resolver here nqp::bindattr($SELF, RakuAST::Code, '$!resolver', $resolver.clone) unless nqp::getattr($SELF, RakuAST::Code, '$!resolver'); my $code-obj := $SELF.meta-object; nqp::bindattr_s($SELF, RakuAST::Code, '$!cuid', QAST::Block.next-cuid()); # Stash it under the QAST block unique ID. my str $cuid := nqp::getattr_s($SELF, RakuAST::Code, '$!cuid'); $context.sub-id-to-code-object(){$cuid} := $code-obj; my $precomp; my $stub := nqp::freshcoderef(sub (*@pos, *%named) { my $code-obj := nqp::getcodeobj(nqp::curcode()); unless $precomp { my $*IMPL-COMPILE-DYNAMICALLY := 1; my $block := $SELF.IMPL-QAST-BLOCK($context, :blocktype); $precomp := $SELF.IMPL-COMPILE-DYNAMICALLY($resolver, $context, $block); } unless nqp::isnull($code-obj) { return $code-obj(|@pos, |%named); } }); nqp::bindattr($code-obj, Code, '$!do', $stub); nqp::markcodestatic($stub); nqp::markcodestub($stub); nqp::setcodeobj($stub, $code-obj); # Create the compiler stuff array and stick it in the code object. # Also add clearup task to remove it again later. my @compstuff; nqp::bindattr($code-obj, Code, '@!compstuff', @compstuff); $context.add-cleanup-task(sub () { nqp::bindattr($code-obj, Code, '@!compstuff', nqp::null()); nqp::bindattr($SELF, RakuAST::Code, '$!resolver', RakuAST::Resolver) if $context.is-precompilation-mode; }); @compstuff[2] := sub ($orig, $clone) { my $do := nqp::getattr($clone, Code, '$!do'); nqp::markcodestub($do); $context.add-cleanup-task(sub () { nqp::bindattr($clone, Code, '@!compstuff', nqp::null()); }); $context.add-clone-for-cuid($clone, $cuid); } $stub }); add-method(RakuAST::Code, 'IMPL-LINK-META-OBJECT', [RakuAST::Code, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$block', 0, 0], anon sub IMPL-LINK-META-OBJECT ($SELF_CONT, $context!, $block!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $block := nqp::decont($block); #line 154 src/Raku/ast/code.rakumod # Obtain the meta-object and connect it to the code block. my $code-obj := $SELF.meta-object; $context.ensure-sc($code-obj); # Associate QAST block with code object, which will ensure it is # fixed up as needed. $block.code_object($code-obj); my @compstuff := nqp::getattr($code-obj, Code, '@!compstuff'); my $cuid := nqp::getattr_s($SELF, RakuAST::Code, '$!cuid'); $block.set-cuid(nqp::getattr_s($SELF, RakuAST::Code, '$!cuid')); my $fixups := QAST::Stmts.new(); unless $context.is-precompilation-mode || $context.is-nested { # We need to do a fixup of the code block for the non-precompiled case. $fixups.push( QAST::Op.new( :op('bindattr'), QAST::WVal.new( :value($code-obj) ), QAST::WVal.new( :value(Code) ), QAST::SVal.new( :value('$!do') ), QAST::BVal.new( :value($block) ) ) ); @compstuff[2] := sub ($orig, $clone) { $context.ensure-sc($clone); $context.add-cleanup-task(sub () { nqp::bindattr($clone, Code, '@!compstuff', nqp::null()); }); $context.add-clone-for-cuid($clone, $cuid); my $tmp := $fixups.unique('tmp_block_fixup'); $fixups.push(QAST::Stmt.new( QAST::Op.new( :op('bind'), QAST::Var.new( :name($tmp), :scope('local'), :decl('var') ), QAST::Op.new( :op('clone'), QAST::BVal.new( :value($block) ) ) ), QAST::Op.new( :op('bind'), QAST::Var.new( :name('$!do'), :scope('attribute'), QAST::WVal.new( :value($clone) ), QAST::WVal.new( :value(Code) ) ), QAST::Var.new( :name($tmp), :scope('local') ), ), QAST::Op.new( :op('setcodeobj'), QAST::Var.new( :name($tmp), :scope('local') ), QAST::WVal.new( :value($clone) ) ))); } @compstuff[3] := $fixups; } @compstuff[0] := $block; $context.add-code-ref(nqp::getattr($code-obj, Code, '$!do'), $block); $context.add-fixup-task(-> { $fixups }); }); add-method(RakuAST::Code, 'IMPL-COMPILE-DYNAMICALLY', [RakuAST::Code, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$block', 0, 0], anon sub IMPL-COMPILE-DYNAMICALLY ($SELF_CONT, $resolver!, $context!, $block!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $block := nqp::decont($block); #line 220 src/Raku/ast/code.rakumod my $wrapper := QAST::Block.new(QAST::Stmts.new(), $block); $wrapper.annotate('DYN_COMP_WRAPPER', 1); my $compunit := QAST::CompUnit.new( :hll('Raku'), :sc($context.sc()), :compilation_mode(0), $wrapper ); my $comp := $*HLL-COMPILER // nqp::getcomp("Raku"); my $precomp := $comp.compile($compunit, :from, :compunit_ok(1)); { my $resolver := nqp::getattr($SELF, RakuAST::Code, '$!resolver'); nqp::dispatch( 'boot-syscall', 'set-compunit-resolver', $precomp, -> $name { my $result := $resolver.resolve-lexical($name); if $result { nqp::istype($result, RakuAST::CompileTimeValue) ?? $result.compile-time-value !! Mu } else { nqp::die("No lexical found with name $name via resolver"); } }, -> $dyn-name { my $dynamic-fallback := $resolver.resolve-lexical-in-outer('&DYNAMIC-FALLBACK'); my $without-star := nqp::replace($dyn-name, 1, 1, ''); $dynamic-fallback.compile-time-value()($dyn-name, $without-star) } ); } my $mainline := $comp.backend.compunit_mainline($precomp); $mainline(); # Fix up Code object associations (including nested blocks). # We un-stub any code objects for already-compiled inner blocks # to avoid wasting re-compiling them, and also to help make # parametric role outer chain work out. Also set up their static # lexpads, if they have any. my @coderefs := $comp.backend.compunit_coderefs($precomp); my int $num-subs := nqp::elems(@coderefs); my int $i := -1; my $result; while ++$i < $num-subs { my $subid := nqp::getcodecuid(@coderefs[$i]); # un-stub code objects for blocks we just compiled: my %sub-id-to-code-object := $context.sub-id-to-code-object(); if nqp::existskey(%sub-id-to-code-object, $subid) { my $code-obj := %sub-id-to-code-object{$subid}; nqp::setcodeobj(@coderefs[$i], $code-obj); nqp::bindattr($code-obj, Code, '$!do', @coderefs[$i]); my $fixups := nqp::getattr($code-obj, Code, '@!compstuff')[3]; if $fixups { $fixups.pop() while $fixups.list; } nqp::bindattr($code-obj, Code, '@!compstuff', nqp::null()); } # un-stub clones of code objects for blocks we just compiled: my %sub-id-to-cloned-code-objects := $context.sub-id-to-cloned-code-objects(); if nqp::existskey(%sub-id-to-cloned-code-objects, $subid) { for %sub-id-to-cloned-code-objects{$subid} -> $code-obj { my $clone := nqp::clone(@coderefs[$i]); nqp::setcodeobj($clone, $code-obj); nqp::bindattr($code-obj, Code, '$!do', $clone); my $fixups := nqp::getattr($code-obj, Code, '@!compstuff')[3]; if $fixups { $fixups.pop() while $fixups.list; } nqp::bindattr($code-obj, Code, '@!compstuff', nqp::null()); } } my %sub-id-to-sc-idx := $context.sub-id-to-sc-idx(); if nqp::existskey(%sub-id-to-sc-idx, $subid) { nqp::markcodestatic(@coderefs[$i]); nqp::scsetcode($context.sc, %sub-id-to-sc-idx{$subid}, @coderefs[$i]); } if $subid eq $block.cuid { # Remember the VM coderef that maps to the thing we were originally # asked to compile. $result := @coderefs[$i]; } } $result }); add-method(RakuAST::Code, 'IMPL-APPEND-SIGNATURE-RETURN', [RakuAST::Code, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$qast-stmts', 0, 0], anon sub IMPL-APPEND-SIGNATURE-RETURN ($SELF_CONT, $context!, $qast-stmts!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $qast-stmts := nqp::decont($qast-stmts); #line 317 src/Raku/ast/code.rakumod my $signature := $SELF.signature; if $signature && $signature.provides-return-value { $qast-stmts.push($signature.returns.IMPL-TO-QAST($context)); } $qast-stmts }); add-method(RakuAST::Code, 'needs-sink-call', [RakuAST::Code, '', 0, 0], anon sub needs-sink-call ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 325 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::Code, 'signature', [RakuAST::Code, '', 0, 0], anon sub signature ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 327 src/Raku/ast/code.rakumod Nil }); #line 62 src/Raku/ast/code.rakumod add-method(RakuAST::Code, 'custom-args', [], anon sub custom-args ($self) { nqp::getattr(nqp::decont($self), RakuAST::Code, '$!custom-args') }); compose(RakuAST::Code); parent(RakuAST::ExpressionThunk, RakuAST::Code); parent(RakuAST::ExpressionThunk, RakuAST::Meta); parent(RakuAST::ExpressionThunk, RakuAST::BeginTime); add-attribute(RakuAST::ExpressionThunk, RakuAST::ExpressionThunk, '$!next'); add-attribute(RakuAST::ExpressionThunk, RakuAST::Signature, '$!signature'); add-method(RakuAST::ExpressionThunk, 'set-next', [RakuAST::ExpressionThunk, '', 0, 0, RakuAST::ExpressionThunk, '$next', 0, 0], anon sub set-next ($SELF_CONT, $next!) { my $SELF := nqp::decont($SELF_CONT); $next := nqp::decont($next); #line 340 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::ExpressionThunk, '$!next', $next); Nil }); add-method(RakuAST::ExpressionThunk, 'thunk-kind', [RakuAST::ExpressionThunk, '', 0, 0], anon sub thunk-kind ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 345 src/Raku/ast/code.rakumod $SELF.HOW.name($SELF) }); add-method(RakuAST::ExpressionThunk, 'thunk-details', [RakuAST::ExpressionThunk, '', 0, 0], anon sub thunk-details ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 349 src/Raku/ast/code.rakumod '' }); add-method(RakuAST::ExpressionThunk, 'is-begin-performed-before-children', [RakuAST::ExpressionThunk, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 353 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::ExpressionThunk, 'PERFORM-BEGIN', [RakuAST::ExpressionThunk, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 355 src/Raku/ast/code.rakumod $SELF.IMPL-STUB-CODE($resolver, $context); Nil }); add-method(RakuAST::ExpressionThunk, 'IMPL-THUNK-CODE-QAST', [RakuAST::ExpressionThunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$target', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub IMPL-THUNK-CODE-QAST ($SELF_CONT, $context!, $target!, $expression!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $target := nqp::decont($target); $expression := nqp::decont($expression); #line 366 src/Raku/ast/code.rakumod my $block := $SELF.IMPL-QAST-BLOCK($context, :$expression); # Link and push the produced code block. $target.push($block); }); add-method(RakuAST::ExpressionThunk, 'IMPL-QAST-FORM-BLOCK', [RakuAST::ExpressionThunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 0], anon sub IMPL-QAST-FORM-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 374 src/Raku/ast/code.rakumod # From the block, compiling the signature. my $signature := $SELF.IMPL-GET-OR-PRODUCE-SIGNATURE; my $block := $SELF.IMPL-SET-NODE( QAST::Block.new( :blocktype('declaration_static'), QAST::Stmts.new( $signature.IMPL-QAST-BINDINGS($context) )), :key); my $stmts := QAST::Stmts.new(); for $SELF.IMPL-UNWRAP-LIST($signature.parameters) { $stmts.push($_.target.IMPL-QAST-DECL($context)) unless $_.target.lexical-name eq '$_'; } if nqp::istype($SELF, RakuAST::ImplicitDeclarations) { for $SELF.IMPL-UNWRAP-LIST($SELF.get-implicit-declarations()) -> $decl { if $decl.is-simple-lexical-declaration { nqp::push($stmts, $decl.IMPL-QAST-DECL($context)); } } } # Add blocks embedded in the thunked expression children of the thunk # block, so they can access the thunk argument. my @code-todo := [$expression]; while @code-todo { my $visit := @code-todo.shift; $visit.visit-children: -> $node { if nqp::istype($node, RakuAST::Code) { if $visit =:= $expression || !(nqp::istype($visit, RakuAST::IMPL::ImmediateBlockUser) && $visit.IMPL-IMMEDIATELY-USES($node)) { $stmts.push($node.IMPL-QAST-DECL-CODE($context)); } } unless nqp::istype($node, RakuAST::LexicalScope) { @code-todo.push($node); } } } $block.push($stmts) if $stmts.list; $block.arity($signature.arity); # If there's an inner thunk the body evaluates to that. if nqp::getattr($SELF, RakuAST::ExpressionThunk, '$!next') { nqp::getattr($SELF, RakuAST::ExpressionThunk, '$!next').IMPL-THUNK-CODE-QAST($context, $block[0], $expression); my $value := nqp::getattr($SELF, RakuAST::ExpressionThunk, '$!next').IMPL-THUNK-VALUE-QAST($context); $block.push($value) if $value; } # Otherwise, we evaluate to the expression. else { $block.push($SELF.IMPL-THUNK-TWEAK-EXPRESSION($context, $expression.IMPL-EXPR-QAST($context))); } $block }); add-method(RakuAST::ExpressionThunk, 'IMPL-THUNK-VALUE-QAST', [RakuAST::ExpressionThunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-THUNK-VALUE-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 433 src/Raku/ast/code.rakumod $SELF.IMPL-CLOSURE-QAST($context) }); add-method(RakuAST::ExpressionThunk, 'IMPL-THUNK-OBJECT-TYPE', [RakuAST::ExpressionThunk, '', 0, 0], anon sub IMPL-THUNK-OBJECT-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 439 src/Raku/ast/code.rakumod Code }); add-method(RakuAST::ExpressionThunk, 'IMPL-THUNK-SIGNATURE', [RakuAST::ExpressionThunk, '', 0, 0], anon sub IMPL-THUNK-SIGNATURE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 443 src/Raku/ast/code.rakumod RakuAST::Signature.new }); add-method(RakuAST::ExpressionThunk, 'IMPL-THUNK-TWEAK-EXPRESSION', [RakuAST::ExpressionThunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$qast', 0, 0], anon sub IMPL-THUNK-TWEAK-EXPRESSION ($SELF_CONT, $context!, $qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $qast := nqp::decont($qast); #line 449 src/Raku/ast/code.rakumod $qast }); add-method(RakuAST::ExpressionThunk, 'IMPL-THUNK-META-OBJECT-PRODUCED', [RakuAST::ExpressionThunk, '', 0, 0, Mu, '$meta', 0, 0], anon sub IMPL-THUNK-META-OBJECT-PRODUCED ($SELF_CONT, $meta!) { my $SELF := nqp::decont($SELF_CONT); $meta := nqp::decont($meta); #line 455 src/Raku/ast/code.rakumod }); add-method(RakuAST::ExpressionThunk, 'IMPL-GET-OR-PRODUCE-SIGNATURE', [RakuAST::ExpressionThunk, '', 0, 0], anon sub IMPL-GET-OR-PRODUCE-SIGNATURE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 458 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::ExpressionThunk, '$!signature') // nqp::bindattr($SELF, RakuAST::ExpressionThunk, '$!signature', $SELF.IMPL-THUNK-SIGNATURE) }); add-method(RakuAST::ExpressionThunk, 'PRODUCE-META-OBJECT', [RakuAST::ExpressionThunk, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 463 src/Raku/ast/code.rakumod my $code := nqp::create($SELF.IMPL-THUNK-OBJECT-TYPE); my $signature := $SELF.IMPL-GET-OR-PRODUCE-SIGNATURE; nqp::bindattr($code, Code, '$!signature', $signature.meta-object); nqp::bindattr($signature.meta-object, Signature, '$!code', $code); $SELF.IMPL-THUNK-META-OBJECT-PRODUCED($code); $code }); add-method(RakuAST::ExpressionThunk, 'IMPL-UPDATE-SIGNATURE', [RakuAST::ExpressionThunk, '', 0, 0], anon sub IMPL-UPDATE-SIGNATURE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 472 src/Raku/ast/code.rakumod return Nil unless $SELF.has-meta-object; my $code := $SELF.meta-object; nqp::bindattr($SELF, RakuAST::ExpressionThunk, '$!signature', $SELF.IMPL-THUNK-SIGNATURE); my $signature := nqp::getattr($SELF, RakuAST::ExpressionThunk, '$!signature'); nqp::bindattr($code, Code, '$!signature', $signature.meta-object); nqp::bindattr($signature.meta-object, Signature, '$!code', $code); $SELF.IMPL-THUNK-META-OBJECT-PRODUCED($code); }); #line 337 src/Raku/ast/code.rakumod add-method(RakuAST::ExpressionThunk, 'next', [], anon sub next ($self) { nqp::getattr(nqp::decont($self), RakuAST::ExpressionThunk, '$!next') }); compose(RakuAST::ExpressionThunk); parent(RakuAST::PlaceholderParameterOwner, RakuAST::Node); add-attribute(RakuAST::PlaceholderParameterOwner, Mu, '$!attached-placeholder-parameters'); add-attribute(RakuAST::PlaceholderParameterOwner, Mu, '$!placeholder-map'); add-attribute(RakuAST::PlaceholderParameterOwner, RakuAST::Signature, '$!placeholder-signature'); add-method(RakuAST::PlaceholderParameterOwner, 'add-placeholder-parameter', [RakuAST::PlaceholderParameterOwner, '', 0, 0, RakuAST::VarDeclaration::Placeholder, '$placeholder', 0, 0], anon sub add-placeholder-parameter ($SELF_CONT, $placeholder!) { my $SELF := nqp::decont($SELF_CONT); $placeholder := nqp::decont($placeholder); #line 498 src/Raku/ast/code.rakumod unless nqp::islist(nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!attached-placeholder-parameters')) { nqp::bindattr($SELF, RakuAST::PlaceholderParameterOwner, '$!attached-placeholder-parameters', []); } my $name := $placeholder.lexical-name; if $SELF.IMPL-HAS-PARAMETER($name) { # matches an explicitly declared parameter $placeholder.IMPL-ALREADY-DECLARED((Bool.WHO)); } else { for nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!attached-placeholder-parameters') { if $_.lexical-name eq $name { # same placeholder is used multiple times $placeholder.IMPL-ALREADY-DECLARED((Bool.WHO)); return Nil } } nqp::push(nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!attached-placeholder-parameters'), $placeholder); } Nil }); add-method(RakuAST::PlaceholderParameterOwner, 'clear-placeholder-attachments', [RakuAST::PlaceholderParameterOwner, '', 0, 0], anon sub clear-placeholder-attachments ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 521 src/Raku/ast/code.rakumod if nqp::islist(nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!attached-placeholder-parameters')) { for nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!attached-placeholder-parameters') { # reset declared state on parameters, # will be re-set when they are attached again $_.IMPL-ALREADY-DECLARED((Bool.WHO)); } nqp::bindattr($SELF, RakuAST::PlaceholderParameterOwner, '$!attached-placeholder-parameters', nqp::null()); } Nil }); add-method(RakuAST::PlaceholderParameterOwner, 'has-placeholder-parameters', [RakuAST::PlaceholderParameterOwner, '', 0, 0], anon sub has-placeholder-parameters ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 534 src/Raku/ast/code.rakumod my $params := nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!attached-placeholder-parameters'); nqp::islist($params) && nqp::elems($params) ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::PlaceholderParameterOwner, 'IMPL-HAS-PARAMETER', [RakuAST::PlaceholderParameterOwner, '', 0, 0, Str, '$name', 0, 0], anon sub IMPL-HAS-PARAMETER ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 539 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::PlaceholderParameterOwner, 'IMPL-PLACEHOLDER-MAP', [RakuAST::PlaceholderParameterOwner, '', 0, 0], anon sub IMPL-PLACEHOLDER-MAP ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 543 src/Raku/ast/code.rakumod unless nqp::ishash(nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!placeholder-map')) { my %map; if $SELF.has-placeholder-parameters { for nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!attached-placeholder-parameters') -> $param { my str $key := $param.lexical-name; (%map{$key} || (%map{$key} := [])).push($param); } } nqp::bindattr($SELF, RakuAST::PlaceholderParameterOwner, '$!placeholder-map', %map); } nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!placeholder-map') }); add-method(RakuAST::PlaceholderParameterOwner, 'placeholder-signature', [RakuAST::PlaceholderParameterOwner, '', 0, 0], anon sub placeholder-signature ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 560 src/Raku/ast/code.rakumod # Return Nil if there isn't one to generate, or the cached one if we have # it. return Nil unless $SELF.has-placeholder-parameters(); return nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!placeholder-signature') if nqp::getattr($SELF, RakuAST::PlaceholderParameterOwner, '$!placeholder-signature'); # Group and sort parameters. my @positionals; my @nameds; my @slurpies; for $SELF.IMPL-PLACEHOLDER-MAP() { my $placeholder := $_.value[0]; if nqp::istype($placeholder, RakuAST::VarDeclaration::Placeholder::Positional) { my int $insert-at := 0; my str $desigil-insert := nqp::substr($placeholder.lexical-name, 1); while $insert-at < nqp::elems(@positionals) { my str $desigil-cur := nqp::substr(@positionals[$insert-at].lexical-name, 1); last if $desigil-insert lt $desigil-cur; $insert-at++; } nqp::splice(@positionals, [$placeholder], $insert-at, 0); } elsif nqp::istype($placeholder, RakuAST::VarDeclaration::Placeholder::Named) { my int $insert-at := 0; my str $desigil-insert := nqp::substr($placeholder.lexical-name, 1); while $insert-at < nqp::elems(@nameds) { my str $desigil-cur := nqp::substr(@nameds[$insert-at].lexical-name, 1); last if $desigil-insert lt $desigil-cur; $insert-at++; } nqp::splice(@nameds, [$placeholder], $insert-at, 0); } else { if $placeholder.lexical-name eq '@_' { # @_ before %_ @slurpies.unshift($placeholder); } else { @slurpies.push($placeholder); } } } # Add to signature. my @parameters; for @positionals, @nameds, @slurpies -> @placeholders { for @placeholders { @parameters.push($_.generate-parameter()); } } my $signature := RakuAST::Signature.new(:@parameters); nqp::bindattr($SELF, RakuAST::PlaceholderParameterOwner, '$!placeholder-signature', $signature); $signature }); compose(RakuAST::PlaceholderParameterOwner); parent(RakuAST::ScopePhaser, Any); add-attribute(RakuAST::ScopePhaser, Bool, '$!has-exit-handler'); add-attribute(RakuAST::ScopePhaser, Bool, '$!is-loop-body'); add-attribute(RakuAST::ScopePhaser, List, '$!ENTER'); add-attribute(RakuAST::ScopePhaser, List, '$!LEAVE'); add-attribute(RakuAST::ScopePhaser, List, '$!KEEP'); add-attribute(RakuAST::ScopePhaser, List, '$!UNDO'); add-attribute(RakuAST::ScopePhaser, List, '$!FIRST'); add-attribute(RakuAST::ScopePhaser, List, '$!NEXT'); add-attribute(RakuAST::ScopePhaser, List, '$!LAST'); add-attribute(RakuAST::ScopePhaser, List, '$!PRE'); add-attribute(RakuAST::ScopePhaser, List, '$!POST'); add-attribute(RakuAST::ScopePhaser, List, '$!QUIT'); add-attribute(RakuAST::ScopePhaser, List, '$!CLOSE'); add-attribute(RakuAST::ScopePhaser, RakuAST::Block, '$!let'); add-attribute(RakuAST::ScopePhaser, RakuAST::Block, '$!temp'); add-attribute(RakuAST::ScopePhaser, int, '$!next-enter-phaser-result'); add-method(RakuAST::ScopePhaser, 'add-phaser', [RakuAST::ScopePhaser, '', 0, 0, Str, '$name', 0, 0, RakuAST::StatementPrefix::Phaser, '$phaser', 0, 0, Any, '$has-exit-handler', 1, 1], anon sub add-phaser ($SELF_CONT, $name!, $phaser!, :$has-exit-handler?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $phaser := nqp::decont($phaser); $has-exit-handler := nqp::decont($has-exit-handler); #line 638 src/Raku/ast/code.rakumod my $attr := '$!' ~ $name; my $list := nqp::getattr($SELF, RakuAST::ScopePhaser, $attr); $list := nqp::bindattr($SELF, RakuAST::ScopePhaser, $attr, []) unless $list; for $list { if nqp::eqaddr($_, $phaser) { return; } } nqp::push($list, $phaser); nqp::bindattr($SELF, RakuAST::ScopePhaser, '$!has-exit-handler', (Bool.WHO)) if $has-exit-handler; }); add-method(RakuAST::ScopePhaser, 'add-enter-phaser', [RakuAST::ScopePhaser, '', 0, 0, RakuAST::StatementPrefix::Phaser, '$phaser', 0, 0], anon sub add-enter-phaser ($SELF_CONT, $phaser!) { my $SELF := nqp::decont($SELF_CONT); $phaser := nqp::decont($phaser); #line 654 src/Raku/ast/code.rakumod $SELF.add-phaser('ENTER', $phaser); my $result-name := '__enter_phaser_result_' ~ nqp::getattr_i($SELF, RakuAST::ScopePhaser, '$!next-enter-phaser-result'); nqp::bindattr_i($SELF, RakuAST::ScopePhaser, '$!next-enter-phaser-result', nqp::getattr_i($SELF, RakuAST::ScopePhaser, '$!next-enter-phaser-result') + 1); $result-name }); add-method(RakuAST::ScopePhaser, 'set-has-let', [RakuAST::ScopePhaser, '', 0, 0], anon sub set-has-let ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 661 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::ScopePhaser, '$!let', RakuAST::Block.new(:implicit-topic((Bool.WHO)))); }); add-method(RakuAST::ScopePhaser, 'set-has-temp', [RakuAST::ScopePhaser, '', 0, 0], anon sub set-has-temp ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 665 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::ScopePhaser, '$!has-exit-handler', (Bool.WHO)); nqp::bindattr($SELF, RakuAST::ScopePhaser, '$!temp', RakuAST::Block.new(:implicit-topic((Bool.WHO)))); }); add-method(RakuAST::ScopePhaser, 'set-is-loop-body', [RakuAST::ScopePhaser, '', 0, 0], anon sub set-is-loop-body ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 671 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::ScopePhaser, '$!is-loop-body', (Bool.WHO)); }); add-method(RakuAST::ScopePhaser, 'is-loop-body', [RakuAST::ScopePhaser, '', 0, 0], anon sub is-loop-body ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 675 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::ScopePhaser, '$!is-loop-body') // (Bool.WHO) }); add-method(RakuAST::ScopePhaser, 'add-list-to-code-object', [RakuAST::ScopePhaser, '', 0, 0, Str, '$attr', 0, 0, Any, '$code-object', 0, 0], anon sub add-list-to-code-object ($SELF_CONT, $attr!, $code-object!) { my $SELF := nqp::decont($SELF_CONT); $attr := nqp::decont($attr); $code-object := nqp::decont($code-object); #line 679 src/Raku/ast/code.rakumod my $list := nqp::getattr($SELF, RakuAST::ScopePhaser, $attr); if $list { my $name := nqp::substr($attr,2); # $!FOO -> FOO for $list { $code-object.add_phaser($name, $_.meta-object); } } }); add-method(RakuAST::ScopePhaser, 'add-phasers-to-code-object', [RakuAST::ScopePhaser, '', 0, 0, Any, '$code-object', 0, 0], anon sub add-phasers-to-code-object ($SELF_CONT, $code-object!) { my $SELF := nqp::decont($SELF_CONT); $code-object := nqp::decont($code-object); #line 689 src/Raku/ast/code.rakumod $SELF.add-list-to-code-object('$!ENTER', $code-object); $SELF.add-list-to-code-object('$!LEAVE', $code-object); $SELF.add-list-to-code-object( '$!KEEP', $code-object); $SELF.add-list-to-code-object( '$!UNDO', $code-object); $SELF.add-list-to-code-object('$!FIRST', $code-object); $SELF.add-list-to-code-object( '$!NEXT', $code-object); $SELF.add-list-to-code-object( '$!LAST', $code-object); $SELF.add-list-to-code-object( '$!QUIT', $code-object); $SELF.add-list-to-code-object( '$!PRE', $code-object); $SELF.add-list-to-code-object( '$!POST', $code-object); $SELF.add-list-to-code-object('$!CLOSE', $code-object); if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!let') { $code-object.add_phaser('UNDO', nqp::getattr($SELF, RakuAST::ScopePhaser, '$!let').meta-object); } if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!temp') { $code-object.add_phaser('LEAVE', nqp::getattr($SELF, RakuAST::ScopePhaser, '$!temp').meta-object); } $code-object.fatalize if $*LANG && $*LANG.pragma('fatal'); }); add-method(RakuAST::ScopePhaser, 'add-phasers-handling-code', [RakuAST::ScopePhaser, '', 0, 0, RakuAST::IMPL::Context, '$context', 0, 0, Mu, '$qast', 0, 0], anon sub add-phasers-handling-code ($SELF_CONT, $context!, $qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $qast := nqp::decont($qast); #line 712 src/Raku/ast/code.rakumod if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!has-exit-handler') { $qast.has_exit_handler(1); } if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!PRE') { my $pre-setup := QAST::Stmts.new; for nqp::getattr($SELF, RakuAST::ScopePhaser, '$!PRE') { $pre-setup.push($_.IMPL-CALLISH-QAST($context)); } $qast[0].push(QAST::Op.new( :op('p6setpre') )); $qast[0].push($pre-setup); $qast[0].push(QAST::Op.new( :op('p6clearpre') )); } if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!FIRST') { my $first-setup := QAST::Stmts.new; for nqp::getattr($SELF, RakuAST::ScopePhaser, '$!FIRST') { $first-setup.push($_.IMPL-CALLISH-QAST($context)); } $qast[0].push: $first-setup; } my $phasers := nqp::istype($SELF, RakuAST::Code) ?? nqp::getattr($SELF.meta-object, Block, '$!phasers') !! NQPMu; if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!ENTER') || nqp::ishash($phasers) && nqp::existskey($phasers, 'ENTER') { my $enter-setup := QAST::Stmts.new; my %seen; if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!ENTER') { for nqp::getattr($SELF, RakuAST::ScopePhaser, '$!ENTER') { my $result-name := $_.IMPL-RESULT-NAME; $enter-setup.push( QAST::Op.new( :op, QAST::Var.new( :name($result-name), :scope, :decl ), $_.IMPL-CALLISH-QAST($context) ) ); %seen{nqp::objectid($_.meta-object)} := 1; } } my $enter-phasers := nqp::atkey($phasers, 'ENTER'); if nqp::isconcrete($enter-phasers) { for $enter-phasers { unless %seen{nqp::objectid($_)} { $context.ensure-sc($_); $enter-setup.push(QAST::Op.new(:op, QAST::WVal.new(:value($_)))); } } } $qast[0].push($enter-setup); } if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!let') { $SELF.IMPL-ADD-PHASER-QAST($context, nqp::getattr($SELF, RakuAST::ScopePhaser, '$!let'), '!LET-RESTORE', $qast); } if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!temp') { $SELF.IMPL-ADD-PHASER-QAST($context, nqp::getattr($SELF, RakuAST::ScopePhaser, '$!temp'), '!TEMP-RESTORE', $qast); } if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!LAST') || nqp::getattr($SELF, RakuAST::ScopePhaser, '$!NEXT') || nqp::getattr($SELF, RakuAST::ScopePhaser, '$!QUIT') || nqp::getattr($SELF, RakuAST::ScopePhaser, '$!CLOSE') { $qast[0].push( QAST::Op.new( :op('callmethod'), :name('!capture_phasers'), QAST::Op.new( :op('getcodeobj'), QAST::Op.new(:op('curcode')) ) ) ); } if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!LEAVE') || nqp::getattr($SELF, RakuAST::ScopePhaser, '$!KEEP') || nqp::getattr($SELF, RakuAST::ScopePhaser, '$!UNDO') || nqp::getattr($SELF, RakuAST::ScopePhaser, '$!POST') { $qast.annotate('WANTMEPLEASE',1); } }); add-method(RakuAST::ScopePhaser, 'IMPL-STUB-PHASERS', [RakuAST::ScopePhaser, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::Context, '$context', 0, 0], anon sub IMPL-STUB-PHASERS ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 792 src/Raku/ast/code.rakumod if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!let') { nqp::getattr($SELF, RakuAST::ScopePhaser, '$!let').IMPL-CHECK($resolver, $context, (Bool.WHO)); nqp::getattr($SELF, RakuAST::ScopePhaser, '$!let').IMPL-STUB-CODE($resolver, $context); } if nqp::getattr($SELF, RakuAST::ScopePhaser, '$!temp') { nqp::getattr($SELF, RakuAST::ScopePhaser, '$!temp').IMPL-CHECK($resolver, $context, (Bool.WHO)); nqp::getattr($SELF, RakuAST::ScopePhaser, '$!temp').IMPL-STUB-CODE($resolver, $context); } }); add-method(RakuAST::ScopePhaser, 'IMPL-ADD-PHASER-QAST', [RakuAST::ScopePhaser, '', 0, 0, RakuAST::IMPL::Context, '$context', 0, 0, RakuAST::Block, '$phaser', 0, 0, Str, '$value_stash', 0, 0, QAST::Block, '$block', 0, 0], anon sub IMPL-ADD-PHASER-QAST ($SELF_CONT, $context!, $phaser!, $value_stash!, $block!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $phaser := nqp::decont($phaser); $value_stash := nqp::decont($value_stash); $block := nqp::decont($block); #line 808 src/Raku/ast/code.rakumod $block[0].push(QAST::Op.new( :op('bind'), QAST::Var.new( :name($value_stash), :scope('lexical'), :decl('var') ), QAST::Op.new( :op('create'), QAST::WVal.new( :value(IterationBuffer))))); $block.symbol($value_stash, :scope('lexical')); my $phaser-block := $phaser.IMPL-QAST-BLOCK($context, :blocktype('declaration_static')); $phaser-block.push(QAST::Op.new( :op('while'), QAST::Op.new( :op('elems'), QAST::Var.new( :name($value_stash), :scope('lexical') )), QAST::Op.new( :op('if'), QAST::Op.new( :op('iscont'), QAST::Op.new( :op('atpos'), QAST::Var.new( :name($value_stash), :scope('lexical') ), QAST::IVal.new( :value(0) ))), QAST::Op.new( # p6store is for Scalar :op('p6store'), QAST::Op.new( :op('shift'), QAST::Var.new( :name($value_stash), :scope('lexical') )), QAST::Op.new( :op('shift'), QAST::Var.new( :name($value_stash), :scope('lexical') ))), QAST::Op.new( # Otherwise we restore by means of the container itself :op('callmethod'), :name('TEMP-LET-RESTORE'), QAST::Op.new( :op('shift'), QAST::Var.new( :name($value_stash), :scope('lexical') )), QAST::Op.new( :op('shift'), QAST::Var.new( :name($value_stash), :scope('lexical') )))))); # Add as phaser. $block[0].push($phaser-block); }); add-method(RakuAST::ScopePhaser, 'clear-phaser-attachments', [RakuAST::ScopePhaser, '', 0, 0], anon sub clear-phaser-attachments ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 853 src/Raku/ast/code.rakumod my @attrs := ['$!LEAVE', '$!FIRST', '$!NEXT', '$!LAST']; for @attrs { my $attr := nqp::getattr($SELF, RakuAST::ScopePhaser, $_); nqp::setelems($attr, 0) if $attr; } }); add-method(RakuAST::ScopePhaser, 'has-phaser', [RakuAST::ScopePhaser, '', 0, 0, str, '$phaser-name', 0, 0], anon sub has-phaser ($SELF_CONT, $phaser-name!) { my $SELF := nqp::decont($SELF_CONT); $phaser-name := nqp::decont($phaser-name); #line 861 src/Raku/ast/code.rakumod # TOOD: Also check '$!phasers' hash on the meta-object nqp::elems(nqp::getattr($SELF, RakuAST::ScopePhaser, '$!' ~ $phaser-name) // []) > 0 }); compose(RakuAST::ScopePhaser); parent(RakuAST::Block, RakuAST::LexicalScope); parent(RakuAST::Block, RakuAST::Term); parent(RakuAST::Block, RakuAST::Code); parent(RakuAST::Block, RakuAST::Meta); parent(RakuAST::Block, RakuAST::BlockStatementSensitive); parent(RakuAST::Block, RakuAST::SinkPropagator); parent(RakuAST::Block, RakuAST::Blorst); parent(RakuAST::Block, RakuAST::ImplicitDeclarations); parent(RakuAST::Block, RakuAST::ImplicitLookups); parent(RakuAST::Block, RakuAST::AttachTarget); parent(RakuAST::Block, RakuAST::PlaceholderParameterOwner); parent(RakuAST::Block, RakuAST::BeginTime); parent(RakuAST::Block, RakuAST::ScopePhaser); parent(RakuAST::Block, RakuAST::Doc::DeclaratorTarget); add-attribute(RakuAST::Block, RakuAST::Blockoid, '$!body'); add-attribute(RakuAST::Block, int, '$!implicit-topic-mode'); add-attribute(RakuAST::Block, int, '$!fresh-match'); add-attribute(RakuAST::Block, int, '$!fresh-exception'); add-method(RakuAST::Block, 'new', [RakuAST::Block, '', 0, 0, RakuAST::Blockoid, '$body', 1, 1, Bool, '$implicit-topic', 1, 1, Bool, '$required-topic', 1, 1, Bool, '$exception', 1, 1, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$body?, :$implicit-topic?, :$required-topic?, :$exception?, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $body := nqp::decont($body); $implicit-topic := nqp::decont($implicit-topic); $required-topic := nqp::decont($required-topic); $exception := nqp::decont($exception); $WHY := nqp::decont($WHY); #line 905 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Block, '$!body', $body // RakuAST::Blockoid.new); $obj.set-implicit-topic($implicit-topic // 1, :required($required-topic), :$exception); $obj.set-WHY($WHY); $obj }); add-method(RakuAST::Block, 'replace-body', [RakuAST::Block, '', 0, 0, RakuAST::Blockoid, '$new-body', 0, 0], anon sub replace-body ($SELF_CONT, $new-body!) { my $SELF := nqp::decont($SELF_CONT); $new-body := nqp::decont($new-body); #line 913 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Block, '$!body', $new-body); Nil }); add-method(RakuAST::Block, 'set-implicit-topic', [RakuAST::Block, '', 0, 0, Bool, '$implicit', 0, 0, Bool, '$required', 1, 1, Bool, '$exception', 1, 1, Bool, '$local', 1, 1], anon sub set-implicit-topic ($SELF_CONT, $implicit!, :$required?, :$exception?, :$local?) { my $SELF := nqp::decont($SELF_CONT); $implicit := nqp::decont($implicit); $required := nqp::decont($required); $exception := nqp::decont($exception); $local := nqp::decont($local); #line 918 src/Raku/ast/code.rakumod nqp::bindattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode', $implicit ?? ($exception ?? 3 !! $required ?? 2 !! 1) !! $local ?? -1 !! 0); Nil }); add-method(RakuAST::Block, 'implicit-topic', [RakuAST::Block, '', 0, 0], anon sub implicit-topic ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 927 src/Raku/ast/code.rakumod nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') == 1 ?? Bool !! nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') > 1 }); add-method(RakuAST::Block, 'required-topic', [RakuAST::Block, '', 0, 0], anon sub required-topic ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 928 src/Raku/ast/code.rakumod nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') > 1 || Bool }); add-method(RakuAST::Block, 'exception', [RakuAST::Block, '', 0, 0], anon sub exception ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 929 src/Raku/ast/code.rakumod nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') > 2 || Bool }); add-method(RakuAST::Block, 'set-fresh-variables', [RakuAST::Block, '', 0, 0, Bool, '$match', 1, 1, Bool, '$exception', 1, 1], anon sub set-fresh-variables ($SELF_CONT, :$match?, :$exception?) { my $SELF := nqp::decont($SELF_CONT); $match := nqp::decont($match); $exception := nqp::decont($exception); #line 931 src/Raku/ast/code.rakumod nqp::bindattr_i($SELF, RakuAST::Block, '$!fresh-match', $match ?? 1 !! 0); nqp::bindattr_i($SELF, RakuAST::Block, '$!fresh-exception', $exception ?? 1 !! 0); }); add-method(RakuAST::Block, 'attach-target-names', [RakuAST::Block, '', 0, 0], anon sub attach-target-names ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 936 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST(['block']) }); add-method(RakuAST::Block, 'clear-attachments', [RakuAST::Block, '', 0, 0], anon sub clear-attachments ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 940 src/Raku/ast/code.rakumod $SELF.clear-handler-attachments(); $SELF.clear-placeholder-attachments(); $SELF.clear-phaser-attachments(); Nil }); add-method(RakuAST::Block, 'propagate-sink', [RakuAST::Block, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 947 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::Block, '$!body').apply-sink($is-sunk); }); add-method(RakuAST::Block, 'PRODUCE-IMPLICIT-DECLARATIONS', [RakuAST::Block, '', 0, 0], anon sub PRODUCE-IMPLICIT-DECLARATIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 951 src/Raku/ast/code.rakumod my @implicit; unless $SELF.IMPL-HAS-PARAMETER('$_') { if nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') == 1 { @implicit[0] := RakuAST::VarDeclaration::Implicit::BlockTopic.new: parameter => $SELF.signature ?? (Bool.WHO) !! (Bool.WHO); } elsif nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') == -1 { @implicit[0] := RakuAST::VarDeclaration::Implicit::BlockTopic.new: parameter => (Bool.WHO); } elsif nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') == 2 { @implicit[0] := RakuAST::VarDeclaration::Implicit::BlockTopic.new: :required, parameter => $SELF.signature ?? (Bool.WHO) !! (Bool.WHO); } elsif nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') == 3 { @implicit[0] := RakuAST::VarDeclaration::Implicit::BlockTopic.new(:required, :exception); } } if nqp::getattr_i($SELF, RakuAST::Block, '$!fresh-match') { nqp::push(@implicit, RakuAST::VarDeclaration::Implicit::Special.new(:name('$/'))); } if nqp::getattr_i($SELF, RakuAST::Block, '$!fresh-exception') { nqp::push(@implicit, RakuAST::VarDeclaration::Implicit::Special.new(:name('$!'))); } $SELF.IMPL-WRAP-LIST(@implicit) }); add-method(RakuAST::Block, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Block, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 981 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Code')) ]) }); add-method(RakuAST::Block, 'is-begin-performed-before-children', [RakuAST::Block, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 987 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::Block, 'PERFORM-BEGIN', [RakuAST::Block, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 989 src/Raku/ast/code.rakumod # Make sure that our placeholder signature has resolutions performed, # and that we don't produce a topic parameter. my $placeholder-signature := $SELF.placeholder-signature; if $placeholder-signature { $placeholder-signature.IMPL-CHECK($resolver, $context, (Bool.WHO)); if nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') > 0 { my $topic := $SELF.IMPL-UNWRAP-LIST($SELF.get-implicit-declarations)[0]; $topic.set-parameter((Bool.WHO)); } } $SELF.IMPL-STUB-PHASERS($resolver, $context); $SELF.IMPL-STUB-CODE($resolver, $context); Nil }); add-method(RakuAST::Block, 'PRODUCE-META-OBJECT', [RakuAST::Block, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1008 src/Raku/ast/code.rakumod $SELF.IMPL-PRODUCE-META-OBJECT }); add-method(RakuAST::Block, 'IMPL-PRODUCE-META-OBJECT', [RakuAST::Block, '', 0, 0], anon sub IMPL-PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1012 src/Raku/ast/code.rakumod # Create block object and install signature. If it doesn't have one, then # we can create it based upon the implicit topic it may or may not have. my $block := nqp::create(Block); my $signature := $SELF.signature || $SELF.placeholder-signature; if $signature { nqp::bindattr($block, Code, '$!signature', $signature.meta-object); nqp::bindattr($signature.meta-object, Signature, '$!code', $block); } elsif nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') > 0 { my constant REQUIRED-TOPIC-SIG := -> { my $param := nqp::create(Parameter); nqp::bindattr_s($param, Parameter, '$!variable_name', '$_'); my $sig := nqp::create(Signature); nqp::bindattr($sig, Signature, '@!params', [$param]); nqp::bindattr_i($sig, Signature, '$!arity', 1); nqp::bindattr($sig, Signature, '$!count', nqp::box_i(1, Int)); $sig }(); my constant OPTIONAL-TOPIC-SIG := -> { my $param := nqp::create(Parameter); nqp::bindattr_s($param, Parameter, '$!variable_name', '$_'); nqp::bindattr_i($param, Parameter, '$!flags', 2048 + 16384); # Optional + default from outer my $sig := nqp::create(Signature); nqp::bindattr($sig, Signature, '@!params', [$param]); nqp::bindattr_i($sig, Signature, '$!arity', 0); nqp::bindattr($sig, Signature, '$!count', nqp::box_i(1, Int)); $sig }(); nqp::bindattr($block, Code, '$!signature', nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') == 1 ?? OPTIONAL-TOPIC-SIG !! REQUIRED-TOPIC-SIG); } $SELF.add-phasers-to-code-object($block); $block }); add-method(RakuAST::Block, 'IMPL-QAST-FORM-BLOCK', [RakuAST::Block, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-QAST-FORM-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 1050 src/Raku/ast/code.rakumod $SELF.IMPL-QAST-FORM-BLOCK-FOR-BODY($context, :$blocktype, :$expression, $SELF.IMPL-APPEND-SIGNATURE-RETURN($context, nqp::getattr($SELF, RakuAST::Block, '$!body').IMPL-TO-QAST($context))); }); add-method(RakuAST::Block, 'IMPL-QAST-FORM-BLOCK-FOR-BODY', [RakuAST::Block, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$body-qast', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-QAST-FORM-BLOCK-FOR-BODY ($SELF_CONT, $context!, $body-qast!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $body-qast := nqp::decont($body-qast); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 1056 src/Raku/ast/code.rakumod # Form block with declarations. my $block := QAST::Block.new( :$blocktype, $SELF.IMPL-QAST-DECLS($context) ); # Compile body and, if needed, a signature, and set up arity and any # exception rethrow logic. my $signature := $SELF.signature || $SELF.placeholder-signature; if $signature { $block.push($signature.IMPL-QAST-BINDINGS($context, :needs-full-binder($SELF.custom-args))); $block.custom_args(1) if $SELF.custom-args; $block.arity($signature.arity); $block.annotate('count', $signature.count); } elsif nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') == 1 { $block.arity(0); $block.annotate('count', 1); } elsif nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') >= 2 { $block.arity(1); $block.annotate('count', 1); } my $is-handler := nqp::getattr_i($SELF, RakuAST::Block, '$!implicit-topic-mode') == 3 ?? (Bool.WHO) !! (Bool.WHO); $block.push($SELF.IMPL-WRAP-SCOPE-HANDLER-QAST($context, $body-qast, :$is-handler)); $SELF.add-phasers-handling-code($context, $block); $block }); add-method(RakuAST::Block, 'IMPL-QAST-DECL-CODE', [RakuAST::Block, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL-CODE ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1089 src/Raku/ast/code.rakumod # Form the block itself and link it with the meta-object. $SELF.IMPL-QAST-BLOCK($context, :blocktype('declaration_static')); }); add-method(RakuAST::Block, 'IMPL-EXPR-QAST', [RakuAST::Block, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '$immediate', 1, 1], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!, :$immediate?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $immediate := nqp::decont($immediate); #line 1094 src/Raku/ast/code.rakumod if $immediate { # For now, assume we never need a code object for such a block. The # closure clone is done for us by the QAST compiler. my $block := $SELF.IMPL-QAST-FORM-BLOCK($context, :blocktype); $SELF.IMPL-LINK-META-OBJECT($context, $block); $block } else { # Not immediate, so already produced as a declaration above; just # closure clone it. Only invoke if it's a bare block. # Ensure the block is linked when our outer block gets cloned before # our IMPL-QAST-DECL-CODE is called. $SELF.IMPL-QAST-BLOCK($context, :blocktype('declaration_static')); my $ast := $SELF.IMPL-CLOSURE-QAST($context); $SELF.bare-block ?? QAST::Op.new( :op('call'), $ast ) !! $ast } }); add-method(RakuAST::Block, 'bare-block', [RakuAST::Block, '', 0, 0], anon sub bare-block ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1115 src/Raku/ast/code.rakumod $SELF.is-block-statement }); add-method(RakuAST::Block, 'block-or-hash', [RakuAST::Block, '', 0, 0, int, '$object-hash', 1, 1], anon sub block-or-hash ($SELF_CONT, :$object-hash?) { my $SELF := nqp::decont($SELF_CONT); $object-hash := nqp::decont($object-hash); #line 1128 src/Raku/ast/code.rakumod my @statements := $SELF.body.statement-list.code-statements; my int $num-statements := nqp::elems(@statements); # Empty block is always an empty hash composer if $num-statements == 0 { return RakuAST::Circumfix::HashComposer.new(:$object-hash) } # Multiple statements is always a block elsif $num-statements > 1 { return $SELF } # Not a statement always means block my $statement := @statements[0]; unless nqp::istype($statement, RakuAST::Statement::Expression) { return $SELF; } # If it's a comma list, then obtain the first element. Otherwise, # we have the thing to test already. my $expression := $statement.expression; my int $is-comma := nqp::istype($expression, RakuAST::ApplyListInfix) && nqp::istype($expression.infix, RakuAST::Infix) && $expression.infix.operator eq ','; my $test := $is-comma ?? $SELF.IMPL-UNWRAP-LIST($expression.operands)[0] !! $expression; # A fatarrow is ok if nqp::istype($test,RakuAST::FatArrow) { } # A colonpair is ok elsif nqp::istype($test,RakuAST::ColonPair) { } # A hash sigil'd variable is ok elsif nqp::istype($test,RakuAST::Var) && $test.sigil eq '%' { } # Some kind of infix may be ok elsif nqp::istype($test,RakuAST::ApplyInfix) { # Get the proper infix to check my $infix := $test.infix; if nqp::istype($infix,RakuAST::Infix) { } elsif nqp::istype($infix,RakuAST::MetaInfix::Reverse) { $infix := $infix.infix; } # It's a block as no valid infix found else { return $SELF } # It's a block if not a fat arrow return $SELF unless $infix.operator eq '=>'; } # It's a block as nothing recognizable else { return $SELF; } # Looks like a hash, but check for declarations or $_ usage. my int $seen-decl-or-topic; $expression.visit: -> $node { # Don't walk into other scopes if nqp::istype($node, RakuAST::LexicalScope) { 0 } # If it's a declaration, it blocks; walk no futher elsif nqp::istype($node, RakuAST::Declaration) { $seen-decl-or-topic := 1; 0 } # If it's a usage of the topic, it also blocks; walk no further elsif nqp::istype($node, RakuAST::Var::Lexical) && $node.name eq '$_' || nqp::istype($node, RakuAST::Term::TopicCall) { $seen-decl-or-topic := 1; 0 } # Otherwise, keep looking else { 1 } } $seen-decl-or-topic ?? $SELF !! RakuAST::Circumfix::HashComposer.new($expression, :$object-hash) }); add-method(RakuAST::Block, 'visit-children', [RakuAST::Block, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1220 src/Raku/ast/code.rakumod $visitor(nqp::getattr($SELF, RakuAST::Block, '$!body')); $visitor($SELF.WHY) if $SELF.WHY; }); add-method(RakuAST::Block, 'IMPL-CAN-INTERPRET', [RakuAST::Block, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1225 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::Block, 'IMPL-INTERPRET', [RakuAST::Block, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 1229 src/Raku/ast/code.rakumod $SELF.meta-object }); add-method(RakuAST::Block, 'as-block', [RakuAST::Block, '', 0, 0], anon sub as-block ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1233 src/Raku/ast/code.rakumod $SELF }); #line 884 src/Raku/ast/code.rakumod add-method(RakuAST::Block, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Block, '$!body') }); compose(RakuAST::Block); parent(RakuAST::PointyBlock, RakuAST::Block); parent(RakuAST::PointyBlock, RakuAST::ImplicitLookups); parent(RakuAST::PointyBlock, RakuAST::Doc::DeclaratorTarget); add-attribute(RakuAST::PointyBlock, RakuAST::Signature, '$!signature'); add-method(RakuAST::PointyBlock, 'new', [RakuAST::PointyBlock, '', 0, 0, RakuAST::Signature, '$signature', 1, 1, RakuAST::Blockoid, '$body', 1, 1, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$signature?, :$body?, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $signature := nqp::decont($signature); $body := nqp::decont($body); $WHY := nqp::decont($WHY); #line 1249 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::PointyBlock, '$!signature', $signature // RakuAST::Signature.new); nqp::bindattr($obj, RakuAST::Block, '$!body', $body // RakuAST::Blockoid.new); $obj.set-WHY($WHY); $obj }); add-method(RakuAST::PointyBlock, 'replace-signature', [RakuAST::PointyBlock, '', 0, 0, RakuAST::Signature, '$new-signature', 0, 0], anon sub replace-signature ($SELF_CONT, $new-signature!) { my $SELF := nqp::decont($SELF_CONT); $new-signature := nqp::decont($new-signature); #line 1259 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::PointyBlock, '$!signature', $new-signature); Nil }); add-method(RakuAST::PointyBlock, 'bare-block', [RakuAST::PointyBlock, '', 0, 0], anon sub bare-block ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1264 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::PointyBlock, 'propagate-sink', [RakuAST::PointyBlock, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 1266 src/Raku/ast/code.rakumod $SELF.body.apply-sink($is-sunk); nqp::getattr($SELF, RakuAST::PointyBlock, '$!signature').apply-sink((Bool.WHO)); }); add-method(RakuAST::PointyBlock, 'visit-children', [RakuAST::PointyBlock, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1271 src/Raku/ast/code.rakumod $visitor(nqp::getattr($SELF, RakuAST::PointyBlock, '$!signature')); $visitor($SELF.body); $visitor($SELF.WHY) if $SELF.WHY; }); add-method(RakuAST::PointyBlock, 'IMPL-HAS-PARAMETER', [RakuAST::PointyBlock, '', 0, 0, Str, '$name', 0, 0], anon sub IMPL-HAS-PARAMETER ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 1277 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::PointyBlock, '$!signature').IMPL-HAS-PARAMETER($name) }); add-method(RakuAST::PointyBlock, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::PointyBlock, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1281 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Callable')) ]) }); add-method(RakuAST::PointyBlock, 'PRODUCE-META-OBJECT', [RakuAST::PointyBlock, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1287 src/Raku/ast/code.rakumod my $block := $SELF.IMPL-PRODUCE-META-OBJECT(); my $signature := $SELF.signature || $SELF.placeholder-signature; if $signature.meta-object.has_returns { my $Callable := $SELF.get-implicit-lookups.AT-POS(0).compile-time-value; $block.HOW.mixin( $block, $Callable.HOW.parameterize( $Callable, $signature.meta-object.returns ) ); } $block }); add-method(RakuAST::PointyBlock, 'PERFORM-BEGIN', [RakuAST::PointyBlock, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1305 src/Raku/ast/code.rakumod # Cannot rely on IMPL-CHECK getting run before this, as that would # also run our children's BEGIN handlers which would screw up our # block-or-hash detection $SELF.resolve-implicit-lookups-with($resolver); # Make sure that our placeholder signature has resolutions performed, # and that we don't produce a topic parameter. if nqp::getattr($SELF, RakuAST::PointyBlock, '$!signature') { nqp::getattr($SELF, RakuAST::PointyBlock, '$!signature').IMPL-ENSURE-IMPLICITS; nqp::getattr($SELF, RakuAST::PointyBlock, '$!signature').IMPL-CHECK($resolver, $context, (Bool.WHO)); } my $placeholder-signature := $SELF.placeholder-signature; if $placeholder-signature { $placeholder-signature.IMPL-CHECK($resolver, $context, (Bool.WHO)); if nqp::getattr($SELF, RakuAST::Block, '$!implicit-topic-mode') { my $topic := $SELF.IMPL-UNWRAP-LIST($SELF.get-implicit-declarations)[0]; $topic.set-parameter((Bool.WHO)); } } $SELF.IMPL-STUB-PHASERS($resolver, $context); $SELF.IMPL-STUB-CODE($resolver, $context); Nil }); add-method(RakuAST::PointyBlock, 'IMPL-WRAP-RETURN-HANDLER', [RakuAST::PointyBlock, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Node, '$body', 0, 0], anon sub IMPL-WRAP-RETURN-HANDLER ($SELF_CONT, $context!, $body!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $body := nqp::decont($body); #line 1333 src/Raku/ast/code.rakumod my $result := $body; my $block := $SELF.compile-time-value; my $signature := nqp::getattr($block, Code, '$!signature'); $context.ensure-sc($block); # Add return type check if needed. # TODO also infer body type my $returns := nqp::ifnull($signature.returns, Mu); unless $returns =:= Mu || $returns =:= Nil || nqp::isconcrete($returns) { $context.ensure-sc($returns); $result := QAST::Op.new( :op('p6typecheckrv'), $result, QAST::WVal.new( :value($block) ), QAST::WVal.new( :value(Nil) ) ); } $result }); add-method(RakuAST::PointyBlock, 'IMPL-QAST-FORM-BLOCK', [RakuAST::PointyBlock, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-QAST-FORM-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 1356 src/Raku/ast/code.rakumod $SELF.IMPL-QAST-FORM-BLOCK-FOR-BODY($context, :$blocktype, :$expression, $SELF.IMPL-WRAP-RETURN-HANDLER($context, $SELF.IMPL-APPEND-SIGNATURE-RETURN($context, $SELF.body.IMPL-TO-QAST($context)))) }); #line 1244 src/Raku/ast/code.rakumod add-method(RakuAST::PointyBlock, 'signature', [], anon sub signature ($self) { nqp::getattr(nqp::decont($self), RakuAST::PointyBlock, '$!signature') }); compose(RakuAST::PointyBlock); parent(RakuAST::Routine, RakuAST::LexicalScope); parent(RakuAST::Routine, RakuAST::Term); parent(RakuAST::Routine, RakuAST::Code); parent(RakuAST::Routine, RakuAST::StubbyMeta); parent(RakuAST::Routine, RakuAST::Declaration); parent(RakuAST::Routine, RakuAST::Attaching); parent(RakuAST::Routine, RakuAST::ImplicitDeclarations); parent(RakuAST::Routine, RakuAST::AttachTarget); parent(RakuAST::Routine, RakuAST::PlaceholderParameterOwner); parent(RakuAST::Routine, RakuAST::ImplicitLookups); parent(RakuAST::Routine, RakuAST::BeginTime); parent(RakuAST::Routine, RakuAST::TraitTarget); parent(RakuAST::Routine, RakuAST::ScopePhaser); parent(RakuAST::Routine, RakuAST::Doc::DeclaratorTarget); add-attribute(RakuAST::Routine, RakuAST::Name, '$!name'); add-attribute(RakuAST::Routine, RakuAST::Signature, '$!signature'); add-attribute(RakuAST::Routine, str, '$!multiness'); add-attribute(RakuAST::Routine, RakuAST::Package, '$!package'); add-attribute(RakuAST::Routine, Bool, '$!need-routine-variable'); add-method(RakuAST::Routine, 'multiness', [RakuAST::Routine, '', 0, 0], anon sub multiness ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1386 src/Raku/ast/code.rakumod my $multiness := nqp::getattr_s($SELF, RakuAST::Routine, '$!multiness'); nqp::isnull_s($multiness) ?? '' !! $multiness }); add-method(RakuAST::Routine, 'replace-name', [RakuAST::Routine, '', 0, 0, RakuAST::Name, '$new-name', 0, 0], anon sub replace-name ($SELF_CONT, $new-name!) { my $SELF := nqp::decont($SELF_CONT); $new-name := nqp::decont($new-name); #line 1391 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Routine, '$!name', $new-name); Nil }); add-method(RakuAST::Routine, 'replace-signature', [RakuAST::Routine, '', 0, 0, RakuAST::Signature, '$new-signature', 0, 0], anon sub replace-signature ($SELF_CONT, $new-signature!) { my $SELF := nqp::decont($SELF_CONT); $new-signature := nqp::decont($new-signature); #line 1396 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Routine, '$!signature', $new-signature); Nil }); add-method(RakuAST::Routine, 'attach-target-names', [RakuAST::Routine, '', 0, 0], anon sub attach-target-names ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1401 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST(['routine', 'block']) }); add-method(RakuAST::Routine, 'attach', [RakuAST::Routine, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1405 src/Raku/ast/code.rakumod my $package := $resolver.find-attach-target('package'); nqp::bindattr($SELF, RakuAST::Routine, '$!package', $package // $resolver.global-package); nqp::bindattr($SELF, RakuAST::Code, '$!resolver', $resolver.clone); }); add-method(RakuAST::Routine, 'set-need-routine-variable', [RakuAST::Routine, '', 0, 0], anon sub set-need-routine-variable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1411 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Routine, '$!need-routine-variable', (Bool.WHO)); }); add-method(RakuAST::Routine, 'clear-attachments', [RakuAST::Routine, '', 0, 0], anon sub clear-attachments ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1415 src/Raku/ast/code.rakumod $SELF.clear-handler-attachments(); $SELF.clear-placeholder-attachments(); $SELF.clear-phaser-attachments(); Nil }); add-method(RakuAST::Routine, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Routine, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1422 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Callable')) ]) }); add-method(RakuAST::Routine, 'PRODUCE-STUBBED-META-OBJECT', [RakuAST::Routine, '', 0, 0], anon sub PRODUCE-STUBBED-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1428 src/Raku/ast/code.rakumod nqp::create($SELF.IMPL-META-OBJECT-TYPE) }); add-method(RakuAST::Routine, 'PRODUCE-META-OBJECT', [RakuAST::Routine, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1432 src/Raku/ast/code.rakumod my $routine := $SELF.stubbed-meta-object; my $signature := $SELF.placeholder-signature || $SELF.signature; nqp::bindattr($routine, Code, '$!signature', $signature.meta-object); nqp::bindattr($signature.meta-object, Signature, '$!code', $routine); if $signature.meta-object.has_returns { my $Callable := $SELF.get-implicit-lookups.AT-POS(0).compile-time-value; $routine.HOW.mixin( $routine, $Callable.HOW.parameterize( $Callable, $signature.meta-object.returns ) ); } if nqp::istype($SELF.body, RakuAST::OnlyStar) { $routine.set_onlystar; } nqp::bindattr($routine,Routine,'$!package',nqp::getattr($SELF, RakuAST::Routine, '$!package').compile-time-value) if nqp::getattr($SELF, RakuAST::Routine, '$!package'); # Make sure that any OperatorProperties are set on the meta-object # if it is some kind of operator. This feels pretty hackish way # to do this, perhaps better done with dedicated subclasses of # RakuAST::Sub. But it will do for now. if nqp::getattr($SELF, RakuAST::Routine, '$!name') { my @parts; for nqp::getattr($SELF, RakuAST::Routine, '$!name').colonpairs { @parts.push($_.canonicalize); } my str $op := nqp::join(' ',@parts); if $op { $op := nqp::substr($op,1,nqp::chars($op) - 2); my str $name := nqp::getattr($SELF, RakuAST::Routine, '$!name').canonicalize; my $op_props := nqp::eqat($name,'infix:',0) ?? OperatorProperties.infix($op) !! nqp::eqat($name,'prefix:',0) ?? OperatorProperties.prefix($op) !! nqp::eqat($name,'postfix:',0) ?? OperatorProperties.postfix($op) !! nqp::eqat($name,'postcircumfix:',0) ?? OperatorProperties.postcircumfix($op) !! nqp::eqat($name,'circumfix:',0) ?? OperatorProperties.circumfix($op) !! Mu; nqp::bindattr($routine,Routine,'$!op_props',$op_props) if $op_props; } } $SELF.add-phasers-to-code-object($routine); $routine }); add-method(RakuAST::Routine, 'is-begin-performed-before-children', [RakuAST::Routine, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1491 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::Routine, 'is-begin-performed-after-children', [RakuAST::Routine, '', 0, 0], anon sub is-begin-performed-after-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1492 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::Routine, 'PERFORM-BEGIN-BEFORE-CHILDREN', [RakuAST::Routine, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-BEFORE-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1494 src/Raku/ast/code.rakumod my $placeholder-signature := $SELF.placeholder-signature; if $placeholder-signature { $placeholder-signature.IMPL-ENSURE-IMPLICITS; } if nqp::getattr($SELF, RakuAST::Routine, '$!signature') { nqp::getattr($SELF, RakuAST::Routine, '$!signature').IMPL-ENSURE-IMPLICITS; } }); add-method(RakuAST::Routine, 'PERFORM-BEGIN-AFTER-CHILDREN', [RakuAST::Routine, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-AFTER-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1504 src/Raku/ast/code.rakumod # Make sure that our placeholder signature has resolutions performed. my $placeholder-signature := $SELF.placeholder-signature; if $placeholder-signature { $placeholder-signature.IMPL-CHECK($resolver, $context, (Bool.WHO)); } # Make sure that our signature has resolutions performed. if nqp::getattr($SELF, RakuAST::Routine, '$!signature') { nqp::getattr($SELF, RakuAST::Routine, '$!signature').set-default-type( RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('Any'), ), ); nqp::getattr($SELF, RakuAST::Routine, '$!signature').IMPL-ENSURE-IMPLICITS; nqp::getattr($SELF, RakuAST::Routine, '$!signature').IMPL-CHECK($resolver, $context, (Bool.WHO)); } if $SELF.multiness eq 'multi' { my $name := '&' ~ $SELF.name.canonicalize; my $proto := $resolver.resolve-lexical($name, :current-scope-only); if $proto { $proto := $proto.compile-time-value; } else { my $scope := $resolver.current-scope; if $proto := $resolver.resolve-lexical-constant($name) { $proto := $proto.compile-time-value.derive_dispatcher; } elsif $proto := $resolver.resolve-lexical-constant-in-outer($name) { $proto := $proto.compile-time-value.derive_dispatcher; } else { my $proto-ast := RakuAST::Sub.new( :scope, :name($SELF.name), :signature(RakuAST::Signature.new( :parameters($SELF.IMPL-WRAP-LIST([ RakuAST::Parameter.new( :slurpy(RakuAST::Parameter::Slurpy::Capture), ) ])), )), :body(RakuAST::OnlyStar.new), :multiness, ); $proto-ast.ensure-begin-performed($resolver, $context); $proto := $proto-ast.meta-object; $scope.add-generated-lexical-declaration( RakuAST::VarDeclaration::Implicit::Block.new(:block($proto-ast)) ); } $scope.add-generated-lexical-declaration( RakuAST::VarDeclaration::Implicit::Constant.new(:$name, :value($proto)) ); } $proto.add_dispatchee($SELF.meta-object); } elsif $SELF.multiness eq 'proto' { nqp::bindattr($SELF.meta-object, Routine, '@!dispatchees', []); } $SELF.IMPL-STUB-PHASERS($resolver, $context); my $stub := $SELF.IMPL-STUB-CODE($resolver, $context); nqp::setcodename($stub, nqp::getattr($SELF, RakuAST::Routine, '$!name').canonicalize) if nqp::getattr($SELF, RakuAST::Routine, '$!name'); # Apply any traits. $SELF.apply-traits($resolver, $context, $SELF) }); add-method(RakuAST::Routine, 'PRODUCE-IMPLICIT-DECLARATIONS', [RakuAST::Routine, '', 0, 0], anon sub PRODUCE-IMPLICIT-DECLARATIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1577 src/Raku/ast/code.rakumod my $slash := 1; my $exclamation-mark := 1; my $underscore := 1; my @declarations; if nqp::getattr($SELF, RakuAST::Routine, '$!signature') { nqp::getattr($SELF, RakuAST::Routine, '$!signature').IMPL-ENSURE-IMPLICITS; my $implicit-invocant := nqp::getattr($SELF, RakuAST::Routine, '$!signature').implicit-invocant; if $implicit-invocant { my $type-captures := $SELF.IMPL-UNWRAP-LIST($implicit-invocant.type-captures); for $type-captures { nqp::push(@declarations, $_); } } for $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Routine, '$!signature').parameters) { if ($_.target) { my $name := $_.target.name; $slash := 0 if $name eq '$/'; $exclamation-mark := 0 if $name eq '$!'; $underscore := 0 if $name eq '$_'; } my $type-captures := $SELF.IMPL-UNWRAP-LIST($_.type-captures); for $type-captures { nqp::push(@declarations, $_); } } } nqp::push(@declarations, RakuAST::VarDeclaration::Implicit::Special.new(:name('$/'))) if $slash; nqp::push(@declarations, RakuAST::VarDeclaration::Implicit::Special.new(:name('$!'))) if $exclamation-mark; nqp::push(@declarations, RakuAST::VarDeclaration::Implicit::Special.new(:name('$_'))) if $underscore; nqp::push(@declarations, RakuAST::VarDeclaration::Implicit::Routine.new()) if nqp::getattr($SELF, RakuAST::Routine, '$!need-routine-variable'); $SELF.IMPL-WRAP-LIST(@declarations) }); add-method(RakuAST::Routine, 'IMPL-HAS-PARAMETER', [RakuAST::Routine, '', 0, 0, Str, '$name', 0, 0], anon sub IMPL-HAS-PARAMETER ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 1611 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::Routine, '$!signature').IMPL-HAS-PARAMETER($name) }); add-method(RakuAST::Routine, 'IMPL-QAST-FORM-BLOCK', [RakuAST::Routine, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-QAST-FORM-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 1616 src/Raku/ast/code.rakumod # RegexThunk needs the body compiled first my $body := $SELF.IMPL-COMPILE-BODY($context); my $block := $SELF.IMPL-SET-NODE( QAST::Block.new( :name($SELF.name ?? $SELF.name.canonicalize !! ''), :blocktype('declaration_static'), $SELF.IMPL-QAST-DECLS($context) ), :key); my $signature := $SELF.placeholder-signature || nqp::getattr($SELF, RakuAST::Routine, '$!signature'); $block.push($signature.IMPL-QAST-BINDINGS($context, :needs-full-binder($SELF.custom-args))); $block.custom_args(1) if $SELF.custom-args; $block.arity($signature.arity); $block.annotate('count', $signature.count); $block.push($body); $SELF.add-phasers-handling-code($context, $block); $block }); add-method(RakuAST::Routine, 'IMPL-COMPILE-BODY', [RakuAST::Routine, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-COMPILE-BODY ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1637 src/Raku/ast/code.rakumod nqp::die('RakuAST::Routine subclass must implement IMPL-COMPILE-BODY') }); add-method(RakuAST::Routine, 'IMPL-WRAP-RETURN-HANDLER', [RakuAST::Routine, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, QAST::Node, '$body', 0, 0], anon sub IMPL-WRAP-RETURN-HANDLER ($SELF_CONT, $context!, $body!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $body := nqp::decont($body); #line 1641 src/Raku/ast/code.rakumod my $result := $body; my $routine := $SELF.compile-time-value; my $signature := nqp::getattr($routine, Code, '$!signature'); $context.ensure-sc($routine); # Add return exception and decont handler if needed. # TODO optimize out if provably no return call my str $decont-rv-op := $context.lang-version lt 'd' && $context.is-moar ?? 'p6decontrv_6c' !! 'p6decontrv'; $result := QAST::Op.new( :op, QAST::Op.new( :op($decont-rv-op), QAST::WVal.new( :value($routine) ), $result ), 'RETURN', QAST::Op.new( :op ) ); # Add return type check if needed. # TODO also infer body type my $returns := nqp::ifnull($signature.returns, Mu); unless $returns =:= Mu || $returns =:= Nil || nqp::isconcrete($returns) { $context.ensure-sc($returns); $result := QAST::Op.new( :op('p6typecheckrv'), $result, QAST::WVal.new( :value($routine) ), QAST::WVal.new( :value(Nil) ) ); } $result }); add-method(RakuAST::Routine, 'IMPL-QAST-DECL-CODE', [RakuAST::Routine, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL-CODE ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1675 src/Raku/ast/code.rakumod # Form the QAST block itself and link it with the meta-object. my $block := $SELF.IMPL-QAST-BLOCK($context); # Set a name, if there is one. if nqp::getattr($SELF, RakuAST::Routine, '$!name') { my $canon-name := nqp::getattr($SELF, RakuAST::Routine, '$!name').canonicalize; $block.name($canon-name); } my $name := $SELF.lexical-name; if $name && ($SELF.scope eq 'our' || $SELF.scope eq 'unit') { my $stmts := $SELF.IMPL-SET-NODE(QAST::Stmts.new(), :key); $stmts.push($block); (nqp::getattr($SELF, RakuAST::Routine, '$!package').meta-object.WHO){$name} := $SELF.meta-object; $stmts.push(QAST::Op.new( :op('bindkey'), QAST::Op.new( :op('who'), QAST::WVal.new( :value(nqp::getattr($SELF, RakuAST::Routine, '$!package').meta-object) ) ), QAST::SVal.new( :value($name) ), QAST::Var.new( :name($name), :scope('lexical') ) )); return $stmts; } $block }); add-method(RakuAST::Routine, 'IMPL-QAST-DECL', [RakuAST::Routine, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1702 src/Raku/ast/code.rakumod # If we're a named lexical thing, install us in the block. my $name := $SELF.lexical-name; if $name && $SELF.multiness ne 'multi' { QAST::Op.new( :op('bind'), QAST::Var.new( :decl, :scope, :$name ), $SELF.IMPL-CLOSURE-QAST($context) ) } else { QAST::Op.new( :op('null') ) } }); add-method(RakuAST::Routine, 'IMPL-EXPR-QAST', [RakuAST::Routine, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1717 src/Raku/ast/code.rakumod $SELF.IMPL-CLOSURE-QAST($context) }); add-method(RakuAST::Routine, 'lexical-name', [RakuAST::Routine, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1721 src/Raku/ast/code.rakumod my $name := $SELF.name; if $name { '&' ~ $name.canonicalize } else { Nil } }); add-method(RakuAST::Routine, 'is-lexical', [RakuAST::Routine, '', 0, 0], anon sub is-lexical ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1731 src/Raku/ast/code.rakumod my str $scope := $SELF.scope; $scope eq 'my' || $scope eq 'state' || $scope eq 'our' || $scope eq 'unit' }); add-method(RakuAST::Routine, 'is-simple-lexical-declaration', [RakuAST::Routine, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1736 src/Raku/ast/code.rakumod $SELF.is-lexical && $SELF.multiness ne 'multi' }); add-method(RakuAST::Routine, 'generate-lookup', [RakuAST::Routine, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1740 src/Raku/ast/code.rakumod if $SELF.is-lexical { my $lookup := RakuAST::Var::Lexical.new($SELF.lexical-name); $lookup.set-resolution($SELF); $lookup } else { nqp::die('Cannot generate lookup of a routine for scope ' ~ $SELF.scope); } }); add-method(RakuAST::Routine, 'IMPL-LOOKUP-QAST', [RakuAST::Routine, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$rvalue', 1, 1], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!, :$rvalue?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $rvalue := nqp::decont($rvalue); #line 1751 src/Raku/ast/code.rakumod QAST::Var.new( :scope('lexical'), :name($SELF.lexical-name) ) }); add-method(RakuAST::Routine, 'visit-children', [RakuAST::Routine, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1755 src/Raku/ast/code.rakumod $visitor(nqp::getattr($SELF, RakuAST::Routine, '$!name')) if nqp::getattr($SELF, RakuAST::Routine, '$!name'); $visitor($SELF.WHY) if $SELF.WHY; # needs to be before signature $visitor(nqp::getattr($SELF, RakuAST::Routine, '$!signature')); $SELF.visit-traits($visitor); $visitor($SELF.body); }); add-method(RakuAST::Routine, 'IMPL-CAN-INTERPRET', [RakuAST::Routine, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1763 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::Routine, 'IMPL-INTERPRET', [RakuAST::Routine, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 1767 src/Raku/ast/code.rakumod $SELF.meta-object }); #line 1381 src/Raku/ast/code.rakumod add-method(RakuAST::Routine, 'signature', [], anon sub signature ($self) { nqp::getattr(nqp::decont($self), RakuAST::Routine, '$!signature') }); #line 1384 src/Raku/ast/code.rakumod add-method(RakuAST::Routine, 'need-routine-variable', [], anon sub need-routine-variable ($self) { nqp::getattr(nqp::decont($self), RakuAST::Routine, '$!need-routine-variable') }); #line 1380 src/Raku/ast/code.rakumod add-method(RakuAST::Routine, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Routine, '$!name') }); compose(RakuAST::Routine); parent(RakuAST::Sub, RakuAST::Routine); parent(RakuAST::Sub, RakuAST::SinkBoundary); add-attribute(RakuAST::Sub, RakuAST::Blockoid, '$!body'); add-method(RakuAST::Sub, 'new', [RakuAST::Sub, '', 0, 0, str, '$scope', 1, 1, str, '$multiness', 1, 1, RakuAST::Name, '$name', 1, 1, RakuAST::Signature, '$signature', 1, 1, List, '$traits', 1, 1, RakuAST::Blockoid, '$body', 1, 1, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$scope?, :$multiness?, :$name?, :$signature?, :$traits?, :$body?, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $multiness := nqp::decont($multiness); $name := nqp::decont($name); $signature := nqp::decont($signature); $traits := nqp::decont($traits); $body := nqp::decont($body); $WHY := nqp::decont($WHY); #line 1786 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr_s($obj, RakuAST::Routine, '$!multiness', $multiness //''); nqp::bindattr($obj, RakuAST::Routine, '$!name', $name // RakuAST::Name); nqp::bindattr($obj, RakuAST::Routine, '$!signature', $signature // RakuAST::Signature.new); $obj.set-traits($traits); nqp::bindattr($obj, RakuAST::Sub, '$!body', $body // RakuAST::Blockoid.new); $obj.set-WHY($WHY); $obj }); add-method(RakuAST::Sub, 'replace-body', [RakuAST::Sub, '', 0, 0, RakuAST::Blockoid, '$new-body', 0, 0], anon sub replace-body ($SELF_CONT, $new-body!) { my $SELF := nqp::decont($SELF_CONT); $new-body := nqp::decont($new-body); #line 1800 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Sub, '$!body', $new-body); Nil }); add-method(RakuAST::Sub, 'IMPL-META-OBJECT-TYPE', [RakuAST::Sub, '', 0, 0], anon sub IMPL-META-OBJECT-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1805 src/Raku/ast/code.rakumod Sub }); add-method(RakuAST::Sub, 'default-scope', [RakuAST::Sub, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1807 src/Raku/ast/code.rakumod $SELF.name ?? 'my' !! 'anon' }); add-method(RakuAST::Sub, 'allowed-scopes', [RakuAST::Sub, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1811 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST(['my', 'anon', 'our']) }); add-method(RakuAST::Sub, 'get-boundary-sink-propagator', [RakuAST::Sub, '', 0, 0], anon sub get-boundary-sink-propagator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1815 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::Sub, '$!body').statement-list }); add-method(RakuAST::Sub, 'is-boundary-sunk', [RakuAST::Sub, '', 0, 0], anon sub is-boundary-sunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1819 src/Raku/ast/code.rakumod my $signature := $SELF.signature; $signature ?? $signature.provides-return-value !! (Bool.WHO) }); add-method(RakuAST::Sub, 'IMPL-COMPILE-BODY', [RakuAST::Sub, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-COMPILE-BODY ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1824 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-RETURN-HANDLER($context, $SELF.IMPL-WRAP-SCOPE-HANDLER-QAST($context, $SELF.IMPL-APPEND-SIGNATURE-RETURN($context, nqp::getattr($SELF, RakuAST::Sub, '$!body').IMPL-TO-QAST($context)))) }); #line 1777 src/Raku/ast/code.rakumod add-method(RakuAST::Sub, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Sub, '$!body') }); compose(RakuAST::Sub); parent(RakuAST::Methodish, RakuAST::Routine); parent(RakuAST::Methodish, RakuAST::Attaching); add-method(RakuAST::Methodish, 'default-scope', [RakuAST::Methodish, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1837 src/Raku/ast/code.rakumod $SELF.name ?? 'has' !! 'anon' }); add-method(RakuAST::Methodish, 'allowed-scopes', [RakuAST::Methodish, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1841 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST(['has', 'my', 'anon', 'our']) }); add-method(RakuAST::Methodish, 'attach', [RakuAST::Methodish, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1845 src/Raku/ast/code.rakumod if $SELF.scope eq 'has' || $SELF.scope eq 'our' { my $package := $resolver.find-attach-target('package'); if $package { nqp::bindattr($SELF, RakuAST::Routine, '$!package', $package); } } nqp::bindattr($SELF, RakuAST::Code, '$!resolver', $resolver.clone); }); add-method(RakuAST::Methodish, 'is-begin-performed-before-children', [RakuAST::Methodish, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1855 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::Methodish, 'is-begin-performed-after-children', [RakuAST::Methodish, '', 0, 0], anon sub is-begin-performed-after-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1856 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::Methodish, 'PERFORM-BEGIN-BEFORE-CHILDREN', [RakuAST::Methodish, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-BEFORE-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1858 src/Raku/ast/code.rakumod my $package := nqp::getattr($SELF, RakuAST::Routine, '$!package'); my $package-is-role := $package && $package.declarator eq 'role'; my $placeholder-signature := $SELF.placeholder-signature; if $placeholder-signature { $placeholder-signature.set-is-on-method((Bool.WHO)); $placeholder-signature.set-is-on-named-method((Bool.WHO)) if $SELF.name; $placeholder-signature.set-is-on-meta-method((Bool.WHO)) if nqp::can($SELF, 'meta') && $SELF.meta; $placeholder-signature.set-is-on-role-method((Bool.WHO)) if $package-is-role; $placeholder-signature.attach($resolver); $placeholder-signature.IMPL-ENSURE-IMPLICITS; } # Make sure that our signature has resolutions performed. my $signature := $SELF.signature; if $signature { $signature.set-default-type( RakuAST::Type::Simple.new( RakuAST::Name.from-identifier('Any'), ), ); $signature.set-is-on-method((Bool.WHO)); $signature.set-is-on-named-method((Bool.WHO)) if $SELF.name; $signature.set-is-on-meta-method((Bool.WHO)) if nqp::can($SELF, 'meta') && $SELF.meta; $signature.set-is-on-role-method((Bool.WHO)) if $package-is-role; $signature.attach($resolver); $signature.IMPL-ENSURE-IMPLICITS; } }); add-method(RakuAST::Methodish, 'PERFORM-BEGIN-AFTER-CHILDREN', [RakuAST::Methodish, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN-AFTER-CHILDREN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1887 src/Raku/ast/code.rakumod if nqp::getattr($SELF,RakuAST::Routine,'$!package') { nqp::getattr($SELF,RakuAST::Routine,'$!package').ATTACH-METHOD($SELF) unless $SELF.scope eq 'our'; } elsif $SELF.scope eq 'has' { nqp::die('Did not find an attach target for method.'); } # Make sure that our placeholder signature has resolutions performed. my $placeholder-signature := $SELF.placeholder-signature; if $placeholder-signature { $placeholder-signature.IMPL-CHECK($resolver, $context, (Bool.WHO)); } # Make sure that our signature has resolutions performed. my $signature := $SELF.signature; if $signature { $signature.IMPL-CHECK($resolver, $context, (Bool.WHO)); } if $SELF.multiness eq 'proto' { nqp::bindattr($SELF.meta-object, Routine, '@!dispatchees', []); } $SELF.IMPL-STUB-PHASERS($resolver, $context); my $stub := $SELF.IMPL-STUB-CODE($resolver, $context); nqp::setcodename($stub, $SELF.name.canonicalize) if $SELF.name; # Apply any traits. $SELF.apply-traits($resolver, $context, $SELF) }); compose(RakuAST::Methodish); parent(RakuAST::Method, RakuAST::Methodish); parent(RakuAST::Method, RakuAST::SinkBoundary); add-attribute(RakuAST::Method, RakuAST::Blockoid, '$!body'); add-attribute(RakuAST::Method, Bool, '$!meta'); add-attribute(RakuAST::Method, Bool, '$!private'); add-method(RakuAST::Method, 'new', [RakuAST::Method, '', 0, 0, str, '$scope', 1, 1, str, '$multiness', 1, 1, Bool, '$private', 1, 1, Bool, '$meta', 1, 1, RakuAST::Name, '$name', 1, 1, RakuAST::Signature, '$signature', 1, 1, List, '$traits', 1, 1, RakuAST::Blockoid, '$body', 1, 1, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$scope?, :$multiness?, :$private?, :$meta?, :$name?, :$signature?, :$traits?, :$body?, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $multiness := nqp::decont($multiness); $private := nqp::decont($private); $meta := nqp::decont($meta); $name := nqp::decont($name); $signature := nqp::decont($signature); $traits := nqp::decont($traits); $body := nqp::decont($body); $WHY := nqp::decont($WHY); #line 1938 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr_s($obj, RakuAST::Routine, '$!multiness', $multiness //''); nqp::bindattr($obj, RakuAST::Method, '$!private', $private ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Method, '$!meta', $meta ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Routine, '$!name', $name // RakuAST::Name); nqp::bindattr($obj, RakuAST::Routine, '$!signature', $signature // RakuAST::Signature.new); $obj.set-traits($traits); nqp::bindattr($obj, RakuAST::Method, '$!body', $body // RakuAST::Blockoid.new); $obj.set-WHY($WHY); $obj }); add-method(RakuAST::Method, 'replace-body', [RakuAST::Method, '', 0, 0, RakuAST::Blockoid, '$new-body', 0, 0], anon sub replace-body ($SELF_CONT, $new-body!) { my $SELF := nqp::decont($SELF_CONT); $new-body := nqp::decont($new-body); #line 1955 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Method, '$!body', $new-body); Nil }); add-method(RakuAST::Method, 'set-meta', [RakuAST::Method, '', 0, 0, Bool, '$meta', 0, 0], anon sub set-meta ($SELF_CONT, $meta!) { my $SELF := nqp::decont($SELF_CONT); $meta := nqp::decont($meta); #line 1960 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Method, '$!meta', $meta ?? (Bool.WHO) !! (Bool.WHO)); }); add-method(RakuAST::Method, 'set-private', [RakuAST::Method, '', 0, 0, Bool, '$private', 0, 0], anon sub set-private ($SELF_CONT, $private!) { my $SELF := nqp::decont($SELF_CONT); $private := nqp::decont($private); #line 1964 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::Method, '$!private', $private ?? (Bool.WHO) !! (Bool.WHO)); }); add-method(RakuAST::Method, 'IMPL-META-OBJECT-TYPE', [RakuAST::Method, '', 0, 0], anon sub IMPL-META-OBJECT-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1968 src/Raku/ast/code.rakumod Method }); add-method(RakuAST::Method, 'PRODUCE-IMPLICIT-DECLARATIONS', [RakuAST::Method, '', 0, 0], anon sub PRODUCE-IMPLICIT-DECLARATIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1970 src/Raku/ast/code.rakumod my $list := nqp::findmethod(RakuAST::Routine, 'PRODUCE-IMPLICIT-DECLARATIONS')($SELF); $SELF.IMPL-UNWRAP-LIST($list).push: RakuAST::VarDeclaration::Implicit::Self.new(), }); add-method(RakuAST::Method, 'get-boundary-sink-propagator', [RakuAST::Method, '', 0, 0], anon sub get-boundary-sink-propagator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1976 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::Method, '$!body').statement-list }); add-method(RakuAST::Method, 'is-boundary-sunk', [RakuAST::Method, '', 0, 0], anon sub is-boundary-sunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1980 src/Raku/ast/code.rakumod my $signature := $SELF.signature; $signature ?? $signature.provides-return-value !! (Bool.WHO) }); add-method(RakuAST::Method, 'IMPL-COMPILE-BODY', [RakuAST::Method, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-COMPILE-BODY ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1985 src/Raku/ast/code.rakumod # If our first expression is a stub object (!!!, ..., ???), # set the yada bit on the Method itself if (my $first-statement := nqp::getattr($SELF, RakuAST::Method, '$!body').statement-list.statements.AT-POS(0)) && nqp::istype($first-statement, RakuAST::Statement::Expression) && nqp::istype($first-statement.expression, RakuAST::Stub) { $SELF.meta-object.set_yada; } $SELF.IMPL-WRAP-RETURN-HANDLER($context, $SELF.IMPL-WRAP-SCOPE-HANDLER-QAST($context, $SELF.IMPL-APPEND-SIGNATURE-RETURN($context, nqp::getattr($SELF, RakuAST::Method, '$!body').IMPL-TO-QAST($context)))) }); #line 1927 src/Raku/ast/code.rakumod add-method(RakuAST::Method, 'private', [], anon sub private ($self) { nqp::getattr(nqp::decont($self), RakuAST::Method, '$!private') }); #line 1926 src/Raku/ast/code.rakumod add-method(RakuAST::Method, 'meta', [], anon sub meta ($self) { nqp::getattr(nqp::decont($self), RakuAST::Method, '$!meta') }); #line 1925 src/Raku/ast/code.rakumod add-method(RakuAST::Method, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Method, '$!body') }); compose(RakuAST::Method); parent(RakuAST::Submethod, RakuAST::Method); add-method(RakuAST::Submethod, 'IMPL-META-OBJECT-TYPE', [RakuAST::Submethod, '', 0, 0], anon sub IMPL-META-OBJECT-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2005 src/Raku/ast/code.rakumod Submethod }); compose(RakuAST::Submethod); parent(RakuAST::RegexDeclaration, RakuAST::Methodish); parent(RakuAST::RegexDeclaration, RakuAST::CheckTime); add-attribute(RakuAST::RegexDeclaration, RakuAST::Regex, '$!body'); add-attribute(RakuAST::RegexDeclaration, str, '$!source'); add-method(RakuAST::RegexDeclaration, 'new', [RakuAST::RegexDeclaration, '', 0, 0, str, '$scope', 1, 1, RakuAST::Name, '$name', 1, 1, RakuAST::Signature, '$signature', 1, 1, List, '$traits', 1, 1, RakuAST::Regex, '$body', 1, 1, str, '$source', 1, 1, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$scope?, :$name?, :$signature?, :$traits?, :$body?, :$source?, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $name := nqp::decont($name); $signature := nqp::decont($signature); $traits := nqp::decont($traits); $body := nqp::decont($body); $source := nqp::decont($source); $WHY := nqp::decont($WHY); #line 2024 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr($obj, RakuAST::Routine, '$!name', $name // RakuAST::Name); nqp::bindattr($obj, RakuAST::Routine, '$!signature', $signature // RakuAST::Signature.new); $obj.set-traits($traits); nqp::bindattr($obj, RakuAST::RegexDeclaration, '$!body', $body // RakuAST::Regex::Assertion::Fail.new); $obj.set-source($source); $obj.set-WHY($WHY); $obj }); add-method(RakuAST::RegexDeclaration, 'declarator', [RakuAST::RegexDeclaration, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2038 src/Raku/ast/code.rakumod 'regex' }); add-method(RakuAST::RegexDeclaration, 'replace-body', [RakuAST::RegexDeclaration, '', 0, 0, RakuAST::Regex, '$new-body', 0, 0], anon sub replace-body ($SELF_CONT, $new-body!) { my $SELF := nqp::decont($SELF_CONT); $new-body := nqp::decont($new-body); #line 2040 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::RegexDeclaration, '$!body', $new-body); Nil }); add-method(RakuAST::RegexDeclaration, 'set-source', [RakuAST::RegexDeclaration, '', 0, 0, Any, '$source', 0, 0], anon sub set-source ($SELF_CONT, $source!) { my $SELF := nqp::decont($SELF_CONT); $source := nqp::decont($source); #line 2045 src/Raku/ast/code.rakumod nqp::bindattr_s($SELF, RakuAST::RegexDeclaration, '$!source', $source // ''); Nil }); add-method(RakuAST::RegexDeclaration, 'PERFORM-CHECK', [RakuAST::RegexDeclaration, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 2054 src/Raku/ast/code.rakumod my $meta := $SELF.meta-object; nqp::bindattr_s($meta, $meta.WHAT, '$!source', $SELF.declarator ~ ' ' ~ nqp::getattr_s($SELF, RakuAST::RegexDeclaration, '$!source') ); (Bool.WHO) }); add-method(RakuAST::RegexDeclaration, 'IMPL-META-OBJECT-TYPE', [RakuAST::RegexDeclaration, '', 0, 0], anon sub IMPL-META-OBJECT-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2062 src/Raku/ast/code.rakumod Regex }); add-method(RakuAST::RegexDeclaration, 'PRODUCE-IMPLICIT-DECLARATIONS', [RakuAST::RegexDeclaration, '', 0, 0], anon sub PRODUCE-IMPLICIT-DECLARATIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2064 src/Raku/ast/code.rakumod my @declarations := [ RakuAST::VarDeclaration::Implicit::Special.new(:name('$/')), RakuAST::VarDeclaration::Implicit::Special.new(:name('$!')), RakuAST::VarDeclaration::Implicit::Special.new(:name('$_')), RakuAST::VarDeclaration::Implicit::Self.new(), RakuAST::VarDeclaration::Implicit::Cursor.new(), ]; nqp::push(@declarations, RakuAST::VarDeclaration::Implicit::Routine.new()) if nqp::getattr($SELF, RakuAST::Routine, '$!need-routine-variable'); $SELF.IMPL-WRAP-LIST(@declarations) }); add-method(RakuAST::RegexDeclaration, 'IMPL-COMPILE-BODY', [RakuAST::RegexDeclaration, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-COMPILE-BODY ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2077 src/Raku/ast/code.rakumod my %mods; %mods := 1 if $SELF.declarator eq 'rule'; %mods := 1 if $SELF.declarator ne 'regex'; my $name := $SELF.name; $name := $name ?? $name.canonicalize !! ""; $SELF.IMPL-SET-NODE( QAST::Stmts.new( # Regex compiler wants a local named "self" QAST::Op.new( :op('bind'), QAST::Var.new( :decl('var'), :scope('local'), :name('self') ), QAST::Var.new( :scope('lexical'), :name('self') ) ), nqp::getattr($SELF, RakuAST::RegexDeclaration, '$!body').IMPL-REGEX-TOP-LEVEL-QAST( $context, $SELF.meta-object, %mods, :$name ) ), :key) }); #line 2015 src/Raku/ast/code.rakumod add-method(RakuAST::RegexDeclaration, 'source', [], anon sub source ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::RegexDeclaration, '$!source') }); #line 2014 src/Raku/ast/code.rakumod add-method(RakuAST::RegexDeclaration, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::RegexDeclaration, '$!body') }); compose(RakuAST::RegexDeclaration); parent(RakuAST::TokenDeclaration, RakuAST::RegexDeclaration); add-method(RakuAST::TokenDeclaration, 'declarator', [RakuAST::TokenDeclaration, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2103 src/Raku/ast/code.rakumod 'token' }); compose(RakuAST::TokenDeclaration); parent(RakuAST::RuleDeclaration, RakuAST::RegexDeclaration); add-method(RakuAST::RuleDeclaration, 'declarator', [RakuAST::RuleDeclaration, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2109 src/Raku/ast/code.rakumod 'rule' }); compose(RakuAST::RuleDeclaration); parent(RakuAST::RegexThunk, RakuAST::Code); parent(RakuAST::RegexThunk, RakuAST::Meta); parent(RakuAST::RegexThunk, RakuAST::BeginTime); add-method(RakuAST::RegexThunk, 'PRODUCE-META-OBJECT', [RakuAST::RegexThunk, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2121 src/Raku/ast/code.rakumod # Create default signature, receiving invocant only. my $signature := nqp::create(Signature); my $parameter := nqp::create(Parameter); nqp::bindattr($parameter, Parameter, '$!type', Mu); nqp::bindattr($signature, Signature, '@!params', nqp::list($parameter)); # Create Regex object. my $regex := nqp::create(Regex); nqp::bindattr($regex, Code, '$!signature', $signature); nqp::bindattr_s($regex, Regex, '$!source', $SELF.origin ?? $SELF.origin.Str !! $SELF.DEPARSE); nqp::bindattr($signature, Signature, '$!code', $regex); $regex }); add-method(RakuAST::RegexThunk, 'IMPL-QAST-FORM-BLOCK', [RakuAST::RegexThunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-QAST-FORM-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 2137 src/Raku/ast/code.rakumod my $slash := RakuAST::VarDeclaration::Implicit::Special.new(:name('$/')); QAST::Block.new( :blocktype('declaration_static'), QAST::Var.new( :decl('var'), :scope('local'), :name('self') ), QAST::Var.new( :decl('var'), :scope('lexical'), :name('$¢') ), QAST::Op.new( :op('bind'), QAST::Var.new(:name('$?REGEX'), :scope, :decl('var')), QAST::Op.new( :op('getcodeobj'), QAST::Op.new( :op('curcode') ) ) ), $slash.IMPL-QAST-DECL($context), QAST::Var.new( :decl('param'), :scope('local'), :name('__lowered_param'), QAST::Op.new( :op('bind'), QAST::Var.new( :scope('local'), :name('self') ), QAST::Op.new( :op('decont'), QAST::Var.new( :scope('local'), :name('__lowered_param') ) ) ) ), $SELF.IMPL-THUNKED-REGEX-QAST($context) ) }); add-method(RakuAST::RegexThunk, 'is-begin-performed-before-children', [RakuAST::RegexThunk, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2167 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::RegexThunk, 'PERFORM-BEGIN', [RakuAST::RegexThunk, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 2169 src/Raku/ast/code.rakumod $SELF.IMPL-STUB-CODE($resolver, $context); Nil }); compose(RakuAST::RegexThunk); parent(RakuAST::QuotedMatchConstruct, RakuAST::Term); parent(RakuAST::QuotedMatchConstruct, RakuAST::BeginTime); add-attribute(RakuAST::QuotedMatchConstruct, List, '$!adverbs'); add-method(RakuAST::QuotedMatchConstruct, 'replace-adverbs', [RakuAST::QuotedMatchConstruct, '', 0, 0, List, '$adverbs', 0, 0], anon sub replace-adverbs ($SELF_CONT, $adverbs!) { my $SELF := nqp::decont($SELF_CONT); $adverbs := nqp::decont($adverbs); #line 2184 src/Raku/ast/code.rakumod my @checked-adverbs; if $adverbs { for $SELF.IMPL-UNWRAP-LIST($adverbs) { unless nqp::istype($_, RakuAST::QuotePair) { nqp::die('A regex adverb may only be a RakuAST::QuotePair'); } nqp::push(@checked-adverbs, $_); } } nqp::bindattr($SELF, RakuAST::QuotedMatchConstruct, '$!adverbs', $SELF.IMPL-WRAP-LIST(@checked-adverbs)); Nil }); add-method(RakuAST::QuotedMatchConstruct, 'IMPL-NORMALIZE-ADVERB', [RakuAST::QuotedMatchConstruct, '', 0, 0, str, '$adverb', 0, 0], anon sub IMPL-NORMALIZE-ADVERB ($SELF_CONT, $adverb!) { my $SELF := nqp::decont($SELF_CONT); $adverb := nqp::decont($adverb); #line 2199 src/Raku/ast/code.rakumod my constant NORMS := nqp::hash( 'ignorecase', 'i', 'ignoremark', 'm', 'ratchet', 'r', 'sigspace', 's', 'continue', 'c', 'pos', 'p', 'th', 'nth', 'st', 'nth', 'nd', 'nth', 'rd', 'nth', 'global', 'g', 'overlap', 'ov', 'exhaustive', 'ex', 'Perl5', 'P5', 'samecase', 'ii', 'samespace', 'ss', 'samemark', 'mm', 'squash', 's', 'complement', 'c', 'delete', 'd' ); NORMS{$adverb} // $adverb }); add-method(RakuAST::QuotedMatchConstruct, 'IMPL-IS-COMPILATION-ADVERB', [RakuAST::QuotedMatchConstruct, '', 0, 0, str, '$norm-adverb', 0, 0], anon sub IMPL-IS-COMPILATION-ADVERB ($SELF_CONT, $norm-adverb!) { my $SELF := nqp::decont($SELF_CONT); $norm-adverb := nqp::decont($norm-adverb); #line 2225 src/Raku/ast/code.rakumod my constant COMPS := nqp::hash('i', 1, 'm', 1, 'r', 1, 's', 1, 'P5', 1); nqp::existskey(COMPS, $norm-adverb) }); add-method(RakuAST::QuotedMatchConstruct, 'IMPL-IS-POSITION-ADVERB', [RakuAST::QuotedMatchConstruct, '', 0, 0, str, '$norm-adverb', 0, 0], anon sub IMPL-IS-POSITION-ADVERB ($SELF_CONT, $norm-adverb!) { my $SELF := nqp::decont($SELF_CONT); $norm-adverb := nqp::decont($norm-adverb); #line 2230 src/Raku/ast/code.rakumod my constant POS := nqp::hash('c', 1, 'p', 1); nqp::existskey(POS, $norm-adverb) }); add-method(RakuAST::QuotedMatchConstruct, 'IMPL-IS-MULTIPLE-ADVERB', [RakuAST::QuotedMatchConstruct, '', 0, 0, str, '$norm-adverb', 0, 0], anon sub IMPL-IS-MULTIPLE-ADVERB ($SELF_CONT, $norm-adverb!) { my $SELF := nqp::decont($SELF_CONT); $norm-adverb := nqp::decont($norm-adverb); #line 2235 src/Raku/ast/code.rakumod my constant POS := nqp::hash('x', 1, 'g', 1, 'ov', 1, 'ex', 1); nqp::existskey(POS, $norm-adverb) }); add-method(RakuAST::QuotedMatchConstruct, 'IMPL-SUBST-TO-MATCH-ADVERB', [RakuAST::QuotedMatchConstruct, '', 0, 0, str, '$adverb', 0, 0], anon sub IMPL-SUBST-TO-MATCH-ADVERB ($SELF_CONT, $adverb!) { my $SELF := nqp::decont($SELF_CONT); $adverb := nqp::decont($adverb); #line 2240 src/Raku/ast/code.rakumod my constant S2M := nqp::hash('ii', 'i', 'ss', 's', 'mm', 'm'); S2M{$adverb} // $adverb }); add-method(RakuAST::QuotedMatchConstruct, 'IMPL-ADVERBS-TO-COMPILATION-MODS', [RakuAST::QuotedMatchConstruct, '', 0, 0], anon sub IMPL-ADVERBS-TO-COMPILATION-MODS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2245 src/Raku/ast/code.rakumod # Obtain adverbs that affect compilation and install them into # the %mods hash. my %mods; for $SELF.IMPL-UNWRAP-LIST($SELF.adverbs) { my str $norm := $SELF.IMPL-SUBST-TO-MATCH-ADVERB($SELF.IMPL-NORMALIZE-ADVERB($_.key)); if $SELF.IMPL-IS-COMPILATION-ADVERB($norm) { %mods{$norm} := $_.simple-compile-time-quote-value() ?? 1 !! 0; } } %mods }); add-method(RakuAST::QuotedMatchConstruct, 'IMPL-VISIT-ADVERBS', [RakuAST::QuotedMatchConstruct, '', 0, 0, Code, '$visitor', 0, 0], anon sub IMPL-VISIT-ADVERBS ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2258 src/Raku/ast/code.rakumod for $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::QuotedMatchConstruct, '$!adverbs')) { $visitor($_); } }); add-method(RakuAST::QuotedMatchConstruct, 'is-begin-performed-before-children', [RakuAST::QuotedMatchConstruct, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2264 src/Raku/ast/code.rakumod (Bool.WHO) }); add-method(RakuAST::QuotedMatchConstruct, 'PERFORM-BEGIN', [RakuAST::QuotedMatchConstruct, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 2266 src/Raku/ast/code.rakumod $SELF.IMPL-STUB-CODE($resolver, $context); Nil }); #line 2182 src/Raku/ast/code.rakumod add-method(RakuAST::QuotedMatchConstruct, 'adverbs', [], anon sub adverbs ($self) { nqp::getattr(nqp::decont($self), RakuAST::QuotedMatchConstruct, '$!adverbs') }); compose(RakuAST::QuotedMatchConstruct); parent(RakuAST::QuotedRegex, RakuAST::RegexThunk); parent(RakuAST::QuotedRegex, RakuAST::QuotedMatchConstruct); parent(RakuAST::QuotedRegex, RakuAST::Sinkable); parent(RakuAST::QuotedRegex, RakuAST::ImplicitLookups); parent(RakuAST::QuotedRegex, RakuAST::CheckTime); add-attribute(RakuAST::QuotedRegex, RakuAST::Regex, '$!body'); add-attribute(RakuAST::QuotedRegex, Bool, '$!match-immediately'); add-method(RakuAST::QuotedRegex, 'new', [RakuAST::QuotedRegex, '', 0, 0, RakuAST::Regex, '$body', 1, 1, Bool, '$match-immediately', 1, 1, List, '$adverbs', 1, 1], anon sub new ($SELF_CONT, :$body?, :$match-immediately?, :$adverbs?) { my $SELF := nqp::decont($SELF_CONT); $body := nqp::decont($body); $match-immediately := nqp::decont($match-immediately); $adverbs := nqp::decont($adverbs); #line 2285 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::QuotedRegex, '$!body', $body // RakuAST::Regex::Assertion::Fail.new); nqp::bindattr($obj, RakuAST::QuotedRegex, '$!match-immediately', $match-immediately ?? (Bool.WHO) !! (Bool.WHO)); $obj.replace-adverbs($adverbs // List); $obj }); add-method(RakuAST::QuotedRegex, 'replace-body', [RakuAST::QuotedRegex, '', 0, 0, RakuAST::Regex, '$new-body', 0, 0], anon sub replace-body ($SELF_CONT, $new-body!) { my $SELF := nqp::decont($SELF_CONT); $new-body := nqp::decont($new-body); #line 2295 src/Raku/ast/code.rakumod nqp::bindattr($SELF, RakuAST::QuotedRegex, '$!body', $new-body); Nil }); add-method(RakuAST::QuotedRegex, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::QuotedRegex, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2300 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical.new('$_'), RakuAST::Var::Lexical.new('$/'), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier-parts( 'Rakudo', 'Internals', 'RegexBoolification6cMarker' )) ]) }); add-method(RakuAST::QuotedRegex, 'IMPL-IS-IMMEDIATE-MATCH-ADVERB', [RakuAST::QuotedRegex, '', 0, 0, str, '$norm-adverb', 0, 0], anon sub IMPL-IS-IMMEDIATE-MATCH-ADVERB ($SELF_CONT, $norm-adverb!) { my $SELF := nqp::decont($SELF_CONT); $norm-adverb := nqp::decont($norm-adverb); #line 2310 src/Raku/ast/code.rakumod $norm-adverb eq 'nth' || $SELF.IMPL-IS-POSITION-ADVERB($norm-adverb) || $SELF.IMPL-IS-MULTIPLE-ADVERB($norm-adverb) }); add-method(RakuAST::QuotedRegex, 'PERFORM-CHECK', [RakuAST::QuotedRegex, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 2315 src/Raku/ast/code.rakumod # Check adverbs for $SELF.IMPL-UNWRAP-LIST($SELF.adverbs) { my str $key := $_.key; my str $norm := $SELF.IMPL-NORMALIZE-ADVERB($key); if $SELF.IMPL-IS-COMPILATION-ADVERB($norm) { # Compile-time adverbs must have a simple compile time value. unless nqp::isconcrete($_.simple-compile-time-quote-value()) { $SELF.add-sorry: $resolver.build-exception: 'X::Value::Dynamic', what => "Adverb $key"; } } elsif !(nqp::getattr($SELF, RakuAST::QuotedRegex, '$!match-immediately') && $SELF.IMPL-IS-IMMEDIATE-MATCH-ADVERB($norm)) { # Not applicable to the construct, so report. $SELF.add-sorry: $resolver.build-exception: 'X::Syntax::Regex::Adverb', adverb => $key, construct => nqp::getattr($SELF, RakuAST::QuotedRegex, '$!match-immediately') ?? 'm' !! 'rx' } } }); add-method(RakuAST::QuotedRegex, 'IMPL-THUNKED-REGEX-QAST', [RakuAST::QuotedRegex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-THUNKED-REGEX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2338 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::QuotedRegex, '$!body').IMPL-REGEX-TOP-LEVEL-QAST($context, $SELF.meta-object, $SELF.IMPL-ADVERBS-TO-COMPILATION-MODS()) }); add-method(RakuAST::QuotedRegex, 'IMPL-QAST-DECL-CODE', [RakuAST::QuotedRegex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL-CODE ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2343 src/Raku/ast/code.rakumod # Form the block itself and link it with the meta-object. $SELF.IMPL-QAST-BLOCK($context, :blocktype('declaration_static')); }); add-method(RakuAST::QuotedRegex, 'IMPL-EXPR-QAST', [RakuAST::QuotedRegex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2348 src/Raku/ast/code.rakumod my $closure := $SELF.IMPL-CLOSURE-QAST($context, :regex); if nqp::getattr($SELF, RakuAST::QuotedRegex, '$!match-immediately') { my $lookups := $SELF.get-implicit-lookups; my $topic := $lookups.AT-POS(0).IMPL-TO-QAST($context); my $slash := $lookups.AT-POS(1).IMPL-TO-QAST($context); my $match-qast := QAST::Op.new( :op('callmethod'), :name('match'), $topic, $closure ); my int $is-multiple-match := 0; for $SELF.IMPL-UNWRAP-LIST($SELF.adverbs) { my str $norm := $SELF.IMPL-NORMALIZE-ADVERB($_.key); if $SELF.IMPL-IS-POSITION-ADVERB($norm) { # These need to be passed the end of the last match. $match-qast.push: QAST::Op.new: :named($norm), :op, $slash, QAST::Op.new( :op, :name, $slash ), QAST::IVal.new( :value(0) ) } else { # Pass the value of the pair. my $arg := $_.value.IMPL-TO-QAST($context); $arg.named($_.key); $match-qast.push($arg); $is-multiple-match := 1 if $SELF.IMPL-IS-MULTIPLE-ADVERB($norm); } } if $is-multiple-match { # Don't update $/ in the list case $match-qast } else { QAST::Op.new( :op('decont'), QAST::Op.new(:op('p6store'), $slash, $match-qast) ) } } else { $SELF.sunk ?? QAST::Op.new( :op('callmethod'), :name('Bool'), $closure ) !! $closure } }); add-method(RakuAST::QuotedRegex, 'IMPL-TWEAK-REGEX-CLONE', [RakuAST::QuotedRegex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$clone', 0, 0], anon sub IMPL-TWEAK-REGEX-CLONE ($SELF_CONT, $context!, $clone!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $clone := nqp::decont($clone); #line 2395 src/Raku/ast/code.rakumod my $lookups := $SELF.get-implicit-lookups; if $context.lang-version lt 'd' { my $topic := $lookups.AT-POS(2).IMPL-TO-QAST($context); $topic.named('topic'); $clone.push($topic); } else { my $topic := $lookups.AT-POS(0).IMPL-TO-QAST($context); $topic.named('topic'); $clone.push($topic); my $slash := $lookups.AT-POS(1).IMPL-TO-QAST($context); $slash.named('slash'); $clone.push($slash); } Nil }); add-method(RakuAST::QuotedRegex, 'visit-children', [RakuAST::QuotedRegex, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2413 src/Raku/ast/code.rakumod $SELF.IMPL-VISIT-ADVERBS($visitor); $visitor(nqp::getattr($SELF, RakuAST::QuotedRegex, '$!body')); }); #line 2283 src/Raku/ast/code.rakumod add-method(RakuAST::QuotedRegex, 'match-immediately', [], anon sub match-immediately ($self) { nqp::getattr(nqp::decont($self), RakuAST::QuotedRegex, '$!match-immediately') }); #line 2282 src/Raku/ast/code.rakumod add-method(RakuAST::QuotedRegex, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::QuotedRegex, '$!body') }); compose(RakuAST::QuotedRegex); parent(RakuAST::Substitution, RakuAST::RegexThunk); parent(RakuAST::Substitution, RakuAST::QuotedMatchConstruct); parent(RakuAST::Substitution, RakuAST::ImplicitLookups); parent(RakuAST::Substitution, RakuAST::CheckTime); add-attribute(RakuAST::Substitution, Bool, '$!immutable'); add-attribute(RakuAST::Substitution, Bool, '$!samespace'); add-attribute(RakuAST::Substitution, RakuAST::Regex, '$!pattern'); add-attribute(RakuAST::Substitution, RakuAST::Infixish, '$!infix'); add-attribute(RakuAST::Substitution, RakuAST::Expression, '$!replacement'); add-method(RakuAST::Substitution, 'new', [RakuAST::Substitution, '', 0, 0, Bool, '$immutable', 1, 1, Bool, '$samespace', 1, 1, List, '$adverbs', 1, 1, RakuAST::Regex, '$pattern', 1, 0, RakuAST::Infixish, '$infix', 1, 1, RakuAST::Expression, '$replacement', 1, 0], anon sub new ($SELF_CONT, :$immutable?, :$samespace?, :$adverbs?, :$pattern!, :$infix?, :$replacement!) { my $SELF := nqp::decont($SELF_CONT); $immutable := nqp::decont($immutable); $samespace := nqp::decont($samespace); $adverbs := nqp::decont($adverbs); $pattern := nqp::decont($pattern); $infix := nqp::decont($infix); $replacement := nqp::decont($replacement); #line 2434 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Substitution, '$!immutable', $immutable ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Substitution, '$!samespace', $samespace ?? (Bool.WHO) !! (Bool.WHO)); $obj.replace-adverbs($adverbs // List); nqp::bindattr($obj, RakuAST::Substitution, '$!pattern', $pattern); nqp::bindattr($obj, RakuAST::Substitution, '$!infix', $infix); nqp::bindattr($obj, RakuAST::Substitution, '$!replacement', $replacement); $obj }); add-method(RakuAST::Substitution, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Substitution, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2447 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Var::Lexical.new('$_'), RakuAST::Var::Lexical.new('$/'), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Positional')), ]) }); add-method(RakuAST::Substitution, 'IMPL-IS-SUBST-MATCH-ADVERB', [RakuAST::Substitution, '', 0, 0, str, '$norm-adverb', 0, 0], anon sub IMPL-IS-SUBST-MATCH-ADVERB ($SELF_CONT, $norm-adverb!) { my $SELF := nqp::decont($SELF_CONT); $norm-adverb := nqp::decont($norm-adverb); #line 2455 src/Raku/ast/code.rakumod my constant SUBST_OK := nqp::hash( 'x', 1, 'g', 1, 'nth', 1, 'ii', 1, 'ss', 1, 'mm', 1); $SELF.IMPL-IS-POSITION-ADVERB($norm-adverb) || nqp::existskey(SUBST_OK, $norm-adverb) }); add-method(RakuAST::Substitution, 'PERFORM-CHECK', [RakuAST::Substitution, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 2462 src/Raku/ast/code.rakumod # Check adverbs for $SELF.IMPL-UNWRAP-LIST($SELF.adverbs) { my str $key := $_.key; my str $norm := $SELF.IMPL-NORMALIZE-ADVERB($key); if $SELF.IMPL-IS-COMPILATION-ADVERB($SELF.IMPL-SUBST-TO-MATCH-ADVERB($norm)) { # Compile-time adverbs must have a simple compile time value. unless nqp::isconcrete($_.simple-compile-time-quote-value()) { $SELF.add-sorry: $resolver.build-exception: 'X::Value::Dynamic', what => "Adverb $key"; } } elsif !$SELF.IMPL-IS-SUBST-MATCH-ADVERB($norm) { # Not applicable to the construct, so report. $SELF.add-sorry: $resolver.build-exception: 'X::Syntax::Regex::Adverb', adverb => $key, construct => nqp::getattr($SELF, RakuAST::Substitution, '$!immutable') ?? 'S' !! 's'; } } # Thunk the replacement part. nqp::getattr($SELF, RakuAST::Substitution, '$!replacement').wrap-with-thunk: RakuAST::SubstitutionReplacementThunk.new: :infix(nqp::getattr($SELF, RakuAST::Substitution, '$!infix')); nqp::getattr($SELF, RakuAST::Substitution, '$!replacement').visit-thunks(-> $thunk { $thunk.ensure-begin-performed($resolver, $context) }); }); add-method(RakuAST::Substitution, 'IMPL-THUNKED-REGEX-QAST', [RakuAST::Substitution, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-THUNKED-REGEX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2490 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::Substitution, '$!pattern').IMPL-REGEX-TOP-LEVEL-QAST($context, $SELF.meta-object, $SELF.IMPL-ADVERBS-TO-COMPILATION-MODS()) }); add-method(RakuAST::Substitution, 'IMPL-QAST-DECL-CODE', [RakuAST::Substitution, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL-CODE ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2495 src/Raku/ast/code.rakumod # Form the block itself and link it with the meta-object. my $block := $SELF.IMPL-QAST-FORM-BLOCK($context, :blocktype('declaration_static')); $SELF.IMPL-LINK-META-OBJECT($context, $block); $block }); add-method(RakuAST::Substitution, 'IMPL-EXPR-QAST', [RakuAST::Substitution, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2502 src/Raku/ast/code.rakumod # Coerce the topic into a Str before we start (we need to do that for # applying the match results anyway, so may as well avoid a double # coercion in the call to .match also). my $lookups := $SELF.get-implicit-lookups; my $topic := $lookups.AT-POS(0); my $slash := $lookups.AT-POS(1); my $Positional := $lookups.AT-POS(2); my $topic-str-var := QAST::Node.unique('subst_topic_str'); my $result := $SELF.IMPL-SET-NODE( QAST::Stmts.new( QAST::Op.new: :op('bind'), QAST::Var.new( :decl('var'), :scope('local'), :name($topic-str-var) ), QAST::Op.new: :op('callmethod'), :name('Str'), $topic.IMPL-TO-QAST($context) ), :key); # Compile the call to match the regex against the stringified topic, # binding it into a result variable. While emitting adverbs, take # note of those needed for the replacement also. my $regex-closure := $SELF.IMPL-CLOSURE-QAST($context); my $match-qast := QAST::Op.new: :op('callmethod'), :name('match'), QAST::Var.new( :scope('local'), :name($topic-str-var) ), $regex-closure; my $match-lookup := $slash.IMPL-TO-QAST($context); my int $samespace := nqp::getattr($SELF, RakuAST::Substitution, '$!samespace'); my int $sigspace := $samespace; my int $samecase := 0; my int $samemark := 0; for $SELF.IMPL-UNWRAP-LIST($SELF.adverbs) { my str $norm := $SELF.IMPL-NORMALIZE-ADVERB($_.key); if $SELF.IMPL-IS-POSITION-ADVERB($norm) { # These need to be passed the end of the last match. $match-qast.push: QAST::Op.new: :named($norm), :op, $match-lookup, QAST::Op.new( :op, :name, $match-lookup ), QAST::IVal.new( :value(0) ) } else { # Pass the value of the pair. my $arg := $_.value.IMPL-TO-QAST($context); $arg.named($_.key); $match-qast.push($arg); # Take note of interesting ones for the replacement. if $norm eq 'ii' { $samecase := 1; } elsif $norm eq 'mm' { $samemark := 1; } elsif $norm eq 'ss' { $samespace := 1; $sigspace := 1; } elsif $norm eq 's' { $sigspace := 1; } } } my $match-result-var := QAST::Node.unique('subst_match'); $result.push: QAST::Op.new: :op('bind'), QAST::Var.new( :decl('var'), :scope('local'), :name($match-result-var) ), $match-qast; # Assign the result to $/. $result.push: QAST::Op.new: :op('p6store'), $match-lookup, QAST::Var.new( :scope('local'), :name($match-result-var) ); # Obtain the replacement part and build the call to apply it to # the matches. my $replacement-closure := nqp::getattr($SELF, RakuAST::Substitution, '$!replacement').IMPL-TO-QAST($context); my $apply-matches-meth := Str.HOW.find_private_method(Str, 'APPLY-MATCHES'); my $apply-call := QAST::Op.new: :op('call'), QAST::WVal.new( :value($apply-matches-meth) ), QAST::Var.new( :scope('local'), :name($topic-str-var) ), QAST::Var.new( :scope('local'), :name($match-result-var) ), $replacement-closure, $match-lookup, # $/ QAST::WVal.new( :value((Bool.WHO)) ), # Flag to update $/ QAST::IVal.new( :value($sigspace) ), QAST::IVal.new( :value($samespace) ), QAST::IVal.new( :value($samecase) ), QAST::IVal.new( :value($samemark) ); # We only want to apply matches if we really did match. The pre-RakuAST # compiler frontend explicitly checked if it got a Match object or a # non-empty List. However, those are both truthy, and all the non-match # cases would be falsey, so we can just emit a truth test. $result.push: QAST::Op.new: :op('if'), QAST::Var.new( :scope('local'), :name($match-result-var) ), # If we matched... nqp::getattr($SELF, RakuAST::Substitution, '$!immutable') # For the S/// form, we evaluate to the result of the call to # APPLY-MATCHES ?? $apply-call # For the s/// form, we assign the result of APPLY-MATCHES # into the topic, and evaluate to the match result. !! QAST::Stmts.new( QAST::Op.new( :op('assign'), $lookups.AT-POS(0).IMPL-TO-QAST($context), $apply-call ), # If we have a list of matches, then put them into $/, # otherwise, $/ already has the Match object we want it to have. # Not entirely sure, why we need to do this. Guess $/ gets # clobbered by the APPLY-MATCHES call. QAST::Op.new( :op('p6store'), $match-lookup, QAST::Var.new( :name($match-result-var), :scope('local') ), ), QAST::Var.new( :scope('local'), :name($match-result-var) ) ), # If we didn't match... nqp::getattr($SELF, RakuAST::Substitution, '$!immutable') # For the S/// form, evaluate to topic Str ?? QAST::Var.new( :scope('local'), :name($topic-str-var) ) # For the s/// form, evaluate to the match variable !! $match-lookup; $result }); add-method(RakuAST::Substitution, 'visit-children', [RakuAST::Substitution, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2635 src/Raku/ast/code.rakumod $SELF.IMPL-VISIT-ADVERBS($visitor); $visitor(nqp::getattr($SELF, RakuAST::Substitution, '$!pattern')); $visitor(nqp::getattr($SELF, RakuAST::Substitution, '$!infix')) if nqp::getattr($SELF, RakuAST::Substitution, '$!infix'); $visitor(nqp::getattr($SELF, RakuAST::Substitution, '$!replacement')); }); #line 2427 src/Raku/ast/code.rakumod add-method(RakuAST::Substitution, 'samespace', [], anon sub samespace ($self) { nqp::getattr(nqp::decont($self), RakuAST::Substitution, '$!samespace') }); #line 2430 src/Raku/ast/code.rakumod add-method(RakuAST::Substitution, 'replacement', [], anon sub replacement ($self) { nqp::getattr(nqp::decont($self), RakuAST::Substitution, '$!replacement') }); #line 2428 src/Raku/ast/code.rakumod add-method(RakuAST::Substitution, 'pattern', [], anon sub pattern ($self) { nqp::getattr(nqp::decont($self), RakuAST::Substitution, '$!pattern') }); #line 2429 src/Raku/ast/code.rakumod add-method(RakuAST::Substitution, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::Substitution, '$!infix') }); #line 2426 src/Raku/ast/code.rakumod add-method(RakuAST::Substitution, 'immutable', [], anon sub immutable ($self) { nqp::getattr(nqp::decont($self), RakuAST::Substitution, '$!immutable') }); compose(RakuAST::Substitution); parent(RakuAST::SubstitutionReplacementThunk, RakuAST::ExpressionThunk); add-attribute(RakuAST::SubstitutionReplacementThunk, RakuAST::Infixish, '$!infix'); add-method(RakuAST::SubstitutionReplacementThunk, 'new', [RakuAST::SubstitutionReplacementThunk, '', 0, 0, RakuAST::Infixish, '$infix', 1, 1], anon sub new ($SELF_CONT, :$infix?) { my $SELF := nqp::decont($SELF_CONT); $infix := nqp::decont($infix); #line 2649 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::SubstitutionReplacementThunk, '$!infix', $infix); $obj }); add-method(RakuAST::SubstitutionReplacementThunk, 'IMPL-THUNK-TWEAK-EXPRESSION', [RakuAST::SubstitutionReplacementThunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$qast', 0, 0], anon sub IMPL-THUNK-TWEAK-EXPRESSION ($SELF_CONT, $context!, $qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $qast := nqp::decont($qast); #line 2655 src/Raku/ast/code.rakumod # We only need to really do the assignment if it's not a plain `=`; # if it's just that, we can avoid that work. if nqp::getattr($SELF, RakuAST::SubstitutionReplacementThunk, '$!infix') && !(nqp::istype(nqp::getattr($SELF, RakuAST::SubstitutionReplacementThunk, '$!infix'), RakuAST::Infix) && nqp::getattr($SELF, RakuAST::SubstitutionReplacementThunk, '$!infix').operator eq '=') { my $temp-var := QAST::Op.new: :op('p6assign'), QAST::Op.new( :op('p6scalarfromdesc'), QAST::Op.new( :op('null') ) ), QAST::Var.new( :name('$/'), :scope('lexical') ); nqp::getattr($SELF, RakuAST::SubstitutionReplacementThunk, '$!infix').IMPL-INFIX-QAST($context, $temp-var, $qast) } else { $qast } }); add-method(RakuAST::SubstitutionReplacementThunk, 'visit-children', [RakuAST::SubstitutionReplacementThunk, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2670 src/Raku/ast/code.rakumod $visitor(nqp::getattr($SELF, RakuAST::SubstitutionReplacementThunk, '$!infix')) if nqp::getattr($SELF, RakuAST::SubstitutionReplacementThunk, '$!infix'); }); #line 2647 src/Raku/ast/code.rakumod add-method(RakuAST::SubstitutionReplacementThunk, 'infix', [], anon sub infix ($self) { nqp::getattr(nqp::decont($self), RakuAST::SubstitutionReplacementThunk, '$!infix') }); compose(RakuAST::SubstitutionReplacementThunk); parent(RakuAST::CurryThunk, RakuAST::ExpressionThunk); parent(RakuAST::CurryThunk, RakuAST::ImplicitLookups); add-attribute(RakuAST::CurryThunk, Mu, '$!parameters'); add-attribute(RakuAST::CurryThunk, Str, '$!original-expression'); add-method(RakuAST::CurryThunk, 'new', [RakuAST::CurryThunk, '', 0, 0, Str, '$original-expression', 0, 0], anon sub new ($SELF_CONT, $original-expression!) { my $SELF := nqp::decont($SELF_CONT); $original-expression := nqp::decont($original-expression); #line 2683 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::CurryThunk, '$!parameters', []); nqp::bindattr($obj, RakuAST::CurryThunk, '$!original-expression', $original-expression); $obj }); add-method(RakuAST::CurryThunk, 'thunk-kind', [RakuAST::CurryThunk, '', 0, 0], anon sub thunk-kind ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2690 src/Raku/ast/code.rakumod 'WhateverCode' }); add-method(RakuAST::CurryThunk, 'thunk-details', [RakuAST::CurryThunk, '', 0, 0], anon sub thunk-details ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2694 src/Raku/ast/code.rakumod '⋐' ~ nqp::x('🔆', $SELF.IMPL-NUM-PARAMS) ~ '⋑' }); add-method(RakuAST::CurryThunk, 'IMPL-THUNK-OBJECT-TYPE', [RakuAST::CurryThunk, '', 0, 0], anon sub IMPL-THUNK-OBJECT-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2698 src/Raku/ast/code.rakumod $SELF.get-implicit-lookups.AT-POS(0).compile-time-value }); add-method(RakuAST::CurryThunk, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::CurryThunk, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2702 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('WhateverCode')) ]) }); add-method(RakuAST::CurryThunk, 'IMPL-ADD-PARAM', [RakuAST::CurryThunk, '', 0, 0, Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$name', 1, 1], anon sub IMPL-ADD-PARAM ($SELF_CONT, $resolver!, $context!, :$name?) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); $name := nqp::decont($name); #line 2708 src/Raku/ast/code.rakumod my $param := RakuAST::Parameter.new( # $name will usually be undefined, but sometimes we re-use references to existing * targets target => RakuAST::ParameterTarget::Whatever.new($name) ); nqp::push(nqp::getattr($SELF, RakuAST::CurryThunk, '$!parameters'), $param); $SELF.IMPL-UPDATE-SIGNATURE; $SELF.IMPL-CHECK($resolver, $context, (Bool.WHO)); $param }); add-method(RakuAST::CurryThunk, 'IMPL-NUM-PARAMS', [RakuAST::CurryThunk, '', 0, 0], anon sub IMPL-NUM-PARAMS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2719 src/Raku/ast/code.rakumod nqp::elems(nqp::getattr($SELF, RakuAST::CurryThunk, '$!parameters')) }); add-method(RakuAST::CurryThunk, 'IMPL-PARAMS', [RakuAST::CurryThunk, '', 0, 0], anon sub IMPL-PARAMS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2723 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::CurryThunk, '$!parameters') }); add-method(RakuAST::CurryThunk, 'IMPL-LAST-PARAM', [RakuAST::CurryThunk, '', 0, 0], anon sub IMPL-LAST-PARAM ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2727 src/Raku/ast/code.rakumod nqp::getattr($SELF, RakuAST::CurryThunk, '$!parameters')[nqp::elems(nqp::getattr($SELF, RakuAST::CurryThunk, '$!parameters')) - 1] }); add-method(RakuAST::CurryThunk, 'IMPL-THUNK-SIGNATURE', [RakuAST::CurryThunk, '', 0, 0], anon sub IMPL-THUNK-SIGNATURE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2731 src/Raku/ast/code.rakumod RakuAST::Signature.new(parameters => $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::CurryThunk, '$!parameters'))) }); add-method(RakuAST::CurryThunk, 'IMPL-THUNK-META-OBJECT-PRODUCED', [RakuAST::CurryThunk, '', 0, 0, Mu, '$code', 0, 0], anon sub IMPL-THUNK-META-OBJECT-PRODUCED ($SELF_CONT, $code!) { my $SELF := nqp::decont($SELF_CONT); $code := nqp::decont($code); #line 2735 src/Raku/ast/code.rakumod nqp::bindattr($code, $SELF.get-implicit-lookups.AT-POS(0).compile-time-value, '$!original-expression', nqp::getattr($SELF, RakuAST::CurryThunk, '$!original-expression')) }); compose(RakuAST::CurryThunk); parent(RakuAST::BlockThunk, RakuAST::ExpressionThunk); parent(RakuAST::BlockThunk, RakuAST::ImplicitDeclarations); add-attribute(RakuAST::BlockThunk, RakuAST::Expression, '$!expression'); add-method(RakuAST::BlockThunk, 'new', [RakuAST::BlockThunk, '', 0, 0, RakuAST::Expression, '$expression', 1, 1], anon sub new ($SELF_CONT, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); #line 2746 src/Raku/ast/code.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::BlockThunk, '$!expression', $expression) if $expression; $obj }); add-method(RakuAST::BlockThunk, 'thunk-kind', [RakuAST::BlockThunk, '', 0, 0], anon sub thunk-kind ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2752 src/Raku/ast/code.rakumod 'Block thunk' }); add-method(RakuAST::BlockThunk, 'thunk-details', [RakuAST::BlockThunk, '', 0, 0], anon sub thunk-details ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2756 src/Raku/ast/code.rakumod '' }); add-method(RakuAST::BlockThunk, 'PRODUCE-IMPLICIT-DECLARATIONS', [RakuAST::BlockThunk, '', 0, 0], anon sub PRODUCE-IMPLICIT-DECLARATIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2760 src/Raku/ast/code.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::VarDeclaration::Implicit::BlockTopic.new: parameter => $SELF.signature ?? (Bool.WHO) !! (Bool.WHO) ]); }); add-method(RakuAST::BlockThunk, 'IMPL-THUNK-OBJECT-TYPE', [RakuAST::BlockThunk, '', 0, 0], anon sub IMPL-THUNK-OBJECT-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2767 src/Raku/ast/code.rakumod Block }); add-method(RakuAST::BlockThunk, 'IMPL-QAST-DECL-CODE', [RakuAST::BlockThunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL-CODE ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 2771 src/Raku/ast/code.rakumod # Form the block itself and link it with the meta-object. $SELF.IMPL-QAST-BLOCK($context, :blocktype('declaration_static'), :expression(nqp::getattr($SELF, RakuAST::BlockThunk, '$!expression'))); }); add-method(RakuAST::BlockThunk, 'PRODUCE-META-OBJECT', [RakuAST::BlockThunk, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2776 src/Raku/ast/code.rakumod my $code := nqp::create($SELF.IMPL-THUNK-OBJECT-TYPE); my $param := nqp::create(Parameter); nqp::bindattr_s($param, Parameter, '$!variable_name', '$_'); nqp::bindattr_i($param, Parameter, '$!flags', 2048 + 16384); # Optional + default from outer my $sig := nqp::create(Signature); nqp::bindattr($sig, Signature, '@!params', [$param]); nqp::bindattr_i($sig, Signature, '$!arity', 0); nqp::bindattr($sig, Signature, '$!count', nqp::box_i(1, Int)); nqp::bindattr($code, Code, '$!signature', $sig); nqp::bindattr($sig, Signature, '$!code', $code); $SELF.IMPL-THUNK-META-OBJECT-PRODUCED($code); $code }); compose(RakuAST::BlockThunk); parent(RakuAST::CompUnit, RakuAST::LexicalScope); parent(RakuAST::CompUnit, RakuAST::SinkBoundary); parent(RakuAST::CompUnit, RakuAST::ImplicitLookups); parent(RakuAST::CompUnit, RakuAST::ImplicitDeclarations); parent(RakuAST::CompUnit, RakuAST::AttachTarget); parent(RakuAST::CompUnit, RakuAST::ScopePhaser); add-attribute(RakuAST::CompUnit, RakuAST::StatementList, '$!statement-list'); add-attribute(RakuAST::CompUnit, RakuAST::Block, '$!mainline'); add-attribute(RakuAST::CompUnit, Str, '$!comp-unit-name'); add-attribute(RakuAST::CompUnit, Str, '$!setting-name'); add-attribute(RakuAST::CompUnit, Mu, '$!language-revision'); add-attribute(RakuAST::CompUnit, Mu, '$!sc'); add-attribute(RakuAST::CompUnit, int, '$!is-sunk'); add-attribute(RakuAST::CompUnit, int, '$!is-eval'); add-attribute(RakuAST::CompUnit, Mu, '$!global-package-how'); add-attribute(RakuAST::CompUnit, Mu, '$!init-phasers'); add-attribute(RakuAST::CompUnit, Mu, '$!end-phasers'); add-attribute(RakuAST::CompUnit, RakuAST::VarDeclaration::Implicit::Doc::Pod, '$!pod'); add-attribute(RakuAST::CompUnit, RakuAST::VarDeclaration::Implicit::Doc::Data, '$!data'); add-attribute(RakuAST::CompUnit, RakuAST::VarDeclaration::Implicit::Doc::Finish, '$!finish'); add-attribute(RakuAST::CompUnit, RakuAST::VarDeclaration::Implicit::Doc::Rakudoc, '$!rakudoc'); add-attribute(RakuAST::CompUnit, Mu, '$!pod-content'); add-attribute(RakuAST::CompUnit, Mu, '$!data-content'); add-attribute(RakuAST::CompUnit, Mu, '$!finish-content'); add-attribute(RakuAST::CompUnit, Mu, '$!singleton-whatever'); add-attribute(RakuAST::CompUnit, Mu, '$!singleton-hyper-whatever'); add-attribute(RakuAST::CompUnit, int, '$!precompilation-mode'); add-attribute(RakuAST::CompUnit, Mu, '$!export-package'); add-attribute(RakuAST::CompUnit, Mu, '$!herestub-queue'); add-attribute(RakuAST::CompUnit, RakuAST::IMPL::QASTContext, '$!context'); add-method(RakuAST::CompUnit, 'new', [RakuAST::CompUnit, '', 0, 0, Str, '$comp-unit-name', 1, 0, Str, '$setting-name', 1, 1, Bool, '$eval', 1, 1, Mu, '$global-package-how', 1, 1, int, '$language-revision', 1, 1, Bool, '$precompilation-mode', 1, 1, Mu, '$export-package', 1, 1, RakuAST::StatementList, '$statement-list', 1, 1, RakuAST::CompUnit, '$outer-cu', 1, 1], anon sub new ($SELF_CONT, :$comp-unit-name!, :$setting-name?, :$eval?, :$global-package-how?, :$language-revision?, :$precompilation-mode?, :$export-package?, :$statement-list?, :$outer-cu?) { my $SELF := nqp::decont($SELF_CONT); $comp-unit-name := nqp::decont($comp-unit-name); $setting-name := nqp::decont($setting-name); $eval := nqp::decont($eval); $global-package-how := nqp::decont($global-package-how); $language-revision := nqp::decont($language-revision); $precompilation-mode := nqp::decont($precompilation-mode); $export-package := nqp::decont($export-package); $statement-list := nqp::decont($statement-list); $outer-cu := nqp::decont($outer-cu); #line 44 src/Raku/ast/compunit.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::CompUnit, '$!statement-list', $statement-list // RakuAST::StatementList.new); my $mainline := RakuAST::Block.new(); $mainline.set-implicit-topic(0); nqp::bindattr($obj, RakuAST::CompUnit, '$!mainline', $mainline); nqp::bindattr($obj, RakuAST::CompUnit, '$!comp-unit-name', $comp-unit-name); nqp::bindattr($obj, RakuAST::CompUnit, '$!setting-name', $setting-name // Str); nqp::bindattr_i($obj, RakuAST::CompUnit, '$!is-eval', $eval ?? $outer-cu ?? 2 !! 1 !! 0); nqp::bindattr($obj, RakuAST::CompUnit, '$!global-package-how', $global-package-how =:= NQPMu ?? Perl6::Metamodel::PackageHOW !! $global-package-how ); nqp::bindattr($obj, RakuAST::CompUnit, '$!export-package', $export-package =:= NQPMu ?? Mu !! $export-package); nqp::bindattr($obj, RakuAST::CompUnit, '$!init-phasers', []); nqp::bindattr($obj, RakuAST::CompUnit, '$!end-phasers', []); nqp::bindattr_i($obj, RakuAST::CompUnit, '$!precompilation-mode', $precompilation-mode ?? 1 !! 0); nqp::bindattr($obj, RakuAST::CompUnit, '$!pod-content', Array.new); nqp::bindattr($obj, RakuAST::CompUnit, '$!data-content', nqp::null); nqp::bindattr($obj, RakuAST::CompUnit, '$!herestub-queue', []); # If CompUnit's language revision is not set explicitly then guess it nqp::bindattr($obj, RakuAST::CompUnit, '$!language-revision', $language-revision ?? Perl6::Metamodel::Configuration.language_revision_object($language-revision) !! nqp::isconcrete( my $setting-rev := nqp::getlexrelcaller( nqp::ctxcallerskipthunks(nqp::ctx()), 'CORE-SETTING-REV' ) ) ?? $setting-rev !! Perl6::Metamodel::Configuration.language_revision_object( nqp::getcomp("Raku").language_revision) ); my $sc; if $outer-cu { my $context := $outer-cu.context.create-nested; $sc := $context.sc; my $precompilation-mode := $outer-cu.precompilation-mode; nqp::bindattr($obj, RakuAST::CompUnit, '$!sc', $sc); nqp::bindattr($obj, RakuAST::CompUnit, '$!context', $context); nqp::bindattr_i($obj, RakuAST::CompUnit, '$!precompilation-mode', $precompilation-mode); } else { $sc := nqp::createsc($comp-unit-name); nqp::pushcompsc($sc); nqp::bindattr($obj, RakuAST::CompUnit, '$!sc', $sc); nqp::bindattr($obj, RakuAST::CompUnit, '$!context', RakuAST::IMPL::QASTContext.new(:$sc, :$precompilation-mode)); nqp::bindattr($obj, RakuAST::CompUnit, '$!pod', RakuAST::VarDeclaration::Implicit::Doc::Pod.new); nqp::bindattr($obj, RakuAST::CompUnit, '$!data', RakuAST::VarDeclaration::Implicit::Doc::Data.new); nqp::bindattr($obj, RakuAST::CompUnit, '$!finish', RakuAST::VarDeclaration::Implicit::Doc::Finish.new); nqp::bindattr($obj, RakuAST::CompUnit, '$!rakudoc', RakuAST::VarDeclaration::Implicit::Doc::Rakudoc.new); } my $file := nqp::getlexdyn('$?FILES'); nqp::scsetdesc($sc, $file) unless nqp::isnull($file); $obj }); add-method(RakuAST::CompUnit, 'check', [RakuAST::CompUnit, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub check ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 125 src/Raku/ast/compunit.rakumod if @*LEADING-DOC { $resolver.add-worry: $resolver.build-exception: 'X::Syntax::Doc::Declarator::MissingDeclarand', :position; } nqp::getattr($SELF, RakuAST::CompUnit, '$!mainline').IMPL-CHECK($resolver, nqp::getattr($SELF, RakuAST::CompUnit, '$!context'), (Bool.WHO)); $SELF.IMPL-CHECK($resolver, nqp::getattr($SELF, RakuAST::CompUnit, '$!context'), (Bool.WHO)); # Not all RakuAST::Doc objects actually have their PERFORM-CHECK # method called on them, causing holes to occur in $=pod (albeit # that the blocks that *are* generated, are in the correct order). # So run over the array and filter out any undefined elements. my int $elems := nqp::getattr($SELF, RakuAST::CompUnit, '$!pod-content').elems; my int $i := $elems; my $pod := nqp::getattr($SELF, RakuAST::CompUnit, '$!pod-content'); while --$i >= 0 { $pod.splice($i,1) unless $pod.EXISTS-POS($i); } }); add-method(RakuAST::CompUnit, 'add-INIT-phaser-for-doc-handling', [RakuAST::CompUnit, '', 0, 0, Any, '$base', 0, 0, Any, '$type', 0, 0], anon sub add-INIT-phaser-for-doc-handling ($SELF_CONT, $base!, $type!) { my $SELF := nqp::decont($SELF_CONT); $base := nqp::decont($base); $type := nqp::decont($type); #line 154 src/Raku/ast/compunit.rakumod # Determine which module to load. If single element type, then it # is $base::To::$type. If multi-element, those are the name parts # to use. my @parts := nqp::split('::',$type); if nqp::elems(@parts) == 1 { nqp::unshift(@parts,'To'); nqp::unshift(@parts,$base); } my $name := RakuAST::Name.from-identifier-parts(|@parts); nqp::getattr($SELF, RakuAST::CompUnit, '$!statement-list').add-statement: RakuAST::Statement::Expression.new( expression => RakuAST::StatementPrefix::Phaser::Init.new( RakuAST::Block.new( body => RakuAST::Blockoid.new( RakuAST::StatementList.new( RakuAST::Statement::Use.new(module-name => $name), RakuAST::Statement::Expression.new( expression => RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier("say"), args => RakuAST::ArgList.new( RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new($name), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier("render"), args => RakuAST::ArgList.new( RakuAST::Var::Doc.new( $base eq 'Pod' ?? "pod" !! "rakudoc" ) ) ) ) ) ) ), RakuAST::Statement::Expression.new( expression => RakuAST::Call::Name.new( name => RakuAST::Name.from-identifier("exit") ) ) ) ) ) ) ) }); add-method(RakuAST::CompUnit, 'replace-statement-list', [RakuAST::CompUnit, '', 0, 0, RakuAST::StatementList, '$statement-list', 0, 0], anon sub replace-statement-list ($SELF_CONT, $statement-list!) { my $SELF := nqp::decont($SELF_CONT); $statement-list := nqp::decont($statement-list); #line 203 src/Raku/ast/compunit.rakumod nqp::bindattr($SELF, RakuAST::CompUnit, '$!statement-list', $statement-list); Nil }); add-method(RakuAST::CompUnit, 'replace-finish-content', [RakuAST::CompUnit, '', 0, 0, Mu, '$finish-content', 0, 0], anon sub replace-finish-content ($SELF_CONT, $finish-content!) { my $SELF := nqp::decont($SELF_CONT); $finish-content := nqp::decont($finish-content); #line 209 src/Raku/ast/compunit.rakumod nqp::bindattr($SELF, RakuAST::CompUnit, '$!finish-content', nqp::hllizefor($finish-content, 'Raku')); Nil }); add-method(RakuAST::CompUnit, 'mark-sunk', [RakuAST::CompUnit, '', 0, 0], anon sub mark-sunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 217 src/Raku/ast/compunit.rakumod nqp::bindattr_i($SELF, RakuAST::CompUnit, '$!is-sunk', 1); Nil }); add-method(RakuAST::CompUnit, 'is-boundary-sunk', [RakuAST::CompUnit, '', 0, 0], anon sub is-boundary-sunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 222 src/Raku/ast/compunit.rakumod nqp::getattr_i($SELF, RakuAST::CompUnit, '$!is-sunk') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::CompUnit, 'get-boundary-sink-propagator', [RakuAST::CompUnit, '', 0, 0], anon sub get-boundary-sink-propagator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 224 src/Raku/ast/compunit.rakumod nqp::getattr($SELF, RakuAST::CompUnit, '$!statement-list') }); add-method(RakuAST::CompUnit, 'is-eval', [RakuAST::CompUnit, '', 0, 0], anon sub is-eval ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 228 src/Raku/ast/compunit.rakumod nqp::getattr_i($SELF, RakuAST::CompUnit, '$!is-eval') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::CompUnit, 'attach-target-names', [RakuAST::CompUnit, '', 0, 0], anon sub attach-target-names ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 230 src/Raku/ast/compunit.rakumod $SELF.IMPL-WRAP-LIST(['compunit']) }); add-method(RakuAST::CompUnit, 'clear-attachments', [RakuAST::CompUnit, '', 0, 0], anon sub clear-attachments ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 234 src/Raku/ast/compunit.rakumod nqp::setelems(nqp::getattr($SELF, RakuAST::CompUnit, '$!init-phasers'), 0); nqp::setelems(nqp::getattr($SELF, RakuAST::CompUnit, '$!end-phasers'), 0); $SELF.clear-handler-attachments(); Nil }); add-method(RakuAST::CompUnit, 'set-pod-content', [RakuAST::CompUnit, '', 0, 0, int, '$i', 0, 0, Any, '$pod', 0, 0], anon sub set-pod-content ($SELF_CONT, $i!, $pod!) { my $SELF := nqp::decont($SELF_CONT); $i := nqp::decont($i); $pod := nqp::decont($pod); #line 242 src/Raku/ast/compunit.rakumod $i == -1 # don't know where to set, so just push ?? nqp::getattr($SELF, RakuAST::CompUnit, '$!pod-content').push($pod) # set in assigned position !! nqp::getattr($SELF, RakuAST::CompUnit, '$!pod-content').ASSIGN-POS($i,$pod); }); add-method(RakuAST::CompUnit, 'data-content', [RakuAST::CompUnit, '', 0, 0], anon sub data-content ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 252 src/Raku/ast/compunit.rakumod nqp::ifnull( nqp::getattr($SELF, RakuAST::CompUnit, '$!data-content'), nqp::bindattr($SELF,RakuAST::CompUnit,'$!data-content', RakuAST::Doc::Block.Hashray ) ) }); add-method(RakuAST::CompUnit, 'add-phaser', [RakuAST::CompUnit, '', 0, 0, Any, '$phasers', 0, 0, Any, '$phaser', 0, 0], anon sub add-phaser ($SELF_CONT, $phasers!, $phaser!) { my $SELF := nqp::decont($SELF_CONT); $phasers := nqp::decont($phasers); $phaser := nqp::decont($phaser); #line 262 src/Raku/ast/compunit.rakumod # Cannot rely on clear-attachments here as a node's attach can be # called multiple times while going up and down the tree and # clear-attachments will only be called once. for $phasers { return Nil if nqp::eqaddr($_,$phaser); # already added } nqp::push($phasers, $phaser); Nil }); add-method(RakuAST::CompUnit, 'add-init-phaser', [RakuAST::CompUnit, '', 0, 0, RakuAST::StatementPrefix::Phaser::Init, '$phaser', 0, 0], anon sub add-init-phaser ($SELF_CONT, $phaser!) { my $SELF := nqp::decont($SELF_CONT); $phaser := nqp::decont($phaser); #line 273 src/Raku/ast/compunit.rakumod $SELF.add-phaser(nqp::getattr($SELF, RakuAST::CompUnit, '$!init-phasers'), $phaser); }); add-method(RakuAST::CompUnit, 'add-end-phaser', [RakuAST::CompUnit, '', 0, 0, RakuAST::StatementPrefix::Phaser::End, '$phaser', 0, 0], anon sub add-end-phaser ($SELF_CONT, $phaser!) { my $SELF := nqp::decont($SELF_CONT); $phaser := nqp::decont($phaser); #line 277 src/Raku/ast/compunit.rakumod $SELF.add-phaser(nqp::getattr($SELF, RakuAST::CompUnit, '$!end-phasers'), $phaser); }); add-method(RakuAST::CompUnit, 'queue-heredoc', [RakuAST::CompUnit, '', 0, 0, Any, '$herestub', 0, 0], anon sub queue-heredoc ($SELF_CONT, $herestub!) { my $SELF := nqp::decont($SELF_CONT); $herestub := nqp::decont($herestub); #line 281 src/Raku/ast/compunit.rakumod nqp::push(nqp::getattr($SELF, RakuAST::CompUnit, '$!herestub-queue'), $herestub); }); add-method(RakuAST::CompUnit, 'ensure-singleton-whatever', [RakuAST::CompUnit, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub ensure-singleton-whatever ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 285 src/Raku/ast/compunit.rakumod unless nqp::isconcrete(nqp::getattr($SELF, RakuAST::CompUnit, '$!singleton-whatever')) { nqp::bindattr($SELF,RakuAST::CompUnit,'$!singleton-whatever', nqp::create($resolver.setting-constant('Whatever')) ); } Nil }); add-method(RakuAST::CompUnit, 'singleton-whatever', [RakuAST::CompUnit, '', 0, 0], anon sub singleton-whatever ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 294 src/Raku/ast/compunit.rakumod nqp::getattr($SELF, RakuAST::CompUnit, '$!singleton-whatever') }); add-method(RakuAST::CompUnit, 'ensure-singleton-hyper-whatever', [RakuAST::CompUnit, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub ensure-singleton-hyper-whatever ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 296 src/Raku/ast/compunit.rakumod unless nqp::isconcrete(nqp::getattr($SELF, RakuAST::CompUnit, '$!singleton-hyper-whatever')) { nqp::bindattr($SELF,RakuAST::CompUnit,'$!singleton-hyper-whatever', nqp::create($resolver.setting-constant('HyperWhatever')) ); } Nil }); add-method(RakuAST::CompUnit, 'singleton-hyper-whatever', [RakuAST::CompUnit, '', 0, 0], anon sub singleton-hyper-whatever ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 305 src/Raku/ast/compunit.rakumod nqp::getattr($SELF, RakuAST::CompUnit, '$!singleton-hyper-whatever') }); add-method(RakuAST::CompUnit, 'cleanup', [RakuAST::CompUnit, '', 0, 0], anon sub cleanup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 307 src/Raku/ast/compunit.rakumod for nqp::getattr($SELF, RakuAST::CompUnit, '$!context').cleanup-tasks { $_() } }); add-method(RakuAST::CompUnit, 'record-precompilation-dependencies', [RakuAST::CompUnit, '', 0, 0], anon sub record-precompilation-dependencies ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 313 src/Raku/ast/compunit.rakumod nqp::getattr_i($SELF, RakuAST::CompUnit, '$!precompilation-mode') ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::CompUnit, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::CompUnit, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 317 src/Raku/ast/compunit.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier-parts( 'CompUnit', 'RepositoryRegistry', )) ]) }); add-method(RakuAST::CompUnit, 'PRODUCE-IMPLICIT-DECLARATIONS', [RakuAST::CompUnit, '', 0, 0], anon sub PRODUCE-IMPLICIT-DECLARATIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 325 src/Raku/ast/compunit.rakumod my @decls; my sub add(Mu $add) { nqp::push(@decls,$add) } # If we're not in an EVAL, we should produce a GLOBAL package and set # it as the current package. unless nqp::getattr_i($SELF, RakuAST::CompUnit, '$!is-eval') { my $global := RakuAST::Package.new( how => nqp::getattr($SELF, RakuAST::CompUnit, '$!global-package-how'), name => RakuAST::Name.from-identifier('GLOBAL') ); add($global); add(RakuAST::VarDeclaration::Implicit::Constant.new( name => 'GLOBALish', value => $global.compile-time-value )); add(RakuAST::VarDeclaration::Implicit::Constant.new( name => 'EXPORT', value => nqp::getattr($SELF, RakuAST::CompUnit, '$!export-package') )) unless nqp::eqaddr(nqp::getattr($SELF, RakuAST::CompUnit, '$!export-package'),Mu); add(RakuAST::VarDeclaration::Implicit::Constant.new( name => '$?PACKAGE', value => $global.compile-time-value )); add(RakuAST::VarDeclaration::Implicit::Special.new(:name('$/'))); add(RakuAST::VarDeclaration::Implicit::Special.new(:name('$!'))); add(RakuAST::VarDeclaration::Implicit::Special.new(:name('$_'))); } # Various markers add(RakuAST::VarDeclaration::Implicit::Constant.new( name => '!UNIT_MARKER', value => 1 )); #TODO remove this when old frontend is gone add(RakuAST::VarDeclaration::Implicit::Constant.new( name => '!RAKUAST_MARKER', value => 1 )); add(RakuAST::VarDeclaration::Implicit::Constant.new( name => '!EVAL_MARKER', value => 1 )) if nqp::getattr_i($SELF, RakuAST::CompUnit, '$!is-eval'); $SELF.IMPL-WRAP-LIST(@decls) }); add-method(RakuAST::CompUnit, 'IMPL-TO-QAST-COMP-UNIT', [RakuAST::CompUnit, '', 0, 0, Any, '%options', 0, 0], anon sub IMPL-TO-QAST-COMP-UNIT ($SELF_CONT, *%options) { my $SELF := nqp::decont($SELF_CONT); %options := nqp::decont(%options); #line 367 src/Raku/ast/compunit.rakumod # Create compilation context. my $context := nqp::getattr($SELF, RakuAST::CompUnit, '$!context'); my $top-level := $SELF.IMPL-SET-NODE: nqp::getattr($SELF, RakuAST::CompUnit, '$!mainline').IMPL-QAST-FORM-BLOCK($context, :blocktype); $top-level.name(''); $top-level.annotate('IN_DECL', nqp::getattr_i($SELF, RakuAST::CompUnit, '$!is-eval') ?? 'eval' !! 'mainline'); my @pre-deserialize; nqp::push(@pre-deserialize, $SELF.IMPL-SETTING-LOADING-QAST($top-level, nqp::getattr($SELF, RakuAST::CompUnit, '$!setting-name'))) if nqp::getattr($SELF, RakuAST::CompUnit, '$!setting-name'); unless nqp::getattr_i($SELF, RakuAST::CompUnit, '$!is-eval') { my $global_install := QAST::Op.new( :op, QAST::Op.new( :op, QAST::SVal.new(:value('GLOBAL')) ), QAST::Op.new( :op('bindcurhllsym'), QAST::SVal.new( :value('GLOBAL') ), QAST::WVal.new( :value($SELF.generated-global) ) ) ); $context.add-fixup-and-deserialize-task(QAST::Stmt.new($global_install)); } # Compile into a QAST::CompUnit. $top-level.push($SELF.IMPL-TO-QAST($context)); nqp::getattr($SELF, RakuAST::CompUnit, '$!mainline').IMPL-LINK-META-OBJECT($context, $top-level); $SELF.add-phasers-to-code-object(nqp::getattr($SELF, RakuAST::CompUnit, '$!mainline').meta-object); $SELF.add-phasers-handling-code($context, $top-level); if !nqp::getattr_i($SELF, RakuAST::CompUnit, '$!precompilation-mode') && !$*INSIDE-EVAL && +(@*MODULES // []) == 0 && (my $main := $SELF.find-lexical('&MAIN')) { $top-level.set_children([QAST::Op.new( :op('call'), :name('&RUN-MAIN'), QAST::WVal.new(:value($main.meta-object)), QAST::Stmts.new(|$top-level.list) # run the mainline and get its result )]); } QAST::CompUnit.new: $top-level, :hll('Raku'), :sc(nqp::getattr($SELF, RakuAST::CompUnit, '$!sc')), :is_nested(nqp::getattr_i($SELF, RakuAST::CompUnit, '$!is-eval') == 2), :code_ref_blocks($context.code-ref-blocks), :compilation_mode(nqp::getattr_i($SELF, RakuAST::CompUnit, '$!precompilation-mode')), :pre_deserialize(@pre-deserialize), :post_deserialize($context.post-deserialize()), :repo_conflict_resolver(QAST::Op.new( :op('callmethod'), :name('resolve_repossession_conflicts'), $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context) )), # If this unit is loaded as a module, we want it to automatically # execute the mainline code above after all other initializations # have occurred. :load(QAST::Op.new( :op('call'), QAST::BVal.new( :value($top-level) ), )), }); add-method(RakuAST::CompUnit, 'IMPL-SETTING-LOADING-QAST', [RakuAST::CompUnit, '', 0, 0, Mu, '$top-level', 0, 0, Str, '$name', 0, 0], anon sub IMPL-SETTING-LOADING-QAST ($SELF_CONT, $top-level!, $name!) { my $SELF := nqp::decont($SELF_CONT); $top-level := nqp::decont($top-level); $name := nqp::decont($name); #line 435 src/Raku/ast/compunit.rakumod # Use the NQP module loader to load Perl6::ModuleLoader, which # is a normal NQP module. my $module-loading := QAST::Stmt.new( QAST::Op.new( :op('loadbytecode'), QAST::VM.new( :jvm(QAST::SVal.new( :value('ModuleLoader.class') )), :moar(QAST::SVal.new( :value('ModuleLoader.moarvm') )), :js(QAST::SVal.new( :value('ModuleLoader') )) )), QAST::Op.new( :op('callmethod'), :name('load_module'), QAST::Op.new( :op('gethllsym'), QAST::SVal.new( :value('nqp') ), QAST::SVal.new( :value('ModuleLoader') ) ), QAST::SVal.new( :value('Perl6::ModuleLoader') ) )); # Load and put in place the setting after deserialization and on fixup. QAST::Stmt.new( $module-loading, QAST::Op.new( :op('forceouterctx'), QAST::BVal.new( :value($top-level) ), QAST::Op.new( :op('callmethod'), :name('load_setting'), QAST::Op.new( :op('getcurhllsym'), QAST::SVal.new( :value('ModuleLoader') ) ), QAST::SVal.new( :value($name) ) ) )); }); add-method(RakuAST::CompUnit, 'IMPL-TO-QAST', [RakuAST::CompUnit, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 473 src/Raku/ast/compunit.rakumod my $*CU := $SELF; $SELF.IMPL-SET-NODE: QAST::Stmts.new( QAST::Var.new( :name('__args__'), :scope('local'), :decl('param'), :slurpy(1) ), $SELF.IMPL-QAST-DECLS($context), $SELF.IMPL-QAST-INIT-PHASERS($context), $SELF.IMPL-QAST-END-PHASERS($context), $SELF.IMPL-QAST-CTXSAVE($context), $SELF.IMPL-WRAP-SCOPE-HANDLER-QAST($context, nqp::getattr($SELF, RakuAST::CompUnit, '$!statement-list').IMPL-TO-QAST($context)), ) }); add-method(RakuAST::CompUnit, 'IMPL-QAST-INIT-PHASERS', [RakuAST::CompUnit, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-INIT-PHASERS ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 486 src/Raku/ast/compunit.rakumod my $setup := QAST::Stmts.new; for nqp::getattr($SELF, RakuAST::CompUnit, '$!init-phasers') { my $container := $_.container; $context.ensure-sc($container); $setup.push( QAST::Op.new( :op, QAST::WVal.new( :value($container) ), QAST::WVal.new( :value(Scalar) ), QAST::SVal.new( :value('$!value') ), $_.IMPL-CALLISH-QAST($context) ) ); } $setup }); add-method(RakuAST::CompUnit, 'IMPL-QAST-END-PHASERS', [RakuAST::CompUnit, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-END-PHASERS ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 504 src/Raku/ast/compunit.rakumod my $end-setup := QAST::Stmts.new; for nqp::getattr($SELF, RakuAST::CompUnit, '$!end-phasers') { $end-setup.push(QAST::Op.new( :op('callmethod'), :name('unshift'), QAST::Op.new( :op('getcurhllsym'), QAST::SVal.new( :value('@END_PHASERS') ), ), QAST::WVal.new( :value($_.meta-object) ) )); } $end-setup }); add-method(RakuAST::CompUnit, 'IMPL-QAST-CTXSAVE', [RakuAST::CompUnit, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-CTXSAVE ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 519 src/Raku/ast/compunit.rakumod QAST::Stmts.new( QAST::Op.new( :op('bind'), QAST::Var.new( :name('ctxsave'), :scope('local'), :decl('var') ), QAST::Var.new( :name('$*CTXSAVE'), :scope('contextual') ) ), QAST::Op.new( :op('unless'), QAST::Op.new( :op('isnull'), QAST::Var.new( :name('ctxsave'), :scope('local') ) ), QAST::Op.new( :op('if'), QAST::Op.new( :op('can'), QAST::Var.new( :name('ctxsave'), :scope('local') ), QAST::SVal.new( :value('ctxsave') ) ), QAST::Op.new( :op('callmethod'), :name('ctxsave'), QAST::Var.new( :name('ctxsave'), :scope('local') ))))) }); add-method(RakuAST::CompUnit, 'generated-global', [RakuAST::CompUnit, '', 0, 0], anon sub generated-global ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 545 src/Raku/ast/compunit.rakumod nqp::die('No generated global in an EVAL-mode compilation unit') if nqp::getattr_i($SELF, RakuAST::CompUnit, '$!is-eval'); $SELF.IMPL-UNWRAP-LIST($SELF.get-implicit-declarations)[0].compile-time-value }); add-method(RakuAST::CompUnit, 'visit-children', [RakuAST::CompUnit, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 550 src/Raku/ast/compunit.rakumod $visitor(nqp::getattr($SELF, RakuAST::CompUnit, '$!statement-list')); $visitor(nqp::getattr($SELF, RakuAST::CompUnit, '$!pod')) if nqp::getattr($SELF, RakuAST::CompUnit, '$!pod'); $visitor(nqp::getattr($SELF, RakuAST::CompUnit, '$!data')) if nqp::getattr($SELF, RakuAST::CompUnit, '$!data'); $visitor(nqp::getattr($SELF, RakuAST::CompUnit, '$!finish')) if nqp::getattr($SELF, RakuAST::CompUnit, '$!finish'); $visitor(nqp::getattr($SELF, RakuAST::CompUnit, '$!rakudoc')) if nqp::getattr($SELF, RakuAST::CompUnit, '$!rakudoc'); }); #line 10 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'statement-list', [], anon sub statement-list ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!statement-list') }); #line 13 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'setting-name', [], anon sub setting-name ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!setting-name') }); #line 24 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'rakudoc', [], anon sub rakudoc ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!rakudoc') }); #line 30 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'precompilation-mode', [], anon sub precompilation-mode ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::CompUnit, '$!precompilation-mode') }); #line 25 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'pod-content', [], anon sub pod-content ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!pod-content') }); #line 21 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'pod', [], anon sub pod ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!pod') }); #line 11 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'mainline', [], anon sub mainline ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!mainline') }); #line 14 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'language-revision', [], anon sub language-revision ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!language-revision') }); #line 32 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'herestub-queue', [], anon sub herestub-queue ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!herestub-queue') }); #line 27 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'finish-content', [], anon sub finish-content ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!finish-content') }); #line 23 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'finish', [], anon sub finish ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!finish') }); #line 22 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'data', [], anon sub data ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!data') }); #line 33 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'context', [], anon sub context ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!context') }); #line 12 src/Raku/ast/compunit.rakumod add-method(RakuAST::CompUnit, 'comp-unit-name', [], anon sub comp-unit-name ($self) { nqp::getattr(nqp::decont($self), RakuAST::CompUnit, '$!comp-unit-name') }); compose(RakuAST::CompUnit); parent(RakuAST::LiteralBuilder, Any); add-attribute(RakuAST::LiteralBuilder, RakuAST::Resolver, '$!resolver'); add-attribute(RakuAST::LiteralBuilder, Mu, '$!cached-rat'); add-attribute(RakuAST::LiteralBuilder, int, '$!has-cached-rat'); add-attribute(RakuAST::LiteralBuilder, Mu, '$!cached-complex'); add-attribute(RakuAST::LiteralBuilder, int, '$!has-cached-complex'); add-method(RakuAST::LiteralBuilder, 'new', [RakuAST::LiteralBuilder, '', 0, 0, RakuAST::Resolver, '$resolver', 1, 1], anon sub new ($SELF_CONT, :$resolver?) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 567 src/Raku/ast/compunit.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::LiteralBuilder, '$!resolver', $resolver) if $resolver; $obj }); add-method(RakuAST::LiteralBuilder, 'set-resolver', [RakuAST::LiteralBuilder, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub set-resolver ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 573 src/Raku/ast/compunit.rakumod nqp::bindattr($SELF, RakuAST::LiteralBuilder, '$!resolver', $resolver); }); add-method(RakuAST::LiteralBuilder, 'intern-int', [RakuAST::LiteralBuilder, '', 0, 0, str, '$chars', 0, 0, int, '$base', 0, 1, Mu, '$error-reporter', 0, 1], anon sub intern-int ($SELF_CONT, $chars!, $base?, $error-reporter?) { my $SELF := nqp::decont($SELF_CONT); $chars := nqp::decont($chars); $base := nqp::decont($base); $error-reporter := nqp::decont($error-reporter); #line 578 src/Raku/ast/compunit.rakumod # TODO interning $SELF.build-int($chars, $base // 10, $error-reporter) }); add-method(RakuAST::LiteralBuilder, 'build-int', [RakuAST::LiteralBuilder, '', 0, 0, str, '$source', 0, 0, int, '$base', 0, 0, Mu, '$error-reporter', 0, 1], anon sub build-int ($SELF_CONT, $source!, $base!, $error-reporter?) { my $SELF := nqp::decont($SELF_CONT); $source := nqp::decont($source); $base := nqp::decont($base); $error-reporter := nqp::decont($error-reporter); #line 584 src/Raku/ast/compunit.rakumod my $res := nqp::radix_I($base, $source, 0, 2, Int); unless nqp::iseq_i(nqp::unbox_i(nqp::atpos($res, 2)), nqp::chars($source)) { $error-reporter ?? $error-reporter() !! nqp::die("'$source' is not a valid number"); } nqp::atpos($res, 0) }); add-method(RakuAST::LiteralBuilder, 'int-type', [RakuAST::LiteralBuilder, '', 0, 0], anon sub int-type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 595 src/Raku/ast/compunit.rakumod Int }); add-method(RakuAST::LiteralBuilder, 'intern-num', [RakuAST::LiteralBuilder, '', 0, 0, str, '$chars', 0, 0], anon sub intern-num ($SELF_CONT, $chars!) { my $SELF := nqp::decont($SELF_CONT); $chars := nqp::decont($chars); #line 598 src/Raku/ast/compunit.rakumod # TODO interning $SELF.build-num($chars) }); add-method(RakuAST::LiteralBuilder, 'build-num', [RakuAST::LiteralBuilder, '', 0, 0, str, '$chars', 0, 0], anon sub build-num ($SELF_CONT, $chars!) { my $SELF := nqp::decont($SELF_CONT); $chars := nqp::decont($chars); #line 604 src/Raku/ast/compunit.rakumod nqp::box_n(nqp::numify($chars), Num) }); add-method(RakuAST::LiteralBuilder, 'num-type', [RakuAST::LiteralBuilder, '', 0, 0], anon sub num-type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 609 src/Raku/ast/compunit.rakumod Num }); add-method(RakuAST::LiteralBuilder, 'intern-str', [RakuAST::LiteralBuilder, '', 0, 0, str, '$chars', 0, 0], anon sub intern-str ($SELF_CONT, $chars!) { my $SELF := nqp::decont($SELF_CONT); $chars := nqp::decont($chars); #line 612 src/Raku/ast/compunit.rakumod # TODO interning $SELF.build-str($chars) }); add-method(RakuAST::LiteralBuilder, 'build-str', [RakuAST::LiteralBuilder, '', 0, 0, str, '$chars', 0, 0], anon sub build-str ($SELF_CONT, $chars!) { my $SELF := nqp::decont($SELF_CONT); $chars := nqp::decont($chars); #line 618 src/Raku/ast/compunit.rakumod nqp::box_s($chars, Str) }); add-method(RakuAST::LiteralBuilder, 'intern-decimal', [RakuAST::LiteralBuilder, '', 0, 0, Any, '$whole-part', 0, 0, Any, '$fractional-part', 0, 0], anon sub intern-decimal ($SELF_CONT, $whole-part!, $fractional-part!) { my $SELF := nqp::decont($SELF_CONT); $whole-part := nqp::decont($whole-part); $fractional-part := nqp::decont($fractional-part); #line 623 src/Raku/ast/compunit.rakumod # TODO interning $SELF.build-decimal($whole-part, $fractional-part) }); add-method(RakuAST::LiteralBuilder, 'build-decimal', [RakuAST::LiteralBuilder, '', 0, 0, Mu, '$whole-part', 0, 0, Mu, '$fractional-part', 0, 0], anon sub build-decimal ($SELF_CONT, $whole-part!, $fractional-part!) { my $SELF := nqp::decont($SELF_CONT); $whole-part := nqp::decont($whole-part); $fractional-part := nqp::decont($fractional-part); #line 629 src/Raku/ast/compunit.rakumod # Whole part may be provided as an Int already, or may be missing. my $parti; if nqp::isconcrete($whole-part) { if nqp::istype($whole-part, Int) { $parti := $whole-part; } else { $parti := $SELF.intern-int($whole-part); } } else { $parti := $SELF.intern-int('0'); } # Now deal with the fractional part; this may also come as an Int # denominator. my $partf; if nqp::istype($fractional-part, Int) { $partf := $fractional-part; } elsif nqp::chars($fractional-part) { $partf := nqp::radix_I(10, $fractional-part, 0, 4, Int); my $base := nqp::pow_I(nqp::box_i(10, Int), $partf[1], Num, Int); $parti := nqp::mul_I($parti, $base, Int); $parti := nqp::add_I($parti, $partf[0], Int); $partf := $base; } else { $partf := $SELF.intern-int('1'); } $SELF.build-rat($parti, $partf) }); add-method(RakuAST::LiteralBuilder, 'intern-rat', [RakuAST::LiteralBuilder, '', 0, 0, Any, '$numerator', 0, 0, Any, '$denominator', 0, 0], anon sub intern-rat ($SELF_CONT, $numerator!, $denominator!) { my $SELF := nqp::decont($SELF_CONT); $numerator := nqp::decont($numerator); $denominator := nqp::decont($denominator); #line 664 src/Raku/ast/compunit.rakumod # TODO interning $SELF.build-rat($numerator, $denominator) }); add-method(RakuAST::LiteralBuilder, 'build-rat', [RakuAST::LiteralBuilder, '', 0, 0, Mu, '$numerator', 0, 0, Mu, '$denominator', 0, 0], anon sub build-rat ($SELF_CONT, $numerator!, $denominator!) { my $SELF := nqp::decont($SELF_CONT); $numerator := nqp::decont($numerator); $denominator := nqp::decont($denominator); #line 670 src/Raku/ast/compunit.rakumod unless nqp::getattr_i($SELF, RakuAST::LiteralBuilder, '$!has-cached-rat') { nqp::bindattr($SELF,RakuAST::LiteralBuilder,'$!cached-rat', nqp::getattr($SELF, RakuAST::LiteralBuilder, '$!resolver').setting-constant('Rat')); nqp::bindattr_i($SELF,RakuAST::LiteralBuilder,'$!has-cached-rat',1); } nqp::getattr($SELF, RakuAST::LiteralBuilder, '$!cached-rat').new($numerator, $denominator) }); add-method(RakuAST::LiteralBuilder, 'intern-complex', [RakuAST::LiteralBuilder, '', 0, 0, Any, '$real-part', 0, 0, Any, '$imaginary-part', 0, 0], anon sub intern-complex ($SELF_CONT, $real-part!, $imaginary-part!) { my $SELF := nqp::decont($SELF_CONT); $real-part := nqp::decont($real-part); $imaginary-part := nqp::decont($imaginary-part); #line 680 src/Raku/ast/compunit.rakumod # TODO interning $SELF.build-complex($real-part, $imaginary-part) }); add-method(RakuAST::LiteralBuilder, 'build-complex', [RakuAST::LiteralBuilder, '', 0, 0, str, '$real-part', 0, 0, str, '$imaginary-part', 0, 0], anon sub build-complex ($SELF_CONT, $real-part!, $imaginary-part!) { my $SELF := nqp::decont($SELF_CONT); $real-part := nqp::decont($real-part); $imaginary-part := nqp::decont($imaginary-part); #line 686 src/Raku/ast/compunit.rakumod my num $real := $real-part ?? nqp::box_n(nqp::numify($real-part), Num) !! 0e0; my num $imaginary := $imaginary-part ?? nqp::box_n(nqp::numify($imaginary-part), Num) !! 1e0; # Produce the Complex object. unless nqp::getattr_i($SELF, RakuAST::LiteralBuilder, '$!has-cached-complex') { nqp::bindattr($SELF, RakuAST::LiteralBuilder, '$!cached-complex', nqp::getattr($SELF, RakuAST::LiteralBuilder, '$!resolver').setting-constant('Complex')); nqp::bindattr_i($SELF,RakuAST::LiteralBuilder,'$!has-cached-complex',1); } nqp::getattr($SELF, RakuAST::LiteralBuilder, '$!cached-complex').new($real, $imaginary) }); compose(RakuAST::LiteralBuilder); parent(RakuAST::StatementPrefix, RakuAST::Term); add-attribute(RakuAST::StatementPrefix, RakuAST::Blorst, '$!blorst'); add-method(RakuAST::StatementPrefix, 'new', [RakuAST::StatementPrefix, '', 0, 0, RakuAST::Blorst, '$blorst', 0, 0], anon sub new ($SELF_CONT, $blorst!) { my $SELF := nqp::decont($SELF_CONT); $blorst := nqp::decont($blorst); #line 7 src/Raku/ast/statementprefixes.rakumod my $obj := nqp::create($SELF); unless $SELF.allowed-on-for-statement { if nqp::istype($blorst, RakuAST::Statement::For) { nqp::die('Do not use this statement prefix on a RakuAST::Statement::For; ' ~ 'instead, set the mode on that node'); } } nqp::bindattr($obj, RakuAST::StatementPrefix, '$!blorst', $blorst); $obj }); add-method(RakuAST::StatementPrefix, 'allowed-on-for-statement', [RakuAST::StatementPrefix, '', 0, 0], anon sub allowed-on-for-statement ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 19 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); add-method(RakuAST::StatementPrefix, 'IMPL-CALLISH-QAST', [RakuAST::StatementPrefix, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-CALLISH-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 21 src/Raku/ast/statementprefixes.rakumod if nqp::istype(nqp::getattr($SELF, RakuAST::StatementPrefix, '$!blorst'), RakuAST::Block) { nqp::getattr($SELF, RakuAST::StatementPrefix, '$!blorst').IMPL-QAST-BLOCK($context, :blocktype); QAST::Op.new( :op('call'), nqp::getattr($SELF, RakuAST::StatementPrefix, '$!blorst').IMPL-TO-QAST($context) ) } else { nqp::getattr($SELF, RakuAST::StatementPrefix, '$!blorst').IMPL-TO-QAST($context) } }); add-method(RakuAST::StatementPrefix, 'visit-children', [RakuAST::StatementPrefix, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 31 src/Raku/ast/statementprefixes.rakumod $visitor(nqp::getattr($SELF, RakuAST::StatementPrefix, '$!blorst')); }); #line 5 src/Raku/ast/statementprefixes.rakumod add-method(RakuAST::StatementPrefix, 'blorst', [], anon sub blorst ($self) { nqp::getattr(nqp::decont($self), RakuAST::StatementPrefix, '$!blorst') }); compose(RakuAST::StatementPrefix); parent(RakuAST::StatementPrefix::Do, RakuAST::StatementPrefix); parent(RakuAST::StatementPrefix::Do, RakuAST::SinkPropagator); add-method(RakuAST::StatementPrefix::Do, 'type', [RakuAST::StatementPrefix::Do, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 41 src/Raku/ast/statementprefixes.rakumod "do" }); add-method(RakuAST::StatementPrefix::Do, 'propagate-sink', [RakuAST::StatementPrefix::Do, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 43 src/Raku/ast/statementprefixes.rakumod $SELF.blorst.apply-sink($is-sunk); }); add-method(RakuAST::StatementPrefix::Do, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Do, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 47 src/Raku/ast/statementprefixes.rakumod $SELF.IMPL-CALLISH-QAST($context) }); compose(RakuAST::StatementPrefix::Do); parent(RakuAST::StatementPrefix::Quietly, RakuAST::StatementPrefix); parent(RakuAST::StatementPrefix::Quietly, RakuAST::SinkPropagator); add-method(RakuAST::StatementPrefix::Quietly, 'type', [RakuAST::StatementPrefix::Quietly, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 57 src/Raku/ast/statementprefixes.rakumod "quietly" }); add-method(RakuAST::StatementPrefix::Quietly, 'propagate-sink', [RakuAST::StatementPrefix::Quietly, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 59 src/Raku/ast/statementprefixes.rakumod $SELF.blorst.apply-sink($is-sunk); }); add-method(RakuAST::StatementPrefix::Quietly, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Quietly, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 63 src/Raku/ast/statementprefixes.rakumod QAST::Op.new( :op('handle'), $SELF.IMPL-CALLISH-QAST($context), 'WARN', QAST::Op.new( :op('resume'), QAST::Op.new( :op('exception') ) ) ) }); compose(RakuAST::StatementPrefix::Quietly); parent(RakuAST::StatementPrefix::Race, RakuAST::StatementPrefix); add-method(RakuAST::StatementPrefix::Race, 'type', [RakuAST::StatementPrefix::Race, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 77 src/Raku/ast/statementprefixes.rakumod "race" }); add-method(RakuAST::StatementPrefix::Race, 'allowed-on-for-statement', [RakuAST::StatementPrefix::Race, '', 0, 0], anon sub allowed-on-for-statement ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 79 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); add-method(RakuAST::StatementPrefix::Race, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Race, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 81 src/Raku/ast/statementprefixes.rakumod QAST::Op.new( :op('callmethod'), :name('race'), $SELF.IMPL-CALLISH-QAST($context), ) }); compose(RakuAST::StatementPrefix::Race); parent(RakuAST::StatementPrefix::Hyper, RakuAST::StatementPrefix); add-method(RakuAST::StatementPrefix::Hyper, 'type', [RakuAST::StatementPrefix::Hyper, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 93 src/Raku/ast/statementprefixes.rakumod "hyper" }); add-method(RakuAST::StatementPrefix::Hyper, 'allowed-on-for-statement', [RakuAST::StatementPrefix::Hyper, '', 0, 0], anon sub allowed-on-for-statement ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 95 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); add-method(RakuAST::StatementPrefix::Hyper, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Hyper, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 97 src/Raku/ast/statementprefixes.rakumod QAST::Op.new( :op('callmethod'), :name('hyper'), $SELF.IMPL-CALLISH-QAST($context), ) }); compose(RakuAST::StatementPrefix::Hyper); parent(RakuAST::StatementPrefix::Lazy, RakuAST::StatementPrefix); add-method(RakuAST::StatementPrefix::Lazy, 'type', [RakuAST::StatementPrefix::Lazy, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 109 src/Raku/ast/statementprefixes.rakumod "lazy" }); add-method(RakuAST::StatementPrefix::Lazy, 'allowed-on-for-statement', [RakuAST::StatementPrefix::Lazy, '', 0, 0], anon sub allowed-on-for-statement ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 111 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); add-method(RakuAST::StatementPrefix::Lazy, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Lazy, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 113 src/Raku/ast/statementprefixes.rakumod QAST::Op.new( :op('callmethod'), :name('lazy'), $SELF.IMPL-CALLISH-QAST($context), ) }); compose(RakuAST::StatementPrefix::Lazy); parent(RakuAST::StatementPrefix::Eager, RakuAST::StatementPrefix); add-method(RakuAST::StatementPrefix::Eager, 'type', [RakuAST::StatementPrefix::Eager, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 125 src/Raku/ast/statementprefixes.rakumod "eager" }); add-method(RakuAST::StatementPrefix::Eager, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Eager, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 127 src/Raku/ast/statementprefixes.rakumod QAST::Op.new( :op('callmethod'), :name('eager'), $SELF.IMPL-CALLISH-QAST($context), ) }); compose(RakuAST::StatementPrefix::Eager); parent(RakuAST::StatementPrefix::Try, RakuAST::StatementPrefix); parent(RakuAST::StatementPrefix::Try, RakuAST::SinkPropagator); parent(RakuAST::StatementPrefix::Try, RakuAST::ImplicitLookups); add-method(RakuAST::StatementPrefix::Try, 'type', [RakuAST::StatementPrefix::Try, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 141 src/Raku/ast/statementprefixes.rakumod "try" }); add-method(RakuAST::StatementPrefix::Try, 'propagate-sink', [RakuAST::StatementPrefix::Try, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 143 src/Raku/ast/statementprefixes.rakumod $SELF.blorst.apply-sink($is-sunk); }); add-method(RakuAST::StatementPrefix::Try, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::StatementPrefix::Try, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 147 src/Raku/ast/statementprefixes.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Nil')), RakuAST::Var::Lexical.new('$!'), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Failure')), ]) }); add-method(RakuAST::StatementPrefix::Try, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Try, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 155 src/Raku/ast/statementprefixes.rakumod # If it's a block that already has a CATCH handler, just run it. my $blorst := $SELF.blorst; if nqp::istype($blorst, RakuAST::Block) && $blorst.IMPL-HAS-CATCH-HANDLER { $SELF.IMPL-CALLISH-QAST($context) } # Otherwise, need to wrap it in exception handler logic. else { my $lookups := $SELF.get-implicit-lookups; my $nil := $lookups.AT-POS(0).IMPL-TO-QAST($context); my $bang := $lookups.AT-POS(1).IMPL-TO-QAST($context); my $Failure := $lookups.AT-POS(2).IMPL-TO-QAST($context); my $tmp := QAST::Node.unique('fatalizee'); my $qast := $SELF.IMPL-CALLISH-QAST($context); QAST::Op.new( :op('handle'), # Success path puts Nil into $! and evaluates to the block. QAST::Stmt.new( :resultchild(0), QAST::Stmts.new( :resultchild(0), QAST::Op.new( :op('bind'), QAST::Var.new( :name($tmp), :scope('local'), :decl('var') ), $qast ), QAST::Op.new( :op('if'), QAST::Op.new( :op('istype'), QAST::Var.new( :name($tmp), :scope('local') ), $Failure, ), QAST::Op.new( :op('callmethod'), :name('sink'), QAST::Var.new( :name($tmp), :scope('local') ) ) )), QAST::Op.new( :op('p6store'), $bang, $nil ) ), # On failure, capture the exception object into $!. 'CATCH', QAST::Stmts.new( QAST::Op.new( :op('p6store'), $bang, QAST::Op.new( :name<&EXCEPTION>, :op, QAST::Op.new( :op('exception') ) ), ), $nil ) ) } }); compose(RakuAST::StatementPrefix::Try); parent(RakuAST::StatementPrefix::Thunky, RakuAST::StatementPrefix); parent(RakuAST::StatementPrefix::Thunky, RakuAST::Meta); parent(RakuAST::StatementPrefix::Thunky, RakuAST::Code); parent(RakuAST::StatementPrefix::Thunky, RakuAST::BeginTime); add-method(RakuAST::StatementPrefix::Thunky, 'is-begin-performed-before-children', [RakuAST::StatementPrefix::Thunky, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 225 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); add-method(RakuAST::StatementPrefix::Thunky, 'PERFORM-BEGIN', [RakuAST::StatementPrefix::Thunky, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 227 src/Raku/ast/statementprefixes.rakumod $SELF.IMPL-STUB-CODE($resolver, $context); Nil }); add-method(RakuAST::StatementPrefix::Thunky, 'PRODUCE-META-OBJECT', [RakuAST::StatementPrefix::Thunky, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 233 src/Raku/ast/statementprefixes.rakumod if nqp::istype($SELF.blorst, RakuAST::Block) { # Block, already has a meta-object. $SELF.blorst.meta-object } else { # Create code object with default empty signature. my $signature := nqp::create(Signature); nqp::bindattr($signature, Signature, '@!params', nqp::list()); my $code := nqp::create(Code); nqp::bindattr($code, Code, '$!signature', $signature); $code } }); add-method(RakuAST::StatementPrefix::Thunky, 'IMPL-QAST-FORM-BLOCK', [RakuAST::StatementPrefix::Thunky, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-QAST-FORM-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 249 src/Raku/ast/statementprefixes.rakumod if nqp::istype($SELF.blorst, RakuAST::Block) { $SELF.blorst.IMPL-QAST-FORM-BLOCK($context, :$blocktype, :$expression) } else { my $block := QAST::Block.new( :blocktype('declaration_static'), QAST::Stmts.new( $SELF.blorst.IMPL-TO-QAST($context) )); $block.arity(0); $block } }); add-method(RakuAST::StatementPrefix::Thunky, 'IMPL-QAST-BLOCK', [RakuAST::StatementPrefix::Thunky, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-QAST-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 265 src/Raku/ast/statementprefixes.rakumod if nqp::istype($SELF.blorst, RakuAST::Block) { $SELF.blorst.IMPL-QAST-BLOCK($context, :$blocktype, :$expression) } else { unless (nqp::getattr($SELF, RakuAST::Code, '$!qast-block')) { $SELF.IMPL-FINISH-CODE-OBJECT($context, :$blocktype, :$expression); } nqp::getattr($SELF, RakuAST::Code, '$!qast-block') } }); add-method(RakuAST::StatementPrefix::Thunky, 'IMPL-QAST-DECL-CODE', [RakuAST::StatementPrefix::Thunky, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL-CODE ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 277 src/Raku/ast/statementprefixes.rakumod if nqp::istype($SELF.blorst, RakuAST::Block) { # Block already, so we need add nothing. QAST::Op.new( :op('null') ) } else { $SELF.IMPL-QAST-BLOCK($context, :blocktype('declaration_static')) } }); compose(RakuAST::StatementPrefix::Thunky); parent(RakuAST::StatementPrefix::Gather, RakuAST::StatementPrefix::Thunky); parent(RakuAST::StatementPrefix::Gather, RakuAST::SinkPropagator); add-method(RakuAST::StatementPrefix::Gather, 'type', [RakuAST::StatementPrefix::Gather, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 293 src/Raku/ast/statementprefixes.rakumod "gather" }); add-method(RakuAST::StatementPrefix::Gather, 'propagate-sink', [RakuAST::StatementPrefix::Gather, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 295 src/Raku/ast/statementprefixes.rakumod $SELF.blorst.apply-sink((Bool.WHO)); }); add-method(RakuAST::StatementPrefix::Gather, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Gather, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 299 src/Raku/ast/statementprefixes.rakumod QAST::Op.new( :op('call'), :name('&GATHER'), $SELF.IMPL-CLOSURE-QAST($context) ) }); compose(RakuAST::StatementPrefix::Gather); parent(RakuAST::StatementPrefix::Blorst, RakuAST::StatementPrefix::Thunky); parent(RakuAST::StatementPrefix::Blorst, RakuAST::SinkPropagator); parent(RakuAST::StatementPrefix::Blorst, RakuAST::ImplicitBlockSemanticsProvider); add-method(RakuAST::StatementPrefix::Blorst, 'propagate-sink', [RakuAST::StatementPrefix::Blorst, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 310 src/Raku/ast/statementprefixes.rakumod $SELF.blorst.apply-sink((Bool.WHO)); }); add-method(RakuAST::StatementPrefix::Blorst, 'apply-implicit-block-semantics', [RakuAST::StatementPrefix::Blorst, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 314 src/Raku/ast/statementprefixes.rakumod $SELF.blorst.set-fresh-variables(:match, :exception) if nqp::istype($SELF.blorst, RakuAST::Block); }); add-method(RakuAST::StatementPrefix::Blorst, 'IMPL-QAST-FORM-BLOCK', [RakuAST::StatementPrefix::Blorst, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 1], anon sub IMPL-QAST-FORM-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 323 src/Raku/ast/statementprefixes.rakumod if nqp::istype($SELF.blorst, RakuAST::Block) { $SELF.blorst.IMPL-QAST-FORM-BLOCK($context, :$blocktype, :$expression) } else { my $block := QAST::Block.new( :blocktype('declaration_static'), QAST::Stmts.new( RakuAST::VarDeclaration::Implicit::Special.new(:name('$/')).IMPL-QAST-DECL($context), RakuAST::VarDeclaration::Implicit::Special.new(:name('$!')).IMPL-QAST-DECL($context), $SELF.blorst.IMPL-TO-QAST($context) )); $block.arity(0); $block } }); add-method(RakuAST::StatementPrefix::Blorst, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Blorst, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 340 src/Raku/ast/statementprefixes.rakumod QAST::Op.new(:op, :name('&' ~ nqp::uc($SELF.type)), $SELF.IMPL-CLOSURE-QAST($context) ) }); compose(RakuAST::StatementPrefix::Blorst); parent(RakuAST::StatementPrefix::Once, RakuAST::StatementPrefix::Blorst); parent(RakuAST::StatementPrefix::Once, RakuAST::ImplicitDeclarations); add-attribute(RakuAST::StatementPrefix::Once, str, '$!state-name'); add-method(RakuAST::StatementPrefix::Once, 'type', [RakuAST::StatementPrefix::Once, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 355 src/Raku/ast/statementprefixes.rakumod "once" }); add-method(RakuAST::StatementPrefix::Once, 'PRODUCE-IMPLICIT-DECLARATIONS', [RakuAST::StatementPrefix::Once, '', 0, 0], anon sub PRODUCE-IMPLICIT-DECLARATIONS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 357 src/Raku/ast/statementprefixes.rakumod my $state-name := QAST::Node.unique('once_'); nqp::bindattr_s($SELF, RakuAST::StatementPrefix::Once, '$!state-name', $state-name); $SELF.IMPL-WRAP-LIST([ RakuAST::VarDeclaration::Implicit::State.new($state-name) ]) }); add-method(RakuAST::StatementPrefix::Once, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Once, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 366 src/Raku/ast/statementprefixes.rakumod QAST::Op.new(:op, QAST::Op.new(:op, QAST::Op.new(:op), QAST::Op.new(:op, QAST::Var.new(:name(nqp::getattr_s($SELF, RakuAST::StatementPrefix::Once, '$!state-name')), :scope), QAST::Op.new(:op, $SELF.IMPL-CLOSURE-QAST($context)) ), QAST::Var.new(:name(nqp::getattr_s($SELF, RakuAST::StatementPrefix::Once, '$!state-name')), :scope) ) ) }); compose(RakuAST::StatementPrefix::Once); parent(RakuAST::StatementPrefix::Start, RakuAST::StatementPrefix::Blorst); parent(RakuAST::StatementPrefix::Start, RakuAST::ImplicitLookups); add-method(RakuAST::StatementPrefix::Start, 'type', [RakuAST::StatementPrefix::Start, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 385 src/Raku/ast/statementprefixes.rakumod "start" }); add-method(RakuAST::StatementPrefix::Start, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::StatementPrefix::Start, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 387 src/Raku/ast/statementprefixes.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Promise')), RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('True')), ]) }); add-method(RakuAST::StatementPrefix::Start, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Start, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 394 src/Raku/ast/statementprefixes.rakumod my $lookups := $SELF.get-implicit-lookups; my $qast := QAST::Op.new( :op('callmethod'), :name('start'), $lookups.AT-POS(0).IMPL-TO-QAST($context), $SELF.IMPL-CLOSURE-QAST($context) ); unless $context.lang-version eq 'c' { my $true := $lookups.AT-POS(1).IMPL-TO-QAST($context); $true.named('report-broken-if-sunk'); $qast.push($true); } $qast }); compose(RakuAST::StatementPrefix::Start); parent(RakuAST::StatementPrefix::React, RakuAST::StatementPrefix::Blorst); add-method(RakuAST::StatementPrefix::React, 'type', [RakuAST::StatementPrefix::React, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 414 src/Raku/ast/statementprefixes.rakumod "react" }); compose(RakuAST::StatementPrefix::React); parent(RakuAST::StatementPrefix::Supply, RakuAST::StatementPrefix::Blorst); add-method(RakuAST::StatementPrefix::Supply, 'type', [RakuAST::StatementPrefix::Supply, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 421 src/Raku/ast/statementprefixes.rakumod "supply" }); compose(RakuAST::StatementPrefix::Supply); parent(RakuAST::StatementPrefix::Phaser, RakuAST::StatementPrefix); add-method(RakuAST::StatementPrefix::Phaser, 'dump-markers', [RakuAST::StatementPrefix::Phaser, '', 0, 0], anon sub dump-markers ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 428 src/Raku/ast/statementprefixes.rakumod '🛸' }); compose(RakuAST::StatementPrefix::Phaser); parent(RakuAST::StatementPrefix::Phaser::Sinky, RakuAST::StatementPrefix::Phaser); parent(RakuAST::StatementPrefix::Phaser::Sinky, RakuAST::ImplicitLookups); parent(RakuAST::StatementPrefix::Phaser::Sinky, RakuAST::SinkPropagator); add-method(RakuAST::StatementPrefix::Phaser::Sinky, 'propagate-sink', [RakuAST::StatementPrefix::Phaser::Sinky, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 437 src/Raku/ast/statementprefixes.rakumod $SELF.blorst.apply-sink((Bool.WHO)); }); add-method(RakuAST::StatementPrefix::Phaser::Sinky, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::StatementPrefix::Phaser::Sinky, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 441 src/Raku/ast/statementprefixes.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Nil')), ]) }); add-method(RakuAST::StatementPrefix::Phaser::Sinky, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Phaser::Sinky, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 447 src/Raku/ast/statementprefixes.rakumod $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context); }); compose(RakuAST::StatementPrefix::Phaser::Sinky); parent(RakuAST::StatementPrefix::Phaser::Begin, RakuAST::StatementPrefix::Phaser); parent(RakuAST::StatementPrefix::Phaser::Begin, RakuAST::StatementPrefix::Thunky); parent(RakuAST::StatementPrefix::Phaser::Begin, RakuAST::BeginTime); add-attribute(RakuAST::StatementPrefix::Phaser::Begin, Mu, '$!value'); add-method(RakuAST::StatementPrefix::Phaser::Begin, 'type', [RakuAST::StatementPrefix::Phaser::Begin, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 460 src/Raku/ast/statementprefixes.rakumod "BEGIN" }); add-method(RakuAST::StatementPrefix::Phaser::Begin, 'PERFORM-BEGIN', [RakuAST::StatementPrefix::Phaser::Begin, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 463 src/Raku/ast/statementprefixes.rakumod $SELF.IMPL-STUB-CODE($resolver, $context); nqp::bindattr_i($SELF, RakuAST::BeginTime, '$!begin-performed', 1); # avoid infinite loop my $producer := $SELF.IMPL-BEGIN-TIME-EVALUATE($SELF,$resolver,$context); nqp::bindattr($SELF, RakuAST::StatementPrefix::Phaser::Begin, '$!value', $producer()); Nil }); add-method(RakuAST::StatementPrefix::Phaser::Begin, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Phaser::Begin, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 473 src/Raku/ast/statementprefixes.rakumod my $value := nqp::getattr($SELF, RakuAST::StatementPrefix::Phaser::Begin, '$!value'); $context.ensure-sc($value); QAST::WVal.new(:$value) }); compose(RakuAST::StatementPrefix::Phaser::Begin); parent(RakuAST::StatementPrefix::Phaser::Check, RakuAST::StatementPrefix::Phaser); parent(RakuAST::StatementPrefix::Phaser::Check, RakuAST::CheckTime); add-attribute(RakuAST::StatementPrefix::Phaser::Check, Mu, '$!value'); add-method(RakuAST::StatementPrefix::Phaser::Check, 'type', [RakuAST::StatementPrefix::Phaser::Check, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 487 src/Raku/ast/statementprefixes.rakumod "CHECK" }); add-method(RakuAST::StatementPrefix::Phaser::Check, 'new', [RakuAST::StatementPrefix::Phaser::Check, '', 0, 0, RakuAST::Blorst, '$blorst', 0, 0], anon sub new ($SELF_CONT, $blorst!) { my $SELF := nqp::decont($SELF_CONT); $blorst := nqp::decont($blorst); #line 489 src/Raku/ast/statementprefixes.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::StatementPrefix, '$!blorst', $blorst); $obj }); add-method(RakuAST::StatementPrefix::Phaser::Check, 'PERFORM-CHECK', [RakuAST::StatementPrefix::Phaser::Check, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 495 src/Raku/ast/statementprefixes.rakumod my $producer := RakuAST::BeginTime.IMPL-BEGIN-TIME-EVALUATE( nqp::getattr($SELF, RakuAST::StatementPrefix, '$!blorst'), $resolver, $context); nqp::bindattr($SELF, RakuAST::StatementPrefix::Phaser::Check, '$!value', nqp::istype($producer,Code) ?? $producer() !! $producer); Nil }); add-method(RakuAST::StatementPrefix::Phaser::Check, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Phaser::Check, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 505 src/Raku/ast/statementprefixes.rakumod my $value := nqp::getattr($SELF, RakuAST::StatementPrefix::Phaser::Check, '$!value'); $context.ensure-sc($value); QAST::WVal.new(:$value) }); compose(RakuAST::StatementPrefix::Phaser::Check); parent(RakuAST::StatementPrefix::Phaser::Init, RakuAST::StatementPrefix::Phaser); parent(RakuAST::StatementPrefix::Phaser::Init, RakuAST::Attaching); add-attribute(RakuAST::StatementPrefix::Phaser::Init, Scalar, '$!container'); add-method(RakuAST::StatementPrefix::Phaser::Init, 'type', [RakuAST::StatementPrefix::Phaser::Init, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 519 src/Raku/ast/statementprefixes.rakumod "INIT" }); add-method(RakuAST::StatementPrefix::Phaser::Init, 'new', [RakuAST::StatementPrefix::Phaser::Init, '', 0, 0, RakuAST::Blorst, '$blorst', 0, 0], anon sub new ($SELF_CONT, $blorst!) { my $SELF := nqp::decont($SELF_CONT); $blorst := nqp::decont($blorst); #line 521 src/Raku/ast/statementprefixes.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::StatementPrefix, '$!blorst', $blorst); nqp::bindattr($obj, RakuAST::StatementPrefix::Phaser::Init, '$!container', nqp::create(Scalar)); $obj }); add-method(RakuAST::StatementPrefix::Phaser::Init, 'attach', [RakuAST::StatementPrefix::Phaser::Init, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 528 src/Raku/ast/statementprefixes.rakumod $resolver.find-attach-target('compunit').add-init-phaser($SELF); }); add-method(RakuAST::StatementPrefix::Phaser::Init, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Phaser::Init, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 532 src/Raku/ast/statementprefixes.rakumod my $container := nqp::getattr($SELF, RakuAST::StatementPrefix::Phaser::Init, '$!container'); $context.ensure-sc($container); QAST::WVal.new( :value($container) ) }); #line 517 src/Raku/ast/statementprefixes.rakumod add-method(RakuAST::StatementPrefix::Phaser::Init, 'container', [], anon sub container ($self) { nqp::getattr(nqp::decont($self), RakuAST::StatementPrefix::Phaser::Init, '$!container') }); compose(RakuAST::StatementPrefix::Phaser::Init); parent(RakuAST::StatementPrefix::Phaser::Enter, RakuAST::StatementPrefix::Phaser); parent(RakuAST::StatementPrefix::Phaser::Enter, RakuAST::StatementPrefix::Thunky); parent(RakuAST::StatementPrefix::Phaser::Enter, RakuAST::Attaching); add-attribute(RakuAST::StatementPrefix::Phaser::Enter, str, '$!result-name'); add-method(RakuAST::StatementPrefix::Phaser::Enter, 'type', [RakuAST::StatementPrefix::Phaser::Enter, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 547 src/Raku/ast/statementprefixes.rakumod "ENTER" }); add-method(RakuAST::StatementPrefix::Phaser::Enter, 'new', [RakuAST::StatementPrefix::Phaser::Enter, '', 0, 0, RakuAST::Blorst, '$blorst', 0, 0], anon sub new ($SELF_CONT, $blorst!) { my $SELF := nqp::decont($SELF_CONT); $blorst := nqp::decont($blorst); #line 549 src/Raku/ast/statementprefixes.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::StatementPrefix, '$!blorst', $blorst); $obj }); add-method(RakuAST::StatementPrefix::Phaser::Enter, 'attach', [RakuAST::StatementPrefix::Phaser::Enter, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 555 src/Raku/ast/statementprefixes.rakumod nqp::bindattr_s($SELF, RakuAST::StatementPrefix::Phaser::Enter, '$!result-name', ($resolver.find-attach-target('block') // $resolver.find-attach-target('compunit') ).add-enter-phaser($SELF) ); nqp::bindattr($SELF, RakuAST::Code, '$!resolver', $resolver.clone); }); add-method(RakuAST::StatementPrefix::Phaser::Enter, 'IMPL-RESULT-NAME', [RakuAST::StatementPrefix::Phaser::Enter, '', 0, 0], anon sub IMPL-RESULT-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 564 src/Raku/ast/statementprefixes.rakumod nqp::getattr_s($SELF, RakuAST::StatementPrefix::Phaser::Enter, '$!result-name') }); add-method(RakuAST::StatementPrefix::Phaser::Enter, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Phaser::Enter, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 568 src/Raku/ast/statementprefixes.rakumod nqp::die("ENTER phaser not attached but result accessed") unless nqp::getattr_s($SELF, RakuAST::StatementPrefix::Phaser::Enter, '$!result-name'); QAST::Var.new(:name(nqp::getattr_s($SELF, RakuAST::StatementPrefix::Phaser::Enter, '$!result-name')), :scope) }); compose(RakuAST::StatementPrefix::Phaser::Enter); parent(RakuAST::StatementPrefix::Phaser::End, RakuAST::StatementPrefix::Phaser::Sinky); parent(RakuAST::StatementPrefix::Phaser::End, RakuAST::StatementPrefix::Thunky); parent(RakuAST::StatementPrefix::Phaser::End, RakuAST::Attaching); add-method(RakuAST::StatementPrefix::Phaser::End, 'type', [RakuAST::StatementPrefix::Phaser::End, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 580 src/Raku/ast/statementprefixes.rakumod "END" }); add-method(RakuAST::StatementPrefix::Phaser::End, 'attach', [RakuAST::StatementPrefix::Phaser::End, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 582 src/Raku/ast/statementprefixes.rakumod $resolver.find-attach-target('compunit').add-end-phaser($SELF); nqp::bindattr($SELF, RakuAST::Code, '$!resolver', $resolver.clone); }); compose(RakuAST::StatementPrefix::Phaser::End); parent(RakuAST::StatementPrefix::Phaser::Quit, RakuAST::StatementPrefix::Phaser::Sinky); parent(RakuAST::StatementPrefix::Phaser::Quit, RakuAST::Attaching); add-method(RakuAST::StatementPrefix::Phaser::Quit, 'type', [RakuAST::StatementPrefix::Phaser::Quit, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 593 src/Raku/ast/statementprefixes.rakumod "QUIT" }); add-method(RakuAST::StatementPrefix::Phaser::Quit, 'attach', [RakuAST::StatementPrefix::Phaser::Quit, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 595 src/Raku/ast/statementprefixes.rakumod $resolver.find-attach-target('block').add-phaser("QUIT", $SELF); }); add-method(RakuAST::StatementPrefix::Phaser::Quit, 'meta-object', [RakuAST::StatementPrefix::Phaser::Quit, '', 0, 0], anon sub meta-object ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 599 src/Raku/ast/statementprefixes.rakumod $SELF.blorst.meta-object }); compose(RakuAST::StatementPrefix::Phaser::Quit); parent(RakuAST::StatementPrefix::Phaser::Block, RakuAST::StatementPrefix::Phaser::Sinky); parent(RakuAST::StatementPrefix::Phaser::Block, RakuAST::StatementPrefix::Thunky); parent(RakuAST::StatementPrefix::Phaser::Block, RakuAST::Attaching); add-method(RakuAST::StatementPrefix::Phaser::Block, 'attach', [RakuAST::StatementPrefix::Phaser::Block, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 610 src/Raku/ast/statementprefixes.rakumod $resolver.find-attach-target('block').add-phaser( $SELF.type, $SELF, :has-exit-handler($SELF.exit-handler)); nqp::bindattr($SELF, RakuAST::Code, '$!resolver', $resolver.clone); }); add-method(RakuAST::StatementPrefix::Phaser::Block, 'exit-handler', [RakuAST::StatementPrefix::Phaser::Block, '', 0, 0], anon sub exit-handler ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 616 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); compose(RakuAST::StatementPrefix::Phaser::Block); parent(RakuAST::StatementPrefix::Phaser::First, RakuAST::StatementPrefix::Phaser::Block); parent(RakuAST::StatementPrefix::Phaser::First, RakuAST::BeginTime); add-attribute(RakuAST::StatementPrefix::Phaser::First, str, '$!value-var-name'); add-attribute(RakuAST::StatementPrefix::Phaser::First, RakuAST::Blorst, '$!original-blorst'); add-method(RakuAST::StatementPrefix::Phaser::First, 'type', [RakuAST::StatementPrefix::Phaser::First, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 624 src/Raku/ast/statementprefixes.rakumod "FIRST" }); add-method(RakuAST::StatementPrefix::Phaser::First, 'original-blorst', [RakuAST::StatementPrefix::Phaser::First, '', 0, 0], anon sub original-blorst ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 640 src/Raku/ast/statementprefixes.rakumod nqp::getattr($SELF, RakuAST::StatementPrefix::Phaser::First, '$!original-blorst') // nqp::getattr($SELF, RakuAST::StatementPrefix, '$!blorst') }); add-method(RakuAST::StatementPrefix::Phaser::First, 'is-begin-performed-before-children', [RakuAST::StatementPrefix::Phaser::First, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 644 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); add-method(RakuAST::StatementPrefix::Phaser::First, 'is-begin-performed-after-children', [RakuAST::StatementPrefix::Phaser::First, '', 0, 0], anon sub is-begin-performed-after-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 645 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); add-method(RakuAST::StatementPrefix::Phaser::First, 'propagate-sink', [RakuAST::StatementPrefix::Phaser::First, '', 0, 0, Bool, '$is-sunk', 0, 0], anon sub propagate-sink ($SELF_CONT, $is-sunk!) { my $SELF := nqp::decont($SELF_CONT); $is-sunk := nqp::decont($is-sunk); #line 649 src/Raku/ast/statementprefixes.rakumod $SELF.blorst.apply-sink((Bool.WHO)) }); add-method(RakuAST::StatementPrefix::Phaser::First, 'PERFORM-BEGIN', [RakuAST::StatementPrefix::Phaser::First, '', 0, 0, Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 653 src/Raku/ast/statementprefixes.rakumod my $blorst := nqp::getattr($SELF, RakuAST::StatementPrefix, '$!blorst'); nqp::bindattr($SELF, RakuAST::StatementPrefix::Phaser::First, '$!original-blorst', $blorst); my $True := RakuAST::Term::Name.new(RakuAST::Name.from-identifier('True')); my $attach-block := $resolver.find-attach-target('block'); my $trigger-name := QAST::Node.unique('!first_block_triggered'); my $trigger-var := RakuAST::VarDeclaration::Implicit::State.new: $trigger-name; my $trigger-lookup := $trigger-var.generate-lookup; $attach-block.add-generated-lexical-declaration($trigger-var); my $value-name := QAST::Node.unique('!first_block_value'); my $value-var := RakuAST::VarDeclaration::Implicit::State.new: $value-name; my $value-lookup := $value-var.generate-lookup; $attach-block.add-generated-lexical-declaration($value-var); nqp::bindattr_s($SELF, RakuAST::StatementPrefix::Phaser::First, '$!value-var-name', $value-name); $blorst := $blorst.as-block; $blorst := RakuAST::Block.new: :body(RakuAST::Blockoid.new: RakuAST::StatementList.new: RakuAST::Statement::Unless.new: :condition($trigger-lookup), :body(RakuAST::Block.new: :body(RakuAST::Blockoid.new: RakuAST::StatementList.new: RakuAST::Statement::Expression.new( :expression(RakuAST::ApplyInfix.new: :infix(RakuAST::Assignment.new(:item)), :left($value-lookup), :right(RakuAST::ApplyPostfix.new: :postfix(RakuAST::Call::Term.new), :operand($blorst)))), # 🛸 ... the actual FIRST code RakuAST::Statement::Expression.new( :expression(RakuAST::ApplyInfix.new: :infix(RakuAST::Assignment.new(:item)), :left($trigger-lookup), :right($True)))))); nqp::bindattr($SELF, RakuAST::StatementPrefix, '$!blorst', $blorst); }); add-method(RakuAST::StatementPrefix::Phaser::First, 'IMPL-EXPR-QAST', [RakuAST::StatementPrefix::Phaser::First, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 697 src/Raku/ast/statementprefixes.rakumod QAST::Var.new(:name(nqp::getattr_s($SELF, RakuAST::StatementPrefix::Phaser::First, '$!value-var-name')), :scope); }); compose(RakuAST::StatementPrefix::Phaser::First); parent(RakuAST::StatementPrefix::Phaser::Next, RakuAST::StatementPrefix::Phaser::Block); add-method(RakuAST::StatementPrefix::Phaser::Next, 'type', [RakuAST::StatementPrefix::Phaser::Next, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 706 src/Raku/ast/statementprefixes.rakumod "NEXT" }); compose(RakuAST::StatementPrefix::Phaser::Next); parent(RakuAST::StatementPrefix::Phaser::Last, RakuAST::StatementPrefix::Phaser::Block); add-method(RakuAST::StatementPrefix::Phaser::Last, 'type', [RakuAST::StatementPrefix::Phaser::Last, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 713 src/Raku/ast/statementprefixes.rakumod "LAST" }); compose(RakuAST::StatementPrefix::Phaser::Last); parent(RakuAST::StatementPrefix::Phaser::Leave, RakuAST::StatementPrefix::Phaser::Block); add-method(RakuAST::StatementPrefix::Phaser::Leave, 'type', [RakuAST::StatementPrefix::Phaser::Leave, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 720 src/Raku/ast/statementprefixes.rakumod "LEAVE" }); add-method(RakuAST::StatementPrefix::Phaser::Leave, 'exit-handler', [RakuAST::StatementPrefix::Phaser::Leave, '', 0, 0], anon sub exit-handler ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 721 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); compose(RakuAST::StatementPrefix::Phaser::Leave); parent(RakuAST::StatementPrefix::Phaser::Keep, RakuAST::StatementPrefix::Phaser::Block); add-method(RakuAST::StatementPrefix::Phaser::Keep, 'type', [RakuAST::StatementPrefix::Phaser::Keep, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 728 src/Raku/ast/statementprefixes.rakumod "KEEP" }); add-method(RakuAST::StatementPrefix::Phaser::Keep, 'exit-handler', [RakuAST::StatementPrefix::Phaser::Keep, '', 0, 0], anon sub exit-handler ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 729 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); compose(RakuAST::StatementPrefix::Phaser::Keep); parent(RakuAST::StatementPrefix::Phaser::Pre, RakuAST::StatementPrefix::Phaser::Block); add-method(RakuAST::StatementPrefix::Phaser::Pre, 'type', [RakuAST::StatementPrefix::Phaser::Pre, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 737 src/Raku/ast/statementprefixes.rakumod "PRE" }); add-method(RakuAST::StatementPrefix::Phaser::Pre, 'new', [RakuAST::StatementPrefix::Phaser::Pre, '', 0, 0, RakuAST::Blorst, '$blorst', 0, 0, Str, '$condition', 0, 1], anon sub new ($SELF_CONT, $blorst!, $condition?) { my $SELF := nqp::decont($SELF_CONT); $blorst := nqp::decont($blorst); $condition := nqp::decont($condition); #line 739 src/Raku/ast/statementprefixes.rakumod my $obj := nqp::create($SELF); # The PRE phaser needs extra code to get the required # functionality, so this converts a given # foo # into # X::Phaser::PrePost.new(:value(~foo)).throw unless foo nqp::bindattr($obj, RakuAST::StatementPrefix, '$!blorst', RakuAST::Statement::Expression.new( expression => RakuAST::ApplyPostfix.new( operand => RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier-parts( 'X','Phaser','PrePost' ) ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('new'), args => RakuAST::ArgList.new( RakuAST::ColonPair::Value.new( key => 'condition', value => RakuAST::StrLiteral.new( $condition ?? nqp::hllizefor($condition, 'Raku') !! $blorst.origin ?? $blorst.origin.Str !! $blorst.DEPARSE ) ) ) ) ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('throw') ) ), condition-modifier => RakuAST::StatementModifier::Unless.new( nqp::istype($blorst, RakuAST::Block) ?? RakuAST::ApplyPostfix.new( operand => $blorst, postfix => RakuAST::Call::Term.new ) !! $blorst ) ) ); $obj }); compose(RakuAST::StatementPrefix::Phaser::Pre); parent(RakuAST::StatementPrefix::Phaser::Post, RakuAST::StatementPrefix::Phaser::Block); add-method(RakuAST::StatementPrefix::Phaser::Post, 'type', [RakuAST::StatementPrefix::Phaser::Post, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 793 src/Raku/ast/statementprefixes.rakumod "POST" }); add-method(RakuAST::StatementPrefix::Phaser::Post, 'exit-handler', [RakuAST::StatementPrefix::Phaser::Post, '', 0, 0], anon sub exit-handler ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 794 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); add-method(RakuAST::StatementPrefix::Phaser::Post, 'new', [RakuAST::StatementPrefix::Phaser::Post, '', 0, 0, RakuAST::Blorst, '$blorst', 0, 0, Str, '$condition', 0, 1], anon sub new ($SELF_CONT, $blorst!, $condition?) { my $SELF := nqp::decont($SELF_CONT); $blorst := nqp::decont($blorst); $condition := nqp::decont($condition); #line 796 src/Raku/ast/statementprefixes.rakumod my $obj := nqp::create($SELF); # The POST phaser needs extra code to get the required # functionality, so this converts a given # foo # into # { # X::Phaser::PrePost.new(:value(~foo), :phaser).throw # unless foo # } nqp::bindattr($obj, RakuAST::StatementPrefix, '$!blorst', RakuAST::Block.new( body => RakuAST::Blockoid.new( RakuAST::StatementList.new( RakuAST::Statement::Expression.new( expression => RakuAST::ApplyPostfix.new( operand => RakuAST::ApplyPostfix.new( operand => RakuAST::Type::Simple.new( RakuAST::Name.from-identifier-parts( 'X','Phaser','PrePost' ) ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('new'), args => RakuAST::ArgList.new( RakuAST::ColonPair::Value.new( key => 'phaser', value => RakuAST::StrLiteral.new( nqp::hllizefor("POST", 'Raku') ) ), RakuAST::ColonPair::Value.new( key => 'condition', value => RakuAST::StrLiteral.new( $condition ?? nqp::hllizefor($condition, 'Raku') !! $blorst.origin ?? $blorst.origin.Str !! $blorst.DEPARSE ) ) ) ) ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('throw') ) ), condition-modifier => RakuAST::StatementModifier::Unless.new( nqp::istype($blorst, RakuAST::Block) ?? RakuAST::ApplyPostfix.new( operand => $blorst, postfix => RakuAST::Call::Term.new ) !! nqp::istype($blorst, RakuAST::Statement::Expression) ?? $blorst.expression !! $blorst ) ) ) ) ) ); $obj }); compose(RakuAST::StatementPrefix::Phaser::Post); parent(RakuAST::StatementPrefix::Phaser::Undo, RakuAST::StatementPrefix::Phaser::Block); add-method(RakuAST::StatementPrefix::Phaser::Undo, 'type', [RakuAST::StatementPrefix::Phaser::Undo, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 869 src/Raku/ast/statementprefixes.rakumod "UNDO" }); add-method(RakuAST::StatementPrefix::Phaser::Undo, 'exit-handler', [RakuAST::StatementPrefix::Phaser::Undo, '', 0, 0], anon sub exit-handler ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 870 src/Raku/ast/statementprefixes.rakumod (Bool.WHO) }); compose(RakuAST::StatementPrefix::Phaser::Undo); parent(RakuAST::StatementPrefix::Phaser::Close, RakuAST::StatementPrefix::Phaser::Block); add-method(RakuAST::StatementPrefix::Phaser::Close, 'type', [RakuAST::StatementPrefix::Phaser::Close, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 877 src/Raku/ast/statementprefixes.rakumod "CLOSE" }); compose(RakuAST::StatementPrefix::Phaser::Close); parent(RakuAST::StatementModifier, RakuAST::Node); add-attribute(RakuAST::StatementModifier, RakuAST::Expression, '$!expression'); add-method(RakuAST::StatementModifier, 'new', [RakuAST::StatementModifier, '', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub new ($SELF_CONT, $expression!) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); #line 7 src/Raku/ast/statement-mods.rakumod my $obj := nqp::create($SELF); $obj.set-expression($expression); $obj }); add-method(RakuAST::StatementModifier, 'set-expression', [RakuAST::StatementModifier, '', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub set-expression ($SELF_CONT, $expression!) { my $SELF := nqp::decont($SELF_CONT); $expression := nqp::decont($expression); #line 13 src/Raku/ast/statement-mods.rakumod nqp::bindattr($SELF, RakuAST::StatementModifier, '$!expression', $expression // RakuAST::Expression); Nil }); add-method(RakuAST::StatementModifier, 'visit-children', [RakuAST::StatementModifier, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 19 src/Raku/ast/statement-mods.rakumod $visitor(nqp::getattr($SELF, RakuAST::StatementModifier, '$!expression')); }); #line 5 src/Raku/ast/statement-mods.rakumod add-method(RakuAST::StatementModifier, 'expression', [], anon sub expression ($self) { nqp::getattr(nqp::decont($self), RakuAST::StatementModifier, '$!expression') }); compose(RakuAST::StatementModifier); parent(RakuAST::StatementModifier::Condition, RakuAST::StatementModifier); parent(RakuAST::StatementModifier::Condition, RakuAST::ImplicitLookups); add-method(RakuAST::StatementModifier::Condition, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::StatementModifier::Condition, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 29 src/Raku/ast/statement-mods.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Empty')) ]) }); add-method(RakuAST::StatementModifier::Condition, 'IMPL-EMPTY', [RakuAST::StatementModifier::Condition, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EMPTY ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 35 src/Raku/ast/statement-mods.rakumod $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context) }); add-method(RakuAST::StatementModifier::Condition, 'expression-thunk', [RakuAST::StatementModifier::Condition, '', 0, 0], anon sub expression-thunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 39 src/Raku/ast/statement-mods.rakumod RakuAST::StatementModifier::Condition::Thunk.new($SELF) }); compose(RakuAST::StatementModifier::Condition); parent(RakuAST::StatementModifier::If, RakuAST::StatementModifier::Condition); add-method(RakuAST::StatementModifier::If, 'IMPL-WRAP-QAST', [RakuAST::StatementModifier::If, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statement-qast', 0, 0], anon sub IMPL-WRAP-QAST ($SELF_CONT, $context!, $statement-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statement-qast := nqp::decont($statement-qast); #line 48 src/Raku/ast/statement-mods.rakumod QAST::Op.new( :op('if'), $SELF.expression.IMPL-TO-QAST($context), $statement-qast, $SELF.IMPL-EMPTY($context) ) }); compose(RakuAST::StatementModifier::If); parent(RakuAST::StatementModifier::Unless, RakuAST::StatementModifier::Condition); add-method(RakuAST::StatementModifier::Unless, 'IMPL-WRAP-QAST', [RakuAST::StatementModifier::Unless, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statement-qast', 0, 0], anon sub IMPL-WRAP-QAST ($SELF_CONT, $context!, $statement-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statement-qast := nqp::decont($statement-qast); #line 62 src/Raku/ast/statement-mods.rakumod QAST::Op.new( :op('unless'), $SELF.expression.IMPL-TO-QAST($context), $statement-qast, $SELF.IMPL-EMPTY($context) ) }); compose(RakuAST::StatementModifier::Unless); parent(RakuAST::StatementModifier::When, RakuAST::StatementModifier::Condition); add-method(RakuAST::StatementModifier::When, 'IMPL-WRAP-QAST', [RakuAST::StatementModifier::When, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statement-qast', 0, 0], anon sub IMPL-WRAP-QAST ($SELF_CONT, $context!, $statement-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statement-qast := nqp::decont($statement-qast); #line 76 src/Raku/ast/statement-mods.rakumod QAST::Op.new( :op('if'), QAST::Op.new( :op('callmethod'), :name('ACCEPTS'), $SELF.expression.IMPL-TO-QAST($context), QAST::Var.new( :name('$_'), :scope('lexical') ) ), $statement-qast, $SELF.IMPL-EMPTY($context) ) }); compose(RakuAST::StatementModifier::When); parent(RakuAST::StatementModifier::With, RakuAST::StatementModifier::Condition); add-method(RakuAST::StatementModifier::With, 'IMPL-WRAP-QAST', [RakuAST::StatementModifier::With, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statement-qast', 0, 0], anon sub IMPL-WRAP-QAST ($SELF_CONT, $context!, $statement-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statement-qast := nqp::decont($statement-qast); #line 94 src/Raku/ast/statement-mods.rakumod if nqp::istype($statement-qast, QAST::Block) { # It's a block, so just use the `with` compilation. QAST::Op.new( :op('with'), $SELF.expression.IMPL-TO-QAST($context), $statement-qast, $SELF.IMPL-EMPTY($context) ) } else { # A non-block statement. Compile more cheaply by making a temporary # $_ to avoid a wrapping block. my $tested := QAST::Node.unique('with_tested'); QAST::Op.new( :op('if'), QAST::Op.new( :op('callmethod'), :name('defined'), QAST::Op.new( :op('bind'), QAST::Var.new( :name($tested), :scope('local'), :decl('var') ), $SELF.expression.IMPL-TO-QAST($context), ), ), $SELF.IMPL-TEMPORARIZE-TOPIC( QAST::Var.new( :name($tested), :scope('local') ), $statement-qast ), $SELF.IMPL-EMPTY($context) ) } }); compose(RakuAST::StatementModifier::With); parent(RakuAST::StatementModifier::Without, RakuAST::StatementModifier::Condition); add-method(RakuAST::StatementModifier::Without, 'IMPL-WRAP-QAST', [RakuAST::StatementModifier::Without, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statement-qast', 0, 0], anon sub IMPL-WRAP-QAST ($SELF_CONT, $context!, $statement-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statement-qast := nqp::decont($statement-qast); #line 132 src/Raku/ast/statement-mods.rakumod my $tested := QAST::Node.unique('without_tested'); QAST::Op.new( :op('unless'), QAST::Op.new( :op('callmethod'), :name('defined'), QAST::Op.new( :op('bind'), QAST::Var.new( :name($tested), :scope('local'), :decl('var') ), $SELF.expression.IMPL-TO-QAST($context), ), ), $SELF.IMPL-TEMPORARIZE-TOPIC( QAST::Var.new( :name($tested), :scope('local') ), $statement-qast ), $SELF.IMPL-EMPTY($context) ) }); compose(RakuAST::StatementModifier::Without); parent(RakuAST::StatementModifier::Loop, RakuAST::StatementModifier); add-method(RakuAST::StatementModifier::Loop, 'expression-thunk', [RakuAST::StatementModifier::Loop, '', 0, 0], anon sub expression-thunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 157 src/Raku/ast/statement-mods.rakumod Nil }); compose(RakuAST::StatementModifier::Loop); parent(RakuAST::StatementModifier::While, RakuAST::StatementModifier::Loop); add-method(RakuAST::StatementModifier::While, 'IMPL-WRAP-QAST', [RakuAST::StatementModifier::While, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statement-qast', 0, 0, Bool, '$sink', 1, 1], anon sub IMPL-WRAP-QAST ($SELF_CONT, $context!, $statement-qast!, :$sink?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statement-qast := nqp::decont($statement-qast); $sink := nqp::decont($sink); #line 164 src/Raku/ast/statement-mods.rakumod if $sink { QAST::Op.new( :op('while'), $SELF.expression.IMPL-TO-QAST($context), $statement-qast ) } else { nqp::die('non-sink statement modifier while NYI'); } }); compose(RakuAST::StatementModifier::While); parent(RakuAST::StatementModifier::Until, RakuAST::StatementModifier::Loop); add-method(RakuAST::StatementModifier::Until, 'IMPL-WRAP-QAST', [RakuAST::StatementModifier::Until, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statement-qast', 0, 0, Bool, '$sink', 1, 1], anon sub IMPL-WRAP-QAST ($SELF_CONT, $context!, $statement-qast!, :$sink?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statement-qast := nqp::decont($statement-qast); $sink := nqp::decont($sink); #line 182 src/Raku/ast/statement-mods.rakumod if $sink { QAST::Op.new( :op('until'), $SELF.expression.IMPL-TO-QAST($context), $statement-qast ) } else { nqp::die('non-sink statement modifier until NYI'); } }); compose(RakuAST::StatementModifier::Until); parent(RakuAST::StatementModifier::Given, RakuAST::StatementModifier::Loop); add-method(RakuAST::StatementModifier::Given, 'IMPL-WRAP-QAST', [RakuAST::StatementModifier::Given, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statement-qast', 0, 0, Bool, '$sink', 1, 1], anon sub IMPL-WRAP-QAST ($SELF_CONT, $context!, $statement-qast!, :$sink?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statement-qast := nqp::decont($statement-qast); $sink := nqp::decont($sink); #line 200 src/Raku/ast/statement-mods.rakumod $SELF.IMPL-TEMPORARIZE-TOPIC( $SELF.expression.IMPL-TO-QAST($context), $statement-qast ) }); compose(RakuAST::StatementModifier::Given); parent(RakuAST::StatementModifier::For, RakuAST::StatementModifier::Loop); parent(RakuAST::StatementModifier::For, RakuAST::ForLoopImplementation); add-method(RakuAST::StatementModifier::For, 'IMPL-WRAP-QAST', [RakuAST::StatementModifier::For, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$statement-qast', 0, 0, Bool, '$sink', 1, 1], anon sub IMPL-WRAP-QAST ($SELF_CONT, $context!, $statement-qast!, :$sink?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $statement-qast := nqp::decont($statement-qast); $sink := nqp::decont($sink); #line 213 src/Raku/ast/statement-mods.rakumod my $expression := $SELF.expression; my $expression-qast := $expression.IMPL-TO-QAST($context); nqp::istype($expression, RakuAST::QuotedRegex) ?? $SELF.IMPL-TEMPORARIZE-TOPIC( $expression-qast, $SELF.IMPL-FOR-QAST( $context, 'serial', ($sink ?? 'sink' !! 'eager'), $expression-qast, $statement-qast)) !! $SELF.IMPL-FOR-QAST( $context, 'serial', ($sink ?? 'sink' !! 'eager'), $expression-qast, $statement-qast) }); add-method(RakuAST::StatementModifier::For, 'expression-thunk', [RakuAST::StatementModifier::For, '', 0, 0], anon sub expression-thunk ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 234 src/Raku/ast/statement-mods.rakumod RakuAST::StatementModifier::For::Thunk.new }); compose(RakuAST::StatementModifier::For); parent(RakuAST::StatementModifier::For::Thunk, RakuAST::ExpressionThunk); add-method(RakuAST::StatementModifier::For::Thunk, 'IMPL-THUNK-SIGNATURE', [RakuAST::StatementModifier::For::Thunk, '', 0, 0], anon sub IMPL-THUNK-SIGNATURE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 243 src/Raku/ast/statement-mods.rakumod RakuAST::Signature.new(parameters => [ RakuAST::Parameter.new( target => RakuAST::ParameterTarget::Var.new('$_'), traits => [ RakuAST::Trait::Is.new(name => RakuAST::Name.from-identifier('raw')) ] ) ]) }); compose(RakuAST::StatementModifier::For::Thunk); parent(RakuAST::StatementModifier::Condition::Thunk, RakuAST::ExpressionThunk); add-attribute(RakuAST::StatementModifier::Condition::Thunk, RakuAST::StatementModifier::Condition, '$!condition'); add-method(RakuAST::StatementModifier::Condition::Thunk, 'new', [RakuAST::StatementModifier::Condition::Thunk, '', 0, 0, RakuAST::StatementModifier::Condition, '$condition', 0, 0], anon sub new ($SELF_CONT, $condition!) { my $SELF := nqp::decont($SELF_CONT); $condition := nqp::decont($condition); #line 260 src/Raku/ast/statement-mods.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::StatementModifier::Condition::Thunk, '$!condition', $condition); $obj }); add-method(RakuAST::StatementModifier::Condition::Thunk, 'IMPL-THUNK-CODE-QAST', [RakuAST::StatementModifier::Condition::Thunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$target', 0, 0, RakuAST::Expression, '$expression', 0, 0], anon sub IMPL-THUNK-CODE-QAST ($SELF_CONT, $context!, $target!, $expression!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $target := nqp::decont($target); $expression := nqp::decont($expression); #line 267 src/Raku/ast/statement-mods.rakumod #TODO handle inner thunks $target.push(nqp::getattr($SELF, RakuAST::StatementModifier::Condition::Thunk, '$!condition').IMPL-WRAP-QAST($context, $expression.IMPL-EXPR-QAST($context))); }); add-method(RakuAST::StatementModifier::Condition::Thunk, 'IMPL-THUNK-VALUE-QAST', [RakuAST::StatementModifier::Condition::Thunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-THUNK-VALUE-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 273 src/Raku/ast/statement-mods.rakumod Nil }); add-method(RakuAST::StatementModifier::Condition::Thunk, 'is-begin-performed-before-children', [RakuAST::StatementModifier::Condition::Thunk, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 277 src/Raku/ast/statement-mods.rakumod (Bool.WHO) }); add-method(RakuAST::StatementModifier::Condition::Thunk, 'is-begin-performed-after-children', [RakuAST::StatementModifier::Condition::Thunk, '', 0, 0], anon sub is-begin-performed-after-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 278 src/Raku/ast/statement-mods.rakumod (Bool.WHO) }); add-method(RakuAST::StatementModifier::Condition::Thunk, 'PERFORM-BEGIN', [RakuAST::StatementModifier::Condition::Thunk, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 280 src/Raku/ast/statement-mods.rakumod Nil }); add-method(RakuAST::StatementModifier::Condition::Thunk, 'PRODUCE-META-OBJECT', [RakuAST::StatementModifier::Condition::Thunk, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 284 src/Raku/ast/statement-mods.rakumod Nil }); add-method(RakuAST::StatementModifier::Condition::Thunk, 'IMPL-QAST-FORM-BLOCK', [RakuAST::StatementModifier::Condition::Thunk, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, str, '$blocktype', 1, 1, RakuAST::Expression, '$expression', 1, 0], anon sub IMPL-QAST-FORM-BLOCK ($SELF_CONT, $context!, :$blocktype?, :$expression!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $blocktype := nqp::decont($blocktype); $expression := nqp::decont($expression); #line 289 src/Raku/ast/statement-mods.rakumod nqp::die('must not call this ' ~ nqp::getattr($SELF, RakuAST::StatementModifier::Condition::Thunk, '$!condition').dump); }); compose(RakuAST::StatementModifier::Condition::Thunk); parent(RakuAST::Signature, RakuAST::Meta); parent(RakuAST::Signature, RakuAST::ImplicitLookups); parent(RakuAST::Signature, RakuAST::Attaching); parent(RakuAST::Signature, RakuAST::Term); add-attribute(RakuAST::Signature, List, '$!parameters'); add-attribute(RakuAST::Signature, RakuAST::Node, '$!returns'); add-attribute(RakuAST::Signature, int, '$!is-on-method'); add-attribute(RakuAST::Signature, int, '$!is-on-named-method'); add-attribute(RakuAST::Signature, int, '$!is-on-meta-method'); add-attribute(RakuAST::Signature, int, '$!is-on-role-method'); add-attribute(RakuAST::Signature, int, '$!is-on-role-body'); add-attribute(RakuAST::Signature, RakuAST::Package, '$!method-package'); add-attribute(RakuAST::Signature, RakuAST::Parameter, '$!implicit-invocant'); add-attribute(RakuAST::Signature, RakuAST::Parameter, '$!implicit-slurpy-hash'); add-attribute(RakuAST::Signature, Mu, '$!ins_params'); add-method(RakuAST::Signature, 'new', [RakuAST::Signature, '', 0, 0, List, '$parameters', 1, 1, RakuAST::Node, '$returns', 1, 1], anon sub new ($SELF_CONT, :$parameters?, :$returns?) { my $SELF := nqp::decont($SELF_CONT); $parameters := nqp::decont($parameters); $returns := nqp::decont($returns); #line 20 src/Raku/ast/signature.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Signature, '$!parameters', $SELF.IMPL-UNWRAP-LIST($parameters) ) if $parameters; nqp::bindattr($obj, RakuAST::Signature, '$!returns', $returns // RakuAST::Node); nqp::bindattr_i($obj, RakuAST::Signature, '$!is-on-method', 0); nqp::bindattr_i($obj, RakuAST::Signature, '$!is-on-named-method', 0); nqp::bindattr_i($obj, RakuAST::Signature, '$!is-on-meta-method', 0); nqp::bindattr_i($obj, RakuAST::Signature, '$!is-on-role-body', 0); nqp::bindattr_i($obj, RakuAST::Signature, '$!is-on-role-method', 0); $obj }); add-method(RakuAST::Signature, 'parameters', [RakuAST::Signature, '', 0, 0], anon sub parameters ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 34 src/Raku/ast/signature.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Signature, '$!parameters') // []) }); add-method(RakuAST::Signature, 'parameters-initialized', [RakuAST::Signature, '', 0, 0], anon sub parameters-initialized ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 37 src/Raku/ast/signature.rakumod nqp::isconcrete(nqp::getattr($SELF, RakuAST::Signature, '$!parameters')) ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Signature, 'attach', [RakuAST::Signature, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 41 src/Raku/ast/signature.rakumod # If we're the signature for a method... if nqp::getattr_i($SELF, RakuAST::Signature, '$!is-on-method') { # ... retrieve the enclosing package so we can set an implicit # invocant parameter up correctly. nqp::bindattr($SELF, RakuAST::Signature, '$!method-package', $resolver.find-attach-target('package')); } }); add-method(RakuAST::Signature, 'set-is-on-method', [RakuAST::Signature, '', 0, 0, Bool, '$is-on-method', 0, 0], anon sub set-is-on-method ($SELF_CONT, $is-on-method!) { my $SELF := nqp::decont($SELF_CONT); $is-on-method := nqp::decont($is-on-method); #line 51 src/Raku/ast/signature.rakumod # Stash away the fact whether we should generate implicit parameters nqp::bindattr_i($SELF, RakuAST::Signature, '$!is-on-method', $is-on-method ?? 1 !! 0); }); add-method(RakuAST::Signature, 'set-is-on-named-method', [RakuAST::Signature, '', 0, 0, Bool, '$is-on-named-method', 0, 0], anon sub set-is-on-named-method ($SELF_CONT, $is-on-named-method!) { my $SELF := nqp::decont($SELF_CONT); $is-on-named-method := nqp::decont($is-on-named-method); #line 56 src/Raku/ast/signature.rakumod # Stash away the fact whether we should put a type constraint on the implicit invocant nqp::bindattr_i($SELF, RakuAST::Signature, '$!is-on-named-method', $is-on-named-method ?? 1 !! 0); }); add-method(RakuAST::Signature, 'set-is-on-meta-method', [RakuAST::Signature, '', 0, 0, Bool, '$is-on-meta-method', 0, 0], anon sub set-is-on-meta-method ($SELF_CONT, $is-on-meta-method!) { my $SELF := nqp::decont($SELF_CONT); $is-on-meta-method := nqp::decont($is-on-meta-method); #line 61 src/Raku/ast/signature.rakumod # Stash away the fact whether we should put a type constraint on the implicit invocant nqp::bindattr_i($SELF, RakuAST::Signature, '$!is-on-meta-method', $is-on-meta-method ?? 1 !! 0); }); add-method(RakuAST::Signature, 'set-is-on-role-method', [RakuAST::Signature, '', 0, 0, Bool, '$is-on-role-method', 0, 0], anon sub set-is-on-role-method ($SELF_CONT, $is-on-role-method!) { my $SELF := nqp::decont($SELF_CONT); $is-on-role-method := nqp::decont($is-on-role-method); #line 66 src/Raku/ast/signature.rakumod # We need to know this later when drafting the type for the implicit invocant nqp::bindattr_i($SELF, RakuAST::Signature, '$!is-on-role-method', $is-on-role-method ?? 1 !! 0); }); add-method(RakuAST::Signature, 'set-is-on-role-body', [RakuAST::Signature, '', 0, 0, Bool, '$is-on-role-body', 0, 0], anon sub set-is-on-role-body ($SELF_CONT, $is-on-role-body!) { my $SELF := nqp::decont($SELF_CONT); $is-on-role-body := nqp::decont($is-on-role-body); #line 71 src/Raku/ast/signature.rakumod # Stash away the fact whether we should generate implicit parameters nqp::bindattr_i($SELF, RakuAST::Signature, '$!is-on-role-body', $is-on-role-body ?? 1 !! 0); }); add-method(RakuAST::Signature, 'provides-return-value', [RakuAST::Signature, '', 0, 0], anon sub provides-return-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 76 src/Raku/ast/signature.rakumod if nqp::getattr($SELF, RakuAST::Signature, '$!returns') { my $value := $SELF.IMPL-RETURN-VALUE(); nqp::isconcrete($value) || nqp::eqaddr($value, Nil) ?? (Bool.WHO) !! (Bool.WHO) } else { (Bool.WHO) } }); add-method(RakuAST::Signature, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Signature, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 86 src/Raku/ast/signature.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('Mu')), RakuAST::Var::Compiler::Lookup.new('$?CLASS') ]) }); add-method(RakuAST::Signature, 'IMPL-HAS-PARAMETER', [RakuAST::Signature, '', 0, 0, Str, '$name', 0, 0], anon sub IMPL-HAS-PARAMETER ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 93 src/Raku/ast/signature.rakumod return (Bool.WHO) if $name eq '%_' && nqp::getattr($SELF, RakuAST::Signature, '$!implicit-slurpy-hash'); if nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { for nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { return (Bool.WHO) if $_.target && $_.target.lexical-name eq $name; } } (Bool.WHO) }); add-method(RakuAST::Signature, 'IMPL-ENSURE-IMPLICITS', [RakuAST::Signature, '', 0, 0], anon sub IMPL-ENSURE-IMPLICITS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 103 src/Raku/ast/signature.rakumod if nqp::getattr_i($SELF, RakuAST::Signature, '$!is-on-method') && !(nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant') || nqp::getattr($SELF, RakuAST::Signature, '$!implicit-slurpy-hash')) { my @param-asts := nqp::getattr($SELF, RakuAST::Signature, '$!parameters') // []; unless @param-asts && @param-asts[0].invocant { my $type; if nqp::getattr_i($SELF, RakuAST::Signature, '$!is-on-meta-method') { $type := $SELF.get-implicit-lookups.AT-POS(0); } elsif nqp::getattr_i($SELF, RakuAST::Signature, '$!is-on-named-method') { if nqp::isconcrete(nqp::getattr($SELF, RakuAST::Signature, '$!method-package')) { my $Class := $SELF.get-implicit-lookups.AT-POS(1); if nqp::getattr_i($SELF, RakuAST::Signature, '$!is-on-role-method') && $Class.is-resolved { $type := RakuAST::Type::Simple.new(RakuAST::Name.from-identifier('$?CLASS')); $type.set-resolution($Class.resolution); } else { my $package := nqp::getattr($SELF, RakuAST::Signature, '$!method-package').stubbed-meta-object; my $package-name := $package.HOW.name($package); $type := RakuAST::Type::Simple.new(RakuAST::Name.from-identifier($package-name)); $type.set-resolution(RakuAST::VarDeclaration::Implicit::Constant.new( :name($package-name), :value($package), :scope)); } } } nqp::bindattr($SELF, RakuAST::Signature, '$!implicit-invocant', RakuAST::Parameter.new(:invocant, :$type)); } unless nqp::getattr_i($SELF, RakuAST::Signature, '$!is-on-meta-method') { my $slurpy-hash-seen := 0; for @param-asts { if !($_.slurpy =:= RakuAST::Parameter::Slurpy) && $_.target && $_.target.sigil eq '%' { $slurpy-hash-seen := 1; last; } } unless $slurpy-hash-seen { nqp::bindattr($SELF, RakuAST::Signature, '$!implicit-slurpy-hash', RakuAST::Parameter.new( :slurpy(RakuAST::Parameter::Slurpy::Flattened.new), :target(RakuAST::ParameterTarget::Var.new('%_')) ) ); } } } if nqp::getattr_i($SELF, RakuAST::Signature, '$!is-on-role-body') && !nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant') { my @param-asts := nqp::getattr($SELF, RakuAST::Signature, '$!parameters') // []; unless @param-asts && @param-asts[0].invocant { my $invocant := RakuAST::Parameter.new(); $invocant.add-type-capture( RakuAST::Type::Capture.new(RakuAST::Name.from-identifier('$?CLASS')) ); $invocant.add-type-capture( RakuAST::Type::Capture.new(RakuAST::Name.from-identifier('::?CLASS')) ); nqp::bindattr($SELF, RakuAST::Signature, '$!implicit-invocant', $invocant); } } }); add-method(RakuAST::Signature, 'PRODUCE-META-OBJECT', [RakuAST::Signature, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 162 src/Raku/ast/signature.rakumod # Produce meta-objects for each parameter. $SELF.IMPL-ENSURE-IMPLICITS(); my @parameters; if nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant') { @parameters.push(nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant').meta-object); } if nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { for nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { @parameters.push($_.meta-object); } } if nqp::getattr($SELF, RakuAST::Signature, '$!implicit-slurpy-hash') { @parameters.push(nqp::getattr($SELF, RakuAST::Signature, '$!implicit-slurpy-hash').meta-object); } # Build signature object. my $signature := nqp::create(Signature); nqp::bindattr($signature, Signature, '@!params', @parameters); nqp::bindattr_i($signature, Signature, '$!arity', $SELF.arity); nqp::bindattr($signature, Signature, '$!count', $SELF.count); # Figure out and set return type. nqp::bindattr($signature, Signature, '$!returns', nqp::getattr($SELF, RakuAST::Signature, '$!returns') ?? $SELF.IMPL-RETURN-VALUE() !! nqp::null()); $signature }); add-method(RakuAST::Signature, 'IMPL-RETURN-VALUE', [RakuAST::Signature, '', 0, 0], anon sub IMPL-RETURN-VALUE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 192 src/Raku/ast/signature.rakumod if nqp::istype(nqp::getattr($SELF, RakuAST::Signature, '$!returns'), RakuAST::Type) { nqp::getattr($SELF, RakuAST::Signature, '$!returns').resolution.compile-time-value } elsif nqp::istype(nqp::getattr($SELF, RakuAST::Signature, '$!returns'), RakuAST::CompileTimeValue) { nqp::getattr($SELF, RakuAST::Signature, '$!returns').compile-time-value } else { nqp::die('--> return constraint must be a type or a constant value'); } }); add-method(RakuAST::Signature, 'IMPL-TO-QAST', [RakuAST::Signature, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 204 src/Raku/ast/signature.rakumod my $signature := $SELF.meta-object; $context.ensure-sc($signature); QAST::WVal.new(:value($signature)) }); add-method(RakuAST::Signature, 'IMPL-QAST-BINDINGS', [RakuAST::Signature, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '$needs-full-binder', 1, 1], anon sub IMPL-QAST-BINDINGS ($SELF_CONT, $context!, :$needs-full-binder?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $needs-full-binder := nqp::decont($needs-full-binder); #line 210 src/Raku/ast/signature.rakumod $SELF.IMPL-ENSURE-IMPLICITS(); my $bindings := QAST::Stmts.new(); my $parameters := nqp::getattr($SELF, RakuAST::Signature, '$!parameters') // []; if $needs-full-binder { $bindings.push(QAST::Op.new( :op('if'), QAST::Op.new( :op('dispatch'), QAST::SVal.new( :value('boot-syscall') ), QAST::SVal.new( :value('bind-will-resume-on-failure') ) ), QAST::Op.new( :op('assertparamcheck'), QAST::Op.new( :op('p6trybindsig') ) ), QAST::Op.new( :op('p6bindsig') ) )); } else { if nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant') { $bindings.push(nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant').IMPL-TO-QAST($context)); } for $parameters { $bindings.push($_.IMPL-TO-QAST($context)); } if nqp::getattr($SELF, RakuAST::Signature, '$!implicit-slurpy-hash') { $bindings.push(nqp::getattr($SELF, RakuAST::Signature, '$!implicit-slurpy-hash').IMPL-TO-QAST($context)); } } $bindings }); add-method(RakuAST::Signature, 'set-default-type', [RakuAST::Signature, '', 0, 0, RakuAST::Type, '$type', 0, 0], anon sub set-default-type ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 243 src/Raku/ast/signature.rakumod if nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { for nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { $_.set-default-type($type); } } }); add-method(RakuAST::Signature, 'arity', [RakuAST::Signature, '', 0, 0], anon sub arity ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 251 src/Raku/ast/signature.rakumod my int $arity := 0; $arity++ if nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant'); if nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { for nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { last unless $_.is-positional && !$_.is-optional; $arity++; } } nqp::box_i($arity, Int) }); add-method(RakuAST::Signature, 'count', [RakuAST::Signature, '', 0, 0], anon sub count ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 263 src/Raku/ast/signature.rakumod my int $count := 0; $count++ if nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant'); if nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { for nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { if $_.is-positional { $count++; } elsif !($_.slurpy =:= RakuAST::Parameter::Slurpy) && $_.target.sigil ne '%' { return nqp::box_n(nqp::inf, Num); } } } nqp::box_i($count, Int) }); add-method(RakuAST::Signature, 'visit-children', [RakuAST::Signature, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 280 src/Raku/ast/signature.rakumod $visitor(nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant')) if nqp::getattr($SELF, RakuAST::Signature, '$!implicit-invocant'); if nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { for nqp::getattr($SELF, RakuAST::Signature, '$!parameters') { $visitor($_); } } $visitor(nqp::getattr($SELF, RakuAST::Signature, '$!implicit-slurpy-hash')) if nqp::getattr($SELF, RakuAST::Signature, '$!implicit-slurpy-hash'); $visitor(nqp::getattr($SELF, RakuAST::Signature, '$!returns')) if nqp::getattr($SELF, RakuAST::Signature, '$!returns'); }); add-method(RakuAST::Signature, 'IMPL-SIGNATURE-PARAMS', [RakuAST::Signature, '', 0, 0, Mu, '$var', 0, 0], anon sub IMPL-SIGNATURE-PARAMS ($SELF_CONT, $var!) { my $SELF := nqp::decont($SELF_CONT); $var := nqp::decont($var); #line 292 src/Raku/ast/signature.rakumod unless nqp::getattr($SELF, RakuAST::Signature, '$!ins_params') { nqp::bindattr($SELF, RakuAST::Signature, '$!ins_params', QAST::Node.unique('__lowered_parameters_')); $var.push( QAST::Op.new( :op('bind'), QAST::Var.new(:name(nqp::getattr($SELF, RakuAST::Signature, '$!ins_params')), :scope('local'), :decl('var')), QAST::Op.new( # Get @!params on the signature :op('getattr'), QAST::Op.new( # Get signature object :op('getattr'), QAST::Op.new( :op('getcodeobj'), QAST::Op.new( :op('curcode') ) ), QAST::WVal.new(:value(Code)), QAST::SVal.new(:value('$!signature')) ), QAST::WVal.new(:value(Signature)), QAST::SVal.new(:value('@!params')) ) ) ); } QAST::Var.new(:name(nqp::getattr($SELF, RakuAST::Signature, '$!ins_params')), :scope('local')) }); #line 10 src/Raku/ast/signature.rakumod add-method(RakuAST::Signature, 'returns', [], anon sub returns ($self) { nqp::getattr(nqp::decont($self), RakuAST::Signature, '$!returns') }); #line 17 src/Raku/ast/signature.rakumod add-method(RakuAST::Signature, 'implicit-invocant', [], anon sub implicit-invocant ($self) { nqp::getattr(nqp::decont($self), RakuAST::Signature, '$!implicit-invocant') }); compose(RakuAST::Signature); parent(RakuAST::FakeSignature, RakuAST::Meta); parent(RakuAST::FakeSignature, RakuAST::Term); parent(RakuAST::FakeSignature, RakuAST::LexicalScope); add-attribute(RakuAST::FakeSignature, RakuAST::Signature, '$!signature'); add-method(RakuAST::FakeSignature, 'new', [RakuAST::FakeSignature, '', 0, 0, Any, '$signature', 0, 0], anon sub new ($SELF_CONT, $signature!) { my $SELF := nqp::decont($SELF_CONT); $signature := nqp::decont($signature); #line 324 src/Raku/ast/signature.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::FakeSignature, '$!signature', $signature); $obj }); add-method(RakuAST::FakeSignature, 'PRODUCE-META-OBJECT', [RakuAST::FakeSignature, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 330 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::FakeSignature, '$!signature').meta-object }); add-method(RakuAST::FakeSignature, 'IMPL-TO-QAST', [RakuAST::FakeSignature, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 334 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::FakeSignature, '$!signature').IMPL-TO-QAST($context) }); add-method(RakuAST::FakeSignature, 'visit-children', [RakuAST::FakeSignature, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 338 src/Raku/ast/signature.rakumod $visitor(nqp::getattr($SELF, RakuAST::FakeSignature, '$!signature')) }); #line 322 src/Raku/ast/signature.rakumod add-method(RakuAST::FakeSignature, 'signature', [], anon sub signature ($self) { nqp::getattr(nqp::decont($self), RakuAST::FakeSignature, '$!signature') }); compose(RakuAST::FakeSignature); parent(RakuAST::Parameter, RakuAST::Meta); parent(RakuAST::Parameter, RakuAST::Attaching); parent(RakuAST::Parameter, RakuAST::ImplicitLookups); parent(RakuAST::Parameter, RakuAST::TraitTarget); parent(RakuAST::Parameter, RakuAST::BeginTime); parent(RakuAST::Parameter, RakuAST::CheckTime); parent(RakuAST::Parameter, RakuAST::Doc::DeclaratorTarget); add-attribute(RakuAST::Parameter, RakuAST::Type, '$!type'); add-attribute(RakuAST::Parameter, RakuAST::ParameterTarget, '$!target'); add-attribute(RakuAST::Parameter, Mu, '$!names'); add-attribute(RakuAST::Parameter, Bool, '$!invocant'); add-attribute(RakuAST::Parameter, Bool, '$!optional'); add-attribute(RakuAST::Parameter, RakuAST::Parameter::Slurpy, '$!slurpy'); add-attribute(RakuAST::Parameter, RakuAST::Expression, '$!default'); add-attribute(RakuAST::Parameter, RakuAST::Expression, '$!where'); add-attribute(RakuAST::Parameter, RakuAST::Node, '$!owner'); add-attribute(RakuAST::Parameter, RakuAST::Package, '$!package'); add-attribute(RakuAST::Parameter, RakuAST::Signature, '$!sub-signature'); add-attribute(RakuAST::Parameter, List, '$!type-captures'); add-attribute(RakuAST::Parameter, Mu, '$!value'); add-method(RakuAST::Parameter, 'new', [RakuAST::Parameter, '', 0, 0, RakuAST::Type, '$type', 1, 1, RakuAST::ParameterTarget, '$target', 1, 1, List, '$names', 1, 1, Bool, '$invocant', 1, 1, Bool, '$optional', 1, 1, RakuAST::Parameter::Slurpy, '$slurpy', 1, 1, List, '$traits', 1, 1, RakuAST::Expression, '$default', 1, 1, RakuAST::Expression, '$where', 1, 1, RakuAST::Signature, '$sub-signature', 1, 1, List, '$type-captures', 1, 1, Mu, '$value', 1, 1, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$type?, :$target?, :$names?, :$invocant?, :$optional?, :$slurpy?, :$traits?, :$default?, :$where?, :$sub-signature?, :$type-captures?, :$value?, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); $target := nqp::decont($target); $names := nqp::decont($names); $invocant := nqp::decont($invocant); $optional := nqp::decont($optional); $slurpy := nqp::decont($slurpy); $traits := nqp::decont($traits); $default := nqp::decont($default); $where := nqp::decont($where); $sub-signature := nqp::decont($sub-signature); $type-captures := nqp::decont($type-captures); $value := nqp::decont($value); $WHY := nqp::decont($WHY); #line 382 src/Raku/ast/signature.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Parameter, '$!type', $type // RakuAST::Type); $target.set-type($type) if $target && nqp::can($target, 'set-type') && $type; nqp::bindattr($obj, RakuAST::Parameter, '$!target', $target // RakuAST::ParameterTarget); nqp::bindattr($obj, RakuAST::Parameter, '$!names', $SELF.IMPL-NAMES($names)); nqp::bindattr($obj, RakuAST::Parameter, '$!invocant', $invocant ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Parameter, '$!optional', nqp::defined($optional) ?? ($optional ?? (Bool.WHO) !! (Bool.WHO)) !! Bool); nqp::bindattr($obj, RakuAST::Parameter, '$!slurpy', nqp::istype($slurpy, RakuAST::Parameter::Slurpy) ?? $slurpy !! RakuAST::Parameter::Slurpy); $obj.set-traits($traits); nqp::bindattr($obj, RakuAST::Parameter, '$!default', $default // RakuAST::Expression); nqp::bindattr($obj, RakuAST::Parameter, '$!where', $where // RakuAST::Expression); nqp::bindattr($obj, RakuAST::Parameter, '$!sub-signature', $sub-signature // RakuAST::Signature); nqp::bindattr($obj, RakuAST::Parameter, '$!type-captures', nqp::defined($type-captures) ?? $SELF.IMPL-TYPE-CAPTURES($type-captures) !! []); nqp::bindattr($obj, RakuAST::Parameter, '$!value', $value) if nqp::defined($value); $obj.set-WHY($WHY); $obj }); add-method(RakuAST::Parameter, 'set-type', [RakuAST::Parameter, '', 0, 0, RakuAST::Type, '$type', 0, 0], anon sub set-type ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 419 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!type', $type); nqp::getattr($SELF, RakuAST::Parameter, '$!target').set-type($type) if nqp::getattr($SELF, RakuAST::Parameter, '$!target') && nqp::can(nqp::getattr($SELF, RakuAST::Parameter, '$!target'), 'set-type'); Nil }); add-method(RakuAST::Parameter, 'set-default-type', [RakuAST::Parameter, '', 0, 0, RakuAST::Type, '$type', 0, 0], anon sub set-default-type ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 425 src/Raku/ast/signature.rakumod my str $sigil := nqp::getattr($SELF, RakuAST::Parameter, '$!target').sigil; unless $sigil eq '@' || $sigil eq '%' || $sigil eq '&' { nqp::bindattr($SELF, RakuAST::Parameter, '$!type', $type) unless nqp::getattr($SELF, RakuAST::Parameter, '$!type'); } Nil }); add-method(RakuAST::Parameter, 'set-invocant', [RakuAST::Parameter, '', 0, 0, Bool, '$invocant', 0, 0], anon sub set-invocant ($SELF_CONT, $invocant!) { my $SELF := nqp::decont($SELF_CONT); $invocant := nqp::decont($invocant); #line 434 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!invocant', $invocant ?? (Bool.WHO) !! (Bool.WHO)); Nil }); add-method(RakuAST::Parameter, 'set-optional', [RakuAST::Parameter, '', 0, 0], anon sub set-optional ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 439 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!optional', (Bool.WHO)); Nil }); add-method(RakuAST::Parameter, 'set-required', [RakuAST::Parameter, '', 0, 0], anon sub set-required ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 444 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!optional', (Bool.WHO)); Nil }); add-method(RakuAST::Parameter, 'clear-optionality', [RakuAST::Parameter, '', 0, 0], anon sub clear-optionality ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 449 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!optional', Bool); Nil }); add-method(RakuAST::Parameter, 'set-slurpy', [RakuAST::Parameter, '', 0, 0, RakuAST::Parameter::Slurpy, '$slurpy', 0, 0], anon sub set-slurpy ($SELF_CONT, $slurpy!) { my $SELF := nqp::decont($SELF_CONT); $slurpy := nqp::decont($slurpy); #line 454 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!slurpy', $slurpy); Nil }); add-method(RakuAST::Parameter, 'set-names', [RakuAST::Parameter, '', 0, 0, List, '$names', 0, 0], anon sub set-names ($SELF_CONT, $names!) { my $SELF := nqp::decont($SELF_CONT); $names := nqp::decont($names); #line 459 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!names', $SELF.IMPL-NAMES($names)); Nil }); add-method(RakuAST::Parameter, 'add-name', [RakuAST::Parameter, '', 0, 0, Str, '$name', 0, 0], anon sub add-name ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 464 src/Raku/ast/signature.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Parameter, '$!names'), $name); Nil }); add-method(RakuAST::Parameter, 'names', [RakuAST::Parameter, '', 0, 0], anon sub names ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 469 src/Raku/ast/signature.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Parameter, '$!names')) }); add-method(RakuAST::Parameter, 'set-default', [RakuAST::Parameter, '', 0, 0, RakuAST::Expression, '$default', 0, 0], anon sub set-default ($SELF_CONT, $default!) { my $SELF := nqp::decont($SELF_CONT); $default := nqp::decont($default); #line 473 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!default', $default); Nil }); add-method(RakuAST::Parameter, 'set-where', [RakuAST::Parameter, '', 0, 0, RakuAST::Expression, '$where', 0, 0], anon sub set-where ($SELF_CONT, $where!) { my $SELF := nqp::decont($SELF_CONT); $where := nqp::decont($where); #line 478 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!where', $where); Nil }); add-method(RakuAST::Parameter, 'set-value', [RakuAST::Parameter, '', 0, 0, Mu, '$value', 0, 0], anon sub set-value ($SELF_CONT, $value!) { my $SELF := nqp::decont($SELF_CONT); $value := nqp::decont($value); #line 483 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!value', $value); Nil }); add-method(RakuAST::Parameter, 'set-sub-signature', [RakuAST::Parameter, '', 0, 0, RakuAST::Expression, '$sub-signature', 0, 0], anon sub set-sub-signature ($SELF_CONT, $sub-signature!) { my $SELF := nqp::decont($SELF_CONT); $sub-signature := nqp::decont($sub-signature); #line 488 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!sub-signature', $sub-signature); Nil }); add-method(RakuAST::Parameter, 'set-type-captures', [RakuAST::Parameter, '', 0, 0, List, '$type-captures', 0, 0], anon sub set-type-captures ($SELF_CONT, $type-captures!) { my $SELF := nqp::decont($SELF_CONT); $type-captures := nqp::decont($type-captures); #line 493 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!type-captures', $SELF.IMPL-TYPE-CAPTURES($type-captures)); }); add-method(RakuAST::Parameter, 'add-type-capture', [RakuAST::Parameter, '', 0, 0, RakuAST::Type::Capture, '$type-capture', 0, 0], anon sub add-type-capture ($SELF_CONT, $type-capture!) { my $SELF := nqp::decont($SELF_CONT); $type-capture := nqp::decont($type-capture); #line 498 src/Raku/ast/signature.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Parameter, '$!type-captures'), $type-capture); Nil }); add-method(RakuAST::Parameter, 'type-captures', [RakuAST::Parameter, '', 0, 0], anon sub type-captures ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 503 src/Raku/ast/signature.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Parameter, '$!type-captures')) }); add-method(RakuAST::Parameter, 'is-positional', [RakuAST::Parameter, '', 0, 0], anon sub is-positional ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 508 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::Parameter, '$!names') || !(nqp::getattr($SELF, RakuAST::Parameter, '$!slurpy') =:= RakuAST::Parameter::Slurpy) ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::Parameter, 'is-declared-optional', [RakuAST::Parameter, '', 0, 0], anon sub is-declared-optional ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 513 src/Raku/ast/signature.rakumod nqp::eqaddr(nqp::getattr($SELF, RakuAST::Parameter, '$!optional'), (Bool.WHO)) }); add-method(RakuAST::Parameter, 'is-declared-required', [RakuAST::Parameter, '', 0, 0], anon sub is-declared-required ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 518 src/Raku/ast/signature.rakumod nqp::eqaddr(nqp::getattr($SELF, RakuAST::Parameter, '$!optional'), (Bool.WHO)) }); add-method(RakuAST::Parameter, 'is-optional', [RakuAST::Parameter, '', 0, 0], anon sub is-optional ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 525 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::Parameter, '$!optional') // (nqp::getattr($SELF, RakuAST::Parameter, '$!default') || nqp::getattr($SELF, RakuAST::Parameter, '$!names') ?? (Bool.WHO) !! (Bool.WHO)) }); add-method(RakuAST::Parameter, 'IMPL-NAMES', [RakuAST::Parameter, '', 0, 0, Mu, '$names', 0, 0], anon sub IMPL-NAMES ($SELF_CONT, $names!) { my $SELF := nqp::decont($SELF_CONT); $names := nqp::decont($names); #line 529 src/Raku/ast/signature.rakumod my @names; if $names { for $SELF.IMPL-UNWRAP-LIST($names) { if nqp::isstr($_) || nqp::istype($_, Str) { @names.push($_); } else { nqp::die('Parameter names list must be a list of Str'); } } } @names }); add-method(RakuAST::Parameter, 'IMPL-TYPE-CAPTURES', [RakuAST::Parameter, '', 0, 0, Mu, '$type-captures', 0, 0], anon sub IMPL-TYPE-CAPTURES ($SELF_CONT, $type-captures!) { my $SELF := nqp::decont($SELF_CONT); $type-captures := nqp::decont($type-captures); #line 544 src/Raku/ast/signature.rakumod my @type-captures; if $type-captures { for $SELF.IMPL-UNWRAP-LIST($type-captures) { if nqp::istype($_, RakuAST::Type::Capture) { @type-captures.push($_); } else { nqp::die('Parameter type-captures list must be a list of RakuAST::Type::Captures'); } } } @type-captures }); add-method(RakuAST::Parameter, 'attach', [RakuAST::Parameter, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 559 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::Parameter, '$!owner', $resolver.find-attach-target('block')); nqp::bindattr($SELF, RakuAST::Parameter, '$!package', $resolver.find-attach-target('package')); }); add-method(RakuAST::Parameter, 'visit-children', [RakuAST::Parameter, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 566 src/Raku/ast/signature.rakumod $visitor(nqp::getattr($SELF, RakuAST::Parameter, '$!type')) if nqp::getattr($SELF, RakuAST::Parameter, '$!type'); $visitor(nqp::getattr($SELF, RakuAST::Parameter, '$!target')) if nqp::getattr($SELF, RakuAST::Parameter, '$!target'); $visitor(nqp::getattr($SELF, RakuAST::Parameter, '$!default')) if nqp::getattr($SELF, RakuAST::Parameter, '$!default'); $visitor(nqp::getattr($SELF, RakuAST::Parameter, '$!where')) if nqp::getattr($SELF, RakuAST::Parameter, '$!where'); $visitor(nqp::getattr($SELF, RakuAST::Parameter, '$!sub-signature')) if nqp::getattr($SELF, RakuAST::Parameter, '$!sub-signature'); $visitor($SELF.WHY) if $SELF.WHY; }); add-method(RakuAST::Parameter, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Parameter, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 575 src/Raku/ast/signature.rakumod my @lookups; my str $sigil := nqp::getattr($SELF, RakuAST::Parameter, '$!target').sigil; my str $sigil-type; if $sigil eq '@' { nqp::push(@lookups, 'Positional'); nqp::push(@lookups, 'PositionalBindFailover') } elsif $sigil eq '%' { nqp::push(@lookups, 'Associative') } elsif $sigil eq '&' { nqp::push(@lookups, 'Callable') } my @types; for @lookups { nqp::push(@types, RakuAST::Type::Setting.new(RakuAST::Name.from-identifier($_))); } $SELF.IMPL-WRAP-LIST(@types) }); add-method(RakuAST::Parameter, 'PRODUCE-META-OBJECT', [RakuAST::Parameter, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 590 src/Raku/ast/signature.rakumod my $parameter := nqp::create(Parameter); if nqp::getattr($SELF, RakuAST::Parameter, '$!target') { nqp::bindattr_s($parameter, Parameter, '$!variable_name', nqp::getattr($SELF, RakuAST::Parameter, '$!target').introspection-name); } if nqp::getattr($SELF, RakuAST::Parameter, '$!names') { my $names-str-list := nqp::list_s(); for nqp::getattr($SELF, RakuAST::Parameter, '$!names') { nqp::push_s($names-str-list, $_); } nqp::bindattr($parameter, Parameter, '@!named_names', $names-str-list); } nqp::bindattr_i($parameter, Parameter, '$!flags', $SELF.IMPL-FLAGS); my $type := $SELF.IMPL-NOMINAL-TYPE(); nqp::bindattr($parameter, Parameter, '$!type', $type); if nqp::getattr($SELF, RakuAST::Parameter, '$!target') { my $name := nqp::getattr($SELF, RakuAST::Parameter, '$!target').introspection-name; my constant SIG_ELEM_IS_RW := 256; my constant SIG_ELEM_IS_COPY := 512; for $SELF.IMPL-UNWRAP-LIST($SELF.traits) { if nqp::istype($_, RakuAST::Trait::Is) && ($_.name.canonicalize eq 'copy' || $_.name.canonicalize eq 'rw') { my $cd := ContainerDescriptor.new(:of($type), :$name, :default($type), :dynamic(0)); nqp::bindattr($parameter, Parameter, '$!container_descriptor', $cd); last; } } } my @post_constraints; if nqp::getattr($SELF, RakuAST::Parameter, '$!where') { nqp::push(@post_constraints, nqp::getattr($SELF, RakuAST::Parameter, '$!where').IMPL-CURRIED || nqp::getattr($SELF, RakuAST::Parameter, '$!where').meta-object); } if nqp::defined(nqp::getattr($SELF, RakuAST::Parameter, '$!value')) { nqp::push(@post_constraints, nqp::getattr($SELF, RakuAST::Parameter, '$!value')); } if nqp::defined(nqp::getattr($SELF, RakuAST::Parameter, '$!type')) && nqp::getattr($SELF, RakuAST::Parameter, '$!type').meta-object.HOW.archetypes.nominalizable { nqp::push(@post_constraints, nqp::getattr($SELF, RakuAST::Parameter, '$!type').meta-object); } if nqp::elems(@post_constraints) { nqp::bindattr($parameter, Parameter, '@!post_constraints', @post_constraints); } if nqp::getattr($SELF, RakuAST::Parameter, '$!sub-signature') { nqp::bindattr($parameter, Parameter, '$!sub_signature', nqp::getattr($SELF, RakuAST::Parameter, '$!sub-signature').meta-object); } if nqp::getattr($SELF, RakuAST::Parameter, '$!type-captures') { my @type-captures := nqp::list_s; for nqp::getattr($SELF, RakuAST::Parameter, '$!type-captures') { nqp::push_s(@type-captures, $_.lexical-name); } nqp::bindattr($parameter, Parameter, '@!type_captures', @type-captures); } # TODO further setup $parameter }); add-method(RakuAST::Parameter, 'IMPL-FLAGS', [RakuAST::Parameter, '', 0, 0], anon sub IMPL-FLAGS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 645 src/Raku/ast/signature.rakumod my constant SIG_ELEM_INVOCANT := 64; my constant SIG_ELEM_MULTI_INVOCANT := 128; my constant SIG_ELEM_IS_RAW := 1024; my constant SIG_ELEM_IS_OPTIONAL := 2048; my constant SIG_ELEM_ARRAY_SIGIL := 4096; my constant SIG_ELEM_HASH_SIGIL := 8192; my constant SIG_ELEM_UNDEFINED_ONLY := 65536; my constant SIG_ELEM_DEFINED_ONLY := 131072; my constant SIG_ELEM_TYPE_GENERIC := 524288; my constant SIG_ELEM_NATIVE_INT_VALUE := 2097152; my constant SIG_ELEM_NATIVE_UINT_VALUE := 134217728; my constant SIG_ELEM_NATIVE_NUM_VALUE := 4194304; my constant SIG_ELEM_NATIVE_STR_VALUE := 8388608; my constant SIG_ELEM_CODE_SIGIL := 33554432; my constant SIG_ELEM_IS_COERCIVE := 67108864; my $sigil := nqp::getattr($SELF, RakuAST::Parameter, '$!target').sigil; my int $flags; $flags := $flags +| SIG_ELEM_INVOCANT if nqp::getattr($SELF, RakuAST::Parameter, '$!invocant'); $flags := $flags +| SIG_ELEM_MULTI_INVOCANT; $flags := $flags +| SIG_ELEM_IS_OPTIONAL if $SELF.is-optional; if $sigil eq '@' { $flags := $flags +| SIG_ELEM_ARRAY_SIGIL; } elsif $sigil eq '%' { $flags := $flags +| SIG_ELEM_HASH_SIGIL; } elsif $sigil eq '&' { $flags := $flags +| SIG_ELEM_CODE_SIGIL; } if nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!target'), RakuAST::ParameterTarget::Term) { $flags := $flags +| SIG_ELEM_IS_RAW; } if nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!type'), RakuAST::Type::Definedness) { $flags := $flags +| (nqp::getattr($SELF, RakuAST::Parameter, '$!type').definite ?? SIG_ELEM_DEFINED_ONLY !! SIG_ELEM_UNDEFINED_ONLY); } if nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!type'), RakuAST::Type::Coercion) { $flags := $flags +| SIG_ELEM_IS_COERCIVE; } if nqp::getattr($SELF, RakuAST::Parameter, '$!type') { my $meta-object := nqp::getattr($SELF, RakuAST::Parameter, '$!type').meta-object; if $meta-object.HOW.archetypes.generic { $flags := $flags +| SIG_ELEM_TYPE_GENERIC; } my $primspec := nqp::objprimspec(nqp::getattr($SELF, RakuAST::Parameter, '$!type').meta-object); if $primspec == 1 { $flags := $flags +| SIG_ELEM_NATIVE_INT_VALUE; } elsif $primspec == 2 { $flags := $flags +| SIG_ELEM_NATIVE_NUM_VALUE; } elsif $primspec == 3 { $flags := $flags +| SIG_ELEM_NATIVE_STR_VALUE; } elsif $primspec == 10 { $flags := $flags +| SIG_ELEM_NATIVE_UINT_VALUE; } } $flags := $flags +| nqp::getattr($SELF, RakuAST::Parameter, '$!slurpy').IMPL-FLAGS($sigil); $flags }); add-method(RakuAST::Parameter, 'IMPL-NOMINAL-TYPE', [RakuAST::Parameter, '', 0, 0], anon sub IMPL-NOMINAL-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 708 src/Raku/ast/signature.rakumod my str $sigil := nqp::getattr($SELF, RakuAST::Parameter, '$!target').sigil; if $sigil eq '@' || $sigil eq '%' || $sigil eq '&' { my $sigil-type := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; nqp::getattr($SELF, RakuAST::Parameter, '$!type') ?? $sigil-type.HOW.parameterize($sigil-type, nqp::getattr($SELF, RakuAST::Parameter, '$!type').resolution.compile-time-value) !! $sigil-type } else { if nqp::getattr($SELF, RakuAST::Parameter, '$!type') { my $type := nqp::getattr($SELF, RakuAST::Parameter, '$!type').meta-object; my $archetypes := $type.HOW.archetypes; $archetypes.nominal || $archetypes.coercive || $archetypes.generic ?? $type !! $archetypes.nominalizable ?? $type.HOW.nominalize($type) !! $type } else { Mu } } }); add-method(RakuAST::Parameter, 'PERFORM-BEGIN', [RakuAST::Parameter, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 736 src/Raku/ast/signature.rakumod $SELF.apply-traits($resolver, $context, $SELF); if nqp::getattr($SELF, RakuAST::Parameter, '$!where') && (! nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!where'), RakuAST::Code) || nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!where'), RakuAST::RegexThunk)) && !nqp::getattr($SELF, RakuAST::Parameter, '$!where').IMPL-CURRIED { my $block := RakuAST::Block.new( body => RakuAST::Blockoid.new( RakuAST::StatementList.new( RakuAST::Statement::Expression.new( expression => RakuAST::ApplyPostfix.new( operand => RakuAST::ApplyPostfix.new( operand => nqp::getattr($SELF, RakuAST::Parameter, '$!where'), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('ACCEPTS'), args => RakuAST::ArgList.new( RakuAST::Var::Lexical.new('$_'), ), ), ), postfix => RakuAST::Call::Method.new( name => RakuAST::Name.from-identifier('Bool'), ), ), ), ), ), ); $block.IMPL-CHECK($resolver, $context, (Bool.WHO)); nqp::bindattr($SELF, RakuAST::Parameter, '$!where', $block); } }); add-method(RakuAST::Parameter, 'PERFORM-CHECK', [RakuAST::Parameter, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 767 src/Raku/ast/signature.rakumod if nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!owner'), RakuAST::Routine) { my $name := nqp::getattr($SELF, RakuAST::Parameter, '$!owner').name; if $name && $name.is-identifier && $name.canonicalize eq 'MAIN' { for $SELF.IMPL-UNWRAP-LIST($SELF.traits) { if nqp::istype($_, RakuAST::Trait::Is) && $_.name.canonicalize eq 'copy' { $SELF.add-worry: $resolver.build-exception: 'X::AdHoc', payload => "'is rw' on parameters of 'sub MAIN' usually cannot be satisfied.\nDid you mean 'is copy'?"; last; } } } } if nqp::getattr($SELF, RakuAST::Parameter, '$!default') { # Ensure this is something that a default can go on. if nqp::isconcrete(nqp::getattr($SELF, RakuAST::Parameter, '$!slurpy')) { $SELF.add-sorry: $resolver.build-exception: 'X::Parameter::Default', how => 'slurpy', parameter => nqp::getattr($SELF, RakuAST::Parameter, '$!target').name; } if $SELF.is-declared-required { $SELF.add-sorry: $resolver.build-exception: 'X::Parameter::Default', how => 'required', parameter => nqp::getattr($SELF, RakuAST::Parameter, '$!target').name; } # If it doesn't have a compile-time value, we'll need to thunk it. unless nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!default'), RakuAST::CompileTimeValue) { nqp::getattr($SELF, RakuAST::Parameter, '$!default').wrap-with-thunk(RakuAST::ParameterDefaultThunk.new($SELF)); nqp::getattr($SELF, RakuAST::Parameter, '$!default').visit-thunks(-> $thunk { $thunk.ensure-begin-performed($resolver, $context) }); } } if nqp::getattr($SELF, RakuAST::Parameter, '$!sub-signature') { nqp::getattr($SELF, RakuAST::Parameter, '$!owner').set-custom-args; } my $param-obj := $SELF.meta-object; my $param-type := nqp::getattr($param-obj, Parameter, '$!type'); my $ptype-archetypes := $param-type.HOW.archetypes($param-type); my int $is-generic := $ptype-archetypes.generic; my int $is-coercive := $ptype-archetypes.coercive; my int $was-slurpy := !(nqp::getattr($SELF, RakuAST::Parameter, '$!slurpy') =:= RakuAST::Parameter::Slurpy); if $is-generic && $is-coercive && !$was-slurpy && !($param-type =:= Mu) && !$SELF.invocant { nqp::getattr($SELF, RakuAST::Parameter, '$!owner').set-custom-args; } }); add-method(RakuAST::Parameter, 'IMPL-TO-QAST', [RakuAST::Parameter, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 818 src/Raku/ast/signature.rakumod nqp::die('shouldnt get here') if nqp::getattr($SELF, RakuAST::Parameter, '$!sub-signature'); # Flag constants we need to pay attention to. my constant SIG_ELEM_IS_RW := 256; my constant SIG_ELEM_IS_COPY := 512; my constant SIG_ELEM_IS_RAW := 1024; my constant SIG_ELEM_IS_COERCIVE := 67108864; my @iscont-ops := ['iscont', 'iscont_i', 'iscont_n', 'iscont_s', 'iscont_i', 'iscont_i', 'iscont_i', 'iscont_u', 'iscont_u', 'iscont_u', 'iscont_u']; # Get the parameter meta-object, since traits can change some things. my $param-obj := $SELF.meta-object; my int $flags := nqp::getattr_i($param-obj, Parameter, '$!flags'); my int $is-rw := $flags +& SIG_ELEM_IS_RW; my $param-type := nqp::getattr($param-obj, Parameter, '$!type'); my $ptype-archetypes := $param-type.HOW.archetypes($param-type); my int $is-generic := $ptype-archetypes.generic; my int $is-coercive := $ptype-archetypes.coercive; my $nominal-type := !$is-generic && $ptype-archetypes.nominalizable ?? $param-type.HOW.nominalize($param-type) !! $param-type; my int $spec := nqp::objprimspec($nominal-type); # Take the parameter into a temporary local. my $name := QAST::Node.unique("__lowered_param"); my $param-qast := QAST::Var.new( :decl('param'), :scope('local'), :$name ); my $temp-qast-var := QAST::Var.new( :name($name), :scope('local') ); # Deal with nameds and slurpies. my int $was-slurpy; my @prepend; if nqp::getattr($SELF, RakuAST::Parameter, '$!names') { $param-qast.named(nqp::elems(nqp::getattr($SELF, RakuAST::Parameter, '$!names')) == 1 ?? nqp::getattr($SELF, RakuAST::Parameter, '$!names')[0] !! nqp::getattr($SELF, RakuAST::Parameter, '$!names')); } elsif !(nqp::getattr($SELF, RakuAST::Parameter, '$!slurpy') =:= RakuAST::Parameter::Slurpy) { nqp::getattr($SELF, RakuAST::Parameter, '$!slurpy').IMPL-TRANSFORM-PARAM-QAST($context, $param-qast, $temp-qast-var, nqp::getattr($SELF, RakuAST::Parameter, '$!target').sigil, @prepend); $was-slurpy := 1; } # HLLize before type checking unless it was a slurpy (in which # case we know full well what we produced) or it's a native type if !$was-slurpy && ($is-generic || !$spec) { $param-qast.push(QAST::Op.new( :op('bind'), $temp-qast-var, QAST::Op.new( :op('hllize'), $temp-qast-var ) )); } # We may need to decontainerize it; produce that lazily if so. my $decont-qast-var := $was-slurpy ?? $temp-qast-var !! Nil; my $get-decont-var := -> { unless $decont-qast-var { my str $name := QAST::Node.unique("__decont_param"); $param-qast.push(QAST::Op.new( :op('bind'), QAST::Var.new( :$name, :scope('local'), :decl('var') ), QAST::Op.new( :op('decont'), $temp-qast-var ) )); $decont-qast-var := QAST::Var.new( :$name, :scope('local') ); } $decont-qast-var } # Add type checks. if !$is-generic && $spec { if $is-rw { $param-qast.push(QAST::ParamTypeCheck.new(QAST::Op.new( :op(@iscont-ops[$spec]), $temp-qast-var ))); } else { $context.ensure-sc($param-type); $param-qast.returns($param-type); } } elsif !$was-slurpy { # Type-check, unless it's Mu, in which case skip it. if $is-generic && !$is-coercive { my $genericname := $param-type.HOW.name(nqp::getattr($SELF, RakuAST::Parameter, '$!package').stubbed-meta-object); $param-qast.push(QAST::ParamTypeCheck.new(QAST::Op.new( :op('istype_nd'), $get-decont-var(), QAST::Var.new( :name($genericname), :scope ) ))); } elsif !($param-type =:= Mu) { if !$ptype-archetypes.generic { if nqp::getattr($SELF, RakuAST::Parameter, '$!target').sigil eq '@' { my $PositionalBindFailover := $SELF.get-implicit-lookups.AT-POS(1).resolution.compile-time-value; $param-qast.push(QAST::Op.new( :op('if'), QAST::Op.new( :op('istype_nd'), $get-decont-var(), QAST::WVal.new( :value($PositionalBindFailover) ) ), QAST::Op.new( :op('bind'), $get-decont-var(), QAST::Op.new( :op('decont'), QAST::Op.new( :op('bind'), $temp-qast-var, QAST::Op.new( :op('callmethod'), :name('cache'), $get-decont-var() )))))); } # Try to be smarter with coercions. We don't have to do full typecheck on them, which results in # additional call to a HOW method. Instead it's ok to check if value matches target or # constraint types. if $is-coercive && nqp::can($param-type.HOW, 'target_type') { my $constraint-type := $param-type.HOW.constraint_type($param-type); $context.ensure-sc($constraint-type); $param-qast.push(QAST::ParamTypeCheck.new(QAST::Op.new( :op('unless'), QAST::Op.new( :op('istype_nd'), $get-decont-var(), QAST::WVal.new( :value($param-type.HOW.target_type($param-type) ))), QAST::Op.new( :op('istype_nd'), $get-decont-var(), QAST::WVal.new( :value($constraint-type)))))); } else { $context.ensure-sc($param-type); $param-qast.push(QAST::ParamTypeCheck.new(QAST::Op.new( :op('istype_nd'), $get-decont-var(), QAST::WVal.new( :value($param-type) ) ))); } } } if nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!type').IMPL-TARGET-TYPE, RakuAST::Type::Definedness) { if nqp::getattr($SELF, RakuAST::Parameter, '$!type').IMPL-TARGET-TYPE.definite { $param-qast.push(QAST::ParamTypeCheck.new(QAST::Op.new( :op('isconcrete_nd'), $get-decont-var() ))); } else { $param-qast.push(QAST::ParamTypeCheck.new(QAST::Op.new( :op('not_i'), QAST::Op.new( :op('isconcrete_nd'), $get-decont-var() )))); } } # If marked `is rw`, do rw check. if $is-rw { $param-qast.push(QAST::ParamTypeCheck.new(QAST::Op.new( :op('isrwcont'), $temp-qast-var, ))); } } my $inst-param; # Make sure we have (possibly instantiated) parameter object ready when we need it if $is-generic || nqp::getattr($SELF, RakuAST::Parameter, '$!sub-signature') { my $inst-param-name := QAST::Node.unique('__lowered_param_obj_'); my $i := 0; #FIXME TODO XXX Need a way to know which parameter this is in the signature! $param-qast.push( # Fetch instantiated Parameter object QAST::Op.new( :op('bind'), QAST::Var.new( :name($inst-param-name), :scope('local'), :decl('var') ), QAST::Op.new( :op('atpos'), nqp::getattr($SELF, RakuAST::Parameter, '$!owner').signature.IMPL-SIGNATURE-PARAMS($param-qast), QAST::IVal.new(:value($i))))); $inst-param := QAST::Var.new(:name($inst-param-name), :scope); } # Handle coercion. # For a generic we can't know beforehand if it's going to be a coercive or any other nominalizable. Thus # we have to fetch the instantiated parameter object and do run-time processing. if $is-generic { # For a generic-typed parameter get its instantiated clone and see if its type is a coercion. $get-decont-var := -> { NQPMu } my $low-param-type := QAST::Node.unique('__lowered_param_type'); $param-qast.push( # Get actual parameter type QAST::Op.new( :op('bind'), QAST::Var.new(:name($low-param-type), :scope('local'), :decl('var')), QAST::Op.new( :op('getattr'), $inst-param, QAST::WVal.new(:value(Parameter)), QAST::SVal.new(:value('$!type'))))); $param-qast.push( QAST::Op.new( :op('if'), QAST::Op.new( :op('istype'), $temp-qast-var, QAST::Var.new(:name($low-param-type), :scope('local')) ), QAST::Op.new( :op('if'), QAST::Op.new( :op('bitand_i'), QAST::Op.new( :op('getattr'), $inst-param, QAST::WVal.new(:value(Parameter)), QAST::SVal.new(:value('$!flags')) ), QAST::IVal.new(:value(SIG_ELEM_IS_COERCIVE)) ), QAST::Op.new( :op('bind'), $temp-qast-var, QAST::Op.new( :op, QAST::SVal.new(:value), QAST::Var.new(:name($low-param-type), :scope), $temp-qast-var))))); } elsif $is-coercive { $get-decont-var := -> { NQPMu } my $coercion-type := $param-type.HOW.wrappee($param-type, :coercion); my $target-type := $coercion-type.HOW.target_type($coercion-type); $context.ensure-sc($param-type); $context.ensure-sc($target-type); $param-qast.push( QAST::Op.new( :op('unless'), QAST::Op.new( :op('istype'), $temp-qast-var, QAST::WVal.new( :value($target-type) ) ), QAST::Op.new( :op('bind'), $temp-qast-var, QAST::Op.new( :op, QAST::SVal.new(:value), QAST::WVal.new(:value($param-type)), $temp-qast-var)))); } # If it's optional, do any default handling. if $SELF.is-optional { if nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!default'), RakuAST::CompileTimeValue) { # Literal default value, so just insert it. $param-qast.default(nqp::getattr($SELF, RakuAST::Parameter, '$!default').IMPL-TO-QAST($context)); } elsif nqp::getattr($SELF, RakuAST::Parameter, '$!default') { # Default has been thunked, so call the produced thunk. $param-qast.default(QAST::Op.new( :op('call'), nqp::getattr($SELF, RakuAST::Parameter, '$!default').IMPL-TO-QAST($context) )); } else { my $sigil := nqp::getattr($SELF, RakuAST::Parameter, '$!target').sigil; if (my $is-array := $sigil eq '@') || $sigil eq '%' { my $role := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; my $base-type := $is-array ?? Array !! Hash; my $value := nqp::istype($nominal-type, $role) && nqp::can($nominal-type.HOW, 'role_arguments') ?? $base-type.HOW.parameterize($base-type, |$nominal-type.HOW.role_arguments($nominal-type)) !! $base-type; $context.ensure-sc($value); $param-qast.default( QAST::Op.new( :op, QAST::WVal.new(value => $value) ) ); } else { if $spec == 1 { $param-qast.default(QAST::IVal.new( :value(0) )); } elsif $spec == 2 { $param-qast.default(QAST::NVal.new( :value(0.0) )); } elsif $spec == 3 { $param-qast.default(QAST::SVal.new( :value('') )); } elsif $spec == 10 { $param-qast.default(QAST::IVal.new( :value(0) )); } else { $param-qast.default(QAST::WVal.new( :value($nominal-type) )); } } } } if nqp::defined(nqp::getattr($SELF, RakuAST::Parameter, '$!value')) { my $value := nqp::getattr($SELF, RakuAST::Parameter, '$!value'); my $wval := QAST::WVal.new: :value($value); $context.ensure-sc($value); my $type := nqp::getattr($SELF, RakuAST::Parameter, '$!type').name.canonicalize; $param-qast.push: QAST::ParamTypeCheck.new: $type eq 'Int' ?? QAST::Op.new(:op, QAST::Op.new(:op, $temp-qast-var), QAST::Op.new(:op, $wval, QAST::Op.new: :op, $temp-qast-var)) !! $type eq 'Num' ?? QAST::Op.new(:op, QAST::Op.new(:op, $temp-qast-var), QAST::Op.new(:op, QAST::Op.new(:op, $wval, $temp-qast-var), # equal QAST::Op.new(:op, # or both are NaNs QAST::Op.new(:op, $wval, $wval), QAST::Op.new(:op, $temp-qast-var, $temp-qast-var)))) !! QAST::Op.new(:op, QAST::Op.new(:op, $temp-qast-var), QAST::Op.new(:op, $wval, $temp-qast-var)); } $context.ensure-sc(nqp::getattr($param-obj, Parameter, '$!container_descriptor')); # Bind parameter into its target. if $SELF.invocant { $param-qast.push(QAST::Op.new( :op('bind'), QAST::Var.new( :name('self'), :scope('lexical') ), $get-decont-var() // QAST::Op.new( :op('decont'), $temp-qast-var, ))); } if nqp::isconcrete(nqp::getattr($SELF, RakuAST::Parameter, '$!target')) { if $flags +& (SIG_ELEM_IS_RW +| SIG_ELEM_IS_RAW) { # Don't do any decontainerization (rw or raw). $param-qast.push(nqp::getattr($SELF, RakuAST::Parameter, '$!target').IMPL-BIND-QAST($context, $temp-qast-var)); } else { my $value := $get-decont-var() // $temp-qast-var; if $flags +& SIG_ELEM_IS_COPY { my $sigil := nqp::getattr($SELF, RakuAST::Parameter, '$!target').sigil; if (my $is-array := $sigil eq '@') || $sigil eq '%' { my $copy-var := $name ~ '_copy'; $param-qast.push( QAST::Op.new( :op, QAST::Var.new( :name($copy-var), :scope, :decl ), QAST::Op.new( :op, QAST::WVal.new( :value($is-array ?? Array !! Hash) ) ) ) ); $param-qast.push( QAST::Op.new( :op, :name, QAST::Var.new( :name($copy-var), :scope ), $value ) ); $value := QAST::Var.new( :name($copy-var), :scope ); } else { my $container_descriptor := $param-obj.container_descriptor; if $container_descriptor { $value := QAST::Op.new( :op, QAST::WVal.new(:value($container_descriptor)), $value ); } else { $value := QAST::Op.new( :op('p6bindattrinvres'), QAST::Op.new( :op('create'), QAST::WVal.new( :value(Scalar) ) ), QAST::WVal.new( :value(Scalar) ), QAST::SVal.new( :value('$!value') ), $value ); } } } # Give the decontainerized thing. $param-qast.push(nqp::getattr($SELF, RakuAST::Parameter, '$!target').IMPL-BIND-QAST($context, $value)); } } for nqp::getattr($SELF, RakuAST::Parameter, '$!type-captures') { $param-qast.push($_.IMPL-BIND-QAST($context, $temp-qast-var)); } if nqp::getattr($SELF, RakuAST::Parameter, '$!where') { $param-qast.push( QAST::ParamTypeCheck.new( QAST::Op.new( :op('call'), nqp::getattr($SELF, RakuAST::Parameter, '$!where').IMPL-TO-QAST($context), $temp-qast-var ) ) ); } # Take care of checking against provided subset types and other nominalizable types. # TODO: Investigate breakage -- No such method 'ACCEPTS' for invocant of type '::?CLASS:D' # if nqp::defined($!type) && $!type.meta-object.HOW.archetypes.nominalizable { if nqp::defined(nqp::getattr($SELF, RakuAST::Parameter, '$!type')) && nqp::istype(nqp::getattr($SELF, RakuAST::Parameter, '$!type').meta-object.HOW, Perl6::Metamodel::SubsetHOW) { my $type-object := nqp::getattr($SELF, RakuAST::Parameter, '$!type').meta-object; $context.ensure-sc($type-object); $param-qast.push( QAST::ParamTypeCheck.new( QAST::Op.new( :op('callmethod'), :name('ACCEPTS'), QAST::WVal.new( :value($type-object) ), $temp-qast-var ) ) ); } @prepend ?? QAST::Stmts.new( |@prepend, $param-qast ) !! $param-qast }); #line 362 src/Raku/ast/signature.rakumod add-method(RakuAST::Parameter, 'where', [], anon sub where ($self) { nqp::getattr(nqp::decont($self), RakuAST::Parameter, '$!where') }); #line 367 src/Raku/ast/signature.rakumod add-method(RakuAST::Parameter, 'value', [], anon sub value ($self) { nqp::getattr(nqp::decont($self), RakuAST::Parameter, '$!value') }); #line 355 src/Raku/ast/signature.rakumod add-method(RakuAST::Parameter, 'type', [], anon sub type ($self) { nqp::getattr(nqp::decont($self), RakuAST::Parameter, '$!type') }); #line 356 src/Raku/ast/signature.rakumod add-method(RakuAST::Parameter, 'target', [], anon sub target ($self) { nqp::getattr(nqp::decont($self), RakuAST::Parameter, '$!target') }); #line 365 src/Raku/ast/signature.rakumod add-method(RakuAST::Parameter, 'sub-signature', [], anon sub sub-signature ($self) { nqp::getattr(nqp::decont($self), RakuAST::Parameter, '$!sub-signature') }); #line 360 src/Raku/ast/signature.rakumod add-method(RakuAST::Parameter, 'slurpy', [], anon sub slurpy ($self) { nqp::getattr(nqp::decont($self), RakuAST::Parameter, '$!slurpy') }); #line 359 src/Raku/ast/signature.rakumod add-method(RakuAST::Parameter, 'optional', [], anon sub optional ($self) { nqp::getattr(nqp::decont($self), RakuAST::Parameter, '$!optional') }); #line 358 src/Raku/ast/signature.rakumod add-method(RakuAST::Parameter, 'invocant', [], anon sub invocant ($self) { nqp::getattr(nqp::decont($self), RakuAST::Parameter, '$!invocant') }); #line 361 src/Raku/ast/signature.rakumod add-method(RakuAST::Parameter, 'default', [], anon sub default ($self) { nqp::getattr(nqp::decont($self), RakuAST::Parameter, '$!default') }); compose(RakuAST::Parameter); parent(RakuAST::ParameterTarget, RakuAST::Node); add-method(RakuAST::ParameterTarget, 'sigil', [RakuAST::ParameterTarget, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1253 src/Raku/ast/signature.rakumod '' }); add-method(RakuAST::ParameterTarget, 'name', [RakuAST::ParameterTarget, '', 0, 0], anon sub name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1254 src/Raku/ast/signature.rakumod '' }); compose(RakuAST::ParameterTarget); parent(RakuAST::ParameterTarget::Var, RakuAST::ParameterTarget); parent(RakuAST::ParameterTarget::Var, RakuAST::TraitTarget); parent(RakuAST::ParameterTarget::Var, RakuAST::Meta); parent(RakuAST::ParameterTarget::Var, RakuAST::ContainerCreator); parent(RakuAST::ParameterTarget::Var, RakuAST::BeginTime); parent(RakuAST::ParameterTarget::Var, RakuAST::CheckTime); parent(RakuAST::ParameterTarget::Var, RakuAST::Attaching); add-attribute(RakuAST::ParameterTarget::Var, str, '$!name'); add-attribute(RakuAST::ParameterTarget::Var, RakuAST::Type, '$!type'); add-attribute(RakuAST::ParameterTarget::Var, Mu, '$!of'); add-attribute(RakuAST::ParameterTarget::Var, RakuAST::Package, '$!attribute-package'); add-attribute(RakuAST::ParameterTarget::Var, RakuAST::VarDeclaration::Simple, '$!declaration'); add-attribute(RakuAST::ParameterTarget::Var, str, '$!scope'); add-method(RakuAST::ParameterTarget::Var, 'new', [RakuAST::ParameterTarget::Var, '', 0, 0, str, '$name', 0, 0, Bool, '$forced-dynamic', 1, 1], anon sub new ($SELF_CONT, $name!, :$forced-dynamic?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $forced-dynamic := nqp::decont($forced-dynamic); #line 1274 src/Raku/ast/signature.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::ParameterTarget::Var, '$!name', $name); nqp::bindattr($obj, RakuAST::ParameterTarget::Var, '$!type', Mu); nqp::bindattr($obj, RakuAST::ParameterTarget::Var, '$!of', Mu); nqp::bindattr($obj, RakuAST::ContainerCreator, '$!forced-dynamic', $forced-dynamic ?? (Bool.WHO) !! (Bool.WHO)); my $sigil := $obj.sigil; my $twigil := $obj.twigil; nqp::bindattr( $obj, RakuAST::ParameterTarget::Var, '$!declaration', RakuAST::VarDeclaration::Simple.new( :scope($obj.scope), :desigilname(RakuAST::Name.from-identifier($obj.desigilname)), :$sigil, :$twigil, :type(Mu), :$forced-dynamic, ) ); $obj }); add-method(RakuAST::ParameterTarget::Var, 'lexical-name', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1299 src/Raku/ast/signature.rakumod nqp::getattr_s($SELF, RakuAST::ParameterTarget::Var, '$!name') }); add-method(RakuAST::ParameterTarget::Var, 'introspection-name', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub introspection-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1303 src/Raku/ast/signature.rakumod nqp::getattr_s($SELF, RakuAST::ParameterTarget::Var, '$!name') }); add-method(RakuAST::ParameterTarget::Var, 'scope', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1307 src/Raku/ast/signature.rakumod nqp::getattr_s($SELF, RakuAST::ParameterTarget::Var, '$!scope') // $SELF.default-scope }); add-method(RakuAST::ParameterTarget::Var, 'replace-scope', [RakuAST::ParameterTarget::Var, '', 0, 0, Any, '$scope', 0, 0], anon sub replace-scope ($SELF_CONT, $scope!) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); #line 1311 src/Raku/ast/signature.rakumod nqp::bindattr_s($SELF, RakuAST::ParameterTarget::Var, '$!scope', $scope); if nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration') { nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration').replace-scope($scope); } }); add-method(RakuAST::ParameterTarget::Var, 'generate-lookup', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1319 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration').generate-lookup }); add-method(RakuAST::ParameterTarget::Var, 'sigil', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub sigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1323 src/Raku/ast/signature.rakumod nqp::substr(nqp::getattr_s($SELF, RakuAST::ParameterTarget::Var, '$!name'), 0, 1) }); add-method(RakuAST::ParameterTarget::Var, 'twigil', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub twigil ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1327 src/Raku/ast/signature.rakumod if nqp::chars(nqp::getattr_s($SELF, RakuAST::ParameterTarget::Var, '$!name')) > 2 { my str $twigil := nqp::substr(nqp::getattr_s($SELF, RakuAST::ParameterTarget::Var, '$!name'), 1, 1); nqp::index('.!^:*?=~', $twigil) >= 0 ?? $twigil !! '' } else { '' } }); add-method(RakuAST::ParameterTarget::Var, 'desigilname', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub desigilname ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1337 src/Raku/ast/signature.rakumod nqp::substr(nqp::getattr_s($SELF, RakuAST::ParameterTarget::Var, '$!name'), $SELF.twigil ?? 2 !! 1) }); add-method(RakuAST::ParameterTarget::Var, 'can-be-bound-to', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub can-be-bound-to ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1341 src/Raku/ast/signature.rakumod (Bool.WHO) #TODO only when parameter is copy }); add-method(RakuAST::ParameterTarget::Var, 'set-type', [RakuAST::ParameterTarget::Var, '', 0, 0, RakuAST::Type, '$type', 0, 0], anon sub set-type ($SELF_CONT, $type!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); #line 1345 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::ParameterTarget::Var, '$!type', $type); nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration').set-type($type) if nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration'); Nil }); add-method(RakuAST::ParameterTarget::Var, 'set-name', [RakuAST::ParameterTarget::Var, '', 0, 0, str, '$name', 0, 0], anon sub set-name ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 1351 src/Raku/ast/signature.rakumod nqp::bindattr_s($SELF, RakuAST::ParameterTarget::Var, '$!name', $name); }); add-method(RakuAST::ParameterTarget::Var, 'set-container-type', [RakuAST::ParameterTarget::Var, '', 0, 0, Mu, '$type', 0, 0, Mu, '$of', 0, 0], anon sub set-container-type ($SELF_CONT, $type!, $of!) { my $SELF := nqp::decont($SELF_CONT); $type := nqp::decont($type); $of := nqp::decont($of); #line 1355 src/Raku/ast/signature.rakumod nqp::bindattr($SELF, RakuAST::ParameterTarget::Var, '$!type', $type); nqp::bindattr($SELF, RakuAST::ParameterTarget::Var, '$!of', $of); }); add-method(RakuAST::ParameterTarget::Var, 'attach', [RakuAST::ParameterTarget::Var, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub attach ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 1360 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration').attach($resolver); }); add-method(RakuAST::ParameterTarget::Var, 'PRODUCE-META-OBJECT', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1364 src/Raku/ast/signature.rakumod nqp::bindattr( $SELF, RakuAST::ParameterTarget::Var, '$!of', nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!type').resolution.compile-time-value ) if nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!type') && nqp::eqaddr(nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!of'), Mu); nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration').meta-object }); add-method(RakuAST::ParameterTarget::Var, 'IMPL-QAST-DECL', [RakuAST::ParameterTarget::Var, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1375 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration').IMPL-QAST-DECL($context) }); add-method(RakuAST::ParameterTarget::Var, 'IMPL-BIND-QAST', [RakuAST::ParameterTarget::Var, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 1379 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration').IMPL-BIND-QAST($context, $source-qast) }); add-method(RakuAST::ParameterTarget::Var, 'IMPL-LOOKUP-QAST', [RakuAST::ParameterTarget::Var, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1383 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration').IMPL-LOOKUP-QAST($context) }); add-method(RakuAST::ParameterTarget::Var, 'PERFORM-BEGIN', [RakuAST::ParameterTarget::Var, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1387 src/Raku/ast/signature.rakumod my $var := nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration'); for $SELF.IMPL-UNWRAP-LIST($SELF.traits) { $var.add-trait($_); } }); add-method(RakuAST::ParameterTarget::Var, 'PERFORM-CHECK', [RakuAST::ParameterTarget::Var, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1397 src/Raku/ast/signature.rakumod # Check for illegal post declaration is actually performed by RakuAST::Scope # Need PERFORM-CHECK because we're a RakuAST::CheckTime and we need to be # that to carry the sorry generated by the check. }); add-method(RakuAST::ParameterTarget::Var, 'default-scope', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1403 src/Raku/ast/signature.rakumod 'my' }); add-method(RakuAST::ParameterTarget::Var, 'allowed-scopes', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1405 src/Raku/ast/signature.rakumod $SELF.IMPL-WRAP-LIST(['my', 'our', 'has', 'HAS']) }); add-method(RakuAST::ParameterTarget::Var, 'is-begin-performed-before-children', [RakuAST::ParameterTarget::Var, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1407 src/Raku/ast/signature.rakumod (Bool.WHO) }); add-method(RakuAST::ParameterTarget::Var, 'visit-children', [RakuAST::ParameterTarget::Var, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1409 src/Raku/ast/signature.rakumod # We don't want to visit the declaration if it is a topic variable, # as that will result in multiple declarations because blocks already # automatically declare a `$_`. And if the signature is not on a block # it will still find a lexical `$_` somewhere in scope. $visitor(nqp::getattr($SELF, RakuAST::ParameterTarget::Var, '$!declaration')) unless nqp::getattr_s($SELF, RakuAST::ParameterTarget::Var, '$!name') eq '$_'; }); #line 1268 src/Raku/ast/signature.rakumod add-method(RakuAST::ParameterTarget::Var, 'type', [], anon sub type ($self) { nqp::getattr(nqp::decont($self), RakuAST::ParameterTarget::Var, '$!type') }); #line 1267 src/Raku/ast/signature.rakumod add-method(RakuAST::ParameterTarget::Var, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::ParameterTarget::Var, '$!name') }); compose(RakuAST::ParameterTarget::Var); parent(RakuAST::ParameterTarget::Term, RakuAST::ParameterTarget); parent(RakuAST::ParameterTarget::Term, RakuAST::Declaration); add-attribute(RakuAST::ParameterTarget::Term, RakuAST::Name, '$!name'); add-method(RakuAST::ParameterTarget::Term, 'new', [RakuAST::ParameterTarget::Term, '', 0, 0, RakuAST::Name, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 1425 src/Raku/ast/signature.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ParameterTarget::Term, '$!name', $name); $obj }); add-method(RakuAST::ParameterTarget::Term, 'lexical-name', [RakuAST::ParameterTarget::Term, '', 0, 0], anon sub lexical-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1431 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::ParameterTarget::Term, '$!name').canonicalize }); add-method(RakuAST::ParameterTarget::Term, 'introspection-name', [RakuAST::ParameterTarget::Term, '', 0, 0], anon sub introspection-name ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1435 src/Raku/ast/signature.rakumod nqp::getattr($SELF, RakuAST::ParameterTarget::Term, '$!name').canonicalize }); add-method(RakuAST::ParameterTarget::Term, 'generate-lookup', [RakuAST::ParameterTarget::Term, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1440 src/Raku/ast/signature.rakumod my $lookup := RakuAST::Term::Name.new(nqp::getattr($SELF, RakuAST::ParameterTarget::Term, '$!name')); $lookup.set-resolution($SELF); $lookup }); add-method(RakuAST::ParameterTarget::Term, 'IMPL-QAST-DECL', [RakuAST::ParameterTarget::Term, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1446 src/Raku/ast/signature.rakumod QAST::Var.new( :decl('var'), :scope('lexical'), :name(nqp::getattr($SELF, RakuAST::ParameterTarget::Term, '$!name').canonicalize) ) }); add-method(RakuAST::ParameterTarget::Term, 'IMPL-BIND-QAST', [RakuAST::ParameterTarget::Term, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$source-qast', 0, 0], anon sub IMPL-BIND-QAST ($SELF_CONT, $context!, $source-qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $source-qast := nqp::decont($source-qast); #line 1450 src/Raku/ast/signature.rakumod QAST::Op.new( :op('bind'), QAST::Var.new( :scope('lexical'), :name(nqp::getattr($SELF, RakuAST::ParameterTarget::Term, '$!name').canonicalize) ), $source-qast ) }); add-method(RakuAST::ParameterTarget::Term, 'IMPL-LOOKUP-QAST', [RakuAST::ParameterTarget::Term, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-LOOKUP-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1458 src/Raku/ast/signature.rakumod my str $scope := 'lexical'; QAST::Var.new( :name(nqp::getattr($SELF, RakuAST::ParameterTarget::Term, '$!name').canonicalize), :$scope ) }); add-method(RakuAST::ParameterTarget::Term, 'default-scope', [RakuAST::ParameterTarget::Term, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1463 src/Raku/ast/signature.rakumod 'my' }); add-method(RakuAST::ParameterTarget::Term, 'allowed-scopes', [RakuAST::ParameterTarget::Term, '', 0, 0], anon sub allowed-scopes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1465 src/Raku/ast/signature.rakumod $SELF.IMPL-WRAP-LIST(['my']) }); add-method(RakuAST::ParameterTarget::Term, 'visit-children', [RakuAST::ParameterTarget::Term, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1467 src/Raku/ast/signature.rakumod $visitor(nqp::getattr($SELF, RakuAST::ParameterTarget::Term, '$!name')); }); #line 1423 src/Raku/ast/signature.rakumod add-method(RakuAST::ParameterTarget::Term, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::ParameterTarget::Term, '$!name') }); compose(RakuAST::ParameterTarget::Term); parent(RakuAST::ParameterTarget::Whatever, RakuAST::ParameterTarget::Term); add-method(RakuAST::ParameterTarget::Whatever, 'new', [RakuAST::ParameterTarget::Whatever, '', 0, 0, str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 1477 src/Raku/ast/signature.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ParameterTarget::Term, '$!name', RakuAST::Name.from-identifier($name // QAST::Node.unique('$whatevercode_arg'))); $obj }); add-method(RakuAST::ParameterTarget::Whatever, 'generate-lookup', [RakuAST::ParameterTarget::Whatever, '', 0, 0], anon sub generate-lookup ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1485 src/Raku/ast/signature.rakumod my $name := nqp::getattr($SELF, RakuAST::ParameterTarget::Term, '$!name'); my $lookup := RakuAST::WhateverCode::Argument.new($name); $lookup.set-resolution($SELF); $lookup }); compose(RakuAST::ParameterTarget::Whatever); parent(RakuAST::Parameter::Slurpy, Any); add-method(RakuAST::Parameter::Slurpy, 'new', [RakuAST::Parameter::Slurpy, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1502 src/Raku/ast/signature.rakumod $SELF }); add-method(RakuAST::Parameter::Slurpy, 'IMPL-FLAGS', [RakuAST::Parameter::Slurpy, '', 0, 0, str, '$sigil', 0, 0], anon sub IMPL-FLAGS ($SELF_CONT, $sigil!) { my $SELF := nqp::decont($SELF_CONT); $sigil := nqp::decont($sigil); #line 1504 src/Raku/ast/signature.rakumod # Not slurpy, so no flags 0 }); add-method(RakuAST::Parameter::Slurpy, 'IMPL-TRANSFORM-PARAM-QAST', [RakuAST::Parameter::Slurpy, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$param-qast', 0, 0, Mu, '$temp-qast', 0, 0, str, '$sigil', 0, 0, Any, '@prepend', 0, 0], anon sub IMPL-TRANSFORM-PARAM-QAST ($SELF_CONT, $context!, $param-qast!, $temp-qast!, $sigil!, @prepend!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $param-qast := nqp::decont($param-qast); $temp-qast := nqp::decont($temp-qast); $sigil := nqp::decont($sigil); @prepend := nqp::decont(@prepend); #line 1510 src/Raku/ast/signature.rakumod # Not slurply, so nothing to do $param-qast }); add-method(RakuAST::Parameter::Slurpy, 'IMPL-QAST-LISTY-SLURP', [RakuAST::Parameter::Slurpy, '', 0, 0, Mu, '$param-qast', 0, 0, Mu, '$temp-qast', 0, 0, List, '$type', 0, 0, str, '$method', 0, 0], anon sub IMPL-QAST-LISTY-SLURP ($SELF_CONT, $param-qast!, $temp-qast!, $type!, $method!) { my $SELF := nqp::decont($SELF_CONT); $param-qast := nqp::decont($param-qast); $temp-qast := nqp::decont($temp-qast); $type := nqp::decont($type); $method := nqp::decont($method); #line 1515 src/Raku/ast/signature.rakumod $param-qast.slurpy(1); $param-qast.push(QAST::Op.new( :op('bind'), $temp-qast, QAST::Op.new( :op('callmethod'), :name($method), QAST::WVal.new( :value($type) ), $temp-qast ) )); }); compose(RakuAST::Parameter::Slurpy); parent(RakuAST::Parameter::Slurpy::Flattened, RakuAST::Parameter::Slurpy); add-method(RakuAST::Parameter::Slurpy::Flattened, 'IMPL-FLAGS', [RakuAST::Parameter::Slurpy::Flattened, '', 0, 0, str, '$sigil', 0, 0], anon sub IMPL-FLAGS ($SELF_CONT, $sigil!) { my $SELF := nqp::decont($SELF_CONT); $sigil := nqp::decont($sigil); #line 1533 src/Raku/ast/signature.rakumod my constant SIG_ELEM_SLURPY_POS := 8; my constant SIG_ELEM_SLURPY_NAMED := 16; $sigil eq '@' ?? SIG_ELEM_SLURPY_POS !! $sigil eq '%' ?? SIG_ELEM_SLURPY_NAMED !! 0 }); add-method(RakuAST::Parameter::Slurpy::Flattened, 'IMPL-TRANSFORM-PARAM-QAST', [RakuAST::Parameter::Slurpy::Flattened, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$param-qast', 0, 0, Mu, '$temp-qast', 0, 0, str, '$sigil', 0, 0, Any, '@prepend', 0, 0], anon sub IMPL-TRANSFORM-PARAM-QAST ($SELF_CONT, $context!, $param-qast!, $temp-qast!, $sigil!, @prepend!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $param-qast := nqp::decont($param-qast); $temp-qast := nqp::decont($temp-qast); $sigil := nqp::decont($sigil); @prepend := nqp::decont(@prepend); #line 1542 src/Raku/ast/signature.rakumod if $sigil eq '@' { $SELF.IMPL-QAST-LISTY-SLURP($param-qast, $temp-qast, Array, 'from-slurpy-flat'); } elsif $sigil eq '%' { $param-qast.slurpy(1); $param-qast.named(1); $param-qast.push(QAST::Op.new( :op('bind'), $temp-qast, QAST::Op.new( :op('p6bindattrinvres'), QAST::Op.new( :op('create'), QAST::WVal.new( :value(Hash) ) ), QAST::WVal.new( :value(Map) ), QAST::SVal.new( :value('$!storage') ), $temp-qast ) )); } else { nqp::die("Parameter * quantifier not applicable to sigil '$sigil'"); } }); compose(RakuAST::Parameter::Slurpy::Flattened); parent(RakuAST::Parameter::Slurpy::Unflattened, RakuAST::Parameter::Slurpy); add-method(RakuAST::Parameter::Slurpy::Unflattened, 'IMPL-FLAGS', [RakuAST::Parameter::Slurpy::Unflattened, '', 0, 0, str, '$sigil', 0, 0], anon sub IMPL-FLAGS ($SELF_CONT, $sigil!) { my $SELF := nqp::decont($SELF_CONT); $sigil := nqp::decont($sigil); #line 1574 src/Raku/ast/signature.rakumod my constant SIG_ELEM_SLURPY_LOL := 32; $sigil eq '@' ?? SIG_ELEM_SLURPY_LOL !! 0 }); add-method(RakuAST::Parameter::Slurpy::Unflattened, 'IMPL-TRANSFORM-PARAM-QAST', [RakuAST::Parameter::Slurpy::Unflattened, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$param-qast', 0, 0, Mu, '$temp-qast', 0, 0, str, '$sigil', 0, 0, Any, '@prepend', 0, 0], anon sub IMPL-TRANSFORM-PARAM-QAST ($SELF_CONT, $context!, $param-qast!, $temp-qast!, $sigil!, @prepend!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $param-qast := nqp::decont($param-qast); $temp-qast := nqp::decont($temp-qast); $sigil := nqp::decont($sigil); @prepend := nqp::decont(@prepend); #line 1580 src/Raku/ast/signature.rakumod if $sigil eq '@' { $SELF.IMPL-QAST-LISTY-SLURP($param-qast, $temp-qast, Array, 'from-slurpy'); } else { nqp::die("Parameter ** quantifier not applicable to sigil '$sigil'"); } }); compose(RakuAST::Parameter::Slurpy::Unflattened); parent(RakuAST::Parameter::Slurpy::SingleArgument, RakuAST::Parameter::Slurpy); add-method(RakuAST::Parameter::Slurpy::SingleArgument, 'IMPL-FLAGS', [RakuAST::Parameter::Slurpy::SingleArgument, '', 0, 0, str, '$sigil', 0, 0], anon sub IMPL-FLAGS ($SELF_CONT, $sigil!) { my $SELF := nqp::decont($SELF_CONT); $sigil := nqp::decont($sigil); #line 1594 src/Raku/ast/signature.rakumod my constant SIG_ELEM_SLURPY_ONEARG := 16777216; $sigil eq '@' || $sigil eq '' ?? SIG_ELEM_SLURPY_ONEARG !! 0 }); add-method(RakuAST::Parameter::Slurpy::SingleArgument, 'IMPL-TRANSFORM-PARAM-QAST', [RakuAST::Parameter::Slurpy::SingleArgument, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$param-qast', 0, 0, Mu, '$temp-qast', 0, 0, str, '$sigil', 0, 0, Any, '@prepend', 0, 0], anon sub IMPL-TRANSFORM-PARAM-QAST ($SELF_CONT, $context!, $param-qast!, $temp-qast!, $sigil!, @prepend!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $param-qast := nqp::decont($param-qast); $temp-qast := nqp::decont($temp-qast); $sigil := nqp::decont($sigil); @prepend := nqp::decont(@prepend); #line 1600 src/Raku/ast/signature.rakumod if $sigil eq '@' || $sigil eq '' { $SELF.IMPL-QAST-LISTY-SLURP($param-qast, $temp-qast, Array, 'from-slurpy-onearg'); } else { nqp::die("Parameter + quantifier not applicable to sigil '$sigil'"); } }); compose(RakuAST::Parameter::Slurpy::SingleArgument); parent(RakuAST::Parameter::Slurpy::Capture, RakuAST::Parameter::Slurpy); add-method(RakuAST::Parameter::Slurpy::Capture, 'IMPL-FLAGS', [RakuAST::Parameter::Slurpy::Capture, '', 0, 0, str, '$sigil', 0, 0], anon sub IMPL-FLAGS ($SELF_CONT, $sigil!) { my $SELF := nqp::decont($SELF_CONT); $sigil := nqp::decont($sigil); #line 1614 src/Raku/ast/signature.rakumod my constant SIG_ELEM_IS_CAPTURE := 32768; SIG_ELEM_IS_CAPTURE }); add-method(RakuAST::Parameter::Slurpy::Capture, 'IMPL-TRANSFORM-PARAM-QAST', [RakuAST::Parameter::Slurpy::Capture, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$param-qast', 0, 0, Mu, '$temp-qast', 0, 0, str, '$sigil', 0, 0, Any, '@prepend', 0, 0], anon sub IMPL-TRANSFORM-PARAM-QAST ($SELF_CONT, $context!, $param-qast!, $temp-qast!, $sigil!, @prepend!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $param-qast := nqp::decont($param-qast); $temp-qast := nqp::decont($temp-qast); $sigil := nqp::decont($sigil); @prepend := nqp::decont(@prepend); #line 1620 src/Raku/ast/signature.rakumod # Sneak in a slurpy hash parameter too. $param-qast.slurpy(1); my $hash-param-name := $temp-qast.name ~ '_hash'; @prepend.push(QAST::Var.new( :name($hash-param-name), :scope('local'), :decl('param'), :slurpy(1), :named(1) )); # Build a capture object. my $capture-wval := QAST::WVal.new( :value(Capture) ); $param-qast.push(QAST::Op.new( :op('bind'), $temp-qast, QAST::Op.new( :op('p6bindattrinvres'), QAST::Op.new( :op('p6bindattrinvres'), QAST::Op.new( :op('create'), $capture-wval ), $capture-wval, QAST::SVal.new( :value('@!list') ), $temp-qast ), $capture-wval, QAST::SVal.new( :value('%!hash') ), QAST::Var.new( :name($hash-param-name), :scope('local') ) ))); }); compose(RakuAST::Parameter::Slurpy::Capture); parent(RakuAST::ParameterDefaultThunk, RakuAST::ExpressionThunk); add-attribute(RakuAST::ParameterDefaultThunk, RakuAST::Parameter, '$!parameter'); add-method(RakuAST::ParameterDefaultThunk, 'new', [RakuAST::ParameterDefaultThunk, '', 0, 0, RakuAST::Parameter, '$parameter', 0, 0], anon sub new ($SELF_CONT, $parameter!) { my $SELF := nqp::decont($SELF_CONT); $parameter := nqp::decont($parameter); #line 1656 src/Raku/ast/signature.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::ParameterDefaultThunk, '$!parameter', $parameter); $obj }); add-method(RakuAST::ParameterDefaultThunk, 'thunk-kind', [RakuAST::ParameterDefaultThunk, '', 0, 0], anon sub thunk-kind ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1662 src/Raku/ast/signature.rakumod 'Parameter default' }); add-method(RakuAST::ParameterDefaultThunk, 'thunk-details', [RakuAST::ParameterDefaultThunk, '', 0, 0], anon sub thunk-details ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1666 src/Raku/ast/signature.rakumod '' }); add-method(RakuAST::ParameterDefaultThunk, 'IMPL-THUNK-META-OBJECT-PRODUCED', [RakuAST::ParameterDefaultThunk, '', 0, 0, Mu, '$code', 0, 0], anon sub IMPL-THUNK-META-OBJECT-PRODUCED ($SELF_CONT, $code!) { my $SELF := nqp::decont($SELF_CONT); $code := nqp::decont($code); #line 1670 src/Raku/ast/signature.rakumod nqp::bindattr(nqp::getattr($SELF, RakuAST::ParameterDefaultThunk, '$!parameter').meta-object, Parameter, '$!default_value', $code); }); compose(RakuAST::ParameterDefaultThunk); parent(RakuAST::Package, RakuAST::PackageInstaller); parent(RakuAST::Package, RakuAST::StubbyMeta); parent(RakuAST::Package, RakuAST::Term); parent(RakuAST::Package, RakuAST::IMPL::ImmediateBlockUser); parent(RakuAST::Package, RakuAST::Declaration); parent(RakuAST::Package, RakuAST::AttachTarget); parent(RakuAST::Package, RakuAST::BeginTime); parent(RakuAST::Package, RakuAST::TraitTarget); parent(RakuAST::Package, RakuAST::ImplicitBlockSemanticsProvider); parent(RakuAST::Package, RakuAST::LexicalScope); parent(RakuAST::Package, RakuAST::Lookup); parent(RakuAST::Package, RakuAST::Doc::DeclaratorTarget); add-attribute(RakuAST::Package, RakuAST::Name, '$!name'); add-attribute(RakuAST::Package, RakuAST::Code, '$!body'); add-attribute(RakuAST::Package, Mu, '$!attribute-type'); add-attribute(RakuAST::Package, Mu, '$!how'); add-attribute(RakuAST::Package, Str, '$!repr'); add-attribute(RakuAST::Package, Bool, '$!augmented'); add-attribute(RakuAST::Package, Mu, '$!role-group'); add-attribute(RakuAST::Package, Mu, '$!block-semantics-applied'); add-attribute(RakuAST::Package, Bool, '$!is-stub'); add-attribute(RakuAST::Package, Mu, '$!attached-methods'); add-attribute(RakuAST::Package, Mu, '$!attached-attributes'); add-attribute(RakuAST::Package, Mu, '$!attached-attribute-usages'); add-method(RakuAST::Package, 'new', [RakuAST::Package, '', 0, 0, str, '$scope', 1, 1, RakuAST::Name, '$name', 1, 1, RakuAST::Signature, '$parameterization', 1, 1, List, '$traits', 1, 1, RakuAST::Code, '$body', 1, 1, Mu, '$attribute-type', 1, 1, Mu, '$how', 1, 1, Str, '$repr', 1, 1, Bool, '$augmented', 1, 1, RakuAST::Doc::Declarator, '$WHY', 1, 1], anon sub new ($SELF_CONT, :$scope?, :$name?, :$parameterization?, :$traits?, :$body?, :$attribute-type?, :$how?, :$repr?, :$augmented?, :$WHY?) { my $SELF := nqp::decont($SELF_CONT); $scope := nqp::decont($scope); $name := nqp::decont($name); $parameterization := nqp::decont($parameterization); $traits := nqp::decont($traits); $body := nqp::decont($body); $attribute-type := nqp::decont($attribute-type); $how := nqp::decont($how); $repr := nqp::decont($repr); $augmented := nqp::decont($augmented); $WHY := nqp::decont($WHY); #line 47 src/Raku/ast/package.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Declaration, '$!scope', $scope); nqp::bindattr($obj, RakuAST::Package, '$!name', $name // RakuAST::Name); nqp::bindattr($obj, RakuAST::Package, '$!attribute-type', nqp::eqaddr($attribute-type, NQPMu) ?? Attribute !! $attribute-type); nqp::bindattr($obj, RakuAST::Package, '$!how', nqp::eqaddr($how,NQPMu) ?? $obj.default-how !! $how); nqp::bindattr($obj, RakuAST::Package, '$!repr', $repr // Str); nqp::bindattr($obj, RakuAST::Package, '$!augmented',$augmented // (Bool.WHO)); $obj.set-traits($traits) if $traits; $obj.replace-body($body, $parameterization); $obj.set-WHY($WHY); # Set up internal defaults nqp::bindattr($obj, RakuAST::Package, '$!attached-methods', []); nqp::bindattr($obj, RakuAST::Package, '$!attached-attributes', []); nqp::bindattr($obj, RakuAST::Package, '$!attached-attribute-usages',[]); nqp::bindattr($obj, RakuAST::Package, '$!role-group', Mu); nqp::bindattr($obj, RakuAST::Package, '$!is-stub', (Bool.WHO)); $obj }); add-method(RakuAST::Package, 'declarator', [RakuAST::Package, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 73 src/Raku/ast/package.rakumod "package" }); add-method(RakuAST::Package, 'dba', [RakuAST::Package, '', 0, 0], anon sub dba ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 74 src/Raku/ast/package.rakumod "package" }); add-method(RakuAST::Package, 'default-how', [RakuAST::Package, '', 0, 0], anon sub default-how ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 75 src/Raku/ast/package.rakumod Metamodel::PackageHOW }); add-method(RakuAST::Package, 'default-scope', [RakuAST::Package, '', 0, 0], anon sub default-scope ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 77 src/Raku/ast/package.rakumod 'our' }); add-method(RakuAST::Package, 'can-have-methods', [RakuAST::Package, '', 0, 0], anon sub can-have-methods ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 78 src/Raku/ast/package.rakumod (Bool.WHO) }); add-method(RakuAST::Package, 'can-have-attributes', [RakuAST::Package, '', 0, 0], anon sub can-have-attributes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 79 src/Raku/ast/package.rakumod (Bool.WHO) }); add-method(RakuAST::Package, 'IMPL-CAN-INTERPRET', [RakuAST::Package, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 80 src/Raku/ast/package.rakumod (Bool.WHO) }); add-method(RakuAST::Package, 'parameterization', [RakuAST::Package, '', 0, 0], anon sub parameterization ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 82 src/Raku/ast/package.rakumod Mu }); add-method(RakuAST::Package, 'is-simple-lexical-declaration', [RakuAST::Package, '', 0, 0], anon sub is-simple-lexical-declaration ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 87 src/Raku/ast/package.rakumod (Bool.WHO) }); add-method(RakuAST::Package, 'is-begin-performed-before-children', [RakuAST::Package, '', 0, 0], anon sub is-begin-performed-before-children ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 90 src/Raku/ast/package.rakumod (Bool.WHO) }); add-method(RakuAST::Package, 'replace-body', [RakuAST::Package, '', 0, 0, RakuAST::Code, '$body', 0, 0, RakuAST::Signature, '$signature', 0, 0], anon sub replace-body ($SELF_CONT, $body!, $signature!) { my $SELF := nqp::decont($SELF_CONT); $body := nqp::decont($body); $signature := nqp::decont($signature); #line 93 src/Raku/ast/package.rakumod nqp::bindattr($SELF, RakuAST::Package, '$!body', $body // RakuAST::Block.new); Nil }); add-method(RakuAST::Package, 'set-repr', [RakuAST::Package, '', 0, 0, Str, '$repr', 0, 0], anon sub set-repr ($SELF_CONT, $repr!) { my $SELF := nqp::decont($SELF_CONT); $repr := nqp::decont($repr); #line 99 src/Raku/ast/package.rakumod nqp::bindattr($SELF, RakuAST::Package, '$!repr', $repr); }); add-method(RakuAST::Package, 'set-is-stub', [RakuAST::Package, '', 0, 0, Bool, '$is-stub', 0, 0], anon sub set-is-stub ($SELF_CONT, $is-stub!) { my $SELF := nqp::decont($SELF_CONT); $is-stub := nqp::decont($is-stub); #line 103 src/Raku/ast/package.rakumod nqp::bindattr($SELF, RakuAST::Package, '$!is-stub', $is-stub ?? (Bool.WHO) !! (Bool.WHO)); }); add-method(RakuAST::Package, 'resolve-with', [RakuAST::Package, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub resolve-with ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 107 src/Raku/ast/package.rakumod if nqp::getattr($SELF, RakuAST::Package, '$!augmented') { my $resolved := $resolver.resolve-name($SELF.name); if $resolved { $SELF.set-resolution($resolved); } } elsif nqp::getattr($SELF, RakuAST::Package, '$!name') { my $resolved := $resolver.resolve-name-constant(nqp::getattr($SELF, RakuAST::Package, '$!name')); if $resolved { my $meta := $resolved.compile-time-value; my $how := $meta.HOW; if $how.HOW.name($how) ne 'Perl6::Metamodel::PackageHOW' && nqp::can($how, 'is_composed') && !$how.is_composed($meta) { $SELF.set-resolution($resolved); } } } Nil }); add-method(RakuAST::Package, 'attach-target-names', [RakuAST::Package, '', 0, 0], anon sub attach-target-names ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 129 src/Raku/ast/package.rakumod $SELF.IMPL-WRAP-LIST(['package', 'also']) }); add-method(RakuAST::Package, 'clear-attachments', [RakuAST::Package, '', 0, 0], anon sub clear-attachments ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 131 src/Raku/ast/package.rakumod # Attributes and methods only attach once as a BEGIN effect, thus we # don't have to deal with duplicates on them. Nil }); add-method(RakuAST::Package, 'ATTACH-METHOD', [RakuAST::Package, '', 0, 0, RakuAST::Method, '$method', 0, 0], anon sub ATTACH-METHOD ($SELF_CONT, $method!) { my $SELF := nqp::decont($SELF_CONT); $method := nqp::decont($method); #line 137 src/Raku/ast/package.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Package, '$!attached-methods'), $method); Nil }); add-method(RakuAST::Package, 'ATTACH-ATTRIBUTE', [RakuAST::Package, '', 0, 0, RakuAST::VarDeclaration::Simple, '$attribute', 0, 0], anon sub ATTACH-ATTRIBUTE ($SELF_CONT, $attribute!) { my $SELF := nqp::decont($SELF_CONT); $attribute := nqp::decont($attribute); #line 143 src/Raku/ast/package.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Package, '$!attached-attributes'), $attribute); Nil }); add-method(RakuAST::Package, 'ATTACH-ATTRIBUTE-USAGE', [RakuAST::Package, '', 0, 0, RakuAST::Var::Attribute, '$attribute', 0, 0], anon sub ATTACH-ATTRIBUTE-USAGE ($SELF_CONT, $attribute!) { my $SELF := nqp::decont($SELF_CONT); $attribute := nqp::decont($attribute); #line 148 src/Raku/ast/package.rakumod nqp::push(nqp::getattr($SELF, RakuAST::Package, '$!attached-attribute-usages'), $attribute); Nil }); add-method(RakuAST::Package, 'IMPL-GENERATE-LEXICAL-DECLARATION', [RakuAST::Package, '', 0, 0, RakuAST::Name, '$name', 0, 0, Mu, '$type-object', 0, 0], anon sub IMPL-GENERATE-LEXICAL-DECLARATION ($SELF_CONT, $name!, $type-object!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $type-object := nqp::decont($type-object); #line 153 src/Raku/ast/package.rakumod RakuAST::Declaration::LexicalPackage.new: :lexical-name($name), :compile-time-value($type-object), :package($SELF); }); add-method(RakuAST::Package, 'PERFORM-BEGIN', [RakuAST::Package, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-BEGIN ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 163 src/Raku/ast/package.rakumod # Note that this early return is actually not effective as the # begin handler will already be run when the parser enters the # package and we only know that it's a stub when we are done # parsing the body. return Nil if nqp::getattr($SELF, RakuAST::Package, '$!is-stub'); # Install the symbol. my str $scope := $SELF.scope; $scope := 'our' if $scope eq 'unit'; my $name := nqp::getattr($SELF, RakuAST::Package, '$!name'); if $name && !$name.is-empty { my $type-object := $SELF.stubbed-meta-object; my $current := $resolver.current-package; my $full-name := nqp::eqaddr($current,$resolver.get-global) ?? $name !! $name.qualified-with( RakuAST::Name.from-identifier-parts( |nqp::split('::', $current.HOW.name($current)) ) ); $type-object.HOW.set_name( $type-object, $full-name.canonicalize(:colonpairs(0)) ) if !nqp::eqaddr($current, $resolver.get-global); # Update the Stash's name, too. nqp::bindattr_s($type-object.WHO, Stash, '$!longname', $type-object.HOW.name($type-object)); $SELF.install-in-scope( $resolver, $scope, $name, $full-name, $type-object ); } # TODO split off the above into a pre-begin handler, so the enter-scope # and declarations can go back into RakuAST::Actions if nqp::istype($resolver, RakuAST::Resolver::Compile) { $resolver.enter-scope($SELF); $SELF.declare-lexicals($resolver); } # Apply any traits $SELF.apply-traits($resolver, $context, $SELF); }); add-method(RakuAST::Package, 'install-in-scope', [RakuAST::Package, '', 0, 0, Any, '$resolver', 0, 0, Any, '$scope', 0, 0, Any, '$name', 0, 0, Any, '$full-name', 0, 0, Any, '$type-object', 0, 0], anon sub install-in-scope ($SELF_CONT, $resolver!, $scope!, $name!, $full-name!, $type-object!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $scope := nqp::decont($scope); $name := nqp::decont($name); $full-name := nqp::decont($full-name); $type-object := nqp::decont($type-object); #line 210 src/Raku/ast/package.rakumod $SELF.IMPL-INSTALL-PACKAGE( $resolver, $scope, $name, $type-object, $resolver.current-package ) if $scope eq 'my' || $scope eq 'our'; }); add-method(RakuAST::Package, 'declare-lexicals', [RakuAST::Package, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub declare-lexicals ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 217 src/Raku/ast/package.rakumod $SELF.meta-object-as-lexicals($resolver, 'CLASS') unless $SELF.declarator eq 'package'; }); add-method(RakuAST::Package, 'meta-object-as-lexicals', [RakuAST::Package, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, str, '$root', 0, 0], anon sub meta-object-as-lexicals ($SELF_CONT, $resolver!, $root!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $root := nqp::decont($root); #line 223 src/Raku/ast/package.rakumod for '$?', '::?' { $resolver.declare-lexical($SELF.implicit-constant($_ ~ $root)); } }); add-method(RakuAST::Package, 'meta-object-as-body-lexicals', [RakuAST::Package, '', 0, 0, str, '$root', 0, 0], anon sub meta-object-as-body-lexicals ($SELF_CONT, $root!) { my $SELF := nqp::decont($SELF_CONT); $root := nqp::decont($root); #line 230 src/Raku/ast/package.rakumod my $body := $SELF.body; for '$?', '::?' { $body.add-generated-lexical-declaration( $SELF.implicit-constant($_ ~ $root) ) } }); add-method(RakuAST::Package, 'implicit-constant', [RakuAST::Package, '', 0, 0, str, '$name', 0, 0], anon sub implicit-constant ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 240 src/Raku/ast/package.rakumod RakuAST::VarDeclaration::Implicit::Constant.new( :$name, :value($SELF.stubbed-meta-object) ) }); add-method(RakuAST::Package, 'PRODUCE-STUBBED-META-OBJECT', [RakuAST::Package, '', 0, 0], anon sub PRODUCE-STUBBED-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 246 src/Raku/ast/package.rakumod if nqp::getattr($SELF, RakuAST::Package, '$!augmented') || $SELF.is-resolved { $SELF.resolution.compile-time-value; } else { # Create the type object and return it; this stubs the type. my %options; %options := nqp::getattr($SELF, RakuAST::Package, '$!name').canonicalize if nqp::getattr($SELF, RakuAST::Package, '$!name'); %options := nqp::getattr($SELF, RakuAST::Package, '$!repr') if nqp::getattr($SELF, RakuAST::Package, '$!repr'); if nqp::getattr($SELF, RakuAST::Package, '$!name') { for nqp::getattr($SELF, RakuAST::Package, '$!name').colonpairs { %options{$_.key} := $_.simple-compile-time-quote-value; } } nqp::getattr($SELF, RakuAST::Package, '$!how').new_type(|%options) } }); add-method(RakuAST::Package, 'PRODUCE-META-OBJECT', [RakuAST::Package, '', 0, 0], anon sub PRODUCE-META-OBJECT ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 264 src/Raku/ast/package.rakumod # Obtain the stubbed meta-object, which is the type object. my $type := $SELF.stubbed-meta-object(); my $how := $type.HOW; # Add methods and attributes. for nqp::getattr($SELF, RakuAST::Package, '$!attached-methods') { my $name := $_.name.canonicalize; my $meta-object := $_.meta-object; if nqp::istype($_, RakuAST::Method) && $_.private { $how.add_private_method($type, $name, $meta-object); } elsif nqp::istype($_, RakuAST::Method) && $_.meta { $how.add_meta_method($type, $name, $meta-object); } elsif $_.multiness eq 'multi' { $how.add_multi_method($type, $name, $meta-object); } else { $how.add_method($type, $name, $meta-object); } } for nqp::getattr($SELF, RakuAST::Package, '$!attached-attributes') { # TODO: create method BUILDALL here $how.add_attribute($type, $_.meta-object); } if $SELF.declarator eq 'role' { $how.set_body_block($type, nqp::getattr($SELF, RakuAST::Package, '$!body').meta-object); # The role needs to be composed before we add the possibility # to the group $how.compose($type); my $group := nqp::getattr($SELF, RakuAST::Package, '$!role-group'); $group.HOW.add_possibility($group, $type) unless $group =:= Mu; } else { # Compose the meta-object $how.compose($type); } # Return the meta-object $type }); add-method(RakuAST::Package, 'apply-implicit-block-semantics', [RakuAST::Package, '', 0, 0], anon sub apply-implicit-block-semantics ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 309 src/Raku/ast/package.rakumod unless nqp::getattr($SELF, RakuAST::Package, '$!block-semantics-applied') { $SELF.meta-object-as-body-lexicals('PACKAGE'); $SELF.additional-body-lexicals; nqp::bindattr($SELF,RakuAST::Package,'$!block-semantics-applied',1); } }); add-method(RakuAST::Package, 'additional-body-lexicals', [RakuAST::Package, '', 0, 0], anon sub additional-body-lexicals ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 319 src/Raku/ast/package.rakumod $SELF.meta-object-as-body-lexicals('CLASS') unless $SELF.declarator eq 'package'; }); add-method(RakuAST::Package, 'IMPL-EXPR-QAST', [RakuAST::Package, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 324 src/Raku/ast/package.rakumod my $type-object := $SELF.meta-object; $context.ensure-sc($type-object); my $body := nqp::getattr($SELF, RakuAST::Package, '$!body').IMPL-QAST-BLOCK($context, :blocktype); my $result := QAST::Stmts.new( $body, QAST::WVal.new( :value($type-object) ) ); $result }); add-method(RakuAST::Package, 'IMPL-INTERPRET', [RakuAST::Package, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 335 src/Raku/ast/package.rakumod $SELF.compile-time-value }); add-method(RakuAST::Package, 'IMPL-COMPOSE', [RakuAST::Package, '', 0, 0], anon sub IMPL-COMPOSE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 339 src/Raku/ast/package.rakumod $SELF.meta-object; # Ensure it's composed }); add-method(RakuAST::Package, 'visit-children', [RakuAST::Package, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 343 src/Raku/ast/package.rakumod $visitor(nqp::getattr($SELF, RakuAST::Package, '$!name')) if nqp::getattr($SELF, RakuAST::Package, '$!name'); $SELF.visit-traits($visitor); $visitor(nqp::getattr($SELF, RakuAST::Package, '$!body')); $visitor($SELF.WHY) if $SELF.WHY; }); add-method(RakuAST::Package, 'needs-sink-call', [RakuAST::Package, '', 0, 0], anon sub needs-sink-call ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 350 src/Raku/ast/package.rakumod (Bool.WHO) }); #line 23 src/Raku/ast/package.rakumod add-method(RakuAST::Package, 'repr', [], anon sub repr ($self) { nqp::getattr(nqp::decont($self), RakuAST::Package, '$!repr') }); #line 19 src/Raku/ast/package.rakumod add-method(RakuAST::Package, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Package, '$!name') }); #line 28 src/Raku/ast/package.rakumod add-method(RakuAST::Package, 'is-stub', [], anon sub is-stub ($self) { nqp::getattr(nqp::decont($self), RakuAST::Package, '$!is-stub') }); #line 22 src/Raku/ast/package.rakumod add-method(RakuAST::Package, 'how', [], anon sub how ($self) { nqp::getattr(nqp::decont($self), RakuAST::Package, '$!how') }); #line 20 src/Raku/ast/package.rakumod add-method(RakuAST::Package, 'body', [], anon sub body ($self) { nqp::getattr(nqp::decont($self), RakuAST::Package, '$!body') }); #line 24 src/Raku/ast/package.rakumod add-method(RakuAST::Package, 'augmented', [], anon sub augmented ($self) { nqp::getattr(nqp::decont($self), RakuAST::Package, '$!augmented') }); #line 21 src/Raku/ast/package.rakumod add-method(RakuAST::Package, 'attribute-type', [], anon sub attribute-type ($self) { nqp::getattr(nqp::decont($self), RakuAST::Package, '$!attribute-type') }); compose(RakuAST::Package); parent(RakuAST::Role, RakuAST::Package); add-method(RakuAST::Role, 'declarator', [RakuAST::Role, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 359 src/Raku/ast/package.rakumod "role" }); add-method(RakuAST::Role, 'default-how', [RakuAST::Role, '', 0, 0], anon sub default-how ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 360 src/Raku/ast/package.rakumod Metamodel::ParametricRoleHOW }); add-method(RakuAST::Role, 'can-have-methods', [RakuAST::Role, '', 0, 0], anon sub can-have-methods ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 362 src/Raku/ast/package.rakumod (Bool.WHO) }); add-method(RakuAST::Role, 'can-have-attributes', [RakuAST::Role, '', 0, 0], anon sub can-have-attributes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 363 src/Raku/ast/package.rakumod (Bool.WHO) }); add-method(RakuAST::Role, 'replace-body', [RakuAST::Role, '', 0, 0, RakuAST::Code, '$body', 0, 0, RakuAST::Signature, '$signature', 0, 0], anon sub replace-body ($SELF_CONT, $body!, $signature!) { my $SELF := nqp::decont($SELF_CONT); $body := nqp::decont($body); $signature := nqp::decont($signature); #line 365 src/Raku/ast/package.rakumod # The body of a role is internally a Sub that has the parameterization # of the role as the signature. This allows a role to be selected # using ordinary dispatch semantics. The statement list gets a return # value added, so that the role's meta-object and lexpad are returned. $signature := RakuAST::Signature.new unless $signature; $signature.set-is-on-role-body(1); $body := RakuAST::Block.new unless $body; $body := $body.body; $body.statement-list.add-statement( RakuAST::Statement::Expression.new( expression => RakuAST::Nqp.new('list', RakuAST::Declaration::ResolvedConstant.new( compile-time-value => $SELF.stubbed-meta-object ), RakuAST::Nqp.new('curlexpad') ) ) ); $body := RakuAST::Sub.new(:name($SELF.name), :$signature, :$body); nqp::bindattr($SELF, RakuAST::Package, '$!body', $body); Nil }); add-method(RakuAST::Role, 'parameterization', [RakuAST::Role, '', 0, 0], anon sub parameterization ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 391 src/Raku/ast/package.rakumod $SELF.body.signature }); add-method(RakuAST::Role, 'declare-lexicals', [RakuAST::Role, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub declare-lexicals ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 393 src/Raku/ast/package.rakumod $SELF.meta-object-as-lexicals($resolver, 'ROLE'); for '$?CLASS', '::?CLASS' { $resolver.declare-lexical( RakuAST::Type::Capture.new(RakuAST::Name.from-identifier($_)) ); } }); add-method(RakuAST::Role, 'install-in-scope', [RakuAST::Role, '', 0, 0, Any, '$resolver', 0, 0, Any, '$scope', 0, 0, Any, '$name', 0, 0, Any, '$full-name', 0, 0, Any, '$type-object', 0, 0], anon sub install-in-scope ($SELF_CONT, $resolver!, $scope!, $name!, $full-name!, $type-object!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $scope := nqp::decont($scope); $name := nqp::decont($name); $full-name := nqp::decont($full-name); $type-object := nqp::decont($type-object); #line 403 src/Raku/ast/package.rakumod # Find an appropriate existing role group my $group-name := $full-name.canonicalize(:colonpairs(0)); my $group := $resolver.resolve-lexical-constant($group-name); if $group { $group := $group.compile-time-value; } # No existing one found - create a role group else { $group := Perl6::Metamodel::ParametricRoleGroupHOW.new_type( :name($group-name), :repr($SELF.repr) ); my $outer := $resolver.find-attach-target('block') // $resolver.find-attach-target('compunit'); $outer.add-generated-lexical-declaration( RakuAST::VarDeclaration::Implicit::Constant.new( :name($name.canonicalize(:colonpairs(0))), :value($group) ) ); $SELF.IMPL-INSTALL-PACKAGE( $resolver, $scope, $name, $group, $resolver.current-package, :no-lexical ) if $scope eq 'our'; } # Add ourselves to the role group $type-object.HOW.set_group($type-object, $group); nqp::bindattr($SELF, RakuAST::Package, '$!role-group', $group); }); add-method(RakuAST::Role, 'additional-body-lexicals', [RakuAST::Role, '', 0, 0], anon sub additional-body-lexicals ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 435 src/Raku/ast/package.rakumod $SELF.meta-object-as-body-lexicals('ROLE'); }); compose(RakuAST::Role); parent(RakuAST::Class, RakuAST::Package); add-method(RakuAST::Class, 'declarator', [RakuAST::Class, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 446 src/Raku/ast/package.rakumod "class" }); add-method(RakuAST::Class, 'default-how', [RakuAST::Class, '', 0, 0], anon sub default-how ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 447 src/Raku/ast/package.rakumod Metamodel::ClassHOW }); add-method(RakuAST::Class, 'can-have-methods', [RakuAST::Class, '', 0, 0], anon sub can-have-methods ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 449 src/Raku/ast/package.rakumod (Bool.WHO) }); add-method(RakuAST::Class, 'can-have-attributes', [RakuAST::Class, '', 0, 0], anon sub can-have-attributes ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 450 src/Raku/ast/package.rakumod (Bool.WHO) }); add-method(RakuAST::Class, 'IMPL-COMPOSE', [RakuAST::Class, '', 0, 0], anon sub IMPL-COMPOSE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 452 src/Raku/ast/package.rakumod # create BUILDALL method if there's something to create, # otherwise put in a generic fallback BUILDALL that doesn't # do anything $SELF.meta-object; # Ensure it's composed }); compose(RakuAST::Class); parent(RakuAST::Grammar, RakuAST::Class); add-method(RakuAST::Grammar, 'declarator', [RakuAST::Grammar, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 466 src/Raku/ast/package.rakumod "grammar" }); add-method(RakuAST::Grammar, 'default-how', [RakuAST::Grammar, '', 0, 0], anon sub default-how ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 467 src/Raku/ast/package.rakumod Metamodel::GrammarHOW }); add-method(RakuAST::Grammar, 'IMPL-COMPOSE', [RakuAST::Grammar, '', 0, 0], anon sub IMPL-COMPOSE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 469 src/Raku/ast/package.rakumod $SELF.meta-object; # Ensure it's composed }); compose(RakuAST::Grammar); parent(RakuAST::Module, RakuAST::Package); add-method(RakuAST::Module, 'declarator', [RakuAST::Module, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 480 src/Raku/ast/package.rakumod "module" }); add-method(RakuAST::Module, 'default-how', [RakuAST::Module, '', 0, 0], anon sub default-how ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 481 src/Raku/ast/package.rakumod Metamodel::KnowHOW }); add-method(RakuAST::Module, 'declare-lexicals', [RakuAST::Module, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0], anon sub declare-lexicals ($SELF_CONT, $resolver!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); #line 483 src/Raku/ast/package.rakumod $SELF.meta-object-as-lexicals($resolver, 'MODULE'); }); add-method(RakuAST::Module, 'additional-body-lexicals', [RakuAST::Module, '', 0, 0], anon sub additional-body-lexicals ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 487 src/Raku/ast/package.rakumod $SELF.meta-object-as-body-lexicals('MODULE'); }); compose(RakuAST::Module); parent(RakuAST::Knowhow, RakuAST::Package); add-method(RakuAST::Knowhow, 'declarator', [RakuAST::Knowhow, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 498 src/Raku/ast/package.rakumod "knowhow" }); add-method(RakuAST::Knowhow, 'default-how', [RakuAST::Knowhow, '', 0, 0], anon sub default-how ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 499 src/Raku/ast/package.rakumod Metamodel::KnowHOW }); compose(RakuAST::Knowhow); parent(RakuAST::Native, RakuAST::Package); add-method(RakuAST::Native, 'declarator', [RakuAST::Native, '', 0, 0], anon sub declarator ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 508 src/Raku/ast/package.rakumod "native" }); add-method(RakuAST::Native, 'default-how', [RakuAST::Native, '', 0, 0], anon sub default-how ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 509 src/Raku/ast/package.rakumod Metamodel::NativeHOW }); compose(RakuAST::Native); parent(RakuAST::Literal, RakuAST::Term); parent(RakuAST::Literal, RakuAST::CompileTimeValue); add-attribute(RakuAST::Literal, Str, '$!typename'); add-attribute(RakuAST::Literal, Mu, '$!value'); add-method(RakuAST::Literal, 'new', [RakuAST::Literal, '', 0, 0, Mu, '$value', 0, 0], anon sub new ($SELF_CONT, $value!) { my $SELF := nqp::decont($SELF_CONT); $value := nqp::decont($value); #line 9 src/Raku/ast/literals.rakumod nqp::die("Please use RakuAST::Literal.from-value()") if nqp::eqaddr($SELF,RakuAST::Literal); my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Literal, '$!value', $value); nqp::bindattr($obj, RakuAST::Literal, '$!typename', nqp::null); $obj }); add-method(RakuAST::Literal, 'from-value', [RakuAST::Literal, '', 0, 0, Mu, '$value', 0, 0], anon sub from-value ($SELF_CONT, $value!) { my $SELF := nqp::decont($SELF_CONT); $value := nqp::decont($value); #line 19 src/Raku/ast/literals.rakumod my $typename := $value.HOW.name($value); my $obj := nqp::create(RakuAST.WHO{$typename ~ 'Literal'}); nqp::bindattr($obj, RakuAST::Literal, '$!value', $value); nqp::bindattr($obj, RakuAST::Literal, '$!typename', $typename); $obj }); add-method(RakuAST::Literal, 'set-value', [RakuAST::Literal, '', 0, 0, Mu, '$value', 0, 0], anon sub set-value ($SELF_CONT, $value!) { my $SELF := nqp::decont($SELF_CONT); $value := nqp::decont($value); #line 27 src/Raku/ast/literals.rakumod nqp::bindattr($SELF, RakuAST::Literal, '$!value', $value); }); add-method(RakuAST::Literal, 'expression', [RakuAST::Literal, '', 0, 0], anon sub expression ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 31 src/Raku/ast/literals.rakumod $SELF }); add-method(RakuAST::Literal, 'type', [RakuAST::Literal, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 32 src/Raku/ast/literals.rakumod nqp::getattr($SELF, RakuAST::Literal, '$!value').WHAT }); add-method(RakuAST::Literal, 'compile-time-value', [RakuAST::Literal, '', 0, 0], anon sub compile-time-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 33 src/Raku/ast/literals.rakumod nqp::getattr($SELF, RakuAST::Literal, '$!value') }); add-method(RakuAST::Literal, 'IMPL-CAN-INTERPRET', [RakuAST::Literal, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 34 src/Raku/ast/literals.rakumod (Bool.WHO) }); add-method(RakuAST::Literal, 'IMPL-INTERPRET', [RakuAST::Literal, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 35 src/Raku/ast/literals.rakumod nqp::getattr($SELF, RakuAST::Literal, '$!value') }); add-method(RakuAST::Literal, 'ast-type', [RakuAST::Literal, '', 0, 0], anon sub ast-type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 37 src/Raku/ast/literals.rakumod RakuAST::Type::Simple.new( RakuAST::Name.from-identifier( nqp::ifnull( nqp::getattr($SELF, RakuAST::Literal, '$!typename'), nqp::bindattr($SELF,RakuAST::Literal,'$!typename', nqp::getattr($SELF, RakuAST::Literal, '$!value').HOW.name(nqp::getattr($SELF, RakuAST::Literal, '$!value'))) ) ) ) }); add-method(RakuAST::Literal, 'IMPL-EXPR-QAST', [RakuAST::Literal, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 50 src/Raku/ast/literals.rakumod my $value := nqp::getattr($SELF, RakuAST::Literal, '$!value'); $context.ensure-sc($value); QAST::WVal.new( :$value ) }); #line 7 src/Raku/ast/literals.rakumod add-method(RakuAST::Literal, 'value', [], anon sub value ($self) { nqp::getattr(nqp::decont($self), RakuAST::Literal, '$!value') }); compose(RakuAST::Literal); parent(RakuAST::Constant, RakuAST::Literal); add-method(RakuAST::Constant, 'deparse', [RakuAST::Constant, '', 0, 0], anon sub deparse ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 61 src/Raku/ast/literals.rakumod $SELF.value.raku }); compose(RakuAST::Constant); parent(RakuAST::IntLiteral, RakuAST::Literal); add-method(RakuAST::IntLiteral, 'IMPL-EXPR-QAST', [RakuAST::IntLiteral, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 67 src/Raku/ast/literals.rakumod my $value := $SELF.value; $context.ensure-sc($value); my $wval := QAST::WVal.new( :$value ); nqp::isbig_I($value) ?? $wval !! QAST::Want.new( $wval, 'Ii', QAST::IVal.new(:value(nqp::unbox_i($value))) ) }); compose(RakuAST::IntLiteral); parent(RakuAST::NumLiteral, RakuAST::Literal); add-method(RakuAST::NumLiteral, 'IMPL-EXPR-QAST', [RakuAST::NumLiteral, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 84 src/Raku/ast/literals.rakumod my $value := $SELF.value; $context.ensure-sc($value); my $wval := QAST::WVal.new( :$value ); QAST::Want.new($wval,'Nn', QAST::NVal.new(:value(nqp::unbox_n($value)))) }); compose(RakuAST::NumLiteral); parent(RakuAST::RatLiteral, RakuAST::Literal); compose(RakuAST::RatLiteral); parent(RakuAST::ComplexLiteral, RakuAST::Literal); compose(RakuAST::ComplexLiteral); parent(RakuAST::VersionLiteral, RakuAST::Literal); compose(RakuAST::VersionLiteral); parent(RakuAST::ListLiteral, RakuAST::Literal); compose(RakuAST::ListLiteral); parent(RakuAST::MapLiteral, RakuAST::Literal); compose(RakuAST::MapLiteral); parent(RakuAST::StrLiteral, RakuAST::Literal); add-method(RakuAST::StrLiteral, 'IMPL-EXPR-QAST', [RakuAST::StrLiteral, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 118 src/Raku/ast/literals.rakumod my $value := $SELF.value; $context.ensure-sc($value); my $wval := QAST::WVal.new( :$value ); QAST::Want.new($wval,'Ss', QAST::SVal.new(:value(nqp::unbox_s($value)))) }); compose(RakuAST::StrLiteral); parent(RakuAST::QuotedString, RakuAST::ColonPairish); parent(RakuAST::QuotedString, RakuAST::Term); parent(RakuAST::QuotedString, RakuAST::ImplicitLookups); add-attribute(RakuAST::QuotedString, Mu, '$!segments'); add-attribute(RakuAST::QuotedString, Mu, '$!processors'); add-method(RakuAST::QuotedString, 'new', [RakuAST::QuotedString, '', 0, 0, List, '$segments', 1, 0, List, '$processors', 1, 1], anon sub new ($SELF_CONT, :$segments!, :$processors?) { my $SELF := nqp::decont($SELF_CONT); $segments := nqp::decont($segments); $processors := nqp::decont($processors); #line 138 src/Raku/ast/literals.rakumod nqp::create($SELF).SET-SELF($segments, $processors) }); add-method(RakuAST::QuotedString, 'SET-SELF', [RakuAST::QuotedString, '', 0, 0, List, '$segments', 0, 0, List, '$processors', 0, 0], anon sub SET-SELF ($SELF_CONT, $segments!, $processors!) { my $SELF := nqp::decont($SELF_CONT); $segments := nqp::decont($segments); $processors := nqp::decont($processors); #line 143 src/Raku/ast/literals.rakumod nqp::bindattr($SELF, RakuAST::QuotedString, '$!segments', $SELF.IMPL-UNWRAP-LIST($segments)); nqp::bindattr($SELF, RakuAST::QuotedString, '$!processors', $SELF.IMPL-CHECK-PROCESSORS($processors)); $SELF }); add-method(RakuAST::QuotedString, 'IMPL-CHECK-PROCESSORS', [RakuAST::QuotedString, '', 0, 0, Mu, '$processors', 0, 0], anon sub IMPL-CHECK-PROCESSORS ($SELF_CONT, $processors!) { my $SELF := nqp::decont($SELF_CONT); $processors := nqp::decont($processors); #line 151 src/Raku/ast/literals.rakumod my constant VALID := nqp::hash('words', Mu, 'quotewords', Mu, 'val', Mu, 'exec', Mu, 'heredoc', Mu, 'format', Mu); my @result; for $SELF.IMPL-UNWRAP-LIST($processors // []) { if nqp::existskey(VALID, $_) { nqp::push(@result, nqp::box_s($_, Str)); } else { nqp::die("Unsupported quoted string processor '$_'"); } } @result }); add-method(RakuAST::QuotedString, 'segments', [RakuAST::QuotedString, '', 0, 0], anon sub segments ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 165 src/Raku/ast/literals.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::QuotedString, '$!segments')) }); add-method(RakuAST::QuotedString, 'processors', [RakuAST::QuotedString, '', 0, 0], anon sub processors ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 169 src/Raku/ast/literals.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::QuotedString, '$!processors')) }); add-method(RakuAST::QuotedString, 'canonicalize', [RakuAST::QuotedString, '', 0, 0], anon sub canonicalize ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 173 src/Raku/ast/literals.rakumod $SELF.IMPL-QUOTE-VALUE($SELF.literal-value // '') }); add-method(RakuAST::QuotedString, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::QuotedString, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 177 src/Raku/ast/literals.rakumod my @needed; if nqp::elems(nqp::getattr($SELF, RakuAST::QuotedString, '$!processors')) { for nqp::getattr($SELF, RakuAST::QuotedString, '$!processors') { if $_ eq 'val' { nqp::push(@needed, RakuAST::Var::Lexical::Setting.new( :sigil<&>, :desigilname(RakuAST::Name.from-identifier('val')))); last; } elsif $_ eq 'format' { nqp::push(@needed, RakuAST::Var::Lexical::Setting.new( :desigilname(RakuAST::Name.from-identifier('Format')))); last; } } } $SELF.IMPL-WRAP-LIST(@needed) }); add-method(RakuAST::QuotedString, 'has-variables', [RakuAST::QuotedString, '', 0, 0], anon sub has-variables ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 197 src/Raku/ast/literals.rakumod for nqp::getattr($SELF, RakuAST::QuotedString, '$!segments') { return (Bool.WHO) if nqp::istype($_,RakuAST::Var); } (Bool.WHO) }); add-method(RakuAST::QuotedString, 'type', [RakuAST::QuotedString, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 204 src/Raku/ast/literals.rakumod if nqp::getattr($SELF, RakuAST::QuotedString, '$!processors') { # Can probably figure some of these out. Mu } else { # Always a string if no processors. Str } }); add-method(RakuAST::QuotedString, 'ast-type', [RakuAST::QuotedString, '', 0, 0], anon sub ast-type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 215 src/Raku/ast/literals.rakumod if nqp::getattr($SELF, RakuAST::QuotedString, '$!processors') { # Can probably figure some of these out. nqp::die('NYI ast-type of non-trivial quoted strings'); } else { # Always a string if no processors. RakuAST::Type::Simple.new(RakuAST::Name.from-identifier('Str')) } }); add-method(RakuAST::QuotedString, 'IMPL-PROCESS-PART', [RakuAST::QuotedString, '', 0, 0, Any, '$result', 0, 0, Any, '$part', 0, 0], anon sub IMPL-PROCESS-PART ($SELF_CONT, $result!, $part!) { my $SELF := nqp::decont($SELF_CONT); $result := nqp::decont($result); $part := nqp::decont($part); #line 226 src/Raku/ast/literals.rakumod return Nil if $part =:= Nil; for nqp::getattr($SELF, RakuAST::QuotedString, '$!processors') { if $_ eq 'words' { return Nil unless nqp::istype($part, Str); my @parts; for $part.WORDS_AUTODEREF.FLATTENABLE_LIST { nqp::push(@parts, $_); } $part := @parts; } elsif $_ eq 'quotewords' { return Nil unless nqp::istype($part, Str); #TODO actually implement special handling of « » my @parts; for $part.WORDS_AUTODEREF.FLATTENABLE_LIST { nqp::push(@parts, $_); } $part := @parts; } elsif $_ eq 'val' { my $val := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; $part := $val(nqp::hllizefor($part, 'Raku')); } elsif $_ eq 'heredoc' { } elsif $_ eq 'format' { } else { return Nil; } } if nqp::islist($part) { for $part { nqp::push($result, $_); } } elsif nqp::istype($part, List) { for $part.FLATTENABLE_LIST { nqp::push($result, $_); } } else { nqp::push($result, $part); } (Bool.WHO) }); add-method(RakuAST::QuotedString, 'literal-value', [RakuAST::QuotedString, '', 0, 0], anon sub literal-value ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 276 src/Raku/ast/literals.rakumod my @parts; for nqp::getattr($SELF, RakuAST::QuotedString, '$!segments') { if nqp::istype($_, RakuAST::StrLiteral) { $SELF.IMPL-PROCESS-PART(@parts, $_.value) || return Nil; } elsif nqp::istype($_, RakuAST::QuoteWordsAtom) && nqp::istype($_.atom, RakuAST::QuotedString) && my $nested-str := $_.atom.literal-value { return Nil if $nested-str =:= Nil; if nqp::istype($nested-str, Str) { nqp::push(@parts, $nested-str); } elsif nqp::istype($nested-str, List) { for $nested-str.FLATTENABLE_LIST { nqp::push(@parts, $_); } } } elsif nqp::istype($_, RakuAST::Var::Lexical) && $_.is-resolved && nqp::istype($_.resolution, RakuAST::VarDeclaration::Constant) { $SELF.IMPL-PROCESS-PART(@parts, $_.resolution.compile-time-value.Str) || return Nil; } else { return Nil; } } my int $return-list := 0; for nqp::getattr($SELF, RakuAST::QuotedString, '$!processors') { if $_ eq 'words' { $return-list := 1; } elsif $_ eq 'quotewords' { $return-list := 1; } elsif $_ eq 'val' && nqp::elems(@parts) == 1 { $return-list := 0; } } return $return-list ?? nqp::hllizefor(@parts, 'Raku') !! nqp::elems(@parts) == 1 ?? @parts[0] # need to preserve val() result !! nqp::box_s(nqp::join('', @parts), Str); }); add-method(RakuAST::QuotedString, 'is-empty-words', [RakuAST::QuotedString, '', 0, 0], anon sub is-empty-words ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 328 src/Raku/ast/literals.rakumod # Is it empty? return (Bool.WHO) if nqp::elems(nqp::getattr($SELF, RakuAST::QuotedString, '$!segments')) >= 2; if nqp::elems(nqp::getattr($SELF, RakuAST::QuotedString, '$!segments')) == 1 { my $seg := nqp::getattr($SELF, RakuAST::QuotedString, '$!segments')[0]; return (Bool.WHO) unless nqp::istype($seg, RakuAST::StrLiteral) && $seg.value eq ''; } # Yes, but is it quote words? for nqp::getattr($SELF, RakuAST::QuotedString, '$!processors') { if $_ eq 'words' { return (Bool.WHO); } } (Bool.WHO) }); add-method(RakuAST::QuotedString, 'dump-extras', [RakuAST::QuotedString, '', 0, 0, int, '$indent', 0, 0], anon sub dump-extras ($SELF_CONT, $indent!) { my $SELF := nqp::decont($SELF_CONT); $indent := nqp::decont($indent); #line 345 src/Raku/ast/literals.rakumod nqp::getattr($SELF, RakuAST::QuotedString, '$!processors') && nqp::elems(nqp::getattr($SELF, RakuAST::QuotedString, '$!processors')) ?? nqp::x(' ', $indent) ~ 'postprocessors: ' ~ nqp::join(', ', nqp::getattr($SELF, RakuAST::QuotedString, '$!processors')) ~ "\n" !! '' }); add-method(RakuAST::QuotedString, 'IMPL-EXPR-QAST', [RakuAST::QuotedString, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-EXPR-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 351 src/Raku/ast/literals.rakumod # If we can constant fold it, just produce the constant. my $literal-value := $SELF.literal-value; if nqp::isconcrete($literal-value) { # format string if nqp::getattr($SELF, RakuAST::QuotedString, '$!processors') && nqp::getattr($SELF, RakuAST::QuotedString, '$!processors')[0] eq 'format' { my $Format := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; # The below code "should" work, but doesn't because references to internal # subs (such as "str-right-justified") appear to be QASTed correctly, but # when executed, do *not* call the unit in question, but simply return the # arguments that were given. Not sure what is going on here. For now, # create the format at run-time: it will still get cached, but *will* incur # a performance penalty at runtime, which is too bad because the whole idea # of a quote string format, was to create all of this at compile time. # # my $format := $Format.new($literal-value); # $context.ensure-sc($format); # return QAST::WVal.new(:value($format)); # for now, until above fixed $context.ensure-sc($literal-value); return QAST::Op.new( :op('callmethod'), :name('new'), QAST::WVal.new( :value($Format) ), QAST::WVal.new( :value($literal-value) ) ); } $context.ensure-sc($literal-value); my $wval := QAST::WVal.new( :value($literal-value) ); return nqp::istype($literal-value, Str) ?? QAST::Want.new( $wval, 'Ss', QAST::SVal.new( :value(nqp::unbox_s($literal-value)) ) ) !! $wval; } # Otherwise, needs compilation. my @segment-asts; for nqp::getattr($SELF, RakuAST::QuotedString, '$!segments') { if $_.type =:= Str || nqp::istype($_, RakuAST::QuoteWordsAtom) { @segment-asts.push($_.IMPL-TO-QAST($context)); } else { my $inter-qast := $_.IMPL-TO-QAST($context); if nqp::istype($_, RakuAST::Block) { $inter-qast := QAST::Op.new( :op('call'), $inter-qast ); } @segment-asts.push(QAST::Op.new( :op('callmethod'), :name('Str'), $inter-qast )); } } my int $seg-count := nqp::elems(@segment-asts); my $qast; if $seg-count == 1 { $qast := @segment-asts[0]; } elsif $seg-count == 2 { $qast := QAST::Op.new( :op('concat'), @segment-asts[0], @segment-asts[1] ) } else { $qast := QAST::Op.new( :op('join'), QAST::SVal.new( :value('') ), QAST::Op.new( :op('list_s'), |@segment-asts ) ) } $SELF.IMPL-QAST-PROCESSORS($context, $qast) }); add-method(RakuAST::QuotedString, 'IMPL-WALK', [RakuAST::QuotedString, '', 0, 0, Any, '$context', 0, 0, Any, '$node', 0, 0, Any, '$result', 0, 0], anon sub IMPL-WALK ($SELF_CONT, $context!, $node!, $result!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $node := nqp::decont($node); $result := nqp::decont($result); #line 427 src/Raku/ast/literals.rakumod if $node.ann('ww_atom') { $result.push($node); } elsif nqp::istype($node, QAST::Op) && $node.name eq '&infix:<~>' { $SELF.IMPL-WALK($context, $node[0], $result); $SELF.IMPL-WALK($context, $node[1], $result); } elsif nqp::istype($node, QAST::Op) && $node.op eq 'concat' { $SELF.IMPL-WALK($context, $node[0], $result); $SELF.IMPL-WALK($context, $node[1], $result); } elsif nqp::istype($node, QAST::Op) && $node.op eq 'join' { for $node[1].list { $SELF.IMPL-WALK($context, $_, $result); } } # (can't just use postprocess_words here because it introduces spurious comma operations) elsif $node.has_compile_time_value { my @words := HLL::Grammar.split_words(nqp::unbox_s($node.compile_time_value)); for @words { $result.push(RakuAST::StrLiteral.new($_).IMPL-EXPR-QAST($context)); } } else { $result.push( QAST::Op.new( :op('callmethod'), :name('Slip'), QAST::Op.new( :op('callmethod'), :name('WORDS_AUTODEREF'), QAST::Op.new( :op('callmethod'), :name('Stringy'), $node ) ) ) ); } }); add-method(RakuAST::QuotedString, 'IMPL-QAST-PROCESSORS', [RakuAST::QuotedString, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$qast', 0, 0], anon sub IMPL-QAST-PROCESSORS ($SELF_CONT, $context!, $qast!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $qast := nqp::decont($qast); #line 470 src/Raku/ast/literals.rakumod # Non-optimized handling of processors. for nqp::getattr($SELF, RakuAST::QuotedString, '$!processors') { if $_ eq 'words' { $qast := QAST::Op.new( :op('callmethod'), :name('WORDS_AUTODEREF'), $qast ); } elsif $_ eq 'quotewords' { my $result := QAST::Op.new( :op('call'), :name('&infix:<,>') ); $SELF.IMPL-WALK($context, $qast, $result); # Strip out list op and possible Slip if only one resulting word $qast := nqp::elems($result) == 1 ?? nqp::istype($result[0], QAST::Op) && $result[0].name eq 'Slip' ?? $result[0][0] !! $result[0] !! QAST::Stmts.new( $result ); } elsif $_ eq 'val' { my $name := $SELF.get-implicit-lookups.AT-POS(0).resolution.lexical-name; $qast := QAST::Op.new(:op('call'), :$name, $qast); } elsif $_ eq 'exec' { $qast := QAST::Op.new( :op('call'), :name('&QX'), $qast ); } elsif $_ eq 'heredoc' { $qast := QAST::Op.new( :op('die_s'), QAST::SVal.new( :value("Premature heredoc consumption") ) ); } elsif $_ eq 'format' { my $Format := $SELF.get-implicit-lookups.AT-POS(0).resolution.compile-time-value; $qast := QAST::Op.new( :op('callmethod'), :name('new'), QAST::WVal.new( :value($Format)), $qast ); } else { nqp::die("Compiling processor '$_' is not implemented"); } } $qast }); add-method(RakuAST::QuotedString, 'visit-children', [RakuAST::QuotedString, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 519 src/Raku/ast/literals.rakumod my @segments := nqp::getattr($SELF, RakuAST::QuotedString, '$!segments'); for @segments { $visitor($_); } }); add-method(RakuAST::QuotedString, 'IMPL-CAN-INTERPRET', [RakuAST::QuotedString, '', 0, 0], anon sub IMPL-CAN-INTERPRET ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 526 src/Raku/ast/literals.rakumod nqp::isconcrete($SELF.literal-value) ?? (Bool.WHO) !! (Bool.WHO) }); add-method(RakuAST::QuotedString, 'IMPL-INTERPRET', [RakuAST::QuotedString, '', 0, 0, RakuAST::IMPL::InterpContext, '$ctx', 0, 0], anon sub IMPL-INTERPRET ($SELF_CONT, $ctx!) { my $SELF := nqp::decont($SELF_CONT); $ctx := nqp::decont($ctx); #line 530 src/Raku/ast/literals.rakumod $SELF.literal-value }); compose(RakuAST::QuotedString); parent(RakuAST::Heredoc, RakuAST::QuotedString); add-attribute(RakuAST::Heredoc, Str, '$!stop'); add-attribute(RakuAST::Heredoc, int, '$!indent'); add-method(RakuAST::Heredoc, 'new', [RakuAST::Heredoc, '', 0, 0, List, '$segments', 1, 0, List, '$processors', 1, 1, Str, '$stop', 1, 1], anon sub new ($SELF_CONT, :$segments!, :$processors?, :$stop?) { my $SELF := nqp::decont($SELF_CONT); $segments := nqp::decont($segments); $processors := nqp::decont($processors); $stop := nqp::decont($stop); #line 541 src/Raku/ast/literals.rakumod my $obj := nqp::create($SELF).SET-SELF($segments, $processors); nqp::bindattr($obj, RakuAST::Heredoc, '$!stop', $stop // ''); $obj }); add-method(RakuAST::Heredoc, 'replace-segments-from', [RakuAST::Heredoc, '', 0, 0, RakuAST::QuotedString, '$source', 0, 0], anon sub replace-segments-from ($SELF_CONT, $source!) { my $SELF := nqp::decont($SELF_CONT); $source := nqp::decont($source); #line 547 src/Raku/ast/literals.rakumod nqp::bindattr( $SELF, RakuAST::QuotedString, '$!segments', nqp::getattr($source, RakuAST::QuotedString, '$!segments') ); Nil }); add-method(RakuAST::Heredoc, 'steal-processors-from', [RakuAST::Heredoc, '', 0, 0, RakuAST::QuotedString, '$source', 0, 0], anon sub steal-processors-from ($SELF_CONT, $source!) { my $SELF := nqp::decont($SELF_CONT); $source := nqp::decont($source); #line 557 src/Raku/ast/literals.rakumod my $processors := nqp::getattr($SELF, RakuAST::QuotedString, '$!processors'); for $SELF.IMPL-UNWRAP-LIST($source.processors) { nqp::push($processors, $_); } # Also steal the implicit lookups as any processor related lookups will # have been done before we got to stealing those processors. nqp::bindattr( $SELF, RakuAST::ImplicitLookups, '$!implicit-lookups-cache', nqp::getattr($source, RakuAST::ImplicitLookups, '$!implicit-lookups-cache') ); }); add-method(RakuAST::Heredoc, 'set-stop', [RakuAST::Heredoc, '', 0, 0, Str, '$stop', 0, 0], anon sub set-stop ($SELF_CONT, $stop!) { my $SELF := nqp::decont($SELF_CONT); $stop := nqp::decont($stop); #line 572 src/Raku/ast/literals.rakumod nqp::bindattr($SELF, RakuAST::Heredoc, '$!stop', $stop); }); add-method(RakuAST::Heredoc, 'stop', [RakuAST::Heredoc, '', 0, 0], anon sub stop ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 575 src/Raku/ast/literals.rakumod nqp::getattr($SELF, RakuAST::Heredoc, '$!stop') }); add-method(RakuAST::Heredoc, 'set-indent', [RakuAST::Heredoc, '', 0, 0, int, '$indent', 0, 0], anon sub set-indent ($SELF_CONT, $indent!) { my $SELF := nqp::decont($SELF_CONT); $indent := nqp::decont($indent); #line 577 src/Raku/ast/literals.rakumod nqp::bindattr_i($SELF, RakuAST::Heredoc, '$!indent', $indent); }); add-method(RakuAST::Heredoc, 'trim', [RakuAST::Heredoc, '', 0, 0], anon sub trim ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 581 src/Raku/ast/literals.rakumod # Remove heredoc postprocessor to defuse the "Premature heredoc consumption" error my $processors := nqp::getattr($SELF, RakuAST::QuotedString, '$!processors'); my $new_processors := []; nqp::bindattr($SELF, RakuAST::QuotedString, '$!processors', $new_processors); for $processors { nqp::push($new_processors, $_) if $_ ne 'heredoc'; } if (nqp::getattr_i($SELF, RakuAST::Heredoc, '$!indent')) { my int $indent := -nqp::getattr_i($SELF, RakuAST::Heredoc, '$!indent'); my $in-fresh-line := 1; for $SELF.IMPL-UNWRAP-LIST($SELF.segments) { if nqp::istype($_, RakuAST::StrLiteral) && !nqp::istype($_, RakuAST::Heredoc::InterpolatedWhiteSpace) { if $in-fresh-line { $_.set-value($_.value.indent($indent)); } else { my $strval := $_.value; if $strval ~~ /\n/ { # we have more lines # add temporary indentation to the front, so every line will be indented my $strbox := nqp::box_s(nqp::x(" ", -$indent) ~ nqp::unbox_s($strval), Str); $in-fresh-line := 1; $_.set-value($strbox.indent($indent)); } } } else { $in-fresh-line := 0; } } } }); compose(RakuAST::Heredoc); parent(RakuAST::Heredoc::InterpolatedWhiteSpace, RakuAST::StrLiteral); compose(RakuAST::Heredoc::InterpolatedWhiteSpace); parent(RakuAST::QuoteWordsAtom, RakuAST::Node); add-attribute(RakuAST::QuoteWordsAtom, RakuAST::Node, '$!atom'); add-method(RakuAST::QuoteWordsAtom, 'new', [RakuAST::QuoteWordsAtom, '', 0, 0, RakuAST::Node, '$atom', 0, 0], anon sub new ($SELF_CONT, $atom!) { my $SELF := nqp::decont($SELF_CONT); $atom := nqp::decont($atom); #line 627 src/Raku/ast/literals.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::QuoteWordsAtom, '$!atom', $atom); $obj }); add-method(RakuAST::QuoteWordsAtom, 'type', [RakuAST::QuoteWordsAtom, '', 0, 0], anon sub type ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 633 src/Raku/ast/literals.rakumod nqp::getattr($SELF, RakuAST::QuoteWordsAtom, '$!atom').type }); add-method(RakuAST::QuoteWordsAtom, 'IMPL-TO-QAST', [RakuAST::QuoteWordsAtom, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-TO-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 637 src/Raku/ast/literals.rakumod my $qast := nqp::getattr($SELF, RakuAST::QuoteWordsAtom, '$!atom').IMPL-TO-QAST($context); $qast.annotate('ww_atom', 1); $qast }); add-method(RakuAST::QuoteWordsAtom, 'visit-children', [RakuAST::QuoteWordsAtom, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 643 src/Raku/ast/literals.rakumod $visitor(nqp::getattr($SELF, RakuAST::QuoteWordsAtom, '$!atom')) }); #line 625 src/Raku/ast/literals.rakumod add-method(RakuAST::QuoteWordsAtom, 'atom', [], anon sub atom ($self) { nqp::getattr(nqp::decont($self), RakuAST::QuoteWordsAtom, '$!atom') }); compose(RakuAST::QuoteWordsAtom); parent(RakuAST::Regex, RakuAST::Node); add-method(RakuAST::Regex, 'IMPL-REGEX-TOP-LEVEL-QAST', [RakuAST::Regex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$code-object', 0, 0, Any, '%mods', 0, 0, int, '$no-scan', 1, 1, Mu, '$body-qast', 1, 1, str, '$name', 1, 1], anon sub IMPL-REGEX-TOP-LEVEL-QAST ($SELF_CONT, $context!, $code-object!, %mods!, :$no-scan?, :$body-qast?, :$name?) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $code-object := nqp::decont($code-object); %mods := nqp::decont(%mods); $no-scan := nqp::decont($no-scan); $body-qast := nqp::decont($body-qast); $name := nqp::decont($name); #line 12 src/Raku/ast/regex.rakumod # Compile the regex. my $regex-qast := $body-qast // $SELF.IMPL-REGEX-QAST($context, %mods); # Store its captures and NFA. $code-object.SET_CAPS(QRegex::P6Regex::Actions.capnames($regex-qast, 0)); # TODO top-level NFA if applicable (e.g. if named rule) QRegex::P6Regex::Actions.alt_nfas($code-object, $regex-qast, $context.sc-handle); # Wrap in scan/pass as appropriate. my $wrap-qast := QAST::Regex.new( :rxtype('concat'), $regex-qast, ($name ?? QAST::Regex.new(:rxtype('pass'), :$name) !! QAST::Regex.new(:rxtype('pass')) ) ); unless $no-scan { $wrap-qast.unshift(QAST::Regex.new( :rxtype('scan') )); } $wrap-qast }); add-method(RakuAST::Regex, 'IMPL-REGEX-BLOCK-CALL', [RakuAST::Regex, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, RakuAST::Block, '$block', 0, 0], anon sub IMPL-REGEX-BLOCK-CALL ($SELF_CONT, $context!, $block!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $block := nqp::decont($block); #line 36 src/Raku/ast/regex.rakumod QAST::Stmts.new( QAST::Op.new( :op('p6store'), QAST::Var.new( :name('$/'), :scope ), QAST::Op.new( QAST::Var.new( :name('$¢'), :scope ), :name('MATCH'), :op('callmethod') ) ), $block.IMPL-TO-QAST($context, :immediate) ) }); add-method(RakuAST::Regex, 'IMPL-APPLY-LITERAL-MODS', [RakuAST::Regex, '', 0, 0, Mu, '$qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-APPLY-LITERAL-MODS ($SELF_CONT, $qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $qast := nqp::decont($qast); %mods := nqp::decont(%mods); #line 51 src/Raku/ast/regex.rakumod if %mods && %mods { $qast.subtype('ignorecase+ignoremark') } elsif %mods { $qast.subtype('ignorecase') } elsif %mods { $qast.subtype('ignoremark') } $qast }); add-method(RakuAST::Regex, 'IMPL-SUBRULE-ALIAS', [RakuAST::Regex, '', 0, 0, Mu, '$qast', 0, 0, str, '$name', 0, 0], anon sub IMPL-SUBRULE-ALIAS ($SELF_CONT, $qast!, $name!) { my $SELF := nqp::decont($SELF_CONT); $qast := nqp::decont($qast); $name := nqp::decont($name); #line 64 src/Raku/ast/regex.rakumod if $qast.name gt '' { $qast.name($name ~ '=' ~ $qast.name); } else { $qast.name($name); } $qast.subtype('capture'); $qast }); compose(RakuAST::Regex); parent(RakuAST::Regex::Branching, RakuAST::Regex); add-attribute(RakuAST::Regex::Branching, Mu, '$!branches'); add-method(RakuAST::Regex::Branching, 'new', [RakuAST::Regex::Branching, '', 0, 0, Any, '@branches', 0, 0], anon sub new ($SELF_CONT, *@branches) { my $SELF := nqp::decont($SELF_CONT); @branches := nqp::decont(@branches); #line 82 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Branching, '$!branches', @branches); $obj }); add-method(RakuAST::Regex::Branching, 'branches', [RakuAST::Regex::Branching, '', 0, 0], anon sub branches ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 89 src/Raku/ast/regex.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Regex::Branching, '$!branches')) }); add-method(RakuAST::Regex::Branching, 'IMPL-REGEX-QAST', [RakuAST::Regex::Branching, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 93 src/Raku/ast/regex.rakumod my $qast := QAST::Regex.new(:rxtype($SELF.IMPL-QAST-REGEX-TYPE)); for nqp::getattr($SELF, RakuAST::Regex::Branching, '$!branches') { my $branch-qast := $_.IMPL-REGEX-QAST($context, %mods); $branch-qast.backtrack('r') if %mods && !$branch-qast.backtrack; $qast.push($branch-qast); } $qast }); add-method(RakuAST::Regex::Branching, 'visit-children', [RakuAST::Regex::Branching, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 103 src/Raku/ast/regex.rakumod for nqp::getattr($SELF, RakuAST::Regex::Branching, '$!branches') { $visitor($_); } }); compose(RakuAST::Regex::Branching); parent(RakuAST::Regex::SequentialAlternation, RakuAST::Regex::Branching); add-method(RakuAST::Regex::SequentialAlternation, 'IMPL-QAST-REGEX-TYPE', [RakuAST::Regex::SequentialAlternation, '', 0, 0], anon sub IMPL-QAST-REGEX-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 114 src/Raku/ast/regex.rakumod 'altseq' }); compose(RakuAST::Regex::SequentialAlternation); parent(RakuAST::Regex::SequentialConjunction, RakuAST::Regex::Branching); add-method(RakuAST::Regex::SequentialConjunction, 'IMPL-QAST-REGEX-TYPE', [RakuAST::Regex::SequentialConjunction, '', 0, 0], anon sub IMPL-QAST-REGEX-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 121 src/Raku/ast/regex.rakumod 'conjseq' }); compose(RakuAST::Regex::SequentialConjunction); parent(RakuAST::Regex::Alternation, RakuAST::Regex::Branching); add-method(RakuAST::Regex::Alternation, 'IMPL-QAST-REGEX-TYPE', [RakuAST::Regex::Alternation, '', 0, 0], anon sub IMPL-QAST-REGEX-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 128 src/Raku/ast/regex.rakumod 'alt' }); compose(RakuAST::Regex::Alternation); parent(RakuAST::Regex::Conjunction, RakuAST::Regex::Branching); add-method(RakuAST::Regex::Conjunction, 'IMPL-QAST-REGEX-TYPE', [RakuAST::Regex::Conjunction, '', 0, 0], anon sub IMPL-QAST-REGEX-TYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 135 src/Raku/ast/regex.rakumod 'conj' }); compose(RakuAST::Regex::Conjunction); parent(RakuAST::Regex::Sequence, RakuAST::Regex); add-attribute(RakuAST::Regex::Sequence, Mu, '$!terms'); add-method(RakuAST::Regex::Sequence, 'new', [RakuAST::Regex::Sequence, '', 0, 0, Any, '@atoms', 0, 0], anon sub new ($SELF_CONT, *@atoms) { my $SELF := nqp::decont($SELF_CONT); @atoms := nqp::decont(@atoms); #line 144 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); my @terms; my @literals; my sub handle-literals($with-whitespace) { my $literal := RakuAST::Regex::Literal.new(nqp::join('',@literals)); @terms.push($with-whitespace ?? RakuAST::Regex::WithWhitespace.new($literal) !! $literal ); nqp::setelems(@literals, 0); } for @atoms { if nqp::istype($_, RakuAST::Regex::Literal) { @literals.push($_.text); } elsif nqp::istype($_, RakuAST::Regex::WithWhitespace) { my $regex := $_.regex; if nqp::istype($regex, RakuAST::Regex::Literal) && @literals { @literals.push($regex.text); handle-literals((Bool.WHO)); } else { handle-literals((Bool.WHO)) if @literals; @terms.push($_); } } else { handle-literals((Bool.WHO)) if @literals; @terms.push($_); } } handle-literals((Bool.WHO)) if @literals; nqp::bindattr($obj, RakuAST::Regex::Sequence, '$!terms', @terms); $obj }); add-method(RakuAST::Regex::Sequence, 'terms', [RakuAST::Regex::Sequence, '', 0, 0], anon sub terms ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 185 src/Raku/ast/regex.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Regex::Sequence, '$!terms')) }); add-method(RakuAST::Regex::Sequence, 'IMPL-REGEX-QAST', [RakuAST::Regex::Sequence, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 189 src/Raku/ast/regex.rakumod my $concat := QAST::Regex.new(:rxtype); my str $collect-literals := ''; for nqp::getattr($SELF, RakuAST::Regex::Sequence, '$!terms') { if nqp::istype($_, RakuAST::Regex::Literal) { $collect-literals := $collect-literals ~ $_.text; } else { if $collect-literals ne '' { $concat.push($SELF.IMPL-LIT($collect-literals, %mods)); $collect-literals := ''; } my $qast := $_.IMPL-REGEX-QAST($context, %mods); if $qast { $qast.backtrack('r') if %mods && !$qast.backtrack; $concat.push($qast); } } } if $collect-literals ne '' { $concat.push($SELF.IMPL-LIT($collect-literals, %mods)); } $concat }); add-method(RakuAST::Regex::Sequence, 'IMPL-LIT', [RakuAST::Regex::Sequence, '', 0, 0, str, '$text', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-LIT ($SELF_CONT, $text!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $text := nqp::decont($text); %mods := nqp::decont(%mods); #line 214 src/Raku/ast/regex.rakumod $SELF.IMPL-APPLY-LITERAL-MODS: QAST::Regex.new( :rxtype, $text ), %mods }); add-method(RakuAST::Regex::Sequence, 'visit-children', [RakuAST::Regex::Sequence, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 220 src/Raku/ast/regex.rakumod for nqp::getattr($SELF, RakuAST::Regex::Sequence, '$!terms') { $visitor($_); } }); compose(RakuAST::Regex::Sequence); parent(RakuAST::Regex::Term, RakuAST::Regex); add-method(RakuAST::Regex::Term, 'whitespace-wrappable', [RakuAST::Regex::Term, '', 0, 0], anon sub whitespace-wrappable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 231 src/Raku/ast/regex.rakumod (Bool.WHO) }); compose(RakuAST::Regex::Term); parent(RakuAST::Regex::Atom, RakuAST::Regex::Term); add-method(RakuAST::Regex::Atom, 'quantifiable', [RakuAST::Regex::Atom, '', 0, 0], anon sub quantifiable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 238 src/Raku/ast/regex.rakumod (Bool.WHO) }); compose(RakuAST::Regex::Atom); parent(RakuAST::Regex::Literal, RakuAST::Regex::Atom); add-attribute(RakuAST::Regex::Literal, str, '$!text'); add-method(RakuAST::Regex::Literal, 'new', [RakuAST::Regex::Literal, '', 0, 0, str, '$text', 0, 0], anon sub new ($SELF_CONT, $text!) { my $SELF := nqp::decont($SELF_CONT); $text := nqp::decont($text); #line 247 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Regex::Literal, '$!text', $text); $obj }); add-method(RakuAST::Regex::Literal, 'IMPL-REGEX-QAST', [RakuAST::Regex::Literal, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 253 src/Raku/ast/regex.rakumod $SELF.IMPL-APPLY-LITERAL-MODS: QAST::Regex.new( :rxtype, nqp::getattr_s($SELF, RakuAST::Regex::Literal, '$!text') ), %mods }); #line 245 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Literal, 'text', [], anon sub text ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Regex::Literal, '$!text') }); compose(RakuAST::Regex::Literal); parent(RakuAST::Regex::Quote, RakuAST::Regex::Atom); add-attribute(RakuAST::Regex::Quote, RakuAST::QuotedString, '$!quoted'); add-method(RakuAST::Regex::Quote, 'new', [RakuAST::Regex::Quote, '', 0, 0, RakuAST::QuotedString, '$quoted', 0, 0], anon sub new ($SELF_CONT, $quoted!) { my $SELF := nqp::decont($SELF_CONT); $quoted := nqp::decont($quoted); #line 268 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Quote, '$!quoted', $quoted); $obj }); add-method(RakuAST::Regex::Quote, 'IMPL-REGEX-QAST', [RakuAST::Regex::Quote, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 274 src/Raku/ast/regex.rakumod my $literal-value := nqp::getattr($SELF, RakuAST::Regex::Quote, '$!quoted').literal-value; if nqp::isconcrete($literal-value) { if nqp::istype($literal-value, Str) { # Really simple string; just match it. $SELF.IMPL-APPLY-LITERAL-MODS: QAST::Regex.new( :rxtype, $literal-value ), %mods } elsif nqp::istype($literal-value, List) { # Quote words alternation. my $alt := QAST::Regex.new( :rxtype ); for $SELF.IMPL-UNWRAP-LIST($literal-value) { $alt.push: $SELF.IMPL-APPLY-LITERAL-MODS: QAST::Regex.new( :rxtype, $_ ), %mods } $alt } else { nqp::die('Unexpected quoted string literal value type in regex quote; got ' ~ $literal-value.HOW.name($literal-value)); } } else { if $SELF.IMPL-UNWRAP-LIST(nqp::getattr($SELF, RakuAST::Regex::Quote, '$!quoted').processors) { # Somehow, overly complex quote words construct. Weird. nqp::die('Unsupported quoted string literal in regex quote'); } else { # Complex string that needs interpolation. QAST::Regex.new( :rxtype, :subtype, QAST::NodeList.new( QAST::SVal.new( :value('!LITERAL') ), nqp::getattr($SELF, RakuAST::Regex::Quote, '$!quoted').IMPL-TO-QAST($context), QAST::IVal.new( :value(%mods ?? 1 !! 0) ) ) ) } } }); add-method(RakuAST::Regex::Quote, 'visit-children', [RakuAST::Regex::Quote, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 317 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Quote, '$!quoted')); }); #line 266 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Quote, 'quoted', [], anon sub quoted ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Quote, '$!quoted') }); compose(RakuAST::Regex::Quote); parent(RakuAST::Regex::Group, RakuAST::Regex::Atom); add-attribute(RakuAST::Regex::Group, RakuAST::Regex, '$!regex'); add-method(RakuAST::Regex::Group, 'new', [RakuAST::Regex::Group, '', 0, 0, RakuAST::Regex, '$regex', 0, 0], anon sub new ($SELF_CONT, $regex!) { my $SELF := nqp::decont($SELF_CONT); $regex := nqp::decont($regex); #line 328 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Group, '$!regex', $regex); $obj }); add-method(RakuAST::Regex::Group, 'IMPL-REGEX-QAST', [RakuAST::Regex::Group, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 334 src/Raku/ast/regex.rakumod nqp::getattr($SELF, RakuAST::Regex::Group, '$!regex').IMPL-REGEX-QAST($context, nqp::clone(%mods)) }); add-method(RakuAST::Regex::Group, 'visit-children', [RakuAST::Regex::Group, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 338 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Group, '$!regex')); }); #line 326 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Group, 'regex', [], anon sub regex ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Group, '$!regex') }); compose(RakuAST::Regex::Group); parent(RakuAST::Regex::CapturingGroup, RakuAST::Regex::Atom); parent(RakuAST::Regex::CapturingGroup, RakuAST::RegexThunk); add-attribute(RakuAST::Regex::CapturingGroup, RakuAST::Regex, '$!regex'); add-attribute(RakuAST::Regex::CapturingGroup, str, '$!unique-name'); add-attribute(RakuAST::Regex::CapturingGroup, Mu, '$!body-qast'); add-method(RakuAST::Regex::CapturingGroup, 'new', [RakuAST::Regex::CapturingGroup, '', 0, 0, RakuAST::Regex, '$regex', 0, 0], anon sub new ($SELF_CONT, $regex!) { my $SELF := nqp::decont($SELF_CONT); $regex := nqp::decont($regex); #line 354 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::CapturingGroup, '$!regex', $regex); $obj }); add-method(RakuAST::Regex::CapturingGroup, 'IMPL-UNIQUE-NAME', [RakuAST::Regex::CapturingGroup, '', 0, 0], anon sub IMPL-UNIQUE-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 360 src/Raku/ast/regex.rakumod my str $unique-name := nqp::getattr_s($SELF, RakuAST::Regex::CapturingGroup, '$!unique-name'); unless $unique-name { nqp::bindattr_s($SELF, RakuAST::Regex::CapturingGroup, '$!unique-name', ($unique-name := QAST::Node.unique('!__REGEX_CAPTURE_'))); } $unique-name }); add-method(RakuAST::Regex::CapturingGroup, 'IMPL-THUNKED-REGEX-QAST', [RakuAST::Regex::CapturingGroup, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-THUNKED-REGEX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 369 src/Raku/ast/regex.rakumod nqp::getattr($SELF, RakuAST::Regex::CapturingGroup, '$!regex').IMPL-REGEX-TOP-LEVEL-QAST($context, $SELF.meta-object, nqp::hash(), :body-qast(nqp::getattr($SELF, RakuAST::Regex::CapturingGroup, '$!body-qast') // nqp::die('Misordered regex compilation')), :no-scan); }); add-method(RakuAST::Regex::CapturingGroup, 'IMPL-QAST-DECL-CODE', [RakuAST::Regex::CapturingGroup, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL-CODE ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 375 src/Raku/ast/regex.rakumod # Form the block itself and link it with the meta-object. Install it # in the lexpad; we'll look it up when we need it. This means we can # avoid closure-cloning it per time we enter it, for example if it is # quantified. my str $name := $SELF.IMPL-UNIQUE-NAME; my $block := $SELF.IMPL-QAST-FORM-BLOCK($context, :blocktype('declaration_static')); $SELF.IMPL-LINK-META-OBJECT($context, $block); QAST::Stmts.new( $block, QAST::Op.new( :op('bind'), QAST::Var.new( :decl, :scope, :$name ), $SELF.IMPL-CLOSURE-QAST($context) ) ) }); add-method(RakuAST::Regex::CapturingGroup, 'IMPL-REGEX-QAST', [RakuAST::Regex::CapturingGroup, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 393 src/Raku/ast/regex.rakumod my str $name := $SELF.IMPL-UNIQUE-NAME; my $body-qast := nqp::getattr($SELF, RakuAST::Regex::CapturingGroup, '$!regex').IMPL-REGEX-QAST($context, nqp::clone(%mods)); nqp::bindattr($SELF, RakuAST::Regex::CapturingGroup, '$!body-qast', $body-qast); QAST::Regex.new( :rxtype('subrule'), :subtype('capture'), QAST::NodeList.new(QAST::Var.new( :$name, :scope('lexical') )), $body-qast ) }); add-method(RakuAST::Regex::CapturingGroup, 'visit-children', [RakuAST::Regex::CapturingGroup, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 404 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::CapturingGroup, '$!regex')); }); #line 348 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CapturingGroup, 'regex', [], anon sub regex ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::CapturingGroup, '$!regex') }); compose(RakuAST::Regex::CapturingGroup); parent(RakuAST::Regex::NamedCapture, RakuAST::Regex::Atom); add-attribute(RakuAST::Regex::NamedCapture, str, '$!name'); add-attribute(RakuAST::Regex::NamedCapture, Bool, '$!array'); add-attribute(RakuAST::Regex::NamedCapture, RakuAST::Term, '$!regex'); add-method(RakuAST::Regex::NamedCapture, 'new', [RakuAST::Regex::NamedCapture, '', 0, 0, str, '$name', 1, 0, Bool, '$array', 1, 1, RakuAST::Term, '$regex', 1, 0], anon sub new ($SELF_CONT, :$name!, :$array?, :$regex!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $array := nqp::decont($array); $regex := nqp::decont($regex); #line 417 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Regex::NamedCapture, '$!name', $name); nqp::bindattr($obj, RakuAST::Regex::NamedCapture, '$!array', $array ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Regex::NamedCapture, '$!regex', $regex); $obj }); add-method(RakuAST::Regex::NamedCapture, 'IMPL-REGEX-QAST', [RakuAST::Regex::NamedCapture, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 426 src/Raku/ast/regex.rakumod my $qast := nqp::getattr($SELF, RakuAST::Regex::NamedCapture, '$!regex').IMPL-REGEX-QAST($context, %mods); if ($qast.rxtype eq 'quant' || $qast.rxtype eq 'dynquant') && $qast[0].rxtype eq 'subrule' { $SELF.IMPL-SUBRULE-ALIAS($qast[0], nqp::getattr_s($SELF, RakuAST::Regex::NamedCapture, '$!name')); } elsif $qast.rxtype eq 'subrule' { $SELF.IMPL-SUBRULE-ALIAS($qast, nqp::getattr_s($SELF, RakuAST::Regex::NamedCapture, '$!name')); $qast := QAST::Regex.new( :rxtype, :min(1), :max(1), $qast) if nqp::getattr($SELF, RakuAST::Regex::NamedCapture, '$!array'); } else { $qast := QAST::Regex.new( :rxtype, :name(nqp::getattr_s($SELF, RakuAST::Regex::NamedCapture, '$!name')), $qast ); } $qast }); add-method(RakuAST::Regex::NamedCapture, 'visit-children', [RakuAST::Regex::NamedCapture, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 442 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::NamedCapture, '$!regex')); }); #line 415 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::NamedCapture, 'regex', [], anon sub regex ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::NamedCapture, '$!regex') }); #line 413 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::NamedCapture, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Regex::NamedCapture, '$!name') }); #line 414 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::NamedCapture, 'array', [], anon sub array ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::NamedCapture, '$!array') }); compose(RakuAST::Regex::NamedCapture); parent(RakuAST::Regex::Anchor, RakuAST::Regex::Atom); add-method(RakuAST::Regex::Anchor, 'new', [RakuAST::Regex::Anchor, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 451 src/Raku/ast/regex.rakumod nqp::create($SELF) }); add-method(RakuAST::Regex::Anchor, 'quantifiable', [RakuAST::Regex::Anchor, '', 0, 0], anon sub quantifiable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 455 src/Raku/ast/regex.rakumod (Bool.WHO) }); add-method(RakuAST::Regex::Anchor, 'IMPL-REGEX-QAST', [RakuAST::Regex::Anchor, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 457 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :subtype($SELF.IMPL-QAST-SUBTYPE) ) }); compose(RakuAST::Regex::Anchor); parent(RakuAST::Regex::Anchor::BeginningOfString, RakuAST::Regex::Anchor); add-method(RakuAST::Regex::Anchor::BeginningOfString, 'IMPL-QAST-SUBTYPE', [RakuAST::Regex::Anchor::BeginningOfString, '', 0, 0], anon sub IMPL-QAST-SUBTYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 466 src/Raku/ast/regex.rakumod 'bos' }); compose(RakuAST::Regex::Anchor::BeginningOfString); parent(RakuAST::Regex::Anchor::BeginningOfLine, RakuAST::Regex::Anchor); add-method(RakuAST::Regex::Anchor::BeginningOfLine, 'IMPL-QAST-SUBTYPE', [RakuAST::Regex::Anchor::BeginningOfLine, '', 0, 0], anon sub IMPL-QAST-SUBTYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 473 src/Raku/ast/regex.rakumod 'bol' }); compose(RakuAST::Regex::Anchor::BeginningOfLine); parent(RakuAST::Regex::Anchor::EndOfString, RakuAST::Regex::Anchor); add-method(RakuAST::Regex::Anchor::EndOfString, 'IMPL-QAST-SUBTYPE', [RakuAST::Regex::Anchor::EndOfString, '', 0, 0], anon sub IMPL-QAST-SUBTYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 480 src/Raku/ast/regex.rakumod 'eos' }); compose(RakuAST::Regex::Anchor::EndOfString); parent(RakuAST::Regex::Anchor::EndOfLine, RakuAST::Regex::Anchor); add-method(RakuAST::Regex::Anchor::EndOfLine, 'IMPL-QAST-SUBTYPE', [RakuAST::Regex::Anchor::EndOfLine, '', 0, 0], anon sub IMPL-QAST-SUBTYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 487 src/Raku/ast/regex.rakumod 'eol' }); compose(RakuAST::Regex::Anchor::EndOfLine); parent(RakuAST::Regex::Anchor::LeftWordBoundary, RakuAST::Regex::Anchor); add-method(RakuAST::Regex::Anchor::LeftWordBoundary, 'IMPL-QAST-SUBTYPE', [RakuAST::Regex::Anchor::LeftWordBoundary, '', 0, 0], anon sub IMPL-QAST-SUBTYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 494 src/Raku/ast/regex.rakumod 'lwb' }); compose(RakuAST::Regex::Anchor::LeftWordBoundary); parent(RakuAST::Regex::Anchor::RightWordBoundary, RakuAST::Regex::Anchor); add-method(RakuAST::Regex::Anchor::RightWordBoundary, 'IMPL-QAST-SUBTYPE', [RakuAST::Regex::Anchor::RightWordBoundary, '', 0, 0], anon sub IMPL-QAST-SUBTYPE ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 501 src/Raku/ast/regex.rakumod 'rwb' }); compose(RakuAST::Regex::Anchor::RightWordBoundary); parent(RakuAST::Regex::MatchFrom, RakuAST::Regex::Atom); add-method(RakuAST::Regex::MatchFrom, 'new', [RakuAST::Regex::MatchFrom, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 508 src/Raku/ast/regex.rakumod nqp::create($SELF) }); add-method(RakuAST::Regex::MatchFrom, 'quantifiable', [RakuAST::Regex::MatchFrom, '', 0, 0], anon sub quantifiable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 512 src/Raku/ast/regex.rakumod (Bool.WHO) }); add-method(RakuAST::Regex::MatchFrom, 'IMPL-REGEX-QAST', [RakuAST::Regex::MatchFrom, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 514 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :subtype, :backtrack, :name('$!from'), QAST::NodeList.new( QAST::SVal.new( :value('!LITERAL') ), QAST::SVal.new( :value('') ) ) ); }); compose(RakuAST::Regex::MatchFrom); parent(RakuAST::Regex::MatchTo, RakuAST::Regex::Atom); add-method(RakuAST::Regex::MatchTo, 'new', [RakuAST::Regex::MatchTo, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 527 src/Raku/ast/regex.rakumod nqp::create($SELF) }); add-method(RakuAST::Regex::MatchTo, 'quantifiable', [RakuAST::Regex::MatchTo, '', 0, 0], anon sub quantifiable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 531 src/Raku/ast/regex.rakumod (Bool.WHO) }); add-method(RakuAST::Regex::MatchTo, 'IMPL-REGEX-QAST', [RakuAST::Regex::MatchTo, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 533 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :subtype, :backtrack, :name('$!to'), QAST::NodeList.new( QAST::SVal.new( :value('!LITERAL') ), QAST::SVal.new( :value('') ) ) ); }); compose(RakuAST::Regex::MatchTo); parent(RakuAST::Regex::CharClass, RakuAST::Regex::Atom); add-method(RakuAST::Regex::CharClass, 'new', [RakuAST::Regex::CharClass, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 549 src/Raku/ast/regex.rakumod nqp::create($SELF) }); compose(RakuAST::Regex::CharClass); parent(RakuAST::Regex::CharClass::Any, RakuAST::Regex::CharClass); add-method(RakuAST::Regex::CharClass::Any, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::Any, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 558 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :name<.> ) }); compose(RakuAST::Regex::CharClass::Any); parent(RakuAST::Regex::CharClass::Negatable, RakuAST::Regex::CharClass); add-attribute(RakuAST::Regex::CharClass::Negatable, Bool, '$!negated'); add-method(RakuAST::Regex::CharClass::Negatable, 'new', [RakuAST::Regex::CharClass::Negatable, '', 0, 0, Bool, '$negated', 1, 1], anon sub new ($SELF_CONT, :$negated?) { my $SELF := nqp::decont($SELF_CONT); $negated := nqp::decont($negated); #line 569 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::CharClass::Negatable, '$!negated', $negated ?? (Bool.WHO) !! (Bool.WHO)); $obj }); #line 567 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClass::Negatable, 'negated', [], anon sub negated ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::CharClass::Negatable, '$!negated') }); compose(RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClassEnumerationElement, RakuAST::Node); add-method(RakuAST::Regex::CharClassEnumerationElement, 'IMPL-CCLASS-ENUM-CHARS', [RakuAST::Regex::CharClassEnumerationElement, '', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-CCLASS-ENUM-CHARS ($SELF_CONT, %mods!) { my $SELF := nqp::decont($SELF_CONT); %mods := nqp::decont(%mods); #line 582 src/Raku/ast/regex.rakumod '' }); add-method(RakuAST::Regex::CharClassEnumerationElement, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClassEnumerationElement, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 584 src/Raku/ast/regex.rakumod nqp::die("Missing IMPL-CCLASS-ENUM-QAST implementation on " ~ $SELF.HOW.name($SELF)); }); add-method(RakuAST::Regex::CharClassEnumerationElement, 'IMPL-MAYBE-NEGATE', [RakuAST::Regex::CharClassEnumerationElement, '', 0, 0, Mu, '$qast', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-MAYBE-NEGATE ($SELF_CONT, $qast!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $qast := nqp::decont($qast); $negate := nqp::decont($negate); #line 588 src/Raku/ast/regex.rakumod $qast.negate(!$qast.negate) if $negate; $qast }); add-method(RakuAST::Regex::CharClassEnumerationElement, 'range-endpoint', [RakuAST::Regex::CharClassEnumerationElement, '', 0, 0], anon sub range-endpoint ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 596 src/Raku/ast/regex.rakumod my str $chars := $SELF.IMPL-CCLASS-ENUM-CHARS({}); nqp::chars($chars) == 1 ?? $chars !! Nil }); compose(RakuAST::Regex::CharClassEnumerationElement); parent(RakuAST::Regex::CharClass::BackSpace, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::BackSpace, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::BackSpace, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::BackSpace, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 608 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype('enumcharlist'), :negate($SELF.negated), "\b" }); add-method(RakuAST::Regex::CharClass::BackSpace, 'IMPL-CCLASS-ENUM-CHARS', [RakuAST::Regex::CharClass::BackSpace, '', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-CCLASS-ENUM-CHARS ($SELF_CONT, %mods!) { my $SELF := nqp::decont($SELF_CONT); %mods := nqp::decont(%mods); #line 613 src/Raku/ast/regex.rakumod $SELF.negated ?? "" !! "\b" }); add-method(RakuAST::Regex::CharClass::BackSpace, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::BackSpace, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 615 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::BackSpace); parent(RakuAST::Regex::CharClass::Digit, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::Digit, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::Digit, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::Digit, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 625 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :name, :negate($SELF.negated) ) }); add-method(RakuAST::Regex::CharClass::Digit, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::Digit, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 629 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::Digit); parent(RakuAST::Regex::CharClass::Escape, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::Escape, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::Escape, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::Escape, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 639 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype('enumcharlist'), :negate($SELF.negated), "\c[27]" }); add-method(RakuAST::Regex::CharClass::Escape, 'IMPL-CCLASS-ENUM-CHARS', [RakuAST::Regex::CharClass::Escape, '', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-CCLASS-ENUM-CHARS ($SELF_CONT, %mods!) { my $SELF := nqp::decont($SELF_CONT); %mods := nqp::decont(%mods); #line 644 src/Raku/ast/regex.rakumod $SELF.negated ?? "" !! "\c[27]" }); add-method(RakuAST::Regex::CharClass::Escape, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::Escape, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 646 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::Escape); parent(RakuAST::Regex::CharClass::FormFeed, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::FormFeed, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::FormFeed, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::FormFeed, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 656 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype('enumcharlist'), :negate($SELF.negated), "\c[12]" }); add-method(RakuAST::Regex::CharClass::FormFeed, 'IMPL-CCLASS-ENUM-CHARS', [RakuAST::Regex::CharClass::FormFeed, '', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-CCLASS-ENUM-CHARS ($SELF_CONT, %mods!) { my $SELF := nqp::decont($SELF_CONT); %mods := nqp::decont(%mods); #line 661 src/Raku/ast/regex.rakumod $SELF.negated ?? "" !! "\c[12]" }); add-method(RakuAST::Regex::CharClass::FormFeed, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::FormFeed, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 663 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::FormFeed); parent(RakuAST::Regex::CharClass::HorizontalSpace, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::HorizontalSpace, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::HorizontalSpace, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::HorizontalSpace, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 673 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype('enumcharlist'), :negate($SELF.negated), "\x[09,20,a0,1680,180e,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,200a,202f,205f,3000]" }); add-method(RakuAST::Regex::CharClass::HorizontalSpace, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::HorizontalSpace, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 679 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::HorizontalSpace); parent(RakuAST::Regex::CharClass::Newline, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::Newline, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::Newline, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::Newline, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 689 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :name, :negate($SELF.negated) ) }); add-method(RakuAST::Regex::CharClass::Newline, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::Newline, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 693 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::Newline); parent(RakuAST::Regex::CharClass::CarriageReturn, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::CarriageReturn, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::CarriageReturn, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::CarriageReturn, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 703 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype('enumcharlist'), :negate($SELF.negated), "\r" }); add-method(RakuAST::Regex::CharClass::CarriageReturn, 'IMPL-CCLASS-ENUM-CHARS', [RakuAST::Regex::CharClass::CarriageReturn, '', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-CCLASS-ENUM-CHARS ($SELF_CONT, %mods!) { my $SELF := nqp::decont($SELF_CONT); %mods := nqp::decont(%mods); #line 708 src/Raku/ast/regex.rakumod $SELF.negated ?? "" !! "\r" }); add-method(RakuAST::Regex::CharClass::CarriageReturn, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::CarriageReturn, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 710 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::CarriageReturn); parent(RakuAST::Regex::CharClass::Space, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::Space, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::Space, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::Space, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 720 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :name, :negate($SELF.negated) ) }); add-method(RakuAST::Regex::CharClass::Space, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::Space, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 724 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::Space); parent(RakuAST::Regex::CharClass::Tab, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::Tab, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::Tab, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::Tab, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 734 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype('enumcharlist'), :negate($SELF.negated), "\t" }); add-method(RakuAST::Regex::CharClass::Tab, 'IMPL-CCLASS-ENUM-CHARS', [RakuAST::Regex::CharClass::Tab, '', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-CCLASS-ENUM-CHARS ($SELF_CONT, %mods!) { my $SELF := nqp::decont($SELF_CONT); %mods := nqp::decont(%mods); #line 739 src/Raku/ast/regex.rakumod $SELF.negated ?? "" !! "\t" }); add-method(RakuAST::Regex::CharClass::Tab, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::Tab, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 741 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::Tab); parent(RakuAST::Regex::CharClass::VerticalSpace, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::VerticalSpace, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::VerticalSpace, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::VerticalSpace, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 751 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype('enumcharlist'), :negate($SELF.negated), "\x[0a,0b,0c,0d,85,2028,2029]\r\n" }); add-method(RakuAST::Regex::CharClass::VerticalSpace, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::VerticalSpace, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 757 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::VerticalSpace); parent(RakuAST::Regex::CharClass::Word, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::Word, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::Word, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::Word, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 767 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :name, :negate($SELF.negated) ) }); add-method(RakuAST::Regex::CharClass::Word, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::Word, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 771 src/Raku/ast/regex.rakumod $SELF.IMPL-MAYBE-NEGATE($SELF.IMPL-REGEX-QAST($context, %mods), $negate) }); compose(RakuAST::Regex::CharClass::Word); parent(RakuAST::Regex::CharClass::Specified, RakuAST::Regex::CharClass::Negatable); parent(RakuAST::Regex::CharClass::Specified, RakuAST::Regex::CharClassEnumerationElement); parent(RakuAST::Regex::CharClass::Specified, RakuAST::CheckTime); add-attribute(RakuAST::Regex::CharClass::Specified, str, '$!characters'); add-method(RakuAST::Regex::CharClass::Specified, 'new', [RakuAST::Regex::CharClass::Specified, '', 0, 0, Bool, '$negated', 1, 1, str, '$characters', 1, 0], anon sub new ($SELF_CONT, :$negated?, :$characters!) { my $SELF := nqp::decont($SELF_CONT); $negated := nqp::decont($negated); $characters := nqp::decont($characters); #line 787 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::CharClass::Negatable, '$!negated', $negated ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr_s($obj, RakuAST::Regex::CharClass::Specified, '$!characters', $characters); $obj }); add-method(RakuAST::Regex::CharClass::Specified, 'PERFORM-CHECK', [RakuAST::Regex::CharClass::Specified, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 796 src/Raku/ast/regex.rakumod if nqp::chars(nqp::getattr_s($SELF, RakuAST::Regex::CharClass::Specified, '$!characters')) > 1 { $SELF.add-sorry: $resolver.build-exception: 'X::NotSingleGrapheme', characters => nqp::getattr_s($SELF, RakuAST::Regex::CharClass::Specified, '$!characters'); } }); add-method(RakuAST::Regex::CharClass::Specified, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::Specified, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 804 src/Raku/ast/regex.rakumod $SELF.IMPL-QAST($context, %mods, $SELF.negated) }); add-method(RakuAST::Regex::CharClass::Specified, 'IMPL-CCLASS-ENUM-CHARS', [RakuAST::Regex::CharClass::Specified, '', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-CCLASS-ENUM-CHARS ($SELF_CONT, %mods!) { my $SELF := nqp::decont($SELF_CONT); %mods := nqp::decont(%mods); #line 808 src/Raku/ast/regex.rakumod $SELF.negated || nqp::chars(nqp::getattr_s($SELF, RakuAST::Regex::CharClass::Specified, '$!characters')) != 1 ?? "" !! nqp::getattr_s($SELF, RakuAST::Regex::CharClass::Specified, '$!characters') }); add-method(RakuAST::Regex::CharClass::Specified, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClass::Specified, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 812 src/Raku/ast/regex.rakumod $SELF.IMPL-QAST($context, %mods, $SELF.negated ?? !$negate !! $negate) }); add-method(RakuAST::Regex::CharClass::Specified, 'IMPL-QAST', [RakuAST::Regex::CharClass::Specified, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negated', 0, 0], anon sub IMPL-QAST ($SELF_CONT, $context!, %mods!, $negated!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negated := nqp::decont($negated); #line 816 src/Raku/ast/regex.rakumod if $negated { # Negated, it is treated like a "long character". Quoting S05: # > A consequence of this is that the negated form advances by a single # > position (matching as . does) when the long character doesn't match # > as a whole # Rakudo got this wrong pre-RakuAST; hopefully it's rare enough of a # construct that we can get away with doing it right here. QAST::Regex.new( :rxtype, QAST::Regex.new( :rxtype, :subtype, :negate, nqp::getattr_s($SELF, RakuAST::Regex::CharClass::Specified, '$!characters') ), QAST::Regex.new( :rxtype, :name<.> ) ) } else { # Non-negated, match the character(s) QAST::Regex.new( :rxtype, nqp::getattr_s($SELF, RakuAST::Regex::CharClass::Specified, '$!characters') ) } }); #line 785 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClass::Specified, 'characters', [], anon sub characters ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Regex::CharClass::Specified, '$!characters') }); compose(RakuAST::Regex::CharClass::Specified); parent(RakuAST::Regex::CharClass::Nul, RakuAST::Regex::CharClass); parent(RakuAST::Regex::CharClass::Nul, RakuAST::Regex::CharClassEnumerationElement); add-method(RakuAST::Regex::CharClass::Nul, 'IMPL-REGEX-QAST', [RakuAST::Regex::CharClass::Nul, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 842 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype, "\0" }); add-method(RakuAST::Regex::CharClass::Nul, 'IMPL-CCLASS-ENUM-CHARS', [RakuAST::Regex::CharClass::Nul, '', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-CCLASS-ENUM-CHARS ($SELF_CONT, %mods!) { my $SELF := nqp::decont($SELF_CONT); %mods := nqp::decont(%mods); #line 846 src/Raku/ast/regex.rakumod "\0" }); compose(RakuAST::Regex::CharClass::Nul); parent(RakuAST::Regex::BackReference, RakuAST::Regex::Atom); add-method(RakuAST::Regex::BackReference, 'IMPL-REGEX-QAST', [RakuAST::Regex::BackReference, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 853 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype, :subtype, QAST::NodeList.new: QAST::SVal.new( :value('!BACKREF') ), QAST::SVal.new( :value($SELF.IMPL-CAPTURE-NAME) ) }); add-method(RakuAST::Regex::BackReference, 'IMPL-CAPTURE-NAME', [RakuAST::Regex::BackReference, '', 0, 0], anon sub IMPL-CAPTURE-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 859 src/Raku/ast/regex.rakumod nqp::die('IMPL-CAPTURE-NAME not implemented in ' ~ $SELF.HOW.name($SELF)) }); compose(RakuAST::Regex::BackReference); parent(RakuAST::Regex::BackReference::Positional, RakuAST::Regex::BackReference); add-attribute(RakuAST::Regex::BackReference::Positional, int, '$!index'); add-method(RakuAST::Regex::BackReference::Positional, 'new', [RakuAST::Regex::BackReference::Positional, '', 0, 0, int, '$index', 0, 0], anon sub new ($SELF_CONT, $index!) { my $SELF := nqp::decont($SELF_CONT); $index := nqp::decont($index); #line 870 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr_i($obj, RakuAST::Regex::BackReference::Positional, '$!index', $index); $obj }); add-method(RakuAST::Regex::BackReference::Positional, 'IMPL-CAPTURE-NAME', [RakuAST::Regex::BackReference::Positional, '', 0, 0], anon sub IMPL-CAPTURE-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 876 src/Raku/ast/regex.rakumod ~nqp::getattr_i($SELF, RakuAST::Regex::BackReference::Positional, '$!index') }); #line 868 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::BackReference::Positional, 'index', [], anon sub index ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Regex::BackReference::Positional, '$!index') }); compose(RakuAST::Regex::BackReference::Positional); parent(RakuAST::Regex::BackReference::Named, RakuAST::Regex::BackReference); add-attribute(RakuAST::Regex::BackReference::Named, str, '$!name'); add-method(RakuAST::Regex::BackReference::Named, 'new', [RakuAST::Regex::BackReference::Named, '', 0, 0, str, '$name', 0, 0], anon sub new ($SELF_CONT, $name!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); #line 885 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Regex::BackReference::Named, '$!name', $name); $obj }); add-method(RakuAST::Regex::BackReference::Named, 'IMPL-CAPTURE-NAME', [RakuAST::Regex::BackReference::Named, '', 0, 0], anon sub IMPL-CAPTURE-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 891 src/Raku/ast/regex.rakumod nqp::getattr_s($SELF, RakuAST::Regex::BackReference::Named, '$!name') }); #line 883 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::BackReference::Named, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Regex::BackReference::Named, '$!name') }); compose(RakuAST::Regex::BackReference::Named); parent(RakuAST::Regex::Statement, RakuAST::Regex::Atom); add-attribute(RakuAST::Regex::Statement, RakuAST::Statement, '$!statement'); add-method(RakuAST::Regex::Statement, 'new', [RakuAST::Regex::Statement, '', 0, 0, RakuAST::Statement, '$statement', 0, 0], anon sub new ($SELF_CONT, $statement!) { my $SELF := nqp::decont($SELF_CONT); $statement := nqp::decont($statement); #line 901 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Statement, '$!statement', $statement); $obj }); add-method(RakuAST::Regex::Statement, 'IMPL-REGEX-QAST', [RakuAST::Regex::Statement, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 907 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype, :subtype, nqp::getattr($SELF, RakuAST::Regex::Statement, '$!statement').IMPL-TO-QAST($context) }); add-method(RakuAST::Regex::Statement, 'visit-children', [RakuAST::Regex::Statement, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 912 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Statement, '$!statement')); }); #line 899 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Statement, 'statement', [], anon sub statement ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Statement, '$!statement') }); compose(RakuAST::Regex::Statement); parent(RakuAST::Regex::Block, RakuAST::Regex::Atom); add-attribute(RakuAST::Regex::Block, RakuAST::Block, '$!block'); add-method(RakuAST::Regex::Block, 'new', [RakuAST::Regex::Block, '', 0, 0, RakuAST::Block, '$block', 0, 0], anon sub new ($SELF_CONT, $block!) { my $SELF := nqp::decont($SELF_CONT); $block := nqp::decont($block); #line 923 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Block, '$!block', $block); $obj }); add-method(RakuAST::Regex::Block, 'quantifiable', [RakuAST::Regex::Block, '', 0, 0], anon sub quantifiable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 929 src/Raku/ast/regex.rakumod (Bool.WHO) }); add-method(RakuAST::Regex::Block, 'IMPL-REGEX-QAST', [RakuAST::Regex::Block, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 931 src/Raku/ast/regex.rakumod my $block-call := $SELF.IMPL-REGEX-BLOCK-CALL($context, nqp::getattr($SELF, RakuAST::Regex::Block, '$!block')); QAST::Regex.new( $block-call, :rxtype ) }); add-method(RakuAST::Regex::Block, 'visit-children', [RakuAST::Regex::Block, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 936 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Block, '$!block')); }); #line 921 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Block, 'block', [], anon sub block ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Block, '$!block') }); compose(RakuAST::Regex::Block); parent(RakuAST::Regex::Interpolation, RakuAST::Regex::Atom); parent(RakuAST::Regex::Interpolation, RakuAST::ImplicitLookups); add-attribute(RakuAST::Regex::Interpolation, RakuAST::Expression, '$!var'); add-attribute(RakuAST::Regex::Interpolation, Bool, '$!sequential'); add-method(RakuAST::Regex::Interpolation, 'new', [RakuAST::Regex::Interpolation, '', 0, 0, RakuAST::Expression, '$var', 1, 1, Bool, '$sequential', 1, 1], anon sub new ($SELF_CONT, :$var?, :$sequential?) { my $SELF := nqp::decont($SELF_CONT); $var := nqp::decont($var); $sequential := nqp::decont($sequential); #line 951 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Interpolation, '$!var', $var); nqp::bindattr($obj, RakuAST::Regex::Interpolation, '$!sequential', $sequential ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Regex::Interpolation, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Regex::Interpolation, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 959 src/Raku/ast/regex.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('PseudoStash')), ]) }); add-method(RakuAST::Regex::Interpolation, 'IMPL-REGEX-QAST', [RakuAST::Regex::Interpolation, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 965 src/Raku/ast/regex.rakumod # Look for fast paths. if nqp::istype(nqp::getattr($SELF, RakuAST::Regex::Interpolation, '$!var'), RakuAST::Lookup) && nqp::getattr($SELF, RakuAST::Regex::Interpolation, '$!var').is-resolved { my $resolution := nqp::getattr($SELF, RakuAST::Regex::Interpolation, '$!var').resolution; # TODO contant case if !%mods && nqp::istype($resolution, RakuAST::VarDeclaration::Simple) && $resolution.sigil eq '$' { my $type := $resolution.type; if $type && $type.is-known-to-be(Str) { # Certainly a string. return QAST::Regex.new: :rxtype, :subtype, QAST::NodeList.new: QAST::SVal.new( :value('!LITERAL') ), nqp::getattr($SELF, RakuAST::Regex::Interpolation, '$!var').IMPL-TO-QAST($context), QAST::IVal.new( :value(%mods ?? 1 !! 0) ) } } } # Fallback to slow path. QAST::Regex.new: :rxtype, :subtype, QAST::NodeList.new: QAST::SVal.new( :value('INTERPOLATE') ), nqp::getattr($SELF, RakuAST::Regex::Interpolation, '$!var').IMPL-TO-QAST($context), QAST::IVal.new( :value((%mods ?? 1 !! 0) + (%mods ?? 2 !! 0)) ), QAST::IVal.new( :value(0) ), QAST::IVal.new( :value(nqp::getattr($SELF, RakuAST::Regex::Interpolation, '$!sequential') ?? 1 !! 0) ), QAST::IVal.new( :value(0) ), QAST::Op.new( :op, :name, $SELF.get-implicit-lookups.AT-POS(0).IMPL-TO-QAST($context) ) }); add-method(RakuAST::Regex::Interpolation, 'visit-children', [RakuAST::Regex::Interpolation, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1001 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Interpolation, '$!var')); }); #line 948 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Interpolation, 'var', [], anon sub var ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Interpolation, '$!var') }); #line 949 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Interpolation, 'sequential', [], anon sub sequential ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Interpolation, '$!sequential') }); compose(RakuAST::Regex::Interpolation); parent(RakuAST::Regex::Assertion, RakuAST::Regex::Atom); add-method(RakuAST::Regex::Assertion, 'IMPL-INTERPOLATE-ASSERTION', [RakuAST::Regex::Assertion, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Mu, '$expression-qast', 0, 0, Bool, '$sequential', 0, 0, Mu, '$PseudoStash', 0, 0], anon sub IMPL-INTERPOLATE-ASSERTION ($SELF_CONT, $context!, %mods!, $expression-qast!, $sequential!, $PseudoStash!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $expression-qast := nqp::decont($expression-qast); $sequential := nqp::decont($sequential); $PseudoStash := nqp::decont($PseudoStash); #line 1012 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype, :subtype, QAST::NodeList.new: QAST::SVal.new( :value('INTERPOLATE_ASSERTION') ), $expression-qast, QAST::IVal.new( :value((%mods ?? 1 !! 0) + (%mods ?? 2 !! 0)) ), QAST::IVal.new( :value(0) ), # XXX 1 if MONKEY-SEE-NO-EVAL QAST::IVal.new( :value($sequential ?? 1 !! 0) ), QAST::IVal.new( :value(1) ), QAST::Op.new( :op, :name, $PseudoStash.IMPL-TO-QAST($context) ) }); compose(RakuAST::Regex::Assertion); parent(RakuAST::Regex::Assertion::Pass, RakuAST::Regex::Assertion); add-method(RakuAST::Regex::Assertion::Pass, 'new', [RakuAST::Regex::Assertion::Pass, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1033 src/Raku/ast/regex.rakumod nqp::create($SELF) }); add-method(RakuAST::Regex::Assertion::Pass, 'quantifiable', [RakuAST::Regex::Assertion::Pass, '', 0, 0], anon sub quantifiable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1037 src/Raku/ast/regex.rakumod (Bool.WHO) }); add-method(RakuAST::Regex::Assertion::Pass, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::Pass, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1039 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :subtype ) }); compose(RakuAST::Regex::Assertion::Pass); parent(RakuAST::Regex::Assertion::Fail, RakuAST::Regex::Assertion); add-method(RakuAST::Regex::Assertion::Fail, 'new', [RakuAST::Regex::Assertion::Fail, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1048 src/Raku/ast/regex.rakumod nqp::create($SELF) }); add-method(RakuAST::Regex::Assertion::Fail, 'quantifiable', [RakuAST::Regex::Assertion::Fail, '', 0, 0], anon sub quantifiable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1052 src/Raku/ast/regex.rakumod (Bool.WHO) }); add-method(RakuAST::Regex::Assertion::Fail, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::Fail, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1054 src/Raku/ast/regex.rakumod QAST::Regex.new( :rxtype, :subtype ) }); compose(RakuAST::Regex::Assertion::Fail); parent(RakuAST::Regex::Assertion::Named, RakuAST::Regex::Assertion); parent(RakuAST::Regex::Assertion::Named, RakuAST::ImplicitLookups); add-attribute(RakuAST::Regex::Assertion::Named, RakuAST::Name, '$!name'); add-attribute(RakuAST::Regex::Assertion::Named, Bool, '$!capturing'); add-method(RakuAST::Regex::Assertion::Named, 'new', [RakuAST::Regex::Assertion::Named, '', 0, 0, RakuAST::Name, '$name', 1, 0, Bool, '$capturing', 1, 1], anon sub new ($SELF_CONT, :$name!, :$capturing?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $capturing := nqp::decont($capturing); #line 1069 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Assertion::Named, '$!name', $name); nqp::bindattr($obj, RakuAST::Regex::Assertion::Named, '$!capturing', $capturing ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Regex::Assertion::Named, 'set-capturing', [RakuAST::Regex::Assertion::Named, '', 0, 0, Bool, '$capturing', 0, 0], anon sub set-capturing ($SELF_CONT, $capturing!) { my $SELF := nqp::decont($SELF_CONT); $capturing := nqp::decont($capturing); #line 1077 src/Raku/ast/regex.rakumod nqp::bindattr($SELF, RakuAST::Regex::Assertion::Named, '$!capturing', $capturing ?? (Bool.WHO) !! (Bool.WHO)); Nil }); add-method(RakuAST::Regex::Assertion::Named, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Regex::Assertion::Named, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1083 src/Raku/ast/regex.rakumod # A call like will look for <&foo> and only then do <.foo> # (but in both cases it captures). $SELF.IMPL-WRAP-LIST: nqp::getattr($SELF, RakuAST::Regex::Assertion::Named, '$!capturing') && nqp::getattr($SELF, RakuAST::Regex::Assertion::Named, '$!name').is-identifier ?? [RakuAST::Var::Lexical.new('&' ~ nqp::getattr($SELF, RakuAST::Regex::Assertion::Named, '$!name').canonicalize)] !! [] }); add-method(RakuAST::Regex::Assertion::Named, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::Named, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1091 src/Raku/ast/regex.rakumod $SELF.IMPL-REGEX-QAST-CALL($context) }); add-method(RakuAST::Regex::Assertion::Named, 'IMPL-REGEX-QAST-CALL', [RakuAST::Regex::Assertion::Named, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-REGEX-QAST-CALL ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1095 src/Raku/ast/regex.rakumod my $longname := nqp::getattr($SELF, RakuAST::Regex::Assertion::Named, '$!name'); if $longname.is-identifier { my $name := $longname.canonicalize; if $name eq 'sym' { nqp::die('special name not yet compiled'); } else { my $lookups := $SELF.get-implicit-lookups; my $qast; if $lookups.elems && $lookups.AT-POS(0).is-resolved { $qast := QAST::Regex.new: :rxtype,:subtype, QAST::NodeList.new: QAST::SVal.new( :value('CALL_SUBRULE') ), $lookups.AT-POS(0).IMPL-TO-QAST($context); } else { $qast := QAST::Regex.new: :rxtype, QAST::NodeList.new(QAST::SVal.new( :value($name) )); } if nqp::getattr($SELF, RakuAST::Regex::Assertion::Named, '$!capturing') { $qast.subtype('capture'); $qast.name($name); } $qast } } else { nqp::die('non-identifier rule calls not yet compiled'); } }); add-method(RakuAST::Regex::Assertion::Named, 'visit-children', [RakuAST::Regex::Assertion::Named, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1127 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::Named, '$!name')); }); #line 1066 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Named, 'name', [], anon sub name ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Named, '$!name') }); #line 1067 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Named, 'capturing', [], anon sub capturing ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Named, '$!capturing') }); compose(RakuAST::Regex::Assertion::Named); parent(RakuAST::Regex::Assertion::Named::Args, RakuAST::Regex::Assertion::Named); add-attribute(RakuAST::Regex::Assertion::Named::Args, RakuAST::ArgList, '$!args'); add-method(RakuAST::Regex::Assertion::Named::Args, 'new', [RakuAST::Regex::Assertion::Named::Args, '', 0, 0, RakuAST::Name, '$name', 1, 0, Bool, '$capturing', 1, 1, Raku::ArgList, '$args', 1, 0], anon sub new ($SELF_CONT, :$name!, :$capturing?, :$args!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $capturing := nqp::decont($capturing); $args := nqp::decont($args); #line 1138 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Assertion::Named, '$!name', $name); nqp::bindattr($obj, RakuAST::Regex::Assertion::Named, '$!capturing', $capturing ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Regex::Assertion::Named::Args, '$!args', $args); $obj }); add-method(RakuAST::Regex::Assertion::Named::Args, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::Named::Args, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1147 src/Raku/ast/regex.rakumod my $call := $SELF.IMPL-REGEX-QAST-CALL($context); nqp::getattr($SELF, RakuAST::Regex::Assertion::Named::Args, '$!args').IMPL-ADD-QAST-ARGS($context, $call[0]); $call }); add-method(RakuAST::Regex::Assertion::Named::Args, 'visit-children', [RakuAST::Regex::Assertion::Named::Args, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1153 src/Raku/ast/regex.rakumod $visitor($SELF.name); $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::Named::Args, '$!args')); }); #line 1136 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Named::Args, 'args', [], anon sub args ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Named::Args, '$!args') }); compose(RakuAST::Regex::Assertion::Named::Args); parent(RakuAST::Regex::Assertion::Named::RegexArg, RakuAST::Regex::Assertion::Named); parent(RakuAST::Regex::Assertion::Named::RegexArg, RakuAST::RegexThunk); add-attribute(RakuAST::Regex::Assertion::Named::RegexArg, RakuAST::Regex, '$!regex-arg'); add-attribute(RakuAST::Regex::Assertion::Named::RegexArg, str, '$!unique-name'); add-attribute(RakuAST::Regex::Assertion::Named::RegexArg, Mu, '$!body-qast'); add-method(RakuAST::Regex::Assertion::Named::RegexArg, 'new', [RakuAST::Regex::Assertion::Named::RegexArg, '', 0, 0, RakuAST::Name, '$name', 1, 0, Bool, '$capturing', 1, 1, Raku::Regex, '$regex-arg', 1, 0], anon sub new ($SELF_CONT, :$name!, :$capturing?, :$regex-arg!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $capturing := nqp::decont($capturing); $regex-arg := nqp::decont($regex-arg); #line 1170 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Assertion::Named, '$!name', $name); nqp::bindattr($obj, RakuAST::Regex::Assertion::Named, '$!capturing', $capturing ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Regex::Assertion::Named::RegexArg, '$!regex-arg', $regex-arg); $obj }); add-method(RakuAST::Regex::Assertion::Named::RegexArg, 'IMPL-UNIQUE-NAME', [RakuAST::Regex::Assertion::Named::RegexArg, '', 0, 0], anon sub IMPL-UNIQUE-NAME ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1180 src/Raku/ast/regex.rakumod my str $unique-name := nqp::getattr_s($SELF, RakuAST::Regex::Assertion::Named::RegexArg, '$!unique-name'); unless $unique-name { nqp::bindattr_s($SELF, RakuAST::Regex::Assertion::Named::RegexArg, '$!unique-name', ($unique-name := QAST::Node.unique('!__REGEX_ARG_'))); } $unique-name }); add-method(RakuAST::Regex::Assertion::Named::RegexArg, 'IMPL-THUNKED-REGEX-QAST', [RakuAST::Regex::Assertion::Named::RegexArg, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-THUNKED-REGEX-QAST ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1189 src/Raku/ast/regex.rakumod nqp::getattr($SELF, RakuAST::Regex::Assertion::Named::RegexArg, '$!regex-arg').IMPL-REGEX-TOP-LEVEL-QAST($context, $SELF.meta-object, nqp::hash(), :body-qast(nqp::getattr($SELF, RakuAST::Regex::Assertion::Named::RegexArg, '$!body-qast') // nqp::die('Misordered regex compilation')), :no-scan); }); add-method(RakuAST::Regex::Assertion::Named::RegexArg, 'IMPL-QAST-DECL-CODE', [RakuAST::Regex::Assertion::Named::RegexArg, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub IMPL-QAST-DECL-CODE ($SELF_CONT, $context!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); #line 1195 src/Raku/ast/regex.rakumod # Form the block itself and link it with the meta-object. Install it # in the lexpad; we'll look it up when we need it. This means we can # avoid closure-cloning it per time we enter it, which may help if we # are scanning or it's in a quantified thing. my str $name := $SELF.IMPL-UNIQUE-NAME; my $block := $SELF.IMPL-QAST-FORM-BLOCK($context, :blocktype('declaration_static')); $SELF.IMPL-LINK-META-OBJECT($context, $block); QAST::Stmts.new( $block, QAST::Op.new( :op('bind'), QAST::Var.new( :decl, :scope, :$name ), $SELF.IMPL-CLOSURE-QAST($context) ) ) }); add-method(RakuAST::Regex::Assertion::Named::RegexArg, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::Named::RegexArg, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1213 src/Raku/ast/regex.rakumod nqp::bindattr($SELF, RakuAST::Regex::Assertion::Named::RegexArg, '$!body-qast', nqp::getattr($SELF, RakuAST::Regex::Assertion::Named::RegexArg, '$!regex-arg').IMPL-REGEX-QAST($context, %mods)); my $qast := $SELF.IMPL-REGEX-QAST-CALL($context); my str $name := $SELF.IMPL-UNIQUE-NAME; $qast[0].push(QAST::Var.new( :$name, :scope('lexical') )); $qast }); add-method(RakuAST::Regex::Assertion::Named::RegexArg, 'visit-children', [RakuAST::Regex::Assertion::Named::RegexArg, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1222 src/Raku/ast/regex.rakumod $visitor($SELF.name); $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::Named::RegexArg, '$!regex-arg')); }); #line 1164 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Named::RegexArg, 'regex-arg', [], anon sub regex-arg ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Named::RegexArg, '$!regex-arg') }); compose(RakuAST::Regex::Assertion::Named::RegexArg); parent(RakuAST::Regex::Assertion::Alias, RakuAST::Regex::Assertion); add-attribute(RakuAST::Regex::Assertion::Alias, str, '$!name'); add-attribute(RakuAST::Regex::Assertion::Alias, RakuAST::Regex::Assertion, '$!assertion'); add-method(RakuAST::Regex::Assertion::Alias, 'new', [RakuAST::Regex::Assertion::Alias, '', 0, 0, str, '$name', 1, 0, RakuAST::Regex::Assertion, '$assertion', 1, 0], anon sub new ($SELF_CONT, :$name!, :$assertion!) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $assertion := nqp::decont($assertion); #line 1236 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Regex::Assertion::Alias, '$!name', $name); nqp::bindattr($obj, RakuAST::Regex::Assertion::Alias, '$!assertion', $assertion); $obj }); add-method(RakuAST::Regex::Assertion::Alias, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::Alias, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1243 src/Raku/ast/regex.rakumod my $qast := nqp::getattr($SELF, RakuAST::Regex::Assertion::Alias, '$!assertion').IMPL-REGEX-QAST($context, %mods); if $qast.rxtype eq 'subrule' { $SELF.IMPL-SUBRULE-ALIAS($qast, nqp::getattr_s($SELF, RakuAST::Regex::Assertion::Alias, '$!name')); } else { QAST::Regex.new( $qast, :name(nqp::getattr_s($SELF, RakuAST::Regex::Assertion::Alias, '$!name')), :rxtype ); } }); add-method(RakuAST::Regex::Assertion::Alias, 'visit-children', [RakuAST::Regex::Assertion::Alias, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1253 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::Alias, '$!assertion')); }); #line 1233 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Alias, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Regex::Assertion::Alias, '$!name') }); #line 1234 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Alias, 'assertion', [], anon sub assertion ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Alias, '$!assertion') }); compose(RakuAST::Regex::Assertion::Alias); parent(RakuAST::Regex::Assertion::Lookahead, RakuAST::Regex::Assertion); add-attribute(RakuAST::Regex::Assertion::Lookahead, Bool, '$!negated'); add-attribute(RakuAST::Regex::Assertion::Lookahead, RakuAST::Regex::Assertion, '$!assertion'); add-method(RakuAST::Regex::Assertion::Lookahead, 'new', [RakuAST::Regex::Assertion::Lookahead, '', 0, 0, Bool, '$negated', 1, 1, RakuAST::Regex::Assertion, '$assertion', 1, 0], anon sub new ($SELF_CONT, :$negated?, :$assertion!) { my $SELF := nqp::decont($SELF_CONT); $negated := nqp::decont($negated); $assertion := nqp::decont($assertion); #line 1266 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Assertion::Lookahead, '$!negated', $negated ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Regex::Assertion::Lookahead, '$!assertion', $assertion); $obj }); add-method(RakuAST::Regex::Assertion::Lookahead, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::Lookahead, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1274 src/Raku/ast/regex.rakumod my $qast := nqp::getattr($SELF, RakuAST::Regex::Assertion::Lookahead, '$!assertion').IMPL-REGEX-QAST($context, %mods); $qast.subtype('zerowidth'); if nqp::getattr($SELF, RakuAST::Regex::Assertion::Lookahead, '$!negated') { $qast.negate(!$qast.negate); } $qast }); add-method(RakuAST::Regex::Assertion::Lookahead, 'visit-children', [RakuAST::Regex::Assertion::Lookahead, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1283 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::Lookahead, '$!assertion')); }); #line 1263 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Lookahead, 'negated', [], anon sub negated ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Lookahead, '$!negated') }); #line 1264 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Lookahead, 'assertion', [], anon sub assertion ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Lookahead, '$!assertion') }); compose(RakuAST::Regex::Assertion::Lookahead); parent(RakuAST::Regex::Assertion::InterpolatedBlock, RakuAST::Regex::Assertion); parent(RakuAST::Regex::Assertion::InterpolatedBlock, RakuAST::ImplicitLookups); add-attribute(RakuAST::Regex::Assertion::InterpolatedBlock, RakuAST::Block, '$!block'); add-attribute(RakuAST::Regex::Assertion::InterpolatedBlock, Bool, '$!sequential'); add-method(RakuAST::Regex::Assertion::InterpolatedBlock, 'new', [RakuAST::Regex::Assertion::InterpolatedBlock, '', 0, 0, RakuAST::Block, '$block', 1, 0, Bool, '$sequential', 1, 1], anon sub new ($SELF_CONT, :$block!, :$sequential?) { my $SELF := nqp::decont($SELF_CONT); $block := nqp::decont($block); $sequential := nqp::decont($sequential); #line 1297 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Assertion::InterpolatedBlock, '$!block', $block); nqp::bindattr($obj, RakuAST::Regex::Assertion::InterpolatedBlock, '$!sequential', $sequential ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Regex::Assertion::InterpolatedBlock, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Regex::Assertion::InterpolatedBlock, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1305 src/Raku/ast/regex.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('PseudoStash')), ]) }); add-method(RakuAST::Regex::Assertion::InterpolatedBlock, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::InterpolatedBlock, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1311 src/Raku/ast/regex.rakumod $SELF.IMPL-INTERPOLATE-ASSERTION( $context, %mods, $SELF.IMPL-REGEX-BLOCK-CALL($context, nqp::getattr($SELF, RakuAST::Regex::Assertion::InterpolatedBlock, '$!block')), nqp::getattr($SELF, RakuAST::Regex::Assertion::InterpolatedBlock, '$!sequential'), $SELF.get-implicit-lookups.AT-POS(0) ) }); add-method(RakuAST::Regex::Assertion::InterpolatedBlock, 'visit-children', [RakuAST::Regex::Assertion::InterpolatedBlock, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1321 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::InterpolatedBlock, '$!block')); }); #line 1295 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::InterpolatedBlock, 'sequential', [], anon sub sequential ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::InterpolatedBlock, '$!sequential') }); #line 1294 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::InterpolatedBlock, 'block', [], anon sub block ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::InterpolatedBlock, '$!block') }); compose(RakuAST::Regex::Assertion::InterpolatedBlock); parent(RakuAST::Regex::Assertion::InterpolatedVar, RakuAST::Regex::Assertion); parent(RakuAST::Regex::Assertion::InterpolatedVar, RakuAST::ImplicitLookups); add-attribute(RakuAST::Regex::Assertion::InterpolatedVar, RakuAST::Expression, '$!var'); add-attribute(RakuAST::Regex::Assertion::InterpolatedVar, Bool, '$!sequential'); add-method(RakuAST::Regex::Assertion::InterpolatedVar, 'new', [RakuAST::Regex::Assertion::InterpolatedVar, '', 0, 0, RakuAST::Expression, '$var', 1, 0, Bool, '$sequential', 1, 1], anon sub new ($SELF_CONT, :$var!, :$sequential?) { my $SELF := nqp::decont($SELF_CONT); $var := nqp::decont($var); $sequential := nqp::decont($sequential); #line 1335 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Assertion::InterpolatedVar, '$!var', $var); nqp::bindattr($obj, RakuAST::Regex::Assertion::InterpolatedVar, '$!sequential', $sequential ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Regex::Assertion::InterpolatedVar, 'PRODUCE-IMPLICIT-LOOKUPS', [RakuAST::Regex::Assertion::InterpolatedVar, '', 0, 0], anon sub PRODUCE-IMPLICIT-LOOKUPS ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1343 src/Raku/ast/regex.rakumod $SELF.IMPL-WRAP-LIST([ RakuAST::Type::Setting.new(RakuAST::Name.from-identifier('PseudoStash')), ]) }); add-method(RakuAST::Regex::Assertion::InterpolatedVar, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::InterpolatedVar, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1349 src/Raku/ast/regex.rakumod $SELF.IMPL-INTERPOLATE-ASSERTION( $context, %mods, nqp::getattr($SELF, RakuAST::Regex::Assertion::InterpolatedVar, '$!var').IMPL-TO-QAST($context), nqp::getattr($SELF, RakuAST::Regex::Assertion::InterpolatedVar, '$!sequential'), $SELF.get-implicit-lookups.AT-POS(0) ) }); add-method(RakuAST::Regex::Assertion::InterpolatedVar, 'visit-children', [RakuAST::Regex::Assertion::InterpolatedVar, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1359 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::InterpolatedVar, '$!var')); }); #line 1332 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::InterpolatedVar, 'var', [], anon sub var ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::InterpolatedVar, '$!var') }); #line 1333 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::InterpolatedVar, 'sequential', [], anon sub sequential ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::InterpolatedVar, '$!sequential') }); compose(RakuAST::Regex::Assertion::InterpolatedVar); parent(RakuAST::Regex::Assertion::Callable, RakuAST::Regex::Assertion); add-attribute(RakuAST::Regex::Assertion::Callable, RakuAST::Expression, '$!callee'); add-attribute(RakuAST::Regex::Assertion::Callable, RakuAST::ArgList, '$!args'); add-method(RakuAST::Regex::Assertion::Callable, 'new', [RakuAST::Regex::Assertion::Callable, '', 0, 0, RakuAST::Expression, '$callee', 1, 0, Raku::ArgList, '$args', 1, 1], anon sub new ($SELF_CONT, :$callee!, :$args?) { my $SELF := nqp::decont($SELF_CONT); $callee := nqp::decont($callee); $args := nqp::decont($args); #line 1372 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Assertion::Callable, '$!callee', $callee); nqp::bindattr($obj, RakuAST::Regex::Assertion::Callable, '$!args', $args // RakuAST::ArgList); $obj }); add-method(RakuAST::Regex::Assertion::Callable, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::Callable, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1380 src/Raku/ast/regex.rakumod my $node-list := QAST::NodeList.new: QAST::SVal.new( :value('CALL_SUBRULE') ), nqp::getattr($SELF, RakuAST::Regex::Assertion::Callable, '$!callee').IMPL-TO-QAST($context); nqp::getattr($SELF, RakuAST::Regex::Assertion::Callable, '$!args').IMPL-ADD-QAST-ARGS($context, $node-list) if nqp::getattr($SELF, RakuAST::Regex::Assertion::Callable, '$!args'); QAST::Regex.new( :rxtype, :subtype, $node-list ) }); add-method(RakuAST::Regex::Assertion::Callable, 'visit-children', [RakuAST::Regex::Assertion::Callable, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1388 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::Callable, '$!callee')); $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::Callable, '$!args')) if nqp::getattr($SELF, RakuAST::Regex::Assertion::Callable, '$!args'); }); #line 1369 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Callable, 'callee', [], anon sub callee ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Callable, '$!callee') }); #line 1370 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Callable, 'args', [], anon sub args ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Callable, '$!args') }); compose(RakuAST::Regex::Assertion::Callable); parent(RakuAST::Regex::Assertion::PredicateBlock, RakuAST::Regex::Assertion); add-attribute(RakuAST::Regex::Assertion::PredicateBlock, Bool, '$!negated'); add-attribute(RakuAST::Regex::Assertion::PredicateBlock, RakuAST::Block, '$!block'); add-method(RakuAST::Regex::Assertion::PredicateBlock, 'new', [RakuAST::Regex::Assertion::PredicateBlock, '', 0, 0, Bool, '$negated', 1, 1, RakuAST::Block, '$block', 1, 0], anon sub new ($SELF_CONT, :$negated?, :$block!) { my $SELF := nqp::decont($SELF_CONT); $negated := nqp::decont($negated); $block := nqp::decont($block); #line 1402 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Assertion::PredicateBlock, '$!negated', $negated ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Regex::Assertion::PredicateBlock, '$!block', $block); $obj }); add-method(RakuAST::Regex::Assertion::PredicateBlock, 'quantifiable', [RakuAST::Regex::Assertion::PredicateBlock, '', 0, 0], anon sub quantifiable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1410 src/Raku/ast/regex.rakumod (Bool.WHO) }); add-method(RakuAST::Regex::Assertion::PredicateBlock, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::PredicateBlock, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1412 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype, :subtype, :negate(nqp::getattr($SELF, RakuAST::Regex::Assertion::PredicateBlock, '$!negated') ?? 1 !! 0), $SELF.IMPL-REGEX-BLOCK-CALL($context, nqp::getattr($SELF, RakuAST::Regex::Assertion::PredicateBlock, '$!block')) }); add-method(RakuAST::Regex::Assertion::PredicateBlock, 'visit-children', [RakuAST::Regex::Assertion::PredicateBlock, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1418 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Assertion::PredicateBlock, '$!block')); }); #line 1399 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::PredicateBlock, 'negated', [], anon sub negated ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::PredicateBlock, '$!negated') }); #line 1400 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::PredicateBlock, 'block', [], anon sub block ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::PredicateBlock, '$!block') }); compose(RakuAST::Regex::Assertion::PredicateBlock); parent(RakuAST::Regex::Assertion::CharClass, RakuAST::Regex::Assertion); add-attribute(RakuAST::Regex::Assertion::CharClass, Mu, '$!elements'); add-method(RakuAST::Regex::Assertion::CharClass, 'new', [RakuAST::Regex::Assertion::CharClass, '', 0, 0, Any, '@elements', 0, 0], anon sub new ($SELF_CONT, *@elements) { my $SELF := nqp::decont($SELF_CONT); @elements := nqp::decont(@elements); #line 1429 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); if nqp::elems(@elements) == 0 { nqp::die('RakuAST::Regex::Assertion::CharClass must have at least one element'); } for @elements { unless nqp::istype($_, RakuAST::Regex::CharClassElement) { nqp::die('Can only construct a RakuAST::Regex::Assertion::CharClass with elements of type RakuAST::Regex::CharClassElement') } } nqp::bindattr($obj, RakuAST::Regex::Assertion::CharClass, '$!elements', @elements); $obj }); add-method(RakuAST::Regex::Assertion::CharClass, 'elements', [RakuAST::Regex::Assertion::CharClass, '', 0, 0], anon sub elements ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1444 src/Raku/ast/regex.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Regex::Assertion::CharClass, '$!elements')) }); add-method(RakuAST::Regex::Assertion::CharClass, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::CharClass, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1448 src/Raku/ast/regex.rakumod # Compile the first element. my $first := nqp::getattr($SELF, RakuAST::Regex::Assertion::CharClass, '$!elements')[0]; my $qast := $first.IMPL-CCLASS-QAST($context, %mods, (Bool.WHO)); # Add further elements, exactly how depending on the exact nature of # the elements if nqp::elems(nqp::getattr($SELF, RakuAST::Regex::Assertion::CharClass, '$!elements')) > 1 { my int $i := 1; while $i < nqp::elems(nqp::getattr($SELF, RakuAST::Regex::Assertion::CharClass, '$!elements')) { my $elem := nqp::getattr($SELF, RakuAST::Regex::Assertion::CharClass, '$!elements')[$i]; my $elem-qast := $elem.IMPL-CCLASS-QAST($context, %mods, (Bool.WHO)); if $elem.negated { $elem-qast.subtype('zerowidth'); $qast := QAST::Regex.new: :rxtype, :subtype, :negate, QAST::Regex.new( :rxtype, :subtype, $elem-qast ), $qast; } else { $qast := QAST::Regex.new( :rxtype, $qast, $elem-qast ); } $i++; } } $qast }); add-method(RakuAST::Regex::Assertion::CharClass, 'visit-children', [RakuAST::Regex::Assertion::CharClass, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1477 src/Raku/ast/regex.rakumod for nqp::getattr($SELF, RakuAST::Regex::Assertion::CharClass, '$!elements') { $visitor($_); } }); compose(RakuAST::Regex::Assertion::CharClass); parent(RakuAST::Regex::Assertion::Recurse, RakuAST::Regex::Assertion); add-attribute(RakuAST::Regex::Assertion::Recurse, RakuAST::Regex::Term, '$!node'); add-method(RakuAST::Regex::Assertion::Recurse, 'new', [RakuAST::Regex::Assertion::Recurse, '', 0, 0, RakuAST::Regex, '$node', 0, 0], anon sub new ($SELF_CONT, $node!) { my $SELF := nqp::decont($SELF_CONT); $node := nqp::decont($node); #line 1489 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Assertion::Recurse, '$!node', $node); $obj; }); add-method(RakuAST::Regex::Assertion::Recurse, 'IMPL-REGEX-QAST', [RakuAST::Regex::Assertion::Recurse, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1495 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype, :subtype, QAST::NodeList.new( QAST::SVal.new( :value('RECURSE') ), :node(nqp::getattr($SELF, RakuAST::Regex::Assertion::Recurse, '$!node'))); }); #line 1487 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Assertion::Recurse, 'node', [], anon sub node ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Assertion::Recurse, '$!node') }); compose(RakuAST::Regex::Assertion::Recurse); parent(RakuAST::Regex::CharClassElement, RakuAST::Node); add-attribute(RakuAST::Regex::CharClassElement, Bool, '$!negated'); #line 1507 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClassElement, 'negated', [], anon sub negated ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::CharClassElement, '$!negated') }); compose(RakuAST::Regex::CharClassElement); parent(RakuAST::Regex::CharClassElement::Rule, RakuAST::Regex::CharClassElement); add-attribute(RakuAST::Regex::CharClassElement::Rule, str, '$!name'); add-method(RakuAST::Regex::CharClassElement::Rule, 'new', [RakuAST::Regex::CharClassElement::Rule, '', 0, 0, str, '$name', 1, 0, Bool, '$negated', 1, 1], anon sub new ($SELF_CONT, :$name!, :$negated?) { my $SELF := nqp::decont($SELF_CONT); $name := nqp::decont($name); $negated := nqp::decont($negated); #line 1516 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::CharClassElement, '$!negated', $negated ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr_s($obj, RakuAST::Regex::CharClassElement::Rule, '$!name', $name); $obj }); add-method(RakuAST::Regex::CharClassElement::Rule, 'IMPL-CCLASS-QAST', [RakuAST::Regex::CharClassElement::Rule, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$first', 0, 0], anon sub IMPL-CCLASS-QAST ($SELF_CONT, $context!, %mods!, $first!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $first := nqp::decont($first); #line 1524 src/Raku/ast/regex.rakumod my $negate := $SELF.negated; my $name := QAST::NodeList.new(QAST::SVal.new( :value(nqp::getattr_s($SELF, RakuAST::Regex::CharClassElement::Rule, '$!name')) )); if $negate && $first { QAST::Regex.new: :rxtype, QAST::Regex.new( :rxtype, :subtype, :$negate, $name ), QAST::Regex.new( :rxtype, :name<.> ); } else { QAST::Regex.new( :rxtype, :subtype, :$negate, $name ) } }); #line 1514 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClassElement::Rule, 'name', [], anon sub name ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Regex::CharClassElement::Rule, '$!name') }); compose(RakuAST::Regex::CharClassElement::Rule); parent(RakuAST::Regex::CharClassElement::Property, RakuAST::Regex::CharClassElement); add-attribute(RakuAST::Regex::CharClassElement::Property, str, '$!property'); add-attribute(RakuAST::Regex::CharClassElement::Property, Bool, '$!inverted'); add-attribute(RakuAST::Regex::CharClassElement::Property, RakuAST::Expression, '$!predicate'); add-method(RakuAST::Regex::CharClassElement::Property, 'new', [RakuAST::Regex::CharClassElement::Property, '', 0, 0, str, '$property', 1, 0, Bool, '$inverted', 1, 1, RakuAST::Expression, '$predicate', 1, 1, Bool, '$negated', 1, 1], anon sub new ($SELF_CONT, :$property!, :$inverted?, :$predicate?, :$negated?) { my $SELF := nqp::decont($SELF_CONT); $property := nqp::decont($property); $inverted := nqp::decont($inverted); $predicate := nqp::decont($predicate); $negated := nqp::decont($negated); #line 1547 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::CharClassElement, '$!negated', $negated ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr_s($obj, RakuAST::Regex::CharClassElement::Property, '$!property', $property); nqp::bindattr($obj, RakuAST::Regex::CharClassElement::Property, '$!inverted', $inverted ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Regex::CharClassElement::Property, '$!predicate', $predicate // RakuAST::Expression); $obj }); add-method(RakuAST::Regex::CharClassElement::Property, 'IMPL-CCLASS-QAST', [RakuAST::Regex::CharClassElement::Property, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$first', 0, 0], anon sub IMPL-CCLASS-QAST ($SELF_CONT, $context!, %mods!, $first!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $first := nqp::decont($first); #line 1560 src/Raku/ast/regex.rakumod my $negate := $SELF.negated ?? !nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Property, '$!inverted') !! nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Property, '$!inverted'); my $qast := QAST::Regex.new( :rxtype, :$negate, nqp::getattr_s($SELF, RakuAST::Regex::CharClassElement::Property, '$!property') ); $qast.push(nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Property, '$!predicate').IMPL-TO-QAST($context)) if nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Property, '$!predicate'); $qast }); add-method(RakuAST::Regex::CharClassElement::Property, 'visit-children', [RakuAST::Regex::CharClassElement::Property, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1567 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Property, '$!predicate')) if nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Property, '$!predicate'); }); #line 1542 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClassElement::Property, 'property', [], anon sub property ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Regex::CharClassElement::Property, '$!property') }); #line 1544 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClassElement::Property, 'predicate', [], anon sub predicate ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::CharClassElement::Property, '$!predicate') }); #line 1543 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClassElement::Property, 'inverted', [], anon sub inverted ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::CharClassElement::Property, '$!inverted') }); compose(RakuAST::Regex::CharClassElement::Property); parent(RakuAST::Regex::CharClassElement::Enumeration, RakuAST::Regex::CharClassElement); parent(RakuAST::Regex::CharClassElement::Enumeration, RakuAST::CheckTime); add-attribute(RakuAST::Regex::CharClassElement::Enumeration, Mu, '$!elements'); add-method(RakuAST::Regex::CharClassElement::Enumeration, 'new', [RakuAST::Regex::CharClassElement::Enumeration, '', 0, 0, List, '$elements', 1, 0, Bool, '$negated', 1, 1], anon sub new ($SELF_CONT, :$elements!, :$negated?) { my $SELF := nqp::decont($SELF_CONT); $elements := nqp::decont($elements); $negated := nqp::decont($negated); #line 1580 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::CharClassElement, '$!negated', $negated ?? (Bool.WHO) !! (Bool.WHO)); my @elements := $SELF.IMPL-UNWRAP-LIST($elements); nqp::bindattr($obj, RakuAST::Regex::CharClassElement::Enumeration, '$!elements', $SELF.IMPL-UNWRAP-LIST($elements)); $obj }); add-method(RakuAST::Regex::CharClassElement::Enumeration, 'elements', [RakuAST::Regex::CharClassElement::Enumeration, '', 0, 0], anon sub elements ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1590 src/Raku/ast/regex.rakumod $SELF.IMPL-WRAP-LIST(nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Enumeration, '$!elements')) }); add-method(RakuAST::Regex::CharClassElement::Enumeration, 'PERFORM-CHECK', [RakuAST::Regex::CharClassElement::Enumeration, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1594 src/Raku/ast/regex.rakumod if nqp::elems(nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Enumeration, '$!elements')) { for nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Enumeration, '$!elements') { unless nqp::istype($_,RakuAST::Regex::CharClassEnumerationElement) { $SELF.add-sorry: $resolver.build-exception: 'X::AdHoc', payload => "Character classes can only be built with RakuAST::Regex::CharClassEnumerationElement objects,\n not with " ~ $_.HOW.name($_) ~ " elements"; } } } else { $SELF.add-worry: $resolver.build-exception: 'X::AdHoc', payload => "Character classes without elements will never match" } }); add-method(RakuAST::Regex::CharClassElement::Enumeration, 'IMPL-CCLASS-QAST', [RakuAST::Regex::CharClassElement::Enumeration, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$first', 0, 0], anon sub IMPL-CCLASS-QAST ($SELF_CONT, $context!, %mods!, $first!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $first := nqp::decont($first); #line 1611 src/Raku/ast/regex.rakumod # Go through the elements, which either produce characters to go into an # enumeration or a QAST node. my str $enum := ''; my @alts; for nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Enumeration, '$!elements') { my str $enum-contrib := $_.IMPL-CCLASS-ENUM-CHARS(%mods); if $enum-contrib ne '' { $enum := $enum ~ $enum-contrib; } else { @alts.push($_.IMPL-CCLASS-ENUM-QAST($context, %mods, $SELF.negated)); } } # If we collected characters, add the enumeration to the alternation # parts we'll compile into. if $enum { @alts.push: QAST::Regex.new: :rxtype, :negate($SELF.negated), :subtype(%mods ?? 'ignoremark' !! ''), $enum } # A single alternation part can compile into just that. if nqp::elems(@alts) == 1 { @alts[0] } # An empty enumation always fails. elsif nqp::elems(@alts) == 0 { QAST::Regex.new( :rxtype, :subtype ) } else { $SELF.negated ?? QAST::Regex.new( :rxtype, :negate(1), QAST::Regex.new( :rxtype, :subtype, |@alts ), QAST::Regex.new( :rxtype, :name<.> ) ) !! QAST::Regex.new( :rxtype, |@alts ); } }); add-method(RakuAST::Regex::CharClassElement::Enumeration, 'visit-children', [RakuAST::Regex::CharClassElement::Enumeration, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1654 src/Raku/ast/regex.rakumod for nqp::getattr($SELF, RakuAST::Regex::CharClassElement::Enumeration, '$!elements') { $visitor($_); } }); compose(RakuAST::Regex::CharClassElement::Enumeration); parent(RakuAST::Regex::CharClassEnumerationElement::Character, RakuAST::Regex::CharClassEnumerationElement); add-attribute(RakuAST::Regex::CharClassEnumerationElement::Character, str, '$!character'); add-method(RakuAST::Regex::CharClassEnumerationElement::Character, 'new', [RakuAST::Regex::CharClassEnumerationElement::Character, '', 0, 0, str, '$character', 0, 0], anon sub new ($SELF_CONT, $character!) { my $SELF := nqp::decont($SELF_CONT); $character := nqp::decont($character); #line 1668 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj, RakuAST::Regex::CharClassEnumerationElement::Character, '$!character', $character); $obj }); add-method(RakuAST::Regex::CharClassEnumerationElement::Character, 'IMPL-CCLASS-ENUM-CHARS', [RakuAST::Regex::CharClassEnumerationElement::Character, '', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-CCLASS-ENUM-CHARS ($SELF_CONT, %mods!) { my $SELF := nqp::decont($SELF_CONT); %mods := nqp::decont(%mods); #line 1675 src/Raku/ast/regex.rakumod my str $c := %mods ?? nqp::chr(nqp::ordbaseat(nqp::getattr_s($SELF, RakuAST::Regex::CharClassEnumerationElement::Character, '$!character'), 0)) !! nqp::getattr_s($SELF, RakuAST::Regex::CharClassEnumerationElement::Character, '$!character'); %mods ?? nqp::fc($c) ~ nqp::uc($c) !! $c }); #line 1666 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClassEnumerationElement::Character, 'character', [], anon sub character ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Regex::CharClassEnumerationElement::Character, '$!character') }); compose(RakuAST::Regex::CharClassEnumerationElement::Character); parent(RakuAST::Regex::CharClassEnumerationElement::Range, RakuAST::CheckTime); parent(RakuAST::Regex::CharClassEnumerationElement::Range, RakuAST::Regex::CharClassEnumerationElement); add-attribute(RakuAST::Regex::CharClassEnumerationElement::Range, int, '$!from'); add-attribute(RakuAST::Regex::CharClassEnumerationElement::Range, int, '$!to'); add-method(RakuAST::Regex::CharClassEnumerationElement::Range, 'new', [RakuAST::Regex::CharClassEnumerationElement::Range, '', 0, 0, int, '$from', 1, 0, int, '$to', 1, 0], anon sub new ($SELF_CONT, :$from!, :$to!) { my $SELF := nqp::decont($SELF_CONT); $from := nqp::decont($from); $to := nqp::decont($to); #line 1695 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr_i($obj, RakuAST::Regex::CharClassEnumerationElement::Range, '$!from', $from); nqp::bindattr_i($obj, RakuAST::Regex::CharClassEnumerationElement::Range, '$!to', $to); $obj }); add-method(RakuAST::Regex::CharClassEnumerationElement::Range, 'PERFORM-CHECK', [RakuAST::Regex::CharClassEnumerationElement::Range, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1704 src/Raku/ast/regex.rakumod if nqp::getattr_i($SELF, RakuAST::Regex::CharClassEnumerationElement::Range, '$!from') > nqp::getattr_i($SELF, RakuAST::Regex::CharClassEnumerationElement::Range, '$!to') { $SELF.add-sorry: $resolver.build-exception: 'X::AdHoc', payload => "Illegal reversed character range"; } }); add-method(RakuAST::Regex::CharClassEnumerationElement::Range, 'IMPL-CCLASS-ENUM-QAST', [RakuAST::Regex::CharClassEnumerationElement::Range, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0, Bool, '$negate', 0, 0], anon sub IMPL-CCLASS-ENUM-QAST ($SELF_CONT, $context!, %mods!, $negate!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); $negate := nqp::decont($negate); #line 1712 src/Raku/ast/regex.rakumod QAST::Regex.new: :rxtype, :$negate, %mods ?? (%mods ?? 'ignorecase+ignoremark' !! 'ignoremark') !! (%mods ?? 'ignorecase' !! ''), QAST::IVal.new( :value(nqp::getattr_i($SELF, RakuAST::Regex::CharClassEnumerationElement::Range, '$!from')) ), QAST::IVal.new( :value(nqp::getattr_i($SELF, RakuAST::Regex::CharClassEnumerationElement::Range, '$!to')) ) }); #line 1693 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClassEnumerationElement::Range, 'to', [], anon sub to ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Regex::CharClassEnumerationElement::Range, '$!to') }); #line 1692 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::CharClassEnumerationElement::Range, 'from', [], anon sub from ($self) { nqp::getattr_i(nqp::decont($self), RakuAST::Regex::CharClassEnumerationElement::Range, '$!from') }); compose(RakuAST::Regex::CharClassEnumerationElement::Range); parent(RakuAST::Regex::InternalModifier, RakuAST::Regex::Atom); add-attribute(RakuAST::Regex::InternalModifier, str, '$!modifier'); add-attribute(RakuAST::Regex::InternalModifier, Bool, '$!negated'); add-method(RakuAST::Regex::InternalModifier, 'new', [RakuAST::Regex::InternalModifier, '', 0, 0, str, '$modifier', 1, 1, Bool, '$negated', 1, 1], anon sub new ($SELF_CONT, :$modifier?, :$negated?) { my $SELF := nqp::decont($SELF_CONT); $modifier := nqp::decont($modifier); $negated := nqp::decont($negated); #line 1730 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr_s($obj,RakuAST::Regex::InternalModifier,'$!modifier', $modifier // $SELF.key); nqp::bindattr( $obj,RakuAST::Regex::InternalModifier,'$!negated', $negated ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Regex::InternalModifier, 'quantifiable', [RakuAST::Regex::InternalModifier, '', 0, 0], anon sub quantifiable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1739 src/Raku/ast/regex.rakumod (Bool.WHO) }); add-method(RakuAST::Regex::InternalModifier, 'whitespace-wrappable', [RakuAST::Regex::InternalModifier, '', 0, 0], anon sub whitespace-wrappable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1740 src/Raku/ast/regex.rakumod (Bool.WHO) }); add-method(RakuAST::Regex::InternalModifier, 'IMPL-REGEX-QAST', [RakuAST::Regex::InternalModifier, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1742 src/Raku/ast/regex.rakumod %mods{$SELF.key} := !$SELF.negated; Nil }); #line 1728 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::InternalModifier, 'negated', [], anon sub negated ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::InternalModifier, '$!negated') }); #line 1727 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::InternalModifier, 'modifier', [], anon sub modifier ($self) { nqp::getattr_s(nqp::decont($self), RakuAST::Regex::InternalModifier, '$!modifier') }); compose(RakuAST::Regex::InternalModifier); parent(RakuAST::Regex::InternalModifier::IgnoreCase, RakuAST::Regex::InternalModifier); add-method(RakuAST::Regex::InternalModifier::IgnoreCase, 'key', [RakuAST::Regex::InternalModifier::IgnoreCase, '', 0, 0], anon sub key ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1752 src/Raku/ast/regex.rakumod 'i' }); compose(RakuAST::Regex::InternalModifier::IgnoreCase); parent(RakuAST::Regex::InternalModifier::IgnoreMark, RakuAST::Regex::InternalModifier); add-method(RakuAST::Regex::InternalModifier::IgnoreMark, 'key', [RakuAST::Regex::InternalModifier::IgnoreMark, '', 0, 0], anon sub key ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1759 src/Raku/ast/regex.rakumod 'm' }); compose(RakuAST::Regex::InternalModifier::IgnoreMark); parent(RakuAST::Regex::InternalModifier::Ratchet, RakuAST::Regex::InternalModifier); add-method(RakuAST::Regex::InternalModifier::Ratchet, 'key', [RakuAST::Regex::InternalModifier::Ratchet, '', 0, 0], anon sub key ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1766 src/Raku/ast/regex.rakumod 'r' }); compose(RakuAST::Regex::InternalModifier::Ratchet); parent(RakuAST::Regex::InternalModifier::Sigspace, RakuAST::Regex::InternalModifier); add-method(RakuAST::Regex::InternalModifier::Sigspace, 'key', [RakuAST::Regex::InternalModifier::Sigspace, '', 0, 0], anon sub key ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 1773 src/Raku/ast/regex.rakumod 's' }); compose(RakuAST::Regex::InternalModifier::Sigspace); parent(RakuAST::Regex::QuantifiedAtom, RakuAST::Regex::Term); parent(RakuAST::Regex::QuantifiedAtom, RakuAST::CheckTime); add-attribute(RakuAST::Regex::QuantifiedAtom, RakuAST::Atom, '$!atom'); add-attribute(RakuAST::Regex::QuantifiedAtom, RakuAST::Quantifier, '$!quantifier'); add-attribute(RakuAST::Regex::QuantifiedAtom, RakuAST::Regex::Term, '$!separator'); add-attribute(RakuAST::Regex::QuantifiedAtom, Bool, '$!trailing-separator'); add-method(RakuAST::Regex::QuantifiedAtom, 'new', [RakuAST::Regex::QuantifiedAtom, '', 0, 0, RakuAST::Atom, '$atom', 1, 0, RakuAST::Quantifier, '$quantifier', 1, 0, RakuAST::Separator, '$separator', 1, 1, Bool, '$trailing-separator', 1, 1], anon sub new ($SELF_CONT, :$atom!, :$quantifier!, :$separator?, :$trailing-separator?) { my $SELF := nqp::decont($SELF_CONT); $atom := nqp::decont($atom); $quantifier := nqp::decont($quantifier); $separator := nqp::decont($separator); $trailing-separator := nqp::decont($trailing-separator); #line 1788 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::QuantifiedAtom, '$!atom', $atom); nqp::bindattr($obj, RakuAST::Regex::QuantifiedAtom, '$!quantifier', $quantifier); nqp::bindattr($obj, RakuAST::Regex::QuantifiedAtom, '$!separator', $separator // RakuAST::Regex::Term); nqp::bindattr($obj, RakuAST::Regex::QuantifiedAtom, '$!trailing-separator', $trailing-separator ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Regex::QuantifiedAtom, 'replace-atom', [RakuAST::Regex::QuantifiedAtom, '', 0, 0, RakuAST::Atom, '$atom', 0, 0], anon sub replace-atom ($SELF_CONT, $atom!) { my $SELF := nqp::decont($SELF_CONT); $atom := nqp::decont($atom); #line 1799 src/Raku/ast/regex.rakumod nqp::bindattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!atom', $atom); Nil }); add-method(RakuAST::Regex::QuantifiedAtom, 'PERFORM-CHECK', [RakuAST::Regex::QuantifiedAtom, '', 0, 0, RakuAST::Resolver, '$resolver', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0], anon sub PERFORM-CHECK ($SELF_CONT, $resolver!, $context!) { my $SELF := nqp::decont($SELF_CONT); $resolver := nqp::decont($resolver); $context := nqp::decont($context); #line 1804 src/Raku/ast/regex.rakumod unless nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!atom').quantifiable { $SELF.add-sorry: $resolver.build-exception: 'X::Syntax::Regex::NonQuantifiable'; } }); add-method(RakuAST::Regex::QuantifiedAtom, 'IMPL-REGEX-QAST', [RakuAST::Regex::QuantifiedAtom, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1811 src/Raku/ast/regex.rakumod my $atom := nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!atom').IMPL-REGEX-QAST($context, %mods); my $quantified := nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!quantifier').IMPL-QAST-QUANTIFY($context, $atom, %mods); if nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!separator') { $quantified.push(nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!separator').IMPL-REGEX-QAST($context, %mods)); if nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!trailing-separator') { QAST::Regex.new( :rxtype, $quantified, QAST::Regex.new( :rxtype, :min(0), :max(1), nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!separator').IMPL-REGEX-QAST($context, %mods) ) ) } else { $quantified } } else { $quantified } }); add-method(RakuAST::Regex::QuantifiedAtom, 'visit-children', [RakuAST::Regex::QuantifiedAtom, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1835 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!atom')); $visitor(nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!quantifier')); $visitor(nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!separator')) if nqp::getattr($SELF, RakuAST::Regex::QuantifiedAtom, '$!separator'); }); #line 1785 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::QuantifiedAtom, 'trailing-separator', [], anon sub trailing-separator ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::QuantifiedAtom, '$!trailing-separator') }); #line 1784 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::QuantifiedAtom, 'separator', [], anon sub separator ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::QuantifiedAtom, '$!separator') }); #line 1783 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::QuantifiedAtom, 'quantifier', [], anon sub quantifier ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::QuantifiedAtom, '$!quantifier') }); #line 1782 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::QuantifiedAtom, 'atom', [], anon sub atom ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::QuantifiedAtom, '$!atom') }); compose(RakuAST::Regex::QuantifiedAtom); parent(RakuAST::Regex::Quantifier, RakuAST::Node); add-attribute(RakuAST::Regex::Quantifier, RakuAST::Regex::Backtrack, '$!backtrack'); add-method(RakuAST::Regex::Quantifier, 'new', [RakuAST::Regex::Quantifier, '', 0, 0, RakuAST::Regex::Backtrack, '$backtrack', 1, 1], anon sub new ($SELF_CONT, :$backtrack?) { my $SELF := nqp::decont($SELF_CONT); $backtrack := nqp::decont($backtrack); #line 1848 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Quantifier, '$!backtrack', nqp::istype($backtrack, RakuAST::Regex::Backtrack) ?? $backtrack !! RakuAST::Regex::Backtrack); $obj }); add-method(RakuAST::Regex::Quantifier, 'visit-children', [RakuAST::Regex::Quantifier, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1857 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::Quantifier, '$!backtrack')) if nqp::getattr($SELF, RakuAST::Regex::Quantifier, '$!backtrack'); }); #line 1846 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Quantifier, 'backtrack', [], anon sub backtrack ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Quantifier, '$!backtrack') }); compose(RakuAST::Regex::Quantifier); parent(RakuAST::Regex::Quantifier::ZeroOrOne, RakuAST::Regex::Quantifier); add-method(RakuAST::Regex::Quantifier::ZeroOrOne, 'IMPL-QAST-QUANTIFY', [RakuAST::Regex::Quantifier::ZeroOrOne, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$atom-qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-QAST-QUANTIFY ($SELF_CONT, $context!, $atom-qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $atom-qast := nqp::decont($atom-qast); %mods := nqp::decont(%mods); #line 1866 src/Raku/ast/regex.rakumod $SELF.backtrack.IMPL-QAST-APPLY: QAST::Regex.new( :rxtype, :min(0), :max(1), $atom-qast ), %mods }); compose(RakuAST::Regex::Quantifier::ZeroOrOne); parent(RakuAST::Regex::Quantifier::ZeroOrMore, RakuAST::Regex::Quantifier); add-method(RakuAST::Regex::Quantifier::ZeroOrMore, 'IMPL-QAST-QUANTIFY', [RakuAST::Regex::Quantifier::ZeroOrMore, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$atom-qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-QAST-QUANTIFY ($SELF_CONT, $context!, $atom-qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $atom-qast := nqp::decont($atom-qast); %mods := nqp::decont(%mods); #line 1877 src/Raku/ast/regex.rakumod $SELF.backtrack.IMPL-QAST-APPLY: QAST::Regex.new( :rxtype, :min(0), :max(-1), $atom-qast ), %mods }); compose(RakuAST::Regex::Quantifier::ZeroOrMore); parent(RakuAST::Regex::Quantifier::OneOrMore, RakuAST::Regex::Quantifier); add-method(RakuAST::Regex::Quantifier::OneOrMore, 'IMPL-QAST-QUANTIFY', [RakuAST::Regex::Quantifier::OneOrMore, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$atom-qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-QAST-QUANTIFY ($SELF_CONT, $context!, $atom-qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $atom-qast := nqp::decont($atom-qast); %mods := nqp::decont(%mods); #line 1888 src/Raku/ast/regex.rakumod $SELF.backtrack.IMPL-QAST-APPLY: QAST::Regex.new( :rxtype, :min(1), :max(-1), $atom-qast ), %mods }); compose(RakuAST::Regex::Quantifier::OneOrMore); parent(RakuAST::Regex::Quantifier::Range, RakuAST::Regex::Quantifier); add-attribute(RakuAST::Regex::Quantifier::Range, Int, '$!min'); add-attribute(RakuAST::Regex::Quantifier::Range, Int, '$!max'); add-attribute(RakuAST::Regex::Quantifier::Range, Bool, '$!excludes-min'); add-attribute(RakuAST::Regex::Quantifier::Range, Bool, '$!excludes-max'); add-method(RakuAST::Regex::Quantifier::Range, 'new', [RakuAST::Regex::Quantifier::Range, '', 0, 0, Int, '$min', 1, 1, Int, '$max', 1, 1, Bool, '$excludes-max', 1, 1, Bool, '$excludes-min', 1, 1, RakuAST::Regex::Backtrack, '$backtrack', 1, 1], anon sub new ($SELF_CONT, :$min?, :$max?, :$excludes-max?, :$excludes-min?, :$backtrack?) { my $SELF := nqp::decont($SELF_CONT); $min := nqp::decont($min); $max := nqp::decont($max); $excludes-max := nqp::decont($excludes-max); $excludes-min := nqp::decont($excludes-min); $backtrack := nqp::decont($backtrack); #line 1905 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Quantifier, '$!backtrack', nqp::istype($backtrack, RakuAST::Regex::Backtrack) ?? $backtrack !! RakuAST::Regex::Backtrack); nqp::bindattr($obj, RakuAST::Regex::Quantifier::Range, '$!min', $min // Int); nqp::bindattr($obj, RakuAST::Regex::Quantifier::Range, '$!max', $max // Int); nqp::bindattr($obj, RakuAST::Regex::Quantifier::Range, '$!excludes-min', $excludes-min ?? (Bool.WHO) !! (Bool.WHO)); nqp::bindattr($obj, RakuAST::Regex::Quantifier::Range, '$!excludes-max', $excludes-max ?? (Bool.WHO) !! (Bool.WHO)); $obj }); add-method(RakuAST::Regex::Quantifier::Range, 'IMPL-QAST-QUANTIFY', [RakuAST::Regex::Quantifier::Range, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$atom-qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-QAST-QUANTIFY ($SELF_CONT, $context!, $atom-qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $atom-qast := nqp::decont($atom-qast); %mods := nqp::decont(%mods); #line 1920 src/Raku/ast/regex.rakumod my int $min := nqp::getattr($SELF, RakuAST::Regex::Quantifier::Range, '$!min') // 0; $min++ if nqp::getattr($SELF, RakuAST::Regex::Quantifier::Range, '$!excludes-min'); my int $max := -1; if nqp::getattr($SELF, RakuAST::Regex::Quantifier::Range, '$!max') { $max := nqp::getattr($SELF, RakuAST::Regex::Quantifier::Range, '$!max'); $max-- if nqp::getattr($SELF, RakuAST::Regex::Quantifier::Range, '$!excludes-max'); } $SELF.backtrack.IMPL-QAST-APPLY: QAST::Regex.new( :rxtype, :min($min), :max($max), $atom-qast ), %mods }); #line 1899 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Quantifier::Range, 'min', [], anon sub min ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Quantifier::Range, '$!min') }); #line 1900 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Quantifier::Range, 'max', [], anon sub max ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Quantifier::Range, '$!max') }); #line 1901 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Quantifier::Range, 'excludes-min', [], anon sub excludes-min ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Quantifier::Range, '$!excludes-min') }); #line 1902 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Quantifier::Range, 'excludes-max', [], anon sub excludes-max ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Quantifier::Range, '$!excludes-max') }); compose(RakuAST::Regex::Quantifier::Range); parent(RakuAST::Regex::Quantifier::BlockRange, RakuAST::Regex::Quantifier); add-attribute(RakuAST::Regex::Quantifier::BlockRange, RakuAST::Block, '$!block'); add-method(RakuAST::Regex::Quantifier::BlockRange, 'new', [RakuAST::Regex::Quantifier::BlockRange, '', 0, 0, RakuAST::Block, '$block', 1, 0, RakuAST::Regex::Backtrack, '$backtrack', 1, 1], anon sub new ($SELF_CONT, :$block!, :$backtrack?) { my $SELF := nqp::decont($SELF_CONT); $block := nqp::decont($block); $backtrack := nqp::decont($backtrack); #line 1940 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::Quantifier, '$!backtrack', nqp::istype($backtrack, RakuAST::Regex::Backtrack) ?? $backtrack !! RakuAST::Regex::Backtrack); nqp::bindattr($obj, RakuAST::Regex::Quantifier::BlockRange, '$!block', $block); $obj }); add-method(RakuAST::Regex::Quantifier::BlockRange, 'IMPL-QAST-QUANTIFY', [RakuAST::Regex::Quantifier::BlockRange, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Mu, '$atom-qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-QAST-QUANTIFY ($SELF_CONT, $context!, $atom-qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); $atom-qast := nqp::decont($atom-qast); %mods := nqp::decont(%mods); #line 1950 src/Raku/ast/regex.rakumod $SELF.backtrack.IMPL-QAST-APPLY: QAST::Regex.new( :rxtype, $atom-qast, QAST::Op.new( :op('callmethod'), :name('DYNQUANT_LIMITS'), QAST::Var.new( :name('$¢'), :scope('lexical') ), RakuAST::Regex.IMPL-REGEX-BLOCK-CALL($context, nqp::getattr($SELF, RakuAST::Regex::Quantifier::BlockRange, '$!block')) ), ), %mods }); add-method(RakuAST::Regex::Quantifier::BlockRange, 'visit-children', [RakuAST::Regex::Quantifier::BlockRange, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1964 src/Raku/ast/regex.rakumod $visitor($SELF.backtrack); $visitor(nqp::getattr($SELF, RakuAST::Regex::Quantifier::BlockRange, '$!block')); }); #line 1938 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::Quantifier::BlockRange, 'block', [], anon sub block ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::Quantifier::BlockRange, '$!block') }); compose(RakuAST::Regex::Quantifier::BlockRange); parent(RakuAST::Regex::BacktrackModifiedAtom, RakuAST::Regex::Term); add-attribute(RakuAST::Regex::BacktrackModifiedAtom, RakuAST::Atom, '$!atom'); add-attribute(RakuAST::Regex::BacktrackModifiedAtom, RakuAST::Regex::Backtrack, '$!backtrack'); add-method(RakuAST::Regex::BacktrackModifiedAtom, 'new', [RakuAST::Regex::BacktrackModifiedAtom, '', 0, 0, RakuAST::Atom, '$atom', 1, 0, RakuAST::Regex::Backtrack, '$backtrack', 1, 0], anon sub new ($SELF_CONT, :$atom!, :$backtrack!) { my $SELF := nqp::decont($SELF_CONT); $atom := nqp::decont($atom); $backtrack := nqp::decont($backtrack); #line 1977 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::BacktrackModifiedAtom, '$!atom', $atom); nqp::bindattr($obj, RakuAST::Regex::BacktrackModifiedAtom, '$!backtrack', $backtrack); $obj }); add-method(RakuAST::Regex::BacktrackModifiedAtom, 'IMPL-REGEX-QAST', [RakuAST::Regex::BacktrackModifiedAtom, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 1984 src/Raku/ast/regex.rakumod my $atom := nqp::getattr($SELF, RakuAST::Regex::BacktrackModifiedAtom, '$!atom').IMPL-REGEX-QAST($context, %mods); $atom.backtrack ?? $atom !! nqp::getattr($SELF, RakuAST::Regex::BacktrackModifiedAtom, '$!backtrack').IMPL-QAST-APPLY($atom, %mods) }); add-method(RakuAST::Regex::BacktrackModifiedAtom, 'visit-children', [RakuAST::Regex::BacktrackModifiedAtom, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 1989 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::BacktrackModifiedAtom, '$!atom')); $visitor(nqp::getattr($SELF, RakuAST::Regex::BacktrackModifiedAtom, '$!backtrack')); }); #line 1975 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::BacktrackModifiedAtom, 'backtrack', [], anon sub backtrack ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::BacktrackModifiedAtom, '$!backtrack') }); #line 1974 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::BacktrackModifiedAtom, 'atom', [], anon sub atom ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::BacktrackModifiedAtom, '$!atom') }); compose(RakuAST::Regex::BacktrackModifiedAtom); parent(RakuAST::Regex::Backtrack, RakuAST::Node); add-method(RakuAST::Regex::Backtrack, 'new', [RakuAST::Regex::Backtrack, '', 0, 0], anon sub new ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2005 src/Raku/ast/regex.rakumod $SELF }); add-method(RakuAST::Regex::Backtrack, 'IMPL-QAST-APPLY', [RakuAST::Regex::Backtrack, '', 0, 0, Mu, '$quant-qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-QAST-APPLY ($SELF_CONT, $quant-qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $quant-qast := nqp::decont($quant-qast); %mods := nqp::decont(%mods); #line 2007 src/Raku/ast/regex.rakumod $quant-qast.backtrack('r') if %mods; $quant-qast }); compose(RakuAST::Regex::Backtrack); parent(RakuAST::Regex::Backtrack::Greedy, RakuAST::Regex::Backtrack); add-method(RakuAST::Regex::Backtrack::Greedy, 'IMPL-QAST-APPLY', [RakuAST::Regex::Backtrack::Greedy, '', 0, 0, Mu, '$quant-qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-QAST-APPLY ($SELF_CONT, $quant-qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $quant-qast := nqp::decont($quant-qast); %mods := nqp::decont(%mods); #line 2015 src/Raku/ast/regex.rakumod $quant-qast.backtrack('g'); $quant-qast }); compose(RakuAST::Regex::Backtrack::Greedy); parent(RakuAST::Regex::Backtrack::Frugal, RakuAST::Regex::Backtrack); add-method(RakuAST::Regex::Backtrack::Frugal, 'IMPL-QAST-APPLY', [RakuAST::Regex::Backtrack::Frugal, '', 0, 0, Mu, '$quant-qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-QAST-APPLY ($SELF_CONT, $quant-qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $quant-qast := nqp::decont($quant-qast); %mods := nqp::decont(%mods); #line 2023 src/Raku/ast/regex.rakumod $quant-qast.backtrack('f'); $quant-qast }); compose(RakuAST::Regex::Backtrack::Frugal); parent(RakuAST::Regex::Backtrack::Ratchet, RakuAST::Regex::Backtrack); add-method(RakuAST::Regex::Backtrack::Ratchet, 'IMPL-QAST-APPLY', [RakuAST::Regex::Backtrack::Ratchet, '', 0, 0, Mu, '$quant-qast', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-QAST-APPLY ($SELF_CONT, $quant-qast!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $quant-qast := nqp::decont($quant-qast); %mods := nqp::decont(%mods); #line 2031 src/Raku/ast/regex.rakumod $quant-qast.backtrack('r'); $quant-qast }); compose(RakuAST::Regex::Backtrack::Ratchet); parent(RakuAST::Regex::WithWhitespace, RakuAST::Regex::Atom); add-attribute(RakuAST::Regex::WithWhitespace, RakuAST::Regex::Term, '$!regex'); add-method(RakuAST::Regex::WithWhitespace, 'new', [RakuAST::Regex::WithWhitespace, '', 0, 0, RakuAST::Regex::Term, '$regex', 0, 0], anon sub new ($SELF_CONT, $regex!) { my $SELF := nqp::decont($SELF_CONT); $regex := nqp::decont($regex); #line 2043 src/Raku/ast/regex.rakumod my $obj := nqp::create($SELF); nqp::bindattr($obj, RakuAST::Regex::WithWhitespace, '$!regex', $regex); $obj }); add-method(RakuAST::Regex::WithWhitespace, 'IMPL-REGEX-QAST', [RakuAST::Regex::WithWhitespace, '', 0, 0, RakuAST::IMPL::QASTContext, '$context', 0, 0, Any, '%mods', 0, 0], anon sub IMPL-REGEX-QAST ($SELF_CONT, $context!, %mods!) { my $SELF := nqp::decont($SELF_CONT); $context := nqp::decont($context); %mods := nqp::decont(%mods); #line 2049 src/Raku/ast/regex.rakumod my $qast := nqp::getattr($SELF, RakuAST::Regex::WithWhitespace, '$!regex').IMPL-REGEX-QAST($context, %mods); %mods ?? QAST::Regex.new(:rxtype, $qast, QAST::Regex.new: :rxtype, :subtype, :name, QAST::NodeList.new(QAST::SVal.new( :value('ws') )) ) !! $qast }); add-method(RakuAST::Regex::WithWhitespace, 'visit-children', [RakuAST::Regex::WithWhitespace, '', 0, 0, Code, '$visitor', 0, 0], anon sub visit-children ($SELF_CONT, $visitor!) { my $SELF := nqp::decont($SELF_CONT); $visitor := nqp::decont($visitor); #line 2061 src/Raku/ast/regex.rakumod $visitor(nqp::getattr($SELF, RakuAST::Regex::WithWhitespace, '$!regex')); }); add-method(RakuAST::Regex::WithWhitespace, 'whitespace-wrappable', [RakuAST::Regex::WithWhitespace, '', 0, 0], anon sub whitespace-wrappable ($SELF_CONT) { my $SELF := nqp::decont($SELF_CONT); #line 2064 src/Raku/ast/regex.rakumod (Bool.WHO) }); #line 2041 src/Raku/ast/regex.rakumod add-method(RakuAST::Regex::WithWhitespace, 'regex', [], anon sub regex ($self) { nqp::getattr(nqp::decont($self), RakuAST::Regex::WithWhitespace, '$!regex') }); compose(RakuAST::Regex::WithWhitespace); #line 1 src/Raku/ast/rakuast-epilogue.nqp EXPORT::DEFAULT.WHO := RakuAST; EXPORT::DEFAULT.WHO := OperatorProperties; } #line 1 src/vm/moar/dispatchers.nqp # Some maximum cache sizes we allow at a callsite before we switch to a # megamorphic strategy. my int $MEGA-TYPE-CALLSITE-SIZE := 16; my int $MEGA-METH-CALLSITE-SIZE := 16; # Return value decontainerization dispatcher. Often we have nothing at all # to do, in which case we can make it identity. Other times, we need a # decont. In a few, we need to re-wrap it. { my $container-fallback := -> $Iterable, $cont { if nqp::isrwcont($cont) { # It's an RW container, so we really need to decont it. my $rv := nqp::decont($cont); if nqp::istype($rv, $Iterable) { my $rc := nqp::create(Scalar); nqp::bindattr($rc, Scalar, '$!value', $rv); $rc } else { $rv } } else { # A read-only container, so just return it. $cont } } my $recont := -> $obj { my $rc := nqp::create(Scalar); nqp::bindattr($rc, Scalar, '$!value', nqp::decont($obj)); $rc } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-rv-decont', -> $capture { # If it's heading megamorphic, then we'll install the fallback, without # any conditions, which is faster than over-filling the cache and running # this dispatch logic every time. my int $cache-size := nqp::dispatch('boot-syscall', 'dispatcher-inline-cache-size'); if $cache-size >= $MEGA-TYPE-CALLSITE-SIZE { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, nqp::gethllsym('Raku', 'Iterable')), 0, $container-fallback)); } else { # We always need to guard on type and concreteness. my $rv := nqp::captureposarg($capture, 0); my $rv_arg := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $rv_arg); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $rv_arg); # Is it a container? if nqp::isconcrete_nd($rv) && nqp::iscont($rv) { # It's a container. We have special cases for Scalar. if nqp::istype_nd($rv, Scalar) { # Check if the descriptor is undefined, in which case it's read-only. my $desc := nqp::getattr($rv, Scalar, '$!descriptor'); my $desc_arg := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $rv_arg, Scalar, '$!descriptor'); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $desc_arg); if nqp::isconcrete($desc) { # Writeable, so we may need to recontainerize the value if # the type is iterable, otherwise we can decont it. my $value := nqp::getattr($rv, Scalar, '$!value'); my $value_arg := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $rv_arg, Scalar, '$!value'); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $value_arg); if nqp::istype_nd($value, nqp::gethllsym('Raku', 'Iterable')) { # Need to recont in order to preserve item nature. # Shuffle in the recont code to invoke. We already # read the deconted value, so we insert that as the # arg so it needn't be dereferenced again. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $value_arg), 0, $recont)); } else { # Decont, so just evaluate to the read attr (boot-value # ignores all but the first argument). nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $capture, 0, $value_arg)); } } else { # Read-only, so identity will do. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } } else { # Delegate to non-Scalar container fallback. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, nqp::gethllsym('Raku', 'Iterable')), 0, $container-fallback)); } } else { # Not containerized, so identity shall do. # Unless it is null, then we map it to Mu. if nqp::isnull($rv) { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, Mu)); } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } } } }); nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-rv-decont-6c', -> $capture { # This emulates a bug where Proxy was never decontainerized no # matter what. The ecosystem came to depend on that, so we will # accept it for now. We need to revisit this in the future. my $rv := nqp::captureposarg($capture, 0); if nqp::eqaddr(nqp::what_nd($rv), Proxy) && nqp::isconcrete_nd($rv) { my $rv_arg := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $rv_arg); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $rv_arg); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-rv-decont', $capture); } }); } # Assignment dispatcher, which case-analyzes assignments and provides optimized # paths for a range of common situations, and typically lifting type checks to # be guards. { sub assign-type-error($desc, $value) { Perl6::Metamodel::Configuration.throw_or_die( 'X::TypeCheck::Assignment', "Type check failed in assignment", :symbol($desc.name), :$desc, :got($value), :expected($desc.of) ); } my $assign-fallback := -> $cont, $value { nqp::assign($cont, $value) } my $assign-scalar-no-whence-no-typecheck := -> $cont, $value { nqp::bindattr($cont, Scalar, '$!value', $value) } my $assign-scalar-nil-no-whence := -> $cont, $value { my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); nqp::bindattr($cont, Scalar, '$!value', nqp::getattr($desc, ContainerDescriptor, '$!default')) } my $assign-scalar-no-whence := -> $cont, $value { my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); my $type := nqp::getattr($desc, ContainerDescriptor, '$!of'); if nqp::istype($value, $type) { if nqp::how_nd($type).archetypes($type).coercive { $value := nqp::dispatch('raku-coercion', $type, $value); } nqp::bindattr($cont, Scalar, '$!value', $value); } else { assign-type-error($desc, $value); } } my $assign-scalar-bindpos-no-typecheck := -> $cont, $value { nqp::bindattr($cont, Scalar, '$!value', $value); my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); nqp::bindpos( nqp::getattr($desc, ContainerDescriptor::BindArrayPos, '$!target'), nqp::getattr_i($desc, ContainerDescriptor::BindArrayPos, '$!pos'), $cont); nqp::bindattr($cont, Scalar, '$!descriptor', nqp::getattr($desc, ContainerDescriptor::BindArrayPos, '$!next-descriptor')); } my $assign-scalar-bindpos := -> $cont, $value { my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); my $next := nqp::getattr($desc, ContainerDescriptor::BindArrayPos, '$!next-descriptor'); my $type := nqp::getattr($next, ContainerDescriptor, '$!of'); if nqp::istype($value, $type) { if nqp::how_nd($type).archetypes($type).coercive { $value := nqp::dispatch('raku-coercion', $type, $value); } nqp::bindattr($cont, Scalar, '$!value', $value); nqp::bindpos( nqp::getattr($desc, ContainerDescriptor::BindArrayPos, '$!target'), nqp::getattr_i($desc, ContainerDescriptor::BindArrayPos, '$!pos'), $cont); nqp::bindattr($cont, Scalar, '$!descriptor', $next); } else { assign-type-error($next, $value); } } my $assign-scalar-uninit-no-typecheck := -> $cont, $value { nqp::bindattr($cont, Scalar, '$!value', $value); my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); nqp::bindattr($cont, Scalar, '$!descriptor', nqp::getattr($desc, ContainerDescriptor::UninitializedAttribute, '$!next-descriptor')); } my $assign-scalar-uninit := -> $cont, $value { my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); my $next := nqp::getattr($desc, ContainerDescriptor::UninitializedAttribute, '$!next-descriptor'); my $type := nqp::getattr($next, ContainerDescriptor, '$!of'); if nqp::istype($value, $type) { if nqp::how_nd($type).archetypes($type).coercive { $value := nqp::dispatch('raku-coercion', $type, $value); } nqp::bindattr($cont, Scalar, '$!value', $value); nqp::bindattr($cont, Scalar, '$!descriptor', $next); } else { assign-type-error($next, $value); } } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-assign', -> $capture { # Whatever we do, we'll guard on the type of the container and its # concreteness. my $tracked-cont := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-cont); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $tracked-cont); # We have various fast paths for an assignment to a Scalar. my int $optimized := 0; my $cont := nqp::captureposarg($capture, 0); if nqp::eqaddr(nqp::what_nd($cont), Scalar) && nqp::isconcrete_nd($cont) { # Now see what the Scalar descriptor type is. my $tracked-desc := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $tracked-cont, Scalar, '$!descriptor'); my $desc := nqp::getattr($cont, Scalar, '$!descriptor'); my $tracked-value := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1); my $value := nqp::captureposarg($capture, 1); if nqp::eqaddr($desc.WHAT, ContainerDescriptor) && nqp::isconcrete($desc) { # Simple assignment, no whence. But is Nil being assigned? my $of := $desc.of; if nqp::eqaddr($value, Nil) { # Yes; just copy in the default, provided we've a simple type. if $of.HOW.archetypes.nominal { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-value); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-desc); my $tracked-of := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $tracked-desc, ContainerDescriptor, '$!of'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $tracked-of); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $assign-scalar-nil-no-whence)); $optimized := 1; } } else { # No whence, no Nil. Is it a nominal type? If yes, we can check # it here. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-desc); if $of.HOW.archetypes.nominal && nqp::istype($value, $of) { # Nominal and passes type check; stack up gurads and delegate to # simple bind. my $tracked-of := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $tracked-desc, ContainerDescriptor, '$!of'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $tracked-of); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-value); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $assign-scalar-no-whence-no-typecheck)); $optimized := 1; } else { # Non-nominal or type check error. nqp::dispatch('boot-syscall', 'dispatcher-guard-not-literal-obj', $tracked-value, Nil); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $assign-scalar-no-whence)); $optimized := 1; } } } elsif nqp::eqaddr($desc.WHAT, ContainerDescriptor::Untyped) && nqp::isconcrete($desc) { if nqp::eqaddr($value, Nil) { # Nil case is NYI. } else { # Assignment to an untyped container descriptor; no type check # is required, just bind the value into place. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-desc); nqp::dispatch('boot-syscall', 'dispatcher-guard-not-literal-obj', $tracked-value, Nil); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $assign-scalar-no-whence-no-typecheck)); $optimized := 1; } } elsif nqp::eqaddr($desc.WHAT, ContainerDescriptor::UninitializedAttribute) && nqp::isconcrete($desc) { # First assignment to an attribute where we care about whether it # was assigned to. We can produce a fast path for this, though # should check what the ultimate descriptor is. It really should # be a normal, boring, container descriptor. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-desc); my $next := nqp::getattr($desc, ContainerDescriptor::UninitializedAttribute, '$!next-descriptor'); if nqp::eqaddr($next.WHAT, ContainerDescriptor) || nqp::eqaddr($next.WHAT, ContainerDescriptor::Untyped) { # Ensure we're not assigning Nil (not yet fast-pathed, but # probably not terribly likely). unless nqp::eqaddr($value.WHAT, Nil) { # Go by whether we can type check the target. my $tracked-next := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $tracked-desc, ContainerDescriptor::UninitializedAttribute, '$!next-descriptor'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $tracked-next); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-value); my $of := $next.of; my $delegate := $of.HOW.archetypes.nominal && (nqp::eqaddr($of, Mu) || nqp::istype($value, $of)) ?? $assign-scalar-uninit-no-typecheck !! $assign-scalar-uninit; nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $delegate)); $optimized := 1; } } } elsif nqp::eqaddr($desc.WHAT, ContainerDescriptor::BindArrayPos) { # Bind into an array. We can produce a fast path for this, though # should check what the ultimate descriptor is. It really should # be a normal, boring, container descriptor. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-desc); my $next := nqp::getattr($desc, ContainerDescriptor::BindArrayPos, '$!next-descriptor'); if nqp::eqaddr($next.WHAT, ContainerDescriptor) || nqp::eqaddr($next.WHAT, ContainerDescriptor::Untyped) { # Ensure we're not assigning Nil. (This would be very odd, as # a Scalar starts off with its default value, and if we are # vivifying we'll likely have a new container). unless nqp::eqaddr($value.WHAT, Nil) { # Go by whether we can type check the target. my $tracked-next := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $tracked-desc, ContainerDescriptor::BindArrayPos, '$!next-descriptor'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $tracked-next); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked-value); my $of := $next.of; my $delegate := $of.HOW.archetypes.nominal && (nqp::eqaddr($of, Mu) || nqp::istype($value, $of)) ?? $assign-scalar-bindpos-no-typecheck !! $assign-scalar-bindpos; nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $delegate)); $optimized := 1; } } } } # If nothing we could optimize, go for the fallback. unless $optimized { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $assign-fallback)); } }); } # Binding type assertion dispatcher, used to do type checks of binds. Evaluates # to the value itself when the type check passes, installing a guard along the # way. Otherwise, throws. { sub bind-error($value, $type) { Perl6::Metamodel::Configuration.throw_or_die( 'X::TypeCheck::Binding', "Type check failed in binding; expected '" ~ nqp::how_nd($type).name($value) ~ "' but got '" ~ nqp::how_nd($value).name($value) ~ "'", :got($value), :expected($type) ); } my $bind-check := -> $value, $value-decont, $type { nqp::istype_nd($value-decont, $type) ?? $value !! bind-error($value, $type) } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-bind-assert', -> $capture { my $value-decont := nqp::captureposarg($capture, 1); my $type := nqp::captureposarg($capture, 2); if nqp::how_nd($type).archetypes.nominal { if nqp::istype_nd($value-decont, $type) { # Nominal, so a type guard on the decont'd value will suffice, # then produce the original value. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1)); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 2)); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } else { my $value := nqp::captureposarg($capture, 0); bind-error($value, $type) } } else { # Not a nominal type, can't guard it, so set up a call to do the # check late-bound. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 2)); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $bind-check); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', $delegate); } }); } # Object construction time checking of if a container is initialized. Done as # a dispatcher primarily to intern .^mixin_type, but also for more compact # bytecode size in generated BUILDALL. my $array-init-check := -> $arr { my $storage := nqp::getattr($arr, List, '$!reified'); nqp::isconcrete($storage) && nqp::elems($storage) } my $hash-init-check := -> $hash { my $storage := nqp::getattr($hash, Map, '$!storage'); nqp::isconcrete($storage) && nqp::elems($storage) } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-is-attr-inited', -> $capture { # If there's a non-concrete object observed, then we bound a non-container # in place, so trivially initialized. my $attr := nqp::captureposarg($capture, 0); my $track-attr := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); my int $inited := 0; my $need-elem-check; if !nqp::isconcrete_nd($attr) { nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-attr); $inited := 1; } # Otherwise, might be a container that was assigned. else { # Just try and read a descriptor. Also see if we have an array or # hash, which needs an additional element check to handle an # assignment to an individual element during BUILD. my $base; my $desc; my $track-desc; try { $base := nqp::how_nd($attr).mixin_base($attr); $desc := nqp::getattr($attr, $base, '$!descriptor'); $track-desc := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-attr, $base, '$!descriptor'); } # If we managed to track a descriptor, then we have a container to # see if was uninitialized. The attribute tracking above will have # established type/concreteness guards on the attribute, so don't # repeat them. if $track-desc { # Guard on the descriptor type, then outcome depends on if # it's an uninitialized attribute descriptor. If it is, then # for arrays and hashes we also need an extra check. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-desc); $inited := !nqp::eqaddr($desc.WHAT, ContainerDescriptor::UninitializedAttribute); if nqp::istype($base, Array) { $need-elem-check := $array-init-check; } elsif nqp::istype($base, Hash) { $need-elem-check := $hash-init-check; } } # Otherwise, bound concrete value. Guard on type and concreteness, # outcome is that it's initialized. else { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-attr); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-attr); $inited := 1; } } # Evaluate to result. if nqp::isconcrete($need-elem-check) && !$inited { # The descriptor suggests it's not initialized by assignment to # the entire array/hash, but individual elements may have been. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $need-elem-check)); } else { # It's certainly initialized per the descriptor, so we're done. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $capture, 0, $inited)); } }); # Sink dispatcher. Called in void context with the decontainerized value to sink. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-sink', -> $capture { # Guard on the type and concreteness. my $sinkee := nqp::captureposarg($capture, 0); my $track-sinkee := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-sinkee); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-sinkee); # Now consider what we're sinking. if nqp::isconcrete_nd($sinkee) { # Concrete. See if it has a `sink` method, and then also if it's not # Mu.sink, which is a no-op. my $meth := nqp::decont(nqp::how_nd($sinkee).find_method($sinkee, 'sink')); if nqp::isconcrete($meth) && !nqp::eqaddr($meth, Mu.HOW.find_method(Mu, 'sink')) { # Need to do a call to the sink method. Since sink is a Raku thing, # assume we can go straight for the Raku method dispatcher. my $with-name := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $capture, 0, 'sink'); my $with-type := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $with-name, 0, nqp::what_nd($sinkee)); my $with-callee := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $with-type, 0, $meth); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call-resolved', $with-callee); } else { # Nothing to do (use boot-value and let void context take care of # discarding the value). nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } } else { # Not concrete, nothing to do. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } }); # A standard call (such as `func($arg)`, `$obj($arg)`, etc.) It receives the # decontainerized callee as the first argument, followed by the arguments. Its # primary purpose is to deal with multi dispatch vs. single dispatch and then # delegate on to the appropriate dispatcher. It also looks at if we are doing a # call to a method (either because it was looked up separately, or because we # are here via lang-call), and in that case sends it via the resolved method # call dispatcher. This means it will have a working nextsame etc. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-call', -> $capture { # Guard on the type and, if it's a routine, on the dispatchees. (We assume # that the set of dispatchees shall not change, even over closure clones - # this may not always be a good assumption - and so we guard on that. If # it's not a dispatcher, we'll be guarding on a literal type object.) my $track_callee := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track_callee); my $callee := nqp::captureposarg($capture, 0); if nqp::istype_nd($callee, Method) && (my str $meth-name := $callee.name) && (my $inv_param := try { $callee.signature.params.AT-POS(0) }) { nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_callee); my $meth-type := $inv_param.type; my $with-type := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 1, $meth-type); my $with-name := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $with-type, 2, $meth-name); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call-resolved', $with-name); } elsif nqp::istype_nd($callee, Routine) { if nqp::can($callee, 'WRAPPERS') { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke-wrapped', $capture); } elsif nqp::can($callee, 'CALL-ME') { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $capture); } else { my int $code-constant := nqp::dispatch('boot-syscall', 'dispatcher-is-arg-literal', $capture, 0); unless $code-constant { nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track_callee, Routine, '@!dispatchees')); } nqp::dispatch('boot-syscall', 'dispatcher-delegate', $callee.is_dispatcher ?? 'raku-multi' !! 'raku-invoke', $capture); } } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $capture); } }); # A standard method call of the form $obj.meth($arg); also used for the # indirect form $obj."$name"($arg). It receives the decontainerized invocant, # the method name, and the args (starting with the invocant including any # container). nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-meth-call', -> $capture { # See if this callsite is heading megamorphic due to loads of different # method names or types; if so, we'll try to cope with that. my $obj := nqp::captureposarg($capture, 0); my str $name := nqp::captureposarg_s($capture, 1); my $how := nqp::how_nd($obj); my int $cache-size := nqp::dispatch('boot-syscall', 'dispatcher-inline-cache-size'); if $cache-size >= $MEGA-METH-CALLSITE-SIZE && nqp::istype($how, Perl6::Metamodel::ClassHOW) { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call-mega', $capture); } else { # See if we're making the method lookup on a pun; if so, rewrite the args # to do the call on the pun. if nqp::istype($how, Perl6::Metamodel::RolePunning) && $how.is_method_call_punned($obj, $name) { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0)); $obj := $how.pun($obj); $how := $obj.HOW; $capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $obj); $capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2), 2, $obj); } # Try to resolve the method call. # TODO Assorted optimizations are possible here later on to speed up some # kinds of dispatch, including: # * Using the dispatcher to directly rewrite args and invoke FALLBACK if # needed # * Handling some forms of delegation via the dispatcher mechanism my $meth := nqp::decont($how.find_method($obj, $name)); # Report an error if there is no such method. unless nqp::isconcrete($meth) { my $class := nqp::getlexcaller('$?CLASS'); report-method-not-found($obj, $name, $class, $how, nqp::iscont($obj)); } # Establish a guard on the invocant type and method name (however the name # may well be a literal, in which case this is free). nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0)); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1)); # Add the resolved method and delegate to the resolved method dispatcher. my $capture_delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $meth); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call-resolved', $capture_delegate); } }); sub report-method-not-found($obj, $name, $class, $how, $containerized) { my $msg := "Method '$name' not found for invocant of class '{$how.name($obj)}'"; if $name eq 'STORE' { Perl6::Metamodel::Configuration.throw_or_die( 'X::Assignment::RO', $msg, :value($obj)); } else { Perl6::Metamodel::Configuration.throw_or_die( 'X::Method::NotFound', $msg, :invocant($obj), :method($name), :typename($how.name($obj)), :private(nqp::hllboolfor(0, 'Raku')), :in-class-call(nqp::hllboolfor(nqp::eqaddr(nqp::what($obj), $class), 'Raku')), :containerized(nqp::hllboolfor($containerized, 'Raku')) ); } } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-meth-call-mega', -> $capture { # We're megamorphic in both type and name. Make sure the type has a lookup # table, and ensure the method exists. If it does not have a method table # then we will not install this dispatcher; we may already have a type # megamorphic handler in place and only missed it because we temporarily # lacked the calculated flattened method table. This avoids us stacking # up the same program repeatedly at the callsite. my $obj := nqp::captureposarg($capture, 0); my $how := nqp::how_nd($obj); unless nqp::isconcrete(nqp::getattr($how, Perl6::Metamodel::ClassHOW, '$!cached_all_method_table')) { nqp::dispatch('boot-syscall', 'dispatcher-do-not-install'); } my %lookup := $how.all_method_table($obj); my str $name := nqp::captureposarg_s($capture, 1); if nqp::isconcrete(nqp::atkey(%lookup, $name)) { # It exists. We'll set up a dispatch program that tracks the HOW of # the type, looks up the cached method table on it, and then tracks # the resolution of the method. my $track-obj := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); my $track-how := nqp::dispatch('boot-syscall', 'dispatcher-track-how', $track-obj); my $track-table := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-how, Perl6::Metamodel::ClassHOW, '$!cached_all_method_table'); my $track-name := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1); my $track-resolution := nqp::dispatch('boot-syscall', 'dispatcher-index-tracked-lookup-table', $track-table, $track-name); # This is only a valid dispatch program if the method is found. (If # not, we'll run this again to report the error.) nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-resolution); # Add the resolved method and delegate to the resolved method dispatcher. my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $capture, 0, $track-resolution); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call-resolved', $capture-delegate); } else { # Probably method not found, but sometimes the cache ends up missing # entries. my $slowpath-found := $how.find_method($obj, $name); if nqp::isconcrete($slowpath-found) { nqp::dispatch('boot-syscall', 'dispatcher-do-not-install'); my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $slowpath-found); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call-resolved', $capture-delegate); } else { my $class := nqp::getlexcaller('$?CLASS'); report-method-not-found($obj, $name, $class, $how, nqp::iscont($obj)); } } }); # Qualified method call dispatcher. This is used for calls of the form # $foo.Some::ClassOrRole::bar($arg). It receives the decontainerized # invocant, the method name, the type qualifier, and then the args # (starting with the invocant including any container). nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-meth-call-qualified', -> $capture { # Lookup outers of the caller and locate the first occurence of the # symbols of interest, which tell us about the caller type. my $ctx := nqp::ctxcaller(nqp::ctx()); my $caller-type := nqp::null(); nqp::repeat_while( nqp::isnull($caller-type) && !nqp::isnull($ctx), nqp::stmts( (my $pad := nqp::ctxlexpad($ctx)), nqp::if( nqp::existskey($pad, '$?CONCRETIZATION'), ($caller-type := nqp::atkey($pad, '$?CONCRETIZATION')), nqp::if( nqp::existskey($pad, '$?CLASS'), ($caller-type := nqp::atkey($pad, '$?CLASS')), ) ), ($ctx := nqp::ctxouterskipthunks($ctx)), ) ); # Establish a guard on the invocant and qualifying type. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0)); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 2)); # Try to resolve the method. my $obj := nqp::captureposarg($capture, 0); my str $name := nqp::captureposarg_s($capture, 1); my $type := nqp::captureposarg($capture, 2); my $meth; for ($caller-type, $obj.WHAT) { if nqp::istype($_, $type) { $meth := nqp::how_nd($_).find_method_qualified($_, $type, $name); last if nqp::isconcrete($meth); } } # If it's resolved, then: # 1. Drop the invocant and type arguments targetted at this resolution # 2. Insert the type we resolved the method against before those, for # deferral (the name is retained ahead of this) # 3. Finally, prepend the resolved method, and delegate to the resolved # method dispatcher. if nqp::isconcrete($meth) { my $with_name_and_args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2), 0); my $with_resolution_start := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $with_name_and_args, 0, $type); my $capture_delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $with_resolution_start, 0, $meth); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call-resolved', $capture_delegate); } # Otherwise, exception. else { Perl6::Metamodel::Configuration.throw_or_die( 'X::Method::InvalidQualifier', "Cannot dispatch to method $name on " ~ nqp::how_nd($type).name($type) ~ " because it is not inherited or done by " ~ nqp::how_nd($obj).name($obj), :method($name), :invocant($obj), :qualifier-type($type)); } }); # Maybe method dispatch, of the form $obj.?foo. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-meth-call-me-maybe', -> $capture { # Establish a guard on the invocant type. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0)); # Try to find the method. my $invocant := nqp::captureposarg($capture, 0); my str $name := nqp::captureposarg_s($capture, 1); my $meth := nqp::decont(nqp::how_nd($invocant).find_method($invocant, $name)); if nqp::isconcrete($meth) { # Found it. Put in resolved method and leave the rest to the resolved # method call dispatcher. my $capture_delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $meth); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call-resolved', $capture_delegate); } else { # Not found. Insert a Nil value at the start (boot-constant ignores # the rest of the args). nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, Nil)); } }); # Private method dispatch. This is actually a fallback, since in the best # case we can resolve the private method into a constant at code-gen time # and just invoke that. This happens with private methods in roles. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-meth-private', -> $capture { # Find the private method. my $type := nqp::captureposarg($capture, 0); my str $name := nqp::captureposarg_s($capture, 1); my $meth := nqp::how_nd($type).find_private_method($type, $name); # If it's found, then we drop the first two arguments, insert the # resolved callee, and invoke it. This goes directly to invoke, as # there's no deferral (due to no inheritance relationship) or multi # dispatch for private methods. if nqp::isconcrete($meth) { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0)); my $capture_delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 0, 2), 0, $meth); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $capture_delegate); } else { # TODO typed exception nqp::die("No such private method '$name' on " ~ nqp::how_nd($type).name($type)); } }); # A linked list is used to model the state of a dispatch that is deferring # through a set of methods or wrappers (a similar approach is used for # multi dispatch, but it needs more types of node). The Exhausted class # is used as a sentinel for the end of the chain (or for dispatchers in # general that have nothing more to contribute). The current state of the # dispatch points into the linked list at the appropriate point; the chain # itself is immutable, and shared over (runtime) dispatches. my class DeferralChain { has $!code; has $!next; method new($code, $next) { my $obj := nqp::create(self); nqp::bindattr($obj, DeferralChain, '$!code', $code); nqp::bindattr($obj, DeferralChain, '$!next', $next); $obj } method code() { $!code } method next() { $!next } }; my class Exhausted {}; # We also need a strategy for `callwith`. The complication is that arguments # given to `callwith` should trigger a resumption of the innermost dispatch # (for example, a wrap), but should also influence the arguments of outer # dispatches too (for example, a multi and/or method dispatch). The overall # strategy for `callwith` is: # 1. Dispatchers for resumable dispatches are always broken into two parts: # one that manages the initial dispatch when there is no resume, and # another that walks through the candidates. # 2. When we do a `callwith`, the current innermost of those dispatchers # marks itself exhausted. It then re-enters itself, passing along a # resumption of kind PROPAGATE_CALLWITH. This includes the information # required to put the next immediate call of the innermost dispatch # into effect (more in a moment on this). # 3. The re-entered dispatcher sets its resume init args up using the # arguments from the callwith propagation, so that a later `callsame` # will use the correct arguments. # 4. It then tries to use next-resumption to pass the callwith propagation # to any enclosing dispatcher. This always uses a common protocol: the # arguments are a kind (the PROPAGATE_CALLWITH integer constant), a # dispatcher name (string argument), a flag for if the arguments include # the invocant (an integer), followed by (typically) some arguments to # the named dispatcher. This is the information required to send the # dispatch to the destination determined by the *innermost* dispatcher. # 5. If there is no next resumption, then we do that call. # 6. Any outer dispatcher, upon receiving a PROPAGATE_CALLWITH, will mark # itself exhausted and re-enter itself with the new arguments. It then # continues with the above process from step 4. # Thus, a callwith in the case there is an active wrap, multi, and method # dispatch, ends up with all the previous resumable dispatchers for these # marked as exhausted, and new ones created, with the updated arguments. # Once all of these updated dispatchers are in place, then finally the next # candidate of the innermost dispatch is invoked. sub nil-or-callwith-propagation-terminal($capture) { unless nqp::dispatch('boot-syscall', 'dispatcher-next-resumption', $capture) { if nqp::captureposarg_i($capture, 0) == nqp::const::DISP_PROPAGATE_CALLWITH { my str $dispatcher := nqp::captureposarg_s($capture, 1); my $invoke-args := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 0, 3); nqp::dispatch('boot-syscall', 'dispatcher-delegate', $dispatcher, $invoke-args); } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, Nil)); } } } # Resolved method call dispatcher. This is used to call a method, once we have # already resolved it to a callee. Its first arg is the callee, the second and # third are the type and name (used in deferral), and the rest are the args to # the method. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-meth-call-resolved', # Initial dispatch -> $capture { # Save dispatch state for resumption. We don't need the method that will # be called now, so drop it. my $resume-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-set-resume-init-args', $resume-capture); # Drop the dispatch start type and name, and delegate to multi-dispatch or # just invoke if it's single dispatch. my $delegate_capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 1, 2); my $method := nqp::captureposarg($delegate_capture, 0); my int $code-constant := nqp::dispatch('boot-syscall', 'dispatcher-is-arg-literal', $capture, 0); unless $code-constant { # Need at least a type guard on the callee, if it's not constant. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0)); } if nqp::istype($method, Routine) { if nqp::can($method, 'WRAPPERS') { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke-wrapped', $delegate_capture); } elsif nqp::can($method, 'CALL-ME') { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $delegate_capture); } else { # If it's not a constant, need a guard on whether it's a dispatcher, # and if so on the candidate list. (Will want to move this when we # have a megamorphic multi solution.) unless $code-constant { nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-attr', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0), Routine, '@!dispatchees')); } my str $dispatcher := $method.is_dispatcher ?? 'raku-multi' !! 'raku-invoke'; nqp::dispatch('boot-syscall', 'dispatcher-delegate', $dispatcher, $delegate_capture); } } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $delegate_capture); } }, # Resumption. The capture itself has a first argument indicating the kind # of resumption operation we're doing. The resume init capture's first two # arguments are the type that we initially did a method dispatch against # and the method name respectively. In this resumption we calculate the # set of methods we will defer through. We then delegate to another # dispatcher to handle movement through that list (this structure helps # us to handle `callwith`). -> $capture { # We put a sentinel value into the resume state in the case that we have # already set up the method resumption. We always guard on it too. my $state := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-state'); my $track_state := nqp::dispatch('boot-syscall', 'dispatcher-track-resume-state'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_state); # Mark that the deferral was already set up, so we don't do this # again. nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); # Guard on the kind of resume we're doing, and get that flag. my $track_kind := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_kind); my int $kind := nqp::captureposarg_i($capture, 0); # If the state is null, it's we are entering a walk through the methods. # We can short-circuit this if it's a lastcall (and the Exhausted above # puts it into effect). if nqp::isnull($state) && $kind != nqp::const::DISP_LASTCALL { # No state, so just starting the resumption. Guard on the # invocant type and name. my $init := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-init-args'); my $track_start_type := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track_start_type); my $track_name := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 1); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_name); # Build up the list of methods to defer through. my $start_type := nqp::captureposarg($init, 0); my str $name := nqp::captureposarg_s($init, 1); my $start_type_how := nqp::how_nd($start_type); my @mro := nqp::can($start_type_how, 'mro_unhidden') ?? $start_type_how.mro_unhidden($start_type) !! nqp::can($start_type_how, 'mro') ?? $start_type_how.mro($start_type) !! []; my @methods; for @mro { my %mt := nqp::hllize(nqp::how_nd($_).method_table($_)); if nqp::existskey(%mt, $name) { @methods.push(%mt{$name}); } } # Turn it into a linked list. my $chain := Exhausted; if nqp::elems(@methods) >= 2 { @methods.shift; # Discard the first one, which we initially called while @methods { $chain := DeferralChain.new(@methods.pop, $chain); } } # Determine the args to pass to the method we defer to. If it's a # callwith, then the arguments are given to us here. If it's a # callwith propagration, we need to use those args also. Otherwise, # they are those from the initial capture. my $args_with_kind; if $kind == nqp::const::DISP_CALLWITH { # Rewrite the kind into callsame, since we've already accounted # for the callwith. We do need to insert the original invocant. my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); my $with_invocant := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $args, 0, nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 2)); $args_with_kind := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $with_invocant, 0, nqp::const::DISP_CALLSAME); } elsif $kind == nqp::const::DISP_PROPAGATE_CALLWITH { $args_with_kind := $capture; } else { my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $init, 0, 2); $args_with_kind := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $args, 0, $track_kind); } # Prepend the chain of methods we dispatch through and defer. my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $args_with_kind, 0, $chain); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-deferral', $delegate); } # Otherwise, we already set up - and presumably completed - walking # through the methods. else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, Nil)); } }); # Method deferral dispatcher. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-meth-deferral', # Entry to the deferral, with the chain of methods to walk through as the # first argument, the resumption kind as the second argument, and the # args to the method (including the invocant) coming next. We assume here # that we already established guards on kind and similar, and that if we # have a lastcall we'll have handled it rather than sending it here. -> $capture { # If the chain is Exhausted, then we will delegate to Nil or to # the propagate callwith terminal. my $chain := nqp::captureposarg($capture, 0); if nqp::eqaddr($chain, Exhausted) { nil-or-callwith-propagation-terminal(nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0)); } # If we're propagating a callwith then we need to set the resume init args # and then invoke the thing that is being propagated. elsif nqp::captureposarg_i($capture, 1) == nqp::const::DISP_PROPAGATE_CALLWITH { my $resume-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 1, 4); # Drop kind, dispatcher name, invocant flag, invokee nqp::dispatch('boot-syscall', 'dispatcher-set-resume-init-args', $resume-capture); my str $dispatcher := nqp::captureposarg_s($capture, 2); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 0, 4); nqp::dispatch('boot-syscall', 'dispatcher-delegate', $dispatcher, $delegate); } # Otherwise, need to do a dispatch step. else { # The resume init state for a multi-step deferral is the next # thing in the chain prepended to the dispatch arguments. my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 0, 2); my $resume-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $args, 0, $chain.next); nqp::dispatch('boot-syscall', 'dispatcher-set-resume-init-args', $resume-capture); # Now perform the action needed based upon the kind of resumption # we have. method-deferral-step($chain, nqp::captureposarg_i($capture, 1), $args); } }, # Resumption, wherein we walk another step through the chain. -> $capture { # Guard on the kind of resume we're doing, and get that flag. my $track_kind := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_kind); my int $kind := nqp::captureposarg_i($capture, 0); # If we're doing a lastcall, set the state to exhausted and we're done. if $kind == nqp::const::DISP_LASTCALL { nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, Nil)); } else { # If there's no dispatch state yet, we're on our first round of # resumption for this dispatcher. Otherwise, look to the state to # find the next method. my $init := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-init-args'); my $state := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-state'); my $track_state := nqp::dispatch('boot-syscall', 'dispatcher-track-resume-state'); my $chain; my $track_chain; if nqp::isnull($state) { # Guard that the resume state is null, and then extract the chain # from the init state. nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_state); $chain := nqp::captureposarg($init, 0); $track_chain := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 0); } else { # The chain is the state. $chain := $state; $track_chain := $track_state; } # If we're exhausted already, then produce Nil. if nqp::istype($chain, Exhausted) { nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_chain); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, Nil)); } # If we're propagating new callwith args then mark this dispatcher # exhausted and re-enter with the updated args and current chain. elsif $kind == nqp::const::DISP_PROPAGATE_CALLWITH { nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $capture, 0, $track_chain); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-deferral', $capture-delegate); } else { # Otherwise, guard on the candidate that we shall be invoking. my $track_method := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track_chain, DeferralChain, '$!code'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_method); # Now perform the action needed based upon the kind of resumption # we have. my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $init, 0); if $kind == nqp::const::DISP_CALLWITH { # Set the state to exhausted as we're abandoning the walk through # the methods with these args. nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); # Re-enter this dispatcher with the new args. my $new_args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); my $with_invocant := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $new_args, 0, nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $args, 0)); my $new_args_with_kind := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $with_invocant, 0, nqp::const::DISP_CALLSAME); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $new_args_with_kind, 0, $track_chain); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-deferral', $delegate); } else { # Update dispatch state to point to the next method. my $track_next := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track_chain, DeferralChain, '$!next'); nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state', $track_next); # It's a normal step. method-deferral-step($chain, $kind, $args); } } } }); sub method-deferral-step($chain-head, int $kind, $args) { # Look at the kind of deferral we have to decide what to do. my $next_method := $chain-head.code; if $kind == nqp::const::DISP_CALLSAME { # Call with same (that is, original) arguments. Invoke with those. # We drop the first two arguments (which are only there for the # resumption), add the code object to invoke, and then leave it # to the invoke dispatcher. my $delegate_capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $args, 0, $next_method); if nqp::istype($next_method, Routine) { if nqp::can($next_method, 'WRAPPERS') { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke-wrapped', $delegate_capture); } elsif nqp::can($next_method, 'CALL-ME') { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $delegate_capture); } elsif $next_method.is_dispatcher { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi', $delegate_capture); } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $delegate_capture); } } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $delegate_capture); } } elsif $kind == nqp::const::DISP_NEXTCALLEE { # We just want method itself, not to invoke it. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $args, 0, $next_method)); } else { nqp::die('Unexpected resumption kind in method dispatch'); } } # Multi-dispatch dispatcher, used for both multi sub and multi method dispatch. # Assumes that we have already guarded on a literal code object (methods) or # ensured consistency of routine (subs where closure cloning may take place). # This does not do the heart of the dispatch itself, but rather determines if # we have a simple or complex proto, and thus whether we need to invoke the # proto at all. In the case of a complex proto, we use dispatch resumption to # continue with the dispatch. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-multi', # Initial dispatch, only setting up resumption if we need to invoke the # proto. -> $capture { my $callee := nqp::captureposarg($capture, 0); my int $onlystar := $callee.onlystar; my int $simple := $onlystar && simple-args-proto($callee, $capture); if $simple { # Don't need to invoke the proto itself, so just get on with the # candidate dispatch. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi-core', $capture); } else { # Set resume init args and run the proto. nqp::dispatch('boot-syscall', 'dispatcher-set-resume-init-args', $capture); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $capture); } }, # Resumption means that we have reached the {*} in the proto and so now # should go ahead and do the dispatch. Make sure we only do this if we # are signalled to that it's a resume for an onlystar. -> $capture { my $track_kind := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_kind); my int $kind := nqp::captureposarg_i($capture, 0); if $kind == nqp::const::DISP_ONLYSTAR { # Put a guard on the dispatchee list, as a given proto may be # cloned and used for multiple candidate lists. my $init_args := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-init-args'); my $track_callee := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init_args, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track_callee, Routine, '@!dispatchees')); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi-core', $init_args); } elsif !nqp::dispatch('boot-syscall', 'dispatcher-next-resumption', $capture) { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-resume-error', $capture); } }); # We in principle could always call the proto and have correct behavior. It is, # however, nice when we can go straight to a candidate. To see if that's the # case, we have to introspect the signature. sub simple-args-proto($callee, $capture) { # If we're compiling the setting, all sorts of things we need to do the # analysis are missing, so don't even try. Nothing invoked in the # CORE.setting build today that has an onlystar proto actually needs # its proto invoking today, so we also regard them all as simple, to # avoid a bunch of throwaway compilations. return 1 if $*COMPILING_CORE_SETTING; # If it's out of range so far as arity goes, we'll call the proto to # produce an error. my $signature := $callee.signature; my int $got-args := nqp::captureposelems($capture) - 1; # First element is the callee return 0 if nqp::islt_i($got-args, $signature.arity) || nqp::isgt_n($got-args, $signature.count); # Otherwise, arity is alright. Look through the params. my int $accepts-any-named := 0; for $signature.params.FLATTENABLE_LIST -> $param { # If there's a constraint or unpack, need the proto to be run. return 0 unless nqp::isnull(nqp::getattr($param, Parameter, '@!post_constraints')) && nqp::isnull(nqp::getattr($param, Parameter, '$!sub_signature')); # Otherwise, go by kind of parameter. if $param.capture { $accepts-any-named := 1; } elsif $param.slurpy { $accepts-any-named := 1 if $param.named; } elsif $param.named { # Can be a bit smarter by diffing what nameds we have or miss, but # for now conservatively run the proto. return 0; } } # If we get here, it's OK to elide running the proto so long as if we have # any named args, it accepts them. return nqp::capturehasnameds($capture) ?? $accepts-any-named !! 1; } # If we invoke a multi with an argument that is a Proxy (or some other non-Scalar # container), we need to read the value(s) from the Proxy argument(s) and then go # on with the dispatch. The ProxyReaderFactory produces code objects that do # that. We key it on total positional arguments, whether there are nameds to # strip, and then the indices of the arguments to strip. class ProxyReaderFactory { has $!lock; has %!readers; method new() { self.bless: lock => NQPLock.new, readers => nqp::hash() } method reader-for($capture, $indices) { $!lock.protect: { # Form a key. my int $num-args := nqp::captureposelems($capture); my int $has-nameds := nqp::capturehasnameds($capture); my str $key := $num-args ~ ($has-nameds ?? '%' !! '|'); my int $i; while $i < nqp::elems($indices) { $key := $key ~ nqp::atpos_i($indices, $i) ~ ','; $i++; } # If we don't already have a reader for this key, produce it. unless nqp::existskey(%!readers, $key) { %!readers{$key} := self.'!produce-reader'($num-args, $has-nameds, $indices); } %!readers{$key} } } method !produce-reader($num-args, $has-nameds, $indices) { # Create a block taking each positional arg required, adding a # slurpy named if needed. my $block := QAST::Block.new(:is_thunk); my int $i := 0; while $i < $num-args { $block.push(QAST::Var.new( :name("a$i"), :decl, :scope )); $i++; } if $has-nameds { $block.push(QAST::Var.new( :name, :decl, :scope, :named, :slurpy )); } # Produce a dispatch op with the required arguments decontainerized. my $dispatch := QAST::Op.new: :op('dispatch'), QAST::SVal.new( :value('boot-resume') ), QAST::IVal.new( :value(nqp::const::DISP_DECONT) ); $i := 0; my $decont-index := 0; while $i < $num-args { my $var := QAST::Var.new( :name("a$i"), :scope ); if nqp::atpos_i($indices, $decont-index) == $i { $dispatch.push(QAST::Op.new( :op, $var )); $decont-index++; } else { $dispatch.push($var); } $i++; } if $has-nameds { $dispatch.push(QAST::Var.new( :name, :scope, :named, :flat )); } $block.push($dispatch); # Compile and return it. my $comp := nqp::getcomp('Raku'); $comp.compile($block, :from($comp.exists_stage('optimize') ?? 'optimize' !! 'qast')) } } my $PROXY-READERS := ProxyReaderFactory.new; nqp::bindhllsym('Raku', 'PROXY-READERS', $PROXY-READERS); # The core of multi dispatch. Once we are here, either there was a simple # proto that we don't need to inovke, or we already did invoke the proto. # # Multiple dispatch is relatively complex in the most general case. However, # the most common case by far consists of: # # * Arguments are not in any containers or in Scalar containers, which we can # dereference as part of the dispatch program # * A candidate that is identified by arity and nominal type, and thus can be # identified just using the callsite and guards on argument types # * No resumption via callsame and friends # # This is the case we want to optimize for, and is called a "trivial" multiple # dispatch. All other cases are "non-trivial", including the case where a # trivial multiple dispatch is resumed. In a trivial multiple dispatch, we # save the incoming argument tuple as dispatch state, establish guards, and # then delegate to raku-invoke to invoke the chose candidate. # # The case with non-Scalar containers is handled by first extracting those and # then proceeding with the dispatch. # # The non-trivial multiple dispatch establishes the guards that a trivial # multiple dispatch does, and then works through the dispatch plan. This is a # linked list featuring candidates to try calling, terminated either with a # fallback to the next resumable dispatcher (if we're in a resume) or to the # production of an error (ambiguous dispatch or no applicable candidate). # # The plan nodes are as follows: # * A candidate to call; we don't expect any bind failure (that is, we # consider it safe from nominality alone). my class MultiDispatchCall { has $!candidate; has $!next; method new($candidate) { my $obj := nqp::create(self); nqp::bindattr($obj, MultiDispatchCall, '$!candidate', $candidate); $obj } method set-next($next) { $!next := $next; } method candidate() { $!candidate } method next() { $!next } method debug() { "Candidate " ~ $!candidate.signature.raku ~ "\n" ~ $!next.debug } } # * A candidate to try and invoke; if there's a bind failure, it will be # mapped into a resumption my class MultiDispatchTry is MultiDispatchCall { method debug() { "Try candidate " ~ self.candidate.signature.raku ~ "\n" ~ self.next.debug } } # * An ambiguity. It's only an error if it's reached during the initial # phase of dispatch, not during a callsame-alike, thus why the chain # continues beyond this point. my class MultiDispatchAmbiguous { has $!next; method set-next($next) { $!next := $next; } method next() { $!next } method debug() { "Ambiguous\n" ~ $!next.debug } } # * The end of the candidates. Either a "no applicable candidates" error # if we are in the initial phase of dispatch, or a next resumption (or # Nil) otherwise. my class MultiDispatchEnd { method debug() { "End" } } # * Not actually used in a plan, but instead conveys that we have containers # that need complex (running code) removal. This is created with the indices # of the arguments that need it removing. my class MultiDispatchNonScalar { has $!args; method new($args) { my $obj := nqp::create(self); nqp::bindattr($obj, MultiDispatchNonScalar, '$!args', $args); $obj } method args() { $!args } method debug() { "Non-Scalar container dispatch" } } # Apart from the last one, these are used as the dispatch state; this is the # same immutable linked list traversal approach as used in other kinds of # resumption. # # The plan is calculated by the following code. Note that the trivial case # also uses this plan calculation routine, but in a "stop on trivial success" # mode. A resumption of a trivial dispatch will call this again, but with that # flag not set, and then drop the first candidate from the plan, which was # already invoked. It will then walk the candidate list as usual. my int $DEFCON_DEFINED := 1; my int $DEFCON_UNDEFINED := 2; my int $DEFCON_MASK := $DEFCON_DEFINED +| $DEFCON_UNDEFINED; my int $TYPE_NATIVE_INT := 4; my int $TYPE_NATIVE_UINT := 32; my int $TYPE_NATIVE_NUM := 8; my int $TYPE_NATIVE_STR := 16; my int $TYPE_NATIVE_MASK := $TYPE_NATIVE_INT +| $TYPE_NATIVE_UINT +| $TYPE_NATIVE_NUM +| $TYPE_NATIVE_STR; my int $BIND_VAL_OBJ := 0; my int $BIND_VAL_INT := 1; my int $BIND_VAL_UINT := 10; my int $BIND_VAL_NUM := 2; my int $BIND_VAL_STR := 3; sub has-named-args-mismatch($capture, %info) { # First consider required nameds. my $required-name-sets := %info; my $nameds-list := nqp::dispatch('boot-syscall', 'capture-names-list', $capture); if $required-name-sets { # Quick exit if we required names, but have none. return 1 unless $nameds-list; # Otherwise check that required nameds are present. my int $i := 0; my int $n := nqp::elems($required-name-sets); while $i < $n { my int $found := 0; my $names := nqp::atpos($required-name-sets, $i); my int $j := 0; my int $m := nqp::elems($names); while $j < $m { if nqp::captureexistsnamed($capture, nqp::atpos_s($names, $j)) { $found := 1; last; } $j++; } return 1 unless $found; $i++; } } # If we don't accept all nameds, then check there are acceptable nameds. if $nameds-list && !%info { # Quick exit if there are no allowed nameds. my $allowed-names := %info; return 1 unless $allowed-names; # Go through the nameds and check they are allowed. my int $i; my int $n := nqp::elems($nameds-list); while $i < $n { return 1 unless nqp::existskey($allowed-names, nqp::atpos_s($nameds-list, $i)); $i++; } } # Otherwise, no mismatch. 0 } sub raku-multi-plan(@candidates, $capture, int $stop-at-trivial, $orig-capture = $capture) { # First check there's no non-Scalar containers in the positional arguments. # If there are, establish guards relating to those and we're done. Native # references don't count; we know the native types they shall match up with # and don't need to dereference them. my int $num_args := nqp::captureposelems($capture); my int $i; my $non-scalar := nqp::list_i(); while $i < $num_args { my int $got_prim := nqp::captureposprimspec($capture, $i); if $got_prim == 0 { my $value := nqp::captureposarg($capture, $i); if nqp::isconcrete_nd($value) && nqp::iscont($value) && !nqp::istype_nd($value, Scalar) && !(nqp::iscont_i($value) || nqp::iscont_u($value) || nqp::iscont_n($value) || nqp::iscont_s($value)) { nqp::push_i($non-scalar, $i); } } $i++; } if nqp::elems($non-scalar) { # Establish guards on types of all positionals, but not on the values # inside of them if they are Scalar containers; we just need to make # sure we have the appropriate tuple of Proxy vs non-Proxy for the # Proxy removal code we'll invoke. my int $i; while $i < $num_args { if nqp::captureposprimspec($capture, $i) == 0 { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, $i)); } $i++; } # Hand back the indices we need to strip Proxy from. return MultiDispatchNonScalar.new($non-scalar); } # We keep track of the head of the plan as well as the tail node of it, # so we know where to add the next step. my $current-head := nqp::null(); my $current-tail := nqp::null(); # Look through all candidates. Eliminate those that can be ruled out by # setting guards on the incoming arguments OR by the shape of the # callsite. That callsite shape includes argument count, which named # arguments are present, and which arguments are natively typed. my int $cur_idx := 0; my int $done := 0; my $need_scalar_read := nqp::list_i(); my $need_scalar_rw_check := nqp::list_i(); my $need_type_guard := nqp::list_i(); my $need_conc_guard := nqp::list_i(); my @possibles; my $Positional := nqp::gethllsym('Raku', 'MD_Pos'); until $done { # The candidate list is broken into tied groups (that is, groups of # candidates that are equally narrow). Those are seperated by a # type object sentinel. my $cur_candidate := nqp::atpos(@candidates, $cur_idx++); if nqp::isconcrete($cur_candidate) { # Candidate; does the arity fit? (If not, it drops out on callsite # shape.) if $num_args >= nqp::atkey($cur_candidate, 'min_arity') && $num_args <= nqp::atkey($cur_candidate, 'max_arity') { # Arity OK; now go through the arguments and see if we can # eliminate any of them based on guardable properties. my int $type_check_count := nqp::atkey($cur_candidate, 'num_types') > $num_args ?? $num_args !! nqp::atkey($cur_candidate, 'num_types'); my int $type_mismatch := 0; my int $rwness_mismatch := 0; my int $i := 0; while $i < $type_check_count && !($type_mismatch +| $rwness_mismatch) { # Obtain parameter properties. my $type := nqp::atpos(nqp::atkey($cur_candidate, 'types'), $i); my int $is-mu := nqp::eqaddr($type, Mu); my int $type_flags := nqp::atpos_i(nqp::atkey($cur_candidate, 'type_flags'), $i); my int $definedness := $type_flags +& $DEFCON_MASK; my int $rwness := nqp::atpos_i(nqp::atkey($cur_candidate, 'rwness'), $i); # Get the primitive type of the argument, and go on whether it's an # object or primitive type. my int $got_prim := nqp::captureposprimspec($capture, $i); my int $want_prim := $type_flags +& $TYPE_NATIVE_MASK; if $got_prim == 0 && $want_prim == 0 { # For a type that's exactly Mu we do not need a type # guard, however if it's got a definedness constraint # we do, since we might then wrongly accept a Scalar # container that meets the definedness property. if $definedness || !$is-mu { nqp::bindpos_i($need_type_guard, $i, 1); } # It's an object type. Obtain the value, and go by if it's a # container or not. my $value := nqp::captureposarg($capture, $i); my int $promoted_primitive; if nqp::iscont($value) && nqp::isconcrete_nd($value) { # Containerized. Scalar we handle specially. if nqp::istype_nd($value, Scalar) { nqp::bindpos_i($need_scalar_read, $i, 1); if $rwness { nqp::bindpos_i($need_scalar_rw_check, $i, 1); my $desc := nqp::getattr($value, Scalar, '$!descriptor'); unless nqp::isconcrete($desc) { $rwness_mismatch := 1; } } $value := nqp::getattr($value, Scalar, '$!value'); } # Otherwise, it should be a native reference. We'll # promote these to their boxed type. elsif nqp::iscont_i($value) { $value := Int; $promoted_primitive := 1; } elsif nqp::iscont_u($value) { $value := Int; $promoted_primitive := 1; } elsif nqp::iscont_n($value) { $value := Num; $promoted_primitive := 1; } elsif nqp::iscont_s($value) { $value := Str; $promoted_primitive := 1; } else { nqp::die('Unknown kind of l-value in multiple dispatch'); } } else { # If we need an rw argument and didn't get a container, # we're out of luck. Before asserting this, we should make # sure that the original container (which maybe was a # Proxy that was removed in the args we're doing the # dispatch over) was not itself rw. if $rwness && !nqp::iscont(nqp::captureposarg($orig-capture, $i)) { $rwness_mismatch := 1; } } # Ensure the value meets the required type constraints. unless $is-mu || nqp::istype_nd(nqp::hllizefor($value, 'Raku'), $type) { if $type =:= $Positional { # Things like Seq can bind to an @ sigil. my $PositionalBindFailover := nqp::gethllsym('Raku', 'MD_PBF'); unless nqp::istype_nd($value, $PositionalBindFailover) { $type_mismatch := 1; } } else { $type_mismatch := 1; } } # Also ensure any concreteness constraints are unheld. if !$type_mismatch && $definedness { my int $got := $promoted_primitive || nqp::isconcrete_nd($value); if ($got && $definedness == $DEFCON_UNDEFINED) || (!$got && $definedness == $DEFCON_DEFINED) { $type_mismatch := 1; } nqp::bindpos_i($need_conc_guard, $i, 1); } } elsif $got_prim == 0 { # and $want_prim != 0 per last condition # Make sure it's the expected kind of native container. nqp::bindpos_i($need_type_guard, $i, 1); my $contish := nqp::captureposarg($capture, $i); unless (($type_flags +& $TYPE_NATIVE_INT) && nqp::iscont_i($contish)) || (($type_flags +& $TYPE_NATIVE_UINT) && nqp::iscont_u($contish)) || (($type_flags +& $TYPE_NATIVE_NUM) && nqp::iscont_n($contish)) || (($type_flags +& $TYPE_NATIVE_STR) && nqp::iscont_s($contish)) { $type_mismatch := 1; } } else { # It's a primitive type. If we want rw, then we ain't got it. if $rwness { $rwness_mismatch := 1; } # If we want a type object, it's certainly not that either. elsif $definedness == $DEFCON_UNDEFINED { $type_mismatch := 1; } # If we want a primitive type, but got the wrong one, then it's # a mismatch. elsif $want_prim { if (($type_flags +& $TYPE_NATIVE_INT) && $got_prim != $BIND_VAL_INT) || (($type_flags +& $TYPE_NATIVE_UINT) && $got_prim != $BIND_VAL_UINT) || (($type_flags +& $TYPE_NATIVE_NUM) && $got_prim != $BIND_VAL_NUM) || (($type_flags +& $TYPE_NATIVE_STR) && $got_prim != $BIND_VAL_STR) { $type_mismatch := 1; } } # Otherwise, we want an object type. Figure out the correct # one that we shall box to. else { my $test_type := $got_prim == $BIND_VAL_INT ?? Int !! $got_prim == $BIND_VAL_UINT ?? Int !! $got_prim == $BIND_VAL_NUM ?? Num !! Str; $type_mismatch := 1 unless nqp::istype($test_type, $type); } } $i++; } # Add it to the possibles list of this group. unless $type_mismatch || $rwness_mismatch { nqp::push(@possibles, $cur_candidate); } } } else { # End of tied group. If there's possibles... if nqp::elems(@possibles) { # Build a new list of filtered possibles by ruling out any # that have unaccepted of missing nameds. Track if we need bind # checks or if we have declarative candidates. Also check for # defaults and exact arity matches, which we can use for # tie-breaking if there are ambiguities. my int $i; my int $n := nqp::elems(@possibles); my int $need-bind-check; my int $first-group := nqp::isnull($current-head); my @filtered-possibles; my @defaults; my @exact-arity; while $i < $n { my %info := @possibles[$i]; unless has-named-args-mismatch($capture, %info) { nqp::push(@filtered-possibles, %info); $need-bind-check++ if nqp::existskey(%info, 'bind_check'); my $sub := %info; nqp::push(@defaults, %info) if nqp::can($sub, 'default') && $sub.default; nqp::push(@exact-arity, %info) if %info == $num_args && %info == $num_args; } $i++; } # If we still have multiple possibles and we don't need a bind # check, try tie-breakers, and failing that add an ambiguity # marker. if !$need-bind-check && nqp::elems(@filtered-possibles) > 1 { if nqp::elems(@defaults) == 1 { @filtered-possibles := @defaults; } elsif nqp::elems(@exact-arity) == 1 { @filtered-possibles := @exact-arity; } else { my $node := MultiDispatchAmbiguous.new(); if nqp::isnull($current-head) { $current-head := $node; } else { $current-tail.set-next($node); } $current-tail := $node; } } # Add the filtered possibles to the plan. $i := 0; $n := nqp::elems(@filtered-possibles); while $i < $n { my %info := @filtered-possibles[$i]; my $node; if $need-bind-check { # Ensure it's already compiled, otherwise we can have # compiler frames obscuring the bind control record we # use for trying the next candidate. my $sub := %info; my $cs := nqp::getattr($sub, Code, '@!compstuff'); unless nqp::isnull($cs) { my $ctf := $cs[1]; $ctf() if $ctf; } $node := MultiDispatchTry.new($sub); } else { $node := MultiDispatchCall.new(%info); } if nqp::isnull($current-head) { $current-head := $node; } else { $current-tail.set-next($node); } $current-tail := $node; $i++; } # If we are to stop at a trivial match and nothing needs a # bind check, and we've no results before now, we're done. if $stop-at-trivial && $first-group && nqp::elems(@filtered-possibles) == 1 && $need-bind-check == 0 { $done := 1; } # Otherwise, clear the set of possibles for the next group. else { nqp::setelems(@possibles, 0); } } # If we're really at the end of the list, we're done. unless nqp::isconcrete(nqp::atpos(@candidates, $cur_idx)) { $done := 1; } } } # Add an end node. if nqp::isnull($current-head) { $current-head := MultiDispatchEnd; } else { $current-tail.set-next(MultiDispatchEnd); } # Install guards as required. $i := 0; while $i < $num_args { my $tracked_value; if nqp::atpos_i($need_scalar_read, $i) { my $tracked := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, $i); if nqp::atpos_i($need_scalar_rw_check, $i) { my $tracked_desc := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $tracked, Scalar, '$!descriptor'); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $tracked_desc); } $tracked_value := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $tracked, Scalar, '$!value'); } else { $tracked_value := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, $i); } if nqp::atpos_i($need_type_guard, $i) { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked_value); } if nqp::atpos_i($need_conc_guard, $i) { nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $tracked_value); } $i++; } # Return the dispatch plan. $current-head } sub form-raku-capture($vm-capture) { my $raku-capture := nqp::create(Capture); nqp::bindattr($raku-capture, Capture, '@!list', nqp::dispatch('boot-syscall', 'capture-pos-args', $vm-capture)); nqp::bindattr($raku-capture, Capture, '%!hash', nqp::dispatch('boot-syscall', 'capture-named-args', $vm-capture)); $raku-capture } sub multi-junction-failover($capture) { # Take a first pass to see if there's a Junction arg (we look at both # named and positional). my int $num-args := nqp::dispatch('boot-syscall', 'capture-num-args', $capture); my int $i; my $found-junction; while $i < $num-args { my int $got-prim := nqp::dispatch('boot-syscall', 'capture-arg-prim-spec', $capture, $i); if $got-prim == 0 { my $value := nqp::dispatch('boot-syscall', 'capture-arg-value', $capture, $i); if nqp::isconcrete($value) && nqp::istype($value, Junction) { $found-junction := 1; last; } } $i++; } # If there is a Junction arg, then take another pass through to put type # guards on all argument types. if $found-junction { $i := 0; while $i < $num-args { if nqp::dispatch('boot-syscall', 'capture-arg-prim-spec', $capture, $i) == 0 { my $arg := nqp::dispatch('boot-syscall', 'capture-arg-value', $capture, $i); my $tracked := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, $i); if nqp::istype_nd($arg, Scalar) { $tracked := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $tracked, Scalar, '$!value'); } nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $tracked); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $tracked); } $i++; } } $found-junction } sub multi-no-match-handler($target, $dispatch-arg-capture, $orig-capture, $orig-arg-capture) { # If no candidates are found but there is a Junction argument, we'll # dispatch to that. if multi-junction-failover($dispatch-arg-capture) { # Guards added here my $with-invocant := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $orig-capture, 0, Junction); my $threader := Junction.HOW.find_method(Junction, 'AUTOTHREAD') // nqp::die('Junction auto-thread method not found'); my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $with-invocant, 0, $threader); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $capture-delegate); } # Otherwise, it's just an error. else { Perl6::Metamodel::Configuration.throw_or_die( 'X::Multi::NoMatch', "Cannot call " ~ $target.name() ~ "; no signatures match", :dispatcher($target), :capture(form-raku-capture($orig-arg-capture))); } } sub multi-ambiguous-handler($dispatch-plan, $target, $arg-capture) { my @ambiguous; my $ambig-call := $dispatch-plan.next; while nqp::istype($ambig-call, MultiDispatchCall) { nqp::push(@ambiguous, $ambig-call.candidate); $ambig-call := $ambig-call.next; } Perl6::Metamodel::Configuration.throw_or_die( 'X::Multi::Ambiguous', "Ambiguous call to " ~ $target.name(), :dispatcher($target), :@ambiguous, :capture(form-raku-capture($arg-capture))); } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-multi-core', # Initial dispatch. Tries to find an initial candidate. -> $capture { # Obtain the candidate list, producing it if it doesn't already exist. my $target := nqp::captureposarg($capture, 0); my @candidates := nqp::getattr($target, Routine, '@!dispatch_order'); if nqp::isnull(@candidates) { nqp::scwbdisable(); @candidates := $target.'!sort_dispatchees_internal'(); nqp::bindattr($target, Routine, '@!dispatch_order', @candidates); nqp::scwbenable(); } # Drop the first argument, to get just the arguments to dispatch on, and # then produce a multi-dispatch plan. Decide what to do based upon it. my $arg-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); my $dispatch-plan := raku-multi-plan(@candidates, $arg-capture, 1); if nqp::istype($dispatch-plan, MultiDispatchCall) && !nqp::istype($dispatch-plan, MultiDispatchTry) && nqp::istype($dispatch-plan.next, MultiDispatchEnd) { # Trivial multi dispatch. Set dispatch state for resumption, and # then delegate to raku-invoke to run it. nqp::dispatch('boot-syscall', 'dispatcher-set-resume-init-args', $capture); my $candidate := $dispatch-plan.candidate; my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $arg-capture, 0, $candidate); nqp::dispatch('boot-syscall', 'dispatcher-delegate', nqp::can($candidate, 'WRAPPERS') ?? 'raku-invoke-wrapped' !! 'raku-invoke', $capture-delegate); } elsif nqp::istype($dispatch-plan, MultiDispatchNonScalar) { # Need to strip the Proxy arguments and then try again. Produce a # proxy reader code object to do so, insert it as the first arg, # and delegate to a dispatcher to manage reading the args and # then retrying with the outcome. my $reader := $PROXY-READERS.reader-for($arg-capture, $dispatch-plan.args); my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $reader); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi-remove-proxies', $capture-delegate); } elsif nqp::istype($dispatch-plan, MultiDispatchAmbiguous) && nqp::istype($dispatch-plan.next, MultiDispatchCall) { multi-ambiguous-handler($dispatch-plan, $target, $arg-capture); } elsif nqp::istype($dispatch-plan, MultiDispatchEnd) { multi-no-match-handler($target, $arg-capture, $capture, $arg-capture); } else { # It's a non-trivial multi dispatch. Prefix the capture with # the dispatch plan, and also a DISP_NONE to indicate this # is not a resumption of any kind. Then delegate to the # non-trivial multi dispatcher. my $capture-with-plan := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $dispatch-plan); my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $capture-with-plan, 0, nqp::const::DISP_NONE); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi-non-trivial', $capture-delegate); } }, # Resume of a trivial dispatch. -> $capture { # Obtain and guard on the kind of resume. my $kind := nqp::captureposarg_i($capture, 0); my $track-kind := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-kind); # We'll delegate the hard work to the non-trivial dispatcher. We # only want to do that once, however, and so set the dispatch state # to exhausted if we've already done it. Check that's not so. Also # shortcut here if it's lastcall. my $track-state := nqp::dispatch('boot-syscall', 'dispatcher-track-resume-state'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-state); my $state := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-state'); if nqp::isnull($state) && $kind != nqp::const::DISP_LASTCALL { # First time. Set state to exhausted. nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); # Obtain resume initialization arguments and form the plan. my $init := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-init-args'); my $target := nqp::captureposarg($init, 0); my @candidates := nqp::getattr($target, Routine, '@!dispatch_order'); my $arg-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $init, 0); my $dispatch-plan := raku-multi-plan(@candidates, $arg-capture, 0); # Put a guard on the dispatchees. my $track-target := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-target, Routine, '@!dispatchees')); # We already called the first candidate in the trivial plan, so # drop it. $dispatch-plan := $dispatch-plan.next; # Now go by the kind of resumption we have. if $kind == nqp::const::DISP_CALLWITH { # It's a callwith, so we'll use the provided args (except # for adding the invocant if it's a multi method), and then # delegate to the non-trivial dispatch handler. my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); if nqp::istype($target, Method) { my $track-invocant := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $arg-capture, 0); $args := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $args, 0, $track-invocant); } my $with-target := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $args, 0, $track-target); my $capture-with-plan := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $with-target, 0, $dispatch-plan); my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $capture-with-plan, 0, nqp::const::DISP_CALLWITH); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi-non-trivial', $capture-delegate); } elsif $kind == nqp::const::DISP_PROPAGATE_CALLWITH { # We're propagating a callwith. Insert our multi dispatch plan # and target after the kind and then pass it along to the # non-trivial dispatcher. my $capture-with-target := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $capture, 1, $track-target); my $capture-with-plan := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture-with-target, 1, $dispatch-plan); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi-non-trivial', $capture-with-plan); } else { # Delegate to the non-trivial dispatcher, passing along the kind # of dispatch we're doing and the plan. my $capture-with-plan := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $init, 0, $dispatch-plan); my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $capture-with-plan, 0, $track-kind); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi-non-trivial', $capture-delegate); } } else { # Mark dispatcher exhausted if it's lastcall. if $kind == nqp::const::DISP_LASTCALL { nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); } # Resume next dispatcher, if any, otherwise hand back Nil. nil-or-callwith-propagation-terminal($capture); } }); # The non-trivial multi dispatch has quite similar initial and resume steps, # and thus the majority of the work is factored out into a subroutine. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-multi-non-trivial', # Initialization of a non-trivial dispatch. Receives a dispatch resumption # kind, which is zero if we're not resuming. -> $capture { # Extract and guard on the kind (first argument). my $track-kind := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-kind); my int $kind := nqp::captureposarg_i($capture, 0); # If it's propagating callwith arguments, then we don't want to invoke # any multi candidate, but rather set up resume init args and then run # the thing propagating args to us. if $kind == nqp::const::DISP_PROPAGATE_CALLWITH { # The resume init capture should have plan, original target, args. # We have kind, plan, original target, 3 values relating to the # callwith propagation, and then the args. my $without-prop-info := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 3, 3); my $init-args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $without-prop-info, 0); nqp::dispatch('boot-syscall', 'dispatcher-set-resume-init-args', $init-args); # Drop the plan and original target to get the callwith envelope, # and then propagate further or invoke. my $callwith-prop := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 1, 2); nil-or-callwith-propagation-terminal($callwith-prop); } # Otherwise, we probably want to run a candidate. else { # Extract and track the current state. my $track-cur-state := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1); my $cur-state := nqp::captureposarg($capture, 1); # Drop the leading two arguments to get the argument capture prefixed # with the original dispatch target, and one more to get the argument # capture. my $orig-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 0, 2); my $arg-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $orig-capture, 0); # Perform the step. raku-multi-non-trivial-step($kind, $track-cur-state, $cur-state, $orig-capture, $arg-capture, 0); } }, -> $capture { # Extract and guard on the kind (first argument). my $track-kind := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-kind); my int $kind := nqp::captureposarg_i($capture, 0); # Obtain and track state. my $track-state := nqp::dispatch('boot-syscall', 'dispatcher-track-resume-state'); my $state := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-state'); # If it's a lastcall, we'll poke an Exhausted into the state, # propagate it, and produce Nil. if $kind == nqp::const::DISP_LASTCALL { nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); if !nqp::dispatch('boot-syscall', 'dispatcher-next-resumption') { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, Nil)); } } # If we're already exhausted, try for the next dispatcher. elsif nqp::istype($state, Exhausted) { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-state); nil-or-callwith-propagation-terminal($capture); } # If it's a callwith, then we want to re-enter the non-trivial # multi dispatcher with the current position in the dispatch # and the new args. elsif $kind == nqp::const::DISP_CALLWITH { my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); my $init := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-init-args'); my $target := nqp::captureposarg($init, 1); if nqp::istype($target, Method) { my $track-invocant := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 2); $args := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $args, 0, $track-invocant); } my $track-cur-state; if nqp::isnull($state) { nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-state); $track-cur-state := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 0); } else { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-state); $track-cur-state := $track-state; } nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); my $track-target := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 1); my $with-target := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $args, 0, $track-target); my $capture-with-plan := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $with-target, 0, $track-cur-state); my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $capture-with-plan, 0, nqp::const::DISP_CALLWITH); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi-non-trivial', $capture-delegate); } # Otherwise, it's a "normal" step through the candidate list. else { # Drop the leading argument to get the argument capture prefixed # with the original target, one more to get the arguments. my $init := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-init-args'); my $orig-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $init, 0); my $arg-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $orig-capture, 0); # Have dispatch state already, or first resume? if nqp::isnull($state) { # First resumption. Guard that it is so. nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-state); # Obtain plan and args from init state. my $track-cur-state := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 0); my $cur-state := nqp::captureposarg($init, 0); raku-multi-non-trivial-step($kind, $track-cur-state, $cur-state, $orig-capture, $arg-capture, 1); } else { raku-multi-non-trivial-step($kind, $track-state, $state, $orig-capture, $arg-capture, 1); } } }); sub raku-multi-non-trivial-step(int $kind, $track-cur-state, $cur-state, $orig-capture, $arg-capture, $is-resume) { if nqp::istype($cur-state, MultiDispatchCall) { # Guard on the current state and on the callee (the type guards are # implicitly established when we guard the callee). my $track-candidate := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-cur-state, MultiDispatchCall, '$!candidate'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-candidate); # If it's a bind failure or success, the we were doing nextcallee # on a dispatch needing a bind check, and want to hand back the # candidate or keep walking. if $kind == nqp::const::DISP_BIND_SUCCESS { # Successful. Peel off the candidate and hand it back. peel-off-candidate($is-resume, $track-cur-state, $cur-state, $orig-capture); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $arg-capture, 0, $track-candidate)); return; } elsif $kind == nqp::const::DISP_BIND_FAILURE { # Unsuccessful. Skip over the candidate we already tried, and then # try again. $track-cur-state := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-cur-state, MultiDispatchCall, '$!next'); $cur-state := $cur-state.next; return raku-multi-non-trivial-step(nqp::const::DISP_NEXTCALLEE, $track-cur-state, $cur-state, $orig-capture, $arg-capture, $is-resume); } # If it needs a bind check, then... my int $peel-off-candidate := 1; my int $try := nqp::istype($cur-state, MultiDispatchTry); if $try { # If it's nextcallee, we need to resume either on success or failure, # and hand back the candidate. This is the only case where we want to # not peel off a candidate now. if $kind == nqp::const::DISP_NEXTCALLEE { my int $failure := nqp::const::DISP_BIND_FAILURE; my int $success := nqp::const::DISP_BIND_SUCCESS; nqp::dispatch('boot-syscall', 'dispatcher-resume-after-bind', $failure, $success); $peel-off-candidate := 0; } # Otherwise, we just want to call it and resume on bind failure. else { nqp::dispatch('boot-syscall', 'dispatcher-resume-on-bind-failure', $kind); } } # Peel off one candidate and use that as the next state, unless we # aren't meant to. if $peel-off-candidate { peel-off-candidate($is-resume, $track-cur-state, $cur-state, $orig-capture); } # Set up the call. If we are doing a callwith then we need to propagate # the args also, otherwise we just invoke it right off. my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $arg-capture, 0, $track-candidate); my $candidate := $cur-state.candidate; my str $disp := $try || $kind != nqp::const::DISP_NEXTCALLEE ?? (nqp::can($candidate, 'WRAPPERS') ?? 'raku-invoke-wrapped' !! 'raku-invoke') !! 'boot-value'; if $kind == nqp::const::DISP_CALLWITH { my $with-inv-flag := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $capture-delegate, 0, 1); my $with-disp-name := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $with-inv-flag, 0, $disp); my $with-propagate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $with-disp-name, 0, nqp::const::DISP_PROPAGATE_CALLWITH); nil-or-callwith-propagation-terminal($with-propagate); } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', $disp, $capture-delegate); } } elsif nqp::istype($cur-state, MultiDispatchEnd) || nqp::istype($cur-state, Exhausted) { # If this is the initial dispatch, then error, otherwise try the next # resumption (possibly method dispatch), and finally give up. if $kind == nqp::const::DISP_NONE { my $target := nqp::captureposarg($orig-capture, 0); multi-no-match-handler($target, $arg-capture, $orig-capture, $arg-capture); } else { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-cur-state); unless nqp::dispatch('boot-syscall', 'dispatcher-next-resumption') { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $arg-capture, 0, Nil)); } } } elsif nqp::istype($cur-state, MultiDispatchAmbiguous) { # If this is the initial dispatch, then error. if $kind == nqp::const::DISP_NONE { my $target := nqp::captureposarg($orig-capture, 0); multi-ambiguous-handler($cur-state, $target, $arg-capture); } # Otherwise, step past it and do whatever comes next. else { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-cur-state); $track-cur-state := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-cur-state, MultiDispatchAmbiguous, '$!next'); $cur-state := $cur-state.next; return raku-multi-non-trivial-step($kind, $track-cur-state, $cur-state, $orig-capture, $arg-capture, $is-resume); } } else { nqp::die('Unexpected multi dispatch step ' ~ $cur-state.HOW.name($cur-state)); } } sub peel-off-candidate($is-resume, $track-cur-state, $cur-state, $orig-capture) { if $is-resume { my $track-next := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-cur-state, MultiDispatchCall, '$!next'); nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state', $track-next); } else { my $next := $cur-state.next; my $init-state := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $orig-capture, 0, $next); nqp::dispatch('boot-syscall', 'dispatcher-set-resume-init-args', $init-state); } } # Proxy removal for multiple dispatch. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-multi-remove-proxies', # The dispatch receives (remover, original invokee, args...). -> $capture { # The resume init state drops the remover. nqp::dispatch('boot-syscall', 'dispatcher-set-resume-init-args', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0)); # We then invoke the remover with the arguments (so need to drop the # original invokee). nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 1)); }, # The resumption is done with the args with proxies stripped. -> $capture { # Make sure this really is the resume with the proxies stripped, # not some inner resume, which we should just pass along. my $track_kind := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_kind); my int $kind := nqp::captureposarg_i($capture, 0); if $kind == nqp::const::DISP_DECONT { # Yes, it's the resume we're looking for. Locate the candidates by # using the resume init args. my $orig-capture := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-init-args'); my $target := nqp::captureposarg($orig-capture, 0); my @candidates := nqp::getattr($target, Routine, '@!dispatch_order'); # Put a guard on the dispatchees. (TODO This risks the callsite in # the generated removers becoming a polymorphic blow-up point; when # we can associate it with the dispatch program of the initial # dispatch, that will be rather better.) my $track_callee := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $orig-capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track_callee, Routine, '@!dispatchees')); # We now make the dispatch plan using the arguments with proxies # removed, put pass along the original arg capture too, for use # in `rw`-ness testing. my $no-proxy-arg-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); my $orig-arg-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $orig-capture, 0); my $dispatch-plan := raku-multi-plan(@candidates, $no-proxy-arg-capture, 0, $orig-arg-capture); # Consider the dispatch plan. Note we should always pass along the original # arguments when invoking, so anything `is rw` gets the Proxy. We for now # also send everything through the non-trivial dispatch path to keep it # a little simpler. if nqp::istype($dispatch-plan, MultiDispatchNonScalar) { nqp::die('FETCH from a Proxy unexpectedly returned another Proxy'); } elsif nqp::istype($dispatch-plan, MultiDispatchAmbiguous) && nqp::istype($dispatch-plan.next, MultiDispatchCall) { multi-ambiguous-handler($dispatch-plan, $target, $orig-arg-capture); } elsif nqp::istype($dispatch-plan, MultiDispatchEnd) { multi-no-match-handler($target, $no-proxy-arg-capture, $orig-capture, $orig-arg-capture); } else { my $capture-with-plan := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $orig-capture, 0, $dispatch-plan); my $capture-delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $capture-with-plan, 0, 0); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-multi-non-trivial', $capture-delegate); } } elsif !nqp::dispatch('boot-syscall', 'dispatcher-next-resumption') { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, Nil)); } }); # This is where invocation bottoms out, however we reach it. By this point, we # just have something to invoke, which is either a code object (potentially with # wrappers) or something that hopefully has a CALL-ME. my $late-coerce := -> $target, $val { my $how := $target.HOW; my $coercion-type := Perl6::Metamodel::CoercionHOW.new_type( (nqp::istype($how, Perl6::Metamodel::ClassHOW) && $how.is_pun($target) ?? $target.HOW.pun_source($target) !! $target.WHAT), $val.WHAT); nqp::dispatch('raku-coercion', $coercion-type, $val); } my $listy-coercion := -> $coercion-type, *@args { my $list := nqp::create(List); nqp::bindattr($list, List, '$!reified', @args); nqp::dispatch('raku-coercion', $coercion-type, $list); } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-invoke', -> $capture { # Guard type and concreteness of code object, unless it is a literal one # (and also determine if it's a literal, as we can avoid some things in # that case). my $code := nqp::captureposarg($capture, 0); my int $code-constant := nqp::dispatch('boot-syscall', 'dispatcher-is-arg-literal', $capture, 0); my $code_arg := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); unless $code-constant { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $code_arg); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $code_arg); } # If it's already a VM-level code reference, just invoke it. if nqp::reprname($code) eq 'MVMCode' { nqp::dispatch('boot-syscall', 'dispatcher-delegate', $code-constant ?? 'boot-code-constant' !! 'boot-code', $capture); } elsif nqp::isconcrete( my $custom-dispatcher := nqp::decont(nqp::how_nd($code).find_method(nqp::decont($code), 'CUSTOM-DISPATCHER', :no_fallback)) ) { nqp::dispatch('boot-syscall', 'dispatcher-delegate', nqp::unbox_s($custom-dispatcher($code)), $capture); } # If it has a CALL-ME method then always use that (this means it being a # Code object, even). elsif nqp::isconcrete(my $call-me := nqp::decont(nqp::how_nd($code).find_method($code, 'CALL-ME', :no_fallback))) { # A CALL-ME method is found; make a call to it. We use raku-call-simple # to avoid setting up any further deferrals, which may get us into the # situation where we set up multiple resumptions. my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $call-me); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-call-simple', $delegate); } # If it's a code object... elsif nqp::istype($code, Code) { # Concrete code object: extract the $!do, replace the code object, # and delegate to boot-code. if nqp::isconcrete($code) { my $do := nqp::getattr($code, Code, '$!do'); if $code-constant && !nqp::dispatch('boot-syscall', 'code-is-stub', $do) { my $args := pass-decontainerized($code, nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0)); my $delegate_capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $args, 0, $do); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', $delegate_capture); } else { my $do_attr := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $code_arg, Code, '$!do'); my $delegate_capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $do_attr); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code', $delegate_capture); } } # Invoking non-concrete code object is an error. else { nqp::die('Cannot invoke a ' ~ $code.HOW.name($code) ~ ' type object'); } } # If it's ForeignCode, extract the wrapped code object and delegate to # lang-code to run whatever is wrapped there. elsif nqp::istype($code, ForeignCode) { if nqp::isconcrete($code) { my $do_attr := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $code_arg, ForeignCode, '$!do'); my $delegate_capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $do_attr); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'lang-call', $delegate_capture); } else { nqp::die('Cannot invoke a ' ~ $code.HOW.name($code) ~ ' type object'); } } # If it's NQP code (ideally we want a more flexible cross-language solution # here) then unrap it also. elsif nqp::istype($code, NQPRoutine) { if nqp::isconcrete($code) { if $code-constant { my $do := nqp::getattr($code, NQPRoutine, '$!do'); my $delegate_capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $do); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', $delegate_capture); } else { my $do_attr := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $code_arg, NQPRoutine, '$!do'); my $delegate_capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $do_attr); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code', $delegate_capture); } } else { nqp::die('Cannot invoke a ' ~ nqp::how_nd($code).name($code) ~ ' type object'); } } # Otherwise, try the coercion path. elsif !nqp::isconcrete($code) && nqp::captureposelems($capture) >= 2 { # Looks like a coercion. In the best case we just have one argument # and things will be straightforward. Failing that, we'll have to # form a list and take the slow-bound path. if nqp::captureposelems($capture) == 2 { # Work out what we have to coerce. my $arg-type; my int $could-not-guard; my int $prim := nqp::captureposprimspec($capture, 1); if $prim == 1 { $arg-type := Int } elsif $prim == 2 { $arg-type := Num } elsif $prim == 3 { $arg-type := Str } else { # Object argument, so type guard. my $arg := nqp::captureposarg($capture, 1); $arg-type := $arg.WHAT; my $track-arg := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-arg); if nqp::isconcrete_nd($arg) && nqp::iscont($arg) { # Containerized. If it's a Scalar, we can deref and guard # on that. If not, we'll have to thunk it and figure it # out each time. if nqp::istype_nd($arg, Scalar) { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-arg, Scalar, '$!value')); } else { $could-not-guard := 1; } } } # Ensure there's no nameds. if nqp::capturehasnameds($capture) { Perl6::Metamodel::Configuration.throw_or_die( 'X::Coerce::Impossible', "Cannot coerce to " ~ nqp::how_nd($code).name($code) ~ " with named arguments", :target-type($code.WHAT), :from-type($arg-type), :hint("named arguments passed") ); } # If we could not guard need to delegate to a late-bound # handler. if $could-not-guard { my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $late-coerce); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', $delegate); } # Otherwise, can rewrite the callsite directly to do the # coercion. else { # Form the coercion type. my $how := nqp::how_nd($code); my $coercion-type := Perl6::Metamodel::CoercionHOW.new_type( (nqp::istype($how, Perl6::Metamodel::ClassHOW) && $how.is_pun($code) ?? $how.pun_source($code) !! $code.WHAT), $arg-type); # Call $coercion-type.HOW.coerce($coercion-type, $val). We # know that there was only one item, so we can drop the # callee, prepend the coercion type, the HOW, and then the # name and type as raku-meth-call wants. my $coercee-only := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); my $with-coercion-type := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $coercee-only, 0, $coercion-type); my $coerce-how := nqp::how_nd($coercion-type); my $with-how := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $with-coercion-type, 0, $coerce-how); my $with-name := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $with-how, 0, 'coerce'); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $with-name, 0, $coerce-how); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', $delegate); } } else { # List formation is too complex for a dispatch program, so we # form a coercion type, prepend it, do the args that form the # list to be coerced, and then delegate to a code object to # do the rest of the work. if nqp::capturehasnameds($capture) { Perl6::Metamodel::Configuration.throw_or_die( 'X::Coerce::Impossible', "Cannot coerce to " ~ nqp::how_nd($code).name($code) ~ " with named arguments", :target-type($code.WHAT), :from-type(List), :hint("named arguments passed") ); } my $how := nqp::how_nd($code); my $coercion-type := Perl6::Metamodel::CoercionHOW.new_type( (nqp::istype($how, Perl6::Metamodel::ClassHOW) && $how.is_pun($code) ?? $how.pun_source($code) !! $code.WHAT), List); my $list-elems-only := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); my $with-coercion-type := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $list-elems-only, 0, $coercion-type); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $with-coercion-type, 0, $listy-coercion); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', $delegate); } } # We can't invoke it; complain. else { my $how := nqp::how_nd($code); my $class := nqp::getlexcaller('$?CLASS'); report-method-not-found($code, 'CALL-ME', $class, $how, nqp::iscont($code)); } }); # When we see that the callee expects readonly arguments, and what we are # going to pass is a Scalar container, we can unwrap them on the caller # side. This has a number of advantages: # * Since in a multiple dispatch we have to decontainerize in order to guard # on the values, this dispatch program will often already have the # values in temporaries. Thus we would be doing the work anyway, and don't # need to leave it to the callee. # * The specializer may do specialization linking and inlining, and may stack # up extra guards, which include reading from containers. This would duplicate # work in the dispatch program. However, if invocation at the end of the # dispatch program is just on values, it can avoid that. # * Since most calls to an operator like infix:<+> will now be two values, not # all permutations of scalar with value and value, we may produce less # specializations. Further, value + value case has by far the simplest code # to inline (and typically avoids further guards and container reads). # * Even in the case we can't inline, removing the value from the container # caller side rather than callee side means that the container doesn't # escape, which - especially as PEA in MoarVM gets more powerful - means it # will be able to do a great deal more scalar replacements. sub pass-decontainerized($code, $args) { my $signature := nqp::getattr($code, Code, '$!signature'); my int $readonly := nqp::getattr_i($signature, Signature, '$!readonly'); my int $pos-args := nqp::captureposelems($args); my int $i := 0; while $i < $pos-args { # If it should be passed read only, and it's an object... if $readonly +& nqp::bitshiftl_i(1, $i) && nqp::captureposprimspec($args, $i) == 0 { # If it's in a Scalar container... my $arg := nqp::captureposarg($args, $i); if nqp::isconcrete_nd($arg) && nqp::what_nd($arg) =:= Scalar { # Read it from the container and pass it decontainerized. my $track-arg := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $args, $i); my $track-value := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-arg, Scalar, '$!value'); $args := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $args, $i), $i, $track-value); } } $i++; } $args } # Entrypoint for dispatch to a wrapped routine. Builds the chain and delegates # to another dispatcher that will handle the walking through it via resumption. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-invoke-wrapped', -> $capture { # Guard on the current set of wrappers (the array of them is immutable, # so we can rely on its identity). my $routine := nqp::captureposarg($capture, 0); my $wrapper-type := $routine.WRAPPER-TYPE; my $track-routine := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); my $track-wrappers := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-routine, $wrapper-type, '$!wrappers'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-wrappers); # With wrappers, we pretty much know we'll be traversing them, so we # build the deferral chain up front, unlike in other dispatchers. my @all-callees := nqp::clone($routine.WRAPPERS); my $chain := Exhausted; while nqp::elems(@all-callees) { $chain := DeferralChain.new(nqp::pop(@all-callees), $chain); } # Delegate to the wrap deferral dispatcher with the arguments to call # the initial wrapper with, preceded by the calculated chain. my $without-routine := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); my $with-chain := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $without-routine, 0, $chain); my $with-kind := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $with-chain, 0, nqp::const::DISP_NONE); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-wrapper-deferral', $with-kind); }); # The wrapper deferral dispatcher that moves through wrappers. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-wrapper-deferral', # Initial dispatch, called with the chain to walk through along with the # arguments. This is used either in the case we are just starting to walk # through the dispatchers or in the event of a callwith. -> $capture { # Obtain and guard on the first wrapper callee. my $cur_deferral := nqp::captureposarg($capture, 1); my $track_cur_deferral := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1); my $track_code := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track_cur_deferral, DeferralChain, '$!code'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_code); # Extract the arguments and set the resume init args to be the next item # in the chain prepended to the arguments, so long as there is a next # wrapper. my $next := $cur_deferral.next; my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-n-args', $capture, 0, 2); if nqp::isconcrete($next) { nqp::dispatch('boot-syscall', 'dispatcher-set-resume-init-args', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $args, 0, $next)); } # Either invoke the wrapper directly, or via callwith propagation. my $code := $cur_deferral.code; my $code-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $args, 0, $code); my int $callwith := nqp::captureposarg_i($capture, 0) == nqp::const::DISP_PROPAGATE_CALLWITH; if $callwith { my $with-inv-flag := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $code-capture, 0, 1); my $with-disp := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $with-inv-flag, 0, 'raku-call-simple'); my $with-kind := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $with-disp, 0, nqp::const::DISP_PROPAGATE_CALLWITH); unless nqp::dispatch('boot-syscall', 'dispatcher-next-resumption', $with-kind) { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-call-simple', $code-capture); } } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-call-simple', $code-capture); } }, # Resumption. -> $capture { # Guard on the kind of resume we're doing, and get that flag. my $track_kind := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_kind); my int $kind := nqp::captureposarg_i($capture, 0); # Work out which wrapper we'll call next. my $init := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-init-args'); my $state := nqp::dispatch('boot-syscall', 'dispatcher-get-resume-state'); my $track_cur_deferral; my $cur_deferral; if $kind == nqp::const::DISP_LASTCALL { # It's lastcall; just update the state to Exhausted. nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); } elsif $kind == nqp::const::DISP_ONLYSTAR { nqp::dispatch('boot-syscall', 'dispatcher-next-resumption') || nqp::die('Failed to dispatch to candidate from wrapped proto') } elsif nqp::isnull($state) { # No state, so the initial resumption. Guard on there being no # dispatch state. my $track_state := nqp::dispatch('boot-syscall', 'dispatcher-track-resume-state'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_state); # The current deferral is obtained from the initialization state. $track_cur_deferral := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $init, 0); $cur_deferral := nqp::captureposarg($init, 0); } elsif !nqp::istype($state, Exhausted) { # Already working through a chain of wrappers deferrals. Thus the # current deferral is the current state; $track_cur_deferral := nqp::dispatch('boot-syscall', 'dispatcher-track-resume-state'); $cur_deferral := $state; } else { # Dispatch already exhausted; guard on that and fall through to returning # Nil. my $track_state := nqp::dispatch('boot-syscall', 'dispatcher-track-resume-state'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_state); } # If we have a current deferral... if $cur_deferral { if $kind == nqp::const::DISP_CALLWITH { # Mark this dispatcher exhausted since we're moving on from it, # and then re-enter the dispatcher with the remaining wrappers # and the args given to us. We guard on the next candidate and # insert it as a literal, since we may not depend on resume # init state if using next resumption with args. nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state-literal', Exhausted); my $args := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0); my $with-chain := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $args, 0, $cur_deferral); my $with-kind := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $with-chain, 0, nqp::const::DISP_PROPAGATE_CALLWITH); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-wrapper-deferral', $with-kind); } else { # Not callwith, so we keep walking the list. Update state to # move to the next wrapper in the list and then put into effect # the resumption. my $track_code := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track_cur_deferral, DeferralChain, '$!code'); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track_code); my $track_next := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track_cur_deferral, DeferralChain, '$!next'); nqp::dispatch('boot-syscall', 'dispatcher-set-resume-state', $track_next); if $kind == nqp::const::DISP_CALLSAME { # Invoke the next bit of code. We send the original dispatchee to # boot-code, since it's an unwrapped code handle; the rest, we # treat as Raku calls, since it's possible somebody decided to wrap # some code up with a multi. my $code := $cur_deferral.code; my $delegate_capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $init, 0), 0, $code); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-call-simple', $delegate_capture); } elsif $kind == nqp::const::DISP_NEXTCALLEE { # We just want the code itself, not to invoke it. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $cur_deferral.code)); } else { nqp::die('Unimplemented resumption kind in wrap dispatch'); } } } else { # This dispatcher is exhausted. However, there may be another one # we can try (for example, in a wrapped method). nil-or-callwith-propagation-terminal($capture); } }); # Like raku-call, except assumes that any method call we see will already have # been taken care of. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-call-simple', -> $capture { my $track_callee := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track_callee); my $callee := nqp::captureposarg($capture, 0); if nqp::istype_nd($callee, Routine) { nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track_callee, Routine, '@!dispatchees')); nqp::dispatch('boot-syscall', 'dispatcher-delegate', $callee.is_dispatcher ?? 'raku-multi' !! 'raku-invoke', $capture); } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-invoke', $capture); } }); # Dispatcher to try to find a method, backing nqp::findmethod, nqp::tryfindmethod, # and nqp::can. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-find-meth', -> $capture { # See if this callsite is going megamorphic and do a fallback if so. We only do # this in the non-exceptional case. my $obj := nqp::captureposarg($capture, 0); my $how := nqp::how_nd($obj); my int $cache-size := nqp::dispatch('boot-syscall', 'dispatcher-inline-cache-size'); my int $exceptional := nqp::captureposarg_i($capture, 2); if $cache-size >= $MEGA-METH-CALLSITE-SIZE && !$exceptional && nqp::istype($how, Perl6::Metamodel::ClassHOW) { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-find-meth-mega', $capture); } else { # Guard on the invocant type and method name. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0)); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1)); # Try to find the method. my str $name := nqp::captureposarg_s($capture, 1); my $meth := $how.find_method($obj, $name); # If it's found, evaluate to it. if nqp::isconcrete($meth) { my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $meth); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', $delegate); } # Otherwise, depends on exceptional flag whether we report the missing # method or hand back a null. else { nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 2)); if $exceptional { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'lang-meth-not-found', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0)); } else { my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, nqp::null()); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', $delegate); } } } }); nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-find-meth-mega', -> $capture { # Always guard on the exception mode (which should always be false, since we # don't handle it here). nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 2)); # Make sure that we have a method table build for this type (but we don't # actually need the table itself). my $obj := nqp::captureposarg($capture, 0); my $how := nqp::how_nd($obj); unless nqp::isconcrete(nqp::getattr($how, Perl6::Metamodel::ClassHOW, '$!cached_all_method_table')) { nqp::dispatch('boot-syscall', 'dispatcher-do-not-install'); } $how.all_method_table($obj); # Track the HOW and then the attribute holding the table. my $track-obj := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); my $track-how := nqp::dispatch('boot-syscall', 'dispatcher-track-how', $track-obj); my $track-table := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-how, Perl6::Metamodel::ClassHOW, '$!cached_all_method_table'); # Do the lookup of the method in the table we found in the meta-object. If # it's not found, the outcome will be a null, which is exactly what we want. my $track-name := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1); my $track-resolution := nqp::dispatch('boot-syscall', 'dispatcher-index-tracked-lookup-table', $track-table, $track-name); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $capture, 0, $track-resolution); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $delegate); }); # The dispatcher backing p6capturelex. If we are passed a code object, then # extracts the underlying handle and causes it to be captured. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-capture-lex', -> $capture { my $code := nqp::captureposarg($capture, 0); my $track-code := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-code); if nqp::istype($code, Code) { my $do := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-code, Code, '$!do'); my $with-do := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $do); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $with-do, 0, 'try-capture-lex'); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-syscall', $delegate); } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } }); # The dispatcher backing p6capturelexwhere. If we are passed a code object, then # extracts the underlying handle and looks down the callstack for a caller that # matches the outer, and captures it. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-capture-lex-callers', -> $capture { my $code := nqp::captureposarg($capture, 0); my $track-code := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-code); if nqp::istype($code, Code) { my $do := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-code, Code, '$!do'); my $with-do := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $do); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $with-do, 0, 'try-capture-lex-callers'); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-syscall', $delegate); } else { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } }); # The dispatcher backing p6getouterctx. Unwraps the code object, and then # gets a context object for its enclosing scope. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-get-code-outer-ctx', -> $capture { my $code := nqp::captureposarg($capture, 0); if nqp::istype($code, Code) { my $track-code := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); my $do := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-code, Code, '$!do'); my $with-do := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $do); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $with-do, 0, 'get-code-outer-ctx'); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-syscall', $delegate); } else { nqp::die('raku-get-code-outer-ctx requires a Code object'); } }); # Resumption error reporting dispatcher. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-resume-error', -> $capture { my str $redispatcher := nqp::getcodename(nqp::callercode()); Perl6::Metamodel::Configuration.throw_or_die( 'X::NoDispatcher', "$redispatcher is not in the dynamic scope of a dispatcher", :$redispatcher ); }); # Invokability test dispatcher. nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-isinvokable', -> $capture { # Guard on the type, then evaluate to a constant for if it's a Code type. nqp::dispatch('boot-syscall', 'dispatcher-guard-type', nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0)); my $callee := nqp::captureposarg($capture, 0); my $delegate := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-int', $capture, 0, nqp::istype($callee, Code)); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-constant', $delegate); }); # Smartmatch support { my $hllbool := nqp::getstaticcode(-> $prim { nqp::hllboolfor(nqp::istrue($prim), 'Raku') }); my $hllbool_not := nqp::getstaticcode(-> $prim { nqp::hllboolfor(nqp::not_i(nqp::istrue($prim)), 'Raku') }); sub is-routine-setting-only($routine, :$U = 0, :$D = 0) { if nqp::istype($routine, Routine) { return nqp::istrue( $routine.IS-SETTING-ONLY( U => $hllbool($U), D => $hllbool($D), with-proto => $hllbool(1))); } elsif nqp::istype($routine, Code) { return nqp::istrue($routine.file.starts-with('SETTING::')); } # Non-Raku code objects are considered coming from the setting. 1 } sub is-method-setting-only($type, str $method-name, :$U = 0, :$D = 0) { my $method := nqp::tryfindmethod($type, $method-name); return 0 unless nqp::defined($method); is-routine-setting-only($method, :$U, :$D) } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-boolify', -> $capture { my $arg-spec := nqp::captureposprimspec($capture, 0); my $arg; if $arg-spec == 1 { $arg := nqp::captureposarg_i($capture, 0); } elsif $arg-spec == 2 { $arg := nqp::captureposarg_n($capture, 0); } elsif $arg-spec == 3 { $arg := nqp::captureposarg_s($capture, 0); } else { $arg := nqp::captureposarg($capture, 0); } my $track_arg := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); my $explicit-call := 0; if nqp::isconcrete($arg) { if $arg-spec { nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track_arg); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track_arg); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $hllbool) ); } elsif nqp::istype($arg, Bool) { nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track_arg); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track_arg); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', $capture); } else { $explicit-call := 1; } } elsif is-method-setting-only($arg, 'Bool', :U) { # For non-concrete objects default method Bool candidate would always produce False. nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track_arg); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track_arg); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $hllbool(0) ) ); } else { $explicit-call := 1; } if $explicit-call { # There is no need to guard for type when fallback to method call. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, nqp::what($arg)), 1, 'Bool')); } }); my &smartmatch-code := nqp::getstaticcode(-> $topic, $rhs { nqp::dispatch('raku-boolify', $rhs.ACCEPTS($topic)) }); my &negate-smartmatch-code := nqp::getstaticcode(-> $topic, $rhs { nqp::hllizefor($rhs.ACCEPTS($topic), 'Raku').not }); my &nominalizable-sm-code := nqp::getstaticcode(-> $topic, $rhs { nqp::hllboolfor(nqp::istype($topic, $rhs), 'Raku') }); my &negate-nominalizable-sm-code := nqp::getstaticcode(-> $topic, $rhs { nqp::hllboolfor(nqp::not_i(nqp::istype($topic, $rhs)), 'Raku') }); my sub find-core-symbol(str $sym, :$ctx, :$revision) { unless nqp::isconcrete($ctx) { $ctx := nqp::ctxcaller(nqp::ctx()); } my $core-rev-sym := 'CORE-SETTING-REV'; while nqp::isnull(nqp::getlexrel($ctx, $core-rev-sym)) { $ctx := nqp::ctxcaller($ctx); } until nqp::isnull($ctx) { my $lexpad := nqp::ctxlexpad($ctx); if nqp::existskey($lexpad, $core-rev-sym) { last unless nqp::isconcrete($revision) && nqp::isne_s(nqp::atkey($lexpad, $core-rev-sym), $revision); } $ctx := nqp::ctxouterskipthunks($ctx); } nqp::die("No symbol '" ~ $sym ~ "' found in CORE" ~ ($revision ?? "." ~ $revision !! "")) if nqp::isnull($ctx); nqp::getlexrel($ctx, $sym) } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-smartmatch', -> $capture { # The dispatch receives: # - lhs with containerization preserved # - rhs with containerization preserved # - boolification flag # boolification flag can either be -1 to negate, 0 to return as-is, 1 to boolify # Note that boolification flag is not guarded because it is expected to be invariant over call site. my $Match := find-core-symbol('Match', :ctx(nqp::ctxcaller(nqp::ctx()))); my $lhs := nqp::captureposarg($capture, 0); my $rhs := nqp::captureposarg($capture, 1); my $boolification := nqp::captureposarg_i($capture, 2); my $track-lhs := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); my $track-rhs := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1); if nqp::istype_nd($lhs, Scalar) { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-lhs ); $track-lhs := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-lhs, Scalar, '$!value'); $lhs := nqp::getattr($lhs, Scalar, '$!value'); } if nqp::istype_nd($rhs, Scalar) { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs ); $track-rhs := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-rhs, Scalar, '$!value'); $rhs := nqp::getattr($rhs, Scalar, '$!value'); } my $explicit-accepts := 1; if $boolification == 0 { if nqp::isconcrete_nd($rhs) && nqp::istype_nd($rhs, Junction) { # Make sure to collapse a Junction. # nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-boolification); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2), # boolification flag 0), # LHS 0, nqp::what($rhs)), 1, 'Bool')); $explicit-accepts := 0; } elsif nqp::isconcrete_nd($rhs) && nqp::istype_nd($rhs, List) { # A list must be reified in order to fire up any code embedded into regexes. # nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-boolification); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2), # boolification flag 0), # LHS 0, nqp::what($rhs)), 1, 'eager')); $explicit-accepts := 0; } elsif nqp::istype_nd($rhs, Nil) { # nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-boolification); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, nqp::hllboolfor(0, 'Raku'))); $explicit-accepts := 0; } else { # nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-boolification); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); # Bypass is normally used with Regex-kind of RHS and it is not specced wether the smartmatch result must # be deconted in this case. Therefore we better return what we've got on RHS as-is. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0)); $explicit-accepts := 0; } } # Delegate to Junction.BOOLIFY-ACCEPTS if possible and makes sense. # - Junction type object on RHS is always a type match and we can pass it to the typematching branch # - when boolifying over a concrete Regex ACCEPTS fallback is required too # - BOOLIFY-ACCEPTS only makes sense when ACCEPTS doesn't handle junctions in a special way. For now this can # only be guaranteed for CORE's ACCEPTS only. elsif nqp::istype_nd($lhs, Junction) && nqp::isconcrete_nd($lhs) && (nqp::isconcrete_nd($rhs) || !nqp::istype($rhs, Junction)) && !(nqp::isconcrete_nd($rhs) && $boolification == 1 && nqp::istype_nd($rhs, Regex)) && is-method-setting-only($rhs, 'ACCEPTS', :D) { # nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-boolification); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-lhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-lhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-rhs); my $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2); $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $method-capture, 2, nqp::hllboolfor($boolification == -1, 'Raku')); # boolification -> Raku's Bool negation flag $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $method-capture, 0, nqp::what($lhs)); $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $method-capture, 1, 'BOOLIFY-ACCEPTS'); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', $method-capture); $explicit-accepts := 0; } else { if nqp::isconcrete_nd($rhs) { if $boolification < 0 { if nqp::istype_nd($rhs, Bool) { # nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-boolification); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $hllbool_not($rhs))); $explicit-accepts := 0; } elsif nqp::istype_nd($rhs, $Match) { # nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-boolification); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2), # boolification flag 0), # LHS 0, nqp::what($rhs)), 1, 'not')); $explicit-accepts := 0; } } elsif nqp::istype_nd($rhs, Bool) || nqp::istype_nd($rhs, $Match) { # nqp::dispatch('boot-syscall', 'dispatcher-guard-literal', $track-boolification); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0)); # drop LHS $explicit-accepts := 0; } } elsif is-method-setting-only($rhs, 'ACCEPTS', :U) { # Non-concrete RHS # A typeobject on RHS with default ACCEPTS can be reduced to nqp::istype, unless LHS is a concrete Junction. nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); my $rhs-how := $rhs.HOW; my $can-archetypes := nqp::can($rhs-how, 'archetypes'); if !$can-archetypes || !$rhs-how.archetypes($rhs).nominalizable || nqp::isnull($rhs-how.wrappee-lookup($rhs, :subset)) { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-lhs); if $can-archetypes && $rhs-how.archetypes($rhs).definite { # If RHS is a definite then concreteness of LHS must be considered. nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-lhs); } my $matches := try nqp::istype_nd($lhs, $rhs); $matches := $boolification < 0 ?? $hllbool_not($matches) !! $hllbool($matches); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $matches)); } else { # Subsets are usually using topic value to ensure matching. Normally it would mean full ACCEPTS+Bool # fallback, but we can shortcut directly to HOW.accepts_type and then boolify. # Note that LHS is not relevant for dispatching in this case. my $sm-code := $boolification < 0 ?? &negate-nominalizable-sm-code !! &nominalizable-sm-code; nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2), # boolification flag 0, $sm-code)); } $explicit-accepts := 0; } } if $explicit-accepts { nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-rhs); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-rhs); if $boolification == 0 || (nqp::isconcrete_nd($rhs) && $boolification > -1 && nqp::istype_nd($rhs, Regex)) { # Do not boolify over a Regex RHS. # First, drop everything except for LHS. my $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2); # boolification flag $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg', $method-capture, 0, nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1)); # Move RHS to the start $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $method-capture, 2); # Old RHS # Then prepare for raku-meth-call: deconted RHS, method name, RHS, LHS. $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $method-capture, 0, nqp::what($rhs)); $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', $method-capture, 1, 'ACCEPTS'); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', $method-capture); } else { my $sm-code := $boolification < 0 ?? &negate-smartmatch-code !! &smartmatch-code; nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2), # boolify flag 0, $sm-code)); } } }); } # Coercion protocol { # Coerce by target method name. I.e. $value.TargetType. my $coerce-by-type-method := nqp::getstaticcode(-> $coercion, $value, $method, $nominal_target, $target_type { nqp::istype((my $coerced_value := $method($value)), $target_type) || nqp::istype($coerced_value, nqp::gethllsym('Raku', 'Failure')) ?? $coerced_value !! nqp::how($coercion)."!invalid_coercion"( $value, nqp::how_nd($nominal_target).name($nominal_target), $coerced_value) }); # Indirect methods are `COERCE` or `new` on the target type. my $coerce-indirect-method := nqp::getstaticcode(-> $coercion, $value, $method, $nominal_target, $target_type { my $*COERCION-TYPE := $coercion; nqp::istype((my $coerced_value := $method($nominal_target, $value)), $target_type) || nqp::istype($coerced_value, nqp::gethllsym('Raku', 'Failure')) ?? $coerced_value !! nqp::how($coercion)."!invalid_coercion"($value, $method.name, $coerced_value) }); # The special case of `new` when we suspect it may throw X::Constructor::Positional which we interpret as "no # coercion method found". my $coerce-new := nqp::getstaticcode(-> $coercion, $value, $method, $nominal_target, $target_type { my $exception; my $coerced_value := nqp::null(); try { CATCH { my $exception_obj := nqp::getpayload($!); if $exception_obj.HOW.name($exception_obj) ne 'X::Constructor::Positional' { $exception := $!; } } my $*COERCION-TYPE := $coercion; $coerced_value := $method($nominal_target, $value); } nqp::if(nqp::defined($exception), nqp::rethrow($exception)); nqp::isnull($coerced_value) ?? nqp::how($coercion)."!invalid"($value, "no acceptable coercion method found") !! nqp::istype($coerced_value, $target_type) || nqp::istype($coerced_value, nqp::gethllsym('Raku', 'Failure')) ?? $coerced_value !! nqp::how($coercion)."!invalid_coercion"($value, 'new', $coerced_value) }); my $coerce-runtime := nqp::getstaticcode(-> $coercion, $value, *@pos { nqp::how($coercion)."!coerce_TargetType"($coercion, $value) }); my $coerce-via-container := nqp::getstaticcode(-> $coercion, $value { nqp::dispatch('raku-coercion', $coercion, nqp::decont($value)) }); sub select-coercer($coercion, $value, :$with-runtime = 0) { my $target_type := nqp::how($coercion).target_type($coercion); my $constraint_type := nqp::how($coercion).constraint_type($coercion); my $nominal_target := nqp::how($coercion).nominal_target($coercion); my $coercer := nqp::null(); my $method := nqp::null(); # Routine's method `cando` doesn't work well with a Match object passed into as the first positional. # Besides, it requires type conversions on NQP/Raku language boundary. Therefore we use a truncated local # version of it. my sub method-cando($method, *@pos) { my $disp; if $method.is_dispatcher { $disp := $method; } else { $disp := nqp::create(nqp::what($method)); nqp::bindattr($disp, Routine, '@!dispatchees', nqp::list($method)); } -> *@_ { $disp.find_best_dispatchee( nqp::usecapture(), 1) }(|@pos) } # Make sure none of the coercion method candidates uses run-time constraints. my sub method-is-optimizable($method) { # Can do no assumptions about a non-Routine. return 0 unless nqp::istype($method, Routine); my @cands := $method.is_dispatcher ?? nqp::getattr($method, Routine, '@!dispatchees') !! nqp::list($method); for @cands -> $cand { my $signature := nqp::decont($cand.signature); # Skip the candidate if it has too few positionals or requires too many of them. next if nqp::islt_n(nqp::decont($signature.count), 2) || nqp::isgt_n(nqp::decont($signature.arity), 2); my $vparam := nqp::atpos(nqp::getattr($cand.signature, Signature, '@!params'), 1); my $ptype := $vparam.type; my $ptypeHOW := nqp::how($ptype); return 0 if $ptypeHOW.archetypes($ptype).nominalizable && !nqp::isnull(my $subset := $ptypeHOW.wrappee-lookup($ptype, :subset)) && nqp::isconcrete(nqp::how($subset).refinement($subset)); # XXX Retreat on any parameter postconstraint present. Some refinement is possible here, but to be # done later. return 0 if nqp::getattr($vparam, Parameter, '@!post_constraints'); } 1 } my sub pun-nominal-target() { CATCH { Perl6::Metamodel::Configuration.throw_or_die( 'X::Coerce::Role', "Coercion from " ~ $value.HOW.name($value) ~ " into " ~ $nominal_target.HOW.name($nominal_target) ~ " died while tried to pun the target role", :target-type($target_type), :from-type(nqp::what($value)), :exception($!) ) } $nominal_target := nqp::how_nd($nominal_target).pun($nominal_target); } if $with-runtime && nqp::can((my $archetypes := nqp::how($constraint_type).archetypes($constraint_type)), 'coercive') && $archetypes.coercive { $coercer := $coerce-runtime; } elsif nqp::defined( $method := nqp::tryfindmethod( nqp::what($value), nqp::how_nd($nominal_target).name($nominal_target))) && method-cando($method, $value) { # There is .TargetType method on the value, use it. $coercer := $coerce-by-type-method; } elsif nqp::defined($method := nqp::tryfindmethod( (nqp::how_nd($nominal_target).archetypes.composable ?? pun-nominal-target() !! $nominal_target), 'COERCE')) && method-cando($method, $nominal_target, $value) { # The target type can .COERCE. if method-is-optimizable($method) { $coercer := $coerce-indirect-method } } elsif nqp::defined($method := nqp::tryfindmethod($nominal_target, 'new')) && (my @cands := method-cando($method, $nominal_target, $value)) { if method-is-optimizable($method) { # We can TargetType.new($value). if +@cands == 1 { if nqp::eqaddr(@cands[0].package, Mu) { # The only .new candidate for a single positional arg call comes from Mu. That one throws # "only named arguments" error which means no candidates are actually found. Simulate this by # resetting $method and pretend it's never been found. $method := nqp::null(); } else { $coercer := $coerce-indirect-method; } } else { $coercer := $coerce-new; } } } elsif $with-runtime && nqp::isconcrete($method) { $coercer := $coerce-runtime; } nqp::list($coercer, $method, $nominal_target) } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-coercion', -> $capture { # The dispatch receives: # - coercion type object # - value my $track-coercion := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); my $track-value := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-coercion); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-value); my $value := nqp::captureposarg($capture, 1); my $coercion := nqp::captureposarg($capture, 0); if nqp::istype_nd($value, Scalar) { $track-value := nqp::dispatch('boot-syscall', 'dispatcher-track-attr', $track-value, Scalar, '$!value'); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-value); $value := nqp::getattr($value, Scalar, '$!value'); } nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-value); my $coercionHOW := nqp::how($coercion); # If the type happens to be another nominalizable, like a subset wrapped around a coercion, then pull out the # actual coercion type we need. unless nqp::istype($coercionHOW, Perl6::Metamodel::CoercionHOW) { $coercion := $coercionHOW.wrappee($coercion, :coercion); $coercionHOW := nqp::how_nd($coercion); } my $target_type := $coercionHOW.target_type($coercion); my $constraint := $coercionHOW.constraint_type($coercion); my $constraintHOW := nqp::how($constraint); my sub runtime-fallback() { my $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $coercionHOW), 0, '!coerce_TargetType'), 0, $coercionHOW); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', $method-capture); } if nqp::iscont($value) { # If despite our efforts the value is still a container then try deconting it first and then re-dispatch. my $code-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-replace-arg-literal-obj', $capture, 1, $value), 0, $coerce-via-container); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', $code-capture); } elsif nqp::istype_nd($value, $target_type) { # Just matches, use identity. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0)); } elsif !nqp::eqaddr($constraint, Mu) && !nqp::istype_nd($value, $constraint) { # The value doesn't match constraint type, throw. my $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 0, $coercionHOW), 0, '!invalid_type'), 0, $coercionHOW); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', $method-capture); } elsif nqp::can((my $archetypes := $constraintHOW.archetypes($constraint)), 'coercive') && $archetypes.coercive { # The constraint type is a coercion on its own. This is not a dispatchable case. Fallback to the metamodel # method. runtime-fallback(); } else { # Try finding one of the coercion methods. my @cdesc := select-coercer($coercion, $value); my $coercer := @cdesc[0]; # Code object to do the coercion my $method := @cdesc[1]; my $nominal_target := @cdesc[2]; if nqp::isconcrete($coercer) { # We found an acceptable coercer, use it. my $code-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $coercer), 3, $method), 4, $nominal_target), 5, $target_type); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', $code-capture); } elsif nqp::isconcrete($method) { # We found a method but cannot reliably assume that it can be optimized. Let the run-time handle it. runtime-fallback(); } else { # There is no way we can coerce the value. my $method-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-str', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 0), 1, "no acceptable coercion method found"), 0, $coercionHOW), 0, '!invalid'), 0, $coercionHOW); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-meth-call', $method-capture); } } }); # Return value type-check dispatcher. The first value is the return value, # the second is the type that is expected, which may be a definiteness or # coercion type. sub return_error($got, $wanted) { Perl6::Metamodel::Configuration.throw_or_die( 'X::TypeCheck::Return', "Type check failed for return value; expected '" ~ $wanted.HOW.name($wanted) ~ "' but got '" ~ $got.HOW.name($got) ~ "'", :$got, :expected($wanted) ); } my $check_type_typeobj := -> $ret, $type { !nqp::isconcrete($ret) && nqp::istype($ret, $type) ?? $ret !! return_error($ret, $type) } my $check_type_concrete := -> $ret, $type { nqp::isconcrete($ret) && nqp::istype($ret, $type) ?? $ret !! return_error($ret, $type) } my $check_type := -> $ret, $type { nqp::istype($ret, $type) ?? $ret !! return_error($ret, $type) } # For @cdesc values see select-coercer sub. my $check_type_typeobj_coerce := -> $ret, $type, $coercion, @cdesc { !nqp::isconcrete($ret) && nqp::istype($ret, $type) ?? @cdesc[0]( # coercer code $coercion, $ret, @cdesc[1], # coercing method @cdesc[2], # nominal target nqp::how($coercion).target_type($coercion)) !! return_error($ret, $type) } my $check_type_concrete_coerce := -> $ret, $type, $coercion, @cdesc { nqp::isconcrete($ret) && nqp::istype($ret, $type) ?? @cdesc[0]( $coercion, $ret, @cdesc[1], @cdesc[2], nqp::how($coercion).target_type($coercion)) !! return_error($ret, $type) } my $check_type_coerce := -> $ret, $type, $coercion, @cdesc { nqp::istype($ret, $type) ?? @cdesc[0]( $coercion, $ret, @cdesc[1], @cdesc[2], nqp::how($coercion).target_type($coercion)) !! return_error($ret, $type) } nqp::dispatch('boot-syscall', 'dispatcher-register', 'raku-rv-typecheck', -> $capture { # Dispatcher arguments: # - return value # - type # - "is generic" flag # If the type is Mu or unset, then nothing is needed except identity. my $type := nqp::captureposarg($capture, 1); my $is_generic := nqp::captureposarg_i($capture, 2); # If the type has been instantiated from a generic then we'd need to track over it too. if $is_generic { my $track-ret-type := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 1); nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-ret-type); } # We will never need the $is_generic argument, but otherwise the capture is used to call checker subs where the # third argument is not anticipated. $capture := nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 2); if nqp::isnull($type) || $type =:= Mu { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 1)) } # Otherwise, need to look at the type. else { my sub runtime-only($t) { return 0 if nqp::isnull($t); nqp::isconcrete(nqp::how_nd($t).refinement($t)) || nqp::how_nd(my $refinee := nqp::how_nd($t).refinee($t)).archetypes($refinee).nominalizable && runtime-only(nqp::how_nd($refinee).wrappee-lookup($refinee, :subset)) } my $rv := nqp::captureposarg($capture, 0); my int $definite-check := -1; my $how := nqp::how_nd($type); my $coercion-type; my $constraint-type := nqp::null(); my $runtime-check := 0; # Is there a run-time constraint? if $how.archetypes($type).nominalizable { $runtime-check := runtime-only($how.wrappee-lookup($type, :subset)); unless nqp::isnull($coercion-type := $how.wrappee-lookup($type, :coercion)) { unless nqp::isnull($constraint-type := nqp::how_nd($coercion-type).constraint_type($coercion-type)) { $runtime-check := $runtime-check || (nqp::how_nd($constraint-type).archetypes($constraint-type).nominalizable && runtime-only(nqp::how_nd($constraint-type).wrappee-lookup($constraint-type, :subset))); } } if $how.archetypes($type).definite { my $dtype := $how.wrappee($type, :definite); $definite-check := nqp::how_nd($dtype).definite($dtype); } } my $track-value := nqp::dispatch('boot-syscall', 'dispatcher-track-arg', $capture, 0); if nqp::istype_nd($rv, Scalar) { nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-value); $track-value := nqp::dispatch( 'boot-syscall', 'dispatcher-track-attr', $track-value, Scalar, '$!value'); } nqp::dispatch('boot-syscall', 'dispatcher-guard-type', $track-value); nqp::dispatch('boot-syscall', 'dispatcher-guard-concreteness', $track-value) if $definite-check != -1; my $need-coercion := $how.archetypes($type).coercive && !nqp::istype($rv, nqp::how_nd($coercion-type).target_type($coercion-type)); my $is-Nil := nqp::istype($rv, Nil); if $is-Nil || !($runtime-check || $need-coercion) { # Static typecheck which would either result in identity or error. if $is-Nil || (nqp::istype($rv, $type) && ($definite-check == 0 ?? !nqp::isconcrete($rv) !! $definite-check == 1 ?? nqp::isconcrete($rv) !! 1)) { nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-value', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 1)); } else { # Not passing the definedness check. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, &return_error)); } } elsif $runtime-check && !$need-coercion { # The case of subset with run-time constraints, no coercion. my $checker := $definite-check == 0 ?? $check_type_typeobj !! $definite-check == 1 ?? $check_type_concrete !! $check_type; nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, $checker)); } elsif !$runtime-check && $need-coercion { # Coercion only. Make sure we can coerce by matching the constraint type and then dispatch directly to # the coercion dispatcher. if nqp::eqaddr($constraint-type, Mu) || nqp::istype($rv, $constraint-type) { # Coercion dispatcher uses reverse order of arguments, same as the metamodel method `coerce`. my $coercion-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-drop-arg', $capture, 1), 0, $type); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'raku-coercion', $coercion-capture); } else { # Coercion is not possible. nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 0, &return_error)); } } else { # The most expensive path: subset with constraints and coercion. # First, we re-consider defininite check because now we're going to use coercion constraint for that. $definite-check := nqp::how_nd($constraint-type).archetypes($constraint-type).definite ?? nqp::how_nd( my $dt := nqp::how_nd($constraint-type).wrappee($constraint-type, :definite) ).definite($dt) !! -1; my $checker := $definite-check == 0 ?? $check_type_typeobj_coerce !! $definite-check == 1 ?? $check_type_concrete_coerce !! $check_type_coerce; my @cdesc := select-coercer($coercion-type, $rv, :with-runtime); my $checker-capture := nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', nqp::dispatch('boot-syscall', 'dispatcher-insert-arg-literal-obj', $capture, 2, $coercion-type), 3, @cdesc), # coercer code 0, $checker); nqp::dispatch('boot-syscall', 'dispatcher-delegate', 'boot-code-constant', $checker-capture); } } }); } # vim: set ft=perl6 nomodifiable :