PreviousUpNext

15.4.76  src/app/makelib/main/makelib-g.pkg

## makelib-g.pkg

# Compiled by:
#     src/app/makelib/makelib.sublib


# This module constitutes our standard

#     makelib application + compiler + interactive system
#
# which is to say, what winds up as the
#
#     bin/mythryld
#
# "executable" (heap image).
#
# We use this application to make+compile everything
# -except- itself.  (Compiling the Mythryl compiler itself
# involves special cases which are handled by the special
#
#        src/app/makelib/mythryl-compiler-compiler/mythryl-compiler-compiler-g.pkg
#
# facility.)
#
# This is the module that actually puts together
# the contents of the
#     pkg makelib
# people find in
#     src/lib/core/makelib/makelib.lib
# which is to say, the set of makelib::* types, functions and values
# visible from the mythryld prompt at runtime.
#
# For example, if you run
#     bin/mythryld
# and then enter
#     makelib::makelib_state::show_all (); 
# at the interactive prompt, you'll invoke the
# show_all fun defined in this file, which
# lists all toplevel symbols.
#
# The code in this file is almost all lightweight
# stuff -- commandline switch parsing and top-level
# glue logic hooking together functionality implemented
# elsewhere.
#
# The major functionality imvoked here is doing the dagwalks
# of the sourcefile dependency graph so as to compile no sourcefile
# until all files it depends upon have been compiled, making the
# type information etc in those files available.  This process is
# somewhat obscured by the "server" facility to allow compiling
# multiple sourcefiles in parallel using multiple Unix subprocesses
# (optionally on separate machines).  This facility appears broken.
#
# The actual dagwalk functionality is largely implemented in
#
#     src/app/makelib/compile/compile-in-dependency-order-g.pkg
#     src/app/makelib/compile/link-in-dependency-order-g.pkg
#
#
# generic invocation context:
#
#     The generic we define is invoked (only) in
#
#         src/lib/core/internal/makelib-internal.pkg
#
#     which consists of the single statement
#
#        package makelib_internal = makelib_g (package mythryl_compiler = mythryl_compiler)
#
#     makelib_internal is used in four places (lumping all the platform files together):
#
#         src/lib/core/mythryl-compiler-compiler/mythryl-compiler-compiler-for-intel32-posix.pkg:      load_plugin = makelib_internal::load_plugin
#         src/lib/core/internal/make-mythryl-compiler-etc.pkg:                                     package make_mythryl_compiler_etc = make_mythryl_compiler_etc_g
#         src/lib/core/makelib/makelib.pkg:                                                        package makelib: Makelib = makelib_internal::makelib
#         src/lib/core/makelib/tools.pkg:                                                          package tools: Tools = makelib_internal::tools
#
# generic argument:
#
#     "mythryl_compiler" is defined by
#
#             package mythryl_compiler = mythryl_compiler_for_intel32_posix;
#         in
#             src/lib/core/compiler/set-mythryl_compiler-to-mythryl_compiler_for_intel32_posix.pkg
#
#         which gets conditionally included by
#
#             src/lib/core/compiler/mythryl-compiler-for-this-platform.lib
#
#         (The above is for "intel32-linux";
#          other platforms are similar.)
#
#
#
# Runtime invocation context:
#
#     The two most important runtime
#     entrypoints in this file are our
#         make
#         compile
#     functions, which are respectively invoked by typing
#         make    "foobar.lib"
#         compile "foobar.lib"
#     at the interactive prompt.
#
#
#
#     We also export a
#
#         read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries
#
#     function which is indirectly invoked by 
#
#         src/lib/core/internal/make-mythryld-executable.pkg
#
#     shortly before dumping the heap image which
#     generates the compiler "executable" heap image.



###            "The most important difference is not that
###             the good programmers are better at getting
###             out of trouble, but that the poor ones are
###             better at getting into it."



###            "Mithril is the fantasy version of unobtainium."


stipulate
    package acf =  anormcode_form;                                      # anormcode_form                                is from   src/lib/compiler/back/top/anormcode/anormcode-form.pkg
    package ad  =  anchor_dictionary;                                   # anchor_dictionary                             is from   src/app/makelib/paths/anchor-dictionary.pkg
    package cmd =  commandline;                                         # commandline                                   is from   src/lib/std/commandline.pkg
    package cms =  compiler_mapstack_set;                               # compiler_mapstack_set                         is from   src/lib/compiler/toplevel/compiler-state/compiler-mapstack-set.pkg
    package cs  =  compiler_state;                                      # compiler_state                                is from   src/lib/compiler/toplevel/interact/compiler-state.pkg
    package ds  =  deep_syntax;                                         # deep_syntax                                   is from   src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.pkg
    package err =  error_message;                                       # error_message                                 is from   src/lib/compiler/front/basics/errormsg/error-message.pkg
    package f8b =  eight_byte_float;                                    # eight_byte_float                              is from   src/lib/std/eight-byte-float.pkg
    package fcx =  find_set_of_compiled_files_for_executable;           # find_set_of_compiled_files_for_executable     is from   src/app/makelib/mythryl-compiler-compiler/find-set-of-compiledfiles-for-executable.pkg
    package fil =  file__premicrothread;                                # file__premicrothread                          is from   src/lib/std/src/posix/file--premicrothread.pkg
    package fp  =  filename_policy;                                     # filename_policy                               is from   src/app/makelib/main/filename-policy.pkg
    package fzp =  freeze_policy;                                       # freeze_policy                                 is from   src/app/makelib/parse/freeze-policy.pkg
    package im  =  int_map;                                             # int_map                                       is from   src/app/makelib/stuff/int-map.pkg
    package it  =  import_tree;                                         # import_tree                                   is from   src/lib/compiler/execution/main/import-tree.pkg
    package lg  =  inter_library_dependency_graph;                      # inter_library_dependency_graph                is from   src/app/makelib/depend/inter-library-dependency-graph.pkg
    package lgr =  logger;                                              # logger                                        is from   src/lib/src/lib/thread-kit/src/lib/logger.pkg
    package llp =  lib_load_path;                                       # lib_load_path                                 is from   src/app/makelib/main/lib-load-path.pkg
    package lms =  list_mergesort;                                      # list_mergesort                                is from   src/lib/src/list-mergesort.pkg
    package lsi =  library_source_index;                                # library_source_index                          is from   src/app/makelib/stuff/library-source-index.pkg
    package lt  =  linking_mapstack;                                    # linking_mapstack                              is from   src/lib/compiler/execution/linking-mapstack/linking-mapstack.pkg
    package mcc =  mythryl_compiler_compiler_configuration;             # mythryl_compiler_compiler_configuration       is from   src/app/makelib/mythryl-compiler-compiler/mythryl-compiler-compiler-configuration.pkg
    package mcv =  mythryl_compiler_version;                            # mythryl_compiler_version                      is from   src/lib/core/internal/mythryl-compiler-version.pkg
    package mld =  makelib_defaults;                                    # makelib_defaults                              is from   src/app/makelib/stuff/makelib-defaults.pkg
    package ms  =  makelib_state;                                       # makelib_state                                 is from   src/app/makelib/main/makelib-state.pkg
    package mtq =  makelib_thread_boss;                                 # makelib_thread_boss                           is from   src/app/makelib/concurrency/makelib-thread-boss.pkg
    package myp =  mythryl_parser;                                      # mythryl_parser                                is from   src/lib/compiler/front/parser/main/mythryl-parser.pkg
    package pcs =  per_compile_stuff;                                   # per_compile_stuff                             is from   src/lib/compiler/front/typer-stuff/main/per-compile-stuff.pkg
    package ph  =  picklehash;                                          # picklehash                                    is from   src/lib/compiler/front/basics/map/picklehash.pkg
    package plp =  platform_properties;                                 # platform_properties                           is from   src/lib/std/src/nj/platform-properties.pkg
    package pp  =  standard_prettyprinter;                              # standard_prettyprinter                        is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg
    package ps  =  pervasive_symbol;                                    # pervasive_symbol                              is from   src/app/makelib/main/pervasive-symbol.pkg
    package psx =  posixlib;                                            # posixlib                                      is from   src/lib/std/src/psx/posixlib.pkg
    package pth =  winix__premicrothread::path;                         # winix__premicrothread                         is from   src/lib/std/winix--premicrothread.pkg
    package raw =  raw_syntax;                                          # raw_syntax                                    is from   src/lib/compiler/front/parser/raw-syntax/raw-syntax.pkg
    package sci =  sourcecode_info;                                     # sourcecode_info                               is from   src/lib/compiler/front/basics/source/sourcecode-info.pkg
    package seg =  code_segment;                                        # code_segment                                  is from   src/lib/compiler/execution/code-segments/code-segment.pkg
    package sg  =  intra_library_dependency_graph;                      # intra_library_dependency_graph                is from   src/app/makelib/depend/intra-library-dependency-graph.pkg
    package sj  =  string_junk;                                         # string_junk                                   is from   src/lib/std/src/string-junk.pkg
    package sm  =  string_map;                                          # string_map                                    is from   src/lib/src/string-map.pkg
    package sma =  supported_architectures;                             # supported_architectures                       is from   src/lib/compiler/front/basics/main/supported-architectures.pkg
    package spm =  source_path_map;                                     # source_path_map                               is from   src/app/makelib/paths/source-path-map.pkg
    package sps =  source_path_set;                                     # source_path_set                               is from   src/app/makelib/paths/source-path-set.pkg
    package sy  =  symbol;                                              # symbol                                        is from   src/lib/compiler/front/basics/map/symbol.pkg
    package sym =  symbol_map;                                          # symbol_map                                    is from   src/app/makelib/stuff/symbol-map.pkg
    package syx =  symbolmapstack;                                      # symbolmapstack                                is from   src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg
    package tc  =  thawedlib_tome;                                      # thawedlib_tome                                is from   src/app/makelib/compilable/thawedlib-tome.pkg
    package tmp =  highcode_codetemp;                                   # highcode_codetemp                             is from   src/lib/compiler/back/top/highcode/highcode-codetemp.pkg
    package wnx =  winix__premicrothread;                               # winix__premicrothread                         is from   src/lib/std/winix--premicrothread.pkg

    # Logging support.  To log messages from this file scatter
    #
    #     to_log {. sprintf "Whatever"; };                              # Do not add trailing newline to message string.
    #
    # calls through the code as appropriate and then either
    # uncomment the below
    #
    #     my _ = lgr::enable  makelib_logging;
    #
    # line or do
    #
    #     logger::enable  (the (logger::find_logtree_node_by_name "makelib::logging"));
    #
    # from the Mythryl interactive prompt.
    #
    makelib_logging
        =
        lgr::make_logtree_leaf
          {
            parent  =>  fil::all_logging,
            name    =>  "makelib::logging",
            default =>   FALSE                                          # Change to true or call  (lgr::enable makelib_logging)   to enable logging in this file.
          };
    #
    to_log =  lgr::log_if  makelib_logging  0;
herein

    generic package   makelib_g (
        #                                                               # "myc" == "mythryl_compiler".
        package myc:                    Mythryl_Compiler;               # Mythryl_Compiler                              is from   src/lib/compiler/toplevel/compiler/mythryl-compiler.api
                                                                        # mythryl_compiler_for_intel32_posix            is from   src/lib/compiler/toplevel/compiler/mythryl-compiler-for-intel32-posix.pkg
    )
    {
        stipulate
            #
            os_kind  = plp::get_os_kind ();                             # UNIX | WIN32 | OS2;

            # Set platform to "intel32-posix" or such:
            #
            platform
                =
                cat [
                    architecture_name,                                  # "pwrpc32"/"sparc32"/"intel32".
                    "-",
                    fp::os_kind_to_string  os_kind
                ]
                where
                    architecture_name =  sma::architecture_name  myc::target_architecture;
                end;

            # Set up a little dictionary defining
            # half a dozen platform properties
            # like architecture ("intel32" or such):
            #
            package mps                                                 # "mps" == "makelib preprocessor state"
                =
                makelib_preprocessor_state_g (                          # makelib_preprocessor_state_g                                          is from   src/app/makelib/main/makelib-preprocessor-state-g.pkg
                    #
                    architecture =  myc::target_architecture;           # PWRPC32/SPARC32/INTEL32.
                    os_kind      =  os_kind;
                    abi_variant  =  myc::abi_variant;
                );


            #############################################################################
            #
            # 'seed_libraries_index__local' gets loaded by read_picklehash_map() from
            #
            #     $ROOT/LIBRARY_CONTENTS
            #
            # and constitutes our master index to the complete
            # contents of the set of seed libraries used to bootstrap
            # the Mythryl system.
            #
            # The   seed_libraries_index__local   index is structured as a map
            #
            #     ad::File -> int_map::Map(cms::Linking_Mapstack)
            #
            # which, given the ad::File equivalent of (say)
            #
            #     $ROOT/src/lib/core/internal/makelib-internal.lib
            #
            # gives us back a summary of the pickle-by-pickle (== compiledfile-by-compiledfile)
            # contents of the corresponding freezefile
            #
            #     $ROOT/src/lib/core/internal/makelib-internal.lib.frozen
            #
            # essentially in the form of a list of triples
            #
            #     (byte_offset_in_freezefile:Int, Picklehash, pickle:Chunk)
            #
            # (The actual structure is an intmap from byte offsets to
            # singleton Linking_Mapstacks associating picklehash to pickle chunk.)
            #
            seed_libraries_index__local
                =
                REF (spm::empty:   spm::Map(  int_map::Map(cms::Linking_Mapstack) ));           #  XXX BUGGO FIXME more icky thread-hostile mutable global state :-/

                                                                                                # int_map                                       is from   src/app/makelib/stuff/int-map.pkg
            # "A central index of freezefile symbol tables,
            # stored in packed stampmapstack form:"
            #
            package ffr                                                                         # XXX BUGGO FIXME more thread-hostile mutable global storage. :-(
                =                                                                               # stampmapstack                                 is from   src/lib/compiler/front/typer-stuff/modules/stampmapstack.pkg
                freezefile_roster_g ();                                                         # freezefile_roster_g                           is from   src/app/makelib/freezefile/freezefile-roster-g.pkg



            read_eval_print_from_stream__hook                                                   # This gets set just once during initialization, below in read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries,
                =                                                                               # so it isn't a problem for concurrent operation.
                REF (\\ _ = {   msg = "read_eval_print_from_stream__hook not set!"              # This hook winds up pointing to   read_eval_print_from_stream          from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg    
                                    + " --makelib-g.pkg";
                                log::fatal msg;
                                raise exception DIE msg;
                            }
                    )
                :
                Ref( fil::Input_Stream -> Void );

            parse_string_to_raw_declarations__hook                                              # This gets set just once during initialization, below in read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries,
                =                                                                               # so it isn't a problem for concurrent operation.
                REF (\\ _ = {   msg = "parse_string_to_raw_declarations__hook"                  # This hook winds up pointing to   parse_string_to_raw_declarations     from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg    
                                    + "not set! --makelib-g.pkg";
                                log::fatal msg;
                                raise exception DIE  msg;
                            }
                    )
                :
                Ref(  { sourcecode_info:        sci::Sourcecode_Info,
                        pp:                     pp::Prettyprinter                                                       # Where to prettyprint results.
                      }
                      ->
                      List( raw::Declaration )
                   );

            compile_raw_declaration_to_package_closure__hook                                                            # 
              =
              REF (\\ _ = {   msg = "compile_raw_declaration_to_package_closure__hook"                                  # This hook winds up pointing to   compile_raw_declaration_to_package_closure   from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg    
                                  + "not set! --makelib-g.pkg";
                              log::fatal msg;
                              raise exception DIE  msg;
                          }
                  )
              : 
              Ref (     
                      {                                                                                                 # 
                        declaration:                            raw::Declaration,                                       #
                        sourcecode_info:                        sci::Sourcecode_Info,                                   # Source code to compile, also error sink.
                        pp:                                     pp::Prettyprinter,                                      # Where to prettyprint results.
                        compiler_state_stack:                   (cs::Compiler_State, List(cs::Compiler_State)),         # Compiler symbol tables to use for this compile.
                        options:                                List( cs::Compile_And_Eval_String_Option )              # Future-proofing, lets us add more parameters in future without breaking backward compatibility at the client-call level.
                      }                                                                                                 #
                      ->
                      Null_Or(
                          { package_closure:                    seg::Package_Closure,
                            import_trees:                       List( it::Import_Tree ),
                            export_picklehash:                  Null_Or( ph::Picklehash ),
                            linking_mapstack:                   lt::Picklehash_To_Heapchunk_Mapstack,
                            code_and_data_segments:             seg::Code_And_Data_Segments,
                            new_symbolmapstack:                 syx::Symbolmapstack,                                    # A symbol table delta containing (only) stuff from raw_declaration.
                            deep_syntax_declaration:            ds::Declaration,                                        # Typechecked form of  raw_declaration.
                            exported_highcode_variables:        List( tmp::Codetemp ),
                            inline_expression:                  Null_Or( acf::Function ),
                            top_level_pkg_etc_defs_jar:         cs::Compiler_Mapstack_Set_Jar,
                            get_current_compiler_mapstack_set:  Void -> cs::Compiler_Mapstack_Set,
                            compiler_verbosity:                 pcs::Compiler_Verbosity,
                            compiler_state_stack:               (cs::Compiler_State, List(cs::Compiler_State))
                          }
                      )
                  );

            link_and_run_package_closure__hook                                                                          # 
              =
              REF (\\ _ = {   msg = "link_and_run_package_closure__hook"                                                # This hook winds up pointing to   link_and_run_package_closure from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg    
                                  + "not set! --makelib-g.pkg";
                              log::fatal msg;
                              raise exception DIE  msg;
                          }
                  )
              : 
              Ref (   { sourcecode_info:                        sci::Sourcecode_Info,                                   # Source code to compile, also error sink.
                        pp:                                     pp::Prettyprinter                                       # Where to prettyprint results.
                      } 
                      ->        
                      { package_closure:                        seg::Package_Closure,
                        import_trees:                           List( it::Import_Tree ),
                        export_picklehash:                      Null_Or( ph::Picklehash ),
                        linking_mapstack:                       lt::Picklehash_To_Heapchunk_Mapstack,
                        code_and_data_segments:                 seg::Code_And_Data_Segments,
                        new_symbolmapstack:                     syx::Symbolmapstack,                                    # A symbol table delta containing (only) stuff from raw_declaration.
                        deep_syntax_declaration:                ds::Declaration,                                        # Typechecked form of  raw_declaration.
                        exported_highcode_variables:            List( tmp::Codetemp ),
                        inline_expression:                      Null_Or( acf::Function ),
                        top_level_pkg_etc_defs_jar:             cs::Compiler_Mapstack_Set_Jar,
                        get_current_compiler_mapstack_set:      Void -> cs::Compiler_Mapstack_Set,
                        compiler_verbosity:                     pcs::Compiler_Verbosity,
                        compiler_state_stack:                   (cs::Compiler_State, List(cs::Compiler_State))          # Compiler symbol tables to use for this compile.
                      }                                                                                                 #
                      ->                                                                                                #
                      (cs::Compiler_State, List(cs::Compiler_State))                                                    # Updated compiler symbol tables.  Caller may keep or discard.
                  );





            # 2008-02-24 CrT:  This is a quick hack to get the eval definition
            #                  from where I can get it to where I want it.  A
            #                  cleaner mechanism would be cool. XXX BUGGO FIXME.
            #
            #                  (I don't intend ever changing this pointer
            #                  once set, so this is not really an example
            #                  of problematic global state.)
            #
            my eval_hook : Ref(String -> Void)
                         = REF (\\ _ = ());


            package cdo                                                                         # "cdo" == 'compile_(in_)dependency_order".
                =
                compile_in_dependency_order_g (                                                 # compile_in_dependency_order_g                 is from   src/app/makelib/compile/compile-in-dependency-order-g.pkg
                    #                                                                           # mythryl_compiler_for_intel32_posix            is from   src/lib/compiler/toplevel/compiler/mythryl-compiler-for-intel32-posix.pkg
                    package myc =  myc;                                                         # "myc" == "mythryl_compiler".
                    package ffr =  ffr;                                                         # "ffr" == "freezefile_roster".
                    #
                    fun read_eval_print_from_stream   stream
                        =
                        *read_eval_print_from_stream__hook   stream;                            # This hook winds up pointing to read_eval_print_from_stream    from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg    
                );

            package t2c                                                                         # "t2c" == "thawedlib_tome to compiledfile".
                =
                thawedlib_tome__to__compiledfile__map_g (                                       # thawedlib_tome__to__compiledfile__map_g       is from   src/app/makelib/compile/thawedlib-tome--to--compiledfile-contents--map-g.pkg
                    #
                    architecture =   myc::target_architecture;                                  # PWRPC32/SPARC32/INTEL32. (Used in compiledfile::read_compiledfile to check that we're loading compiled code for the right architecture.)
                );


            package ltw                                                                         # "ltw" == "linking dagwalk".
                =
                link_in_dependency_order_g (                                                    # link_in_dependency_order_g                    is from   src/app/makelib/compile/link-in-dependency-order-g.pkg
                    #
                    package thawedlib_tome__to__compiledfile__map =  t2c;
                    #
                    seed_libraries_index__local = seed_libraries_index__local;
                );
            #
            drop_thawedlib_tome_from_linker_map
                =
                ltw::drop_thawedlib_tome_from_linker_map;


            stipulate
                find_files
                    =   
                    fcx::find_set_of_compiled_files_for_executable
                        #
                        (\\ filepath = filepath);                                               # Null filename transform.
            herein

                make_bootlist
                    =
                    .l   o   find_files;
            end;


            # This is the 'dagwalker' function
            # for the 'compile' function implementing
            #
            #     makelib::compile "foo.lib"
            #
            fun dagwalker_for_compile_command
                    #
                    (makelib_state:     ms::Makelib_State)
                    #
                    (root_library:      lg::Inter_Library_Dependency_Graph)                     # Freshly read in by parse_libfile_tree_and_return_interlibrary_dependency_graph from   src/app/makelib/parse/libfile-parser-g.pkg
                =
                {
                    my { compile_library_catalog_in_dependency_order, ... }
                        =
                        cdo::make_dependency_order_compile_fns
                          {
                            root_library,
                            #   
                            maybe_drop_thawedlib_tome_from_linker_map
                               => drop_thawedlib_tome_from_linker_map,                          # Sometimes we pass in a dummy, but not here.
                            #   
                            set__compiledfile__for__thawedlib_tome
                                =>
                                \\ _ = ()                                                       # Dummy.
                          };

                    {
                        not_null (compile_library_catalog_in_dependency_order  makelib_state);
                    }
                    then
                        {
                            ltw::cleanup makelib_state;
                        };
                };

                                                                                                # make_dependency_order_compile_fns     is from   src/app/makelib/compile/compile-in-dependency-order-g.pkg
                                                                                                # evict                                 is from   src/app/makelib/compile/link-in-dependency-order-g.pkg

            # This is the 'dagwalker' function for the 'make' function implementing
            #     makelib::make "foo.lib"
            # It combines the actions of "compile" and "exec".
            # When successful, it combines the results
            # (thus forming a full dictionary) and adds
            # it to the toplevel dictionary.
            #
            fun dagwalker_for_make_command
    # MUSTDIE add_namings is probably part of the problem:
                    (add_namings:       Bool)                                                   # Bool: 'TRUE' for regular commandline make, 'FALSE' when called from load_plugin' 
                    (makelib_state:     ms::Makelib_State)
                    (root_library as lg::LIBRARY _)                                             # The result of   (parse_libfile_tree_and_return_interlibrary_dependency_graph  foo.lib) 
                =>
                {
                    (t2c::make__thawedlib_tome__to__compiledfile__map ())                       # cc is defined at top of file.
                        ->
                        { set__compiledfile__for__thawedlib_tome,
                          get__compiledfile__for__thawedlib_tome
                        };

                    # Both of the next two calls return
                    # fates, which must be called
                    # with a makelib_state argument in order
                    # to actually obtain a useful result:
                    #
                    my { compile_library_catalog_in_dependency_order =>  compile_my_library, ... }
                        =
                        cdo::make_dependency_order_compile_fns
                          {
                            root_library,
                            #
                            maybe_drop_thawedlib_tome_from_linker_map
                               => drop_thawedlib_tome_from_linker_map,                          # Sometimes we pass in a dummy, but not here.
                            #
                            set__compiledfile__for__thawedlib_tome
                          };

                    my { linking_mapstack => linking_fate, ... }
                        =
                        ltw::make_linking_dagwalk (
                            root_library,
                            .compiledfile o get__compiledfile__for__thawedlib_tome
                        );


                    case (compile_my_library  makelib_state)
                        #
#                       NULL => FALSE;
                        NULL =>
                            {
                                FALSE;
                            };  
                        #
                        THE { symbolmapstack, inlining_mapstack }
                            =>
                            {
                                ltw::cleanup  makelib_state;

                                                           # string_set                         is from   src/lib/src/string-set.pkg



                                case (linking_fate  makelib_state)
                                    #
                                    THE linking_mapstack
                                        =>
                                        {
                                            if add_namings
                                                #
                                                compiler_mapstack_set_differences
                                                    =
                                                    cms::make_compiler_mapstack_set { 
                                                        symbolmapstack,
                                                        linking_mapstack,
                                                        inlining_mapstack
                                                    };


                                                top_level_pkg_etc_defs_jar =  cs::get_top_level_pkg_etc_defs_jar ();
                                                base_compiler_mapstack_set    =  top_level_pkg_etc_defs_jar.get_mapstack_set ();

                                                new_compiler_mapstack_set
                                                    =
                                                    cms::concatenate_compiler_mapstack_sets
                                                      (
                                                        compiler_mapstack_set_differences,
                                                        base_compiler_mapstack_set
                                                      );

                                                top_level_pkg_etc_defs_jar.set_mapstack_set  new_compiler_mapstack_set;

                                                fil::say {. "                           makelib-g.pkg:   New names added."; };
                                            fi;

                                            TRUE;
                                        };

                                    NULL => FALSE;
                                esac;
                            };
                    esac;
                };

                dagwalker_for_make_command _ _ lg::BAD_LIBRARY
                    =>
                    FALSE;
            end;


            package fzf                                                                 # "fzf" == "freezefile".
                =
                freezefile_g (                                                          # freezefile_g                                  is from   src/app/makelib/freezefile/freezefile-g.pkg
                    #
                    architecture =   myc::target_architecture;                          # PWRPC32/SPARC32/INTEL32.
                    #
                    package ffr =  ffr;                                                 # "ffr" == "freezefile_roster".


                                                                                        # thawedlib_tome__to__compiledfile__map_g       is from   src/app/makelib/compile/thawedlib-tome--to--compiledfile-contents--map-g.pkg
                    # A function which allows
                    #
                    #     freezefile::save_freezefile
                    #
                    # to compile any thawed library
                    # handed to it, one tome at a time:
                    #
                    fun compile_library
                            #
                            (makelib_state:   ms::Makelib_State)
                            #
                            (root_library:    lg::Inter_Library_Dependency_Graph)
                        =
                        {   (t2c::make__thawedlib_tome__to__compiledfile__map ())
                                ->
                                { set__compiledfile__for__thawedlib_tome,
                                  get__compiledfile__for__thawedlib_tome
                                };
                                

                            my { compile_library_catalog_in_dependency_order =>  compile_my_library, ... }
                                =
                                cdo::make_dependency_order_compile_fns
                                  {
                                    root_library,
                                    #
                                    maybe_drop_thawedlib_tome_from_linker_map
                                       => drop_thawedlib_tome_from_linker_map,
                                    #
                                    set__compiledfile__for__thawedlib_tome
                                  };

                            case (compile_my_library  makelib_state)
                                #
                                THE _ =>  THE get__compiledfile__for__thawedlib_tome;
                                NULL  =>  NULL;
                            esac;
                        };

                    get_symbol_and_inlining_mapstacks
                        =
                        cdo::get_symbol_and_inlining_mapstacks;
                );


            # "Access to the library-building mechanism
            #  is integrated into the .lib file parser.
            #
            # "I'm not sure if this is the cleanest way,
            #  but it works well enough."               -- Matthias Blume
            #
            package lfp                                                                                 # "lfp" == "libfile parser"
                =
                libfile_parser_g (                                                                      # libfile_parser_g      is from   src/app/makelib/parse/libfile-parser-g.pkg
                    #
                    package freezefile        =  fzf;
                    package freezefile_roster =  ffr;
                    #
                    fun drop_stale_entries_from_compiler_and_linker_maps ()
                        =
                        {   cdo::drop_stale_entries_from_compiler_map ();
                            ltw::drop_stale_entries_from_linker_map   ();
                        };
                );


            stipulate

                Primordial_Library_Dependency_Graph
                    =
                    { primordial_library: lg::Inter_Library_Dependency_Graph };


                filename_policy =   fp::policy;
                                                                                                        # filename_policy       is from   src/app/makelib/main/filename-policy.pkg

                primordial_library_hook
                    =
                    REF (NULL: Null_Or( Primordial_Library_Dependency_Graph ));

            herein
                anchor_dictionary =   ad::dictionary;

                #
                fun make_standard_source_path   file_path                                               # E.g. "$ROOT/src/lib/core/init/init.cmi"   or   "$ROOT/src/lib/std/standard.lib"
                    =                                                                                   # or   "$ROOT/src/lib/core/mythryl-compiler-compiler/mythryl-compiler-compiler-for-this-platform.lib"
                    case (llp::search_lib_load_path_for_file  file_path)
                        #
                        THE file_path   =>  ad::from_standard  anchor_dictionary  file_path;            # Found file on MYTHRYL_LIB_LOAD_PATH (or default value for it) so use expansion for it.
                        NULL            =>  ad::from_standard  anchor_dictionary  file_path;            # Did not find file via new lib-load-path facility, so fall back to Matthias Blume's old anchor-dictionary mechanism.
                    esac;

                #
                fun show_api  (api_name: String)
                    =
                    {
                        symbolmapstack
                            =
                            compiler_mapstack_set::symbolmapstack_part
                                (cs::combined ());

                        symbol =   sy::make_api_symbol  api_name;

                        case (symbolmapstack::get  (symbolmapstack, symbol))
                            #
                            symbolmapstack_entry::NAMED_API a
                                =>
                                {
                                    output_stream
                                      =
                                      { consumer  =>  (\\ string =  fil::write  (fil::stdout,  string)),
                                        flush     =>  {. fil::flush  fil::stdout; },
                                        close     =>  \\ () = ()
                                      };

                                    pp =   pp::make_prettyprinter  output_stream  [];
                                                                                                   # unparse_package_language   is from   src/lib/compiler/front/typer/print/unparse-package-language.pkg
                                    unparse_package_language::unparse_api
                                        pp
                                        (a, symbolmapstack, /* max prettyprint recursion depth: */ 200);

                                    pp::flush_prettyprinter  pp;

                                };

                            _   =>
                                print "                         makelib-g.pkg:show_api: Improbable failure.\n";
                        esac
                        except
                            unbound
                                =
                                print ("No api " + api_name + " defined at top level.\n");

                    };
                #
                fun show_pkg  (pkg_name: String)
                    =
                    {
                        symbolmapstack
                            =
                            compiler_mapstack_set::symbolmapstack_part
                                (cs::combined ());

                        symbol
                            =
                            sy::make_package_symbol  pkg_name;

                        case (symbolmapstack::get  (symbolmapstack, symbol))
                            #
                            symbolmapstack_entry::NAMED_PACKAGE a
                                =>
                                {
                                    output_stream
                                      =
                                      { consumer  =>  (\\ string =  fil::write  (fil::stdout,  string)),
                                        flush     =>  {. fil::flush  fil::stdout; },
                                        close     =>  \\ () = ()        
                                      };

                                    pp =   pp::make_prettyprinter  output_stream  [];

                                    unparse_package_language::unparse_package
                                        pp
                                        (a, symbolmapstack, /* max prettyprint recursion depth: */ 200);

                                    pp::flush_prettyprinter  pp;

                                };
                            #
                            _   =>  print "                         makelib-g.pkg:show_pkg: Improbable failure.\n";
                        esac
                        except
                            unbound
                                =
                                print ("No package " + pkg_name + " defined at top level.\n");

                    };
                                                                                    # symbolmapstack_entry      is from   src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack-entry.pkg
                                                                                    # symbolmapstack            is from   src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg
                                                                                    #   
                                                                                    # compiler_mapstack_set     is from   src/lib/compiler/toplevel/compiler-state/compiler-mapstack-set.pkg
                                                                                    # symbol                    is from   src/lib/compiler/front/basics/map/symbol.pkg
                                                                                    # symbol_map                is from   src/app/makelib/stuff/symbol-map.pkg
                                                                                    #   
                fun show_all ()
                    =
                    {   symbols =  cs::list_bound_symbols ();

                        descriptions
                            =
                            map
                                sy::describe
                                symbols;
                        #
                        fun pr s
                            =
                            fil::say {. s; };

                        fil::say {. "\nTop-level definitions:"; };
                        apply pr descriptions;
                    };

                #
                fun show  title_string  filter_fn
                    =
                    {   symbols  =  cs::list_bound_symbols ();
                        symbols  =  list::filter  filter_fn  symbols;

                        names    =   map
                                         sy::name
                                         symbols;

                        sorted_names =   lms::sort_list   string::(>)   names;
                        #
                        fun pr s
                            =
                            fil::say {. cat [s, " "]; };

                        fil::say {. cat ["\nTop-level ", title_string, " definitions:"]; };
                        apply pr sorted_names;
                        fil::say {. ""; };
                    };

                #
                fun show_vals     () =  show  "val"        (\\ symbol =  (sy::name_space symbol  ==  sy::VALUE_NAMESPACE  ));
                fun show_apis     () =  show  "api"        (\\ symbol =  (sy::name_space symbol  ==  sy::API_NAMESPACE    ));
                fun show_pkgs     () =  show  "pkg"        (\\ symbol =  (sy::name_space symbol  ==  sy::PACKAGE_NAMESPACE));
                fun show_types    () =  show  "type"       (\\ symbol =  (sy::name_space symbol  ==  sy::TYPE_NAMESPACE   ));
                fun show_generics () =  show  "generic"    (\\ symbol =  (sy::name_space symbol  ==  sy::GENERIC_NAMESPACE));


                                                                                    # unparse_compiler_state            is from   src/lib/compiler/front/typer-stuff/symbolmapstack/unparse-compiler-state.pkg
                                                                                    # latex_print_compiler_state        is from   src/lib/compiler/front/typer-stuff/symbolmapstack/latex-print-compiler-state.pkg
                #
                fun dump_api_reference  filename
                    =
                    unparse_compiler_state::unparse_compiler_state_to_file
                        filename;
                #
                fun latex_dump_api_reference
                        { directory,
                          filename_prefix,
                          filename_suffix
                        }
                    =
                    latex_print_compiler_state::latex_print_compiler_state_to_file
                        { directory,
                          filename_prefix,
                          filename_suffix
                        };
                #
                fun get_primordial_library_hook_value ()
                    =
                    the *primordial_library_hook
                    except
                        NULL_OR
                        =
                        raise exception DIE "                     makelib-g.pkg: primordial_library_hook not initialized";
                #
                fun make_makelib_session  { we_are_a_subprocess,  keep_going_after_compile_errors }
                    =
                    {   makelib_thread_boss = mtq::make_makelib_thread_boss ();
                        #
                        { filename_policy,
                          anchor_dictionary,
                          platform,
                          we_are_a_subprocess => REF we_are_a_subprocess,
                          #     
                          find_makelib_preprocessor_symbol =>   mps::find_makelib_preprocessor_symbol,
                          keep_going_after_compile_errors,
                          makelib_thread_boss
                        };
                    };

                primordial_library
                    =
                    .primordial_library  o  get_primordial_library_hook_value;

                                                                                                # makelib_defaults      is from   src/app/makelib/stuff/makelib-defaults.pkg
                                                                                                # libfile_parser_g      is from   src/app/makelib/parse/libfile-parser-g.pkg
                # Maybe delete picklestrings
                # from memory to save ram:
                #
                fun maybe_clear_pickle_cache ()
                    =
                    if (mld::conserve_memory.get ())                                            #  'FALSE' by default, but user-settable. 
                        #
                        lfp::clear_pickle_cache ();
                    fi;

                # Construct an arg record for   parse_libfile_tree_and_return_interlibrary_dependency_graph argument   from   src/app/makelib/parse/libfile-parser-g.pkg
                #
                fun parse_arg_0  we_are_a_subprocess  (library_source_index, freeze_policy, makelib_file_to_read)
                    =
                    { makelib_file_to_read,                                                     #  Primary input to parse_libfile_tree_and_return_interlibrary_dependency_graph fn. 

                      load_plugin,
                      library_source_index,

                      makelib_session
                          =>
                          make_makelib_session
                            {
                              we_are_a_subprocess,
                              keep_going_after_compile_errors =>  mld::keep_going_after_compile_errors.get ()
                            },

                      freeze_policy,                                                            # See explanation in   src/app/makelib/parse/freeze-policy.api

                      primordial_library    =>  primordial_library (),
                      paranoid           =>  FALSE
                    }

                also
                fun parse_arg       x =   parse_arg_0 FALSE x

                also
                fun server_parse_arg x =   parse_arg_0 TRUE  x

                also
                fun run
                        make_src_path                                                           # Always make_standard_source_path.
                        freeze_policy                                                           # One of: fzp::FREEZE_NONE  fzp::FREEZE_ONE  fzp::FREEZE_ALL
                        dagwalker                                                               # dagwalker_for_freeze_command / dagwalker_for_make_command TRUE / dagwalker_for_compile_command
                        libfile_path_string                                                     # E.g. "$ROOT/src/lib/std/standard.lib"
                    =
                    # Read in a .lib library definition file and
                    # apply given 'dagwalker' to the result:
                    #
                    {
                        libfile_path =   make_src_path   libfile_path_string;
                        #
                        library_source_index
                            =
                            lsi::make_library_source_index ();


                        {   fil::say {.
                                cat [
                                    "                           makelib-g.pkg:   Making   library        ",
                                    libfile_path_string
                                ];
                            };

    #                        show_all ();

                            case (lfp::parse_libfile_tree_and_return_interlibrary_dependency_graph
                                     (parse_arg
                                         ( library_source_index,
                                           freeze_policy,
                                           libfile_path
                                         )
                                     ))
                                #
                                THE (library, makelib_state)
                                    =>
                                    {
                                        dagwalker   makelib_state   library;
                                    };
                                #
                                NULL
                                    =>
                                    {
                                        FALSE;
                                    };
                            esac;
                        }
                        then
                            maybe_clear_pickle_cache ();
                    }


                also
                fun load_plugin'  plugin_path
                    =
                    {   plugin_description
                            =
                            ad::describe  plugin_path;

                        fil::say {.
                            cat
                              [
                                  "                               makelib-g.pkg:  Attempting to load plugin ",
                                  plugin_description
                              ];
                        };

                        library_source_index
                            =
                            lsi::make_library_source_index ();

                        succeeded
                            =
                            {   case (lfp::parse_libfile_tree_and_return_interlibrary_dependency_graph (
                                         parse_arg (
                                             library_source_index,
                                             fzp::FREEZE_NONE,
                                             plugin_path
                                         )
                                     ))

                                    THE (group, makelib_state)
                                        =>
                                        dagwalker_for_make_command   FALSE   makelib_state   group;

                                    NULL
                                        =>
                                        FALSE;
                                esac
                                then
                                    maybe_clear_pickle_cache ();
                            }
                            except
                                _ = FALSE;

                        if succeeded   fil::say {. cat ["                               makelib-g.pkg:  plugin ", plugin_description, " loaded successfully]"]; };
                        else           fil::say {. cat ["                               makelib-g.pkg:  Unable to load plugin ", plugin_description]; };
                        fi;

                        succeeded;
                    }


                also
                fun load_plugin  path_root  file_path
                    = 
                    {   fun badname string
                            =
                            fil::say {.
                                cat
                                    [
                                        "                         makelib-g.pkg:  Bad plugin name: '",
                                        string,
                                        "'\n"
                                    ];
                            };

                                                                    # say                       is from   src/lib/std/src/io/say.pkg
                        prefile
                            =
                            ad::from_standard'
                                { anchor_dictionary,
                                  plaint_sink => badname
                                }
                                { path_root,
                                  file_path
                                };

                        load_plugin' (ad::file  prefile);
                    };

                #
                fun cwd_load_plugin  x
                    =
                    load_plugin (ad::current_working_directory ()) x;



                # This function may be interactively invoked
                # from the commandline as makelib::freeze'.
                # (Or as makelib::freeze
                # in which case the 'recursively' boolean arg is implicit.)
                #
                fun freeze'
                        #
                        { recursively }
                        #
                        root
                    =
                    {
                        # Since we are a toplevel interactive entrypoint,
                        # allot a fresh makelib state:
                        #
                        makelib_state
                          =
                          { library_source_index =>  lsi::make_library_source_index (),
                            plaint_sink          =>  err::default_plaint_sink (),
                            #   
                            timestamp_of_youngest_sourcefile_in_library
                                =>
                                REF timestamp::ancient,                                         # Set up to track most recent (known) edit of any sourcefile in the library.

                            makelib_session
                                =>
                                make_makelib_session
                                  {
                                    we_are_a_subprocess             =>  FALSE,
                                    keep_going_after_compile_errors =>  mld::keep_going_after_compile_errors.get ()
                                  }
                          };

                        fun dagwalker_for_freeze_command  makelib_state  g
                            =
                            {
                                my { compile_all_fat_tomes_in_library_in_dependency_order, ... }
                                    =
                                    cdo::make_dependency_order_compile_fns
                                      {
                                        root_library =>  g,
                                        #
                                        maybe_drop_thawedlib_tome_from_linker_map
                                           => drop_thawedlib_tome_from_linker_map,
                                        #
                                        set__compiledfile__for__thawedlib_tome
                                            =>
                                            \\ _ = ()
                                      };

                                                                    # compile_dagwalk                   def is    above.
                                                                    # linking_dagwalk                   def is    above.

                                compile_all_fat_tomes_in_library_in_dependency_order  makelib_state;
                            };

                        #
                        fun freeze_library_dummy_dagwalker  makelib_state  group
                            =
                            TRUE;


                        cdo::clear_state ();                     #  A bit too draconian? 

                        run
                            make_standard_source_path
                            (recursively ?? fzp::FREEZE_ALL :: fzp::FREEZE_ONE)
                            freeze_library_dummy_dagwalker
                            root;
                    };                                                                          # fun freeze'



                ##########################################################
                #  These are the entry points that will execute when we   
                #  respectively do    'makelib::make    "foobar.lib"; or 
                #                     'makelib::compile "foobar.lib";'   
                #  at the interactive prompt:                             
                ##########################################################

                my make     =   run   make_standard_source_path   fzp::FREEZE_NONE   (dagwalker_for_make_command TRUE);
                my compile  =   run   make_standard_source_path   fzp::FREEZE_NONE    dagwalker_for_compile_command;


                #
                fun to_portable s
                    =
                    {   gp =   make_standard_source_path   s;                                   # "gp" might be "group", one old name for a library.
                        #
                        fun nativesrc  file_path
                            =
                            {   p = ad::from_standard'
                                        { plaint_sink  =>   \\ s =  raise exception DIE s,
                                          anchor_dictionary
                                        }
                                        { path_root =>   ad::dir   gp,
                                          file_path
                                        };

                                ad::os_string'   (ad::file   p);
                            };
                        #
                        fun mkres (g, pl)
                          =
                          { graph     => g,
                            imports   => pl,
                            nativesrc
                          };

                        null_or::map
                            (mkres o to_portable::export)
                            (lfp::parse_libfile_tree_and_return_interlibrary_dependency_graph
                                (parse_arg
                                    ( lsi::make_library_source_index (),
                                      fzp::FREEZE_NONE,
                                      make_standard_source_path s
                                    )
                                )
                            );
                    };
                                                                    # null_or                   is from   src/lib/std/src/null-or.pkg
                                                                    # to_portable               is from   src/app/makelib/depend/to-portable.pkg
                                                                    # library_source_index      is from   src/app/makelib/stuff/library-source-index.pkg


                # This function is exported to the user interface as
                # makelib::sources.  It provides dependency generation
                # support used by 'makedepend7'.
                #
                # According to the manual:
                #
                #    The 'makelib::sources' function can be used to find the
                #    names of all source files that a given library depends on.
                #
                #    It returns the names of all files involved with
                #    the exception of module_dependencies_summary files and .compiled files.
                # 
                #    Frozen libraries are represented by their freezefile;
                #    their description file or constituent members are
                #    NOT listed.
                #
                #    Normally, the function reports actual file
                #    names as used for accessing the file system.
                #
                #    For freezefiles this behavior can be
                #    inconvenient because these names depend on
                #    architecture and operating system.
                #
                #    For this reason, makelib::sources accepts an
                #    optional pair of strings that then will be used
                #    in place of the architecture- and OS-specific
                #    part of these names.
                #
                #    If there was some error analyzing the specified
                #    library or sublibrary, makelib::sources returns NULL.
                #       Otherwise the result is a list of records, each
                #    carrying a file name, the corresponding ilk, and
                #    information about whether or not the source was
                #    created by some tool:
                #
                #              my sources:  { arch: String,   os: String } Null_Or
                #                   -> String
                #                   ->  Null_Or( List { file: String,   ilk: String,   derived: Bool } )
                #
                fun sources platform group
                    =
                    {   policy
                            =
                            case platform
                                #
                                NULL                    =>  filename_policy;
                                THE architecture_and_os =>  fp::policy;
                            esac;

                                                                    # filename_policy   is from   src/app/makelib/main/filename-policy.pkg
                                                                    # source_path_set   is from   src/app/makelib/paths/source-path-set.pkg
                        #
                        fun sources_of  ((lt: lg::Library_Thunk), (v, a))
                            =
                            {   v' = sps::add (v, lt.libfile);

                                case (lt.library_thunk ())
                                    #
                                    lg::LIBRARY { more, sources, ... }
                                        =>
                                        {   fun add (p, x, a)
                                                =
                                                sm::set (a, ad::os_string p, x);
                                            #
                                            fun sg l
                                                =
                                                if (sps::member (v, lt.libfile))
                                                    #
                                                    (v, a);
                                                else
                                                    fold_forward
                                                        sources_of
                                                        (  v',
                                                           spm::keyed_fold_forward add a sources
                                                        )
                                                        l;
                                                fi;

                                            case more
                                                #
                                                lg::SUBLIBRARY n
                                                    =>
                                                    sg n.sublibraries;
                                                #
                                                lg::MAIN_LIBRARY { frozen_vs_thawed_stuff, makelib_version_intlist }
                                                    =>
                                                    case frozen_vs_thawed_stuff
                                                        #
                                                        lg::THAWEDLIB_STUFF d =>  sg  d.sublibraries;
                                                        #
                                                        lg::FROZENLIB_STUFF _
                                                            =>
                                                            {   f =   ad::os_string   lt.libfile;
                                                                #
                                                                (sm::get_and_drop (a, f)) ->   (a, x);

                                                                freezefile_name
                                                                   =
                                                                   fp::make_freezefile_name
                                                                      policy
                                                                      lt.libfile;

                                                                ( v',
                                                                  sm::set (a, freezefile_name, the x)                   # We're trust that 'f' is always in 'a' above.
                                                                );
                                                            }; 
                                                    esac;
                                            esac;
                                        };

                                    lg::BAD_LIBRARY
                                        =>
                                        (v', a);
                                esac;
                            };

                        p =  make_standard_source_path group;


                        library_source_index
                            =
                            lsi::make_library_source_index ();


                        case (lfp::parse_libfile_tree_and_return_interlibrary_dependency_graph
                                 (parse_arg
                                     (   library_source_index,
                                         fzp::FREEZE_NONE,
                                         p
                               ) )   )
                            #
                            THE (g, _)
                                =>
                                {   my (_, sm)
                                        =
                                        sources_of ( { libfile   =>  p,
                                                       library_thunk =>  \\ () = g
                                                      ,renamings     =>  []     # MUSTDIE
                                                     },
                                                     ( sps::empty,
                                                       sm::singleton ( ad::os_string p,
                                                                             { ilk     =>  "cm",
                                                                               derived =>  FALSE
                                                                             }
                                                                           )
                                                     )
                                                  );
                                    #
                                    fun add (s, { ilk, derived }, l)
                                        =
                                        { file => s, ilk, derived } ! l;

                                    THE (sm::keyed_fold_forward add [] sm);
                                };
                            #
                            _ => NULL;
                        esac
                        then
                            maybe_clear_pickle_cache ();
                    };
                #
                fun build_executable_heap_image
                        freeze_policy           # fzp::FREEZE_NONE/fzp::FREEZE_ONE/fzp::FREEZE_ALL
                        { setup,                # Always NULL in practice.
                          libfile_to_run,       # E.g. "nowhere.lib"
                          wrapper_libfile,      # One-line scratch .lib file created by bin/build-an-executable-mythryl-heap-image script.
                          heap_filename         # Heapfile to create (i.e., executable), say "nowhere"
                        }
                    =
                    {   spopt           =   null_or::map make_standard_source_path  setup;
                        libfile_to_run  =   make_standard_source_path  libfile_to_run;
                        wrapper_libfile =   make_standard_source_path  wrapper_libfile;
                        timestamp       =   timestamp::last_file_modification_time  heap_filename;

                                                                            # timestamp is from   src/app/makelib/paths/timestamp.pkg

                        library_source_index
                            =
                            lsi::make_library_source_index ();
                        #
                        fun do_libfile p
                            =
                            case (lfp::parse_libfile_tree_and_return_interlibrary_dependency_graph
                                     (parse_arg
                                         ( library_source_index,
                                           fzp::FREEZE_NONE,
                                           p
                                         )
                                   ) )
                                #
                                THE (g, gp)
                                    =>
                                    if (dagwalker_for_compile_command gp g)   THE (make_bootlist g);
                                    else                                       NULL;
                                    fi;
                                #
                                NULL =>   NULL;
                           esac;

                        set_up_list
                            =
                            case spopt
                                #
                                THE sp =>  the_else (do_libfile sp, []);
                                NULL   =>  [];
                            esac;
                        #
                        fun in_setup (i, _)
                            =
                            list::exists
                                (fcx::same_info i  o  #1)
                                set_up_list;

                                                                    # list      is from   src/lib/std/src/list.pkg
                        #
                        fun do_wrapper ()
                            =
                            case (do_libfile  wrapper_libfile)
                                #
                                NULL  =>  NULL;
                                THE l =>  THE (  map #2 ( set_up_list @ list::filter (not o in_setup) l) );
                            esac;

                        case (lfp::parse_libfile_tree_and_return_interlibrary_dependency_graph
                                 (parse_arg
                                     ( library_source_index,
                                       freeze_policy,
                                       libfile_to_run
                                     )
                               ) )
                            #
                            THE (group, makelib_state)
                                =>
                                if  (freeze_policy != fzp::FREEZE_NONE
                                or  dagwalker_for_compile_command  makelib_state  group
                                )
                                    # If none of the sourcefiles have been
                                    # modified since the target was created,
                                    # we don't need to rebuild:
                                    #
                                    case (timestamp, *makelib_state.timestamp_of_youngest_sourcefile_in_library)        # This is the only place in the codebase where we actually *use*   timestamp_of_youngest_sourcefile_in_library.
                                       #                                                                                # This field is actually computed in   src/app/makelib/compile/compile-in-dependency-order-g.pkg
                                         ( timestamp::TIMESTAMP target_timestamp,
                                           timestamp::TIMESTAMP source_timestamp
                                         )
                                             =>
                                             if (time::(<) (target_timestamp, source_timestamp))   do_wrapper ();
                                             else                                                  THE [];
                                             fi;

                                         _   =>
                                             do_wrapper ();
                                    esac;
                                else
                                    NULL;
                                fi;
                            #
                            NULL => NULL;
                        esac
                        then
                            maybe_clear_pickle_cache ();
                    };

                #
                fun redump_heap  filename_for_heap_image:  Void
                    =
                    fate::switch_to_fate   *myc::rpl::redump_heap_fate   filename_for_heap_image;                       # redump_heap_fate      is from   src/lib/compiler/toplevel/interact/read-eval-print-loops-g.pkg


                # The following function is essentially the second half
                # of the 'bin/build-an-executable-mythryl-heap-image'
                # (aka sh/_build-an-executable-mythryl-heap-image) script
                # to build an executable heap image file from a .lib file.
                #
                # The script invokes this function using a
                # ' --build-an-executable-mythryl-heap-image' commandline switch
                # kludged into bin/mythryld.  It probably should be executed
                # via a "'bin/mythryld -e 'your code here()', sort of mechanism,
                # but we haven't implemented that yet.   XXX BUGGO FIXME
                #
                fun build_an_executable_mythryl_heap_image  buildargs
                    =
                    wnx::process::exit
                        #
                        case buildargs
                            #
                            [       libfile_to_run, libfile, heap, compiled_files_file, linkargs_file] =>  do_it (NULL,      libfile_to_run, libfile, heap, compiled_files_file, linkargs_file);
                            [setup, libfile_to_run, libfile, heap, compiled_files_file, linkargs_file] =>  do_it (THE setup, libfile_to_run, libfile, heap, compiled_files_file, linkargs_file);
                            #
                            _ => { fil::say {. "bad arguments to --build-an-executable-mythryl-heap-image"; };
                                   wnx::process::failure;
                                 };
                        esac

                    where
                        #
                        fun do_it (setup, libfile_to_run, wrapper_libfile, heap_filename, compiled_files_file, linkargs_file)
                            =
                            case (build_executable_heap_image
                                     fzp::FREEZE_NONE
                                     { setup,
                                       libfile_to_run,                  # Master .lib to build the app, e.g. "nowhere.lib"
                                       heap_filename,                   # "Executable" file to create, e.g. "nowhere"
                                       wrapper_libfile                  # Scratch one-line .lib file created by bin/build-an-executable-mythryl-heap-image script.
                                     }
                                   )
                                #
                                NULL   => {  fil::say {. "Compilation failed."; };          wnx::process::failure; };
                                THE [] => {  fil::say {. "Heap was already up-to-date."; }; wnx::process::success; };
                                #
                                THE l
                                    =>
                                    {   fun wrf (f, l)
                                            =
                                            {   s =  fil::open_for_write  f;
                                                #
                                                fun wr string
                                                    =
                                                    fil::write (s, string + "\n");

                                                fil::say {.
                                                    cat ["\n",
                                                         "                           makelib-g.pkg:   Creating file '", f, "'\n"
                                                        ];
                                                };
                                                apply wr l;
                                                fil::close_output  s;
                                                fil::say {. ""; };
                                            };

                                       s =   fil::open_for_write  compiled_files_file;
                                        #
                                       fun wr str
                                           =
                                           fil::write (s, str + "\n");

                                       n =   length l;
                                        #
                                       fun maxsz (s, n)
                                           =
                                           int::max (size s, n);

                                       m =  fold_forward maxsz 0 l;

                                       wrf (compiled_files_file,
                                            "# This file built by src/app/makelib/main/makelib-g.pkg: build_an_executable_mythryl_heap_image"
                                            ! "# for consumption by src/c/main/load-compiledfiles.c: BuildCompiled_FileList."
                                            ! "#"
                                            ! "# It gives a list of .compiled files to be linked together to form a Mythryl \"executable\" (heap image)."
                                            ! "#"
                                            ! "# Each line after the header specifies one .compiled file to load."
                                            ! "#"
                                            ! "# The lines are topogically sorted so that no .compiled file depends upon a later one."
                                            ! "#"
                                            ! "# A .compiled file is specified as either a simple filename, or else as a"
                                            ! "# FREEZEFILENAME@OFFSET: LIBRARY_DESCRIPTION triple giving the offset of the"
                                            ! "# compiledfile image within some library file, where LIBRARY_DESCRIPTION in turn"
                                            ! "# is a LIBFILE@OFFSET (SOURCEFILE) triple giving the .lib file which created"
                                            ! "# the library and the name of the source file which was compiled to produce"
                                            ! "# the .compiled file.  (The second OFFSET is redundant with the first.)"
                                            ! cat ["FILES=",           int::to_string n ]
                                            ! cat ["MAX_LINE_LENGTH=", int::to_string m ]
                                            ! ""
                                            ! l);

                                       wrf (linkargs_file,
                                            [cat [" --runtime-compiledfiles-to-load=", compiled_files_file]]);

                                       wnx::process::success;
                                   }
                                   except
                                       _ =  wnx::process::failure;
                            esac;

                    end;
                #
                fun clear_state ()
                  =
                  { cdo::clear_state ();
                    ltw::clear_state ();
                    #
                    lfp::clear_state ();                        # libfile_parser_g                      is from   src/app/makelib/parse/libfile-parser-g.pkg
                    tc::clear_state  ();                        # thawedlib_tome                        is from   src/app/makelib/compilable/thawedlib-tome.pkg
                    ffr::clear_state ();                        # freezefile_roster_g                   is from   src/app/makelib/freezefile/freezefile-roster-g.pkg
                  };


                # Our tasks here are:
                #
                #  1) Load $ROOT/LIBRARY_CONTENTS into memory.
                #  2) Compile and load primordial libfile "src/lib/core/init/init.cmi" 
                #  3) Set up primordial_library_hook for use elsewhere in file.
                #  4) Preload the libraries listed in mcc::libraries_to_preload;
                #
                # Calling this function is the last
                # thing done by 'read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'.
                #
                # This means that we, like it, are
                # essentially executed at compiletime
                # rather than runtime --
                #
                #     src/lib/core/internal/make-mythryld-executable.pkg
                #
                # calls us -before- dumping to disk
                # the heap image which becomes the
                # mythryld "executable":
                #
                fun read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'
                      {
                        root_directory,         # Contains src/ bin/ sh/ etc.
                        linking_mapstack,
                        run_commandline,
                        makelib_state
                      }  
                    =
                    {
                                                                                                        # print ("src/app/makelib/main/makelib-g.pkg/read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'/AAA: root_directory = " + root_directory + " cwd= " + (psx::current_directory()) + "\n");


                        ##########################################################
                        # Saving an in-memory datastructure to disk is
                        # called "pickling", and the result is called
                        # a "pickle".
                        #
                        # In particular, the .compiled object-code files
                        # produced by the compiler consist of pickles
                        # plus a little relish.
                        #
                        # We identify pickles by 16-byte hashes of their
                        # contents, which we call "picklehashes".
                        #
                        # A library freezefile is essentially a collection
                        # of pickles, and to use it we mainly need to know
                        # which pickles are where, which we express by an
                        # index mapping picklehashes (abstract pickle names) to
                        # byte offsets (pickle locations within the freezefile).
                        #
                        # The file
                        #
                        #     LIBRARY_CONTENTS
                        #
                        # contains one such an index for every freezefile
                        # in the src/* directory tree which is slated for
                        # inclusion in the mythryld executable, in a simple
                        # one-index-per-line text format. For more details,
                        # see its top-of-file comments or the code that creates
                        # it: write_picklehash_map() in
                        #
                        #     src/app/makelib/mythryl-compiler-compiler/mythryl-compiler-compiler-g.pkg: 
                        #
                        # Our next task is to load LIBRARY_CONTENTS into memory.
                        ##########################################################


                                                                                                # picklehash                            is from   src/lib/compiler/front/basics/map/picklehash.pkg
                                                                                                # string                                is from   src/lib/std/string.pkg
                                                                                                # source_path_map                       is from   src/app/makelib/paths/source-path-map.pkg
                        # Construct full pathname for
                        # the LIBRARY_CONTENTS file:
                        #
                        picklehash_map_file                                                     # Something like:  "/home/cynbe/src/mythryl7.110.58/LIBRARY_CONTENTS"
                            =
                            pth::cat (
                                root_directory,                                                 # Root of Mythryl distribution sourcecode tree -- contains sh/ bin/ src/ ...
                                mcc::picklehash_map_filename                                    # "LIBRARY_CONTENTS"
                            );

                        #
                        fun read_picklehash_map s
                            =
                            {   seed_libraries_index__local
                                    :=
                                    loop  spm::empty;
                            }
                            where
                                #
                                fun loop  seed_libraries_index
                                    =
                                    {   fun add_seed_library's_pickles_to_index
                                              ( lib,                                                                    # Some string like:   "$ROOT/src/lib/core/internal/makelib-internal.lib"
                                                pickles                                                                 # Some list like:     [ "38830:0868B4FAE15B953295FA742D8CAC2A73", "265848:B47207DB3FD2774954EA9DC70B9EAA8D" ]
                                              )
                                            =
                                            # Map the ad::File for the foo.lib library name
                                            # to the contents of the library, in the form of
                                            # a map from file byte-offsets to pickles, where
                                            # the pickles in turn are in turn (Picklehash,Chunk)
                                            # pairs (in essence):
                                            #   
                                            spm::set (
                                                #
                                                seed_libraries_index,
                                                #
                                                ad::decode  anchor_dictionary  lib,                                     # Resolve text library name into internal ad::File representation.
                                                #
                                                fold_forward  parse_pickles  im::empty  pickles
                                            )
                                            where
                                                #
                                                fun parse_pickles
                                                      (
                                                        pickle_info,                                                    # Some string like:  "38830:0868B4FAE15B953295FA742D8CAC2A73" -- byte_offset_in_freezefile followed by hash_of_pickle.
                                                        byteoffset_to_pickle_map                                        # Given the byte offst of a pickle in a freezefile, returns pickle as a singleton linktable mapping (Picklehash -> Chunk)
                                                      )
                                                    =
                                                    case (string::tokens  (\\ c =  c == ':')  pickle_info)              # E.g., split   "38830:0868B4FAE15B953295FA742D8CAC2A73"   into   [ "38830", "0868B4FAE15B953295FA742D8CAC2A73" ].
                                                        #
                                                        [ decimal_byte_offset_in_freezefile, hex_picklehash ]
                                                            =>
                                                            case ( ph::from_hex      hex_picklehash,                    # Convert picklehash  from ascii string to binary in-ram form.
                                                                   int::from_string  decimal_byte_offset_in_freezefile  # Convert byte-offset from ascii string to Int form.
                                                                 )
                                                                #
                                                                (THE picklehash, THE byte_offset_in_freezefile)
                                                                    =>
                                                                    case (lt::get  linking_mapstack  picklehash)
                                                                        #       
                                                                        THE chunk
                                                                            =>
                                                                            im::set
                                                                              ( byteoffset_to_pickle_map,
                                                                                byte_offset_in_freezefile,
                                                                                lt::singleton (picklehash, chunk)
                                                                              );
                                                                        #
                                                                        NULL      =>  byteoffset_to_pickle_map;         # Is this another "impossible" case being silently ignored?  Or...?  XXX BUGGO FIXME
                                                                    esac;
                                                                #
                                                                _   =>   byteoffset_to_pickle_map;                      # Ascii-to-binary conversion failed(?!) -- silently ignore this pickle. XXX BUGGO FIXME.
                                                            esac;
                                                        #       
                                                        _ => byteoffset_to_pickle_map;                                  # Breaking pickle on ':' failed to produce two strings?!  Silently ignore it.   XXX BUGGO FIXME.

                                                    esac;
                                            end;

                                        # A sample line from LIBRARY_CONTENTS looks like:
                                        #
                                        #     $ROOT/src/lib/core/internal/makelib-internal.lib 38830:0868B4FAE15B953295FA742D8CAC2A73 265848:B47207DB3FD2774954EA9DC70B9EAA8D
                                        #      
                                        # The logical structure here is:
                                        #
                                        #    library:                          $ROOT/src/lib/core/internal/makelib-internal.lib
                                        #    list-of-compiledfiles-in-library: 38830:0868B4FAE15B953295FA742D8CAC2A73 265848:B47207DB3FD2774954EA9DC70B9EAA8D
                                        #
                                        # Here $ROOT is the root directory of the Mythryl source distribution, say   /home/cynbe/src/mythryl-110.58
                                        #
                                        # In practice we are interested not in
                                        #
                                        #     makelib-internal.lib  
                                        #
                                        # itself but rather in
                                        #
                                        #     makelib-internal.lib.frozen  
                                        # 
                                        # which contains all the compiled code for the library.  This file
                                        # is structured essentially as a sequence of "pickles" -- compiled
                                        # sourcefiles is on-disk form.
                                        # 
                                        # The compiledfile references are structured as
                                        # 
                                        #     byte_offset_in_freezefile:picklehash_for_compiledfile
                                        # 
                                        # pairs, which tell us the two things we initially want to
                                        # know about a pickle:
                                        # 
                                        #   o What byte offset to seek to in   makelib-internal.lib.frozen
                                        #     in order to read it.
                                        # 
                                        #   o The 16-byte 'picklehash' (message digest hash of the pickle)
                                        #     which we use internally to identify that pickle.
                                        # 
                                        case (fil::read_line s)
                                            #
                                            NULL =>   seed_libraries_index;                                                                     # No more lines in LIBRARY_CONTENTS file, so return result.
                                            #
                                            THE line                                                                                            # Got next line from LIBRARY_CONTENTS file.
                                                =>
                                                if (string::get_byte_as_char (line, 0) == '#')                                                  # Is it a comment line?
                                                    #
                                                    loop seed_libraries_index;                                                                  # Yes, ignore it.
                                                else
                                                    case (string::tokens  char::is_space  line)                                                 # Break line up into tokens delimited by whitespace.
                                                        #
                                                        lib ! pickles =>   loop (add_seed_library's_pickles_to_index( lib, pickles ));
                                                        _             =>   loop seed_libraries_index;                                           # Some sort of garbage line, silently ignore it. XXX BUGGO FIXME.
                                                    esac;
                                                fi;
                                        esac;
                                    };                                  # fun loop
                            end;                                        # fun read_picklehash_map

# The following will print something like:
#
#     src/app/makelib/main/makelib-g.pkg about to open picklehash_map_file /mythryl7/mythryl7.110.58/mythryl7.110.58/LIBRARY_CONTENTS: cwd = /mythryl7/mythryl7.110.58/mythryl7.110.58
#
# print ("src/app/makelib/main/makelib-g.pkg about to open picklehash_map_file " + picklehash_map_file + ": cwd = " + (psx::current_directory()) + "\n");
                        safely::do
                            {
                              open_it  =>  {. fil::open_for_read  picklehash_map_file; },
                              close_it =>  fil::close_input,
                              cleanup  =>  \\ _ =  ()
                            }
                            read_picklehash_map;

                        mythryl_primordial_library                                                      # "$ROOT/src/lib/core/init/init.cmi" 
                            =
                            make_standard_source_path   mcc::mythryl_primordial_library;

                                                                                                # library_source_index                  is from   src/app/makelib/stuff/library-source-index.pkg
                                                                                                # timestamp                             is from   src/app/makelib/paths/timestamp.pkg

                                                                                                # freezefile is defined above, via freezefile_g().
                        fun load_primordial_library ()
                            =
                            fzf::load_freezefile
                                #
                                { get_library =>   \\ _ =  raise exception DIE "makelib-g.pkg: load_primordial_library",
                                  saw_errors  =>   REF FALSE
                                }
                                #
                                ( makelib_state, 
                                  mythryl_primordial_library,
                                  NULL                  # 'makelib_version_intlist' info XXX BUGGO DELETME
                                    , []        # MUSTDIE
                                );


                        case (load_primordial_library ())
                            #
                            THE primordial_library
                                =>
                                {   cdo::clear_state ();
                                    ltw::clear_state ();


                                    my { per_fat_tome_fns_to_compile_after_dependencies, ... }
                                        =
                                        cdo::make_dependency_order_compile_fns
                                          {
                                            root_library                              =>  primordial_library,
                                            maybe_drop_thawedlib_tome_from_linker_map =>  \\ _ = \\ _ = (),
                                            set__compiledfile__for__thawedlib_tome    =>  \\ _ = ()
                                          };

                                    my { exports => linking_dagwalk_map, ... }
                                        =
                                        ltw::make_linking_dagwalk
                                          (
                                            primordial_library,
                                            \\ _ =  raise exception DIE "init: get bfc?"
                                          );
                                    #
                                    fun get_symbol_dagwalk (dagwalk_map, symbol)
                                        =
                                        case (sym::get (dagwalk_map, symbol))
                                            #
                                            THE dagwalk =>  dagwalk;
                                            NULL         =>  raise exception DIE "init: bogus init library (1)";
                                        esac;



                                    stipulate
                                        pervasive_symbol = ps::pervasive_package_symbol;                        # Get symbol for "<Pervasive>".
                                    herein
                                        pervasive_compile_dagwalk =  get_symbol_dagwalk ( per_fat_tome_fns_to_compile_after_dependencies, pervasive_symbol );
                                        pervasive_linking_dagwalk =  get_symbol_dagwalk ( linking_dagwalk_map, pervasive_symbol );
                                    end;

                                    #
                                    fun do_dagwalk  dagwalk
                                        =
                                        case (dagwalk  makelib_state)
                                            #
                                            THE r =>  r;
                                            NULL  =>  raise exception DIE "init: bogus init library (2)";
                                        esac;

                                    (do_dagwalk  pervasive_compile_dagwalk)
                                        ->
                                        { symbolmapstack   =>  pervasive_symbolmapstack,
                                          inlining_mapstack =>  pervasive_inlining_mapstack
                                        };

                                    pervasive_linking_mapstack
                                        =
                                        do_dagwalk  pervasive_linking_dagwalk;

                                    pervasive_fun_etc_defs
                                        =
                                        cms::make_compiler_mapstack_set
                                          {
                                            symbolmapstack    =>  pervasive_symbolmapstack,
                                            linking_mapstack  =>  pervasive_linking_mapstack,
                                            inlining_mapstack =>  pervasive_inlining_mapstack
                                          };
                                    #
                                    fun bare_autoload x
                                        =
                                        {   fil::say {. cat ["!* ", x, ": \"autoload\" not available, using \"make\""]; };
                                            make x;
                                        };


                                    cs::pervasive_fun_etc_defs_jar.set_mapstack_set
                                        #
                                        pervasive_fun_etc_defs;


                                    (cs::get_top_level_pkg_etc_defs_jar ()).set_mapstack_set
                                        #
                                        cms::null_compiler_mapstack_set;                       #  redundant? XXX BUGGO FIXME 

                                    primordial_library_hook
                                        :=
                                        THE { primordial_library };



                                                                                                                # preload                                       is from   src/app/makelib/main/preload.pkg

                                    # 'load' all the libraries which are
                                    # to be preloaded into the final
                                    # mythryld executable image:
                                    #
                                    preload::load  make  mcc::libraries_to_preload;


                                    THE run_commandline;
                               };
                            #
                            NULL => raise exception DIE "makelib-g.pkg:   Unable to load primordial libfile  init.cmi";
                            #
                        esac;
                    };                  #  fun read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'       
            end;                        #  stipulate ... in ...

            #   
            fun show_controls (getarg, getval, padval) level
                =
                {   fun walk indent (global_control_index::INDEX_TREE rt)
                        =
                        {   include package   printf_combinator;                                # printf_combinator     is from   src/lib/src/printf-combinator.pkg

                            fun say strings =  fil::say {. cat strings; };

                            rt -> { help, control_set, subregs, path };
                            #
                            fun one ci
                                =
                                {   arg = cat
                                              (fold_backward
                                                  (\\ (s, r) =  s ! "::" ! r)
                                                  [getarg ci]
                                                  path
                                              );

                                    value = getval ci;
                                    size' = size value;

                                    lw    = *control_print::linewidth;
                                    padsz = lw - 6 - size arg - indent;


                                    if (padsz < size')
                                        #
                                        padsz' = int::max (lw, size' + 8 + indent);


                                        format' say      (sp (indent + 6) o
                                                         text arg o nl o
                                                         padval padsz' (text value)
                                                         );

                                    else
                                        format' say     (  sp (indent + 6)
                                                        o  text arg
                                                        o  padval padsz (text value)
                                                        );
                                    fi;
                                };

                            case (control_set, subregs)
                                #
                                ([], []) => ();
                                #
                                _        => { format' say (sp indent o text help o text ":" o nl);
                                              apply one control_set;
                                              apply (walk (indent + 1)) subregs;
                                            };
                            esac;
                        };
                    #
                    fun inc n
                        =
                        n + 1;

                                                    # global_control_index              is from   src/lib/global-controls/global-control-index.pkg
                                                    # basic_control             is from   src/lib/compiler/front/basics/main/basic-control.pkg


                    walk 2 (global_control_index::controls
                                (basic_control::top_index, null_or::map inc level));

                };
            #
            fun show_control_setting  level
                =
                show_controls
                    (
                      \\ ci =  (global_control::name ci.control + " = "),
                      \\ ci =   global_control::get  ci.control,
                      \\ _  =  \\ ff = ff
                    )
                    level;
            #
            fun show_controls' ()
                =
                {   show_control_setting NULL;
                    #
                    fil::say {. cat [ "\nTo get a control value interactively:  show_control \"mythryl_parser::show_interactive_result_types\";" ]; };
                    fil::say {. cat [   "To set a control value interactively:  set_control  \"mythryl_parser::show_interactive_result_types\" \"TRUE\";" ]; };
                    fil::say {. cat [   "To do same thing at commandline:       my -Cmythryl_parser::show_interactive_result_types=TRUE" ]; };
                };

            stipulate
                                                # global_control_index  is from   src/lib/global-controls/global-control-index.pkg
                                                # basic_control         is from   src/lib/compiler/front/basics/main/basic-control.pkg
                                                # global_control        is from   src/lib/global-controls/global-control.pkg

                find_control
                    =
                    global_control_index::find_control
                        basic_control::top_index;
                #
                fun split_control_path  path
                    =
                    string::tokens   (\\ c =  c == ':')   path;

            herein
                #
                fun show_control name
                    =
                    if (name == "")
                        #
                        print "Control name must be non-empty\n";
                    else
                        case (find_control (split_control_path name))
                            #
                            NULL        =>   fil::say {. cat  ["!* no such control: ", name, "\n"]; };
                            THE control =>   print (global_control::get control + "\n");
                        esac;
                    fi; 
                #
                fun set_control''' name value
                    =
                    case (find_control (split_control_path name))
                        #
                        NULL =>   fil::say {. cat  ["!* no such control: ", name, "\n"]; };
                        #
                        THE control =>
                            #
                            global_control::set (control, value)
                            except
                                global_control::BAD_VALUE_SYNTAX vse
                                    =
                                    fil::say {.
                                        cat [ "!* unable to parse value `",
                                              vse.value,        "' for ",
                                              vse.control_name, " : ",
                                              vse.name_of_type,    "\n"
                                            ];
                                    };
                    esac;
                #
                fun set_control'' name value
                    =
                    if (name == "")   print "Control name must be non-null\n";
                    else              set_control''' name value;
                    fi;
                #
                fun set_control'
                        bad             # 
                        is_config       # FALSE
                        spec            # "name=value"
                    =
                    {
                        my (name, value)
                            =
                            substring::split_off_prefix   {. #c != '='; }   spec;

                        name    =   substring::to_string name;

                        value   =   substring::to_string

                                        if  (substring::size value > 0)
                                             substring::make_slice (value, 1, NULL);
                                        else value;
                                        fi;

                        if (name == "")
                            #
                            bad ();
                            #
                        elif   is_config
                            #
                            set_control''' name value;
                            #
                        elif   (value == "")
                            #   
                            #   #define $name 1
                            #   
                            (mps::find_makelib_preprocessor_symbol name).set   (THE 1);
                        else
                            case (int::from_string  value)
                                #
                                THE i =>  (mps::find_makelib_preprocessor_symbol name).set  (THE i);            #   #define $name i
                                NULL  =>  bad ();
                            esac;
                        fi;
                    };
            end;                        # stipulate
            #
            fun set_control  spec
                =
                set_control'
                    {. print "Bad option\n"; }
                    TRUE                                        # is_config
                    (substring::from_string spec);              # "name=value"

        herein                          #  outermost 'stipulate' 

            # We get called ultimately by
            #     src/lib/core/internal/make-mythryld-executable.pkg
            # via
            #     src/lib/core/internal/make-mythryl-compiler-etc.pkg
            # shortly before it dumps the heap image
            # which becomes our standard mythryld
            # make/compiler executable (see top of file
            # comments for details). 
            #
            # Thus, we essentially do this initialization
            # at the compiler's compiletime rather than
            # at its runtime.
            #
            # Runtime arguments:
            #
            #     read_eval_print_from_stream,
            #      #
            #          # Ultimately defined in
            #          #     src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg
            #          # We pass this to
            #          #     src/app/makelib/compile/compile-in-dependency-order-g.pkg
            #          # which uses it to execute pre/post 'setup' sourcecode fragments
            #          # extracted originally from .lib files.
            #
            #     read_eval_print_from_file
            #       #
            #       # Defined in
            #           #   src/lib/compiler/toplevel/interact/read-eval-print-loops-g.pkg
            #           # as a wrapper of above.
            #
            #     read_eval_print_from_user
            #       #
            #       # Likewise defined in
            #           #   src/lib/compiler/toplevel/interact/read-eval-print-loops-g.pkg
            #       # but as a wrapper for  read_eval_print_from_user  in
            #           #   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg
            #
            fun read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries
                (   root_directory,                                     # Contains sh/ bin/ src/ ... 
                    linking_mapstack,
                    parse_string_to_raw_declarations,
                    compile_raw_declaration_to_package_closure,
                    link_and_run_package_closure,
                    read_eval_print_from_user,
                    read_eval_print_from_stream,                        # We pass this to compile-dependency-graph-walk, to evaluate sourcecode fragments.
                    read_eval_print_from_file,                          # We use this to compile vanilla commandline source files like foo.pkg
                    errorwrap
                )
                =
                {
                    makelib_state
                      =
                      { library_source_index =>  lsi::make_library_source_index (),
                        plaint_sink          =>  err::default_plaint_sink (),
                        #       
                        timestamp_of_youngest_sourcefile_in_library
                            =>
                            REF timestamp::ancient,                                             # Set up to track most recent (known) edit of any sourcefile in the library.

                        makelib_session
                            =>
                            make_makelib_session
                              {
                                we_are_a_subprocess         =>  FALSE,
                                keep_going_after_compile_errors =>  FALSE
                              }
                      };
                    #
                    fun eval_string  code_string                        # This should be a supported, exported 'eval' function. XXX BUGGO FIXME
                        =
                        safely::do
                          {
                            open_it  =>   {. fil::open_string (code_string + " ;;"); },
                            close_it =>   fil::close_input,
                            cleanup  =>   \\ _  =  ()
                          }
                          read_eval_print_from_stream;

                     eval_hook :=  eval_string;


                    fun run_commandline ()
                        #
                        # Function to process Unix command-line switches
                        # and filename arguments given to mythryld.
                        #
                        # We get called (only...?) from main() in
                        #
                        #     src/lib/core/internal/mythryld-app.pkg
                        #
                        # NB:  Any options starting with --runtime 
                        #      will already have been eaten by
                        #
                        #          src/c/main/runtime-options.c
                        =
                        {   make     = errorwrap (ignore o make    );
                            #
                            fun process_filename (filename, mk, ("api" | "pkg") ) =>  read_eval_print_from_file filename;
                                process_filename (filename, mk, "lib"           ) =>  mk filename;
                                process_filename (filename, mk, extension       ) =>  fil::say {. cat ["!* unable to process `", filename, "' (unknown extension `", extension, "')\n"]; };
                            end;
                            #
                            fun help level
                                =
                                {    fil::say {. cat
                                        ["mythryld [rtsargs] [options] [files]\n\
                                         \\n\
                                         \  run time system args:\n\
                                         \    --runtime-heap-image-to-run=<h>     (start specified heap image)\n\
                                         \    --runtime-gc-gen0-bufsize=<s>    (gc generation-zero buffer size)\n\
                                         \    --runtime-cmdname=<n>  (set command name)\n\
                                         \    --runtime-verbosity=<n> (set level of runtime verbosity)\n\
                                         \    --runtime-show-code-chunk-comments (list code heapchunks)\n\
                                         \    --runtime-debug=<f>    (write debugging info to file)\n\
                                         \\n\
                                         \  files:\n\
                                         \    <file>.lib     (makelib::make)\n\
                                         \    <file>.api       (run)\n\
                                         \    <file>.pkg       (run)\n\
                                         \\n\
                                         \  options:\n\
                                         \    -e 'expression'  (Evaluate and print 'expression', then quit.)\n\
                                         \    -x 'expression'  (Like -e, but also prints a newline.)\n\
                                         \    -E 'expression'  (Like -E, but does not quit.)\n\
                                         \    -D<name>=<v>    (set makelib variable to given value)\n\
                                         \    -D<name>        (set makelib variable to 1)\n\
                                         \    -Uname          (unset makelib variable)\n\
                                         \    -C<control>=<v> (set named control)\n\
                                         \    -H               (produce complete help listing)\n\
                                         \    -h               (produce minimal help listing)\n\
                                         \    -h<level>        (help with obscurity limit)\n\
                                         \    -S               (list all current settings)\n\
                                         \    -s<level>        (limited list of settings)\n\
                                         \    -P               (list all preprocessor variables)\n\
                                         \    -p<level>        (limited list of preprocessor variables)\n\
                                         \    --no-prompt       (Disable interactive mode prompts)\n\
                                         \n\
                                         \Do   bin/mythryld   to start an interactive session.\n\
                                         \n"]; };

                                    show_controls (global_control::name o .control,
                                                   \\ ci =
                                                      cat ["(", .help (global_control::info ci.control),
                                                              ")"],
                                                   printf_combinator::pad printf_combinator::left)
                                                  level;

                                                                    # global_control    is from   src/lib/global-controls/global-control.pkg
                                                                    # printf_combinator is from   src/lib/src/printf-combinator.pkg
                               };
                            #
                            fun show_env_vars level
                                =
                                show_controls
                                    ( \\ ci =  (global_control::name ci.control + ":"),
                                      \\ ci =  null_or::the_else (ci.info.dictionary_name, "(none)"),
                                      printf_combinator::pad printf_combinator::left
                                    )
                                    level;
                            #
                            fun badopt opt f ()
                                =
                                fil::say {.
                                    cat ["!* bad ", opt, " option: `", f, "'\n",
                                          "!* try `-h' or `-h<level>' for help\n"];
                                };
                            #
                            fun quit ()
                                =
                                wnx::process::exit
                                    wnx::process::success;

                            #
                            fun quit_if TRUE  =>  quit ();
                                quit_if FALSE =>  ();
                            end;



                            # This function mainly handles Unix commandline arguments of the form -Xyyy
                            # where X is a switch char and yyy is some argument string for it.  (Ick. XXX BUGGO FIXME. Change to usual GNU conventions.)
                            #
                            # We also arrive here for anything else
                            # not previously recognized as a switch,
                            # in particular for filename arguments.
                            #
                            # First argument is the two-char "-X" argument prefix.
                            # Second argument is the full argument.
                            # Third argument is either 'automake' or 'make' function, per last -a or -m switch.
                            # Fourth argument is TRUE iff there is more stuff remaining on commandline.
                            #
                            # What 'carg' is supposed to mean, I haven't a clue.  continued_arg maybe.  ("commandline_arg"? "control_arg"? "config_arg"? "compound arg"?) XXX BUGGO FIXME pick a decent name.
                            #
                            fun carg (    opt as ("-C" | "-D"), f, _, _)
                                =>
                                {   bad        =   badopt opt f;
                                    spec       =   substring::extract (f, 2, NULL);             # substring     is from   src/lib/std/substring.pkg
                                    is_config  =   opt == "-C";

                                    set_control' bad is_config spec;
                                };

                               carg ("-U", f, _, _)   =>    case (string::extract (f, 2, NULL))
                                                                #
                                                                ""  =>  badopt "-U" f ();
                                                                var =>  (mps::find_makelib_preprocessor_symbol var).set NULL;           #   #undef $var
                                                            esac;


                               carg ("-h", f, _, last) => {   case (string::extract (f, 2, NULL))
                                                                  #
                                                                  ""    =>  help (THE 0);
                                                                  level =>  help (int::from_string level);
                                                              esac;

                                                              quit_if last;
                                                          };

                               carg ("-s", f, _, last) => {   case (string::extract (f, 2, NULL))
                                                                  #
                                                                  ""    =>  show_control_setting  (THE 0);
                                                                  level =>  show_control_setting  (int::from_string  level);
                                                              esac;

                                                              quit_if  last;
                                                          };

                               carg ("-p", f, _, last) => {   case (string::extract (f, 2, NULL))
                                                                  #
                                                                  ""    =>  show_env_vars (THE 0);
                                                                  level =>  show_env_vars (int::from_string level);
                                                              esac;

                                                              quit_if  last;
                                                          };

                               carg (_, filename, mk, _)   =>   process_filename (
                                                                    filename,
                                                                    mk,
                                                                    string::map char::to_lower (the_else (wnx::path::ext filename, "<none>"))
                                                                );
                                                                            # string                    is from   src/lib/std/string.pkg
                                                                            # char                      is from   src/lib/std/char.pkg
                                                                            # winix__premicrothread     is from   src/lib/std/winix--premicrothread.pkg
                            end;

                            interactive
                                =
                                myp::print_interactive_prompts;


                            unparse_result
                                =
                                myp::unparse_result;


    just_return = REF FALSE;
    force_interactive = REF FALSE;    # temporary kludge

                            # Process all commandline arguments,
                            # both switches and filenames:
                            #
                            fun args ("-H"          ! rest, mk) =>  { help NULL;                      args_q (rest, mk); };
                                args ("-S"          ! rest, mk) =>  { show_control_setting NULL;      args_q (rest, mk); };
                                args ("-P"          ! rest, mk) =>  { show_env_vars NULL;             args_q (rest, mk); };

                                args ("-z"          ! rest, mk) =>  { just_return := TRUE;            args   (rest, mk); };

                                args ("-q"          ! _, _)     =>  quit ();

                                args ("-i"          ! _, _)     =>  { force_interactive := TRUE; myp::print_interactive_prompts := TRUE; };

                                args ("--build"                                     ! rest, _) =>  build_an_executable_mythryl_heap_image  rest;
                                args ("--build-an-executable-mythryl-heap-image"    ! rest, _) =>  build_an_executable_mythryl_heap_image  rest;

                                args (["--redump",  heapfile], _)
                                    =>
                                    redump_heap heapfile;

                                args ("-e" ! code_string ! rest, mk)
                                    =>
                                    {   interactive    := FALSE;
                                        eval_string code_string;
                                        quit ();
                                    };

                                args ("-x" ! code_string ! rest, mk)
                                    =>
                                    {   interactive    := FALSE;
                                        eval_string  code_string;
                                        print "\n";
                                        quit ();
                                    };

                                args ("-E" ! code_string ! rest, mk)
                                    =>
                                    {   interactive    := FALSE;
                                        eval_string  code_string;
                                        interactive    := TRUE;
                                        args( rest, mk );
                                    };

                                args (filename ! rest, mk)
                                    =>
                                    {   carg
                                            ( string::substring (filename, 0, 2) except exceptions::INDEX_OUT_OF_BOUNDS = "",
                                            filename,
                                            mk,              #  make
                                            list::null rest
                                        );

                                        args (rest, mk);
                                    };

                                args ([], _) => ();
                            end 

                            also
                            fun args_q ([],   _) =>  quit ();
                                args_q (rest, f) =>  args (rest, f);
                            end;


                                                                                                # winix_base_text_file_io_driver_for_posix__premicrothread      is from   src/lib/std/src/io/winix-base-text-file-io-driver-for-posix--premicrothread.pkg
                                                                                                # winix__premicrothread                                         is from   src/lib/std/winix--premicrothread.pkg
                                                                                                # winix_text_file_for_os_g__premicrothread                      is from   src/lib/std/src/io/winix-text-file-for-os-g--premicrothread.pkg

                            # This fn is duplicated between here and   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg   XXX BUGGO FIXME
                            #
                            fun input_is_tty  f
                                = 
                                {   (fil::pur::get_reader  (fil::get_instream  f))              # "pur" == "pure" (I/O).
                                        ->
                                        (rd, buf);

                                    is_tty
                                        =
                                        case rd
                                            #
                                             winix_base_text_file_io_driver_for_posix__premicrothread::FILEREADER { io_descriptor => THE iod, ... }
                                                 =>
                                                 (wnx::io::iod_to_iodkind iod  ==  wnx::io::CHAR_DEVICE);

                                              _ => FALSE;
                                        esac;

                                    # Since getting the reader will have terminated
                                    # the stream, we now need to build a new stream:
                                    #
                                    fil::set_instream   (f, fil::pur::make_instream (rd, buf) );

                                    is_tty;
                                };

                            case (cmd::get_commandline_arguments ())
                                #
                                l   =>
                                    {
                                        # The next line was part of a failed attempt
                                        # to get multi-core 'make-compiler' compiles
                                        # working:              XXX BUGGO FIXME
                                        #       
#                                       fil::set_process_name_in_logfile "MYTHRYLD";
                                        fil::set_logger_to (fil::LOG_TO_FILE "mythryl.compile.log");

                                        args (l, make);                         # Process all commandline switches and arguments.



  if (not *just_return) 
                                        if (input_is_tty fil::stdin
                                        or *force_interactive)
                                            #
                                            read_eval_print_from_user ();
                                            quit ();
                                        fi;

                                        interactive    := FALSE;
                                        unparse_result := FALSE;
  fi;

                                        # Issue the interactive blurb.                  # I think the below code paragraph may now be dead code ripe to delete.
                                        # We delay doing this until commandline         # In particular, if one does 'mythryld' at the Linux commandline,
                                        # switches have been processed, so as           # the banner gets printed by the logic in read_eval_print_from_user() in   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg
                                        # to be able to disable it with --no-prompt:    # not by the below logic.   -- 2015-09-01 CrT
                                        #       
                                        if *myp::print_interactive_prompts
                                            #
                                            print "\n";
                                            print mcv::mythryl_interactive_banner;      # Something like:   "Mythryl 110.58.3.0.2 built Thu Dec 23 14:11:49 2010"
                                            print "\nDo   help();   for help  (interact)";
                                        fi;
                                    };
                            esac;
                        };

                    read_eval_print_from_stream__hook                     :=  read_eval_print_from_stream;                              # Set hook to read_eval_print_from_stream                       from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg
                    parse_string_to_raw_declarations__hook                :=  parse_string_to_raw_declarations;                         # Set hook to parse_string_to_raw_declarations                  from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg
                    compile_raw_declaration_to_package_closure__hook      :=  compile_raw_declaration_to_package_closure;               # Set hook to compile_raw_declaration_to_package_closure        from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg
                    link_and_run_package_closure__hook                    :=  link_and_run_package_closure;                             # Set hook to link_and_run_package_closure                      from   src/lib/compiler/toplevel/interact/read-eval-print-loop-g.pkg

                    read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries'
                      {
                        root_directory,
                        linking_mapstack,
                        run_commandline,
                        makelib_state
                      };
                };                                                                      #  fun read_''library_contents''_and_compile_''init_cmi''_and_preload_libraries 
            #
            fun help ()
                =
                apply
                    print
                    [   "\n\n",
                        "              Mythryl Interactive Help\n",
                        "\n",
                        "You are interacting with an incremental compiler for\n",
                        "Mythryl, an advanced posix-flavored mostly-functional\n",
                        "programming language.\n",
                        "\n",
                        "Enter one expression per line.\n",
                        "\n",
                        "Examples:\n",
                        "    2+2;\n",
                        "    print \"Hello, world!\\n\";\n",
                        "    print `ls -l`;\n",
                        "    printf \"%d %g\\n\" (1 << 3) (sin 0.3);\n",
                        "    for (i=0; i<10; ++i) { printf \"%d\\n\" i; };\n",
                        "    fun hello () = print \"Hello, world!\\n\";\n",
                        "    hello ();\n",
                        "\n",
                        "Some useful commands:\n",
                        "\n",
                        "    # List values, functions, packages and APIs defined at top level:\n",
                        "    show_all ();\n",
                        "    show_apis();     # As above, showing only API     defs\n",
                        "    show_pkgs();     # As above, showing only package defs\n",
                        "    show_vals();     #                        value   defs\n",
                        "    show_types();    #                        type    defs\n",
                        "    show_generics(); #                        generic defs\n",
                        "\n",
                        "    show_api \"Integer\"; # Show definition of Integer API\n",
                        "    show_pkg \"control\"; # Mainly useful for packages with anonymous APIs.\n",
                        "\n",
                        "    # Display all compiler configuration variables:\n",
                        "    show_controls();\n",
                        "\n",
                        "    # Load hello lib into ram, first re/compiling as needed:\n",
                        "    make \"src/app/tut/hello/hello.lib\";\n",
                        "\n",
                        "    # Make hello.lib library freezefile 'hello.lib.frozen':\n",
                        "    freeze \"src/app/tut/hello/hello.lib\";\n",
                        "\n",
                        "Type <Ctrl>-D to exit.  (<Ctrl>-Q <Ctrl>-D in emacs.)\n"
                    ];


            # This package defines the externally visible 'makelib', exported by
            #
            #     src/lib/core/makelib/makelib.pkg
            #
            # sealed with the Makelib api from
            #
            #     src/lib/core/internal/makelib.api
            #
            package makelib_external {

                Controller(X) = {   get:  Void -> X,
                                      set:  X -> Void
                                  };

                                                                                        # makelib_defaults                      is from   src/app/makelib/stuff/makelib-defaults.pkg
                                                                                        # libfile_parser_g                      is from   src/app/makelib/parse/libfile-parser-g.pkg
                package control {
                    #
                    verbose                 =  mld::verbose;
                    parse_caching           =  mld::parse_caching;
                    #
                    warn_on_obsolete_syntax =  mld::warn_on_obsolete_syntax;
                    debug                   =  mld::debug;
                    conserve_memory         =  mld::conserve_memory;
                    #
                    generate_index          =  mld::generate_index;
                    #
                    keep_going_after_compile_errors
                        =
                        mld::keep_going_after_compile_errors;
                };

                package freezefile_db {
                    #
                    Freezefile = ad::File;
                    #
                    known     =  lfp::list_freezefiles;
                    describe  =  ad::describe;
                    #
                    os_string =  ad::os_string;
                    dismiss   =  lfp::dismiss_freezefile;
                    #
                    fun unshare library
                        =
                        {   ltw::unshare  library;
                            #
                            dismiss  library;
                        };
                };

                package makelib_state {
                    #
                    clear_state = clear_state;
                    dump        =       dump_api_reference;
                    dump_latex  = latex_dump_api_reference;
                };


                compile       =  compile;                                               # Defined above by    my compile  = ... [ LATER ] This probably doesn't belong in the scripting globals -- not of broad/frequent enough interest.
                search_lib_load_path_for_file   = llp::search_lib_load_path_for_file;   #                                       [ LATER ] This probably doesn't belong in the scripting globals -- not of broad/frequent enough interest.

                help          =  help;

                make          =  make;  /* DEPRECATED */                                # Defined above by    my make     = ...
                load          =  make;  /* DEPRECATED */                                # For now (at least) this is just a synonym for 'make', intended to read better at the top of scripts.
                use           =  make;                                                  # Another synonym for 'make'. Perl has this right: Scripters care about making the library available;
                                                                                        # they don't care about compiling vs loading etc. DEPRECATING 'make' and 'load' here.

                freeze        =  freeze' { recursively => TRUE };
                freeze'       =  freeze';


                show_all      =  show_all;
                show_apis     =  show_apis;
                show_pkgs     =  show_pkgs;
                show_vals     =  show_vals;
                show_types    =  show_types;
                show_generics =  show_generics;
                show_controls =  show_controls';
                show_control  =  show_control;
                set_control   =  set_control'';

                show_api      =  show_api;
                show_pkg      =  show_pkg;

                sources       =  sources;

                get_makelib_preprocessor_symbol_value
                    =
                    mps::find_makelib_preprocessor_symbol;

                load_plugin   =  cwd_load_plugin; 

                build_executable_heap_image
                    =
                    build_executable_heap_image;


                fun parse_string_to_raw_declarations           arg       = *parse_string_to_raw_declarations__hook           arg;
                fun compile_raw_declaration_to_package_closure arg       = *compile_raw_declaration_to_package_closure__hook arg;
                fun link_and_run_package_closure               arg1 arg2 = *link_and_run_package_closure__hook               arg1 arg2;

                package graph =   package {
                                      graph = to_portable;
                                  };

                redump_heap =   redump_heap;

                # Random stuff we want to be defined globally at the
                # interactive prompt.  This gets 'included' by
                #     src/lib/core/internal/make-mythryld-executable.pkg
                # There's probably a cleaner way to do this.
                # These are available as unqualified names in scripts;
                # they may be accessed as makelib::scripting_globals::foo
                # in non-script code:
                #
                package scripting_globals {                                             # NB: If you change types or values in scripting_globals you'll want make matching changes in   src/lib/core/internal/makelib.api

                    (_!)    = multiword_int::(_!);                                      # Factorial.

                    # Note:  The (_[])   enables   'vec[index]'           notation;
                    #        The (_[]:=) enables   'vec[index] := value'  notation;
                    #
#                   (_[])   =  string::get_byte_as_char;
#                   (_[])   =  rw_vector::get;
                    (_[]:=) =  rw_vector::set;

                    in     = list::in;

                    exit   = wnx::process::exit;
                    exit_x  = wnx::process::exit_x;

                    bin_sh          =  spawn__premicrothread::bin_sh;
                    bin_sh'         =  wnx::process::bin_sh';
                    #
                    fun round f     =  f8b::to_int  ieee_float::TO_NEAREST  f;

                    atoi     =  sj::atoi;
                    atod     =  sj::atod;
                    basename =  sj::basename;
                    dirname  =  sj::dirname;
                    trim     =  sj::trim;

                    #
                    fun die   message = {   print message;      exit  1;   };
                    fun die_x message = {   print message;      exit_x 1;   };


                    =~          =  regex::(=~);
                    chomp       =  string::chomp; 
                    chdir       =  wnx::file::change_directory;
                    environ     =  psx::environment;
                    explode     =  string::explode;
                    factors     =  int::factors;
                    fields      =  string::fields;
                    filter      =  list::filter;
                    fscanf      =  scanf::fscanf;
                    getcwd      =  wnx::file::current_directory;
                    getenv      =  wnx::process::get_env;
                    getpid      =  wnx::process::get_process_id;
                    getppid     =  psx::get_parent_process_id;
                    getuid      =  psx::get_user_id;
                    geteuid     =  psx::get_effective_user_id;
                    getgid      =  psx::get_group_id;
                    getegid     =  psx::get_effective_group_id;
                    getgroups   =  psx::get_group_ids;
                    getlogin    =  psx::get_login;
                    getpgrp     =  psx::get_process_group;
                    setgid      =  psx::set_group_id;
                    setpgid     =  psx::set_process_group_id;
                    setsid      =  psx::set_session_id;
                    setuid      =  psx::set_user_id;
                    implode     =  string::implode;
                    iseven      =  \\ i = i & 1 == 0;
                    isodd       =  \\ i = i & 1 == 1;
                    isprime     =  int::is_prime;
                    join        =  string::join;
                    join'       =  string::join';
                    lstat       =  psx::lstat;
                    mkdir       =  (\\ path = psx::mkdir (path, psx::s::flags [ psx::s::irwxu, psx::s::irgrp, psx::s::iwgrp, psx::s::iroth, psx::s::iwoth ]));          # XXX BUGGO FIXME somehow this is producing 744 instead of 755.
                    now         =  time::to_float_seconds o time::get_current_time_utc;
                    product     =  int::product;
                    rename      =  psx::rename;
                    rmdir       =  psx::rmdir;
                    shuffle     =  list_shuffle::shuffle;
                    shuffle'    =  list_shuffle::shuffle';
                    sleep       =  wnx::process::sleep;
                    sort        =  lms::sort_list;
                    sorted      =  lms::list_is_sorted;
                    scanf       =  scanf::scanf;
                    sscanf      =  scanf::sscanf;
                    stat        =  psx::stat;
                    strcat      =  string::cat;
                    strlen      =  string::length_in_bytes;
                    strsort     =  (lms::sort_list string::(>));
                    struniqsort =  (lms::sort_list_and_drop_duplicates  string::compare);
                    sum         =  int::sum;
                    symlink     =  psx::symlink;
                    time        =  psx::get_elapsed_seconds_since_1970;         # NB: 'now' has much more precision.
                    tolower     =  string::to_lower;
                    toupper     =  string::to_upper;
                    tokens      =  string::tokens;
                    uniquesort  =  lms::sort_list_and_drop_duplicates;
                    unlink      =  psx::unlink;
                    words       =  string::tokens  char::is_space;

                    dotqquotes__op =  words;                    # So that ."a b c d e f" == ["a", "b", "c", "d", "e", "f"]
                    backticks__op  =  words;                    # So that ."a b c d e f" == ["a", "b", "c", "d", "e", "f"]
                    #
                    # The following String -> X symbols are initialized in
                    #    src/lib/core/init/pervasive.pkg
                    # and we leave them at those values.  We mostly use
                    # them to quote regular expressions:
                    #
                    #    dotquotes__op    = identity;   # .'foo'
                    #    dotbrokets__op   = identity;   # .<foo>
                    #    dotbarets__op    = identity;   # .|foo|
                    #    dotslashets__op  = identity;   # ./foo/
                    #    dothashets__op   = identity;   # .#foo#
                    #    dotbackticks__op = identity;   # .`foo`
                    #
                    # NB: We also have the X -> Y symbols |i| <i> /i/ {i} <i| |i>.
                    # They may be set via
                    #     (|_|) = foo;
                    #     (<_>) = foo;
                    #     (/_/) = foo;
                    #     ({_}) = foo;
                    #     (<_|) = foo;
                    #     (|_>) = foo;
                    #
                    # I wonder if we shouldn't also have a   .[_]: List(X) -> Y   syntax.


                    arg0     =  cmd::get_program_name;          # XXX BUGGO FIXME For scripts this comes out "bin/my" or "/usr/bin/my" or such, which is not helpful.
                    argv     =  cmd::get_commandline_arguments;

                    # NB: The following have the perl-inspired
                    #     lexer-implemented synonyms
                    #     -F -D -P -L -S -C -B
                    #
                    fun isfile     filename =  psx::stat::is_file      (psx::stat  filename)  except _ = FALSE;
                    fun isdir      filename =  psx::stat::is_directory (psx::stat  filename)  except _ = FALSE;
                    fun ispipe     filename =  psx::stat::is_pipe      (psx::stat  filename)  except _ = FALSE;
                    fun issymlink  filename =  psx::stat::is_symlink   (psx::lstat filename)  except _ = FALSE;
                    fun issocket   filename =  psx::stat::is_socket    (psx::stat  filename)  except _ = FALSE;
                    fun ischardev  filename =  psx::stat::is_char_dev  (psx::stat  filename)  except _ = FALSE;
                    fun isblockdev filename =  psx::stat::is_block_dev (psx::stat  filename)  except _ = FALSE;

                    # I would like these to return TRUE if
                    # the effective uid may do the indicated
                    # operation.  I don't know if this code
                    # implements exactly that, but it is a
                    # quick first cut, at least.                  XXX BUGGO FIXME
                    #
                    # NB: The following have the perl-inspired
                    #     lexer-implemented synonyms
                    #     -R -W -X
                    #
                    fun mayread     filename =  wnx::file::access (filename, [wnx::file::MAY_READ])     except _ = FALSE;
                    fun maywrite    filename =  wnx::file::access (filename, [wnx::file::MAY_WRITE])    except _ = FALSE;
                    fun mayexecute  filename =  wnx::file::access (filename, [wnx::file::MAY_EXECUTE])  except _ = FALSE;

                    # These are used in
                    #     src/lib/src/eval-unit-test.pkg
                    # There must be a cleaner way! *ruefulgrin*   XXX BUGGO FIXME
                    # 
                    eval_kludge_ref_int         =  REF 0;
                    eval_kludge_ref_float       =  REF 0.0;
                    eval_kludge_ref_string      =  REF "";
                    #
                    eval_kludge_ref_list_int    =  REF []:  Ref( List( Int    ) );
                    eval_kludge_ref_list_float  =  REF []:  Ref( List( Float  ) );
                    eval_kludge_ref_list_string =  REF []:  Ref( List( String ) );
                    #
                    fun  eval       code_string
                      = *eval_hook  code_string;
                    #
                    fun evali  user_code = {  eval("makelib::scripting_globals::eval_kludge_ref_int         := (" + user_code + ")");  *eval_kludge_ref_int;          };
                    fun evalf  user_code = {  eval("makelib::scripting_globals::eval_kludge_ref_float       := (" + user_code + ")");  *eval_kludge_ref_float;        };
                    fun evals  user_code = {  eval("makelib::scripting_globals::eval_kludge_ref_string      := (" + user_code + ")");  *eval_kludge_ref_string;       };
                    #
                    fun evalli user_code = {  eval("makelib::scripting_globals::eval_kludge_ref_list_int    := (" + user_code + ")");  *eval_kludge_ref_list_int;     };
                    fun evallf user_code = {  eval("makelib::scripting_globals::eval_kludge_ref_list_float  := (" + user_code + ")");  *eval_kludge_ref_list_float;   };
                    fun evalls user_code = {  eval("makelib::scripting_globals::eval_kludge_ref_list_string := (" + user_code + ")");  *eval_kludge_ref_list_string;  };

                    include package   threadkit;                                        # threadkit                                     is from   src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg
                };
            };                                                                          # package makelib

            package mythryl_compiler_compiler_configuration
                  = mythryl_compiler_compiler_configuration;                            # mythryl_compiler_compiler_configuration       is from   src/app/makelib/mythryl-compiler-compiler/mythryl-compiler-compiler-configuration.pkg

                                                                                        # tools_g                                       is from   src/app/makelib/tools/main/tools-g.pkg
            package tools
                =
                tools_g (
                    load_plugin' = load_plugin';
                    anchor_dictionary = anchor_dictionary;
                );

            load_plugin =  load_plugin;

            (_!) = multiword_int::(_!);
        end;                                                                            #  stipulate ... herein ...  
    };                                                                                  #  generic makelib_g    
end;




Comments and suggestions to: bugs@mythryl.org

PreviousUpNext