PreviousUpNext

15.4.520  src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg

## translate-deep-syntax-to-lambdacode.pkg 
#
# CONTEXT:
#
#     The Mythryl compiler code representations used are, in order:
#
#     1)  Raw Syntax is the initial frontend code representation.
#     2)  Deep Syntax is the second and final frontend code representation.
#     3)  Lambdacode is the first backend code representation, used only transitionally.
#     4)  Anormcode (A-Normal format) is the second backend code representation, and the first used for optimization.
#     5)  Nextcode is the third and chief backend tophalf code representation.
#     6)  Treecode is the backend tophalf/lowhalf transitional code representation. It is typically slightly specialized for each target architecture, e.g. Intel32 (x86).
#     7)  Machcode abstracts the target architecture machine instructions. It gets specialized for each target architecture.
#     8)  Execode is absolute executable binary machine instructions for the target architecture.
#
# Our task here is converting from the second to the third form.
#
# This package is the doorway between the front end,
# which is concerned with syntax and typechecking,
# and the back end, which is concerned with performance
# improvements and code generation.

# Deep syntax is the most abstract of the frontend
# code representations:
#
#     src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.api
#
# A-Normal form is the highest level code representation
# used for optimization in the back end.  In particular,
# A-Normal form still explicitly represents the call hierarchy
# and is thus an apppropriate setting for code optimizations
# based on call hierarchy:
#
#     src/lib/compiler/back/top/anormcode/anormcode-form.api
#
# We use a polymorphically typed lambda calculus representation
# as a stepping stone to get from deep syntax to A-Normal form:
#
#     src/lib/compiler/back/top/lambdacode/lambdacode-form.api
#
# A-Normal is a relatively minor code representation in
# this compiler;  it serves primarily as a stepping stone
# to our nextcode ("continuation passing style") code
# representation, which is the workhorse of the back
# end top half:
#
#     src/lib/compiler/back/top/nextcode/nextcode-form.api
#
# For higher-level context, read 
#
#     src/A.COMPILER.OVERVIEW
#
#
# "In this phase the deep syntax, annotated with static semantic information,
#  is translated into a strict call-by-value lambda calculus augmented with
#  data constructors, records and primitive operators and explicitly typed
#  using a simple typelocked type system.  The type information is converted
#  directly from the static semantic information attached to the deep syntax.
#  Coercion functions are inserted at each abstraction and instantiation site
#  to correctly support abstraction and polymorphicism.  In addition this phase
#  also inserts the proper implementation of each equality test and assignment
#  operator, and does pattern-match compilation"
#      p33, "Compiling Standard ML For Efficient Execution on Modern Machines"
#      http://flint.cs.yale.edu/flint/publications/zsh-thesis.pdf
#
# We get invoked (only) from
#
#     src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg
#


# Compiled by:
#     src/lib/compiler/core.sublib



#DO set_control "compiler::trap_int_overflow" "TRUE";

stipulate
    package ds  =  deep_syntax;                 # deep_syntax           is from   src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.pkg
    package tmp =  highcode_codetemp;           # highcode_codetemp     is from   src/lib/compiler/back/top/highcode/highcode-codetemp.pkg
    package it  =  import_tree;                 # import_tree           is from   src/lib/compiler/execution/main/import-tree.pkg
    package lcf =  lambdacode_form;             # lambdacode_form       is from   src/lib/compiler/back/top/lambdacode/lambdacode-form.pkg
    package pci =  per_compile_info;            # per_compile_info      is from   src/lib/compiler/front/typer-stuff/main/per-compile-info.pkg
    package ph  =  picklehash;                  # picklehash            is from   src/lib/compiler/front/basics/map/picklehash.pkg
    package syx =  symbolmapstack;              # symbolmapstack        is from   src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg
    package vh  =  varhome;                     # varhome               is from   src/lib/compiler/front/typer-stuff/basics/varhome.pkg
herein

    api Translate_Deep_Syntax_To_Lambdacode {

        # Invariant: translate_deep_syntax_to_lambdacode is always applied
        # to a top-level ds::Declaration

        translate_deep_syntax_to_lambdacode
            :
            { declaration:                  ds::Declaration,
              exported_highcode_variables:  List( tmp::Codetemp ),
              symbolmapstack:               syx::Symbolmapstack,
              ansi_c_prototype_convention:  String,                                                     #  "unix_convention" or "windows_convention" 
              per_compile_info:             pci::Per_Compile_Info( ds::Declaration )
            }
            ->
            { lambdacode_expression:        lcf::Lambdacode_Expression,
              #
              imports:                      List( ( ph::Picklehash,
                                                    it::Import_Tree_Node
                                                ) )
            };
    };
end;


###          "It is not the strongest of the species
###           that survive, not the most intelligent,
###           but the one most responsive to change."
###
###                          -- Charles Darwin



stipulate
    package bt  =  type_types;                                  # type_types                                    is from   src/lib/compiler/front/typer/types/type-types.pkg
    package coa =  core_access;                                 # core_access                                   is from   src/lib/compiler/front/typer-stuff/symbolmapstack/core-access.pkg
    package coc =  compiler_controls;                           # compiler_controls                             is from   src/lib/compiler/toplevel/main/compiler-controls.pkg
    package csy =  core_symbol;                                 # core_symbol                                   is from   src/lib/compiler/front/typer-stuff/basics/core-symbol.pkg
    package di  =  debruijn_index;                              # debruijn_index                                is from   src/lib/compiler/front/typer/basics/debruijn-index.pkg
    package d2l =  translate_deep_syntax_types_to_lambdacode;   # translate_deep_syntax_types_to_lambdacode     is from   src/lib/compiler/back/top/translate/translate-deep-syntax-types-to-lambdacode.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 hbo =  highcode_baseops;                            # highcode_baseops                              is from   src/lib/compiler/back/top/highcode/highcode-baseops.pkg
    package hcf =  highcode_form;                               # highcode_form                                 is from   src/lib/compiler/back/top/highcode/highcode-form.pkg
    package tmp =  highcode_codetemp;                           # highcode_codetemp                             is from   src/lib/compiler/back/top/highcode/highcode-codetemp.pkg
    package hut =  highcode_uniq_types;                         # highcode_uniq_types                           is from   src/lib/compiler/back/top/highcode/highcode-uniq-types.pkg
    package iht =  int_hashtable;                               # int_hashtable                                 is from   src/lib/src/int-hashtable.pkg
    package ij  =  inlining_junk;                               # inlining_junk                                 is from   src/lib/compiler/front/semantic/basics/inlining-junk.pkg
    package it  =  import_tree;                                 # import_tree                                   is from   src/lib/compiler/execution/main/import-tree.pkg
    package lcf =  lambdacode_form;                             # lambdacode_form                               is from   src/lib/compiler/back/top/lambdacode/lambdacode-form.pkg
    package lms =  list_mergesort;                              # list_mergesort                                is from   src/lib/src/list-mergesort.pkg
    package ln  =  literal_to_num;                              # literal_to_num                                is from   src/lib/compiler/src/stuff/literal-to-num.pkg
    package mld =  module_level_declarations;                   # module_level_declarations                     is from   src/lib/compiler/front/typer-stuff/modules/module-level-declarations.pkg
    package mc  =  translate_deep_syntax_pattern_to_lambdacode; # translate_deep_syntax_pattern_to_lambdacode   is from   src/lib/compiler/back/top/translate/translate-deep-syntax-pattern-to-lambdacode.pkg
    package pds =  prettyprint_deep_syntax;                     # prettyprint_deep_syntax                       is from   src/lib/compiler/front/typer/print/prettyprint-deep-syntax.pkg
    package peq =  polyequal;                                   # polyequal                                     is from   src/lib/compiler/back/top/translate/polyequal.pkg
    package ph  =  picklehash;                                  # picklehash                                    is from   src/lib/compiler/front/basics/map/picklehash.pkg
    package phm =  picklehash_map;                              # picklehash_map                                is from   src/lib/compiler/front/basics/map/picklehash-map.pkg
    package pp  =  prettyprint;                                 # prettyprint                                   is from   src/lib/prettyprint/big/src/prettyprint.pkg
    package sy  =  symbol;                                      # symbol                                        is from   src/lib/compiler/front/basics/map/symbol.pkg
    package syp =  symbol_path;                                 # symbol_path                                   is from   src/lib/compiler/front/typer-stuff/basics/symbol-path.pkg
    package sxe =  symbolmapstack_entry;                        # symbolmapstack_entry                          is from   src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack-entry.pkg
    package td  =  typer_debugging;                             # typer_debugging                               is from   src/lib/compiler/front/typer/main/typer-debugging.pkg
    package trj =  typer_junk;                                  # typer_junk                                    is from   src/lib/compiler/front/typer/main/typer-junk.pkg
    package ty  =  types;                                       # types                                         is from   src/lib/compiler/front/typer-stuff/types/types.pkg
    package tyj =  type_junk;                                   # type_junk                                     is from   src/lib/compiler/front/typer-stuff/types/type-junk.pkg
    package uds =  unparse_deep_syntax;                         # unparse_deep_syntax                           is from   src/lib/compiler/front/typer/print/unparse-deep-syntax.pkg
    package ut  =  unparse_type;                                # unparse_type                                  is from   src/lib/compiler/front/typer/print/unparse-type.pkg
    package vac =  variables_and_constructors;                  # variables_and_constructors                    is from   src/lib/compiler/front/typer-stuff/deep-syntax/variables-and-constructors.pkg
    package vh  =  varhome;                                     # varhome                                       is from   src/lib/compiler/front/typer-stuff/basics/varhome.pkg
    #
    package im
        =
        red_black_map_g (                                       # red_black_map_g                               is from   src/lib/src/red-black-map-g.pkg

            Key = multiword_int::Int;
            compare = multiword_int::compare;
        );
herein 

    package   translate_deep_syntax_to_lambdacode
    : (weak)  Translate_Deep_Syntax_To_Lambdacode               # Translate_Deep_Syntax_To_Lambdacode           is from   src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg
    {
        #############################################################################
        #                   CONSTANTS AND UTILITY FUNCTIONS
        #############################################################################

        debugging = typer_data_controls::translate_to_anormcode_debugging;              #  REF FALSE 
        #
        fun bug msg
            =
            err::impossible("translate_deep_syntax_to_lambdacode: " + msg);

        say = global_controls::print::say;

        prettyprint_depth =  global_controls::print::print_depth;
        #
        fun prettyprint_type  type
            =
            td::with_internals
              (fn ()
                  =
                  td::debug_print
                      debugging
                      ( "type: ",
                        ut::unparse_type symbolmapstack::empty,
                        type
                      )
              );


        prettyprint_declaration = pds::prettyprint_declaration (symbolmapstack::empty, NULL);
        prettyprint_expression  = pds::prettyprint_expression  (symbolmapstack::empty, NULL);
        prettyprint_pattern     = pds::prettyprint_pattern      symbolmapstack::empty;

        unparse_declaration = uds::unparse_declaration (symbolmapstack::empty, NULL);
        unparse_expression  = uds::unparse_expression  (symbolmapstack::empty, NULL);
        unparse_pattern     = uds::unparse_pattern      symbolmapstack::empty;

        unparse_typevar_ref = ut::unparse_typevar_ref         symbolmapstack::empty;
        #
        fun if_debugging_unparse_expression (msg, expression)
            =
            if *debugging       
                td::with_internals
                    (fn () =  td::debug_print debugging (msg, unparse_expression, expression));
            fi;
        #
        fun if_debugging_unparse_pattern (msg, pattern)
            =
            if *debugging       
                td::with_internals
                    (fn () =  td::debug_print debugging (msg, unparse_pattern, pattern));
            fi;
        #
        fun if_debugging_unparse_declaration (msg, declaration)
            =
            if *debugging       
                td::with_internals
                    (fn () =  td::debug_print debugging (msg, unparse_declaration, declaration));
            fi;
        #
        fun if_debugging_unparse_typevar_ref  (msg, typevar_ref)
            = 
            if *debugging               # Without this 'if' (and the matching one in unify_types), compiling the compiler takes 5X as long! :-)
                td::with_internals
                    (fn () =  td::debug_print debugging (msg, unparse_typevar_ref, typevar_ref));
            fi;


        #
        fun if_debugging_prettyprint_expression (msg, expression)
            =
            if *debugging       
                td::with_internals
                    (fn () =  td::debug_print debugging (msg, prettyprint_expression, expression));
            fi;
        #
        fun if_debugging_prettyprint_pattern (msg, pattern)
            =
            if *debugging       
                td::with_internals
                    (fn () =  td::debug_print debugging (msg, prettyprint_pattern, pattern));
            fi;
        #
        fun if_debugging_prettyprint_declaration (msg, declaration)
            =
            if *debugging       
                td::with_internals
                    (fn () =  td::debug_print debugging (msg, prettyprint_declaration, declaration));
            fi;


        #
        fun print_callstack
            (msg:        String)
            (callstack:  List(String))
            =
            {   printf "%s:  callstack(%d) == " msg (list::length callstack);
                apply  .{ printf " -> %s" #string; }  (reverse callstack);
                printf "\n";
            };
        #
        fun identity_fn x   =   x;

        void_lexp = lcf::RECORD [];
        #
        fun get_name_or_null p
            =
            if (syp::null p)   NULL;
            else               THE (syp::last p);
            fi;

# apparently not actually used:
#       Picklehash = ph::Picklehash;

                                                # fold_backward def in    src/lib/core/init/pervasive.pkg

        # Old-style fold for cases where
        # it is partially applied:
        #
        fun fold f l init
            =
            fold_backward f init l;


        # Sorting the record fields for
        # record types and record expressions:
        #
        stipulate
            #
            fun elem_gtr ((ds::NUMBERED_LABEL { number=>x, ... }, _), (ds::NUMBERED_LABEL { number=>y, ... }, _))
                =
                x > y;
        herein
            #
            fun sorted  x   =   lms::list_is_sorted  elem_gtr  x;
            fun sortrec x   =   lms::sort_list       elem_gtr  x;
            #
        end;

        # Is given varhome external?
        #
        fun varhome_is_external (vh::EXTERN _)    =>   TRUE;
            varhome_is_external (vh::PATH (a, _)) =>   varhome_is_external a;
            varhome_is_external _                 =>   FALSE;
        end;

        # An exception to raise exception if
        # coreDict is not available: 
        #
        exception NO_CORE;



        # This is the external entrypoint
        # into this file.  We are invoked
        # (only) from
        #
        #     src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg
        #
        # All the remaining code in this file
        # is nested within this function:
        #
        fun translate_deep_syntax_to_lambdacode
            {
              declaration => given_declaration:  ds::Declaration,
              exported_highcode_variables:       List( tmp::Codetemp ),
              symbolmapstack:                    symbolmapstack::Symbolmapstack,
              ansi_c_prototype_convention:       String,                                #  "unix_convention" or "windows_convention"  XXX BUGGO FIXME This should be a datatype.
              # 
              per_compile_info
                  as
                    { error_match,
                      error_fn,
                      ...
                    }:                           per_compile_info::Per_Compile_Info( ds::Declaration )
            }
            :
            { lambdacode_expression:             lcf::Lambdacode_Expression,
              imports:                           List(   (ph::Picklehash, it::Import_Tree_Node)   )     
            }   
            =
            {
                if *debugging
                    printf "\n============= translate_deep_syntax_to_lambdacode/TOP =============  in translate-deep-syntax-to-lambdacode.pkg\n";
                    printf   "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\n";
                    if_debugging_unparse_declaration     ("given_declaration unparsed      at translate_deep_syntax_to_lambdacode/TOP", (given_declaration, 100) );
                    if_debugging_prettyprint_declaration ("given_declaration prettyprinted at translate_deep_syntax_to_lambdacode/TOP", (given_declaration, 100) );
                fi;

                issue_highcode_codetemp
                    =
                    per_compile_info.issue_highcode_codetemp;
                #
                fun make_var ()
                    =
                    issue_highcode_codetemp  NULL;

                # Set up a new type translator incorporating a fresh markmap:
                #
                (d2l::make_deep_syntax_to_lambdacode_type_translator ())
                    ->
                    { deepsyntax_typpath_to_uniqkind,
                      deepsyntax_typpath_to_uniqtyp,
                      deepsyntax_type_to_uniqtyp,
                      deepsyntax_type_to_uniqtype,
                      deepsyntax_package_to_uniqtype,
                      deepsyntax_generic_package_to_uniqtype,
                      mark_letbound_typevar
                    };
                #
                fun to_tc_lt  debruijn_depth
                    =
                    ( deepsyntax_type_to_uniqtyp   debruijn_depth,
                      deepsyntax_type_to_uniqtype  debruijn_depth
                    );



                # Translate the type field in
                # VALCON into Uniqtype.
                #
                # Constant valcons will take
                # void_uniqtype as the argument.
                #
                fun to_dcon_lty  debruijn_depth  type                           # "dcon" == "datatype constructor";  "lty" == "lambda type".
                    =
                    case type 
                        #                     
                        ty::TYPE_SCHEME_TYPE
                            {
                              type_scheme_arg_eq_properties => an_api,
                              type_scheme => ty::TYPE_SCHEME { arity, body }
                            }
                                =>
                                if (bt::is_arrow_type body)
                                    #
                                    deepsyntax_type_to_uniqtype  debruijn_depth  type;
                                else
                                    deepsyntax_type_to_uniqtype  debruijn_depth
                                      (
                                        ty::TYPE_SCHEME_TYPE
                                          {
                                            type_scheme_arg_eq_properties =>    an_api,
                                            type_scheme                   =>    ty::TYPE_SCHEME
                                                                                  { arity,
                                                                                    body  =>   bt::(-->) (bt::void_type, body)
                                                                                  }
                                          }
                                      );
                                fi;

                        _ =>    if (bt::is_arrow_type type)    deepsyntax_type_to_uniqtype  debruijn_depth  type;
                                else                           deepsyntax_type_to_uniqtype  debruijn_depth  (bt::(-->) (bt::void_type, type));
                                fi;
                    esac;

                # The special look-up functions for the Core dictionary:
                # 
                fun core_lookup (id, dictionary)
                    = 
                    {   sp  =   syp::SYMBOL_PATH [   csy::core_symbol,   sy::make_value_symbol id   ];
                        err =   fn _ =  fn _ =  fn _ =  raise exception NO_CORE;

                        find_in_symbolmapstack::find_value_via_symbol_path (dictionary, sp, err);
                    };
                #
                fun con' ((_, vh::REFCELL_REP, lt), ts, e)
                        =>
                        lcf::APPLY (lcf::BASEOP (hbo::MAKE_REFCELL, lt, ts), e);

                    con' ((_, vh::SUSPENSION (THE (vh::HIGHCODE_VARIABLE d, _)), lt), ts, e)
                        =>
                        {   v  =   make_var ();

                            fe =   lcf::FN (v, hcf::make_tuple_uniqtype [], e);

                            lcf::APPLY (lcf::APPLY_TYPEFUN (lcf::VAR d, ts), fe);
                        };

                    con' x => lcf::CONSTRUCTOR x;
                end;

                # The following code implements the exception tracking and 
                # errormsg reporting. 


                stipulate
                    source_code_region
                        =
                        REF (0, 0);

                    markexn =   lcf::BASEOP
                                  (
                                    hbo::MARK_EXCEPTION_WITH_STRING,                                                            # Op
                                    #
                                    hcf::make_lambdacode_arrow_uniqtype                                                         # Result type
                                      ( hcf::make_tuple_uniqtype [ hcf::exception_uniqtype, hcf::string_uniqtype ],
                                        hcf::exception_uniqtype
                                      ),
                                    []                                                                                          # Arg types.
                                  );
                herein 
                    #
                    fun with_region loc f x
                        =
                        {   r =   *source_code_region;

                            {   source_code_region := loc;

                                f x
                                before
                                    source_code_region := r;
                            }
                            except
                                e = {   source_code_region := r;
                                        raise exception e;
                                    };
                        };
                    #
                    fun make_raise (x, lt)
                        = 
                        {   e =    if *global_controls::track_exn   lcf::APPLY (markexn, lcf::RECORD [ x, lcf::STRING (error_match *source_code_region) ] );
                                   else                            x;
                                   fi;

                            lcf::RAISE (e, lt);
                        };
                    #
                    fun complain s =   error_fn   *source_code_region   s;
                    fun rep_err x  =   complain  err::ERROR  x  err::null_error_body;
                    #
                    fun maybe_report_use_of_poly_eq ()
                        = 
                        if *global_controls::poly_eq_warn
                            #
                            complain err::WARNING "calling poly_equal"  err::null_error_body;
                        fi;

                end;                    #  markexn-local 



                ############################################################################
                #          Sharing and lifting of package imports and varhomes
                ############################################################################

                exception HASHTABLE;

                Key = Int;

                # * hashkey of varhomepath + varhomepath + res_var 

                Info =  (Key, List(Int), tmp::Codetemp); 

                my hashtable:  iht::Hashtable( List( Info ) )
                            =  iht::make_hashtable  { size_hint => 32,  not_found_exception => HASHTABLE };
                #
                fun hashkey l
                    =
                    fold_backward
                        (fn (x, y) =  ((x * 10 + y) % 1019))                                                    # Are we being bloody stupid yet?  XXX SUCKO FIXME.
                        0
                        l;
                #
                fun build_header v
                    = 
                    {
                        fold_backward  h  identity_fn  info
                        where
                            info =   iht::get  hashtable  v;
                            #
                            fun h ((_, l, w), header)
                                = 
                                {   le   =   fold_forward  (fn (k, e) =  lcf::GET_FIELD (k, e))
                                                        (lcf::VAR v)
                                                        l;

                                    fn e =  header (lcf::LET (w, le, e));
                                };
                        end;
                    }
                    except
                        _ = identity_fn;

                #
                fun bindvar (var, [], _)
                        =>
                        var;

                    bindvar (var, l, name_or_null)
                        => 
                        find_or_make_var info
                        where
                            info   =   (iht::get  hashtable  var)  except _ = [];
                            key    =   hashkey l;
                            #
                            fun find_or_make_var []
                                    =>  
                                    {   var' =   issue_highcode_codetemp  name_or_null;

                                        iht::set hashtable (var, (key, l, var') ! info);

                                        var';
                                    };

                                find_or_make_var ((key', l', var') ! rest)
                                    => 
                                    if (key' == key)
                                        #
                                        if  (l' == l)  var';
                                        else           find_or_make_var  rest;
                                        fi;
                                    else
                                        find_or_make_var  rest;
                                    fi;
                            end;
                        end;
                end;

                Picklehash_Info
                  = ANON    List( (Int, Picklehash_Info) )
                  | NAMED  (tmp::Codetemp, hut::Uniqtype,  List( (Int, Picklehash_Info) ))
                  ;

                #
                fun make_picklehash_info
                    ( uniqtype,
                      l,
                      name_or_null
                    )
                    = 
                    {   v =  issue_highcode_codetemp   name_or_null;
                        #
                        fun h []      =>  NAMED (v, uniqtype, []);
                            h (a ! r) =>  ANON [(a, h r)];
                        end;

                        ( h l,
                          v
                        );
                    };
                #
                fun merge_picklehash_info (pi, uniqtype, l, name_or_null)
                    = 
                    h (pi, l)
                    where
                        fun h (z as NAMED (v, _, _), [])
                                =>
                                (z, v);

                            h (ANON xl, [])
                                => 
                                {   v = issue_highcode_codetemp  name_or_null;

                                    ( NAMED (v, uniqtype, xl),
                                      v
                                    );
                                };

                            h (z, a ! r)
                                => 
                                {   my (xl, make_node)
                                        = 
                                        case z
                                            #
                                            ANON c =>   (c, ANON);
                                            #
                                            NAMED (v, uniqtype', c)
                                                =>
                                                ( c,
                                                  fn x = NAMED (v, uniqtype', x)
                                                );
                                        esac;
                                    #
                                    fun dump ((np, v), z, y)
                                        = 
                                        {   nz =  (a, np) ! z;

                                            ( make_node ((reverse y) @ nz),
                                              v
                                            );
                                        };
                                    #   
                                    fun get ([], y)
                                            =>
                                            dump (   make_picklehash_info (uniqtype, r, name_or_null),
                                                     [],
                                                     y
                                                 );

                                        get (u as ((x as (i, pi)) ! z), y)
                                            => 
                                            if   (i <  a)   get (z, x ! y);
                                            elif (i == a)   dump (h (pi, r), z, y);
                                            else            dump (make_picklehash_info (uniqtype, r, name_or_null), u, y);
                                            fi;
                                    end;


                                    get (xl, []);
                                };
                        end;
                    end;               # where (fun merge_picklehash_info)


                # A map that stores information
                # about external references:
                # 
                picklehash_map
                    =
                    REF (phm::empty:  phm::Map( Picklehash_Info ));

                #
                fun make_picklehash (picklehash, t, l, name_or_null)
                    =
                    case (phm::get (*picklehash_map, picklehash))
                        #                     
                        NULL => 
                            {   (make_picklehash_info (t, l, name_or_null))
                                    ->
                                    (picklehash_info, var);

                                picklehash_map
                                    :=
                                    phm::set
                                      ( *picklehash_map,
                                         picklehash,
                                         picklehash_info
                                      );

                                var;
                            };

                        THE picklehash_info
                            =>
                            {   my (new_picklehash_info, var)
                                    =
                                    merge_picklehash_info (picklehash_info, t, l, name_or_null);
                                #
                                fun remove (key, map)
                                    = 
                                    {   my (new_map, _) = phm::drop (map, key); 
                                        new_map;
                                    }
                                    except
                                        e =  map;

                                picklehash_map
                                    :=
                                    phm::set
                                      ( remove (picklehash, *picklehash_map),
                                        picklehash,
                                        new_picklehash_info
                                      );
                                var;
                            };
                    esac;

                integer_map   =   REF (im::empty:  im::Map( tmp::Codetemp ));
                #
                fun get_interface_info  n
                    =
                    case (im::get (*integer_map, n))
                        #                     
                        THE v => v;
                        #
                        NULL  => {   v = make_var ();
                                     integer_map := im::set (*integer_map, n, v);
                                     v;
                                 };
                    esac;

                # Convert a varhome with type into a lambda expression 
                #
                fun translate_varhome_with_type (p, t, name_or_null)
                    = 
                    lcf::VAR (h (p, []))
                    where
                        fun h (vh::HIGHCODE_VARIABLE v, l) =>   bindvar (v, l, name_or_null);
                            h (vh::EXTERN picklehash,   l) =>   make_picklehash (picklehash, t, l, name_or_null);
                            h (vh::PATH (a, i),         l) =>   h (a, i ! l);
                            h _                            =>   bug "unexpected varhome in translate_varhome_with_type";
                        end;
                    end;

                # Convert a varhome into a lambda expression 
                #
                fun translate_varhome (p, name_or_null)
                    = 
                    lcf::VAR (h (p, []))
                    where
                        fun h (vh::HIGHCODE_VARIABLE v, l) =>   bindvar (v, l, name_or_null);
                            h (vh::PATH (a, i), l)         =>   h (a, i ! l);
                            h _                            =>   bug "unexpected varhome in translate_varhome";
                        end;
                    end;


                # These two functions are major gross hacks.
                # The NO_CORE exceptions would raised when compiling the files
                #     src/lib/core/init/runtime.pkg,
                #     src/lib/core/init/runtime.api,
                #     boot/core.pkg
                # The assumption is that the result of core_exn and core_get
                # would never be used when compiling these three files.
                #
                # A good way to clean this up would be to put all the core constructors
                # and base ops into the base ops dictionary. XXX BUGGO FIXME (ZHONG)

                exception NO_CORE;
                #
                fun core_exn id
                    =
                    case (coa::get_constructor'  (fn () =  raise exception NO_CORE)  (symbolmapstack, id))
                        #                     
                        ty::VALCON { name, form as vh::EXCEPTION _, type, ... }
                            =>
                            {   type =  to_dcon_lty  di::top  type;

                                constructor_rep  =   make_representation (form, type, name);

                                con'((name, constructor_rep, type), [], void_lexp);
                            };
                        #
                        _ => bug "core_exn in translate";
                    esac
                    except
                        NO_CORE
                            =
                            {   say "WARNING: no Core access\n";
                                lcf::INT  0;
                            }

                also
                fun core_get id
                    =
                    case (coa::get_variable'  (fn () =  raise exception NO_CORE)  (symbolmapstack, id))
                        #                     
                        vac::ORDINARY_VARIABLE { varhome, var_type, path, ... }
                            =>
                            translate_varhome_with_type (   varhome,
                                       deepsyntax_type_to_uniqtype di::top  *var_type,
                                       get_name_or_null  path
                                   );

                        _   =>
                            bug "core_get in translate";
                    esac
                    except
                        NO_CORE
                            =
                            {   say ("FATAL:  Unable to fetch '" + id + "' from core.pkg! -- translate-deep-syntax-to-lambdacode.pkg\n");
                                lcf::INT 0;
                            }

                # Expand the flex record pattern and convert the EXCEPTION varhome pattern 
                # internalize the Valcon_Form's varhome, always exceptions 
                #
                also
                fun make_representation (representation, lt, name)
                    = 
                    {   fun g (vh::HIGHCODE_VARIABLE v, l, t) =>  bindvar (v, l, THE name);
                            g (vh::PATH (a, i),         l, t) =>  g (a, i ! l, t);
                            g (vh::EXTERN p,            l, t) =>  make_picklehash (p, t, l, THE name);
                            #
                            g _ => bug "unexpected varhome in make_representation";
                        end;

                    
                        case representation
                            #
                            (vh::EXCEPTION x)
                                => 
                                {   my (argt, _) =  hcf::unpack_lambdacode_arrow_uniqtype lt;
                                    #   
                                    vh::EXCEPTION ( vh::HIGHCODE_VARIABLE ( g (x,   [],   hcf::make_exception_tag_uniqtype argt)));
                                };
                            #
                            (vh::SUSPENSION NULL)
                                =>                                              #  A hack to support "delay-force" base ops 
                                case (core_get "delay", core_get "force")
                                    #
                                    (lcf::VAR x, lcf::VAR y)
                                        =>
                                        vh::SUSPENSION ( THE ( vh::HIGHCODE_VARIABLE x,
                                                               vh::HIGHCODE_VARIABLE y
                                                             )
                                                       );
                                    #
                                    _   =>   bug "unexpected case on Valcon_Form SUSPENSION 1";
                                esac;
                            #
                            (vh::SUSPENSION (THE _))
                                =>
                                bug "unexpected case on Valcon_Form SUSPENSION 2";

                            _ => representation;
                        esac; 
                    };

                # Convert a value of varhome+info into the lambda expression 
                #
                fun translate_varhome_info (varhome, info, get_lty, name_or_null)
                    = 
                    varhome_is_external varhome   ??   translate_varhome_with_type (varhome, get_lty(), name_or_null)
                                                  ::   translate_varhome           (varhome,            name_or_null);

                #
                fun fill_pattern (pattern, d)
                    = 
                    fill pattern
                    where
                        fun fill (ds::TYPE_CONSTRAINT_PATTERN (p, t))
                                =>
                                fill p;

                            fill (ds::AS_PATTERN (p, q))
                                =>
                                ds::AS_PATTERN (fill p, fill q);

                            fill (ds::RECORD_PATTERN { fields, is_incomplete => FALSE, type_ref } )
                                =>
                                ds::RECORD_PATTERN
                                  {
                                    fields        =>   map   (fn (lab, p) =  (lab, fill p))   fields,
                                    is_incomplete =>  FALSE,
                                    type_ref
                                  };

                            fill (pattern as ds::RECORD_PATTERN { fields, is_incomplete => TRUE, type_ref } )
                                =>
                                {   exception DONT_BOTHER;

                                    fields' =   map   (fn (l, p) =  (l, fill p))   fields;
                                    #
                                    fun find (t as ty::TYPCON_TYPE (ty::RECORD_TYP labels, _))
                                            => 
                                            {   type_ref := t;
                                                labels;
                                            };

                                        find _ => {   complain err::ERROR "unresolved flexible record"
                                                          (fn stream
                                                                =
                                                                {   pp::newline stream;
                                                                    pp::string stream "pattern: ";
                                                                    uds::unparse_pattern  symbolmapstack  stream  (pattern, *global_controls::print::print_depth);
                                                                }
                                                           );

                                                       raise exception DONT_BOTHER;
                                                   };
                                    end;
                                    #
                                    fun merge (a as ((id, p) ! r), lab ! s)
                                            =>
                                            if (sy::eq (id, lab) ) (id,  p                   ) ! merge (r, s);
                                            else                   (lab, ds::WILDCARD_PATTERN) ! merge (a, s);
                                            fi;

                                        merge ([], lab ! s) => (lab, ds::WILDCARD_PATTERN) ! merge([], s);
                                        merge ([], []) => [];
                                        merge _ => bug "merge in translate";
                                    end;


                                    ds::RECORD_PATTERN
                                      {
                                        fields        =>  merge  (fields',  find (tyj::head_reduce_type  *type_ref)),
                                        is_incomplete =>  FALSE,
                                        type_ref
                                      }
                                    except
                                        DONT_BOTHER
                                            =
                                            ds::WILDCARD_PATTERN;
                                };

                            fill (ds::VECTOR_PATTERN (pats, type)) =>   ds::VECTOR_PATTERN (map fill pats, type);
                            fill (ds::OR_PATTERN (p1, p2))         =>   ds::OR_PATTERN (fill p1, fill p2);

                            fill (ds::CONSTRUCTOR_PATTERN (ty::VALCON { name, is_constant, type, is_lazy, signature, form }, ts))
                                => 
                                ds::CONSTRUCTOR_PATTERN (
                                    #
                                    ty::VALCON {
                                        #
                                        name,
                                        is_constant,
                                        type,
                                        is_lazy,
                                        signature,

                                        form
                                            =>
                                            make_representation
                                              (
                                                form,
                                                to_dcon_lty  d  type,
                                                name
                                              )
                                    },
                                    ts
                                );

                            fill (ds::APPLY_PATTERN (    ty::VALCON { name, is_constant, type, form, signature, is_lazy },
                                              ts,
                                              pattern
                                         )
                                 )
                                => 
                                ds::APPLY_PATTERN (
                                    #
                                    ty::VALCON {
                                        #
                                        name,
                                        is_constant,
                                        type,
                                        signature,
                                        is_lazy,

                                        form
                                            =>
                                            make_representation 
                                              (
                                                form,
                                                to_dcon_lty  d  type,
                                                name
                                              )
                                    },
                                    ts,
                                    fill pattern
                                );

                            fill xp
                                =>
                                xp;
                        end;
                    end;                                # fun fill_pattern 

                # The runtime polymorphic equality
                # and string equality dictionary:
                #
                polymorphic_equality_dictionary
                    =
                    { get_string_eq,
                      get_integer_eq,
                      get_poly_eq
                    }
                    where
                        my str_eq_ref:      Ref( Null_Or( lcf::Lambdacode_Expression ) ) =   REF NULL;
                        my poly_eq_ref:     Ref( Null_Or( lcf::Lambdacode_Expression ) ) =   REF NULL;
                        my integer_eq_ref:  Ref( Null_Or( lcf::Lambdacode_Expression ) ) =   REF NULL;
                        #
                        fun get_string_eq ()
                            = 
                            case *str_eq_ref
                                #                              
                                THE e => e;
                                NULL  => {   e = core_get "string_equal";                                       # string_equal  def in    src/lib/core/init/core.pkg
                                             str_eq_ref := THE e;
                                             e;
                                         };
                            esac;
                        #
                        fun get_integer_eq ()           #  same as polyeq, but silent 
                            =
                            case *integer_eq_ref
                                #                              
                                THE e => e;
                                #
                                NULL => {   e = lcf::APPLY_TYPEFUN (core_get "poly_equal",                      # poly_equal    def in    src/lib/core/init/core.pkg
                                                    [deepsyntax_type_to_uniqtyp di::top bt::multiword_int_type]);
                                            integer_eq_ref := THE e;
                                            e;
                                         };
                            esac;
                        #
                        fun get_poly_eq ()
                            = 
                            {   maybe_report_use_of_poly_eq ();

                                case *poly_eq_ref
                                    #
                                    THE e => e;
                                    #
                                    NULL => {   e = core_get "poly_equal";                                      # poly_equal    def in    src/lib/core/init/core.pkg
                                                poly_eq_ref := (THE e);
                                                e;
                                            };
                                esac;
                            };
                    end;

                eq_g = peq::equal (polymorphic_equality_dictionary, symbolmapstack); 


                ############################################################################
                #
                # Translating the primops; this should be moved into a separate file
                # in the future. (ZHONG)        XXX BUGGO FIXME
                #
                ############################################################################

                lt_tyc   = hcf::make_typ_uniqtype;
                lt_arrow = hcf::make_lambdacode_arrow_uniqtype;
                lt_tuple = hcf::make_tuple_uniqtype;
                lt_int   = hcf::int_uniqtype;
                lt_int1 = hcf::int1_uniqtype;
                lt_bool  = hcf::bool_uniqtype;
                lt_void  = hcf::void_uniqtype;

                lt_ipair    = lt_tuple [lt_int,   lt_int];
                lt_i32pair  = lt_tuple [lt_int1, lt_int1];
                #
                lt_icmp     = lt_arrow (lt_ipair, lt_bool);
                lt_ineg     = lt_arrow (lt_int,   lt_int);
                lt_intop    = lt_arrow (lt_ipair, lt_int);
                lt_voidvoid = lt_arrow (lt_void,  lt_void);

                my (true_dcon', false_dcon')
                    = 
                    ( h bt::true_dcon,
                      h bt::false_dcon
                    )
                    where
                        lt = hcf::make_lambdacode_arrow_uniqtype (hcf::void_uniqtype, hcf::bool_uniqtype);      # highcode "Void -> Bool"
                        #
                        fun h (ty::VALCON { name, form, type, ... } )                   # Take name and form from basetype, plug in our Void->Bool type.
                            =
                            (name, form, lt);
                    end;

                true_lexp  =   lcf::CONSTRUCTOR (true_dcon',  [], void_lexp); 
                false_lexp =   lcf::CONSTRUCTOR (false_dcon', [], void_lexp);
                #
                fun cond (a, b, c)
                    =
                    lcf::SWITCH
                      ( a,

                        bt::bool_signature,

                        [ (lcf::VAL_CASETAG (true_dcon',  [], make_var()), b),
                          (lcf::VAL_CASETAG (false_dcon', [], make_var()), c)
                        ],

                        NULL
                     );
                #
                fun compose_not (eq, t)
                    =  
                    {   v = make_var();
                        argt = lt_tuple [t, t];
                        lcf::FN (v, argt, cond (lcf::APPLY (eq, lcf::VAR v), false_lexp, true_lexp));
                    };
                #
                fun cmp_op  p =   lcf::BASEOP (p, lt_icmp, []);
                fun ineg_op p =   lcf::BASEOP (p, lt_ineg, []);

                lessu = hbo::CMP { op=>hbo::LTU, kindbits=>hbo::UNT 31 };

                lt_len = hcf::make_typeagnostic_uniqtype([hcf::plaintype_uniqkind], [lt_arrow (hcf::make_typevar_i_uniqtype 0, lt_int)]);

                lt_upd
                    = 
                    {   x = hcf::make_ref_uniqtype (hcf::make_typevar_i_uniqtype 0);
                        hcf::make_typeagnostic_uniqtype([hcf::plaintype_uniqkind], 
                                  [lt_arrow (lt_tuple [x, lt_int, hcf::make_typevar_i_uniqtype 0], hcf::void_uniqtype)]);
                    };
                #
                fun len_op (tc) =   lcf::BASEOP (hbo::VECTOR_LENGTH_IN_SLOTS, lt_len, [tc]);
                #
                fun rshift_op  k =  hbo::MATH { op=>hbo::RSHIFT, overflow=>FALSE,  kindbits=>k };
                fun rshiftl_op k =  hbo::MATH { op=>hbo::RSHIFTL, overflow=>FALSE, kindbits=>k };
                fun lshift_op  k =  hbo::MATH { op=>hbo::LSHIFT,  overflow=>FALSE, kindbits=>k };
                #
                fun lword0 (hbo::UNT 31) =>   lcf::UNT   0u0;  
                    lword0 (hbo::UNT 32) =>   lcf::UNT1 0u0;
                    #
                    lword0 _             =>   bug "unexpected case in lword0";
                end;
                #
                fun baselt (hbo::UNT 31) =>  lt_int;
                    baselt (hbo::UNT 32) =>  lt_int1;
                    #
                    baselt _             =>  bug "unexpected case in baselt";
                end;
                #
                fun shift_type k
                    = 
                    {   element = baselt k;
                        tupt = lt_tuple [element, lt_int]; 
                        lt_arrow (tupt, element);
                    }; 
                #
                fun inline_shift (shift_op, kindbits, clear)
                    = 
                    {   fun shift_limit (hbo::UNT lim) =>   lcf::UNT (unt::from_int lim);
                            shift_limit (hbo::INT lim) =>   lcf::UNT (unt::from_int lim);       # Yes, both coded as lcf::UNT here.
                            #                   
                            shift_limit _ => bug "unexpected case in shift_limit";
                        end;

                        p     = make_var();   vp   =   lcf::VAR  p;
                        w     = make_var();   vw   =   lcf::VAR  w;
                        count = make_var();   vcnt =   lcf::VAR  count;

                        argt = lt_tuple  [ baselt kindbits,  lt_int ];

                        cmp_shift_amt
                            = 
                            lcf::BASEOP (hbo::CMP { op=>hbo::LEU, kindbits=>hbo::UNT 31 }, lt_icmp, []);

                        lcf::FN                                                                 # fn (w, count) = if (shift_limit(kindbits) <= count)   clear w;
                          (                                                                     #                 else                                  shift_op (w, count);
                            p,                                                                  # Arg
                            argt,                                                               # Arg type
                            lcf::LET                                                            # Body
                              ( w,
                                lcf::GET_FIELD (0, vp),
                                lcf::LET
                                  ( count,
                                    lcf::GET_FIELD (1, vp),
                                    cond
                                      ( lcf::APPLY (cmp_shift_amt, lcf::RECORD [shift_limit kindbits, vcnt]),
                                        clear vw, 
                                        lcf::APPLY
                                          ( lcf::BASEOP (shift_op kindbits, shift_type kindbits, []),
                                            lcf::RECORD [vw, vcnt]
                                          )
                                      )
                                  )
                              )
                          );
                    };
                #
                fun inline_ops nk
                    =
                    {
                        my (lt_arg, zero, overflow)
                            =
                            case nk                                                     # "nk" == "number kind (and bitsize)"
                                #
                                hbo::INT   31 => (hcf::int_uniqtype,      lcf::INT        0,  TRUE );
                                hbo::UNT   31 => (hcf::int_uniqtype,      lcf::UNT      0u0,  FALSE);
                                hbo::INT   32 => (hcf::int1_uniqtype,    lcf::INT1      0,  TRUE );
                                hbo::UNT   32 => (hcf::int1_uniqtype,    lcf::UNT1    0u0,  FALSE);
                                hbo::FLOAT 64 => (hcf::float64_uniqtype,  lcf::FLOAT64 "0.0", FALSE);
                                #
                                _ => bug "inline_ops: bad number_kind_and_bitsize";
                            esac;

                        lt_argpair =   lt_tuple [lt_arg, lt_arg];

                        compare_lambda_types =   lt_arrow (lt_argpair, lt_bool);

                        lt_neg =   lt_arrow (lt_arg, lt_arg);

                        less    =   lcf::BASEOP (hbo::CMP  { op => hbo::LT,     kindbits => nk           }, compare_lambda_types, []);
                        greater =   lcf::BASEOP (hbo::CMP  { op => hbo::GT,     kindbits => nk           }, compare_lambda_types, []);
                        negate  =   lcf::BASEOP (hbo::MATH { op => hbo::NEGATE, kindbits => nk, overflow }, lt_neg,               []);

                        { lt_arg, lt_argpair, compare_lambda_types, less, greater, zero, negate };
                    };
                #
                fun inl_minmax (nk, ismax)
                    =
                    {   (inline_ops nk) ->   { lt_argpair, less, greater, compare_lambda_types, ... };

                        x =  make_var ();
                        y =  make_var ();
                        z =  make_var ();

                        cmp_op =    if ismax  greater;
                                    else      less;
                                    fi;

                        elsebranch
                            =
                            case nk
                                #
                                hbo::FLOAT _ => {
                                    #  testing for NaN 
                                    fequal =
                                        lcf::BASEOP (hbo::CMP { op => hbo::EQL, kindbits => nk }, compare_lambda_types, []);

                                    cond (lcf::APPLY (fequal, lcf::RECORD [lcf::VAR y, lcf::VAR y]), lcf::VAR y, lcf::VAR x);
                                };

                                _ => lcf::VAR y;
                            esac;

                        lcf::FN (z, lt_argpair,
                            lcf::LET (x, lcf::GET_FIELD (0, lcf::VAR z),
                                 lcf::LET (y, lcf::GET_FIELD (1, lcf::VAR z),
                                      cond (lcf::APPLY (cmp_op, lcf::RECORD [lcf::VAR x, lcf::VAR y]),
                                            lcf::VAR x, elsebranch))));
                    };
                #
                fun inl_abs nk
                    =
                    {   (inline_ops nk) ->   { lt_arg, greater, zero, negate, ... };

                        x = make_var ();

                        lcf::FN (x, lt_arg,
                            cond (lcf::APPLY (greater, lcf::RECORD [lcf::VAR x, zero]),
                                  lcf::VAR x, lcf::APPLY (negate, lcf::VAR x)));
                    };
                #
                fun inl_inf_prec (what, corename, p, lt, is_from_inf)                   # 'inf' is probably 'indefinite-precision-integer'.  'prec' is 'precision-conversion', i.e. bitwidth change.
                    =
                    {   my (orig_arg_lt, res_lt)
                            =
                            case (hcf::unpack_arrow_uniqtype lt)
                                #                              
                                (_, [a], [r]) =>  (a, r);
                                _             =>  bug ("unexpected type of " + what);
                            esac;

                        extra_arg_lt
                            =
                            hcf::make_lambdacode_arrow_uniqtype  if is_from_inf  (orig_arg_lt, hcf::int1_uniqtype);
                                             else            (hcf::int1_uniqtype, orig_arg_lt);
                                             fi;

                        new_arg_lt =  hcf::make_tuple_uniqtype [orig_arg_lt, extra_arg_lt];
                        new_lt     =  hcf::make_lambdacode_arrow_uniqtype (new_arg_lt, res_lt);

                        x = make_var ();

                        lcf::FN (x, orig_arg_lt,
                            lcf::APPLY (lcf::BASEOP (p, new_lt, []),
                                 lcf::RECORD [lcf::VAR x, core_get corename]));
                    };
                #
                fun translate_baseop (baseop, lt, ts)           
                    = 
                    g baseop
                    where
                        fun g (hbo::LSHIFT_MACRO  k) =>  inline_shift (lshift_op,  k, fn _ =  lword0 (k));
                            g (hbo::RSHIFTL_MACRO k) =>  inline_shift (rshiftl_op, k, fn _ =  lword0 (k));

                            g (hbo::RSHIFT_MACRO k)                                     # Preserve sign bit with arithmetic rshift 
                                =>
                                inline_shift (rshift_op, k, clear)
                                where
                                    fun clear w
                                        =
                                        lcf::APPLY (lcf::BASEOP (rshift_op k, shift_type k, []), 
                                                      lcf::RECORD [w, lcf::UNT 0u31]); 
                                end;

                            g (hbo::MIN_MACRO nk) =>   inl_minmax (nk, FALSE);
                            g (hbo::MAX_MACRO nk) =>   inl_minmax (nk, TRUE);
                            g (hbo::ABS_MACRO nk) =>   inl_abs nk;

                            g hbo::NOT_MACRO
                                =>
                                {   x = make_var();

                                    lcf::FN (x, lt_bool, cond (lcf::VAR x, false_lexp, true_lexp));
                                }; 

                            g hbo::COMPOSE_MACRO
                                =>
                                {   my (t1, t2, t3)
                                        = 
                                        case ts
                                            #                                     
                                            [a, b, c] =>  ( lt_tyc  a,
                                                            lt_tyc  b,
                                                            lt_tyc  c
                                                          );

                                            _         =>  bug "unexpected type for INLCOMPOSE";
                                        esac;

                                    argt = lt_tuple [ lt_arrow  (t2, t3),
                                                      lt_arrow  (t1, t2)
                                                    ];

                                    x =  make_var ();
                                    z =  make_var (); 
                                    f =  make_var ();
                                    g =  make_var ();

                                    lcf::FN (z, argt, 
                                        lcf::LET (f, lcf::GET_FIELD (0, lcf::VAR z),
                                          lcf::LET (g, lcf::GET_FIELD (1, lcf::VAR z),
                                            lcf::FN (x, t1, lcf::APPLY (lcf::VAR f, lcf::APPLY (lcf::VAR g, lcf::VAR x))))));
                                };                  

                            g hbo::BEFORE_MACRO
                                =>
                                {   my (t1, t2)
                                        = 
                                        case ts
                                            #                                     
                                            [a, b] =>  (lt_tyc a, lt_tyc b);
                                            _      =>  bug "unexpected type for INLBEFORE";
                                        esac;

                                    argt = lt_tuple [t1, t2];
                                    x = make_var();

                                    lcf::FN (x, argt, lcf::GET_FIELD (0, lcf::VAR x));
                                };

                            g hbo::IGNORE_MACRO
                                =>
                                {   argt =
                                        case ts
                                            #                                     
                                            [a] =>  lt_tyc a;
                                            _   =>  bug "unexpected type for INLIGNORE";
                                        esac;

                                    lcf::FN (make_var (), argt, void_lexp);
                                };

                            g hbo::IDENTITY_MACRO
                                =>
                                {   argt =
                                        case ts
                                            #                                     
                                            [a] =>  lt_tyc  a;
                                            _   =>  bug "unexpected type for INLIDENTITY";
                                        esac;

                                    v = make_var ();

                                    lcf::FN (v, argt, lcf::VAR v);
                                };

                            g hbo::CVT64
                                =>
                                {   v = make_var ();
                                    lcf::FN (v, lt_i32pair, lcf::VAR v);
                                };

                            g hbo::GET_RO_VECSLOT_CONTENTS_AFTER_BOUNDS_CHECK
                                =>
                                {   my (tc1, t1)
                                        =
                                        case ts
                                            #                                     
                                            [z] =>  (z, lt_tyc z);
                                            _   =>  bug "unexpected type for INLSUBV";
                                        esac;

                                    seqtc =  hcf::make_ro_vector_uniqtyp tc1;
                                    argt  =  lt_tuple [lt_tyc seqtc, lt_int];

                                    op =   lcf::BASEOP (hbo::GET_RW_VECSLOT_CONTENTS, lt, ts);

                                    p =  make_var ();
                                    a =  make_var ();
                                    i =  make_var ();

                                    vp =  lcf::VAR  p;
                                    va =  lcf::VAR  a;
                                    vi =  lcf::VAR  i;

                                    if *coc::check_vector_index_bounds
                                        #
                                        lcf::FN (p, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vp),
                                              lcf::LET (i, lcf::GET_FIELD (1, vp),
                                                cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op seqtc, va)]),             # if i < len(v)
                                                     lcf::APPLY (op, lcf::RECORD [va, vi]),                                                     #      a[i];
                                                     make_raise (core_exn "SUBSCRIPT", t1)))));                                                 # else raise exception SUBSCRIPT;  fi;
                                    else
                                        lcf::FN (p, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vp),
                                                lcf::LET (i, lcf::GET_FIELD (1, vp),
                                                    lcf::APPLY (op, lcf::RECORD [va, vi]))));                                                   #      a[i];
                                    fi;
                                };


                            g  hbo::GET_RW_VECSLOT_CONTENTS_AFTER_BOUNDS_CHECK
                                => 
                                {   my (tc1, t1)
                                        =
                                        case ts
                                            #                                     
                                            [z] => (z, lt_tyc z);
                                            _   => bug "unexpected type for INLSUB";
                                        esac;

                                    seqtc = hcf::make_rw_vector_uniqtyp tc1;
                                    argt  = lt_tuple [lt_tyc seqtc, lt_int];

                                    op =  lcf::BASEOP (hbo::GET_RW_VECSLOT_CONTENTS, lt, ts);

                                    p = make_var();
                                    a = make_var();
                                    i = make_var();

                                    vp = lcf::VAR p;
                                    va = lcf::VAR a;
                                    vi = lcf::VAR i;

                                    if *coc::check_vector_index_bounds
                                        #
                                        lcf::FN (p, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vp),
                                              lcf::LET (i, lcf::GET_FIELD (1, vp),
                                                cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op seqtc, va)]),             # if i < len(v)
                                                     lcf::APPLY (op, lcf::RECORD [va, vi]),                                                     #      a[i];
                                                     make_raise (core_exn "SUBSCRIPT", t1)))));                                                 # else raise exception SUBSCRIPT;  fi;
                                    else
                                        lcf::FN (p, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vp),
                                                lcf::LET (i, lcf::GET_FIELD (1, vp),
                                                     lcf::APPLY (op, lcf::RECORD [va, vi]))));                                                  #      a[i];
                                    fi;
                                };

                            g (hbo::GET_VECSLOT_NUMERIC_CONTENTS { kindbits, checked=>TRUE, immutable } )
                                =>
                                {   my (tc1, t1, t2)
                                        = 
                                        case ts
                                            #                                     
                                            [a, b] =>  (a, lt_tyc a, lt_tyc b);
                                            _      =>  bug "unexpected type for NUMSUB";
                                        esac;

                                    argt = lt_tuple [t1, lt_int];

                                    p = make_var();
                                    a = make_var();
                                    i = make_var();

                                    vp = lcf::VAR p;
                                    va = lcf::VAR a;
                                    vi = lcf::VAR i;

                                    op = hbo::GET_VECSLOT_NUMERIC_CONTENTS { kindbits, checked=>FALSE,
                                                               immutable };
                                    op' = lcf::BASEOP (op, lt, ts);

                                    if *coc::check_vector_index_bounds
                                        #
                                        lcf::FN (p, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vp),
                                              lcf::LET (i, lcf::GET_FIELD (1, vp),
                                                cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op tc1, va)]),               # if i < len(v)
                                                     lcf::APPLY (op', lcf::RECORD [va, vi]),                                                    #      a[i];
                                                     make_raise (core_exn "SUBSCRIPT", t2)))));                                                 # else raise exception SUBSCRIPT;  fi;
                                    else
                                        lcf::FN (p, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vp),
                                                lcf::LET (i, lcf::GET_FIELD (1, vp),
                                                     lcf::APPLY (op', lcf::RECORD [va, vi]))));                                                 #      a[i];
                                    fi;
                                };

                            g hbo::SET_VECSLOT_AFTER_BOUNDS_CHECK
                                => 
                                {   my (tc1, t1)
                                        =
                                        case ts
                                            #                                     
                                            [z] =>  (z, lt_tyc z);
                                            _   =>  bug "unexpected type for INLSUB";
                                        esac;

                                    seqtc = hcf::make_rw_vector_uniqtyp tc1;
                                    argt = lt_tuple [lt_tyc seqtc, lt_int, t1];

                                    op = lcf::BASEOP (hbo::SET_VECSLOT, lt, ts);

                                    x = make_var();

                                    a = make_var();
                                    i = make_var();
                                    v = make_var();

                                    vx = lcf::VAR x;
                                    va = lcf::VAR a;
                                    vi = lcf::VAR i;
                                    vv = lcf::VAR v;

                                    if *coc::check_vector_index_bounds
                                        #
                                        lcf::FN (x, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vx),
                                              lcf::LET (i, lcf::GET_FIELD (1, vx),
                                                lcf::LET (v, lcf::GET_FIELD (2, vx),
                                                  cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op seqtc, va)]),           # if i < len(v)
                                                       lcf::APPLY (op, lcf::RECORD [va, vi, vv]),                                               #     a[i] = v;
                                                       make_raise (core_exn "SUBSCRIPT", hcf::void_uniqtype))))));                              # else raise exception SUBSCRIPT; fi;
                                    else
                                        #
                                        lcf::FN (x, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vx),
                                                lcf::LET (i, lcf::GET_FIELD (1, vx),
                                                    lcf::LET (v, lcf::GET_FIELD (2, vx),
                                                        lcf::APPLY (op, lcf::RECORD [va, vi, vv])))));                                          #     a[i] = v;
                                    fi;
                                };

                            g (hbo::SET_VECSLOT_TO_NUMERIC_VALUE { kindbits, checked=>TRUE } )
                                =>
                                {   my (tc1, t1, t2)
                                        = 
                                        case ts
                                            #                                     
                                            [a, b] =>  (a, lt_tyc a, lt_tyc b);
                                            _      =>  bug "unexpected type for SET_VECSLOT_TO_NUMERIC_VALUE";
                                        esac;

                                    argt = lt_tuple [t1, lt_int, t2];

                                    p = make_var();
                                    a = make_var();
                                    i = make_var();
                                    v = make_var();

                                    vp = lcf::VAR p;
                                    va = lcf::VAR a;
                                    vi = lcf::VAR i;
                                    vv = lcf::VAR v;

                                    op = hbo::SET_VECSLOT_TO_NUMERIC_VALUE { kindbits, checked=>FALSE };
                                    op' = lcf::BASEOP (op, lt, ts);

                                    if *coc::check_vector_index_bounds
                                        #
                                        lcf::FN (p, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vp),
                                              lcf::LET (i, lcf::GET_FIELD (1, vp),
                                                lcf::LET (v, lcf::GET_FIELD (2, vp),
                                                  cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op tc1, va)]),             # if i < len(v)
                                                       lcf::APPLY (op', lcf::RECORD [va, vi, vv]),                                              #     a[i] = v;
                                                       make_raise (core_exn "SUBSCRIPT", hcf::void_uniqtype))))));                              # else raise exception SUBSCRIPT; fi;
                                    else
                                        lcf::FN (p, argt,
                                            lcf::LET (a, lcf::GET_FIELD (0, vp),
                                                lcf::LET (i, lcf::GET_FIELD (1, vp),
                                                    lcf::LET (v, lcf::GET_FIELD (2, vp),
                                                        lcf::APPLY (op', lcf::RECORD [va, vi, vv])))));                                         #     a[i] = v;
                                    fi;
                                };

                  /**** ASSIGN (r, x) != UPDATE (r, 0, x) under new rw_vector reps (John H Reppy;1998-10-30)
                          | g (hbo::SET_REFCELL) = 
                                let my (tc1, t1) = case ts of [z] => (z, lt_tyc z)
                                                      | _ => bug "unexpected type for ASSIGN"

                                    seqtc = hcf::make_ref_uniqtyp tc1
                                    argt = lt_tuple [lt_tyc seqtc, t1]

                                    op = lcf::BASEOP (hbo::SET_VECSLOT, lt_upd, [tc1])

                                    x = make_var()
                                    varX = lcf::VAR x

                                 in lcf::FN (x, argt, 
                                     lcf::APPLY (op, lcf::RECORD [lcf::GET_FIELD (0, varX), lcf::INT 0, lcf::GET_FIELD (1, varX)]))
                                end
                  ****/

                            # Precision-conversion operations involving integer.
                            # These need to be translated specially by providing
                            # a second argument -- the routine from _Core that
                            # does the actual conversion to or from integer.

                            g (p as hbo::SHRINK_INTEGER prec)
                                =>
                                inl_inf_prec ("TEST_INF", "test_inf", p, lt, TRUE);


                            g (p as hbo::CHOP_INTEGER prec)
                                =>
                                inl_inf_prec ("TRUNC_INF", "trunc_inf", p, lt, TRUE);


                            g (p as hbo::STRETCH_TO_INTEGER prec)
                                =>
                                inl_inf_prec ("EXTEND_INF", "fin_to_inf", p, lt, FALSE);


                            g (p as hbo::COPY_TO_INTEGER prec)
                                =>
                                inl_inf_prec ("COPY", "fin_to_inf", p, lt, FALSE);

                            # Default handling for all other
                            # base operations:
                            #
                            g baseop
                                =>
                                lcf::BASEOP (baseop, lt, ts);
                        end; 
                    end;                        #  where (fun translate_baseop)

                #
                fun make_integer_switch (sv, cases, default)
                    =
                    {   v = make_var ();

                        # Build a chain of equality tests
                        # for checking large pattern values 
                        #
                        fun build []
                                =>
                                default;

                            build ((n, e) ! r)
                                =>
                                cond ( lcf::APPLY ( polymorphic_equality_dictionary.get_integer_eq (),
                                             lcf::RECORD [lcf::VAR v, lcf::VAR (get_interface_info n)]
                                           ),
                                       e,
                                       build r
                                     );
                        end;

                        # Split pattern values into small values and large values.
                        # Small values can be handled directly using SWITCH:
                        #
                        fun split ([], s, l)
                                =>
                                (reverse s, reverse l);

                            split ((n, e) ! r, sm, lg)
                                =>
                                case (ln::low_val n)
                                    #
                                    THE l =>   split (r, (lcf::INT_CASETAG l, e) ! sm, lg);
                                    NULL  =>   split (r, sm, (n, e) ! lg);
                                esac;
                        end;
                        #
                        fun gen ()
                            =
                            case (split (cases, [], []))
                                #
                                ([], largeints)
                                    =>
                                    build largeints;

                                (smallints, largeints)
                                    =>
                                    {   iv = make_var ();

                                        lcf::LET
                                          ( iv,

                                            lcf::APPLY (core_get "inf_low_value", lcf::VAR v),

                                            lcf::SWITCH
                                              (
                                                lcf::VAR iv,
                                                vh::NULLARY_CONSTRUCTOR,
                                                smallints,
                                                THE (build largeints)
                                              )
                                          );
                                    };
                            esac;

                        lcf::LET (v, sv, gen ());
                    };


                ##########################################################################################
                # 
                # Translation of various namings into lambda expressions:
                # 
                #  translate_variable:  (vac::Variable, di::Debruijn_Depth) -> lcf::Lambdacode_Expression
                #  mkVE:  (vac::var, List( t::Type )) -> lcf::Lambdacode_Expression
                #  mkCE:  ( t::Constructor,
                #              List( t::Type ),
                #              Null_Or( lcf::Lambdacode_Expression ),
                #              di::Debruijn_Depth
                #            )
                #          -> l::Lambdacode_Expression
                #  translate_package:  (mld::Package, di::Debruijn_Depth) -> lcf::Lambdacode_Expression
                #  translate_generic:  (mld::Generic, di::Debruijn_Depth) -> lcf::Lambdacode_Expression
                #  translate_symbolmapstack_entry:    di::Debruijn_Depth  -> sxe::naming -> lcf::Lambdacode_Expression
                #
                ##########################################################################################
                fun translate_variable
                        ( (v as vac::ORDINARY_VARIABLE { varhome, inlining_data, var_type, path }):   vac::Variable,
                          debruijn_depth:  di::Debruijn_Depth
                        )
                        : lcf::Lambdacode_Expression
                        => 
                        translate_varhome_info
                          (
                            varhome,
                            inlining_data,
                            fn () =  deepsyntax_type_to_uniqtype  debruijn_depth  *var_type,
                            get_name_or_null  path
                          );

                    translate_variable _
                        =>
                        bug "unexpected vars in makeVariable";
                end;
                #
                fun translate_variable_in_expression (v, ts, d)
                    =
                    {   fun otherwise ()
                            =
                            case ts
                                #
                                [] =>  translate_variable (v, d);
                                _  =>  lcf::APPLY_TYPEFUN (translate_variable (v, d), map (deepsyntax_type_to_uniqtyp d) ts);
                            esac;
                    
                        case v
                            #                     
                            vac::ORDINARY_VARIABLE { inlining_data, ... }
                                =>
                                ij::case_inlining_data  inlining_data
                                  {
                                    do_inline_package =>  fn _  =  otherwise (),
                                    do_inline_nothing =>  fn () =  otherwise (),

                                    do_inline_baseop
                                        =>
                                        fn ( baseop:            hbo::Baseop,
                                             type
                                           )
                                            =
                                            case (baseop, ts)
                                                #                                                 
                                                (hbo::POLY_EQL, [t])
                                                    =>
                                                    eq_g (type, t, to_tc_lt d);

                                                (hbo::POLY_NEQ, [t])
                                                    =>
                                                    compose_not (eq_g (type, t, to_tc_lt d), deepsyntax_type_to_uniqtype d t);

                                                (hbo::MAKE_RW_VECTOR_MACRO, [t])
                                                    => 
                                                    {   dictionary = 
                                                            { default =>  core_get "make_vector",                                               # make_vector           def in    src/lib/core/init/core.pkg
                                                              table   =>  [ ([hcf::float64_uniqtyp], core_get "make_float_vector") ]            # make_float_vector     def in    src/lib/core/init/core.pkg
                                                            };

                                                        lcf::GENOP (
                                                            dictionary,
                                                            baseop,
                                                            deepsyntax_type_to_uniqtype  d  type,
                                                            map  (deepsyntax_type_to_uniqtyp d)  ts
                                                        );
                                                    };

                                                (hbo::RAW_CCALL NULL, [a, b, c])
                                                    =>
                                                    {   i = THE (cprototype::decode ansi_c_prototype_convention
                                                                                  { function_type => a, encoding => b }
                                                                )
                                                                except
                                                                    cprototype::BAD_ENCODING =  NULL;

                                                        lcf::BASEOP (
                                                            hbo::RAW_CCALL  i,
                                                            deepsyntax_type_to_uniqtype  d  type,
                                                            map  (deepsyntax_type_to_uniqtyp d)  ts
                                                        );
                                                    };

                                                _   =>
                                                    translate_baseop
                                                      (
                                                        baseop,
                                                        (deepsyntax_type_to_uniqtype d type),
                                                        map (deepsyntax_type_to_uniqtyp d) ts
                                                      );
                                            esac
                                };

                            _   =>
                                otherwise ();
                        esac;
                    };
                #
                fun translate_constructor_expression (ty::VALCON { is_constant, form, name, type, ... }, ts, ap_op, d)
                    = 
                    {   lt = to_dcon_lty  d  type;
                        form' = make_representation (form, lt, name);
                        dc = (name, form', lt);
                        ts' = map (deepsyntax_type_to_uniqtyp d) ts;

                        if is_constant
                            #
                            con'(dc, ts', void_lexp);
                        else
                            case ap_op
                                #                              
                                THE le => con'(dc, ts', le);

                                NULL => 
                                  {   my (arg_t, _) = hcf::unpack_lambdacode_arrow_uniqtype (hcf::apply_typeagnostic_type_to_arglist_with_single_result (lt, ts'));
                                      v = make_var ();
                                      lcf::FN (v, arg_t, con'(dc, ts', lcf::VAR v));
                                  };
                            esac;
                        fi;
                    };
                #
                fun translate_package (s as mld::A_PACKAGE { varhome, inlining_data=>info, ... }, d)
                        =>
                        translate_varhome_info
                            (
                              varhome,
                              info,
                              fn () = deepsyntax_package_to_uniqtype (s, d, per_compile_info),
                              NULL
                            );

                    translate_package _ =>   bug "unexpected packages in translate_package";
                end;

                #
                fun translate_generic (f as mld::GENERIC { varhome, inlining_data=>info, ... }, d)
                        =>
                        translate_varhome_info
                            (
                              varhome,
                              info,
                              fn () = deepsyntax_generic_package_to_uniqtype (f, d, per_compile_info),
                              NULL
                            );

                    translate_generic _ =>   bug "unexpected generics in translate_generic";
                end;

                #
                fun translate_symbolmapstack_entry
                    (debruijn_depth:  di::Debruijn_Depth)
                    : (sxe::Symbolmapstack_Entry -> lcf::Lambdacode_Expression)
                    =
                    g
                    where
                        fun g (sxe::NAMED_VARIABLE v) =>  translate_variable (v, debruijn_depth);
                            g (sxe::NAMED_PACKAGE  s) =>  translate_package  (s, debruijn_depth);
                            g (sxe::NAMED_GENERIC  f) =>  translate_generic  (f, debruijn_depth);

                            g (sxe::NAMED_CONSTRUCTOR (ty::VALCON  { form=> vh::EXCEPTION acc,  name,  type, ... } ))
                                =>
                                {   nt = to_dcon_lty  debruijn_depth  type;

                                    my (argt, _) = hcf::unpack_lambdacode_arrow_uniqtype nt;

                                    translate_varhome_with_type (acc, hcf::make_exception_tag_uniqtype argt, THE name);
                                };

                            g _ => bug "unexpected namings in translate_symbolmapstack_entry";
                        end;
                    end;


                #################################################################################
                # 
                # Translate core deep_syntax_tree declarations into lambda expressions:
                # 
                #    my translate_named_values:  List( ds::Named_Value )
                #                          * depth
                #                         -> lcf::Lambdacode_Expression
                #                         -> lcf::Lambdacode_Expression
                # 
                #    my translate_named_recursive_values
                #        :
                #        (List( ds::Named_Recursive_Values ) * )
                #     -> lcf::Lambdacode_Expression
                #     -> lcf::Lambdacode_Expression
                # 
                #    my translate_exception_declarations:   List( ds::eb )
                #               * depth
                #              -> lcf::Lambdacode_Expression
                #              -> lcf::Lambdacode_Expression
                #
                #################################################################################

                                                                                                        # lambdacode_form       is from   src/lib/compiler/back/top/lambdacode/lambdacode-form.pkg
                                                                                                        # deep_syntax           is from   src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.pkg

/*x*/           fun translate_pattern_expression (expression, d, [], callstack)
                        =>
                        {
                                    if *debugging
                                        print_callstack "\n============= translate_pattern_expression/TOP ============= " callstack;
                                        if_debugging_unparse_expression ("translate_pattern_expression input expression argument:", (expression,100));
                                        printf "translate_pattern_expression bound_typevar_refs argument has 0 entries so calling translate_expression instead of translate_pattern-expression.\n";
                                    fi;

                            result = translate_deep_syntax_expression_to_lambdacode (expression, d, "translate_pattern_expression" ! callstack );

                                    if *debugging
                                        printf "translate_pattern_expression/BOTTOM in translate-deep-syntax-to-lambdacode.pkg\n";
                                    fi;

                            result;
                        };

/*x*/               translate_pattern_expression
/*x*/                   ( expression:          ds::Deep_Expression,
/*x*/                     debruijn_depth:      di::Debruijn_Depth,
/*x*/                     bound_typevar_refs:  List( types::Typevar_Ref ),      # From a deep syntax NAMED_VALUE or NAMED_RECURSIVE_VALUES record.
/*x*/                     callstack:           List( String ) 
/*x*/                   )
/*x*/                   : lcf::Lambdacode_Expression
/*x*/                   => 
/*x*/                   {
                            if *debugging
                                print_callstack "\n============= translate_pattern_expression/TOP ============= " callstack;
                                if_debugging_unparse_expression ("translate_pattern_expression input expression argument:", (expression,100));
                                printf "translate_pattern_expression bound_typevar_refs argument has %d entries:\n"  (length  bound_typevar_refs);
                                apply unparse bound_typevar_refs
                                where
                                    fun unparse  typevar_ref
                                        =
                                        if_debugging_unparse_typevar_ref  ("", typevar_ref);
                                end;
                                printf "\n";
                            fi;



/*x*/                       bound_typevar_refs'
/*x*/                           =
/*x*/                           map f bound_typevar_refs
/*x*/                           where
/*x*/                               fun f { id, ref_typevar }
/*x*/                                   =
/*x*/                                   ref_typevar;
/*x*/                           end;

/*x*/                       old_bound_typevar_refs_values
/*x*/                           =
/*x*/                           map  (*_)  bound_typevar_refs';

                                                                                        # translate_types       is from   src/lib/compiler/back/top/translate/translate-deep-syntax-types-to-lambdacode.pkg
                            # Assign TYPE_VARIABLE_MARK type_variables.
                            # We will erase these before we return.
                            #
                            # These TYPE_VARIABLE_MARK values are only
                            # used in translate_deep_syntax_types_to_lambdacode::deepsyntax_type_to_uniqtyp():  
                            #
                            #   "We have implemented a "minimum typing derivation" phase in our compiler to give
                            #    all local variables "least" polymorphic types.  The derivation is done after [typechecking]
                            #    so that is it only applied to type-correct programs.  Our algoirthm, which is similar
                            #    to Bjorner's algorithm M, does a bottom-up traversal of the [deep syntax].
                            #    During the traversal, we mark all variables which are local (e.g. let-bound)
                            #    or hidden because of signature matching.  For each marked polymorphic variable v
                            #    we gather all of its actual type instantiations and reassign v a new type -- the
                            #    lead general type scheme that generalizes [its instantiations].  The new type is
                            #    then propagated into v's declaration d, constraining other variables referenced by d."
                            #
                            #          -- p33, "Compiling Standard ML For Efficient Execution on Modern Machines"
                            #             http://flint.cs.yale.edu/flint/publications/zsh-thesis.pdf
                            #
/*x*/                       g (0, bound_typevar_refs)
                            where
                                fun g (i, [])
                                        =>
                                        ();

/*x*/                               g (i, { id, ref_typevar as REF (ty::META_TYPE_VARIABLE _ | ty::INCOMPLETE_RECORD_TYPE_VARIABLE _) } ! rest)
/*x*/                                   =>
/*x*/                                   {   m =   mark_letbound_typevar (debruijn_depth, i);            # This is the only call to mark_letbound_typevar in the compiler.

                                            if *debugging
                                                printf "Setting [id%d]typevar_ref to (TYPE_VARIABLE_MARK (mark_letbound_typevar (d==%d, i==%d))):  g()  in  translate_pattern_expression()  in translate_deep_syntax_to_lambdacode\n" id (di::dp_toint debruijn_depth)  i;
                                            fi;

/*x*/                                       ref_typevar :=   ty::TYPE_VARIABLE_MARK m;          # This is the only place TYPE_VARIABLE_MARK are created.

/*x*/                                       g (i+1, rest);
                                        };

                                    # 2009-06-01 CrT: In the parent SML/NJ compiler this case cannot happen.
                                    # When I added OOP support, in particular generalizing mutually recursive
                                    # functions, it became possible, but so far as I can see it is harmless,
                                    # so now we just ignore this case:
                                    #
/*x*/                               g (i, ( typevar_ref as { id, ref_typevar as REF (ty::TYPE_VARIABLE_MARK _) } ) ! result)
/*x*/                                   =>
                                        {   if *debugging
                                                printf "Ignoring the fact that [id%d]typevar_ref is already set to (TYPE_VARIABLE_MARK (i d==%d) translate_deep_syntax_to_lambdacode\n" id i;
                                            fi;
/*x*/                                      # bug (sprintf "unexpected [id%d]type_variable TYPE_VARIABLE_MARK in translate_pattern_expression i d=%d" id i);
/*x*/                                      ();
                                        };

                                    g _ => bug "unexpected type_variable MACRO_EXPANDED in translate_pattern_expression";
                                end;
                            end;


/*x*/                       expression' = translate_deep_syntax_expression_to_lambdacode (expression, di::next debruijn_depth, "translate_pattern_expression" ! callstack);

                            if *debugging
                                printf "translate_pattern_expression/BBB in translate-deep-syntax-to-lambdacode.pkg\n";
                            fi; 

                            # Set all bound_typevar_refs
                            # back to their original value:
                            #
                            restore (bound_typevar_refs', old_bound_typevar_refs_values)
                            where
                                fun restore ([], [])
                                        =>
                                        ();

                                    restore
                                        ( ref_typevar ! ref_typevars,
                                          old_value   ! old_values
                                        )
                                        =>
                                        {   ref_typevar := old_value;
                                            restore (ref_typevars, old_values);
                                        };

                                    restore _
                                        =>
                                        bug "unexpected cases in translate_pattern_expression";
                                end;
                            end;

                            len = length  bound_typevar_refs';

                            if *debugging
                                printf "translate_pattern_expression/BOTTOM in translate-deep-syntax-to-lambdacode.pkg\n";
                                printf "translate_pattern_expression bound_typevar_refs argument %d entries restored:\n"  (length  bound_typevar_refs);
                                apply unparse bound_typevar_refs
                                where
                                    fun unparse  typevar_ref
                                        =
                                        if_debugging_unparse_typevar_ref  ("", typevar_ref);
                                end;
                            fi; 

                            lcf::TYPEFUN (hcf::n_plaintype_uniqkinds  len,  expression');
                        };
                end 

                also
/*x*/           fun translate_named_values
/*x*/               ( named_values:    List( ds::Named_Value ),         # Obtained from a ds::VALUE_DECLARATIONS
/*x*/                 debruijn_depth:  di::Debruijn_Depth,
/*x*/                 callstack:       List( String ) 
/*x*/               )
/*x*/               : (lcf::Lambdacode_Expression -> lcf::Lambdacode_Expression)
/*x*/               =
/*x*/               {
                                                             if *debugging    print_callstack "\n============= translate_named_values/TOP    ============= " callstack; fi;
/*x*/                   result =  fold  g  named_values;
                                                             if *debugging    print_callstack "\n============= translate_named_values/BOTTOM ============= " callstack; fi;
/*x*/                   result;
/*x*/               }
                    where
                        fun eq_tvs ([], [])                                     # "tvs" == "type variables"
                                =>
                                TRUE;

                            eq_tvs (a ! r, (ty::TYPE_VARIABLE_REF b) ! s)
                                =>
                                if (a==b)  eq_tvs (r, s);
                                else       FALSE;
                                fi;

                            eq_tvs _
                                =>
                                FALSE;
                        end;

/*x*/                   fun g named_value
/*x*/                       =
/*x*/                       {
                                                             if *debugging printf "\ntranslate_named_values/LOOP TOP\n"; fi;
/*x*/                           result =  g'  named_value;
                                                             if *debugging printf "\ntranslate_named_values/LOOP BOTTOM\n"; fi;
/*x*/                           result;
/*x*/                       }
                        also
                        fun g'  ( ds::NAMED_VALUE
                                    {
                                      pattern    => ds::VARIABLE_IN_PATTERN (vac::ORDINARY_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, ... } ),
                                      expression as ds::VARIABLE_IN_EXPRESSION (REF (w as (vac::ORDINARY_VARIABLE _)), instys),
                                      bound_typevar_refs,
                                      ...
                                    },
                                  fold_result_so_far
                                )
                                => 
                                if   (eq_tvs (bound_typevar_refs, instys))
if *debugging printf "\nCALLING translate_variable:  g()/NAMED_VALUE I in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
                                     result = lcf::LET (v, translate_variable (w, debruijn_depth), fold_result_so_far);
if *debugging printf "\nCALLED  translate_variable:  g()/NAMED_VALUE I in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
                                     result;
                                else
if *debugging printf "\nCALLING translate_pattern_expression:  g()/NAMED_VALUE I in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;

                                     result = lcf::LET (v, translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_named_values/g/NAMED_VALUE" ! callstack), fold_result_so_far);

if *debugging printf   "CALLED  translate_pattern_expression:  g()/NAMED_VALUE I in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;

                                     result;
                                fi;

/*x*/                       g'  ( ds::NAMED_VALUE { pattern as ds::VARIABLE_IN_PATTERN (vac::ORDINARY_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, ... } ),
/*x*/                                           expression,
/*x*/                                           bound_typevar_refs,
/*x*/                                           ...
/*x*/                                         },
/*x*/                             fold_result_so_far
/*x*/                           )
/*x*/                           =>
/*x*/                           {
                                                               if *debugging    print_callstack "\n============= translate_named_values/g()/NAMED_VALUE II/TOP    ============= " callstack; fi;
                                                               if_debugging_unparse_expression ("\nexpression:", (expression,100));
                                                               if_debugging_unparse_pattern    ("\npattern:",    (pattern,   100));
                                                               if *debugging
                                                                   printf "\nbound_typevar_refs (%d entries):\n"  (length  bound_typevar_refs);
                                                                   apply unparse bound_typevar_refs
                                                                   where
                                                                       fun unparse  typevar_ref
                                                                           =
                                                                           if_debugging_unparse_typevar_ref  ("", typevar_ref);
                                                                   end;
                                                                   printf "\n";
                                                               fi;
                                                               if_debugging_prettyprint_expression ("\nexpression:", (expression,100));
                                                               if_debugging_prettyprint_pattern    ("\npattern:",    (pattern,   100));

                                                               if *debugging printf "\nCALLING translate_pattern_expression:  g()/NAMED_VALUE II in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;

/*x*/                               result = lcf::LET (v, translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_named_values.g/NAMED_VALUE II" ! callstack), fold_result_so_far);

                                                               if *debugging printf "CALLED  translate_pattern_expression:  g()/NAMED_VALUE II in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
                                                               if *debugging    print_callstack "\n============= translate_named_values/g()/NAMED_VALUE II/BOTTOM ============= " callstack; fi;

/*x*/                               result;
                                }; 

                            g'  ( ds::NAMED_VALUE { pattern => ds::TYPE_CONSTRAINT_PATTERN (ds::VARIABLE_IN_PATTERN (vac::ORDINARY_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, ... } ), _),
                                                expression,
                                                bound_typevar_refs,
                                                ...
                                              },
                                  fold_result_so_far
                                )
                                =>
                                {
if *debugging printf "\nCALLING translate_pattern_expression:  g()/NAMED_VALUE III (type-constrained variable) in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
                                    result = lcf::LET (v, translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_named_values.g/NAMED_VALUE III" ! callstack), fold_result_so_far);
if *debugging printf "CALLED  translate_pattern_expression:  g()/NAMED_VALUE III (type-constrained variable) in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
                                    result;
                                };

                            g'  ( ds::NAMED_VALUE { pattern, expression, bound_typevar_refs, ... },
                                  fold_result_so_far
                                )
                                =>
                                {
if *debugging printf "\nCALLING translate_pattern_expression:  g()/NAMED_VALUE IV (type-constrained variable) in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
                                    ee    = translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_pattern_expression.g/NAMED_VALUE IV" ! callstack);
if *debugging printf "CALLED  translate_pattern_expression:  g()/NAMED_VALUE IV (type-constrained variable) in  translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;

                                    rules = [ (fill_pattern (pattern, debruijn_depth), fold_result_so_far),
                                              (ds::WILDCARD_PATTERN, void_lexp)
                                            ];

                                    root_var = make_var();
                                    #
                                    fun finish x
                                        =
                                        lcf::LET (root_var, ee, x);

                                    mc::compile_naming_pattern (
                                        symbolmapstack,
                                        rules,
                                        finish,
                                        root_var,
                                        to_tc_lt  debruijn_depth,
                                        complain,
                                        make_integer_switch
                                    );
                                };
                        end;
                    end                         # where (fun translate_named_values) 

                also
                fun translate_named_recursive_values (rvbs, debruijn_depth, callstack)
                    =
                    {
if *debugging    print_callstack "\n============= translate_named_recursive_values/TOP    ============= " callstack; fi;
                        result =    fn (b: lcf::Lambdacode_Expression) =  lcf::MUTUALLY_RECURSIVE_FNS (vlist, tlist, elist, b);
if *debugging    print_callstack "\n============= translate_named_recursive_values/BOTTOM ============= " callstack; fi;
                        result;
                    }
                    where
                        my (vlist, tlist, elist)
                            =
                            fold_backward g ([], [], []) rvbs
                            where
                                fun g   ( ds::NAMED_RECURSIVE_VALUES
                                            { variable => vac::ORDINARY_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, var_type => REF type, ... },
                                              expression,
                                              bound_typevar_refs,
                                              ...
                                             },

                                          (vlist, tlist, elist)
                                        )
                                        => 
#                                       {   ee = translate_expression (expression, debruijn_depth); #  was translate_pattern_expression (expression, debruijn_depth, tvs) 
#                                                                                 #  we no longer track type namings at NAMED_RECURSIVE_VALUES anymore ! 
                                        {
if *debugging printf "\nCALLING translate_pattern_expression:  g() in translate_named_recursive_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
                                            ee = translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_named_recursive_values" ! callstack);         # Restored old code 2009-04-25 CrT
if *debugging printf "CALLED  translate_pattern_expression:  g() in translate_named_recursive_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
                                            vt = deepsyntax_type_to_uniqtype  debruijn_depth   type;

                                            ( v  ! vlist,
                                              vt ! tlist,
                                              ee ! elist
                                            );
                                        };

                                    g _ => bug "unexpected valrec namings in makeRecursiveValueNamings";
                                end;
                            end;
                    end

                also
                fun translate_exception_declarations (ebs, debruijn_depth, callstack)
                    = 
                    fold g ebs
                    where
                        fun g (   ds::NAMED_EXCEPTION {
                                      exception_constructor => ty::VALCON {
                                                                 form => vh::EXCEPTION (vh::HIGHCODE_VARIABLE v),
                                                                 type,
                                                                 ...
                                                             }, 
                                      name_string => ident,
                                      ...
                                  },
                                  b
                              )
                                =>
                                {   nt = to_dcon_lty  debruijn_depth  type;

                                    my (argt, _) = hcf::unpack_lambdacode_arrow_uniqtype  nt;

                                    lcf::LET ( v,
                                          lcf::EXCEPTION_TAG
                                            ( translate_deep_syntax_expression_to_lambdacode
                                                ( ident,
                                                  debruijn_depth,
                                                  "translate_exception_declarations" ! callstack
                                                ),
                                              argt
                                            ),
                                          b
                                        );
                                };

                            g (    ds::DUPLICATE_NAMED_EXCEPTION {
                                       exception_constructor => ty::VALCON {
                                                                  form => vh::EXCEPTION (vh::HIGHCODE_VARIABLE v),
                                                                  type,
                                                                  name,
                                                                  ...
                                                              },
                                       equal_to => ty::VALCON { form=>vh::EXCEPTION acc, ... }
                                   },
                                   b
                              )
                                =>
                                {   nt = to_dcon_lty  debruijn_depth  type;
                                    my (argt, _) = hcf::unpack_lambdacode_arrow_uniqtype nt;

                                    lcf::LET (v, translate_varhome_with_type (acc, hcf::make_exception_tag_uniqtype argt, THE name), b);
                                };

                            g _ => bug "unexpected exn namings in makeExceptionNamings";
                        end;
                    end


                ###########################################################################
                # 
                # Translating module exprs and decls into lambda expressions:
                # 
                #    translate_package_expression
                #        :
                #        (ds::Package_Expression, depth)
                #     -> lcf::Lambdacode_Expression
                # 
                #    translate_generic_expression
                #        : 
                #        (ds::Generic_Expression, depth)
                #     -> lcf::Lambdacode_Expression
                # 
                #    translate_package_declarations
                #        :
                #        (List( ds::Named_Package ), depth)
                #     -> lcf::Lambdacode_Expression
                #     -> lcf::Lambdacode_Expression
                # 
                #    translate_generic_namings
                #        :
                #        (List( ds::Named_Generic ), depth)
                #     -> lcf::Lambdacode_Expression
                #     -> lcf::Lambdacode_Expression
                # 
                ###########################################################################

/*x*/           also
/*x*/           fun translate_package_expression (package_expression, debruijn_depth, callstack)
                    = 
                    g package_expression
                    where
                        fun g (ds::PACKAGE_BY_NAME  a_package)
                                =>
                                translate_package (a_package, debruijn_depth);

                            g (ds::PACKAGE_DEFINITION bs)
                                =>
                                lcf::PACKAGE_RECORD
                                    (map  (translate_symbolmapstack_entry debruijn_depth)
                                          bs
                                    );

                            g (ds::COMPUTED_PACKAGE { a_generic=>op, generic_argument=>arg, parameter_types } )
                                => 
                                {   e1 = translate_generic (op, debruijn_depth);
                                    typs =  map  (deepsyntax_typpath_to_uniqtyp  debruijn_depth)  parameter_types;
                                    e2 = translate_package (arg, debruijn_depth);
                                    lcf::APPLY (lcf::APPLY_TYPEFUN (e1, typs), e2);
                                };

/*x*/                       g (ds::PACKAGE_LET { declaration, expression })
/*x*/                           =>
/*x*/                           translate_deep_syntax_to_lambdacode'
/*x*/                               (declaration, debruijn_depth, "translate_package_expression" ! callstack)
/*x*/                               (g expression);

                            g (ds::SOURCE_CODE_REGION_FOR_PACKAGE (b, reg))
                                =>
                                with_region reg g b;
                        end;
                    end

                also
                fun translate_generic_expression (fe, debruijn_depth, callstack)
                    = 
                    g fe
                    where
                        fun g (ds::GENERIC_BY_NAME f)
                                =>
                                translate_generic (f, debruijn_depth);

                            g (ds::GENERIC_DEFINITION { parameter as mld::A_PACKAGE { varhome, ... }, parameter_types, definition=>def } )
                                =>
                                case varhome
                                    #
                                    vh::HIGHCODE_VARIABLE v
                                        =>
                                        {   knds      =  map  deepsyntax_typpath_to_uniqkind  parameter_types;
                                            new_depth =  di::next debruijn_depth;
                                            body      =  translate_package_expression (def, new_depth, "translate_generic_expression" ! callstack);
                                            header    =  build_header v;

                                        #  Naming of all v's components 

                                            lcf::TYPEFUN (knds, lcf::FN (v, deepsyntax_package_to_uniqtype (parameter, new_depth, per_compile_info), header body));
                                        };

                                    _ => bug "translate_generic_expression: unexpected varhome";
                                esac;

                            g (ds::GENERIC_LET (declaration, b))
                                =>
                                translate_deep_syntax_to_lambdacode'
                                  ( declaration,
                                    debruijn_depth,
                                    "translate_generic_expression" ! callstack
                                  )
                                  (g b);

                            g (ds::SOURCE_CODE_REGION_FOR_GENERIC (b, reg))
                                =>
                                with_region reg g b;

                            g _ => bug "unexpected generic package expressions in translate_generic_expression";
                        end;
                    end

                also
/*x*/           fun translate_package_declarations (sbs, debruijn_depth, callstack)
                    =
/*x*/               fold g sbs
                    where
/*x*/                   fun g (ds::NAMED_PACKAGE { a_package=>mld::A_PACKAGE { varhome, ... }, definition, ... }, b)
                                =>
                                case varhome
                                    #                             
/*x*/                               vh::HIGHCODE_VARIABLE  v
/*x*/                                   =>
/*x*/                                   {   header = build_header v;     #  Naming of all v's components 
/*x*/                                       #
/*x*/                                       lcf::LET (v, translate_package_expression (definition, debruijn_depth, "translate_package_declarations" ! callstack), header b);
/*x*/                                   };

                                    _   =>
                                        bug "translate_package_declarations: unexpected varhome";
                                esac;

                            g _ => bug "unexpected package namings in translate_package_declarations";
                        end;
                    end

                also
                fun translate_generic_namings (fbs, debruijn_depth, callstack)
                    = 
                    fold g fbs
                    where
                        fun g (ds::NAMED_GENERIC { a_generic=>mld::GENERIC { varhome, ... }, definition=>def, ... }, b)
                                =>
                                case varhome
                                    #                             
                                    vh::HIGHCODE_VARIABLE v
                                        =>
                                        { header = build_header v;

                                            lcf::LET (v, translate_generic_expression (def, debruijn_depth, "translate_generic_namings" ! callstack), header b);
                                        };

                                    _   =>
                                        bug "translate_generic_namings: unexpected varhome";
                                esac;

                            g _ => bug "unexpected generic package namings in translate_package_declarations";
                        end;
                    end


                also
/*x*/           fun translate_deep_syntax_to_lambdacode'
/*x*/               ( declaration:      ds::Declaration,
/*x*/                 debruijn_depth:   di::Debruijn_Depth,
/*x*/                 callstack:        List( String )
/*x*/               )
/*x*/               : (lcf::Lambdacode_Expression -> lcf::Lambdacode_Expression)
/*x*/               = 
/*x*/               g declaration
                    where
                        fun g (ds::VALUE_DECLARATIONS vbs)                 => translate_named_values           ( vbs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);
                            g (ds::RECURSIVE_VALUE_DECLARATIONS rvbs)      => translate_named_recursive_values (rvbs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);
                            g (ds::ABSTRACT_TYPE_DECLARATION { body, ... } ) => g body;

                            g (ds::EXCEPTION_DECLARATIONS        ebs)      => translate_exception_declarations (ebs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);
/*x*/                       g (ds::PACKAGE_DECLARATIONS          sbs)      => translate_package_declarations   (sbs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);

                            g (ds::GENERIC_DECLARATIONS fbs)               => translate_generic_namings (fbs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);
                            g (ds::LOCAL_DECLARATIONS (ld, vd))            => (g ld) o (g vd);
                            g (ds::SEQUENTIAL_DECLARATIONS ds)             =>  fold_backward (o) identity_fn (map g ds);

                            g (ds::SOURCE_CODE_REGION_FOR_DECLARATION (x, reg))
                                => 
                                {   f = with_region reg g x;

                                    fn y =  with_region reg f y;
                                };

                            g (ds::INCLUDE_DECLARATIONS xs)
                                => 
                                {   # Special hack to make the include tree simpler:
                                    #
                                    apply mkos xs
                                    where
                                        fun mkos (_, s as mld::A_PACKAGE { varhome, ... } )
                                                =>
                                                if (varhome_is_external varhome)
                                                    #
                                                    translate_varhome_with_type (varhome, deepsyntax_package_to_uniqtype (s, debruijn_depth, per_compile_info), NULL);
                                                    ();
                                                fi;
                                            #
                                            mkos _ =>   ();
                                        end;
                                    end;        

                                    identity_fn;
                                };

                            g _ => identity_fn;
                        end;
                    end

                also
/*x*/           fun translate_deep_syntax_expression_to_lambdacode
/*x*/               ( expression:       ds::Deep_Expression,
/*x*/                 debruijn_depth:   di::Debruijn_Depth,
/*x*/                 callstack:        List( String )
/*x*/               )
/*x*/               : lcf::Lambdacode_Expression
/*x*/               = 
/*x*/               {
/*x*/                   result =   translate_deep_syntax_expression_to_lambdacode' expression;
 
                        if *debugging
                            print_callstack "\n============= translate_deep_syntax_expression_to_lambdacode/BOTTOM ============= " callstack;
                        fi;

                        result;
                    }
                    where
                        if *debugging
                            print_callstack "\n============= translate_deep_syntax_expression_to_lambdacode/TOP    ============= " callstack;
                            if_debugging_unparse_expression ("translate_deep_syntax_expression_to_lambdacode input expression argument:", (expression,100));
                        fi;

                        t_typ =  deepsyntax_type_to_uniqtyp       debruijn_depth;
                        t_lty =  deepsyntax_type_to_uniqtype  debruijn_depth;

                        #
                        fun make_rules xs
                            =
                            map (fn (ds::CASE_RULE (p, e)) =  (fill_pattern (p, debruijn_depth), translate_deep_syntax_expression_to_lambdacode' e))
                                xs

                        also
/*x*/                   fun translate_deep_syntax_expression_to_lambdacode'  expression
                            =
                            {
                                        if *debugging
                                            print_callstack "\n============= translate_deep_syntax_expression_to_lambdacode'/TOP    ============= " callstack;
                                            if_debugging_unparse_expression ("translate_deep_syntax_expression_to_lambdacode' input expression argument:", (expression,100));
                                        fi;

/*x*/                           result =  translate_deep_syntax_expression_to_lambdacode'' expression;

                                        if *debugging
                                            print_callstack "\n============= translate_deep_syntax_expression_to_lambdacode'/BOTTOM ============= " callstack;
                                        fi;

                                result;
                            }
                        where
                            fun translate_deep_syntax_expression_to_lambdacode'' (ds::VARIABLE_IN_EXPRESSION (REF v, ts))
                                    =>
                                    translate_variable_in_expression (v, ts, debruijn_depth);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::VALCON_IN_EXPRESSION (dc, ts))
                                    =>
                                    translate_constructor_expression (dc, ts, NULL, debruijn_depth);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::APPLY_EXPRESSION (ds::VALCON_IN_EXPRESSION (dc, ts), e2))
                                    =>
                                    translate_constructor_expression (dc, ts, THE (translate_deep_syntax_expression_to_lambdacode' e2), debruijn_depth);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::INT_CONSTANT_IN_EXPRESSION (s, t))
                                   =>
                                    if   (tyj::types_are_equal (t, bt::int_type    ))  lcf::INT   (ln::int   s);
                                    elif (tyj::types_are_equal (t, bt::int1_type  ))  lcf::INT1 (ln::one_word_int s);
                                    elif (tyj::types_are_equal (t, bt::multiword_int_type))  lcf::VAR (get_interface_info s);
                                    elif (tyj::types_are_equal (t, bt::int2_type  ))

                                        my (hi, lo) =   ln::two_word_int s;

                                        lcf::RECORD [lcf::UNT1 hi, lcf::UNT1 lo];

                                    else
                                        bug "translate INT_CONSTANT_IN_EXPRESSION";
                                    fi
                                    except
                                        OVERFLOW = { rep_err "int constant too large";
                                                     lcf::INT 0;
                                                   };

                                translate_deep_syntax_expression_to_lambdacode'' (ds::UNT_CONSTANT_IN_EXPRESSION (s, t))
                                    =>
                                    if   (tyj::types_are_equal (t, bt::unt_type  ))   lcf::UNT    (ln::unt   s);
                                    elif (tyj::types_are_equal (t, bt::unt8_type ))   lcf::UNT    (ln::one_byte_unt  s);
                                    elif (tyj::types_are_equal (t, bt::unt1_type))   lcf::UNT1  (ln::one_word_unt s);
                                    elif (tyj::types_are_equal (t, bt::unt2_type)) 

                                        (ln::two_word_unt s) ->   (hi, lo);

                                        lcf::RECORD [lcf::UNT1 hi, lcf::UNT1 lo];

                                    else
                                        prettyprint_type t;
                                        bug "translate UNT_CONSTANT_IN_EXPRESSION";
                                    fi
                                    except
                                        OVERFLOW = { rep_err "word constant too large";   lcf::INT 0;};

                                translate_deep_syntax_expression_to_lambdacode'' (ds::FLOAT_CONSTANT_IN_EXPRESSION s)
                                    =>
                                    lcf::FLOAT64  s;

                                translate_deep_syntax_expression_to_lambdacode'' (ds::STRING_CONSTANT_IN_EXPRESSION s)
                                    =>
                                    lcf::STRING s;

                                translate_deep_syntax_expression_to_lambdacode'' (ds::CHAR_CONSTANT_IN_EXPRESSION s)
                                    =>
                                    lcf::INT (char::to_int (string::get (s, 0)));

                                     # NOTE: the above won't work for cross compiling to 
                                     #  multi-byte characters        XXX BUGGO FIXME

                                translate_deep_syntax_expression_to_lambdacode'' (ds::RECORD_IN_EXPRESSION [])
                                    =>
                                    void_lexp;

                                translate_deep_syntax_expression_to_lambdacode'' (ds::RECORD_IN_EXPRESSION xs)
                                     =>
                                     if (sorted xs)
                                         #
                                         lcf::RECORD  (map  (fn (_, e) = translate_deep_syntax_expression_to_lambdacode' e)  xs);
                                     else
                                         vars =   map  (fn (l, e) =  (l, (translate_deep_syntax_expression_to_lambdacode' e, make_var())))
                                                       xs;
                                         #
                                         fun bind ((_, (e, v)), x)
                                             =
                                             lcf::LET (v, e, x);

                                         bexp =   map  (fn (_, (_, v)) =  lcf::VAR v)
                                                       (sortrec vars);

                                         fold_backward
                                             bind
                                             (lcf::RECORD bexp)
                                             vars;
                                     fi;

                                translate_deep_syntax_expression_to_lambdacode'' (ds::RECORD_SELECTOR_EXPRESSION (ds::NUMBERED_LABEL { number=>i, ... }, e))
                                     =>
                                     lcf::GET_FIELD (i, translate_deep_syntax_expression_to_lambdacode' e);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::VECTOR_IN_EXPRESSION ([], type))
                                     => 
                                     lcf::APPLY_TYPEFUN (core_get "zero_length_vector__global", [t_typ type]);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::VECTOR_IN_EXPRESSION (xs, type))
                                     => 
                                     {   tc   =   t_typ type;

                                         vars =   map (fn e =  (translate_deep_syntax_expression_to_lambdacode' e, make_var()))
                                                      xs;
                                         #
                                         fun bind ((e, v), x)
                                             =
                                             lcf::LET (v, e, x);

                                         bexp =   map (fn (_, v) = lcf::VAR v)
                                                      vars;

                                         fold_backward  bind  (lcf::VECTOR (bexp, tc))  vars;
                                     };

                                translate_deep_syntax_expression_to_lambdacode'' (ds::ABSTRACTION_PACKING_EXPRESSION (e, type, typs))
                                     =>
                                     translate_deep_syntax_expression_to_lambdacode' e;

    #                           {   my  (nty, ks, tps)
    #                                   =
    #                                   tyj::reformatTypeAbstraction (type, typs, debruijn_depth);
    #
    #                               ts = map (tpsTypeConstructor debruijn_depth) tps;
    #                               # * use of LtyDict::tcAbs is a temporary hack (ZHONG) *
    #
    #                               nts =   paired_listyj::map LtyDict::tcAbs (ts, ks);
    #
    #                               nd =   di::next debruijn_depth;
    #
    #                              case (ks, tps)
    #                                of ([], []) => translate_deep_syntax_expression_to_lambdacode' e
    #                                 | _ => PACK (hcf::make_polymorphic_uniqtype (ks, [deepsyntax_type_to_uniqtype nd nty]), 
    #                                             ts, nts, translate_deep_syntax_expression_to_lambdacode' e);
    #                           }

                                translate_deep_syntax_expression_to_lambdacode'' (ds::SEQUENTIAL_EXPRESSIONS [e])
                                    =>
                                    translate_deep_syntax_expression_to_lambdacode' e;

                                translate_deep_syntax_expression_to_lambdacode'' (ds::SEQUENTIAL_EXPRESSIONS (e ! r))
                                    =>
                                    lcf::LET (make_var(), translate_deep_syntax_expression_to_lambdacode' e, translate_deep_syntax_expression_to_lambdacode' (ds::SEQUENTIAL_EXPRESSIONS r)); 

                                translate_deep_syntax_expression_to_lambdacode'' (ds::APPLY_EXPRESSION (e1, e2))
                                    =>
                                    lcf::APPLY (translate_deep_syntax_expression_to_lambdacode' e1, translate_deep_syntax_expression_to_lambdacode' e2);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::SOURCE_CODE_REGION_FOR_EXPRESSION (expression, region))
                                    =>
                                    with_region  region  translate_deep_syntax_expression_to_lambdacode''  expression;

                                translate_deep_syntax_expression_to_lambdacode'' (ds::TYPE_CONSTRAINT_EXPRESSION (e, _))
                                    =>
                                    translate_deep_syntax_expression_to_lambdacode' e;

                                translate_deep_syntax_expression_to_lambdacode'' (ds::RAISE_EXPRESSION (e, type))
                                     =>
                                     make_raise (translate_deep_syntax_expression_to_lambdacode' e, t_lty type);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::EXCEPT_EXPRESSION (e, (l, type)))
                                     =>
                                     {   root_var =   make_var();
                                         #
                                         fun f x
                                             =
                                             lcf::FN (root_var, t_lty type, x);

                                         l' =   make_rules l;

                                         lcf::EXCEPT
                                           ( translate_deep_syntax_expression_to_lambdacode' e,
                                             mc::compile_exception_pattern
                                               ( symbolmapstack,
                                                 l',
                                                 f, 
                                                 root_var,
                                                 to_tc_lt  debruijn_depth,
                                                 complain,
                                                 make_integer_switch
                                           )   );
                                     };

                                translate_deep_syntax_expression_to_lambdacode'' (ds::FN_EXPRESSION (l, type))
                                     => 
                                     {   root_var =   make_var();
                                         #      
                                         fun f x
                                             =
                                             lcf::FN (root_var, t_lty type, x);

                                         mc::compile_case_pattern
                                           (
                                             symbolmapstack,
                                             make_rules l,
                                             f,
                                             root_var,
                                             to_tc_lt  debruijn_depth,
                                             complain,
                                             make_integer_switch
                                           );
                                     };

                                translate_deep_syntax_expression_to_lambdacode'' (ds::CASE_EXPRESSION (ee, l, is_match))
                                     => 
                                     {   root_var = make_var();

                                         ee' = translate_deep_syntax_expression_to_lambdacode' ee;
                                         #
                                         fun f x
                                             =
                                             lcf::LET (root_var, ee', x);

                                         l' =   make_rules l;

                                         (is_match ?? mc::compile_case_pattern
                                                   :: mc::compile_naming_pattern
                                         ) (
                                             symbolmapstack,
                                             l',
                                             f,
                                             root_var,
                                             to_tc_lt  debruijn_depth,
                                             complain,
                                             make_integer_switch
                                           );
                                     };

                                translate_deep_syntax_expression_to_lambdacode'' (ds::IF_EXPRESSION { test_case, then_case, else_case } )
                                     =>
                                     cond (translate_deep_syntax_expression_to_lambdacode' test_case, translate_deep_syntax_expression_to_lambdacode' then_case, translate_deep_syntax_expression_to_lambdacode' else_case);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::AND_EXPRESSION (e1, e2))
                                     =>
                                     cond (translate_deep_syntax_expression_to_lambdacode' e1, translate_deep_syntax_expression_to_lambdacode' e2, false_lexp);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::OR_EXPRESSION (e1, e2))
                                     =>
                                     cond (translate_deep_syntax_expression_to_lambdacode' e1, true_lexp, translate_deep_syntax_expression_to_lambdacode' e2);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::WHILE_EXPRESSION { test, expression } )
                                     =>
                                     {   fv = make_var ();

                                         body = lcf::FN (make_var (), lt_void,
                                                 cond (translate_deep_syntax_expression_to_lambdacode' test,
                                                       lcf::LET (make_var (), translate_deep_syntax_expression_to_lambdacode' expression, lcf::APPLY (lcf::VAR fv, void_lexp)),
                                                       void_lexp));

                                         lcf::MUTUALLY_RECURSIVE_FNS ([fv], [lt_voidvoid], [body], lcf::APPLY (lcf::VAR fv, void_lexp));
                                     };

/*x*/                           translate_deep_syntax_expression_to_lambdacode'' (ds::LET_EXPRESSION (dc, e))
/*x*/                                =>
/*x*/                                translate_deep_syntax_to_lambdacode' (dc, debruijn_depth, "translate_deep_syntax_expression_to_lambdacode''" ! callstack) (translate_deep_syntax_expression_to_lambdacode' e);

                                translate_deep_syntax_expression_to_lambdacode'' e
                                     => 
                                     err::impossible_with_body "untranslateable expression"
                                         (fn stream
                                             =
                                             {   pp::string stream " expression: ";
                                                 uds::unparse_expression
                                                     (symbolmapstack, NULL)
                                                     stream
                                                     (e, *prettyprint_depth);
                                             }
                                         );
                            end;                        # fun translate_deep_syntax_expression_to_lambdacode''
                        end;                            # where
                    end                                 # fun translate_deep_syntax_expression_to_lambdacode

                also
                fun translate_integer (debruijn_depth, callstack) s
                    =
                    # This is a temporary solution.  Since integer literals
                    # are created using a core function call, there is
                    # no indication within the program that we are really
                    # dealing with a constant value that -- in principle --
                    # could be subject to such things as constant folding. XXX BUGGO FIXME

                    {   valcon_expression =   ds::VALCON_IN_EXPRESSION (bt::cons_dcon, [bt::unt_type]);
                        #
                        fun build []
                                =>
                                ds::VALCON_IN_EXPRESSION (bt::nil_dcon, [bt::unt_type]);

                            build (d ! ds)
                                =>
                                {   i = unt::to_int_x d;

                                    ds::APPLY_EXPRESSION (valcon_expression,
                                            trj::tupleexp [ds::UNT_CONSTANT_IN_EXPRESSION (multiword_int::from_int i, bt::unt_type),
                                                         build ds]);
                                };
                        end;
                        #
                        fun small w
                            =
                            lcf::APPLY ( core_get (ln::is_negative s   ??   "make_small_neg_inf"
                                                                  ::   "make_small_pos_inf"
                                  ),

                                  translate_deep_syntax_expression_to_lambdacode
                                    (
                                      ds::UNT_CONSTANT_IN_EXPRESSION (multiword_int::from_int (unt::to_int_x w), bt::unt_type),
                                      debruijn_depth,
                                      "translate_integer" ! callstack
                                )   );

                        case (ln::rep_digits  s)
                            #                     
                            []  =>  small 0u0;
                            [w] =>  small w;
                            ws  =>  lcf::APPLY (
                                        core_get (ln::is_negative s   ??   "make_neg_inf"
                                                                      ::   "make_pos_inf"
                                                 ),
                                        translate_deep_syntax_expression_to_lambdacode (build ws,  debruijn_depth, "translate_integer" ! callstack)
                                    );
                        esac;
                    };

                #  Wrap namings for multiword_int::Int literals around body. 
                #
                fun wrap_integer (body, callstack)
                    =
                    im::keyed_fold_forward
                        do_one
                        body
                       *integer_map
                    where 
                        fun do_one (n, v, b)
                            =
                            lcf::LET (v, translate_integer (di::top, "wrap_integer" ! callstack) n, b);

                    end;


                #
                fun wrap_picklehash_info
                    ( body:              lcf::Lambdacode_Expression,
                      picklehash_infos:  List( (ph::Picklehash, Picklehash_Info) )
                    )
                    : ( lcf::Lambdacode_Expression,
                        List(   (ph::Picklehash, it::Import_Tree_Node)   )
                      )
                    = 
                    {   imports
                            = 
                            map
                                (fn (p, pi) =  (p, p2itree pi))
                                picklehash_infos
                            where
                                fun p2itree (ANON xl)
                                        => 
                                        it::IMPORT_TREE_NODE
                                            (map (fn (i, z) = (i, p2itree z))
                                                 xl
                                            );

                                    p2itree (NAMED _)
                                        =>
                                        it::IMPORT_TREE_NODE [];
                                end;
                            end;

                  /*
                        {   say "\n ****************** \n";
                            say "\n the current include tree is :\n";
                            #
                            fun tree (it::IMPORT_TREE_NODE [])
                                    =
                                    [ "\n" ];

                              | tree (it::IMPORT_TREE_NODE xl)
                                    = 
                                    fold_backward (fn ((i, x), z)
                                                   =
                                                   {   ts = tree x;
                                                       u = (int::to_string i)  + "   ";
                                                       (map (fn y = (u + y)) ts) @ z;
                                                   }
                                               )
                                               []
                                               xl;
                            #
                            fun prettyprint (p, n)
                                = 
                                {   say ("Picklehash " + (ph::to_hex p) + "\n"); 
                                    apply say (tree n));
                                    apply prettyprint imports; say "\n ****************** \n";
                                }
                  */
                        lambdacode_expression
                            = 
                            {   fun get ((_, ANON xl), z)
                                        =>
                                        fold_forward get z xl;

                                    get ((_, u as NAMED (_, t, _)), (n, cs, ts))
                                        => 
                                        (n+1, (n, u) ! cs, t ! ts);
                                end;

                                #  Get the fringe information 

                                getp =   fn ((_, pi), z) =  get((0, pi), z);

                                my  (finfos, lts)
                                    = 
                                    {   my  (_, fx, lx)
                                            =
                                            fold_forward  getp  (0,[],[])  picklehash_infos;

                                        (reverse fx, reverse lx);
                                    };

                                # Do the selection of all import variables:
                                #
                                fun make_selection (u, xl, be)
                                    = 
                                    fold_backward g be xl
                                    where
                                        fun g ((i, pi), be)
                                            = 
                                            {   my  (v, xs)
                                                    =
                                                    case pi
                                                        #                                                      
                                                        ANON z => (make_var(), z);
                                                        NAMED (v, _, z) => (v, z);
                                                    esac;

                                                lcf::LET (v, lcf::GET_FIELD (i, u), make_selection (lcf::VAR v, xs, be));
                                            };
                                    end;

                                impvar =  make_var();
                                implty =  hcf::make_package_uniqtype lts;
                                nbody  =  make_selection (lcf::VAR impvar, finfos, body) ;

                                lcf::FN (impvar, implty, nbody);
                            };

                        (lambdacode_expression, imports);
                    };                                              # fun wrap_picklehash_info 

                # The list of things being exported
                # from the current compilation unit:
                #
                export_lexp =   lcf::PACKAGE_RECORD  (map  lcf::VAR  exported_highcode_variables);

                # Translate the deep_syntax_declaration
                # into a lambdacode expression:
                # 
                body =   translate_deep_syntax_to_lambdacode' (given_declaration, di::top, []) export_lexp;


                # Add namings for integer constants:
                #
                body =   wrap_integer (body, []);


                #  Wrap up the body with the imported variables:
                #
                my (lambdacode_expression, imports)
                    =
                    wrap_picklehash_info (body, phm::keyvals_list  *picklehash_map);

                                                                                                  
                print_lambdacode_expression
                    (global_controls::highcode::print, prettyprint_lambdacode_expression::print_lexp)
                    "translate_deep_syntax_to_lambdacode"
                    lambdacode_expression
                where
                    fun print_lambdacode_expression (flag, print_e) s e
                        =
                        if *flag
                             say ("\n\n[After " + s + " ...]\n\n");
                             print_e  e;
                        fi;
                end;


#               # Normalize the lambdacode expression
#                # into A-Normal form:
#               #
#               anormcode
#                    =
#                    translate_lambdacode_to_anormcode::translate
#                        lambdacode_expression;
#
#           
                if *debugging
                    printf "\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
                    printf   "============= translate_deep_syntax_to_lambdacode/BOTTOM ========== in translate-deep-syntax-to-lambdacode.pkg\n";
                fi;

                { lambdacode_expression, imports };
#               { anormcode, imports };

            };                                                                  #  fun translate_deep_syntax_to_lambdacode 
    };                                                                          #  package translate_deep_syntax_to_lambdacode 
end;                                                                            #  top-level with






Comments and suggestions to: bugs@mythryl.org

PreviousUpNext