PreviousUpNext

15.4.626  src/lib/compiler/front/typer-stuff/types/type-declaration-types.pkg

## type-declaration-types.pkg
#
# Datastructures describing type declarations.
#
# In particular,
#
#     Type
#
# 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
#
# CAVEAT PROGRAMMER: Many types in this file are hardwired in the pickler -- see Note[1].

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





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
    package lnd =  line_number_db;                                              # line_number_db                is from   src/lib/compiler/front/basics/source/line-number-db.pkg
herein

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

        Typescheme_Eqflags                                                      # Track which args in a typescheme must be equality types. 
            =
            List( Bool );                                                       # eqflags.

        package e {                                                             # Give YES/NO/... their own little namespace.
            #
            Is_Eqtype
              = YES
              | NO
              | INDETERMINATE                                                   # This was "IND", which I'm guessing was a cryptonym for "INDETERMINATE" -- 2009-03-21 CrT
              | CHUNK
              | DATA
              | UNDEF
              ;
        };

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


        Typevar                                                                 # User-specified type variables like X.  
            #
            = USER_TYPEVAR {
                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_TYPEVAR                                                      # A typeagnostic ("polymorphic") type variable.  It expresses maximal ignorance:  This is what we initialize a TYPEVAR_REF to before
              {                                                                 # doing type inference on it -- see generalize_type' in src/lib/compiler/front/typer/types/type-core-language-declaration-g.pkg
                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_TYPEVAR {                                       # Used to represent a record type before we know all of its fields.  For example if we see "foo.bar" we know 'foo' is a record, but the only field we know is 'bar'.
                known_fields:           List( (Label, Typoid) ),
                eq:                     Bool,                                   # Must it resolve to an 'equality type'?
                fn_nesting:             Int                                     # Outermost fun/fn lexical context mentioning/using us.
              }

            | RESOLVED_TYPEVAR          Typoid                                  # When we resolve a META_TYPEVAR to a concrete type, we replace it by this.

            | OVERLOADED_TYPEVAR        Bool                                    # arg is TRUE iff it must resolve to an equality type.
                                                                                # Represents overloaded operators like '+' which must be resolved at compiletime to concrete functions based on types of arguments.
                                                                                # Overloaded ops are set up in    src/lib/core/init/pervasive.pkg
                                                                                # and compiletime-resolved in     src/lib/compiler/front/typer/types/resolve-overloaded-variables.pkg

            | LITERAL_TYPEVAR {                                                 # Literals like '0' may be any of (Int, Unt, Integer, ...). We use this until the type resolves.
                kind:                   Literal_Kind,
                source_code_region:     lnd::Source_Code_Region
              }

            | TYPEVAR_MARK  Int

        also
        Typepath                        
            = TYPEPATH_VARIABLE         Exception
            | TYPEPATH_TYPE             Type
            | TYPEPATH_GENERIC          (List(Typepath), List(Typepath))
            | TYPEPATH_APPLY            (Typepath,       List(Typepath))
            | TYPEPATH_SELECT           (Typepath, Int)

        also
        Typekind
            = BASE  Int                                                         # Used for builtin types like Char/String/Float/Exception -- see pt2tc  in   src/lib/compiler/front/typer-stuff/types/core-type-types.pkg
            | SUMTYPE 
                { index:                Int,
                  stamps:               Vector(  sta::Stamp ),
                  root:                 Null_Or( sta::Stamp ),                  # The root field used by type spec only.
                  free_types:           List( Type ),
                  family:               Sumtype_Family
                }
            | ABSTRACT                  Type                                    # Used in strong sealing; the process starts in the   STRONG_PACKAGE_CAST   case in type_constrained_package() in     src/lib/compiler/front/typer/main/type-package-language-g.pkg
            | FORMAL                                                            # Used only inside apis 
            | TEMP                                                              # Used only during sumtype elaborations 
            | FLEXIBLE_TYPE             Typepath                                # Macro expanded formal type constructor 
                                                                                # Nomenclature: "Definition of SML" calls typcons from apis "flexible" an all others "rigid".
        also
        Type                                                                    # Type is the referent for   symbolmapstack_entry::Symbolmapstack_Entry.NAMED_TYPE
            = SUM_TYPE                                                          # Used for raw::SUM_TYPE (==sumtypes) -- see type_sumtype_declaration in src/lib/compiler/front/typer/main/type-type.pkg
                Sumtype_Record                                                  # 

            | NAMED_TYPE {                                                      # Used for raw::NAMED_TYPE (not sumtypes) -- see typecheck_named_type() in src/lib/compiler/front/typer/main/type-type.pkg
                # 
                stamp:                  sta::Stamp,                             # stamp         is from   src/lib/compiler/front/typer-stuff/basics/stamp.pkg
                typescheme:             Typescheme,                             # typescheme.arity gives the formals like 'X'; 
                #                                                               # typescheme.body  gives the 'THIS | THAT ...' info.
                strict:                 List( Bool ),
                namepath:               ip::Inverse_Path                        # Name is ip::last(path) -- the 'Foo' from  Foo = ...  or  Foo(X) = ...
              }

            | TYPE_BY_STAMPPATH  {                                              # Used only inside apis 
                arity:                  Int,
                stamppath:              mp::Stamppath,                          # stamppath     is from   src/lib/compiler/front/typer-stuff/modules/stamppath.pkg
                namepath:               ip::Inverse_Path                        # Name is ip::last(path) -- the 'Foo' from  Foo = ...
              }

            | RECORD_TYPE               List( Label )
            | RECURSIVE_TYPE            Int                                     #  Used only in domain type of Valcon_Info 
            | FREE_TYPE                 Int                                     #  Used only in domain type of Valcon_Info 
            | ERRONEOUS_TYPE

        also
        Typoid                                                                  # Things which are type-like but not actually types, hence the name "typoid".
            = TYPEVAR_REF               Typevar_Ref
            | TYPESCHEME_ARG            Int                                     # i-th argument to a typescheme.
            | WILDCARD_TYPOID
            | UNDEFINED_TYPOID
            | TYPCON_TYPOID             (Type, List(Typoid))
            | TYPESCHEME_TYPOID                                                 # A type with typevars:  Foo(X) = ...
                { typescheme:           Typescheme,
                  typescheme_eqflags:   Typescheme_Eqflags                      # Track which typescheme args are equality types.
                }

        also
        Typescheme                                                              # Represents a type with typevars:  Foo(X) = ...
            = TYPESCHEME 
                { arity:                Int,
                  body:                 Typoid
                }

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

        also
        Valcon_Info                                                             # Used in Sumtype_Member
            =
            { name:                     sy::Symbol,
              form:                     vh::Valcon_Form,                        # Runtime form for valcon: tagged_int, exception , ...
              domain:                   Null_Or( Typoid )
            }

        also
        Sumtype_Member                                                          # A member of a family of (potentially) mutually recursive sumtypes.
            =                                                                   # Might be only one member in the family.
            { name_symbol:              sy::Symbol,
              arity:                    Int,
              is_eqtype:                Ref( e::Is_Eqtype ),                    # Records whether this is/isn't/might-be/... an "equality type".
              is_lazy:                  Bool,
              valcons:                  List( Valcon_Info ),
              an_api:                   vh::Valcon_Signature
            }

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

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

        also
        Sumtype_Record                                                          # Sumtype_Record is the referent for   stammapstack::Stampmapstack.type_map,  module_level_declarations::Modtree.SUMTYPE_MODTREE_NODE
            =
            { stamp:                    sta::Stamp, 
              arity:                    Int, 
              is_eqtype:                Ref( e::Is_Eqtype ),                    # YES/NO/... Records what we know about legality of equality comparisons on this type.
              #
              kind:                     Typekind,
              namepath:                 ip::Inverse_Path,                       # Name is ip::last(path) -- the 'Foo' from  Foo = ...
              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_typevar_id ()
                =
                {   id = *next_type_var_id;
                    next_type_var_id := id + 1;
                    id;
                };

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

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

        end;

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

        infinity = 10000000;                                                    # Now you know. :)

        Valcon                                                                  # Valcon" == "Value Constructor" -- "FOO' in   "Foo = FOO".
            =                                                                   # CAVEAT PROGRAMMER: This record is hardwired in the pickler -- see Note[1]
            VALCON  {                                                           # The first three fields are the only ones that really matter:
              name:             sy::Symbol,                                     # Name of valcon -- "FOO" value-symbol.
              typoid:           Typoid,
              form:             vh::Valcon_Form,                                # Runtime form for valcon: tagged_int, exception , ...
              # 
              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 sumtype? (Nonstandard, undocumented extension.)
            };
    };                                                                          # package types 
end;                                                                            # stipulate

##########################################################################
# Note[1]
# Various types in this file are hardwired in the pickling code:
#
#     src/lib/compiler/src/library/pickler.pkg
#     src/lib/compiler/src/library/unpickler.pkg
#
#     src/lib/compiler/front/semantic/pickle/unpickler-junk.pkg
#     src/lib/compiler/front/semantic/pickle/pickler-junk.pkg
#
# Modifying these types is nontrivial because pickled code is on
# disk and mixing the old and new pickled versions won't work.
#
# Modify these types will require doing a two-step dance:
# 1) Define a replacement type for an existing type.
# 2) Modify all relevant code to accept the new type as well as the old type.
# 3) Do a full compile cycle to establish the new code.
# 3) Convert all code to generate the new type instead of the old type.
# 4) Do a full compile cycle to flush out all pickles containing the original type.
# 5) Remove the original type and the code using it.
# 6) Do a full compile cycle to flush out all remnants of the original type.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext