PreviousUpNext

15.4.519  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, which preserves expression tree structure) is the second backend code representation, and the first used for optimization.
#     5)  Nextcode ("continuation-passing style", a single-assignment basic-block-graph form where call and return are essentially the same) 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-PASSES.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 type system without typevariables.
#
#  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.
#
#  Tis phase also inserts the proper implementation of each equality test
#  and assignment operator and does pattern-match compilation"
#
#      -- Paraphrased from:
#         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 pcs =  per_compile_stuff;           # per_compile_stuff     is from   src/lib/compiler/front/typer-stuff/main/per-compile-stuff.pkg
    package ph  =  picklehash;                  # picklehash            is from   src/lib/compiler/front/basics/map/picklehash.pkg
    package 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_stuff:                    pcs::Per_Compile_Stuff( 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 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 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 di  =  debruijn_index;                              # debruijn_index                                is from   src/lib/compiler/front/typer/basics/debruijn-index.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 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 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 mld =  module_level_declarations;                   # module_level_declarations                     is from   src/lib/compiler/front/typer-stuff/modules/module-level-declarations.pkg
    package mtt =  more_type_types;                             # more_type_types                               is from   src/lib/compiler/front/typer/types/more-type-types.pkg
    package pcs =  per_compile_stuff;                           # per_compile_stuff                             is from   src/lib/compiler/front/typer-stuff/main/per-compile-stuff.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 pht =  prettyprint_highcode_types;                  # prettyprint_highcode_types                    is from   src/lib/compiler/back/top/highcode/prettyprint-highcode-types.pkg
    package plx =  prettyprint_lambdacode_expression;           # prettyprint_lambdacode_expression             is from   src/lib/compiler/back/top/lambdacode/prettyprint-lambdacode-expression.pkg
    package pp  =  standard_prettyprinter;                      # standard_prettyprinter                        is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg
    package ppt =  prettyprint_type;                            # prettyprint_type                              is from   src/lib/compiler/front/typer/print/prettyprint-type.pkg
    package sxe =  symbolmapstack_entry;                        # symbolmapstack_entry                          is from   src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack-entry.pkg
    package sy  =  symbol;                                      # symbol                                        is from   src/lib/compiler/front/basics/map/symbol.pkg
    package syp =  symbol_path;                                 # symbol_path                                   is from   src/lib/compiler/front/typer-stuff/basics/symbol-path.pkg
    package td  =  typer_debugging;                             # typer_debugging                               is from   src/lib/compiler/front/typer/main/typer-debugging.pkg
    package tdt =  type_declaration_types;                      # type_declaration_types                        is from   src/lib/compiler/front/typer-stuff/types/type-declaration-types.pkg
    package tmp =  highcode_codetemp;                           # highcode_codetemp                             is from   src/lib/compiler/back/top/highcode/highcode-codetemp.pkg
    package trj =  typer_junk;                                  # typer_junk                                    is from   src/lib/compiler/front/typer/main/typer-junk.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 
        internals = REF FALSE;                                                          # For what I'm doing at the moment I find the 'internals' output to be clutter. -- CrT 2013-09-15
        #
        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
            =
            if *internals
                td::with_internals
                  (\\ ()
                      =
                      td::debug_print
                          debugging
                          ( "type: ",
                            ut::unparse_typoid  symbolmapstack::empty,
                            type
                          )
                  );
            else
              td::debug_print
                  debugging
                  ( "type: ",
                    ut::unparse_typoid  symbolmapstack::empty,
                    type
                  );
            fi;


        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       
                if *internals
                    td::with_internals
                        (\\ () =  td::debug_print debugging (msg, unparse_expression, expression));
                else
                    td::debug_print debugging (msg, unparse_expression, expression);
                fi;
            fi;
        #
        fun if_debugging_unparse_pattern (msg, pattern)
            =
            if *debugging       
                if *internals
                    td::with_internals
                        (\\ () =  td::debug_print debugging (msg, unparse_pattern, pattern));
                else
                    td::debug_print debugging (msg, unparse_pattern, pattern);
                fi;
            fi;
        #
        fun if_debugging_unparse_declaration (msg, declaration)
            =
            if *debugging       
                if *internals
                    td::with_internals
                        (\\ () =  td::debug_print debugging (msg, unparse_declaration, declaration));
                else
                    td::debug_print debugging (msg, unparse_declaration, declaration);
                fi;
            fi;
        #
        fun if_debugging_unparse_typevar_ref  (msg, typevar_ref)
            = 
            if *debugging               # Without this 'if' (and the matching one in unify_typoids), compiling the compiler takes 5X as long! :-)
                if *internals
                    td::with_internals
                        (\\ () =  td::debug_print debugging (msg, unparse_typevar_ref, typevar_ref));
                else
                    td::debug_print debugging (msg, unparse_typevar_ref, typevar_ref);
                fi;
            fi;


        #
        fun if_debugging_prettyprint_expression (msg, expression)
            =
            if *debugging       
                if *internals
                    td::with_internals
                        (\\ () =  td::debug_print debugging (msg, prettyprint_expression, expression));
                else
                    td::debug_print debugging (msg, prettyprint_expression, expression);
                fi;
            fi;
        #
        fun if_debugging_prettyprint_pattern (msg, pattern)
            =
            if *debugging       
                if *internals
                    td::with_internals
                        (\\ () =  td::debug_print debugging (msg, prettyprint_pattern, pattern));
                else
                    td::debug_print debugging (msg, prettyprint_pattern, pattern);
                fi;
            fi;
        #
        fun if_debugging_prettyprint_declaration (msg, declaration)
            =
            if *debugging       
                if *internals
                    td::with_internals
                        (\\ () =  td::debug_print debugging (msg, prettyprint_declaration, declaration));
                else
                    td::debug_print debugging (msg, prettyprint_declaration, declaration);
                fi;
            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 sumtype.
              # 
              per_compile_stuff
                  as
                    { error_match,
                      error_fn,
                      prettyprinter_or_null,
                      ...
                    }:                           per_compile_stuff::Per_Compile_Stuff( 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_stuff.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_typepath_to_uniqkind,
                      deepsyntax_typepath_to_uniqtype,
                      deepsyntax_type_to_uniqtype,
                      deepsyntax_typoid_to_uniqtypoid,
                      deepsyntax_package_to_uniqtypoid,
                      deepsyntax_generic_package_to_uniqtypoid,
                      mark_letbound_typevar
                    };
                #
                fun to_tc_lt  debruijn_depth
                    =
                    ( deepsyntax_type_to_uniqtype   debruijn_depth,
                      deepsyntax_typoid_to_uniqtypoid  debruijn_depth
                    );



                # Translate the type field in
                # VALCON into Uniqtypoid.
                #
                # Constant valcons will take
                # void_uniqtypoid as the argument.
                #
                fun to_valcon_lty  debruijn_depth  type                         # "valcon" == "sumtype constructor";  "lty" == "lambda type".
                    =
                    case type 
                        #                     
                        tdt::TYPESCHEME_TYPOID
                            {
                              typescheme_eqflags => an_api,
                              typescheme => tdt::TYPESCHEME { arity, body }
                            }
                                =>
                                if (mtt::is_arrow_type body)
                                    #
                                    deepsyntax_typoid_to_uniqtypoid  debruijn_depth  type;
                                else
                                    deepsyntax_typoid_to_uniqtypoid  debruijn_depth
                                      (
                                        tdt::TYPESCHEME_TYPOID
                                          {
                                            typescheme_eqflags =>    an_api,
                                            typescheme                   =>    tdt::TYPESCHEME
                                                                                  { arity,
                                                                                    body  =>   mtt::(-->) (mtt::void_typoid, body)
                                                                                  }
                                          }
                                      );
                                fi;

                        _ =>    if (mtt::is_arrow_type type)    deepsyntax_typoid_to_uniqtypoid  debruijn_depth  type;
                                else                            deepsyntax_typoid_to_uniqtypoid  debruijn_depth  (mtt::(-->) (mtt::void_typoid, 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 =   \\ _ =  \\ _ =  \\ _ =  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_uniqtypoid [], 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_uniqtypoid                                                       # Result type
                                      ( hcf::make_tuple_uniqtypoid [ hcf::exception_uniqtypoid, hcf::string_uniqtypoid ],
                                        hcf::exception_uniqtypoid
                                      ),
                                    []                                                                                          # Arg types.
                                  );
                herein 
                    #
                    fun with_region loc f x
                        =
                        {   r =   *source_code_region;
                            #
                            {   source_code_region := loc;
                                #
                                f x
                                then
                                    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;                                                                                                            #  stipulate



                ############################################################################
                #          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
                        (\\ (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  (\\ (k, e) =  lcf::GET_FIELD (k, e))
                                                        (lcf::VAR v)
                                                        l;

                                    \\ 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::Uniqtypoid,  List( (Int, Picklehash_Info) ))
                  ;

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

                        ( h l,
                          v
                        );
                    };
                #
                fun merge_picklehash_info (pi, uniqtypoid, 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, uniqtypoid, xl),
                                      v
                                    );
                                };

                            h (z, a ! r)
                                => 
                                {   my (xl, make_node)
                                        = 
                                        case z
                                            #
                                            ANON c =>   (c, ANON);
                                            #
                                            NAMED (v, uniqtypoid', c)
                                                =>
                                                ( c,
                                                  \\ x = NAMED (v, uniqtypoid', 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 (uniqtypoid, 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 (uniqtypoid, 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
                            =>
                            {   (merge_picklehash_info (picklehash_info, t, l, name_or_null))
                                    ->
                                    (new_picklehash_info, var);
                                    
                                #
                                fun drop (key, map)
                                    = 
                                    phm::drop (map, key); 

                                picklehash_map
                                    :=
                                    phm::set
                                      ( drop (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'  (\\ () =  raise exception NO_CORE)  (symbolmapstack, id))
                        #                     
                        tdt::VALCON { name, form as vh::EXCEPTION _, typoid, ... }
                            =>
                            {   type =  to_valcon_lty  di::top  typoid;
                                #
                                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'  (\\ () =  raise exception NO_CORE)  (symbolmapstack, id))
                        #                     
                        vac::PLAIN_VARIABLE { varhome, vartypoid_ref, path, ... }
                            =>
                            translate_varhome_with_type (   varhome,
                                       deepsyntax_typoid_to_uniqtypoid di::top  *vartypoid_ref,
                                       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_uniqtypoid lt;
                                    #   
                                    vh::EXCEPTION ( vh::HIGHCODE_VARIABLE ( g (x,   [],   hcf::make_exception_tag_uniqtypoid 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   (\\ (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   (\\ (l, p) =  (l, fill p))   fields;
                                    #
                                    fun find (t as tdt::TYPCON_TYPOID (tdt::RECORD_TYPE labels, _))
                                            => 
                                            {   type_ref := t;
                                                labels;
                                            };

                                        find _ => {   complain err::ERROR "unresolved flexible record"
                                                          (\\ pp
                                                                =
                                                                {   pp.newline();
                                                                    pp.lit "pattern: ";
                                                                    uds::unparse_pattern  symbolmapstack  pp  (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_typoid  *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 (tdt::VALCON { name, is_constant, typoid, is_lazy, signature, form }, ts))
                                => 
                                ds::CONSTRUCTOR_PATTERN (
                                    #
                                    tdt::VALCON {
                                        #
                                        name,
                                        is_constant,
                                        typoid,
                                        is_lazy,
                                        signature,

                                        form
                                            =>
                                            make_representation
                                              (
                                                form,
                                                to_valcon_lty  d  typoid,
                                                name
                                              )
                                    },
                                    ts
                                );

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

                                        form => make_representation 
                                                  (
                                                    form,
                                                    to_valcon_lty  d  typoid,
                                                    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_uniqtype di::top mtt::multiword_int_typoid]);
                                            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_type_uniqtypoid;
                lt_arrow = hcf::make_lambdacode_arrow_uniqtypoid;
                lt_tuple = hcf::make_tuple_uniqtypoid;
                lt_int   = hcf::int_uniqtypoid;
                lt_int1 = hcf::int1_uniqtypoid;
                lt_bool  = hcf::bool_uniqtypoid;
                lt_void  = hcf::void_uniqtypoid;

                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_valcon', false_valcon')
                    = 
                    ( h mtt::true_valcon,
                      h mtt::false_valcon
                    )
                    where
                        lt = hcf::make_lambdacode_arrow_uniqtypoid (hcf::void_uniqtypoid, hcf::bool_uniqtypoid);        # highcode "Void -> Bool"
                        #
                        fun h (tdt::VALCON { name, form, ... } )                        # Take name and form from basetype, plug in our Void->Bool type.
                            =
                            (name, form, lt);
                    end;

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

                        mtt::bool_signature,

                        [ (lcf::VAL_CASETAG (true_valcon',  [], make_var()), b),
                          (lcf::VAL_CASETAG (false_valcon', [], 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::COMPARE { op=>hbo::LTU, kind_and_size=>hbo::UNT 31 };

                lt_len = hcf::make_typeagnostic_uniqtypoid([hcf::plaintype_uniqkind], [lt_arrow (hcf::make_typevar_i_uniqtypoid 0, lt_int)]);

                lt_upd
                    = 
                    {   x = hcf::make_ref_uniqtypoid (hcf::make_typevar_i_uniqtypoid 0);
                        hcf::make_typeagnostic_uniqtypoid([hcf::plaintype_uniqkind], 
                                  [lt_arrow (lt_tuple [x, lt_int, hcf::make_typevar_i_uniqtypoid 0], hcf::void_uniqtypoid)]);
                    };
                #
                fun len_op (tc) =   lcf::BASEOP (hbo::VECTOR_LENGTH_IN_SLOTS, lt_len, [tc]);
                #
                fun rshift_op  k =  hbo::ARITH { op=>hbo::RSHIFT, overflow=>FALSE,  kind_and_size=>k };
                fun rshiftl_op k =  hbo::ARITH { op=>hbo::RSHIFTL, overflow=>FALSE, kind_and_size=>k };
                fun lshift_op  k =  hbo::ARITH { op=>hbo::LSHIFT,  overflow=>FALSE, kind_and_size=>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, kind_and_size, 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 kind_and_size,  lt_int ];

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

                        lcf::FN                                                                 # \\ (w, count) = if (shift_limit(kind_and_size) <= 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 kind_and_size, vcnt]),
                                        clear vw, 
                                        lcf::APPLY
                                          ( lcf::BASEOP (shift_op kind_and_size, shift_type kind_and_size, []),
                                            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_uniqtypoid,      lcf::INT        0,  TRUE );
                                hbo::UNT   31 => (hcf::int_uniqtypoid,      lcf::UNT      0u0,  FALSE);
                                hbo::INT   32 => (hcf::int1_uniqtypoid,    lcf::INT1      0,  TRUE );
                                hbo::UNT   32 => (hcf::int1_uniqtypoid,    lcf::UNT1    0u0,  FALSE);
                                hbo::FLOAT 64 => (hcf::float64_uniqtypoid,  lcf::FLOAT64 "0.0", FALSE);
                                #
                                _ => bug "inline_ops: bad number_kind_and_sizeize";
                            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::COMPARE  { op => hbo::LT,     kind_and_size => nk           }, compare_lambda_types, []);
                        greater =   lcf::BASEOP (hbo::COMPARE  { op => hbo::GT,     kind_and_size => nk           }, compare_lambda_types, []);
                        negate  =   lcf::BASEOP (hbo::ARITH     { op => hbo::NEGATE, kind_and_size => nk, overflow }, lt_neg,               []);

                        { lt_arg, lt_argpair, compare_lambda_types, less, greater, zero, negate };
                    };
                #
                fun inline_min_or_max (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::COMPARE { op => hbo::EQL, kind_and_size => 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 inline_absolute 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_uniqtypoid lt)
                                #                              
                                (_, [a], [r]) =>  (a, r);
                                _             =>  bug ("unexpected type of " + what);
                            esac;

                        extra_arg_lt
                            =
                            hcf::make_lambdacode_arrow_uniqtypoid
                                #
                                if is_from_inf  (orig_arg_lt,  hcf::int1_uniqtypoid);
                                else            (hcf::int1_uniqtypoid,  orig_arg_lt);
                                fi;

                        new_arg_lt =  hcf::make_tuple_uniqtypoid [ orig_arg_lt, extra_arg_lt ];

                        new_lt     =  hcf::make_lambdacode_arrow_uniqtypoid (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,   uniqtypes: List(hut::Uniqtype))         # This fn is called in one place:  below in  translate_variable_in_expression/PLAIN_VARIABLE/do_inline_baseop
                    = 
                    translate_baseop' baseop
                    where
                        fun translate_baseop' (hbo::LSHIFT_MACRO  k) =>  inline_shift (lshift_op,  k, \\ _ =  lword0 k);
                            translate_baseop' (hbo::RSHIFTL_MACRO k) =>  inline_shift (rshiftl_op, k, \\ _ =  lword0 k);

                            translate_baseop' (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;

                            translate_baseop' (hbo::MIN_MACRO nk) =>   inline_min_or_max (nk, FALSE);
                            translate_baseop' (hbo::MAX_MACRO nk) =>   inline_min_or_max (nk, TRUE);
                            translate_baseop' (hbo::ABS_MACRO nk) =>   inline_absolute nk;

                            translate_baseop' hbo::NOT_MACRO
                                =>
                                {   x = make_var();

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

                            translate_baseop' hbo::COMPOSE_MACRO
                                =>
                                {   my (t1, t2, t3)
                                        = 
                                        case uniqtypes
                                            #                                     
                                            [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))))));
                                };                  

                            translate_baseop' hbo::THEN_MACRO
                                =>
                                {   my (t1, t2)
                                        = 
                                        case uniqtypes
                                            #                                     
                                            [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));
                                };

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

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

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

                                    v = make_var ();

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

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

# Soon:
                            translate_baseop' hbo::RO_MATRIX_GET_WITH_BOUNDSCHECK_MACRO =>  bug "hbo::RO_MATRIX_GET_WITH_BOUNDSCHECK_MACRO unimplemented -- translate-deep-syntax-to-lambdacode.pkg";
                            translate_baseop' hbo::RW_MATRIX_GET_WITH_BOUNDSCHECK_MACRO =>  bug "hbo::RW_MATRIX_GET_WITH_BOUNDSCHECK_MACRO unimplemented -- translate-deep-syntax-to-lambdacode.pkg";
                            translate_baseop' hbo::RW_MATRIX_SET_WITH_BOUNDSCHECK_MACRO =>  bug "hbo::RW_MATRIX_SET_WITH_BOUNDSCHECK_MACRO unimplemented -- translate-deep-syntax-to-lambdacode.pkg";
                            #
                            translate_baseop' hbo::RO_MATRIX_GET_MACRO =>  bug "hbo::RO_MATRIX_GET_MACRO unimplemented -- translate-deep-syntax-to-lambdacode.pkg";
                            translate_baseop' hbo::RW_MATRIX_SET_MACRO =>  bug "hbo::RW_MATRIX_SET_MACRO unimplemented -- translate-deep-syntax-to-lambdacode.pkg";

                            translate_baseop' hbo::RW_MATRIX_GET_MACRO
                                =>
                                {
                                    bug "hbo::RW_MATRIX_GET_MACRO unimplemented -- translate-deep-syntax-to-lambdacode.pkg";

                                    my (tc1, t1)
                                        =
                                        case uniqtypes
                                            #                                     
                                            [z] => (z, lt_tyc z);
                                            _   => bug "unexpected type for INLSUB";
                                        esac;

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

                                    op =  lcf::BASEOP (hbo::RW_VECTOR_GET, lt, uniqtypes);

                                    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 "INDEX_OUT_OF_BOUNDS", t1)))));                                                       # else raise exception INDEX_OUT_OF_BOUNDS;  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;

                                };

                            translate_baseop' hbo::RO_VECTOR_GET_WITH_BOUNDSCHECK
                                =>
                                {   my (tc1, t1)
                                        =
                                        case uniqtypes
                                            #                                     
                                            [z] =>  (z,  lt_tyc z);
                                            _   =>  bug "unexpected type for INLSUBV";
                                        esac;

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

                                    op =   lcf::BASEOP (hbo::RW_VECTOR_GET, lt, uniqtypes);

                                    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 "INDEX_OUT_OF_BOUNDS", t1)))));                                                       # else raise exception INDEX_OUT_OF_BOUNDS;  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;
                                };


                            translate_baseop'  hbo::RW_VECTOR_GET_WITH_BOUNDSCHECK
                                => 
                                {   my (tc1, t1)
                                        =
                                        case uniqtypes
                                            #                                     
                                            [z] => (z, lt_tyc z);
                                            _   => bug "unexpected type for INLSUB";
                                        esac;

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

                                    op =  lcf::BASEOP (hbo::RW_VECTOR_GET, lt, uniqtypes);

                                    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 "INDEX_OUT_OF_BOUNDS", t1)))));                                                       # else raise exception INDEX_OUT_OF_BOUNDS;  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;
                                };

                            translate_baseop' (hbo::GET_VECSLOT_NUMERIC_CONTENTS { kind_and_size, checkbounds=>TRUE, immutable } )
                                =>
                                {
                                                                                                                                {   if *debugging
                                                                                                                                        #
                                                                                                                                        stderr             =   winix_text_file_for_posix__premicrothread::stderr;
                                                                                                                                        unparse_textstream =   winix_text_file_for_posix__premicrothread::stderr;

                                                                                                                                        output_stream
                                                                                                                                          =
                                                                                                                                          { consumer  =>  (\\ string =  winix_text_file_for_posix__premicrothread::write  (unparse_textstream,  string)),
                                                                                                                                            flush     =>  {. winix_text_file_for_posix__premicrothread::flush  unparse_textstream; },
                                                                                                                                            close     =>  \\ () = ()
                                                                                                                                          };

                                                                                                                                        pp =   pp::make_prettyprinter  output_stream  [];

                                                                                                                                        fun prettyprint_uniqtype  uniqtype
                                                                                                                                            =
                                                                                                                                            {   pp.lit "   <<< ";
                                                                                                                                                pht::prettyprint_uniqtype  symbolmapstack::empty  pp  uniqtype;
                                                                                                                                                pp.lit " >>>   ";
                                                                                                                                            };  

                                                                                                                                        len = list::length uniqtypes;

                                                                                                                                        pp.newline();
                                                                                                                                        pp.lit (sprintf "Prettyprinting %d types:          -- translate_baseop/GET_VECSLOT_NUMERIC_CONTENTS [translate-deep-syntax-to-lambdacode.pkg]\n" len);

                                                                                                                                        apply prettyprint_uniqtype uniqtypes;

                                                                                                                                        pp.newline();
                                                                                                                                        pp.lit (sprintf "Prettyprinting %d types complete. -- translate_baseop/GET_VECSLOT_NUMERIC_CONTENTS [translate-deep-syntax-to-lambdacode.pkg]\n" len);

                                                                                                                                        pp::flush_prettyprinter  pp;
                                                                                                                                        pp::close_prettyprinter  pp;
                                                                                                                                    fi;
                                                                                                                                };
                                    my (tc1, t1, t2)
                                        = 
                                        case uniqtypes
                                            #                                     
                                            [a, b] =>   {
                                                            ( a,  lt_tyc a,  lt_tyc b);
                                                        };
                                            _      =>   {   fprintf winix_text_file_for_posix__premicrothread::stderr "Unexpected type for hbo::GET_VECSLOT_NUMERIC_CONTENTS -- list::length(uniqtypes) == %d, expected 2\n" (list::length uniqtypes);
                                                            bug "unexpected type for hbo::GET_VECSLOT_NUMERIC_CONTENTS";
                                                        };
                                        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 { kind_and_size, checkbounds=>FALSE, immutable };

                                    op' = lcf::BASEOP (op, lt, uniqtypes);

                                    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 "INDEX_OUT_OF_BOUNDS", t2)))));                                                       # else raise exception INDEX_OUT_OF_BOUNDS;  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;
                                };

                            translate_baseop' hbo::RW_VECTOR_SET_WITH_BOUNDSCHECK
                                => 
                                {   my (tc1, t1)
                                        =
                                        case uniqtypes
                                            #                                     
                                            [z] =>  (z, lt_tyc z);
                                            _   =>  bug "unexpected type for INLSUB";
                                        esac;

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

                                    op = lcf::BASEOP (hbo::RW_VECTOR_SET, lt, uniqtypes);

                                    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 "INDEX_OUT_OF_BOUNDS", hcf::void_uniqtypoid))))));                          # else raise exception INDEX_OUT_OF_BOUNDS; 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;
                                };

                            translate_baseop' (hbo::SET_VECSLOT_TO_NUMERIC_VALUE { kind_and_size, checkbounds=>TRUE } )
                                =>
                                {   my (tc1, t1, t2)
                                        = 
                                        case uniqtypes
                                            #                                     
                                            [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 { kind_and_size, checkbounds=>FALSE };
                                    op' = lcf::BASEOP (op, lt, uniqtypes);

                                    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 "INDEX_OUT_OF_BOUNDS", hcf::void_uniqtypoid))))));                          # else raise exception INDEX_OUT_OF_BOUNDS; 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)
                          | translate_baseop' (hbo::SET_REFCELL) = 
                                let my (tc1, t1) = case uniqtypes of [z] => (z, lt_tyc z)
                                                      | _ => bug "unexpected type for ASSIGN"

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

                                    op = lcf::BASEOP (hbo::RW_VECTOR_SET, 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.

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


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


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


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

                            # Default handling for all other
                            # base operations:
                            #
                            translate_baseop' baseop
                                =>
                                lcf::BASEOP (baseop, lt, uniqtypes);
                        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::PLAIN_VARIABLE { varhome, inlining_data, vartypoid_ref, path }):   vac::Variable,
                          debruijn_depth:  di::Debruijn_Depth
                        )
                        : lcf::Lambdacode_Expression
                        => 
                        translate_varhome_info
                          (
                            varhome,
                            inlining_data,
                            \\ () =  deepsyntax_typoid_to_uniqtypoid  debruijn_depth  *vartypoid_ref,
                            get_name_or_null  path
                          );

                    translate_variable _
                        =>
                        bug "unexpected vars in translate_variable";
                end;
                #
                fun translate_variable_in_expression (v, typoids, d)
                    =
                    {   fun otherwise ()
                            =
                            case typoids
                                #
                                [] =>  translate_variable (v, d);
                                _  =>  lcf::APPLY_TYPEFUN (translate_variable (v, d), map (deepsyntax_type_to_uniqtype d) typoids);
                            esac;
                    
                        case v
                            #                     
                            vac::PLAIN_VARIABLE { inlining_data, ... }
                                =>
                                ij::case_inlining_data  inlining_data
                                  {
                                    do_inline_list  =>  \\ _  =  otherwise (),
                                    do_inline_nil   =>  \\ () =  otherwise (),

                                    do_inline_baseop
                                        =>
                                        \\ ( baseop:            hbo::Baseop,
                                             type
                                           )
                                            =
                                            case (baseop, typoids)
                                                #                                                 
                                                (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_typoid_to_uniqtypoid d t);

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

                                                        lcf::GENOP (
                                                            dictionary,
                                                            baseop,
                                                            deepsyntax_typoid_to_uniqtypoid  d  type,
                                                            map  (deepsyntax_type_to_uniqtype d)  typoids
                                                        );
                                                    };

                                                (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_typoid_to_uniqtypoid  d  type,
                                                            map  (deepsyntax_type_to_uniqtype d)  typoids
                                                        );
                                                    };

                                                _   =>  {
                                                                                                                                if *debugging
                                                                                                                                    #
                                                                                                                                    stderr             =   winix_text_file_for_posix__premicrothread::stderr;

                                                                                                                                    output_stream
                                                                                                                                      =
                                                                                                                                      { consumer  =>  (\\ string =  winix_text_file_for_posix__premicrothread::write  (stderr,  string)),
                                                                                                                                        flush     =>  {. winix_text_file_for_posix__premicrothread::flush  stderr; },
                                                                                                                                        close     =>  \\ () = ()        
                                                                                                                                      };

                                                                                                                                    pp =   pp::make_prettyprinter  output_stream  [];

                                                                                                                                    fun prettyprint_typoid typoid
                                                                                                                                        =
                                                                                                                                        {   pp.lit "   <<< ";
                                                                                                                                            ppt::prettyprint_typoid  symbolmapstack::empty  pp  typoid;
                                                                                                                                            pp.lit " >>>   ";
                                                                                                                                            pp.newline();
                                                                                                                                        };      

                                                                                                                                    len =  list::length  typoids;       
                                                                                                                                    pp.newline();
                                                                                                                                    pp.lit "translate_variable_in_expression/vac::PLAIN_VARIABLE/do_inline_baseop/other";
                                                                                                                                    pp.newline();
                                                                                                                                    pp.lit (sprintf "prettyprinting %d typoids:     -- translate_variable_in_expression/PLAIN_VARIABLE/do_inline_baseop/   [translate-deep-syntax-to-lambdacode.pkg]"  len);
                                                                                                                                    pp.newline();

                                                                                                                                    apply prettyprint_typoid  typoids;

                                                                                                                                    pp.newline();
                                                                                                                                    pp.lit (sprintf "prettyprinting %d typoids done -- translate_variable_in_expression/PLAIN_VARIABLE/do_inline_baseop/   [translate-deep-syntax-to-lambdacode.pkg]" len);
                                                                                                                                    pp.newline();
                                                                                                                                    pp::flush_prettyprinter  pp;
                                                                                                                                    pp::close_prettyprinter  pp;
                                                                                                                                fi;
                                                            translate_baseop
                                                              (
                                                                baseop,
                                                                (deepsyntax_typoid_to_uniqtypoid d type),
                                                                map (deepsyntax_type_to_uniqtype d) typoids
                                                              );
                                                        };
                                            esac
                                };

                            _   =>
                                otherwise ();
                        esac;
                    };
                #
                fun translate_constructor_expression (tdt::VALCON { is_constant, form, name, typoid, ... }, ts, ap_op, d)
                    = 
                    {   lt = to_valcon_lty  d  typoid;
                        form' = make_representation (form, lt, name);
                        dc = (name, form', lt);
                        ts' = map (deepsyntax_type_to_uniqtype 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_uniqtypoid (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,
                              \\ () = deepsyntax_package_to_uniqtypoid (s, d, per_compile_stuff),
                              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,
                              \\ () = deepsyntax_generic_package_to_uniqtypoid (f, d, per_compile_stuff),
                              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)
                    =
                    translate'
                    where
                        fun translate' (sxe::NAMED_VARIABLE v) =>  translate_variable (v, debruijn_depth);
                            translate' (sxe::NAMED_PACKAGE  s) =>  translate_package  (s, debruijn_depth);
                            translate' (sxe::NAMED_GENERIC  f) =>  translate_generic  (f, debruijn_depth);

                            translate' (sxe::NAMED_CONSTRUCTOR (tdt::VALCON  { form=> vh::EXCEPTION acc,  name,  typoid, ... } ))
                                =>
                                {   nt =  to_valcon_lty  debruijn_depth  typoid;
                                    #
                                    my (argt, _) =   hcf::unpack_lambdacode_arrow_uniqtypoid nt;

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

                            translate' _ =>   bug "unexpected arg 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_Value ) * )
                #     -> 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 ============= [translate-deep-syntax-to-lambdacode.pkg] " callstack;
                                                                                                                if_debugging_unparse_expression ("translate_pattern_expression input expression argument:", (expression,100));
                                                                                                                printf "\ntranslate_pattern_expression generalized_typevars argument has 0 entries so calling translate_expression instead of translate_pattern_expression.  [translate-deep-syntax-to-lambdacode.pkg]\n";
                                                                                                            fi;

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

                                    if *debugging
                                        printf "\ntranslate_pattern_expression/BOTTOM   [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*/                     generalized_typevars:  List( tdt::Typevar_Ref ),      # From a deep syntax NAMED_VALUE or NAMED_RECURSIVE_VALUE 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     ("\ntranslate_pattern_expression input expression argument unparsed:", (expression,100));
                                                                                                                                    if_debugging_prettyprint_expression ("\ntranslate_pattern_expression input expression argument pprinted:", (expression,100));
                                                                                                                                    printf "translate_pattern_expression generalized_typevars argument has %d entries:\n"  (length  generalized_typevars);
                                                                                                                                    apply unparse generalized_typevars
                                                                                                                                    where
                                                                                                                                        fun unparse  typevar_ref
                                                                                                                                            =
                                                                                                                                            if_debugging_unparse_typevar_ref  ("", typevar_ref);
                                                                                                                                    end;
                                                                                                                                    printf "\n";
                                                                                                                                fi;



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

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

                                                                                        # translate_types       is from   src/lib/compiler/back/top/translate/translate-deep-syntax-types-to-lambdacode.pkg
                            # Assign TYPEVAR_MARK typevars.
                            # We will erase these before we return.
                            #
                            # These TYPEVAR_MARK values are only
                            # used in translate_deep_syntax_types_to_lambdacode::deepsyntax_type_to_uniqtype(): 
                            #
                            #   "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, generalized_typevars)
                            where
                                fun g (i, [])
                                        =>
                                        ();

/*x*/                               g (i, { id, ref_typevar as REF (tdt::META_TYPEVAR _ | tdt::INCOMPLETE_RECORD_TYPEVAR _) } ! 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 (TYPEVAR_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 :=   tdt::TYPEVAR_MARK m;               # This is the only place TYPEVAR_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 (tdt::TYPEVAR_MARK _) } ) ! result)
/*x*/                                   =>
                                        {   if *debugging
                                                printf "Ignoring the fact that [id%d]typevar_ref is already set to (TYPEVAR_MARK (i d==%d) translate_deep_syntax_to_lambdacode\n" id i;
                                            fi;
/*x*/                                      # bug (sprintf "unexpected [id%d]typevar TYPEVAR_MARK in translate_pattern_expression i d=%d" id i);
/*x*/                                      ();
                                        };

                                    g _ => bug "unexpected typevar 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 generalized_typevars
                            # back to their original value:
                            #
                            restore (generalized_typevars', 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  generalized_typevars';

                            if *debugging
                                printf "translate_pattern_expression/BOTTOM in translate-deep-syntax-to-lambdacode.pkg\n";
                                printf "translate_pattern_expression generalized_typevars argument %d entries restored:\n"  (length  generalized_typevars);
                                apply unparse generalized_typevars
                                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, (tdt::TYPEVAR_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::VALUE_NAMING
                                    {
                                      pattern    => ds::VARIABLE_IN_PATTERN (vac::PLAIN_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, ... } ),
                                      expression as ds::VARIABLE_IN_EXPRESSION {  var => REF (w as (vac::PLAIN_VARIABLE _)),  typescheme_args },
                                      generalized_typevars,
                                      ...
                                    },
                                  fold_result_so_far
                                )
                                => 
                                if (eq_tvs (generalized_typevars, typescheme_args))
                                                                                                                                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, generalized_typevars, "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::VALUE_NAMING { pattern as ds::VARIABLE_IN_PATTERN (vac::PLAIN_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, ... } ),
/*x*/                                           expression,
/*x*/                                           generalized_typevars,
/*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  generalized_typevars);
                                                                                                                                   apply unparse generalized_typevars
                                                                                                                                   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  [translate_named_values  [translate-deep-syntax-to-lambdacode.pkg]\n"; fi;

/*x*/                               result = lcf::LET (v, translate_pattern_expression (expression, debruijn_depth, generalized_typevars, "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   [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::VALUE_NAMING { pattern => ds::TYPE_CONSTRAINT_PATTERN (ds::VARIABLE_IN_PATTERN (vac::PLAIN_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, ... } ), _),
                                                expression,
                                                generalized_typevars,
                                                ...
                                              },
                                  fold_result_so_far
                                )
                                =>
                                {                                                                                               if *debugging printf "\nCALLING translate_pattern_expression:  g()/NAMED_VALUE III (type-constrained variable) in  translate_named_values   [translate-deep-syntax-to-lambdacode.pkg]\n";fi;

                                    result = lcf::LET ( v,
                                                        translate_pattern_expression (expression, debruijn_depth, generalized_typevars,  "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   [translate-deep-syntax-to-lambdacode.pkg]\n"; fi;
                                    result;
                                };

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

                                    ee    = translate_pattern_expression (expression, debruijn_depth, generalized_typevars, "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   [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 =    \\ (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_VALUE
                                            { variable => vac::PLAIN_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, vartypoid_ref => REF type, ... },
                                              expression,
                                              generalized_typevars,
                                              ...
                                             },

                                          (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_VALUE anymore ! 
                                        {
                                                                                                                                if *debugging printf "\nCALLING translate_pattern_expression:  g() in translate_named_recursive_values   [translate-deep-syntax-to-lambdacode.pkg]\n"; fi;

                                            ee = translate_pattern_expression (expression, debruijn_depth, generalized_typevars, "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   [translate-deep-syntax-to-lambdacode.pkg]\n"; fi;
                                            vt = deepsyntax_typoid_to_uniqtypoid  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 => tdt::VALCON {
                                                                 form => vh::EXCEPTION (vh::HIGHCODE_VARIABLE v),
                                                                 typoid,
                                                                 ...
                                                               }, 
                                      name_string => ident,
                                      ...
                                  },
                                  b
                              )
                                =>
                                {   nt = to_valcon_lty  debruijn_depth  typoid;
                                    #
                                    my (argt, _) =  hcf::unpack_lambdacode_arrow_uniqtypoid  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 => tdt::VALCON {
                                                                       form => vh::EXCEPTION (vh::HIGHCODE_VARIABLE v),
                                                                       typoid,
                                                                       name,
                                                                       ...
                                                                   },
                                       equal_to => tdt::VALCON { form=>vh::EXCEPTION acc, ... }
                                   },
                                   b
                              )
                                =>
                                {   nt = to_valcon_lty  debruijn_depth  typoid;
                                    #
                                    my (argt, _) = hcf::unpack_lambdacode_arrow_uniqtypoid nt;

                                    lcf::LET (v, translate_varhome_with_type (acc, hcf::make_exception_tag_uniqtypoid 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);
                                    types =  map  (deepsyntax_typepath_to_uniqtype  debruijn_depth)  parameter_types;
                                    e2 = translate_package (arg, debruijn_depth);
                                    lcf::APPLY (lcf::APPLY_TYPEFUN (e1, types), 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_typepath_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_uniqtypoid (parameter, new_depth, per_compile_stuff), 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::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;

                                    \\ 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_uniqtypoid (s, debruijn_depth, per_compile_stuff), 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     ("\ntranslate_deep_syntax_expression_to_lambdacode input expression unparsed:",      (expression,100));
                                                                                                                                    if_debugging_prettyprint_expression ("\ntranslate_deep_syntax_expression_to_lambdacode input expression prettyprinted:", (expression,100));
                                                                                                                                fi;

                        to_uniqtype    =  deepsyntax_type_to_uniqtype      debruijn_depth;
                        to_uniqtypoid  =  deepsyntax_typoid_to_uniqtypoid  debruijn_depth;

                        #
                        fun make_rules  case_rules
                            =
                            map  make_rule  case_rules
                            where
                                fun make_rule  (ds::CASE_RULE (pattern, expression))
                                    =
                                    ( fill_pattern (pattern, debruijn_depth),
                                      #
                                      translate_deep_syntax_expression_to_lambdacode'  expression
                                    );
                            end

                        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     ("\ntranslate_deep_syntax_expression_to_lambdacode' input expression unparsed:",      (expression,100));
                                                                                                                                    if_debugging_prettyprint_expression ("\ntranslate_deep_syntax_expression_to_lambdacode' input expression prettyprinted:", (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'' (x as (ds::VARIABLE_IN_EXPRESSION {  var => REF v,  typescheme_args  }))
                                    =>
{
                                                                                                                                if *debugging
                                                                                                                                    print_callstack "\n============= translate_deep_syntax_expression_to_lambdacode''/ds::VARIABLE_IN_EXPRESSION   ============= " callstack;
                                                                                                                                    printf "translate_deep_syntax_expression_to_lambdacode''/ds::VARIABLE_IN_EXPRESSION   list::length(typescheme_args) d=%d\n" (list::length typescheme_args);
                                                                                                                                    if_debugging_unparse_expression     ("\ntranslate_deep_syntax_expression_to_lambdacode''/ds::VARIABLE_IN_EXPRESSION x unparsed:", (x,100));
                                                                                                                                    if_debugging_prettyprint_expression ("\ntranslate_deep_syntax_expression_to_lambdacode''/ds::VARIABLE_IN_EXPRESSION x pprinted:", (x,100));
                                                                                                                                fi;
                                    translate_variable_in_expression (v, typescheme_args, debruijn_depth);                      # Only call to this fn.
};
                                translate_deep_syntax_expression_to_lambdacode'' (ds::VALCON_IN_EXPRESSION { valcon, typescheme_args })
                                    =>
                                    translate_constructor_expression (valcon, typescheme_args, NULL, debruijn_depth);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::APPLY_EXPRESSION { operator => ds::VALCON_IN_EXPRESSION { valcon, typescheme_args }, operand => e2 })
                                    =>
                                    translate_constructor_expression (valcon, typescheme_args, 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::typoids_are_equal (t, mtt::int_typoid          ))  lcf::INT   (ln::int   s);
                                    elif (tyj::typoids_are_equal (t, mtt::int1_typoid         ))  lcf::INT1 (ln::one_word_int s);
                                    elif (tyj::typoids_are_equal (t, mtt::multiword_int_typoid))  lcf::VAR (get_interface_info s);
                                    elif (tyj::typoids_are_equal (t, mtt::int2_typoid         ))

                                        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::typoids_are_equal (t, mtt::unt_typoid ))   lcf::UNT    (ln::unt   s);
                                    elif (tyj::typoids_are_equal (t, mtt::unt8_typoid))   lcf::UNT    (ln::one_byte_unt  s);
                                    elif (tyj::typoids_are_equal (t, mtt::unt1_typoid))   lcf::UNT1  (ln::one_word_unt s);
                                    elif (tyj::typoids_are_equal (t, mtt::unt2_typoid)) 

                                        (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 (string::get_byte (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  (\\ (_, e) = translate_deep_syntax_expression_to_lambdacode' e)  xs);
                                    else
                                        vars =   map  (\\ (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  (\\ (_, (_, 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", [to_uniqtype type]);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::VECTOR_IN_EXPRESSION (xs, type))
                                    => 
                                    {   tc   =   to_uniqtype type;
                                        #
                                        vars =   map (\\ e =  (translate_deep_syntax_expression_to_lambdacode' e, make_var()))
                                                     xs;
                                        #
                                        fun bind ((e, v), x)
                                            =
                                            lcf::LET (v, e, x);

                                        bexp =   map (\\ (_, 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, types))
                                    =>
                                    translate_deep_syntax_expression_to_lambdacode' e;

    #                           {   my  (nty, ks, tps)
    #                                   =
    #                                   tyj::reformatTypeAbstraction (type, types, 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_uniqtypoid (ks, [deepsyntax_typoid_to_uniqtypoid 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 { operator => e1, operand => 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, to_uniqtypoid type);

                                translate_deep_syntax_expression_to_lambdacode'' (ds::EXCEPT_EXPRESSION (e, (l, type)))
                                    =>
                                    {   root_var =   make_var();
                                        #
                                        fun f x
                                            =
                                            lcf::FN (root_var, to_uniqtypoid 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, to_uniqtypoid 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"
                                        (\\ pp
                                            =
                                            {   pp.lit " expression: ";
                                                uds::unparse_expression
                                                    (symbolmapstack, NULL)
                                                    pp
                                                    (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  { valcon => mtt::cons_valcon,  typescheme_args => [mtt::unt_typoid] };
                        #
                        fun build []
                                =>
                                ds::VALCON_IN_EXPRESSION  { valcon => mtt::nil_valcon,  typescheme_args => [mtt::unt_typoid] };

                            build (d ! ds)
                                =>
                                {   i =  unt::to_int_x  d;
                                    #
                                    ds::APPLY_EXPRESSION {
                                        operator => valcon_expression,
                                        operand  => trj::tupleexp [ds::UNT_CONSTANT_IN_EXPRESSION (multiword_int::from_int i, mtt::unt_typoid),
                                                         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), mtt::unt_typoid),
                                      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 (\\ (p, pi) =  (p, p2itree pi))
                                        picklehash_infos
                                    where
                                        fun p2itree (ANON xl)
                                                => 
                                                it::IMPORT_TREE_NODE
                                                    (map (\\ (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 (\\ ((i, x), z)
                                                   =
                                                   {   ts = tree x;
                                                       u = (int::to_string i)  + "   ";
                                                       (map (\\ 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 =   \\ ((_, pi), z) =  get((0, pi), z);

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

                                        (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_uniqtypoid 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 named integer constants:
                #
                body =   wrap_integer (body, []);


                #  Wrap up the body with the imported variables:
                #
                (wrap_picklehash_info (body, phm::keyvals_list  *picklehash_map))
                    ->
                    (lambdacode_expression, imports);
                                                                                                  
                case prettyprinter_or_null
                    NULL   =>   ();
                    THE pp =>   {
                                    print_lambdacode_expression
                                        (global_controls::highcode::print,   plx::prettyprint_lambdacode_expression pp)
                                        "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;
                                };
                esac;

#               # 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 ==========   [translate-deep-syntax-to-lambdacode.pkg]\n";
                fi;

                per_compile_stuff ->   { prettyprinter_or_null, compiler_verbosity, ... };

                # Prettyprint to logfile if so requested:
                #
                case prettyprinter_or_null
                    #
                    NULL => ();

                    THE pp
                        =>
                        if compiler_verbosity.pprint_lambdacode_tree
                            #
                            if (pcs::saw_errors  per_compile_stuff)
                                #
                                pp.newline();
                                pp.newline();
                                pp.lit   "(Due to syntax errors, no lambdacode tree.)\n";
                                pp.newline();
                            else 
                                pp.newline();
                                pp.newline();
                                pp.lit   "(Following printed by src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg.)";
                                pp.newline();

                                pp.newline();
                                pp.lit   "Lambdacode tree, prettyprinted:";
                                pp.newline();
                                #
                                plx::prettyprint_lambdacode_expression  pp  lambdacode_expression;
                                pp.newline();
                            fi;
                            pp.flush();
                        fi;
                esac;



                { lambdacode_expression, 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