PreviousUpNext

15.4.628  src/lib/compiler/front/typer-stuff/types/types.pkg

## types.pkg
## (C) 2001 Lucent Technologies, Bell Labs

# Compiled by:
#     src/lib/compiler/front/typer-stuff/typecheckdata.sublib



# Datastructures describing type declarations.
#
# In particular,
#
#     Typ
#
# provides the value type bound by the symbol table
# for that namespace -- see OVERVIEW section in
#
#     src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg


# NB: In general we avoid plurals in package names,
#     but we use the plural in this case to sidestep
#     the problem that 'type' is a reserved word.               XXX BUGGO FIXME -- except that 'type' is no longer reserved! ;-)



stipulate
    package ip  =  inverse_path;                        # inverse_path  is from   src/lib/compiler/front/typer-stuff/basics/symbol-path.pkg
    package mp  =  stamppath;                           # stamppath     is from   src/lib/compiler/front/typer-stuff/modules/stamppath.pkg
    package ph  =  picklehash;                          # picklehash    is from   src/lib/compiler/front/basics/map/picklehash.pkg
    package pl  =  property_list;                       # property_list is from   src/lib/src/property-list.pkg
    package sta =  stamp;                               # stamp         is from   src/lib/compiler/front/typer-stuff/basics/stamp.pkg
    package sy  =  symbol;                              # symbol        is from   src/lib/compiler/front/basics/map/symbol.pkg
    package vh  =  varhome;                             # varhome       is from   src/lib/compiler/front/typer-stuff/basics/varhome.pkg
herein

    package   types
    : (weak)  Types                                     # Types         is from   src/lib/compiler/front/typer-stuff/types/types.api
    {
        Label = sy::Symbol;

        Type_Scheme_Arg_Eq_Properties
            =
            List( Bool );                               # equality property indicator 

        package eq_type {                               # Give YES/NO/... their own little namespace.
            #
            Data
              = YES
              | NO
              | INDETERMINATE                           # This was "IND", which I'm guessing is cryptic for "INDETERMINATE" -- 2009-03-21 CrT
              | CHUNK
              | DATA
              | EQ_ABSTRACT                             # Used to implement "abstype" statements.
              | UNDEF
              ;
        };

        Literal_Kind
            =
            INT | UNT | FLOAT | CHAR | STRING; 


        Type_Variable                   # User-specified type variables like X.  

            = USER_TYPE_VARIABLE {
                name:        sy::Symbol,                                                # A type variable symbol.
                eq:          Bool,                                              # Must it resolve to an 'equality type'?
                fn_nesting:  Int                                                # Outermost fun/fn lexical context mentioning/using us.
              }

            | META_TYPE_VARIABLE {
                eq:          Bool,                                              # Must it resolve to an 'equality type'?
                fn_nesting:  Int                                                # Outermost fun/fn lexical context mentioning/using us.
                                                                                #   fn_nesting = infinity for META-args
                                                                                #   fn_nesting < infinity for lambda bound
              }

            | INCOMPLETE_RECORD_TYPE_VARIABLE {
                known_fields: List( (Label, Type) ),
                eq:           Bool,                                             # Must it resolve to an 'equality type'?
                fn_nesting:   Int                                               # Outermost fun/fn lexical context mentioning/using us.
              }

            | RESOLVED_TYPE_VARIABLE Type                                                               # A type variable for which we have inferred a type.

            | OVERLOADED_TYPE_VARIABLE  Bool                                                            # Overloaded operator type scheme variable:
                                                                                                        # arg is TRUE if it must resolve to an equality type.

            | LITERAL_TYPE_VARIABLE                                                                     # Used to resolve type of a type-agnostic literal.
               { kind: Literal_Kind,
                 source_code_region: line_number_db::Source_Code_Region
               }

            | TYPE_VARIABLE_MARK  Int

        also
        Typ_Path                        
            = TYPPATH_VARIABLE   Exception
            | TYPPATH_TYP        Typ
            | TYPPATH_GENERIC   (List(Typ_Path), List(Typ_Path))
            | TYPPATH_APPLY     (Typ_Path,       List(Typ_Path))
            | TYPPATH_SELECT    (Typ_Path, Int)

        also
        Typ_Kind
            = BASE  Int
            | DATATYPE 
                { index:        Int,
                  stamps:       Vector(  sta::Stamp ),
                  root:         Null_Or( sta::Stamp ),          # The root field used by type spec only. 
                  free_typs:    List( Typ ),
                  family:       Datatype_Family
                }
            | ABSTRACT  Typ
            | FORMAL                                            # Used only inside apis 
            | TEMP                                              # Used only during enum elaborations 
            | FLEXIBLE_TYP  Typ_Path                            # Macro expanded formal type constructor 
                                                                # Nomenclature: "Definition of SML" calls typcons from apis "flexible" an all others "rigid".
        also
        Typ                                                     # Typ is the referent for   symbolmapstack_entry::Symbolmapstack_Entry.NAMED_TYPE

            = PLAIN_TYP  Plain_Typ_Record
            | DEFINED_TYP 
                {   stamp:        sta::Stamp, 
                    type_scheme:  Type_Scheme, 
                    strict:       List( Bool ), 
                    path:         ip::Inverse_Path
                }
            | TYP_BY_STAMPPATH                                  #  Used only inside apis 
                {   arity:        Int,
                    stamppath:    mp::Stamppath,
                    path:         ip::Inverse_Path
                }
            | RECORD_TYP  List( Label )
            | RECURSIVE_TYPE  Int                               #  Used only in domain type of Constructor_Description 
            | FREE_TYPE  Int                                    #  Used only in domain type of Constructor_Description 
            | ERRONEOUS_TYP

        also
        Type 
            = TYPE_VARIABLE_REF  Typevar_Ref
            | TYPE_SCHEME_ARG_I  Int                            # i-th argument to a type function.
            | WILDCARD_TYPE
            | UNDEFINED_TYPE
            | TYPCON_TYPE  (Typ, List(Type))
            | TYPE_SCHEME_TYPE 
                {   type_scheme_arg_eq_properties:      Type_Scheme_Arg_Eq_Properties,
                    type_scheme:                        Type_Scheme
                }

        also
        Type_Scheme 
            = TYPE_SCHEME 
                {   arity: Int,
                    body: Type
                }

        withtype
        Typevar_Ref
            =
            {   ref_typevar:  Ref( Type_Variable ),
                id:           Int                                                       # Purely for debuggging printout purposes.
            }



        also
        Constructor_Description                                                         # Used in Datatype_Member 
            =
            { name:             sy::Symbol,
              form:             vh::Valcon_Form,
              domain:           Null_Or( Type )
            }



        #  A member of a family of (potentially) mutually recursive datatypes 

        also
        Datatype_Member
            =
            { typ_name:         sy::Symbol,
              arity:            Int,
              eqtype_info:      Ref( eq_type::Data ),                   # Records whether this is/isn't/might-be/... an "equality type".
              is_lazy:          Bool,
              constructor_list: List( Constructor_Description ),
              an_api:           vh::Valcon_Signature
            }

        also
        Datatype_Family
            = 
            { mkey:             sta::Stamp,                             # "member key"...? 
              members:          Vector( Datatype_Member ),
              property_list:    pl::Property_List
            }

        also
        Stub_Info
            =
            { owner:            ph::Picklehash,
              is_lib:           Bool
            }

        also
        Plain_Typ_Record                                                # Plain_Typ_Record is the referent for   stammapstack::Stampmapstack.typ_map,  module_level_declarations::Modtree.PLAIN_TYP_MODTREE_NODE
            =
            { stamp:            sta::Stamp, 
              arity:            Int, 
              eqtype_info:      Ref( eq_type::Data ),           # YES/NO/... Records what we know about legality of equality comparisons on this type.
              #
              kind:             Typ_Kind,
              path:             ip::Inverse_Path,
              stub:             Null_Or( Stub_Info )
            };

        debugging  =   typer_data_controls::types_debugging;            #  REF FALSE 

        stipulate
            #
            next_type_var_id =  REF 0;                                  # Used purely for debugging printout purposes.
            #
        herein
            #

            fun allocate_type_variable_id ()
                =
                {   id = *next_type_var_id;
                    next_type_var_id := id + 1;
                    id;
                };

            fun make_type_variable_ref
                ( typevar:  Type_Variable,
                  stack:    List(String)
                )
                :
                Typevar_Ref
                =
                {   if *debugging
                        printf "make_type_variable_ref making typevar_ref id%d for %s\n"  *next_type_var_id  (string::join "" (reverse stack));
                    fi; 
                    #
                    { ref_typevar => REF typevar,
                      id          => allocate_type_variable_id()
                    }; 
                };

            fun make_type_variable_ref'
                ( ref_typevar:  Ref( Type_Variable ),
                  stack:        List(String)
                )
                :
                Typevar_Ref
                =
                {   if *debugging
                        printf "make_type_variable_ref' making typevar_ref id%d for %s\n"  *next_type_var_id  (string::join "" (reverse stack));
                    fi; 
                    #
                    { id => allocate_type_variable_id (),
                      ref_typevar
                    }; 
                };

        end;

        fun copy_type_variable_ref ({ ref_typevar, ... }: Typevar_Ref)
            =
            { ref_typevar =>  REF *ref_typevar,
              id          =>  allocate_type_variable_id()
            };

        infinity = 10000000;                                                    # Now you know. :)

        Valcon                                                                  # Valcon" == "Value Constructor" -- "FOO' in   "Foo = FOO".
            =
            VALCON  {                                                           # The first three fields are the only ones that really matter:
              name:             sy::Symbol,                                     # Name of valcon -- "FOO" value-symbol.
              type:             Type,
              form:             vh::Valcon_Form,                                # Runtime form for valcon -- can be tagged_int or exception or all sorts of other stuff.
              # 
              is_constant:      Bool,                                           # TRUE iff constructor takes no arguments -- e.g., TRUE, FALSE, NULL.   (This field is redundant, could be determined from type.) 
              signature:        vh::Valcon_Signature,                           # (Redundant, could be determined from type.)
              # 
              is_lazy:          Bool                                            # Does valcon belong to lazy datatype? (Nonstandard, undocumented extension.)
            };
    };                                                                          # package types 
end;                                                                            # stipulate



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext