RaCoCo result: Red::PrepareCode

# Red::PrepareCode 94.6%

    use Red::AST;
    use Red::AST::Unary;
    use Red::AST::Infixes;
    use Red::AST::Empty;
    use Red::AST::Next;
    use Red::AST::Value;
    use CX::Red::Bool;

    #| Transform a hash into filter (Red::AST)
    sub hash-to-cond(%val) is export {
        my Red::AST $ast;
        for %val.kv -> Red::AST $cond, Bool $so {
            my Red::AST $filter = $so ?? Red::AST::So.new($cond) !! $cond.not;
            with $ast {
                $ast = Red::AST::AND.new: $ast, $filter
            } else {
                $ast = $filter
            }
        }
        $ast
    }

    #| Found a boolean while trying to find what's hapenning inside a block
    sub found-bool(@values, $try-again is rw, %bools, CX::Red::Bool $ex) is export {
        if %bools{$ex.ast}:!exists {
            $try-again = True;
            %bools{ $ex.ast }++;
            if not @values {
                @values.push: [ :{ $ex.ast => $ex.value }, Red::AST ];
            } else {
                my @new-keys = @values.map: -> $item { my %key{Red::AST} = $item.[0].clone; %key{$ex.ast} = $ex.value.succ; %key };
                for @values {
                    .[0].{$ex.ast} = $ex.value
                }
                @values.push: |@new-keys.map: -> %key { [ %key, Red::AST ] };
            }
        }
        $ex.resume
    }

    sub prepare-response($resp) is export {
        do given $resp {
            when Empty {
                Red::AST::Empty.new
            }
            when Red::AST {
                $_
            }
            default {
                ast-value $_
            }
        }
    }

    #| Tries to find what a block do
    sub what-does-it-do(&func, \type --> Hash) is export {
        my Bool $try-again = False;
        my %bools is SetHash;
        my @values;
        my %*VALS := :{};

        my $ret = func type;
        return :{ Red::AST => prepare-response $ret } unless $try-again;
        @values.head.[1] = $ret;
        my %first-key := :{ @values.head.[0].keys.head.clone => @values.head.[0].values.head.clone };
        %first-key{ %first-key.keys.head } = True;
        @values.push: [%first-key, Red::AST];

        for @values -> @data (%values, $response is rw) {
            $try-again = False;
            %*VALS := %values;
            $response = func type;
            CONTROL {
                when CX::Next {
                    $response = Red::AST::Next.new;
                }
                when CX::Red::Bool {                # Will work when we can create real custom CX
                    found-bool @values, $try-again, %bools, $_
                }
            }
        }
        CONTROL {
            when CX::Red::Bool {                # Will work when we can create real custom CX
                found-bool @values, $try-again, %bools, $_
            }
            when CX::Next {
                die
            }
        }

        my Red::AST %values{Red::AST};
        for @values {
            %values{hash-to-cond(.[0])} = prepare-response .[1]
        }
        %values
    }