PreviousUpNext

15.4.646  src/lib/compiler/front/typer/main/type-package-language-g.pkg

## type-package-language-g.pkg
#
# See overview comments in:
#
#     src/lib/compiler/front/typer/main/type-package-language.api

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


                                                                        # Api_Match                             is from   src/lib/compiler/front/typer/modules/api-match-g.pkg
                                                                        # Type_Core_Language_Declaration        is from   src/lib/compiler/front/typer/types/type-core-language-declaration-g.pkg
                                                                        # api_match                             is from   src/lib/compiler/front/semantic/modules/api-match.pkg
                                                                        # type_core_language_declaration        is from   src/lib/compiler/front/semantic/types/type-core-language-declaration.pkg

stipulate
    package bug =  typer_debugging;                                     # typer_debugging                       is from   src/lib/compiler/front/typer/main/typer-debugging.pkg
    package ds  =  deep_syntax;                                         # deep_syntax                           is from   src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.pkg
    package di  =  debruijn_index;                                      # debruijn_index                        is from   src/lib/compiler/front/typer/basics/debruijn-index.pkg
    package err =  error_message;                                       # error_message                         is from   src/lib/compiler/front/basics/errormsg/error-message.pkg
    package fst =  find_in_symbolmapstack;                              # find_in_symbolmapstack                is from   src/lib/compiler/front/typer-stuff/symbolmapstack/find-in-symbolmapstack.pkg
    package id  =  inlining_data;                                       # inlining_data                         is from   src/lib/compiler/front/typer-stuff/basics/inlining-data.pkg
    package ip  =  inverse_path;                                        # inverse_path                          is from   src/lib/compiler/front/typer-stuff/basics/symbol-path.pkg
    package lnd =  line_number_db;                                      # line_number_db                        is from   src/lib/compiler/front/basics/source/line-number-db.pkg
    package mld =  module_level_declarations;                           # module_level_declarations             is from   src/lib/compiler/front/typer-stuff/modules/module-level-declarations.pkg
    package mp  =  stamppath;                                           # stamppath                             is from   src/lib/compiler/front/typer-stuff/modules/stamppath.pkg
    package spc =  stamppath_context;                                   # stamppath_context                     is from   src/lib/compiler/front/typer-stuff/modules/stamppath-context.pkg
    package mj  =  module_junk;                                         # module_junk                           is from   src/lib/compiler/front/typer-stuff/modules/module-junk.pkg
    package pp  =  standard_prettyprinter;                              # standard_prettyprinter                is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg
    package ppu =  unparse_junk;                                        # unparse_junk                          is from   src/lib/compiler/front/typer/print/unparse-junk.pkg
    package prs =  prettyprint_raw_syntax;                              # prettyprint_raw_syntax                is from   src/lib/compiler/front/typer/print/prettyprint-raw-syntax.pkg
    package raw =  raw_syntax;                                          # raw_syntax                            is from   src/lib/compiler/front/parser/raw-syntax/raw-syntax.pkg
    package sta =  stamp;                                               # stamp                                 is from   src/lib/compiler/front/typer-stuff/basics/stamp.pkg
    package stx =  stampmapstack;                                       # stampmapstack                         is from   src/lib/compiler/front/typer-stuff/modules/stampmapstack.pkg
    package sxe =  symbolmapstack_entry;                                # symbolmapstack_entry                  is from   src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack-entry.pkg
    package sy  =  symbol;                                              # symbol                                is from   src/lib/compiler/front/basics/map/symbol.pkg
    package syp =  symbol_path;                                         # symbol_path                           is from   src/lib/compiler/front/typer-stuff/basics/symbol-path.pkg
    package syx =  symbolmapstack;                                      # symbolmapstack                        is from   src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg
    package tdt =  type_declaration_types;                              # type_declaration_types                is from   src/lib/compiler/front/typer-stuff/types/type-declaration-types.pkg
    package ta  =  type_api;                                            # type_api                              is from   src/lib/compiler/front/typer/main/type-api.pkg
    package tcl =  type_core_language;                                  # type_core_language                    is from   src/lib/compiler/front/typer/main/type-core-language.pkg
    package tro =  typerstore;                                          # typerstore                            is from   src/lib/compiler/front/typer-stuff/modules/typerstore.pkg
    package trj =  typer_junk;                                          # typer_junk                            is from   src/lib/compiler/front/typer/main/typer-junk.pkg
    package tt  =  type_type;                                           # type_type                             is from   src/lib/compiler/front/typer/main/type-type.pkg
    package tu  =  type_junk;                                           # type_junk                             is from   src/lib/compiler/front/typer-stuff/types/type-junk.pkg
    package vac =  variables_and_constructors;                          # variables_and_constructors            is from   src/lib/compiler/front/typer-stuff/deep-syntax/variables-and-constructors.pkg
    package vh  =  varhome;                                             # varhome                               is from   src/lib/compiler/front/typer-stuff/basics/varhome.pkg

    Pp = pp::Pp;

    include package   module_level_declarations;                                        # module_level_declarations             is from   src/lib/compiler/front/typer-stuff/modules/module-level-declarations.pkg

    expand_oop_syntax_in_package_expression  =  expand_oop_syntax::expand_oop_syntax_in_package_expression;
    expand_oop_syntax_in_package_expression2 =  expand_oop_syntax2::expand_oop_syntax_in_package_expression;
