Goose  Artifact [322282cdf0]

Artifact 322282cdf0ac639bd7a673919dc412a78b5d8c69f7cdd572070462479893e1fa:

  • File bs/builtins/operators/comma.cpp — part of check-in [1099848ccd] at 2019-08-31 14:57:28 on branch trunk —
    • Unification: anonymous holes are substituted with their content right away, since otherwise they don't get substituted before the second pass.
    • When a tuple of types is used as a param type, it is converted to a tuple type.
    • Fix comma operator not correctly handling prepending a value to an open tuple.
    • Added tests for various tuple based features.
    (user: achavasse size: 3414)

#include "builtins/builtins.h"
#include "precedence.h"
#include "helpers.h"

using namespace empathy;
using namespace empathy::ir;
using namespace empathy::parse;

namespace empathy::builtins
{
    void SetupCommaOp( Env& e )
    {
        using LocVarOfAnyType =
           CustomPattern< LocalVar, LocalVar::PatternAny >;

        BuildParseRule( e, ","_sid,
            LeftAssInfixOp( "operator_comma"_sid, precedence::CommaOp,

                // Overload: any tuple, any tuple
                ForTypes< CustomPattern< Value, TuplePattern >, CustomPattern< Value, TuplePattern > >(
                []( auto&& lhs, auto&& rhs ) -> Value
                {
                    if( IsOpenTuple( lhs ) )
                    {
                        if( IsOpenTuple( rhs ) )
                            return ConcatenateTuples( lhs, rhs );

                        return AppendToTuple( lhs, rhs );
                    }

                    if( IsOpenTuple( rhs ) )
                        return PrependToTuple( lhs, rhs );

                    return AppendToTuple( AppendToTuple( EmptyTuple(), lhs ), rhs );
                } ),

                // Overload: any tuple, anything
                ForTypes< CustomPattern< Value, TuplePattern >, Value >(
                []( auto&& lhs, auto&& rhs ) -> Value
                {
                    if( IsOpenTuple( lhs ) )
                        return AppendToTuple( lhs, rhs );

                    return AppendToTuple( AppendToTuple( EmptyTuple(), lhs ), rhs );
                } ),

                // Overload: anything, any tuple
                ForTypes< Value, CustomPattern< Value, TuplePattern > >(
                []( auto&& lhs, auto&& rhs ) -> Value
                {
                    if( IsOpenTuple( rhs ) )
                        return PrependToTuple( lhs, rhs );

                    return AppendToTuple( AppendToTuple( EmptyTuple(), lhs ), rhs );
                } ),

                // Overload: anything, anything
                ForType< Value >(
                []( auto&& lhs, auto&& rhs ) -> Value
                {
                    return AppendToTuple( AppendToTuple( EmptyTuple(), lhs ), rhs );
                } ),

                // By default, locvars return their content during unification.
                // Since we want to keep them as is in tuples, we need specific overloads that will
                // get locvars as such.
                ForType< LocVarOfAnyType >(
                []( auto&& lhs, auto&& rhs ) -> Value
                {
                    return AppendToTuple( AppendToTuple( EmptyTuple(), lhs ), rhs );
                } ),

                ForTypes< CustomPattern< Value, TuplePattern >, LocVarOfAnyType >(
                []( auto&& lhs, auto&& rhs ) -> Value
                {
                    if( IsOpenTuple( lhs ) )
                        return AppendToTuple( lhs, rhs );

                    return AppendToTuple( AppendToTuple( EmptyTuple(), lhs ), rhs );
                } ),

                ForTypes< LocVarOfAnyType, CustomPattern< Value, TuplePattern > >(
                []( auto&& lhs, auto&& rhs ) -> Value
                {
                    if( IsOpenTuple( rhs ) )
                        return PrependToTuple( lhs, rhs );

                    return AppendToTuple( AppendToTuple( EmptyTuple(), lhs ), rhs );
                } )
            )
        );
    }
}