herein

    # We use a generic to factor out dependencies on highcode.
    #
    # This generic is invoked once, in
    #
    #     src/lib/compiler/front/semantic/typecheck/type-package-language.pkg
    #
    generic package   type_package_language_g
        (
          package am:           Api_Match;
          package tcd:          Type_Core_Language_Declaration;                 # type_core_language_declaration        is from   src/lib/compiler/front/semantic/types/type-core-language-declaration.pkg
        )
    : (weak)  Type_Package_Language

    {
        package ins = am::expand_generic::generics_expansion_junk;      # "ins" might be "instantiate"

        Package_Cast
               =    WEAK_PACKAGE_CAST
               |  STRONG_PACKAGE_CAST
               | PARTIAL_PACKAGE_CAST
               ;

        # Debugging: 
        #
        say         =   control_print::say;
#       debugging   =   typer_control::type_package_language_debugging;         #  eval:   set_control "typechecker::type_package_language_debugging" "TRUE";
debugging   =   log::debugging;



        # To use the above "debugging" flag you might (say) do
        #
        #     linux$ cd src/app/tut/test
        #     linux$ touch test.pkg
        #     linux$ my
        #     eval:  set_control "typechecker::type_package_language_debugging" "TRUE";
        #     eval:  make "test.lib";
        #
        # This will spew debug printouts of various datastructures
        # as the code in this file runs.


        #
        fun if_debugging_say (msg: String)
            =
            if *debugging 
                say msg;
                say "\n";
            fi;

        #
        fun bug msg
            =
            error_message::impossible("type_package_language: " + msg);


        debug_print
            =
            \\ x =  bug::debug_print  debugging  x;


        #
        fun unparse_raw_declaration
            (
              msg:          String,
              declaration:  raw::Declaration,
              symbolmapstack: syx::Symbolmapstack
            )
            =
            if *debugging
                print "\n";
                print msg;
                pp = standard_prettyprinter::make_standard_prettyprinter_into_file "/dev/stdout" [];

                unparse_raw_syntax::unparse_declaration
                    (symbolmapstack, NULL)
                    pp
                    (declaration, 100);

                pp.flush ();
                pp.close ();
                print "\n";
            fi;
        #
        fun prettyprint_raw_declaration
            (
              msg:          String,
              declaration:  raw::Declaration,
              symbolmapstack: syx::Symbolmapstack
            )
            =
            if *debugging
                print "\n";
                print msg;
                pp = standard_prettyprinter::make_standard_prettyprinter_into_file "/dev/stdout" [];

                prs::prettyprint_declaration
                    (symbolmapstack, NULL)
                    pp
                    (declaration, 100);

                pp.flush ();
                pp.close ();
                print "\n";
            fi;
        #
        fun unparse_deep_declaration
            (
              msg:          String,
              declaration:  deep_syntax::Declaration,
              symbolmapstack: syx::Symbolmapstack
            )
            =
            if *debugging
                print "\n";
                print msg;
                pp = standard_prettyprinter::make_standard_prettyprinter_into_file "/dev/stdout" [];

                unparse_deep_syntax::unparse_declaration
                    (symbolmapstack, NULL)
                    pp
                    (declaration, 100);

                pp.flush ();
                pp.close ();
                print "\n";
            fi;
        #
        fun if_debugging_show_package (msg, a_package, symbolmapstack)
            =
            {
                bug::with_internals
                    (\\ ()
                        =
                        debug_print
                            ( msg,
                              (\\ pp = \\ a_package =
                                unparse_package_language::unparse_package pp (a_package, symbolmapstack, 100)
                              ),
                              a_package)
                            );
                if *debugging   print "\n";   fi;
            };
        #
        fun if_debugging_show_api (msg, an_api, symbolmapstack)
            =
            {
                bug::with_internals
                    (\\ ()
                        =
                        debug_print
                            ( msg,
                              (\\ pp = \\ an_api =
                                unparse_package_language::unparse_api pp (an_api, symbolmapstack, 100)
                              ),
                              an_api)
                            );
                if *debugging   print "\n";   fi;
            };

#       fun show_symbolmapstack (msg, symbolmapstack)
#           =
#            if *debugging
#               print "\n";
#                print msg;
#                pp = standard_prettyprinter::make_standard_prettyprinter_into_file "/dev/stdout" [];
#
#                prettyprint_symbolmapstack::prettyprint_symbolmapstack
#                    pp
#                    symbolmapstack;
#
#                pp.flush ();
#                pp.close ();
#               print "\n";
#            fi;

        #
        fun show_generic (msg, a_generic, symbolmapstack)
            =
            bug::with_internals
                (\\ ()
                    =
                    debug_print
                        ( msg,
                          (\\ pp = \\ a_generic'
                              =
                              unparse_package_language::unparse_generic pp (a_generic', symbolmapstack, 100)
                          ),
                          a_generic)
                        );


        # Check if a typechecked_package declaration is empty
        # in order to avoid the unnecessary recompilation
        # bug reported by Matthias Blume (ZHONG)
        #
        fun module_declaration_is_not_empty ( mld::EMPTY_GENERIC_EVALUATION_DECLARATION
                                                     | mld::SEQUENTIAL_DECLARATIONS []
                                                     )
                =>
                FALSE;

            module_declaration_is_not_empty _
                =>
                TRUE;
        end;
        #
        fun module_declaration_sequence  declarations
            = 
            {   nodes = list::filter
                            module_declaration_is_not_empty
                            declarations;

                case nodes
                    #
                    []   =>   mld::EMPTY_GENERIC_EVALUATION_DECLARATION;
                    _    =>   mld::SEQUENTIAL_DECLARATIONS  nodes;
                esac;
            };

        #
        fun local_module_declaration (d1, d2)
            =
            module_declaration_sequence [d1, d2]; 


        include package   special_symbols;                      #  A dozen symbols like <parameter> <generic> <genericbody> ... 

        #
        fun strip_source_code_region_data_from_named_api (
                raw::SOURCE_CODE_REGION_FOR_NAMED_API (
                    api_naming',
                    source_code_region'
                ),
                source_code_region
            )
                =>
                strip_source_code_region_data_from_named_api (api_naming', source_code_region');

            strip_source_code_region_data_from_named_api x
                =>
                x;
        end;
        #
        fun strip_source_code_region_data_from_named_generic_api
                (
                  raw::SOURCE_REGION_FOR_NAMED_GENERIC_API (
                    generic_api_naming',
                    source_code_region'
                  ),

                  source_code_region
                )
                =>
                strip_source_code_region_data_from_named_generic_api (generic_api_naming', source_code_region');

            strip_source_code_region_data_from_named_generic_api x
                =>
                x;
        end;
        #
        fun strip_source_code_region_data_from_named_generics
                (
                    raw::SOURCE_CODE_REGION_FOR_NAMED_GENERIC (
                        generic_naming',
                        source_code_region'),
                    source_code_region
                )
                =>
                strip_source_code_region_data_from_named_generics (generic_naming', source_code_region');

            strip_source_code_region_data_from_named_generics x
                =>
                x;
        end;
        #
        fun strip_source_code_region_data_from_named_package (
                raw::SOURCE_CODE_REGION_FOR_NAMED_PACKAGE (
                    named_package',
                    source_code_region'
                ),
                source_code_region
            )
                =>
                strip_source_code_region_data_from_named_package (named_package', source_code_region');

            strip_source_code_region_data_from_named_package x
                =>
                x;
        end;

        # Change of syntactic_typechecking_context on entering a package
        #
        fun enter_package trj::AT_TOPLEVEL
                =>
                trj::IN_PACKAGE;

            enter_package z
                =>
                z;
        end; 

        # Add mod_id to stamppath mappings 
        # for all appropriate elements of a package
        # that has just been typechecked.
        # 
        # If stamppath_context is the empty context
        # (rigid), then this is an expensive no-op, so we
        #  test stamppath_context first.
        # 
        # But, would this be equivalent to context=INFCT _ ?  XXX BUGGO FIXME  ("INFCT" may be "in functor", i.e., "in generic")
        # 
        # stamppath_context is the stamppath_context
        # for the interior of the package -- i.e. the package
        # naming's Module_Stamp has been added to the bind_context 
        #
        # map_paths is quite heavyweight right now.      XXX BUGGO FIXME
        # It can be simplified in  several ways.
        # First, all type stamps don't have to be remapped, 
        # if new type stamps are mapped by macro_expand, then each map_paths
        # only need to deal with packages and generics.
        # Even dealing with packages and generics can be distributed
        # into the api matching or the instantiation process. (ZHONG)


#       map_paths_phase = (compile_statistics::make_phase "Compiler 033 1-map_paths") 
#       also map_paths x = compile_statistics::do_phase map_paths_phase map_paths0 x

        #
        fun map_paths ( stamppath_context,
                        A_PACKAGE { an_api, typechecked_package, ... },
                        flex                                                    # "Definition of SML" calls typcons from apis "flexible" an all others "rigid".
                      )
                =>
                map_stamppath_context
                    (
                      stamppath_context,
                      an_api,
                      typechecked_package,
                      flex
                    );

            map_paths _ => ();
        end 

        also
        fun map_stamppath_context
            (
                stamppath_context,
                an_api as API { api_elements, ... },
                typechecked_package: mld::Typechecked_Package,
                flex
            )
                => 
                {   typechecked_package ->   { typerstore, ... };
                    #
                    if (not (spc::is_empty  stamppath_context))
                        #
                        list::apply  do_element  api_elements;
                    fi
                    where
                        fun do_element (_, TYPE_IN_API { module_stamp, ... } )
                                =>
                                # bind only if type is flexible -- have to pass flexibility        "Definition of SML" calls typcons from apis "flexible" an all others "rigid".
                                # tester  -- but wait! what about a rigid package with a
                                # new api? Have to record even rigid packages and generics in
                                # case they have new apis 
                                #
                                case (tro::find_entry_by_module_stamp (typerstore, module_stamp))
                                    #
                                    TYPE_ENTRY type
                                        =>
                                        case type
                                            #
                                            tdt::ERRONEOUS_TYPE => ();

                                            _   =>
                                                {   stamp = tu::stamp_of_type type;
                                                    #
                                                    if (flex stamp)
                                                        #
                                                        spc::bind_typepath(
                                                            stamppath_context,
                                                            stx::typestamp_of'  type,
                                                            module_stamp
                                                        );
                                                    fi;
                                                };
                                         esac;
                                    #
                                    ERRONEOUS_ENTRY => ();
                                    #
                                    _ => bug "map_macro_expansion_path_context 1";
                                esac;

                            do_element (_, PACKAGE_IN_API { module_stamp, an_api => this_api, ... } )
                                =>
                                # Map this package (unconditionally, because it may 
                                # have a different api) 
                                #
                                case this_api             #  Don't record ERRONEOUS_API -- error tolerance 
                                    #
                                    API _
                                        =>
                                        case (tro::find_entry_by_module_stamp (typerstore, module_stamp))
                                            #
                                            PACKAGE_ENTRY nr
                                                =>
                                                {   i = mj::make_packagestamp (this_api, nr);
                                                    #
                                                    case (spc::find_stamppath_for_package (stamppath_context, i))
                                                        #
                                                        THE _ => ();

                                                       _ => {   spc::bind_stamppath (stamppath_context, i, module_stamp);

                                                                 map_stamppath_context (
                                                                     spc::enter_open (stamppath_context, THE module_stamp),
                                                                     this_api,
                                                                     nr,
                                                                     flex
                                                                 );
                                                             };
                                                    esac;
                                                };

                                            ERRONEOUS_ENTRY => ();

                                            _ => bug "map_macro_expansion_path_context 2";

                                        esac;

                                   ERRONEOUS_API => ();
                               esac;


                            do_element (_, GENERIC_IN_API { module_stamp, a_generic_api => this_api, ... } )
                                =>
                                # Map this generic (unconditionally):
                                #
                                case this_api
                                    # 
                                    GENERIC_API _
                                        =>
                                        case (tro::find_entry_by_module_stamp (typerstore, module_stamp))
                                            #
                                            GENERIC_ENTRY nr
                                                =>
                                                {   i = mj::make_genericstamp (this_api, nr);
                                                    #
                                                    spc::bind_generic_path (stamppath_context, i, module_stamp);
                                                };

                                            ERRONEOUS_ENTRY =>  ();
                                            _               =>  bug "map_macro_expansion_path_context 3";
                                        esac;

                                     ERRONEOUS_GENERIC_API => ();
                                 esac;

                            do_element _ => ();
                        end;                            # fun do_element
                    end;                                # where
                };

            map_stamppath_context _ => ();
        end;



        # ASSERT: order of DEFtypes in types respects dependencies, i.e. no
        #         NAMED_TYPE refers to types occurring after itself. 
        #
        fun bind_new_types (trj::IN_GENERIC _, epctxt, make_stamp, dtypes, wtypes, inverse_path, err)
                => 
                {   fun strip_path path
                        =
                        {   name_path = ip::INVERSE_PATH [ip::last path];
                            prefix    = ip::last_prefix path;

                            if (not (ip::equal (inverse_path, prefix))   )

                                err err::WARNING
                                         "Harmless compiler bug: bad type path prefix"
                                         err::null_error_body;
                            fi;

                            name_path;
                        };

                    vizty   =   (\\ typoid =   #1 (mj::relativize_typoid   epctxt  typoid));
                    viztc   =   (\\ tc     =   #1 (mj::relativize_type     epctxt  tc  ));

                    #  This is ok because stamppath_context has state; a bit ugly       XXX BUGGO FIXME
                    # 
                    new_dtypes
                        =
                        case dtypes
                            #                     
                            (tdt::SUM_TYPE { kind, ... } ! _)
                                =>
                                case kind
                                    #
                                    tdt::SUMTYPE { index => 0,  family,  free_types, stamps, root }
                                        =>
                                        {   rootev    = make_stamp();
                                            rtev_op   = THE rootev;
                                            nfreetypes = map viztc free_types;
                                            nstamps   = vector::map (\\ _ =  make_stamp()) stamps;

                                            map new_sumtype dtypes
                                            where
                                                fun new_sumtype (dt as tdt::SUM_TYPE { kind, arity, is_eqtype, namepath, ... } )
                                                        =>
                                                        case kind
                                                            #
                                                            tdt::SUMTYPE { index,  ... }
                                                                =>
                                                                {   my (module_stamp, rtev)
                                                                        = 
                                                                        if (index == 0)    (rootev,       NULL   );
                                                                        else              (make_stamp(), rtev_op);
                                                                        fi;

                                                                    nkind
                                                                        = 
                                                                        tdt::SUMTYPE { index,
                                                                                      stamps   => nstamps,
                                                                                      free_types => nfreetypes,
                                                                                      root     => rtev,
                                                                                      family
                                                                                   };

                                                                    # The rtev field in SUMTYPE indicates
                                                                    # how to discover the new stamps when 
                                                                    # such sumtypes get evalent-ed.
                                                                    #
                                                                    ndt = tdt::SUM_TYPE
                                                                            {
                                                                              arity,
                                                                              is_eqtype,
                                                                              #
                                                                              kind      => nkind,
                                                                              namepath  => strip_path  namepath, 
                                                                              stamp     => vector::get (nstamps, index),
                                                                              stub      => NULL
                                                                            };


                                                                    spc::bind_typepath (
                                                                        epctxt,
                                                                        mj::typestamp_of  dt,
                                                                        module_stamp
                                                                    );

                                                                    ( module_stamp,
                                                                      dt,
                                                                      mld::FORMAL_TYPE ndt
                                                                    );
                                                                };

                                                           _ => bug "unexpected case in new_sumtypeyc (1)";
                                                       esac;

                                                   new_sumtype _ => bug "unexpected case in new_sumtypeyc (2)";

                                                end;                    # fun new_sumtype
                                            end;                        # where 
                                        };

                                    _ => bug "unexpected types in bind_new_types (1)";
                                esac;

                            [] => [];

                            _ => bug "unexpected types in bind_new_types (2)";
                        esac;

                    nwtypes
                        = 
                        map newtc wtypes
                        where
                            fun newtc (tc as tdt::NAMED_TYPE { typescheme => tdt::TYPESCHEME { arity, body }, 
                                                                stamp,
                                                                strict,
                                                                namepath
                                                              }
                                       )
                                    =>
                                    {   module_stamp = make_stamp ();
                                        #
                                        spc::bind_typepath   (epctxt,   mj::typestamp_of tc,   module_stamp);

                                        ntc = tdt::NAMED_TYPE {
                                                  stamp      => make_stamp(),
                                                  strict, 
                                                  namepath   => strip_path  namepath,
                                                  typescheme => tdt::TYPESCHEME { arity,  body => vizty body }
                                              };

                                        ( module_stamp,
                                          tc,
                                          mld::FORMAL_TYPE ntc
                                        );
                                    };

                                newtc _ => bug "unexpected case in newwtyc";
                            end;
                        end;
                    #
                    fun bind  ( (module_stamp, tc, te)   !   tcs,
                                typerstore,
                                typechecked_package_decs
                              )
                            =>
                            bind( tcs,
                                  tro::set( typerstore,
                                            module_stamp,
                                            mld::TYPE_ENTRY( tc )
                                          ),
                                  mld::TYPE_DECLARATION (module_stamp, te) ! typechecked_package_decs
                                );

                        bind (NIL, typerstore, typechecked_package_decs)
                            =>
                            ( tro::mark( make_stamp, typerstore ),
                               module_declaration_sequence( reverse typechecked_package_decs )
                            );
                    end;


                    bind(  new_dtypes @ nwtypes,
                           tro::empty,
                           []
                    );
                };

           bind_new_types _
               =>
               ( tro::empty,
                 mld::EMPTY_GENERIC_EVALUATION_DECLARATION
               );
        end;


        ###########################################################################
        #                                                                         #
        # Extract API etc info from a symbol table.                               #
        #                                                                         #
        # Recompute dynamic accesses after the elaboration of a package body,     #
        # replacing the original dynamic access by a SLOT and generating a        #
        # thinning that will be used (in translate) to create the package         #
        # record.                                                                 #
        #                                                                         #
        # Recompute all the dynamic accesses in an dictionary, suppress doubles   #
        # and allot slots. Components are ordered so that slot allocation is   #
        # independent of the way elaboration is done.                             #
        #                                                                         #
        # Should we use dictionary::fold or dictionary::map?                                  #
        #                                                                         #
        ###########################################################################
        #
        fun extract_symbolmapstack_contents
            (
              symbolmapstack:                                           syx::Symbolmapstack,
              stamppath_context:                                        spc::Context,
              syntactic_typechecking_context:                           trj::Syntactic_Typechecking_Context,    # TOPLEVEL/API/PKG/GENERIC
              per_compile_stuff as { make_fresh_stamp, ... }:           trj::Per_Compile_Stuff
            )
            :
            ( List( (symbol::Symbol, mld::Api_Element ) ),              # api_elements
              mld::Typerstore,                                          # typerstore
              List( Module_Declaration ),                               # module_declarations
              List( symbolmapstack_entry::Symbolmapstack_Entry ),       # locations
              Bool                                                      # contains_generic
            )
            =
            {   fun get_modulepath_or_null (get, mod_id)
                    =
                    case syntactic_typechecking_context
                        trj::IN_GENERIC _ =>  get (stamppath_context, mod_id);
                        _                =>  NULL;
                    esac;

                relativize
                    =
                    case syntactic_typechecking_context
                        #
                        trj::IN_GENERIC _ =>  \\ typoid =    #1  (mj::relativize_typoid  stamppath_context  typoid);
                        _                 =>  \\ x = x;
                    esac;


                # We call this once for each entry in the symbol table.
                #
                # The first argument is the name/entry symbol table pair.
                #
                # The second argument holds the lists etc in which
                # we accumulate extracted symbol table entry
                # information.
                #
                # We discard the 'slot_count' variable when we complete
                # reading all the symbol table entries;  we use it only
                # for assigning successive package record slots to
                # VALUE_IN_API records etc.
                #
                fun note_named_symbolmapstack_entry
                    (
                      # Named entry to note:
                      #
                      ( symbol:                         symbol::Symbol,
                        symbolmapstack_entry:           sxe::Symbolmapstack_Entry
                      ), 

                      # Info from previously noted
                      # named entries:
                      #
                      { named_api_elements:             List( (symbol::Symbol, Api_Element) ),
                        typerstore:                     Typerstore,
                        module_declarations:            List( Module_Declaration ),
                        symbolmapstack_entries:         List( sxe::Symbolmapstack_Entry ),
                        slot_count:                     Int,
                        contains_generic:               Bool
                      }
                    )
                    = 
                    case symbolmapstack_entry
                        #                      
                        sxe::NAMED_VARIABLE( vac::PLAIN_VARIABLE { vartypoid_ref, path, ... } )
                            =>
                            {   api_element
                                    =
                                    VALUE_IN_API {
                                      typoid =>  relativize *vartypoid_ref,
                                      slot   =>  slot_count
                                    };

                                named_api_elements     = (symbol, api_element) ! named_api_elements;
                                symbolmapstack_entries = symbolmapstack_entry  ! symbolmapstack_entries;
                                slot_count             = slot_count + 1;

                                { named_api_elements,
                                  typerstore,
                                  module_declarations,
                                  symbolmapstack_entries, 
                                  slot_count,
                                  contains_generic
                                };
                            };

                        sxe::NAMED_CONSTRUCTOR (
                                valcon as tdt::VALCON {
                                    name,
                                    is_constant,
                                    is_lazy,
                                    signature,
                                    typoid,
                                    form
                                }
                            )
                            =>
                            {   typoid = relativize  typoid;
                                #
                                my  ( form,
                                      symbolmapstack_entries,
                                      slot,
                                      slot_count
                                    )
                                    =
                                    case form
                                        #
                                        vh::EXCEPTION _
                                            => 
                                            (   vh::EXCEPTION (vh::null_varhome),
                                                symbolmapstack_entry ! symbolmapstack_entries, 
                                                THE slot_count,
                                                slot_count + 1
                                            );

                                       _ => (form, symbolmapstack_entries, NULL, slot_count);

                                    esac;

                                sumtype = tdt::VALCON
                                              {
                                                name,
                                                is_constant,
                                                signature,
                                                typoid,
                                                form,
                                                is_lazy
                                              };

                                sumtype = VALCON_IN_API { sumtype,   slot };

                                named_api_elements =  (symbol, sumtype) ! named_api_elements;

                                { named_api_elements,
                                  typerstore,
                                  module_declarations,
                                  symbolmapstack_entries,
                                  slot_count,
                                  contains_generic
                                };
                            };

                        sxe::NAMED_PACKAGE ( a_package as A_PACKAGE { an_api, typechecked_package, ... } )
                            =>
                            {   modulepath_or_null
                                    =
                                    get_modulepath_or_null (
                                      spc::find_stamppath_for_package,
                                      mj::packagestamp_of   a_package
                                    );

                                my  ( module_stamp,
                                      typerstore,
                                      module_declarations
                                    )
                                    =
                                    case modulepath_or_null
                                        #
                                        THE [module_stamp]
                                            =>
                                            ( module_stamp,
                                              typerstore,
                                              module_declarations
                                            );

                                        _   =>
                                            (module_stamp, ee, ed)
                                            where
                                                module_stamp =   make_fresh_stamp ();

                                                ee = tro::set (typerstore, module_stamp, PACKAGE_ENTRY typechecked_package);

                                                ed =    case syntactic_typechecking_context
                                                            #
                                                            trj::IN_GENERIC _
                                                                => 
                                                                {   package_expression
                                                                        = 
                                                                        case modulepath_or_null 
                                                                            THE stamppath => mld::VARIABLE_PACKAGE stamppath;
                                                                            _               => mld::CONSTANT_PACKAGE typechecked_package;
                                                                        esac;

                                                                    (mld::PACKAGE_DECLARATION (module_stamp, package_expression, symbol))
                                                                    !
                                                                    module_declarations;
                                                                };

                                                            _ => module_declarations;
                                                        esac;
                                            end;
                                    esac;

                                  api_element
                                      =
                                      PACKAGE_IN_API {
                                        slot       => slot_count,
                                        definition => NULL,
                                        an_api,
                                        module_stamp
                                      };

                                  named_api_elements     =  (symbol, api_element) ! named_api_elements;
                                  symbolmapstack_entries =   symbolmapstack_entry   ! symbolmapstack_entries;
                                  slot_count             =   slot_count + 1;

                                  contains_generic
                                      = 
                                      case an_api 
                                           API sg =>  contains_generic or sg.contains_generic;
                                           _      =>  contains_generic;
                                      esac;

                                  { named_api_elements,
                                    typerstore,
                                    module_declarations,
                                    symbolmapstack_entries, 
                                    slot_count,
                                    contains_generic
                                  };
                            };

                        sxe::NAMED_GENERIC ( a_generic as GENERIC { a_generic_api, typechecked_generic, ... } )
                            =>
                            {   modulepath_or_null
                                    =
                                    get_modulepath_or_null   (spc::find_stamppath_for_generic,   mj::genericstamp_of  a_generic);

                                my  ( module_stamp,
                                      typerstore,
                                      module_declarations
                                    )
                                    =
                                    case modulepath_or_null
                                        #
                                        THE [x] => (x, typerstore, module_declarations);

                                        _ => 
                                            (x, ee, ed)
                                            where
                                                x  =   make_fresh_stamp ();

                                                ee = tro::set (typerstore, x, GENERIC_ENTRY  typechecked_generic);

                                                ed = case syntactic_typechecking_context

                                                          trj::IN_GENERIC _
                                                              => 
                                                              {   generic_expression
                                                                      = 
                                                                      case modulepath_or_null 
                                                                          THE stamppath =>  mld::VARIABLE_GENERIC  stamppath;
                                                                          _               =>  mld::CONSTANT_GENERIC  typechecked_generic;
                                                                      esac;

                                                                  (mld::GENERIC_DECLARATION (x, generic_expression))
                                                                  !
                                                                  module_declarations;
                                                              };

                                                          _ => module_declarations;
                                                     esac;
                                            end;                # where
                                    esac;

                                api_element
                                    =
                                    GENERIC_IN_API {
                                      slot   => slot_count,
                                      a_generic_api,
                                      module_stamp
                                    };

                                named_api_elements     =  (symbol, api_element) ! named_api_elements;
                                symbolmapstack_entries =   symbolmapstack_entry   ! symbolmapstack_entries;
                                slot_count             =   slot_count + 1;
                                contains_generic       =   TRUE;

                                { named_api_elements,
                                  typerstore,
                                  module_declarations,
                                  symbolmapstack_entries, 
                                  slot_count,
                                  contains_generic
                                };
                            };

                        sxe::NAMED_TYPE type
                            =>
                            {   modulepath_or_null
                                    =
                                    case type
                                        #
                                        tdt::ERRONEOUS_TYPE =>  NULL;
                                         _                  =>  get_modulepath_or_null (
                                                                  spc::find_stamppath_for_type,
                                                                  mj::typestamp_of  type
                                                                );
                                    esac;

                                my  ( module_stamp,
                                      typerstore,
                                      module_declarations
                                    )
                                    =
                                    case modulepath_or_null

                                        THE [x] => (x, typerstore, module_declarations);

                                        _ => 
                                            (x, ee, ed)
                                            where 
                                                x =   make_fresh_stamp ();

                                                ee = tro::set (typerstore, x, TYPE_ENTRY type);

                                                ed = case syntactic_typechecking_context
                                                         #
                                                         trj::IN_GENERIC _
                                                             => 
                                                             {   typechecked_type_expression
                                                                     = 
                                                                     case modulepath_or_null
                                                                         #
                                                                         THE stamppath =>  mld::TYPEVAR_TYPE  stamppath;
                                                                         _             =>  mld::CONSTANT_TYPE  type;
                                                                     esac;

                                                                 (mld::TYPE_DECLARATION (x, typechecked_type_expression))
                                                                 !
                                                                 module_declarations;
                                                             };

                                                         _  => module_declarations;
                                                     esac;

                                            end;                        # where
                                    esac;

                                api_element
                                    =
                                    TYPE_IN_API {
                                      type => tdt::ERRONEOUS_TYPE,
                                      is_a_replica     => FALSE,
                                      scope            => 0,
                                      module_stamp
                                    };

                                named_api_elements =  (symbol, api_element) ! named_api_elements;

                                # Use of tdt::ERRONEOUS_TYPE above is a hack.
                                #
                                # It relies on the fact that the inferred api
                                # would never be macro expanded or api-matched
                                # against anyway.
                                #
                                # One might wonder what about a generic declaration
                                # with no result api constraint -- the
                                # inferred Generic_Api would contain
                                # tdt::ERRONEOUS_TYPE -- but fortunately
                                # the result api in this Generic_Api
                                # would never be matched against either. (ZHONG)

                                { named_api_elements,
                                  typerstore,
                                  module_declarations,
                                  symbolmapstack_entries,
                                  slot_count,
                                  contains_generic
                                };
                            };

                       _ => { named_api_elements,
                              typerstore,
                              module_declarations,
                              symbolmapstack_entries,
                              slot_count,
                              contains_generic
                            };
                  esac;                                 # fun note_named_symbolmapstack_entry

                  named_symbolmapstack_entries
                      =
                      syx::to_sorted_list (syx::consolidate symbolmapstack);

                  (list::fold_forward
                      note_named_symbolmapstack_entry
                      { named_api_elements     => ([]:          List( (symbol::Symbol, Api_Element) )),
                        typerstore             => tro::empty,
                        module_declarations    => ([]:          List( Module_Declaration )),
                        symbolmapstack_entries => ([]:          List( sxe::Symbolmapstack_Entry )),
                        slot_count             => 0,
                        contains_generic       => FALSE
                      }
                      (named_symbolmapstack_entries:    List ((symbol::Symbol, syx::Entry)))
                  )
                      ->
                      { named_api_elements,
                        typerstore,
                        module_declarations,
                        symbolmapstack_entries,
                        slot_count,                     # Discarded at this point.
                        contains_generic
                      };

            
                  ( reverse  named_api_elements,
                    typerstore,
                    reverse  module_declarations,
                    reverse  symbolmapstack_entries,
                    contains_generic
                  );
            };                                          #  fun extract_symbolmapstack_contents 

            # 2009-08-10 CrT:
            #    THIS IS NOT WORKING.  It radiated
            #    error conditions into parts of the
            #    backend I do not understand well
            #    enough to modify appropriately.
            # 
            #    I implemented this before I realized
            #    that parts of a package can be selectively
            #    strong-sealed by putting them in a subpackage,
            #    sealing it, and then including it back into
            #    the main package.
            # 
            #    Now that I'm more aware of that hack,
            #    I'm undecided as to whether the PARTIAL_CAST
            #    idea is worth pursuing.
            # 
            # This is our core hack to implement
            # partial package casting ("sealing").
            #
            # The only difference between strong and
            # partial package casting is that strong
            # package casting hides all package elements
            # not explicitly listed in the api, whereas
            # partial package casting leaves unmentioned
            # elements visible and unchanged.
            #
            # This function conditionally extends the api
            # with all unmentioned elements from the package,
            # thereby reducing partial package casting to
            # the already-implemented case of strong package
            # casting.
            #
            #
            # Our three input arguments are:
            #
            #   o The constraining api (if any).
            #
            #   o The cast operation. We do nothing
            #     unless it is PARTIAL_PACKAGE_CAST.
            #
            #   o The constrained package.
            #
            #   o The associated symbol table.
            #
            #
            # We return three results:
            #
            #   o The constraining API, possibly augmented
            #     with new elements.
            #
            #   o The cast operation, possibly changed
            #     from PARTIAL_PACKAGE_CAST
            #     to    STRONG_PACKAGE_CAST.
            #
            fun maybe_extend_api_to_cover_package
                (
                  constraining_api_or_null:     Null_Or( mld::Api ),
                  package_cast:                 Package_Cast,                   # How to apply constraining API -- strong/weak/partial cast.
                  a_package:                    mld::Package,
                  symbolmapstack:                 syx::Symbolmapstack
                )
                :
                ( Null_Or( mld::Api ),          # constraining_api_or_null
                  Package_Cast,                 # package_cast
                  syx::Symbolmapstack           # symbolmapstack
                )
                =
                {
                                                                                                                                if *debugging
                                                                                                                                    case package_cast
                                                                                                                                           WEAK_PACKAGE_CAST => print "maybe_extend_api_to_cover_package: This is a WEAK cast.\n";
                                                                                                                                         STRONG_PACKAGE_CAST => print "maybe_extend_api_to_cover_package: This is a STRONG cast.\n";
                                                                                                                                        PARTIAL_PACKAGE_CAST => print "maybe_extend_api_to_cover_package: This is a PARTIAL cast.\n";
                                                                                                                                    esac;
                                                                                                                                fi;
                    case package_cast
                        #
                        PARTIAL_PACKAGE_CAST
                            =>
                            case (constraining_api_or_null, a_package)
                                #
                                ( THE (old_api as API { stamp, name, stub, api_elements => constraining_elements, closed, symbols, property_list, contains_generic, type_sharing, package_sharing } ),
                                  A_PACKAGE  { an_api =>  API { api_elements => constrained_elements, ... }, ... }
                                )
                                    =>
                                    {    # The difference between PARTIAL_PACKAGE_CAST
                                         # and STRONG_PACKAGE_CAST is just that the latter
                                         # hides all package elements not explicitly listed
                                         # in the API, whereas the former passes through
                                         # unchanged all package elements not mentioned
                                         # by the api.

                                                                                                                                { old_debug_setting = *debugging;
                                                                                                                                  debugging := TRUE;
                                                                                                                                                                         if_debugging_show_api     ("maybe_extend_api_to_cover_package: original api:    -- type-package-language-g.pkg",        old_api,   symbolmapstack);
                                                                                                                                                                         if_debugging_show_package ("maybe_extend_api_to_cover_package: constrained_package:   --type-package-language-g.pkg", a_package, symbolmapstack);
                                                                                                                                  debugging := old_debug_setting;
                                                                                                                                };
                                                                                                                                fun print_elements  []
                                                                                                                                        =>
                                                                                                                                        ();

                                                                                                                                    print_elements ((symbol, api_element: mld::Api_Element) ! rest)
                                                                                                                                        =>
                                                                                                                                        {   printf "  api element: %s\n" (sy::name symbol);
                                                                                                                                            print_elements rest;
                                                                                                                                        };
                                                                                                                                end;
                                                                                                                                printf "Initial constraining elements: \n";  print_elements constraining_elements;
                                                                                                                                printf "Initial constrained  elements: \n";  print_elements  constrained_elements;

                                         constraining_elements
                                             =
                                             (reverse  constrained_elements)
                                             @
                                             constraining_elements;
#                                            constraining_elements;
#                                            constrained_elements @ constraining_elements;

                                                                                                                                printf "Final   constraining elements: \n";  print_elements constraining_elements;


                                         # We implement that here by adding to the api 'elements'
                                         # list all "missing" elements in it present in the package.
                                         # With this done, we can then proceed with further processing
                                         # exactly as in the STRONG_PACKAGE_CAST case.
                                         # We start by sorting both lists:
#
#                                        fun elem_eq ((s1, _), (s2, _)) = sy::eq        (s1, s2);
#                                        fun elem_gt ((s1, _), (s2, _)) = sy::symbol_gt (s1, s2);
#
#                                        constraining_elements = list_mergesort::sort  elem_gt  constraining_elements;
#                                        constrained_elements  = list_mergesort::sort  elem_gt  constrained_elements;
#
#
#                                        # We now merge the two sorted lists to produce the new
#                                        # constraining_elements list, favoring constraining
#                                        # over constrained elements whenever there is a choice:
#                                        #
#                                        constraining_elements
#                                            =
#                                            left_favoring_merge( constraining_elements, constrained_elements, [] )
#                                            where  
#                                                # "s1" == "symbol1", "e1" == "element1" etc:
#                                                #
#                                                fun left_favoring_merge (list1 as (e1 ! rest1), list2 as (e2 ! rest2), results)
#                                                        =>
#                                                        if   (elem_eq (e1, e2))   left_favoring_merge (rest1, rest2, e1 ! results);
#                                                        elif (elem_gt (e1, e2))   left_favoring_merge (list1, rest2, e2 ! results);
#                                                        else                      left_favoring_merge (rest1, list2, e1 ! results);
#                                                        fi;
#
#                                                    left_favoring_merge (        [], e2 ! rest2, results) => left_favoring_merge ([], rest2, e2 ! results);
#                                                    left_favoring_merge (e1 ! rest1,         [], results) => left_favoring_merge (rest1, [], e1 ! results);
#                                                    left_favoring_merge (        [],         [], results) => reverse results;
#                                                end;
#                                            end;

                                         # Reconstitute the constraining API with
                                         # the new elements and symbols lists:
                                         #      
                                         new_api =   API { api_elements => constraining_elements,
                                                           symbols  => map  #1  constraining_elements,
                                                           stamp,
                                                           name,
                                                           stub,
                                                           closed,
                                                           property_list,
                                                           contains_generic,
                                                           type_sharing,
                                                           package_sharing
                                                         };

                                         # Old API is still in symbol table,
                                         # so we need to override it:
                                         #
                                         symbolmapstack
                                             =
                                             case name
                                                 THE symbol => syx::bind (symbol, sxe::NAMED_API new_api, symbolmapstack);
                                                 NULL       => symbolmapstack;
                                             esac; 

                                         { old_debug_setting = *debugging;
                                           debugging := TRUE;
                                           if_debugging_show_api          ("maybe_extend_api_to_cover_package: extended api:    --type-package-language-g.pkg",        new_api,   symbolmapstack);
                                           debugging := old_debug_setting;
                                         };
                                                                                                                                # show_symbolmapstack ("--maybe_extend_api_to_cover_package: symbol table: ",                   symbolmapstack)
                                                                                                                                if_debugging_say "maybe_extend_api_to_cover_package.    --type-package-language-g.pkg\n";
                                         ( THE new_api,
                                           STRONG_PACKAGE_CAST,
                                           symbolmapstack
                                         );
                                    };

                                other => (constraining_api_or_null, package_cast, symbolmapstack);      # No change.
                            esac;
                        other         => (constraining_api_or_null, package_cast, symbolmapstack);      # No change.
                    esac;

                };


        ############################################################################
        #                                                                          #
        # The type_constrained_package function is used to                    #
        # perform api matching on package declarations with package casts.         #
        #                                                                          #
        # The "package_cast" argument  is used to indicate whether the             #
        # package cast is strong, weak or partial.                                 #
        #                                                                          #
        ############################################################################
        #
        fun type_constrained_package
            (
              constrained_package:              mld::Package,                   # Package to be constrained by api.
              package_cast:                     Package_Cast,                   # How to apply constraining API -- strong/weak/partial cast.
              constraining_api:                 mld::Api,                       # Api to constrain package.
              # 
              package_declaration:              ds::Declaration,
              package_expression:               mld::Package_Expression,
              module_stamp_or_null:             Null_Or( sta::Stamp ),
              debruijn_depth:                   di::Debruijn_Depth,
              typerstore:                       mld::Typerstore,
              inverse_path:                     ip::Inverse_Path,
              symbolmapstack:                   syx::Symbolmapstack,            # Combines both info from all .compiled files we depend on and info from raw-syntax being processed.
              #
              source_code_region:               lnd::Source_Code_Region,
              per_compile_stuff:                 trj::Per_Compile_Stuff
            )
            :
            ( ds::Declaration,
              mld::Package,
              mld::Package_Expression
            )
            = 
            {
                                                                                                                                if_debugging_say "type_constrained_package/TOP    -- type-package-language-g.pkg";
                                                                                                                                if *debugging
                                                                                                                                   case package_cast
                                                                                                                                       WEAK_PACKAGE_CAST => print "type_constrained_package: This is a WEAK cast.\n";
                                                                                                                                     STRONG_PACKAGE_CAST => print "type_constrained_package: This is a STRONG cast.\n";
                                                                                                                                    PARTIAL_PACKAGE_CAST => print "type_constrained_package: This is a PARTIAL cast.\n";
                                                                                                                                   esac;
                                                                                                                                fi;
                                                                                                                                if_debugging_show_package ("type_constrained_package/TOP: constrained_package:   --type-package-language-g.pkg", constrained_package, symbolmapstack);
                                                                                                                                if_debugging_show_api     ("type_constrained_package/TOP: constraining_api:    --type-package-language-g.pkg",    constraining_api,    symbolmapstack);
                                                                                                                                unparse_deep_declaration  ("type_constrained_package/TOP: unparsing package_declaration deep syntax:  --type-package-language-g.pkg", package_declaration, symbolmapstack);

                my  { result_declaration          => result_declaration1:           ds::Declaration,
                      result_package              => result_package1:               mld::Package,
                      coerced_package_expression  => result_package_expression1:    mld::Package_Expression
                    }
                    = 
                    am::thin_package                                                    # thin_package          def in    src/lib/compiler/front/typer/modules/api-match-g.pkg
                        {
                          constrained_package,                  # Check this package
                          constraining_api,                     # against this api.

                          module_stamp_or_null,
                          debruijn_depth,
                          package_expression,
                          typerstore,
                          inverse_path,
                          symbolmapstack,
                          source_code_region,
                          per_compile_stuff
                        };


                                                                                                                                if_debugging_say           "type_constrained_package: am::thin_package done   --type-package-language-g.pkg";
                                                                                                                                if_debugging_show_package ("type_constrained_package: result_package1:  --type-package-language-g.pkg", result_package1, symbolmapstack);
                                                                                                                                unparse_deep_declaration  ("type_constrained_package: unparsing result_declaration1 deep syntax:  --type-package-language-g.pkg", result_declaration1, symbolmapstack);
                                                                                                                                if *debugging
                                                                                                                                   case package_cast
                                                                                                                                       WEAK_PACKAGE_CAST => print "type_constrained_package: This is a WEAK cast.\n";
                                                                                                                                     STRONG_PACKAGE_CAST => print "type_constrained_package: This is a STRONG cast.\n";
                                                                                                                                    PARTIAL_PACKAGE_CAST => print "type_constrained_package: This is a PARTIAL cast.\n";
                                                                                                                                   esac;
                                                                                                                                fi;
                case package_cast
                    #
                    WEAK_PACKAGE_CAST
                        =>
                        ( ds::SEQUENTIAL_DECLARATIONS [package_declaration, result_declaration1],
                          result_package1,
                          result_package_expression1
                        );

                    STRONG_PACKAGE_CAST
                        =>
                        {    my  {  result_declaration => result_declaration2,
                                    result_package     => result_package2,
                                    result_expression  => result_expression2
                                 }
                                 = 
                                 am::cast_package                                                                       # cast_package          def in    src/lib/compiler/front/typer/modules/api-match-g.pkg
                                     {
                                       constrained_package =>  result_package1,
                                       constraining_api,

                                       package_expression =>  result_package_expression1, 

                                       debruijn_depth,
                                       inverse_path,
                                       symbolmapstack,


                                       typerstore,
                                       source_code_region,
                                       per_compile_stuff
                                     };

                             if_debugging_say           "type_constrained_package[STRONG_PACKAGE_CAST]: am::cast_package done   --type-package-language-g.pkg";
                             if_debugging_show_package ("type_constrained_package[STRONG_PACKAGE_CAST]: result_package2:  --type-package-language-g.pkg", result_package2, symbolmapstack);
                             unparse_deep_declaration  ("type_constrained_package[STRONG_PACKAGE_CAST]: unparsing result_declaration2 deep syntax: --type-package-language-g.pkg", result_declaration2, symbolmapstack);

                             ( ds::SEQUENTIAL_DECLARATIONS [ package_declaration, result_declaration1, result_declaration2 ],
                               result_package2,
                               result_expression2
                             );
                        };

# XXX BUGGO FIXME 2009-03-22 CrT: This is at the moment just a clone of the above case:
                    PARTIAL_PACKAGE_CAST
                        =>
                        {   my  { result_declaration => result_declaration2,
                                  result_package     => result_package2,
                                  result_expression  => result_expression2
                                }
                                = 
                                am::cast_package
                                    {
                                      constrained_package =>  result_package1,
                                      constraining_api,

                                      package_expression =>  result_package_expression1, 

                                      debruijn_depth,
                                      inverse_path,
                                      symbolmapstack,


                                      typerstore,
                                      source_code_region,
                                      per_compile_stuff
                                    };

                                                                                                                                if_debugging_say           "type_constrained_package[PARTIAL_PACKAGE_CAST]: am::cast_package done   --main/type-package-language-g.pkg";
                                                                                                                                if_debugging_show_package ("type_constrained_package[PARTIAL_PACKAGE_CAST]: result_package2:  --main/type-package-language-g.pkg", result_package2, symbolmapstack);
                                                                                                                                unparse_deep_declaration  ("type_constrained_package[PARTIAL_PACKAGE_CAST]: unparsing result_declaration2 deep syntax:  --main/type-package-language-g.pkg",
                                                                                                                                                                result_declaration2, symbolmapstack);
                            ( ds::SEQUENTIAL_DECLARATIONS [ package_declaration, result_declaration1, result_declaration2 ],
                              result_package2,
                              result_expression2
                            );
                        };
                esac;
            };



        # type_package: typecheck the raw package, without api constraint:
        # Several invariants: 
        #     Every package_expression
        #     is now typechecked into a quadruple
        #         ( deep_syntax_tree,
        #           resulting_package_expression,       # Gets folded into module_declarations result.
        #           macro expansion expressions,
        #           delta macro expansion dictionary
        #         )
        #     where the latter was collected while typechecking
        #     the current package expression.
        #
        #     The macro expansion dictionary delta is
        #     designed to deal with LET_IN_PACKAGE
        #     and LET_IN_GENERIC and to maintain the
        #     hidden typechecked_package dictionary context.
        #
        fun type_package
            (
              package_body_to_typecheck:       raw::Package_Expression,                         # package body to typecheck
              name:                            Null_Or( sy::Symbol ), 

              symbolmapstack:                   syx::Symbolmapstack,
              typerstore:                       mld::Typerstore,

              syntactic_typechecking_context:  trj::Syntactic_Typechecking_Context,
              stamppath_context:             spc::Context,   

              module_stamp_v:                  Null_Or( sta::Stamp ),  

              inverse_path:                    ip::Inverse_Path,
              source_code_region:              lnd::Source_Code_Region,      

              per_compile_stuff as { issue_highcode_codetemp=>make_var, make_fresh_stamp, error_fn, ... }: trj::Per_Compile_Stuff
            )
            :
            ( ds::Declaration,
              mld::Package,
              mld::Package_Expression,
              tro::Typerstore
            )
            =
            {   debruijn_depth
                    =
                    case syntactic_typechecking_context
                        #
                        trj::IN_GENERIC { debruijn_depth, ... }   =>  debruijn_depth;
                        _                                         =>  di::top;
                    esac;

                if_debugging_say ("type_package:  [type-package-language-g.pkg]" + pkg_name)
                where
                    pkg_name =  case name   THE n =>  sy::name n;
                                            NULL  =>  "<anonymous>";
                                esac;
                end;

                # type_package':
                #     ( raw::Package_Expression,
                #       Symbolmapstack,
                #       Typerstore,
                #       Source_Code_Region
                #     )
                #     ->
                #     ( ds::Declaration
                #       mld::Package
                #       mld::Package_Expression
                #       tro::Typerstore
                #     )
                #
                fun type_package'
                        (
                          raw::PACKAGE_DEFINITION declaration:  raw::Package_Expression,
                          symbolmapstack:                       syx::Symbolmapstack,
                          typerstore:                   mld::Typerstore,
                          source_code_region:                   lnd::Source_Code_Region
                        )
                        :
                        ( ds::Declaration,                      # result_declaration 
                          mld::Package,                         # result_package
                          mld::Package_Expression,              # result_package_expression
                          tro::Typerstore
                        )
                        =>
                        {   # We wind up here for vanilla package declarations.

                                                                                                                                if_debugging_say "type_package'[PACKAGE_DEFINITION]   [type-package-language-g.pkg]";
                            # We enter a new module path context
                            # whenever we enter a PACKAGE_DEFINITION:
                            #
                            stamppath_context'
                                =
                                spc::enter_open (
                                    stamppath_context,
                                    module_stamp_v
                                );

                            my  ( abstract_declaration:                 ds::Declaration,
                                  symbolmapstack':                      syx::Symbolmapstack,
                                  module_declaration:                   Module_Declaration,
                                  typerstore':                          Typerstore
                                )
                                = 
                                type_declaration'
                                  (
                                    declaration:                        raw::Declaration,
                                    symbolmapstack:                     syx::Symbolmapstack,
                                    typerstore,
                                    enter_package
                                    syntactic_typechecking_context,
                                    TRUE,                               #  toplevel 
                                    stamppath_context',
                                    inverse_path,
                                    source_code_region,
                                    per_compile_stuff
                                  );

                                                                                                                                if_debugging_say "typecheck[PACKAGE_DEFINITION]: type_declaration' done   --type-package-language-g.pkg";
                                                                                                                                if_debugging_say "type_package'[PACKAGE_DEFINITION]: calling extract_symbolmapstack_contents...  --type-package-language-g.pkg";

                            my  ( api_elements:                         List( (symbol::Symbol, mld::Api_Element ) ),
                                  typerstore'':                         mld::Typerstore,
                                  module_declarations:                  List( Module_Declaration ),
                                  symbolmapstack_entries:               List( symbolmapstack_entry::Symbolmapstack_Entry ),
                                  contains_generic:                     Bool
                                )
                                =
                                extract_symbolmapstack_contents (
                                    symbolmapstack',
                                    stamppath_context',
                                    syntactic_typechecking_context,
                                    per_compile_stuff
                                );

                                                                                                                                if_debugging_say "type_package'[PACKAGE_DEFINITION]: extract_symbolmapstack_contents done  [type-package-language-g.pkg]";

                            my  ( typerstore__local,
                                  module_declaration__local
                                )
                                =
                                case syntactic_typechecking_context

                                     trj::IN_GENERIC _
                                         => 
                                         ( tro::mark (make_fresh_stamp, tro::atop (typerstore'', typerstore')), 
                                           module_declaration_sequence (module_declaration ! module_declarations)
                                         );

                                    _ => (typerstore'', module_declaration);
                                esac;

                            package_expression
                                =
                                PACKAGE {
                                    stamp => mld::MAKE_STAMP,

                                    module_declaration
                                        =>
                                        module_declaration__local
                                };

                            result_package
                                = 
                                mld::A_PACKAGE {

                                  an_api,
                                  typechecked_package,

                                  varhome,
                                  inlining_data
                                }
                                where

                                    symbols =  map  #1  api_elements;

                                    an_api
                                        = 
                                        mld::API {

                                          stamp         =>  make_fresh_stamp (),
                                          property_list =>  property_list::make_property_list (),

                                          api_elements,
                                          symbols,

                                          name          =>  NULL,
                                          closed        =>  FALSE,

                                          type_sharing  =>  NIL,
                                          stub          =>  NULL,

                                          contains_generic,
                                          package_sharing => NIL
                                        };

                                    typechecked_package
                                        =
                                        { stamp         => make_fresh_stamp(),      #  Generate package stamp 
                                          stub          => NULL,

                                          property_list => property_list::make_property_list (),
                                          inverse_path,

                                          typerstore
                                              =>
                                              tro::mark (
                                                  make_fresh_stamp,
                                                  tro::atop (
                                                      typerstore__local,
                                                      typerstore
                                                  )
                                              )
                                        };

                                    varhome =   vh::named_varhome (temp_package_id, make_var);

                                    inlining_data
                                        =
                                        id::LIST (map mj::extract_inlining_data  symbolmapstack_entries);
                                end;

                            result_declaration
                                = 
                                ds::PACKAGE_DECLARATIONS
                                    [
                                      ds::NAMED_PACKAGE
                                        {
                                          name_symbol =>  temp_package_id,
                                          a_package   =>  result_package,
                                          definition
                                              =>                                        # body
                                              ds::PACKAGE_LET {
                                                  declaration => abstract_declaration,
                                                  expression  => ds::PACKAGE_DEFINITION  symbolmapstack_entries
                                              }
                                        }
                                    ];
                                                                                                                                if_debugging_say "type_package'[PACKAGE_DEFINITION]   [type-package-language-g.pkg]";
                            ( result_declaration:               ds::Declaration,
                              result_package:                   mld::Package,
                              package_expression:               mld::Package_Expression,
                              tro::empty
                            );
                        };

                    type_package'
                        ( raw::CALL_OF_GENERIC (symbol_path, args),
                          symbolmapstack,
                          typerstore,
                          source_code_region
                        )
                        =>
                        {   package_expression'
                                =
                                raw::LET_IN_PACKAGE
                                    (
                                      raw::PACKAGE_DECLARATIONS
                                          [
                                            raw::NAMED_PACKAGE
                                              {
                                                name_symbol => return_id,
                                                constraint  => raw::NO_PACKAGE_CAST,
                                                definition  => raw::INTERNAL_CALL_OF_GENERIC (symbol_path, args),
                                                kind        => raw::PLAIN_PACKAGE
                                              }
                                          ],

                                      raw::PACKAGE_BY_NAME ( [ return_id, result_id ] )
                                    );

                            type_package' ( package_expression',
                                        symbolmapstack,
                                        typerstore,
                                        source_code_region
                                      );
                        };

                    type_package'
                        (
                          raw::INTERNAL_CALL_OF_GENERIC (symbol_path, [ (arg, b) ] ),
                          symbolmapstack,
                          typerstore,
                          source_code_region
                        )
                        =>
                        {                                                                                                       if_debugging_say "type_package'[CALL_OF_GENERIC-one]   [type-package-language-g.pkg]";
                            a_generic
                                =
                                fst::find_generic_via_symbol_path (symbolmapstack,   syp::SYMBOL_PATH symbol_path,   error_fn  source_code_region);

                                                                                                                                if_debugging_say "type_package'[CALL_OF_GENERIC-one]: generic lookup done  type-package-language-g.pkg";
                                                                                                                                show_generic   ("type_package'[CALL_OF_GENERIC]: generic ", a_generic, symbolmapstack);

                            rstamp =   make_fresh_stamp ();                                                                     #  module_stamp for the uncoerced argument

                            my  ( arg_declaration:              ds::Declaration,
                                  arg_package:                  mld::Package,
                                  arg_expression:               mld::Package_Expression,
                                  arg_dee
                                )
                                = 
                                type_package (
                                    arg,                                # package body to typecheck
                                    NULL,                               # name_or_null
                                    symbolmapstack,
                                    typerstore,
                                    syntactic_typechecking_context,
                                    stamppath_context,
                                    THE rstamp,
                                    ip::INVERSE_PATH [],
                                    source_code_region,
                                    per_compile_stuff
                                );
                                                                                                                                if_debugging_say           "type_package'[CALL_OF_GENERIC-one]: typecheck arg done  [type-package-language-g.pkg]";
                                                                                                                                if_debugging_show_package ("type_package'[CALL_OF_GENERIC-one]: arg package:  [type-package-language-g.pkg]", arg_package, symbolmapstack);
                            case (a_generic, arg_package)
                                #
                                 (   (mld::ERRONEOUS_GENERIC, _)
                                 | (_, mld::ERRONEOUS_PACKAGE)
                                 )
                                     =>
                                     {                                                                                          if_debugging_say "type_package'[CALL_OF_GENERIC-one]: error generic or arg  [type-package-language-g.pkg]";
                                         ( ds::SEQUENTIAL_DECLARATIONS [],
                                           mld::ERRONEOUS_PACKAGE,
                                           mld::CONSTANT_PACKAGE (mld::bogus_typechecked_package),
                                           tro::empty
                                         );
                                     };

                                 ( mld::GENERIC   { typechecked_generic, ... },
                                   mld::A_PACKAGE { typechecked_package =>  arg_typechecked_package,     ... }
                                 )
                                     =>
                                     {    result_dee
                                             =
                                             tro::mark (make_fresh_stamp, tro::set (arg_dee, rstamp, mld::PACKAGE_ENTRY arg_typechecked_package));

                                                  #  the argument package should be bound to rstamp 

                                          generic_expression
                                              = 
                                              case (spc::find_stamppath_for_generic
                                                       (
                                                         stamppath_context,
                                                         mj::genericstamp_of  a_generic
                                                   )   )

                                                   THE stamppath =>  VARIABLE_GENERIC stamppath;
                                                   NULL            =>  CONSTANT_GENERIC typechecked_generic;
                                              esac;

                                          my { result_declaration, result_package, result_expression }
                                              = 
                                              am::apply_generic
                                                {
                                                  module_stamp_or_null
                                                      =>
                                                      THE rstamp,

                                                  stamppath_context
                                                      =>
                                                      spc::enter_open
                                                          ( stamppath_context,
                                                            module_stamp_v
                                                          ),

                                                  a_generic,
                                                  generic_expression,

                                                  arg_package,
                                                  arg_expression,

                                                  debruijn_depth,
                                                  symbolmapstack,

                                                  inverse_path,
                                                  source_code_region,
                                                  per_compile_stuff
                                                };

                                                                                                                                if_debugging_say          "type_package'[CALL_OF_GENERIC-one]: apply_generic done   [type-package-language-g.pkg]";
                                                                                                                                if_debugging_show_package("type_package'[CALL_OF_GENERIC-one]: result: [type-package-language-g.pkg]", result_package, symbolmapstack);
                                                                                                                                if_debugging_say          "type_package'[CALL_OF_GENERIC-one]  [type-package-language-g.pkg]";

                                          ( ds::SEQUENTIAL_DECLARATIONS [ arg_declaration, result_declaration ]:                ds::Declaration,
                                            result_package:                                                                     mld::Package,
                                            result_expression:                                                                  mld::Package_Expression,
                                            result_dee
                                          );
                                      };

                                _ => bug "INTERNAL_CALL_OF_GENERIC: one arg";
                            esac;

                        };       #  INTERNAL_CALL_OF_GENERIC - one arg 

                    type_package'
                        ( raw::INTERNAL_CALL_OF_GENERIC (symbol_path, arg ! arglist),
                          symbolmapstack,
                          typerstore,
                          source_code_region
                        )
                        =>
                        {                                                                                                       if_debugging_say "type_package':[CALL_OF_GENERIC-many]  [type-package-language-g.pkg]";
                            #
                            package_expression'
                                =
                                raw::LET_IN_PACKAGE
                                    (
                                      raw::PACKAGE_DECLARATIONS
                                          [
                                            raw::NAMED_PACKAGE
                                                {
                                                  name_symbol =>  hidden_id,
                                                  constraint  =>  raw::NO_PACKAGE_CAST,
                                                  definition  =>  raw::INTERNAL_CALL_OF_GENERIC (symbol_path, [arg]),
                                                  kind        =>  raw::PLAIN_PACKAGE
                                                }
                                          ],

                                      raw::INTERNAL_CALL_OF_GENERIC ( [ hidden_id, generic_id ], arglist)
                                    );

                            type_package' (
                                package_expression',
                                symbolmapstack,
                                typerstore,
                                source_code_region
                            );
                        };                            #  INTERNAL_CALL_OF_GENERIC - multiple args 

                    type_package' (raw::INTERNAL_CALL_OF_GENERIC (symbol_path, []), symbolmapstack, typerstore, source_code_region)
                        =>
                        bug "type_package::INTERNAL_CALL_OF_GENERIC -- empty arg list";

                    type_package'
                        ( raw::PACKAGE_BY_NAME path,
                          symbolmapstack,
                          typerstore,
                          source_code_region
                        )
                        =>
                        {                                                                                                       if_debugging_say "type_package'[PACKAGE_BY_NAME]  [type-package-language-g.pkg]";
                            #
                            a_package = fst::find_package_via_symbol_path (symbolmapstack, syp::SYMBOL_PATH path,   error_fn  source_code_region);

                                                                                                                                #  if_debugging_show_package("type_package'[PACKAGE_BY_NAME]: package:  [type-package-language-g.pkg]", a_package, symbolmapstack);

                            typechecked_package
                                = 
                                case a_package
                                     A_PACKAGE { typechecked_package, ... } =>  typechecked_package;
                                     _                                     =>  mld::bogus_typechecked_package;                  #  error recovery
                                esac;

                            result_expression
                                =
                                case a_package
                                  
                                     A_PACKAGE _
                                         =>
                                         #  if_debugging_say "type_package'[PACKAGE_BY_NAME]: result_expression/A_PACKAGE   [type-package-language-g.pkg]"; 
                                         #
                                         case (spc::find_stamppath_for_package
                                                   (
                                                     stamppath_context,
                                                     mj::packagestamp_of  a_package
                                              )    )
                                           
                                              THE stamppath =>   mld::VARIABLE_PACKAGE stamppath;
                                              NULL            =>   mld::CONSTANT_PACKAGE typechecked_package;
                                         esac;

                                    _ => mld::CONSTANT_PACKAGE mld::bogus_typechecked_package;                                  #  error recovery
                                esac;

                                                                                                                                #  if_debugging_say "type_package'[PACKAGE_BY_NAME]  [type-package-language-g.pkg]"; 

                            (   ds::SEQUENTIAL_DECLARATIONS []:         ds::Declaration,
                                a_package:                                      mld::Package,
                                result_expression:                              mld::Package_Expression,
                                tro::empty
                            );
                        };

                    type_package'
                        ( raw::LET_IN_PACKAGE (declaration, a_package),
                          symbolmapstack,
                          typerstore,
                          source_code_region
                        )
                        =>
                        {                                                                                                       if_debugging_say "type_package'[LET_IN_PACKAGE]   [type-package-language-g.pkg]";
                            my  ( local_abstract_declaration,
                                  symbolmapstack',
                                  local_module_declaration,
                                  typerstore'
                                )
                                = 
                                type_declaration' (
                                    declaration,
                                    symbolmapstack,
                                    typerstore,
                                    syntactic_typechecking_context,
                                    TRUE,                               #  toplevel 
                                    stamppath_context,
                                    inverse_path,
                                    source_code_region,
                                    per_compile_stuff
                                );

                            # top = TRUE: Don't allow nongeneralized type variables
                            # in local declarations because of bug 905/952.  This is
                            # stricter than necessary.  Could allow top = FALSE
                            # if the body package contains no generics.  To make the
                            # condition more precise, have to synthesize a boolean
                            # attribute indicating presence of generics [dbm]


                            # DAVE? what context to use for the local declarations?
                            # perhaps should null bind_context as for generic body?
                            # perhaps it doesn't matter because of relativization
                            # and the fact that local typerstore can't be referred
                            # to from outside.   XXX BUGGO FIXME

                                                                                                                                if_debugging_say "type_package'[LET_IN_PACKAGE]: local type_declaration' done   [type-package-language-g.pkg]";
                            my  ( body_abstract_declaration:            ds::Declaration,
                                  body_package:                         mld::Package,
                                  body_expression:                      mld::Package_Expression,
                                  body_dee
                                )
                                = 
                                type_package' (
                                    a_package,
                                    syx::atop (symbolmapstack', symbolmapstack),
                                    tro::atop (typerstore', typerstore),
                                    source_code_region
                                );

                            result_declaration = ds::SEQUENTIAL_DECLARATIONS [local_abstract_declaration, body_abstract_declaration];
                            result_expression  = mld::PACKAGE_LET { declaration => local_module_declaration, expression => body_expression };

                                                                                                                                if_debugging_say "type_package'[LET_IN_PACKAGE]: typecheck body pkg done   [type-package-language-g.pkg]";
                            ( result_declaration:               ds::Declaration,
                              body_package:                     mld::Package,
                              result_expression:                mld::Package_Expression,
                              tro::mark
                                ( make_fresh_stamp,
                                  tro::atop_sp (body_dee, typerstore')
                                )
                            );
                        };

                    type_package'
                        ( raw::PACKAGE_CAST (constrained_package, api_constraint),
                          symbolmapstack,
                          typerstore,
                          source_code_region
                        )
                        =>
                        {   if_debugging_say "type_package'[PACKAGE_CAST]: TOP  [type-package-language-g.pkg]";
                            #
                            my  ( module_stamp_v,
                                  module_stamp_or_null
                                )
                                = 
                                case api_constraint 
                                    #
                                    raw::NO_PACKAGE_CAST
                                        =>
                                        (module_stamp_v, NULL);

                                    _   => {   nentv = THE (make_fresh_stamp());

                                               (nentv, nentv);
                                           };
                                esac;
                                                                                                                                if_debugging_say "type_package'[PACKAGE_CAST]: above call to type_package  [type-package-language-g.pkg]";
                            #  Typecheck the constrained package by itself: 
                            #
                            my  ( abstract_pkg_declaration:             ds::Declaration,
                                  a_package:                            mld::Package,
                                  expression:                           mld::Package_Expression,
                                  typerstore_additions
                                )
                                = 
                                type_package (
                                    constrained_package,                # package body to typecheck
                                    NULL,                               # name_or_null.
                                    symbolmapstack,
                                    typerstore,
                                    syntactic_typechecking_context,
                                    stamppath_context,
                                    module_stamp_v,
                                    inverse_path,
                                    source_code_region,
                                    per_compile_stuff
                                );

                                                                                                                                if_debugging_say "type_package'[PACKAGE_CAST]: above call to type_api  [type-package-language-g.pkg]";
                            #  Typecheck the constraining api by itself: 
                            #
                            my  ( constraining_api_or_null,
                                  package_cast
                                )
                                = 
                                {   fun type_api  api_expression
                                        = 
                                        ta::type_api {

                                            api_expression,
                                            symbolmapstack,

                                            name_or_null  =>  NULL,

                                            typerstore,
                                            stamppath_context,
                                            source_code_region,
                                            per_compile_stuff
                                        };
                                                                                                                                if_debugging_say "type_package'[PACKAGE_CAST]: above possible call to type_api  [type-package-language-g.pkg]";
                                    my  ( constraining_api_or_null:    Null_Or( mld::Api ),
                                          package_cast:                Package_Cast
                                        )
                                        =
                                        case api_constraint 
                                            raw::WEAK_PACKAGE_CAST     an_api =>   (THE (type_api an_api),     WEAK_PACKAGE_CAST );
                                            raw::PARTIAL_PACKAGE_CAST  an_api =>   (THE (type_api an_api),  PARTIAL_PACKAGE_CAST );
                                            raw::STRONG_PACKAGE_CAST   an_api =>   (THE (type_api an_api),   STRONG_PACKAGE_CAST );
                                            _                                 =>   (NULL,                      WEAK_PACKAGE_CAST );
                                        esac;
                                                                                                                                if_debugging_say "type_package'[PACKAGE_CAST]: below possible call to type_api  [type-package-language-g.pkg]";
                                    ( constraining_api_or_null,
                                      package_cast
                                    );
                                };
                                                                                                                                if *debugging
                                                                                                                                   case package_cast
                                                                                                                                       WEAK_PACKAGE_CAST => print "--type_package'[PACKAGE_CAST] above hack: This is a WEAK cast.\n";
                                                                                                                                     STRONG_PACKAGE_CAST => print "--type_package'[PACKAGE_CAST] above hack: This is a STRONG cast.\n";
                                                                                                                                    PARTIAL_PACKAGE_CAST => print "--type_package'[PACKAGE_CAST] above hack: This is a PARTIAL cast.\n";
                                                                                                                                   esac;
                                                                                                                                fi;
                            # If this is a PARTIAL_PACKAGE_CAST,
                            # hack the constraining api to reduce
                            # it to the STRONG_PACKAGE_CAST case:
                            #
                            my (constraining_api_or_null, package_cast, symbolmapstack)
                                =
                                maybe_extend_api_to_cover_package (constraining_api_or_null, package_cast, a_package, symbolmapstack);

                                                                                                                                if *debugging
                                                                                                                                   case package_cast
                                                                                                                                       WEAK_PACKAGE_CAST => print "--type_package'[PACKAGE_CAST] below hack: This is a WEAK cast.\n";
                                                                                                                                     STRONG_PACKAGE_CAST => print "--type_package'[PACKAGE_CAST] below hack: This is a STRONG cast.\n";
                                                                                                                                    PARTIAL_PACKAGE_CAST => print "--type_package'[PACKAGE_CAST] below hack: This is a PARTIAL cast.\n";
                                                                                                                                   esac;
                                                                                                                                fi;

                                                                                                                                if_debugging_say          "type_package'[PACKAGE_CAST]: below call to type_package  [type-package-language-g.pkg]";
                                                                                                                                unparse_deep_declaration ("type_package'[PACKAGE_CAST]: unparsing abtract_pkg_declaration deep syntax: [type-package-language-g.pkg]", abstract_pkg_declaration, symbolmapstack);
                                                                                                                                if_debugging_show_package("type_package'[PACKAGE_CAST]: a_package:  [type-package-language-g.pkg]", a_package, symbolmapstack);

                            result_dee
                                = 
                                case api_constraint 
                                    #
                                    raw::NO_PACKAGE_CAST
                                        =>
                                        typerstore_additions;

                                   _ => case module_stamp_or_null
                                            #
                                            THE tmpev
                                                =>
                                                {   typechecked_package
                                                        =
                                                        case a_package
                                                            #
                                                            mld::A_PACKAGE { typechecked_package, ... }
                                                                =>
                                                                typechecked_package;

                                                            _ => mld::bogus_typechecked_package;
                                                        esac;

                                                    tro::set (typerstore_additions, tmpev, mld::PACKAGE_ENTRY typechecked_package);
                                                };

                                             _ => bug "unexpected api_constraint while typechecking constrained package";
                                        esac;
                                esac;

                                                                                                                                if_debugging_say "type_package'[PACKAGE_CAST]: above possible call to type_constrained_package  [type-package-language-g.pkg]";

                            # Now typecheck the constrained package
                            # against the constraining api:
                            #
                            my  ( result_declaration:           ds::Declaration,
                                  result_package:               mld::Package,
                                  result_expression:            mld::Package_Expression
                                )
                                = 
                                case constraining_api_or_null
                                    #
                                    NULL => {   if (package_cast != WEAK_PACKAGE_CAST)

                                                    error_fn
                                                        source_code_region
                                                        err::ERROR
                                                        "missing api in abstraction declaration"
                                                         err::null_error_body;
                                                fi;

                                                (abstract_pkg_declaration, a_package, expression);
                                            };

                                    THE constraining_api
                                        => 
                                        type_constrained_package (

                                            a_package:                          mld::Package,                   # Package to be constrained by api.
                                            package_cast:                       Package_Cast,                   # How to apply API -- strong/weak/partial cast.
                                            constraining_api:                   mld::Api,                               # Api to constrain package.

                                            abstract_pkg_declaration:           ds::Declaration,
                                            expression:                         mld::Package_Expression,

                                            module_stamp_or_null,
                                            debruijn_depth,
                                            typerstore,
                                            inverse_path,
                                            symbolmapstack,
                                            source_code_region,
                                            per_compile_stuff
                                        );
                                esac;
                                                                                                                                if_debugging_say          "type_package'[PACKAGE_CAST]: below possible call to type_constrained_package -- DONE  [type-package-language-g.pkg]";
                                                                                                                                unparse_deep_declaration ("type_package'[PACKAGE_CAST]: unparsing result_declaration deep syntax:  [type-package-language-g.pkg]", result_declaration, symbolmapstack);
                                                                                                                                if_debugging_show_package("type_package'[PACKAGE_CAST]: package:  [type-package-language-g.pkg]", result_package, symbolmapstack);
                            ( result_declaration:               ds::Declaration,
                              result_package:                   mld::Package,
                              result_expression:                mld::Package_Expression,
                              result_dee
                            );
                        };

                    type_package' (
                        raw::SOURCE_CODE_REGION_FOR_PACKAGE (
                            package_expression',
                            source_code_region'
                        ),
                        symbolmapstack,
                        typerstore,
                        source_code_region
                    )
                        => 
                        {   my  ( result_declaration:           ds::Declaration,
                                  a_package:                    mld::Package,
                                  result_expression:            mld::Package_Expression,
                                  result_dee
                                )
                                = 
                                type_package' (
                                    package_expression',
                                    symbolmapstack,
                                    typerstore,
                                    source_code_region'
                                );

                            ( ds::SOURCE_CODE_REGION_FOR_DECLARATION (result_declaration, source_code_region'):         ds::Declaration,
                              a_package:                                                                                        mld::Package,
                              result_expression:                                                                                mld::Package_Expression,
                              result_dee
                            );
                        };
                end;                            # fun type_package'

                my  ( result_declaration:               ds::Declaration,
                      result_package:                   mld::Package,
                      result_expression:                mld::Package_Expression,
                      result_dee
                    )
                    =
                    type_package' (
                        package_body_to_typecheck:       raw::Package_Expression,
                        symbolmapstack:                  syx::Symbolmapstack,
                        typerstore:              mld::Typerstore,
                        source_code_region:              lnd::Source_Code_Region
                    );

                if_debugging_say "type_package   [type-package-language-g.pkg]";


                ( result_declaration:           ds::Declaration,
                  result_package:               mld::Package,
                  result_expression:            mld::Package_Expression,
                  result_dee
                );
            }                           #  function type_package 




        #  type_generic: Typecheck a generic, possibly with api constraint: 
        #
        also
        fun type_generic (

               generic_expression: raw::Generic_Expression, 

               curried:                                 Bool,
               name:                                    sy::Symbol,   
               symbolmapstack:                          syx::Symbolmapstack,

               typerstore:                      mld::Typerstore,
               syntactic_typechecking_context:          trj::Syntactic_Typechecking_Context,
               stamppath_context: spc::Context,

               inverse_path:                            ip::Inverse_Path,
               source_code_region:                      lnd::Source_Code_Region,

               per_compile_stuff as { issue_highcode_codetemp => make_var, make_fresh_stamp, error_fn, ... }:   trj::Per_Compile_Stuff
            )
            :
            ( ds::Declaration,
              mld::Generic_Expression,
              mld::Generic,
              tro::Typerstore
            )
            =
            {   debruijn_depth
                    =
                    case syntactic_typechecking_context
                        #
                        trj::IN_GENERIC { debruijn_depth, ... } =>   debruijn_depth;
                        _                                       =>   di::top;
                    esac;
                                                                                                                                if_debugging_say ("type_generic: [type-package-language-g.pkg] " + (sy::name name));
                case generic_expression
                    #             
                    raw::GENERIC_BY_NAME (symbol_path, constraint_expression)
                        =>
                        {   a_generic = fst::find_generic_via_symbol_path (symbolmapstack, syp::SYMBOL_PATH symbol_path,  error_fn  source_code_region);
                            #
                            case a_generic
                                #
                                ERRONEOUS_GENERIC
                                    =>
                                    ( ds::SEQUENTIAL_DECLARATIONS [],
                                      CONSTANT_GENERIC (mld::bogus_typechecked_generic),
                                      a_generic,
                                      tro::empty
                                    );

                                _ =>
                                    {   uncoerced_expression
                                            = 
                                            case (spc::find_stamppath_for_generic  (stamppath_context,  mj::genericstamp_of  a_generic))
                                                #
                                                THE  stamppath
                                                    =>
                                                    VARIABLE_GENERIC  stamppath;

                                                NULL =>  {   typechecked_package
                                                                 =
                                                                 case a_generic
                                                                     #
                                                                     GENERIC ft =>   ft.typechecked_generic;
                                                                     _          =>   mld::bogus_typechecked_generic;
                                                                 esac;

                                                             CONSTANT_GENERIC typechecked_package;
                                                         };
                                            esac;


                                        case constraint_expression
                                            #
                                            raw::NO_PACKAGE_CAST
                                                =>
                                                ( ds::SEQUENTIAL_DECLARATIONS [],
                                                  uncoerced_expression,
                                                  a_generic,
                                                  tro::empty
                                                );

                                            raw::WEAK_PACKAGE_CAST raw_generic_api
                                                =>
                                                {   name_or_null = THE (anonymous_generic_api_id);
                                                    #
                                                    a_generic_api
                                                        = 
                                                        ta::type_generic_api {

                                                            generic_api_expression => raw_generic_api,

                                                            name_or_null,
                                                            symbolmapstack,

                                                            typerstore,
                                                            stamppath_context,

                                                            source_code_region,
                                                            per_compile_stuff
                                                        };

                                                    my { result_declaration, result_generic, result_expression }
                                                        =
                                                        am::match_generic
                                                            {
                                                              an_api             =>  a_generic_api,
                                                              generic_expression =>  uncoerced_expression,

                                                              a_generic,
                                                              debruijn_depth,

                                                              typerstore,
                                                              inverse_path,

                                                              symbolmapstack,
                                                              source_code_region,
                                                              per_compile_stuff
                                                            };

                                                    ( result_declaration,
                                                      result_expression,
                                                      result_generic,
                                                      tro::empty
                                                    );
                                                };

                                            raw::PARTIAL_PACKAGE_CAST raw_generic_api
                                                => 
                                                bug "'partial' generic constraints not implemented";   #  XXX BUGGO FIXME 

                                            raw::STRONG_PACKAGE_CAST raw_generic_api
                                                => 
                                                bug "Opaque generic constraints not implemented";   #  XXX BUGGO FIXME 
                                        esac;
                                    };
                            esac;
                        };

                    raw::LET_IN_GENERIC (declaration, a_generic)
                        =>
                        {                                                                                                       if_debugging_say "typecheck[LET_IN_GENERIC]  [type-package-language-g.pkg]";
                            my  ( local_abstract_declaration,
                                  symbolmapstack',
                                  local_module_declaration,
                                  typerstore'
                                )
                                = 
                                type_declaration' (
                                    declaration,
                                    symbolmapstack,
                                    typerstore,
                                    syntactic_typechecking_context,
                                    TRUE,                               #  top 
                                    stamppath_context,
                                    inverse_path,
                                    source_code_region,
                                    per_compile_stuff
                                );

                             # top = TRUE: don't allow nongeneralized type variables
                             # in local declarations because of bug 905/952 [dbm]
                                                                                                                                if_debugging_say "typecheck[LET_IN_GENERIC]: local type_declaration' done  [type-package-language-g.pkg]";
                            my  ( body_abstract_declaration,
                                  body_expression,
                                  body_g,
                                  body_dee
                                )
                                = 
                                type_generic
                                  ( a_generic,
                                    FALSE,                                     #  Curried 
                                    name,
                                    syx::atop (symbolmapstack', symbolmapstack),
                                    tro::atop (typerstore', typerstore),
                                    syntactic_typechecking_context,
                                    stamppath_context,
                                    inverse_path,
                                    source_code_region,
                                    per_compile_stuff
                                  );

                            result_deep_syntax_tree     =   ds::SEQUENTIAL_DECLARATIONS [local_abstract_declaration, body_abstract_declaration];

                            result_expression           =   mld::LET_GENERIC (local_module_declaration, body_expression);

                            result_typerstore  =   tro::mark (make_fresh_stamp, tro::atop_sp (body_dee, typerstore'));

                            ( result_deep_syntax_tree,
                              result_expression,
                              body_g,
                              result_typerstore
                            );
                        };

                    raw::CONSTRAINED_CALL_OF_GENERIC (symbol_path, arglist, constraint)
                        =>
                        {   generic_expression'
                                =
                                raw::LET_IN_GENERIC (

                                    raw::PACKAGE_DECLARATIONS [

                                        raw::NAMED_PACKAGE {

                                           name_symbol => hidden_id,
                                           constraint  => raw::NO_PACKAGE_CAST,
                                           definition  => raw::INTERNAL_CALL_OF_GENERIC (symbol_path, arglist),
                                           kind        => raw::PLAIN_PACKAGE
                                        }
                                    ],

                                    raw::GENERIC_BY_NAME (
                                        [ hidden_id, generic_id ],
                                        constraint
                                    )
                                );

                            type_generic
                              ( generic_expression',
                                FALSE,
                                name,
                                symbolmapstack,
                                typerstore,
                                syntactic_typechecking_context,
                                stamppath_context,
                                inverse_path,
                                source_code_region,
                                per_compile_stuff
                              );
                        };

                    raw::GENERIC_DEFINITION { parameters => [ (parameter_name_or_null, param_sig_expression) ], body, constraint }
                        =>
                        {   if_debugging_say "type_generic[GENERIC_DEFINITION]  [type-package-language-g.pkg]";
                            #
                            body = if curried
                                       body;
                                   else
                                       raw::PACKAGE_DEFINITION (
                                           raw::PACKAGE_DECLARATIONS [
                                               raw::NAMED_PACKAGE {
                                                   name_symbol => result_id,
                                                   definition  => body,
                                                   constraint,
                                                   kind        => raw::PLAIN_PACKAGE
                                               }
                                           ]
                                       );
                                   fi;

                            constraint
                                =
                                if curried   constraint;
                                else         raw::NO_PACKAGE_CAST;
                                fi;

                            my (flex, debruijn_depth)
                                =
                                case syntactic_typechecking_context
                                    #
                                    trj::IN_GENERIC { flex, debruijn_depth }
                                        =>
                                        (flex, debruijn_depth); 

                                    _   =>                                      # Entering generic for first time.
                                        {   base = make_fresh_stamp();
                                            #
                                            fun h s
                                                =
                                                case (stamp::compare (base, s))
                                                    LESS =>  TRUE;
                                                    _    =>  FALSE;
                                                esac;


                                            (h, di::top);
                                        };
                                esac;

                            parameter_name
                                =
                                case parameter_name_or_null
                                    THE n =>  n;
                                    NULL  =>  param_id;
                                esac;

                            param_typechecked_package_variable
                                =
                                make_fresh_stamp ();
                                                                                                                                if_debugging_say (   "type_generic[GENERIC_DEFINITION]: param_macro_expansion_variable = "
                                                                                                                                           +   mp::module_stamp_to_string param_typechecked_package_variable
                                                                                                                                           +  " [type-package-language-g.pkg]"
                                                                                                                                           );
                            param_sig
                                = 
                                ta::type_api {

                                    api_expression => param_sig_expression,
                                    name_or_null  => NULL,

                                    symbolmapstack,
                                    typerstore,
                                    stamppath_context,

                                    source_code_region,
                                    per_compile_stuff
                                };
                                                                                                                                if_debugging_say "type_generic[GENERIC_DEFINITION]: param_sig defined  [type-package-language-g.pkg]";
                            case param_sig
                                #
                                ERRONEOUS_API => raise exception err::COMPILE_ERROR;   #  Bail out -- not attempting to recover 

                                _ => ();
                            esac;

                            #  Now know that param_sig is defined. 
                            # This creates new stamps, but we don't bother to update the
                            # epcontext, we do that later through map_paths:
                            #
                            my  { typechecked_package    =>  param_typechecked_package,
                                  typepaths =>  param_tps
                                }
                                =
                                ins::do_generic_parameter_api {

                                    an_api       => param_sig,

                                    inverse_path => ip::INVERSE_PATH (   case parameter_name_or_null
                                                                             NULL => [];
                                                                             _    => [parameter_name];
                                                                         esac
                                                                  ),
                                    typerstore,
                                    source_code_region,
                                    debruijn_depth,
                                    per_compile_stuff
                                };

                            parameter_package
                                = 
                                {   param_dacc = vh::named_varhome (parameter_name, make_var);
                                    #
                                    mld::A_PACKAGE {
                                        an_api             => param_sig,
                                        typechecked_package => param_typechecked_package, 

                                        varhome             => param_dacc,                      # "dacc" is probably "dynamic access"
                                        inlining_data      => id::NIL
                                    };
                                };
                                                                                                                                if_debugging_say           "type_generic[GENERIC_DEFINITION]: parameter macro expanded  [type-package-language-g.pkg]";
                                                                                                                                if_debugging_show_package ("type_generic[GENERIC_DEFINITION]: [type-package-language-g.pkg]  parameter_package: ", parameter_package, symbolmapstack);
                            typerstore'
                                = 
                                tro::mark (
                                    make_fresh_stamp,
                                    tro::set (
                                        typerstore,
                                        param_typechecked_package_variable,
                                        mld::PACKAGE_ENTRY param_typechecked_package
                                    )
                                );
                                                                                                                                if_debugging_say "type_generic[GENERIC_DEFINITION]: parameter tro::set  [type-package-language-g.pkg]";
                            symbolmapstack'
                                =
                                case parameter_name_or_null
                                    #
                                    NULL  =>  mj::include_package (symbolmapstack, parameter_package);

                                    THE _ =>  syx::bind (parameter_name, sxe::NAMED_PACKAGE parameter_package, symbolmapstack);
                                esac;
                                                                                                                                if_debugging_say "type_generic[GENERIC_DEFINITION]: parameter bound/opened  [type-package-language-g.pkg]";
                            stamppath_context'
                                =
                                spc::enter_closed stamppath_context;

                            #  Fill in path_dictionary with paths for elements of parameter_package: 
                            #
                            map_paths (spc::enter_open (stamppath_context', THE param_typechecked_package_variable), parameter_package, flex);

                            spc::bind_stamppath
                              (
                                stamppath_context',
                                mj::packagestamp_of  parameter_package,
                                param_typechecked_package_variable
                              );
                                                                                                                                if_debugging_say "type_generic[GENERIC_DEFINITION]: stamppath_context initialized   [type-package-language-g.pkg]";
                            # Must typecheck result api before the body is typechecked
                            # so that stamppath_context' is not changed:
                            #
                            my  ( module_stamp_v,
                                  constraining_api,
                                  constraining_api_op
                                )
                                =
                                {   fun type_api x
                                        =
                                        ta::type_api {

                                            api_expression => x,
                                            name_or_null  => NULL,

                                            symbolmapstack                    => symbolmapstack', 
                                            typerstore             =>  typerstore',
                                            stamppath_context =>  stamppath_context', 

                                            source_code_region,
                                            per_compile_stuff
                                        };

                                    case constraint
                                        #
                                        raw::NO_PACKAGE_CAST             =>   (NULL,                     NULL,                          WEAK_PACKAGE_CAST);
                                        raw::WEAK_PACKAGE_CAST    an_api =>   (THE (make_fresh_stamp()), THE (type_api an_api),    WEAK_PACKAGE_CAST); 
                                        raw::PARTIAL_PACKAGE_CAST an_api =>   (THE (make_fresh_stamp()), THE (type_api an_api), PARTIAL_PACKAGE_CAST);
                                        raw::STRONG_PACKAGE_CAST  an_api =>   (THE (make_fresh_stamp()), THE (type_api an_api),  STRONG_PACKAGE_CAST);
                                    esac;
                                };

                                                                                                                                if_debugging_say "type_generic[GENERIC_DEFINITION]: result api typecheckd  [type-package-language-g.pkg]";
                            # Adjust the trj::context value; the debruijn_depth refers to the number
                            # of enclosing generic abstractions. (ZHONG)
                            #
                            debruijn_depth' =  di::next debruijn_depth;
                            context'        =  trj::IN_GENERIC { flex, debruijn_depth => debruijn_depth' };

                            # body_dee is discarded here;
                            # however, it is not discarded
                            # when generic is applied.
                            #
                            my  ( body_abstract_declaration,
                                  body_package,
                                  body_expression,
                                  body_dee                      # "dee" == "delta eleboration environment" I think -- additions to typechecking dictionary.
                                )
                                = 
                                type_package (
                                  body,
                                  NULL,
                                  symbolmapstack',
                                  typerstore',
                                  context',
                                  stamppath_context',
                                  module_stamp_v,
                                  ip::INVERSE_PATH [],
                                  source_code_region,
                                  per_compile_stuff
                                );

                                                                                                                                if_debugging_say          "type_generic[GENERIC_DEFINITION]: body typecheckd   [type-package-language-g.pkg]";
                                                                                                                                if_debugging_show_package("type_generic[GENERIC_DEFINITION]: body_package:  [type-package-language-g.pkg]", body_package, symbolmapstack);
                            #  Constrain by result api, on of:
                            #  
                            #
                            my  ( body_abstract_declaration',
                                  body_package',
                                  body_expression'
                                )
                                = 
                                case constraining_api
                                    #
                                    NULL => (body_abstract_declaration, body_package, body_expression);

                                    THE constraining_api'
                                        =>
                                        type_constrained_package (

                                            body_package,
                                            constraining_api_op,                # match/edit/cast.
                                            constraining_api',
                                            body_abstract_declaration,
                                            body_expression,
                                            module_stamp_v,
                                            debruijn_depth',
                                            typerstore',
                                            ip::INVERSE_PATH [],
                                            symbolmapstack', 
                                            source_code_region,
                                            per_compile_stuff
                                        );
                                esac;
                                                                                                                                if_debugging_say "type_generic[GENERIC_DEFINITION]: body constrained  [type-package-language-g.pkg]";
                            generic_expression
                                =
                                mld::LAMBDA {
                                    parameter => param_typechecked_package_variable,
                                    body      => body_expression'
                                };

                            result_generic
                                = 
                                {   body_sig'
                                        =
                                        case body_package'
                                            #
                                            A_PACKAGE { an_api, ... } =>   an_api;
                                            _                         =>   ERRONEOUS_API;
                                        esac;

                                    a_generic_api
                                        = 
                                        mld::GENERIC_API
                                          {
                                            kind          => NULL,
                                            parameter_api => param_sig, 
                                            body_api      => body_sig',

                                            parameter_variable  => param_typechecked_package_variable, 
                                            parameter_symbol    => parameter_name_or_null
                                          };

                                    typechecked_generic
                                        =
                                        {
                                          stamp          =>  make_fresh_stamp (),
                                          property_list  =>  property_list::make_property_list (),
                                          inverse_path,
                                          #
                                          stub           => NULL,
                                          typepath       => NULL,

                                          #  Closure: Using the old typechecked_package dictionary !! XXX BUGGO FIXME 

                                          generic_closure =>  mld::GENERIC_CLOSURE
                                                                {
                                                                  parameter_module_stamp =>  param_typechecked_package_variable,
                                                                  body_package_expression            =>  body_expression',
                                                                  typerstore
                                                                }
                                        };

                                    dacc   =   vh::named_varhome (name, make_var);

                                    mld::GENERIC {   a_generic_api,
                                                   typechecked_generic,

                                                   varhome       =>  dacc,
                                                   inlining_data =>  id::NIL
                                               };
                                };
                                                                                                                                if_debugging_say "type_generic[GENERIC_DEFINITION]: result_generic defined   [type-package-language-g.pkg]";
                            result_declaration
                                =
                                {   x = ds::GENERIC_DEFINITION  { parameter       => parameter_package,
                                                                  parameter_types => param_tps,
                                                                  definition      => ds::PACKAGE_LET {
                                                                                       declaration => body_abstract_declaration',
                                                                                       expression  => ds::PACKAGE_BY_NAME body_package'
                                                                                     }
                                                                };

                                    ds::GENERIC_DECLARATIONS [ ds::NAMED_GENERIC { name_symbol => name,
                                                                                   a_generic   => result_generic,
                                                                                   definition  => x
                                                                                 }
                                                             ];
                                };
                                                                                                                                if_debugging_say          "type_generic[GENERIC_DEFINITION]   [type-package-language-g.pkg]";
                                                                                                                                if_debugging_show_package("type_generic[GENERIC_DEFINITION]: parameter_package:  [type-package-language-g.pkg] ", parameter_package, symbolmapstack);
                            (result_declaration, generic_expression, result_generic, tro::empty);
                        };

                    raw::GENERIC_DEFINITION { parameters => parameter ! lparam, body, constraint }
                        =>
                        {   generic_expression'
                                = 
                                raw::GENERIC_DEFINITION {
                                    parameters => [ parameter ],
                                    body       => raw::PACKAGE_DEFINITION (
                                                     raw::GENERIC_DECLARATIONS [
                                                         raw::NAMED_GENERIC {
                                                             name_symbol => generic_id,
                                                             definition => raw::GENERIC_DEFINITION {
                                                                              parameters => lparam,
                                                                              body,
                                                                              constraint
                                                                          }
                                                         }
                                                     ]
                                                 ),
                                    constraint => raw::NO_PACKAGE_CAST
                                };


                            type_generic
                              ( generic_expression',
                                TRUE,
                                name,
                                symbolmapstack,
                                typerstore,
                                syntactic_typechecking_context,
                                stamppath_context,
                                inverse_path,
                                source_code_region,
                                per_compile_stuff
                              );
                        };

                    raw::GENERIC_DEFINITION { parameters => [], ... }
                        =>
                        bug "type_generic";

                    raw::SOURCE_CODE_REGION_FOR_GENERIC ( generic_expression', source_code_region' )
                        =>
                        type_generic
                          ( generic_expression',
                            curried,
                            name,
                            symbolmapstack,
                            typerstore,
                            syntactic_typechecking_context,
                            stamppath_context,
                            inverse_path,
                            source_code_region',
                            per_compile_stuff
                          );
                esac;
            }                       #  function type_generic 



        #  type_named_packages: typecheck named packages, with api constraint.
        #
        also
        fun type_named_packages
              (
                named_packages:                 List( raw::Named_Package ),                                                     # Declarations being typechecked.
                given_symbolmapstack:           syx::Symbolmapstack,                                                            # Symbol table containing info from all .compiled files we depend on.

                typerstore0:                    mld::Typerstore,
                syntactic_typechecking_context: trj::Syntactic_Typechecking_Context,
                stamppath_context:              spc::Context,

                inverse_path:                   ip::Inverse_Path,
                source_code_region:             lnd::Source_Code_Region,

                per_compile_stuff as { make_fresh_stamp,
                                      issue_highcode_codetemp => make_var,
                                      error_fn,
                                      ...
                                    }
                                    :   trj::Per_Compile_Stuff
            ) 
            :
            ( ds::Declaration,                                                                                                  # Typechecked version of  named_packages.
              syx::Symbolmapstack,                                                                                              # Contains (only) stuff from named_packages.
              mld::Module_Declaration,
              Typerstore
            )
            =
            {   debruijn_depth
                    =
                    case syntactic_typechecking_context
                        #
                        trj::IN_GENERIC { debruijn_depth, ... } =>  debruijn_depth;
                        _                                       =>  di::top;
                    esac;

                                                                                                                                if_debugging_say "type_named_packages  [type-package-language-g.pkg]";
                (   loop ( named_packages,
                           [],                  # declarations accumulate here.
                           syx::empty,          # Symbol table to fill out.
                           [],                  # generics accumulate here.
                           tro::empty           # Generics dictionary to fill out.
                         )
                    except
                        tro::UNBOUND
                            =
                            {   if_debugging_say
                                    (   "@@type_named_packages0 "
                                    ); 
                                raise exception tro::UNBOUND;
                            }
                )
                where
                    fun loop ([], declarations, symbolmapstack', module_declarations, typerstore)
                            => 
                            {
                                # We've finished processing our input
                                # list of named packages (first arg)
                                # so it is time to wrap up and return
                                # our results:
                                                                                                                                if_debugging_say "list exhausted/AAA in   loop() in  type_named_packages   src/lib/compiler/front/typer/main/type-package-language-g.pkg";
                                result_declaration
                                    = 
                                    ds::PACKAGE_DECLARATIONS (reverse declarations); 

                                                                                                                                if_debugging_say "list exhausted/BBB in   loop() in  type_named_packages   src/lib/compiler/front/typer/main/type-package-language-g.pkg";
                                module_declaration
                                    =
                                    case module_declarations

                                         [] =>  mld::EMPTY_GENERIC_EVALUATION_DECLARATION;
                                        _   =>  module_declaration_sequence (reverse module_declarations);
                                    esac;

                                                                                                                                if_debugging_say "list exhausted/CCC in   loop() in  type_named_packages   src/lib/compiler/front/typer/main/type-package-language-g.pkg";

                                ( result_declaration,                                                                           # Typechecked deep-syntax version of  named_packages.
                                  symbolmapstack',                                                                              # Contains (only) stuff from named_packages.
                                  module_declaration,
                                  typerstore
                                );
                            };

                        # Peel one named package off our input list
                        # (first arg), process it, accumulate the
                        # results in our remaining args, and loop:
                        #
                        loop
                            ( named_package ! remaining_named_packages,                                                         # Input list of raw-syntax named packages.
                              declarations,                                                                                     # Output list of typechecked deep-syntax packages.
                              symbolmapstack',                                                                                  # Contains (only) stuff from input named_packages list.
                              module_declarations,
                              typerstore
                            )
                            => 
                            {
                                                                                                                                if_debugging_say "list NOT exhausted/AAA in loop() in type_named_packages   in src/lib/compiler/front/typer/main/type-package-language-g.pkg";
                                # Discard any source code region info nodes,
                                # after noting the current source code region:
                                #
                                my  ( name:                         symbol::Symbol,
                                      constraint:                   raw::Package_Cast( raw::Api_Expression ),
                                      package_body_to_typecheck:    raw::Package_Expression,
                                      kind:                         raw::Package_Kind,
                                      source_code_region'
                                    )
                                    =
                                    case (strip_source_code_region_data_from_named_package (named_package, source_code_region))

                                         (raw::NAMED_PACKAGE { name_symbol, constraint, definition, kind }, region)
                                             =>
                                             (name_symbol, constraint, definition, kind, region);

                                        _ => bug "non package namings in type_named_packages";
                                    esac;

                                                                                                                                if_debugging_say ("package " + sy::name name + "list NOT exhausted/BBB in loop() in type_named_packages   in  src/lib/compiler/front/typer/main/type-package-language-g.pkg");

                                # Do OOP syntax expansion:
                                #
                                package_body_to_typecheck
                                    =
                                    case kind

                                        raw::PLAIN_PACKAGE
                                            =>
                                            package_body_to_typecheck;

                                        raw::CLASS_PACKAGE
                                            =>
                                            expand_oop_syntax_in_package_expression
                                              (
                                                name,
                                                package_body_to_typecheck,
                                                syx::atop
                                                  ( symbolmapstack',                                                                    # Contains (only) stuff from input named_packages list.
                                                    given_symbolmapstack                                                                        # Symbol table containing info from all .compiled files we depend on.
                                                  ),
                                                source_code_region',
                                                per_compile_stuff
                                              );

                                        raw::CLASS2_PACKAGE
                                            =>
                                            expand_oop_syntax_in_package_expression2
                                              (
                                                name,
                                                package_body_to_typecheck,
                                                syx::atop
                                                  ( symbolmapstack',                                                                    # Contains (only) stuff from input named_packages list.
                                                    given_symbolmapstack                                                                        # Symbol table containing info from all .compiled files we depend on.
                                                  ),
                                                source_code_region',
                                                per_compile_stuff
                                              );
                                    esac;
        

                                # Make a typechecked_package stamp
                                # for the current package declaration: 
                                #
                                rstamp =  make_fresh_stamp ();                                                                  # We don't always have to do this 



                                                                                                                                if_debugging_say ("package " + sy::name name + "list NOT exhausted/CCC in loop() in type_named_packages   in  src/lib/compiler/front/typer/main/type-package-language-g.pkg");
                                # module_stamp_v  is the context for evaluating
                                # the right-hand-side  of a package declaration:
                                #
                                my  ( module_stamp_v,
                                      module_stamp_or_null,
                                      constraining_api_or_null,
                                      package_cast
                                    )
                                    = 
                                    {   fun type_api  api_expression
                                            = 
                                            {
                                                                                                                                if_debugging_say ("calling ta::type_api  in   package " + sy::name name
                                                                                                                                                 + " list NOT exhausted/DDD in type_api loop() in type_named_packages   in  src/lib/compiler/front/typer/main/type-package-language-g.pkg");
                                                constraint_api
                                                    = 
                                                    ta::type_api
                                                      {
                                                        api_expression,                                                         # This is what we're typechecking.

                                                        name_or_null   =>  NULL,
                                                        symbolmapstack =>  given_symbolmapstack,                                # Symbol table containing info from all .compiled files we depend on.
                                                        typerstore     =>  typerstore0,

                                                        stamppath_context,
                                                        source_code_region,
                                                        per_compile_stuff
                                                      };
                                                                                                                                if_debugging_say ("back from ta::type_api  in   package " + sy::name name
                                                                                                                                                 + " list NOT exhausted/EEE in type_api loop() in type_named_packages   in  src/lib/compiler/front/typer/main/type-package-language-g.pkg");


                                                # If constraining api didn't typecheck,
                                                # just pretend it didn't exist:
                                                #
                                                                                                                                if_debugging_say ("constraining api " + case constraint_api ERRONEOUS_API => "did NOT"; _ => "DID"; esac
                                                                                                                                                 + " typecheck  in   package " + sy::name name
                                                                                                                                                 + "list NOT exhausted/FFF in type_api loop() in type_named_packages   in  src/lib/compiler/front/typer/main/type-package-language-g.pkg");
                                                case constraint_api
                                                    #
                                                    ERRONEOUS_API =>  NULL;  
                                                    _             =>  THE constraint_api;
                                                esac;
                                            };

                                                                                                                                if_debugging_say ("Doing 'constraint' case src/lib/compiler/front/typer/main/type-package-language-g.pkg:  --type_named_packages: \n");

                                        my  ( constraining_api_or_null,
                                              package_cast
                                            )
                                            =
                                            case constraint 
                                                #
                                                raw::WEAK_PACKAGE_CAST api_expression
                                                    =>
                                                    {   if_debugging_say "type_named_packages[WEAK_PACKAGE_CAST]: calling type_api  [type-package-language-g.pkg]\n";
                                                        ( type_api  api_expression,
                                                          WEAK_PACKAGE_CAST
                                                        );
                                                    };

                                                raw::PARTIAL_PACKAGE_CAST api_expression
                                                    =>
                                                    {   if_debugging_say "type_named_packages[PARTIAL_PACKAGE_CAST]: calling type_api  [type-package-language-g.pkg]\n";
                                                        case (type_api  api_expression)
                                                              NULL  => (NULL, WEAK_PACKAGE_CAST);
                                                              other => (other, PARTIAL_PACKAGE_CAST);
                                                        esac;
                                                    };

                                                raw::STRONG_PACKAGE_CAST api_expression
                                                    =>
                                                    {   if_debugging_say "type_named_packages[STRONG_PACKAGE_CAST]: calling type_api  [type-package-language-g.pkg]\n";
                                                        case (type_api  api_expression)
                                                              NULL  => (NULL, WEAK_PACKAGE_CAST);
                                                              other => (other, STRONG_PACKAGE_CAST);
                                                        esac;
                                                    };

                                                _   =>
                                                    {   if_debugging_say "type_named_packages[(NULL api constraint)]: not calling type_api  [type-package-language-g.pkg]\n";
                                                        (NULL, WEAK_PACKAGE_CAST);
                                                    }; 

                                            esac;


                                                                                                                                if_debugging_say "type_named_packages: DONE 'constraint' case  [type-package-language-g.pkg]\n";

                                        #  The temporary anonymous package: 
                                        #
                                        my  ( module_stamp_v,
                                              module_stamp_or_null
                                            )
                                            = 
                                            case constraining_api_or_null
                                                #
                                                NULL => (rstamp, NULL);

                                                _ => {   new_module_stamp =   make_fresh_stamp ();

                                                         ( new_module_stamp,
                                                           THE new_module_stamp
                                                         );
                                                     };
                                            esac;

                                        (module_stamp_v, module_stamp_or_null, constraining_api_or_null, package_cast);
                                    };

                                                                                                                                if_debugging_say "type_named_packages: typechecking package body  [type-package-language-g.pkg]\n";
                                # Typecheck the package body:
                                #
                                my  ( abstract_package_declaration:      ds::Declaration,
                                      a_package:                         mld::Package,
                                      package_expression:                mld::Package_Expression,
                                      typerstore_additions:              tro::Typerstore
                                    )
                                    = 
                                    type_package
                                      (
                                        package_body_to_typecheck,
                                        THE name,
                                        given_symbolmapstack,                                                                   # Symbol table containing info from all .compiled files we depend on.
                                        typerstore0,
                                        syntactic_typechecking_context,
                                        stamppath_context,
                                        THE module_stamp_v,
                                        ip::extend (inverse_path, name),
                                        source_code_region',
                                        per_compile_stuff
                                    );
                                                                                                                                if_debugging_say "type_named_packages: DONE typechecking package body.   [type-package-language-g.pkg]\n";
                                # Check for partially applied curried generic 
                                #
                                a_package
                                    =
                                    if (sy::eq (name, return_id))
                                        #
                                        # a_package should be generic application wrapper package
                                        # with single package component "result_package"
                                        #
                                        if case a_package
                                               #
                                               ERRONEOUS_PACKAGE => TRUE;

                                               _ => case (mj::get_package_symbols a_package)
                                                        #
                                                        [symbol] => sy::eq (symbol, result_id);
                                                        _        => FALSE;
                                                    esac;

                                           esac


                                             a_package;
                                        else
                                             error_fn
                                                  source_code_region'
                                                  err::ERROR
                                                  (   "package "
                                                  +   sy::name (ip::last inverse_path)
                                                  +   " defined by partially applied generic"
                                                  )
                                                  err::null_error_body;

                                              ERRONEOUS_PACKAGE;
                                        fi;
                                    else
                                        a_package;
                                    fi;
                                                                                                                                if_debugging_say          "type_named_packages: type_package done  [type-package-language-g.pkg]";
                                                                                                                                unparse_deep_declaration ("type_named_packages after body typechecking: unparsing  abstract_package_declaration deep syntax:  [type-package-language-g.pkg] ",
                                                                                                                                                            abstract_package_declaration, symbolmapstack');
                                                                                                                                if_debugging_show_package("unconstrained package:  [type-package-language-g.pkg] ", a_package, symbolmapstack');
                                # If this is a PARTIAL_PACKAGE_CAST,
                                # hack the constraining api to reduce
                                # it to the STRONG_PACKAGE_CAST case:
                                #
if_debugging_say "type_named_packages: calling maybe_extend_api_to_cover_package.  [type-package-language-g.pkg]\n";
                                my  ( constraining_api_or_null,
                                      package_cast,
                                      symbolmapstack'                                                                           # Contains (only) stuff from input named_packages list.
                                    )
                                    =
                                    maybe_extend_api_to_cover_package
                                      ( constraining_api_or_null,
                                        package_cast,
                                        a_package,
                                        symbolmapstack'
                                      );
                                                                                                                                if_debugging_say "type_named_packages: DONE calling maybe_extend_api_to_cover_package.  [type-package-language-g.pkg]\n";

                                # Typecheck an api match.
                                # Notice that we did introduce stamps
                                # during the abstraction matching, but
                                # that these stamps are always visible,
                                # thus will always be caught by the post
                                # api-matching "map_paths" function call:
                                #
                                my  ( result_declaration,
                                      result_package,
                                      result_package_expression
                                    )
                                    = 
                                    case constraining_api_or_null
                                        #
                                        NULL
                                            => 
                                            {   case package_cast
                                                    #
                                                    WEAK_PACKAGE_CAST
                                                        =>
                                                        ();

                                                    PARTIAL_PACKAGE_CAST
                                                        =>
                                                         (   error_fn
                                                                 source_code_region'
                                                                 err::ERROR
                                                                 "missing api in partial package cast declaration"
                                                                 err::null_error_body
                                                         );

                                                    STRONG_PACKAGE_CAST
                                                        =>
                                                         (   error_fn
                                                                 source_code_region'
                                                                 err::ERROR
                                                                 "missing api in strong package cast declaration"
                                                                 err::null_error_body
                                                         );
                                                esac;
                                                                                                                               if_debugging_say "type_named_packages: NOT calling type_constrained_package  [type-package-language-g.pkg] ";
                                                ( abstract_package_declaration,
                                                  a_package,
                                                  package_expression
                                                );
                                            };

                                        THE constraint_api
                                            => 
                                            {
                                                                                                                               if_debugging_say "type_named_packages: calling type_constrained_package [type-package-language-g.pkg] ";
                                               type_constrained_package
                                                 (
                                                    a_package,
                                                    package_cast,
                                                    constraint_api,
                                                    abstract_package_declaration,
                                                    package_expression, 
                                                    module_stamp_or_null,
                                                    debruijn_depth,
                                                    typerstore0,
                                                    ip::INVERSE_PATH [ name ], 
                                                    syx::atop
                                                      ( symbolmapstack',                                                        # Contains (only) stuff from input named_packages list.
                                                        given_symbolmapstack                                                    # Symbol table containing info from all .compiled files we depend on.
                                                      ),
                                                    source_code_region,
                                                    per_compile_stuff
                                                );
                                           };
                                   esac;
                                                                                                                                if_debugging_say "type_named_packages: now past type_constrained_package call point.  [type-package-language-g.pkg]";
                                typerstore_additions
                                    = 
                                    case (module_stamp_or_null, constraining_api_or_null)
                                        #
                                        (NULL, NULL)
                                            =>
                                            typerstore_additions;

                                        (THE module_stamp, THE _)
                                            =>
                                            case a_package
                                                #
                                                mld::A_PACKAGE { typechecked_package, ... }
                                                    =>
                                                    tro::set (
                                                        typerstore_additions,
                                                        module_stamp,
                                                        mld::PACKAGE_ENTRY typechecked_package
                                                    );

                                                _   =>  tro::set (
                                                            typerstore_additions,
                                                            module_stamp,
                                                            mld::PACKAGE_ENTRY mld::bogus_typechecked_package
                                                        );
                                             esac;

                                        _  => bug "unexpected case in type_named_packages: macro_expansion_dictionary_additions";
                                    esac;

                                                                                                                                if_debugging_say           "type_named_packages: constrain done [type-package-language-g.pkg] ";
                                                                                                                                if_debugging_show_package ("type_named_packages: result_package:  [type-package-language-g.pkg] ", result_package, symbolmapstack');

                                # NOTE: bind_package modifies the varhome field of result_package;
                                # this may create packages with same ids but different dynamic
                                # accesses --- BUT, we assume that before or during the pickling, 
                                # both the dynamic access and the inlining_data will be updated 
                                # completely and replaced with proper persistent accesses (ZHONG)
                                #
                                my  ( bound_package,
                                      typechecked_package
                                    )
                                    = 
                                    case result_package
                                        #
                                        A_PACKAGE { typechecked_package, an_api, varhome, inlining_data }
                                            =>
                                            ( A_PACKAGE { varhome       => vh::named_varhome (name, make_var),
                                                          typechecked_package,
                                                          an_api,
                                                          inlining_data
                                                        },

                                              mld::PACKAGE_ENTRY  typechecked_package
                                            );

                                        _   => ( result_package,
                                                 mld::PACKAGE_ENTRY  mld::bogus_typechecked_package
                                               );
                                    esac;
                                                                                                                                if_debugging_show_package("type_named_packages: bound_package:  [type-package-language-g.pkg] ", bound_package, symbolmapstack');
                                declarations' = pkg_declaration ! declarations
                                where
                                    pkg_declaration
                                        =
                                        ds::NAMED_PACKAGE
                                          {
                                            name_symbol => name,
                                            a_package   => bound_package, 
                                            definition  => ds::PACKAGE_LET
                                                             { declaration => result_declaration,
                                                               expression  => ds::PACKAGE_BY_NAME result_package
                                                             }
                                          };
                                end;


                                my  ( typerstore',
                                      module_declarations'
                                    )
                                    = 
                                    case syntactic_typechecking_context
                                        #
                                        trj::IN_GENERIC { flex, ... }
                                            => 
                                            {   typerstore1 = tro::atop_sp (typerstore_additions, typerstore);
                                                typerstore2 = tro::set     (typerstore1, rstamp, typechecked_package);
                                                typerstore3 = tro::mark    (make_fresh_stamp, typerstore2);
                                                                                                                                if_debugging_say "type_named_packages: about to map_paths bound_package [type-package-language-g.pkg] ";
                                                # We are remapping macro_expansion_paths for elements of
                                                # the new package unconditionally, even if
                                                # there is no api constraint and the
                                                # defining package_expression is PACKAGE_DEFINITION -- David MacQueen.

                                                map_paths ( spc::enter_open (stamppath_context, THE rstamp),
                                                            bound_package,
                                                            flex
                                                          );
                                                                                                                                if_debugging_say "type_named_packages: map_paths bound_package done [type-package-language-g.pkg] ";
                                                case bound_package
                                                    #
                                                    A_PACKAGE { an_api, typechecked_package, ... }
                                                        =>
                                                        spc::bind_stamppath (
                                                            stamppath_context, 
                                                            mj::make_packagestamp  (an_api,  typechecked_package),
                                                            rstamp
                                                        );

                                                    _ => ();
                                                esac;



                                                ( typerstore3,
                                                  mld::PACKAGE_DECLARATION (rstamp, result_package_expression, name)  !  module_declarations
                                                );
                                            };

                                        _ => ( typerstore,
                                               module_declarations
                                             );
                                    esac;
                                                                                                                                if_debugging_show_package("type_named_packages: bound_package: [type-package-language-g.pkg] ", bound_package, symbolmapstack');
                                symbolmapstack'' =  syx::bind (name, sxe::NAMED_PACKAGE bound_package, symbolmapstack');

                                loop (remaining_named_packages, declarations', symbolmapstack'', module_declarations', typerstore');
                            };
                    end;                # fun loop
                end;                    # where
            }                           #  function type_named_packages 



        # type_declaration'(): typecheck an arbitrary package-level declaration: 
        #
        # Typechecking ultimately converts a raw syntax tree into
        #
        #  o  A deep syntax tree holding executable content and
        #  o  Symbol table holding declarative content.
        #
        # Those account for our first two return values here.
        #
        # Our other two return values are internal typechecking
        # information discarded at the completion of this
        # typechecking call;  they track information used during
        # processing of generics.
        #
        also
        fun type_declaration' (
              # 
              raw_declaration:                  raw::Declaration,                               # Declaration being typechecked.
              symbolmapstack:                   syx::Symbolmapstack,                            # Symbol table containing info from all .compiled files we depend on.

              typerstore0:                      mld::Typerstore,
              syntactic_typechecking_context:   trj::Syntactic_Typechecking_Context,
              top:                              Bool,

              stamppath_context:                spc::Context,
              inverse_path:                     ip::Inverse_Path,
              source_code_region:               lnd::Source_Code_Region,

              per_compile_stuff as { make_fresh_stamp, issue_highcode_codetemp=>make_var, error_fn, deep_syntax_transform, ... }:   trj::Per_Compile_Stuff
            )
            :
            ( ds::Declaration,                                                                  # Typechecked version of  raw_declaration.
              syx::Symbolmapstack,                                                              # Contains (only) stuff from raw_declaration.
              Module_Declaration,
              Typerstore
            )
            =
            {   
                                                                                                                                if *debugging
                                                                                                                                    #
                                                                                                                                    unparse_raw_declaration
                                                                                                                                        (
                                                                                                                                          "type_declaration': unparsing declaration raw syntax: [type-package-language-g.pkg]\n",
                                                                                                                                          raw_declaration,
                                                                                                                                          symbolmapstack
                                                                                                                                        );

                                                                                                                                    prettyprint_raw_declaration
                                                                                                                                        (
                                                                                                                                          "type_declaration': prettyprinting declaration raw syntax: [type-package-language-g.pkg]\n",
                                                                                                                                          raw_declaration,
                                                                                                                                          symbolmapstack
                                                                                                                                        );
                                                                                                                                fi;

                case raw_declaration
                    #
                    raw::PACKAGE_DECLARATIONS named_packages
                        =>
                        type_named_packages
                          (
                            named_packages,
                            symbolmapstack,
                            typerstore0,
                            syntactic_typechecking_context,
                            stamppath_context, 
                            inverse_path,
                            source_code_region,
                            per_compile_stuff
                          );

                    raw::INCLUDE_DECLARATIONS paths
                        =>
                        {   err =   error_fn  source_code_region;
                            #
                            packages =  map path_to_package  paths
                                            where
                                                fun path_to_package  symbol_list
                                                    =
                                                    {   symbol_path =   syp::SYMBOL_PATH  symbol_list;
                                                        #
                                                        ( symbol_path,
                                                          fst::find_package_via_symbol_path (symbolmapstack, symbol_path, err)
                                                        );
                                                    };
                                            end;

                            loop (packages, syx::empty)
                            where
                                fun loop ([], symbolmapstack')
                                        =>
                                        (   ds::INCLUDE_DECLARATIONS packages,
                                            symbolmapstack',
                                            mld::EMPTY_GENERIC_EVALUATION_DECLARATION,
                                            tro::empty
                                        );

                                    loop ((_, s) ! r, symbolmapstack')
                                        =>
                                        loop (r, mj::include_package (symbolmapstack', s));
                                end;
                           end;
                        };

                    raw::GENERIC_DECLARATIONS named_generics
                        =>
                        {                                                                                                       if_debugging_say "type_declaration'/GENERIC_DECLARATIONS   [type-package-language-g.pkg] ";
                            (   loop (named_generics, NIL, syx::empty, NIL, tro::empty)
                                except
                                    tro::UNBOUND
                                        =
                                        {   if_debugging_say ("@@type_declaration': GENERIC_DECLARATION  [type-package-language-g.pkg] "); 
                                            raise exception tro::UNBOUND;
                                        }
                            )
                            where
                                fun loop ([], declarations, symbolmapstack', module_declarations, typerstore')
                                        => 
                                        {   result_declaration   =   ds::GENERIC_DECLARATIONS (reverse declarations);
                                            #
                                            module_declaration
                                                =
                                                case module_declarations
                                                    #
                                                    [] =>  mld::EMPTY_GENERIC_EVALUATION_DECLARATION;

                                                    _  =>  module_declaration_sequence (reverse module_declarations);
                                                esac;
                                                                                                                                if_debugging_say "type_declaration'/GENERIC_DECLARATIONS/ZZZ  [type-package-language-g.pkg] ";
                                            (result_declaration, symbolmapstack', module_declaration, typerstore');
                                        };

                                    loop (named_generic ! rest, declarations, symbolmapstack', module_declarations, typerstore')
                                        => 
                                        {   my  ( name,
                                                  definition,
                                                  source_code_region'
                                                )
                                                =
                                                case (strip_source_code_region_data_from_named_generics
                                                       (
                                                         named_generic,
                                                         source_code_region
                                                     ))
                                                    #
                                                    (raw::NAMED_GENERIC { name_symbol, definition }, region)
                                                        =>
                                                        (name_symbol, definition, region);

                                                    _ => bug "non generic namings for GENERIC_DECLARATION named_generics";
                                                esac;

                                                                                                                                if_debugging_say("type_declaration': GENERIC_DECLARATIONS/AAA  [type-package-language-g.pkg] " + sy::name name);

                                            #  Dynamic varhome is assigned in type_generic: 
                                            #
                                            my  ( generic_abstract_declaration,
                                                  generic_expression,
                                                  a_generic,
                                                  typerstore_additions
                                                )
                                                = 
                                                type_generic
                                                  (
                                                    definition,
                                                    FALSE,                       #  Not curried. 
                                                    name,
                                                    symbolmapstack,
                                                    typerstore0,
                                                    syntactic_typechecking_context,
                                                    stamppath_context,
                                                    inverse_path,
                                                    source_code_region',
                                                    per_compile_stuff
                                                  );

                                            # WARNING: bind_generic modifies the varhome field of a_generic; 
                                            # this may create generics with same ids but 
                                            # different dynamic accesses --- BUT, we assume that 
                                            # before or during the pickling, both the dynamic 
                                            # varhome and the inlining_data will be updated completely 
                                            # and replaced with proper persistent accesses (ZHONG)
                                            #
                                            my  ( bind_generic,
                                                  typechecked_generic
                                                )
                                                = 
                                                case a_generic
                                                    #
                                                    GENERIC { typechecked_generic, a_generic_api, varhome, inlining_data }
                                                        =>
                                                        ( GENERIC {
                                                            varhome       => vh::named_varhome (name, make_var),
                                                            typechecked_generic,
                                                            a_generic_api,
                                                            inlining_data
                                                          },

                                                          GENERIC_ENTRY  typechecked_generic
                                                        );

                                                    ERRONEOUS_GENERIC => (a_generic, ERRONEOUS_ENTRY);
                                                esac;

                                            fb = ds::NAMED_GENERIC { name_symbol => name,
                                                                     a_generic   => bind_generic, 
                                                                     definition  => ds::GENERIC_LET (
                                                                                          generic_abstract_declaration,
                                                                                          ds::GENERIC_BY_NAME a_generic
                                                                                    )
                                                                     };

                                            declarations' = fb ! declarations;

                                            my  ( typerstore'',
                                                  module_declarations'
                                                )
                                                = 
                                                case syntactic_typechecking_context
                                                    #
                                                    trj::IN_GENERIC _
                                                        => 
                                                        {   module_stamp =   make_fresh_stamp ();
                                                            #
                                                            case bind_generic
                                                                #
                                                                GENERIC _
                                                                    =>
                                                                    spc::bind_generic_path (
                                                                        #
                                                                        stamppath_context, 
                                                                        mj::genericstamp_of  bind_generic,
                                                                        module_stamp
                                                                    );

                                                                ERRONEOUS_GENERIC => ();
                                                            esac;

                                                            typerstore1 =   tro::atop_sp (
                                                                                typerstore_additions,
                                                                                typerstore'
                                                                            );

                                                            typerstore2 =   tro::set (
                                                                                typerstore1,
                                                                                module_stamp,
                                                                                typechecked_generic
                                                                            );

                                                            typerstore3 =   tro::mark (
                                                                                make_fresh_stamp,
                                                                                typerstore2
                                                                            );

                                                            ( typerstore3,
                                                              # 
                                                              mld::GENERIC_DECLARATION (
                                                                  module_stamp,
                                                                  generic_expression
                                                              )
                                                              !
                                                              module_declarations
                                                            );
                                                        };


                                                    _ => (typerstore', module_declarations);

                                                esac;

                                            symbolmapstack'' = syx::bind (
                                                                name,
                                                                sxe::NAMED_GENERIC bind_generic,
                                                                symbolmapstack'
                                                            );


                                            loop (rest, declarations', symbolmapstack'', module_declarations', typerstore'');
                                        };
                                end;                    # fun loop
                            end;                                # where
                        };

                    raw::API_DECLARATIONS named_apis
                        =>
                        {                                                                                                       if_debugging_say "type_api_bs   [type-package-language-g.pkg] ";
                            (   loop (named_apis, NIL, syx::empty)
                                except
                                    tro::UNBOUND
                                        =
                                        {   if_debugging_say("@@type_declaration': API_DECLARATION  [type-package-language-g.pkg] "); 
                                            raise exception tro::UNBOUND;
                                        }
                            )
                            where
                                fun loop ([], apis, symbolmapstack')
                                        => 
                                        {
                                                                                                                                if_debugging_say "type_api_bs  [type-package-language-g.pkg] ";
                                            ( ds::API_DECLARATIONS (reverse apis),
                                              symbolmapstack',
                                              mld::EMPTY_GENERIC_EVALUATION_DECLARATION,
                                              tro::empty
                                            );
                                        };

                                    loop (named_api ! rest, apis, symbolmapstack')
                                        =>
                                        {   my  ( name,
                                                  definition,
                                                  source_code_region'
                                                )
                                                =
                                                case (strip_source_code_region_data_from_named_api (named_api, source_code_region))
                                                    #
                                                    (raw::NAMED_API { name_symbol, definition }, region)
                                                        =>
                                                        (name_symbol, definition, region);

                                                     _   => bug "non api namings for API_DECLARATION named_apis";
                                                esac;
                                                                                                                                if_debugging_say("type_declaration':   [type-package-language-g.pkg]  api " + sy::name name);
                                            an_api =    ta::type_api
                                                          {
                                                            api_expression =>  definition,
                                                            name_or_null   =>  THE name,
                                                            symbolmapstack, 

                                                            typerstore         =>  typerstore0,
                                                            source_code_region =>  source_code_region',

                                                            stamppath_context,
                                                            per_compile_stuff
                                                          };

                                            # Process to check well-formedness:
                                            #
                                            if (*typer_control::macro_expand_sigs)
                                                #
                                                ins::do_generic_parameter_api
                                                  {
                                                    an_api,
                                                    typerstore => tro::empty,
                                                    #
                                                    debruijn_depth     =>  di::top,
                                                    inverse_path       =>  ip::empty,
                                                    source_code_region =>  source_code_region',
                                                    per_compile_stuff
                                                  };

                                                 ();
                                            fi;
                                                                                                                                if_debugging_say ("type_declaration' [API_DECLARATIONS]:   [type-package-language-g.pkg]  binding NAMED_API " + (sy::name name)); 
                                            loop (  rest,
                                                    an_api ! apis,
                                                    syx::bind (name, sxe::NAMED_API an_api, symbolmapstack')
                                                 );
                                        };
                                end;                    # fun loop
                            end;                        # where
                        };

                    raw::GENERIC_API_DECLARATIONS named_generic_apis
                        =>
                        {                                                                                                       if_debugging_say "type_declaration'/GENERIC_API_DECLARATIONS  [type-package-language-g.pkg] ";
                            (   loop (named_generic_apis, NIL, syx::empty)
                                except
                                    tro::UNBOUND
                                        =
                                        {   if_debugging_say ("@@type_declaration': GENERIC_API_DECLARATIONS  [type-package-language-g.pkg] "); 
                                            raise exception tro::UNBOUND;
                                        }
                            )
                            where
                                fun loop ([], generic_apis, symbolmapstack')
                                        => 
                                        {                                                                                       if_debugging_say "type_declaration'/GENERIC_API_DECLARATIONS/ZZZ [type-package-language-g.pkg] ";
                                            (    ds::GENERIC_API_DECLARATIONS (reverse generic_apis),
                                                 symbolmapstack',
                                                 mld::EMPTY_GENERIC_EVALUATION_DECLARATION,
                                                 tro::empty
                                            );
                                        };

                                    loop (named_generic_api ! rest, generic_apis, symbolmapstack')
                                        =>
                                        {   my (name,
                                                definition,
                                                source_code_region')
                                                =
                                                case (strip_source_code_region_data_from_named_generic_api
                                                    ( named_generic_api,
                                                      source_code_region
                                                    ))

                                                     (raw::NAMED_GENERIC_API { name_symbol=>n, definition=>d }, r)
                                                         =>
                                                         (n, d, r);

                                                     _
                                                         =>
                                                         bug "non Generic_Api namings for GENERIC_API_DECLARATIONS generic_named_apis";
                                                esac;

                                                                                                                                if_debugging_say("type_declaration'/GENERIC_API_DECLARATIONS/LLL:   [type-package-language-g.pkg}  generic_api " + sy::name name);

                                            s = ta::type_generic_api
                                                  {
                                                    generic_api_expression => definition,

                                                    name_or_null            => THE name,
                                                    symbolmapstack,
                                                    typerstore  => typerstore0,

                                                    stamppath_context, 
                                                    source_code_region      => source_code_region',
                                                    per_compile_stuff
                                                  };

                                            loop (
                                                rest,
                                                s ! generic_apis,
                                                syx::bind (name, sxe::NAMED_GENERIC_API s, symbolmapstack')
                                            );
                                        };
                                end;            # fun loop
                            end;                        # where
                        };

                    raw::LOCAL_DECLARATIONS (declaration_in, declaration_out)
                        =>
                        {   top_in =    trj::contains_package_declaration declaration_in    or
                                        trj::contains_package_declaration declaration_out;

                                # If declaration_in contains a generic declaration (at
                                # any nesting depth) we must suppress ungeneralized
                                # type variables to avoid bug 905/952.
                                #
                                # Using TRJ::contains_package_declaration is a cheap conservative approximation
                                # to checking for the presence of generic declarations,
                                # although it excludes some legal SML 96 programs where
                                # packages but not generics are present.


                            my  ( deep_syntax_tree_in,
                                  env_in,
                                  entdeclaration_in,
                                  input_typerstore
                                )
                                =
                                type_declaration' (
                                    declaration_in,
                                    symbolmapstack,
                                    typerstore0,
                                    syntactic_typechecking_context,
                                    top_in,
                                    stamppath_context,
                                    inverse_path,
                                    source_code_region,
                                    per_compile_stuff
                                );



                            # ** DAVE? what is the right stamppath_context to pass here? XXX BUGGO FIXME **

                            symbolmapstack' = syx::atop (env_in, symbolmapstack);

                            typerstore' =   tro::mark (
                                                make_fresh_stamp,
                                                tro::atop (input_typerstore, typerstore0)
                                            );

                            my  ( deep_syntax_tree_out,
                                  env_out,
                                  entdeclaration_out,
                                  output_typerstore
                                )
                                = 
                                type_declaration' (
                                    declaration_out,
                                    symbolmapstack',
                                    typerstore',
                                    syntactic_typechecking_context,
                                    top,
                                    stamppath_context,
                                    inverse_path,
                                    source_code_region,
                                    per_compile_stuff
                                );

                            result_deep_syntax_tree
                                =
                                ds::LOCAL_DECLARATIONS (deep_syntax_tree_in, deep_syntax_tree_out);

                            my  ( module_declaration,
                                  result_typerstore
                                )
                                = 
                                case syntactic_typechecking_context
                                    #
                                    trj::IN_GENERIC _
                                        => 
                                        ( local_module_declaration (entdeclaration_in, entdeclaration_out),

                                          tro::mark (
                                            make_fresh_stamp,
                                            tro::atop (output_typerstore, input_typerstore)
                                          )
                                        );

                                    _ => (mld::EMPTY_GENERIC_EVALUATION_DECLARATION, tro::empty);
                                esac;

                            ( result_deep_syntax_tree,
                              env_out,
                              module_declaration,
                              result_typerstore
                            );
                        };

                    raw::SEQUENTIAL_DECLARATIONS declarations
                        => 
                        {                                                                                                       if_debugging_say "type_declaration'/SEQUENTIAL_DECLARATIONS  [type-package-language-g.pkg] ";
                            (   loop (declarations, NIL, syx::empty, NIL, tro::empty)
                                except
                                    tro::UNBOUND
                                        =
                                        {   if_debugging_say("@@type_declaration': SEQUENTIAL_DECLARATIONS  [type-package-language-g.pkg] "); 
                                            raise exception tro::UNBOUND;
                                        }
                            )
                            where
                                fun loop ([], asdeclarations, symbolmapstack', module_declarations, typerstore')
                                        => 
                                        {   result_deep_syntax_tree
                                                =
                                                ds::SEQUENTIAL_DECLARATIONS (reverse asdeclarations);

                                            my  ( module_declaration',
                                                  typerstore''
                                                )
                                                = 
                                                case syntactic_typechecking_context
                                                    #
                                                    trj::IN_GENERIC _
                                                        => 
                                                        (   module_declaration_sequence (reverse module_declarations),
                                                            typerstore'
                                                        );

                                                    _ => (mld::EMPTY_GENERIC_EVALUATION_DECLARATION, tro::empty);
                                                esac;
                                                                                                                                debug_print ("type_declaration'/SEQUENTIAL_DECLARATIONS/ZZZ - symbols: ", bug::prettyprint_symbol_list, bug::symbolmapstack_symbols symbolmapstack');

                                                                                                                                if_debugging_say "type_declaration'/SEQUENTIAL_DECLARATIONS/ZZZZ  [type-package-language-g.pkg] ";
                                            (result_deep_syntax_tree, symbolmapstack', module_declaration', typerstore'');
                                        };

                                    loop (declaration ! rest, asdeclarations, symbolmapstack', module_declarations, typerstore')
                                        => 
                                        {   symbolmapstack1   =   syx::atop (symbolmapstack', symbolmapstack);
                                            #
                                            typerstore1 =   tro::mark ( make_fresh_stamp,
                                                                        tro::atop (typerstore', typerstore0)
                                                                      );

                                            my  ( deep_syntax_declaration,
                                                  symbolmapstack'',
                                                  module_declaration,
                                                  typerstore''
                                                )
                                                = 
                                                type_declaration' (
                                                    declaration,
                                                    symbolmapstack1,
                                                    typerstore1,
                                                    syntactic_typechecking_context,
                                                    top,
                                                    stamppath_context,
                                                    inverse_path,
                                                    source_code_region,
                                                    per_compile_stuff
                                                );

                                            loop (
                                                rest,
                                                deep_syntax_declaration ! asdeclarations,
                                                syx::atop (symbolmapstack'', symbolmapstack'),
                                                module_declaration ! module_declarations,
                                                tro::mark (
                                                    make_fresh_stamp,
                                                    tro::atop (typerstore'', typerstore')
                                                )
                                            );
                                        };
                                end;                            # fun loop
                            end;                                # where

                        };

                    raw::TYPE_DECLARATIONS named_types          # ** ASSERT: the types declared are all DEFtypes **
                        =>
                        (   {   my  ( declaration,
                                      symbolmapstack'
                                    )
                                    =
                                    tt::type_type_declaration (
                                        named_types,
                                        symbolmapstack,
                                        inverse_path,
                                        source_code_region,
                                        per_compile_stuff
                                    );

                                types = case declaration

                                           ds::TYPE_DECLARATIONS  z
                                               =>
                                               z;

                                           _   =>   bug "type_declaration' for TYPE_DECLARATIONS";
                                       esac;

                                my  ( typerstore',
                                      module_declaration
                                    )
                                    = 
                                    bind_new_types (
                                        syntactic_typechecking_context,
                                        stamppath_context,
                                        make_fresh_stamp,
                                        [],
                                        types,
                                        inverse_path,
                                        error_fn  source_code_region
                                    );

                                ( declaration,
                                  symbolmapstack',
                                  module_declaration,
                                  typerstore'
                                );
                            }
                            except
                                tro::UNBOUND
                                    =
                                    {   if_debugging_say("@@type_declaration': TYPE_DECLARATIONS  [type-package-language-g.pkg] ");
                                        raise exception tro::UNBOUND;
                                    }
                        );

                    raw::SUMTYPE_DECLARATIONS (x as { sumtypes, with_types } )
                        =>
                        case sumtypes
                            #
                            (raw::SUM_TYPE { right_hand_side => (raw::VALCONS _), ... } ) ! _
                                =>
                                {   is_free =   case syntactic_typechecking_context 
                                                    #
                                                    trj::IN_GENERIC _
                                                        =>
                                                        (\\ type
                                                            =
                                                            case (spc::find_stamppath_for_type (
                                                                     stamppath_context,
                                                                     mj::typestamp_of  type
                                                                 ))
                                                                #
                                                                THE _ =>  TRUE;
                                                                _     =>  FALSE;
                                                            esac

                                                        );

                                                    _ => (\\ _ = FALSE);
                                                esac;


                                    my  ( sumtypes,
                                          with_types,
                                          _,
                                          symbolmapstack'
                                        )
                                        =
                                        tt::type_sumtype_declaration (
                                            x,
                                            symbolmapstack,
                                            [],
                                            tro::empty,
                                            is_free,
                                            inverse_path,
                                            source_code_region,
                                            per_compile_stuff
                                        );

                                    my  ( typerstore',
                                          module_declaration
                                        )
                                        = 
                                        bind_new_types (
                                            syntactic_typechecking_context,
                                            stamppath_context,
                                            make_fresh_stamp,
                                            sumtypes,
                                            with_types,
                                            inverse_path,
                                            error_fn  source_code_region
                                        );

                                    result_declaration
                                        = 
                                        ds::SUMTYPE_DECLARATIONS  {  sumtypes,  with_types  };

                                    ( result_declaration,
                                      symbolmapstack',
                                      module_declaration,
                                      typerstore'
                                    );
                                };

                            (raw::SUM_TYPE { name_symbol,
                                               right_hand_side  => raw::REPLICAS symbols,
                                               typevars   => NIL,
                                               is_lazy          => FALSE
                                             }
                                             !
                                             NIL
                             )
                                =>
                                {   fun no_sumtype ()
                                        =
                                        {   error_fn
                                                source_code_region
                                                err::ERROR
                                                "rhs of sumtype replication not a sumtype"
                                                err::null_error_body;

                                            (   ds::SEQUENTIAL_DECLARATIONS [],
                                                syx::empty,
                                                mld::ERRONEOUS_ENTRY_DECLARATION,
                                                tro::empty
                                            );
                                        };

                                    case with_types
                                        #
                                        _ ! _
                                            => 
                                            {   error_fn
                                                    source_code_region
                                                    err::ERROR
                                                    "withtype not allowed in sumtype replication"
                                                    err::null_error_body;

                                                (   ds::SEQUENTIAL_DECLARATIONS [],
                                                    syx::empty,
                                                    mld::ERRONEOUS_ENTRY_DECLARATION,
                                                    tro::empty
                                                );
                                            };

                                        []  =>
                                            {   type =  fst::find_type_via_symbol_path (
                                                            symbolmapstack,
                                                            syp::SYMBOL_PATH symbols,
                                                            error_fn  source_code_region
                                                        );

                                                case type
                                                    #
                                                    tdt::SUM_TYPE { kind => tdt::SUMTYPE _, ... }
                                                        =>
                                                        {   dcons =   tu::extract_sumtype type;
                                                            #
                                                            env_dcons
                                                                =
                                                                fold_forward (\\ (d as tdt::VALCON { name, ... }, e)
                                                                             =
                                                                             syx::bind (
                                                                                 name,
                                                                                 sxe::NAMED_CONSTRUCTOR d,
                                                                                 e
                                                                             )
                                                                      )
                                                                      syx::empty dcons;

                                                            symbolmapstack'
                                                                =
                                                                syx::bind (
                                                                    name_symbol,
                                                                    sxe::NAMED_TYPE type,
                                                                    env_dcons
                                                                );

                                                            module_stamp  =   make_fresh_stamp ();

                                                            stamp_of_type =   mj::typestamp_of  type;

                                                            my  ( ee_dec,
                                                                  ee_env
                                                                )
                                                                =
                                                                case syntactic_typechecking_context
                                                                    #
                                                                    trj::IN_GENERIC _
                                                                        =>
                                                                        {   texp = case (spc::find_stamppath_for_type (stamppath_context, stamp_of_type))
                                                                                       #
                                                                                       NULL          =>   mld::CONSTANT_TYPE  type;
                                                                                       THE stamppath =>   mld::TYPEVAR_TYPE   stamppath;
                                                                                   esac;

                                                                            (  mld::TYPE_DECLARATION (module_stamp, texp),
                                                                               tro::set (
                                                                                 tro::empty,
                                                                                 module_stamp,
                                                                                 mld::TYPE_ENTRY type
                                                                               )
                                                                            );
                                                                        };

                                                                    _ => (mld::EMPTY_GENERIC_EVALUATION_DECLARATION, tro::empty);
                                                                esac;

                                                            result_declaration
                                                                =
                                                                ds::SUMTYPE_DECLARATIONS {
                                                                    sumtypes => [ type ],
                                                                    with_types  => [ ]
                                                                };

                                                            spc::bind_typepath (stamppath_context, stamp_of_type, module_stamp);

                                                            (result_declaration, symbolmapstack', ee_dec, ee_env);
                                                        };

                                                   _ => no_sumtype ();
                                                esac;
                                            };
                                    esac;
                                };

                            _ => {   error_fn
                                          source_code_region
                                          err::ERROR
                                          "argument type variables in sumtype replication"
                                          err::null_error_body;

                                      (   ds::SEQUENTIAL_DECLARATIONS [],
                                          syx::empty,
                                          mld::ERRONEOUS_ENTRY_DECLARATION,
                                          tro::empty
                                      );
                                  };
                        esac;


                    raw::SOURCE_CODE_REGION_FOR_DECLARATION (declaration', source_code_region')
                        =>
                        type_declaration' (
                            declaration',
                            symbolmapstack,
                            typerstore0,
                            syntactic_typechecking_context,
                            top,
                            stamppath_context,
                            inverse_path,
                            source_code_region',
                            per_compile_stuff
                        );

                    declaration
                        =>
                        (   {   is_free =   case syntactic_typechecking_context 
                                                #
                                                trj::IN_GENERIC _
                                                    =>
                                                    (   \\ type
                                                           =
                                                           case (spc::find_stamppath_for_type (
                                                                    stamppath_context,
                                                                    mj::typestamp_of type
                                                                ))

                                                                THE _ => TRUE; 
                                                               _      => FALSE;
                                                           esac

                                                    );

                                                _ => (\\ _ = FALSE);
                                            esac;

                                my  ( declaration,
                                      symbolmapstack''
                                    )
                                    =
                                    tcl::type_declaration
                                      (
                                        declaration,
                                        symbolmapstack,
                                        is_free, 
                                        inverse_path,
                                        source_code_region,
                                        per_compile_stuff
                                      )
                                      except
                                          tro::UNBOUND =  {   if_debugging_say ("@@tcl::type_declaration  [type-package-language-g.pkg] ");
                                                              raise exception tro::UNBOUND;
                                                          };

                                                                                                                                if_debugging_say
                                                                                                                                    (   "type_declaration'/declaration  [type-package-language-g.pkg] [after tcl::type_declaration: top=" 
                                                                                                                                    +   (bool::to_string top)
                                                                                                                                    +   "]"
                                                                                                                                    );
                                declaration'   =   deep_syntax_transform declaration;
                                                                                                                                if_debugging_say "type_declaration'/declaration [type-package-language-g.pkg] [after deep_syntax_transform]";
                                declaration''
                                    =
                                    tcd::type_core_language_declaration                                                         # SIDE-EFFECTS:  Sets tdt::TYPEVAR_REF.ref_typevar (in unify_typoids)   and   vac::PLAIN_VARIABLE.vartypoid_ref (in generalize_*).
                                      {
                                        symbolmapstack   =>  syx::atop (symbolmapstack'', symbolmapstack),
                                        declaration      =>  declaration',
                                        outside_all_lets =>  top,
                                        error_function   =>  error_fn,
                                        source_code_region
                                      }
                                    except
                                        tro::UNBOUND
                                            =
                                            {   if_debugging_say("@@type_core_language_declaration  [type-package-language-g.pkg] ");
                                                raise exception tro::UNBOUND;
                                            };
                                                                                                                                if_debugging_say "type_declaration'/declaration [after type_core_language_declaration]  [type-package-language-g.pkg] ";

                               ( declaration'',                                                 # Typechecked version of  raw_declaration.
                                 symbolmapstack'',                                              # Contains (only) stuff from raw_declaration.
                                 mld::EMPTY_GENERIC_EVALUATION_DECLARATION,
                                 tro::empty
                               );
                           }
                           except
                               tro::UNBOUND
                                   =
                                   {   if_debugging_say("@@type_declaration': Core_Declaration  [type-package-language-g.pkg] ");
                                       raise exception tro::UNBOUND;
                                   }
                        );
                esac;
            };                          # fun type_declaration'



            #  The top-level wrapper of the type_declaration' function: 
            #
            fun type_declaration                                                                                                # Called (only) from type_declaration   in   src/lib/compiler/front/typer/main/translate-raw-syntax-to-deep-syntax-g.pkg 
                  {
                    raw_declaration,                                                    # Declaration being typechecked.
                    symbolmapstack,
                    typerstore,
                    syntactic_typechecking_context,
                    level,
                    stamppath_context,
                    path,
                    source_code_region,
                    per_compile_stuff
                  }
                =
                {
                                                                                                                                if *debugging
                                                                                                                                    #
                                                                                                                                    unparse_raw_declaration
                                                                                                                                        (
                                                                                                                                          "type_declaration/AAA: unparsing declaration raw syntax:  [type-package-language-g.pkg]\n",
                                                                                                                                          raw_declaration,
                                                                                                                                          symbolmapstack
                                                                                                                                        );

                                                                                                                                    prettyprint_raw_declaration
                                                                                                                                        (
                                                                                                                                          "type_declaration/AAA: prettyprinting declaration raw syntax:  [type-package-language-g.pkg] \n",
                                                                                                                                          raw_declaration,
                                                                                                                                          symbolmapstack
                                                                                                                                        );
                                                                                                                                fi;

                    my  ( deep_syntax_declaration,                                      # Typechecked version of  raw_declaration.
                          symbolmapstack,                                               # Contains (only) stuff from raw_declaration.
                          _,
                          _
                        )
                        = 
                        type_declaration'
                          (
                            raw_declaration,                                            # Declaration being typechecked.
                            symbolmapstack,                                             # Symbol table containing info from all .compiled files we depend on.
                            typerstore,
                            syntactic_typechecking_context,
                            level, 
                            stamppath_context,
                            path,
                            source_code_region,
                            per_compile_stuff
                         );

                    { deep_syntax_declaration,                                          # Typechecked version of  raw_declaration.
                      symbolmapstack                                                    # Contains (only) stuff from raw_declaration.
                    };
                };
    };                                                                                  # generic package type_package_language_g 
end;                                                                                    # stipulate










Comments and suggestions to: bugs@mythryl.org

PreviousUpNext