


## translate-deep-syntax-to-lambdacode.pkg
#
# CONTEXT:
#
# The Mythryl compiler code representations used are, in order:
#
# 1) Raw Syntax is the initial frontend code representation.
# 2) Deep Syntax is the second and final frontend code representation.
# 3) Lambdacode is the first backend code representation, used only transitionally.
# 4) Anormcode (A-Normal format) is the second backend code representation, and the first used for optimization.
# 5) Nextcode is the third and chief backend tophalf code representation.
# 6) Treecode is the backend tophalf/lowhalf transitional code representation. It is typically slightly specialized for each target architecture, e.g. Intel32 (x86).
# 7) Machcode abstracts the target architecture machine instructions. It gets specialized for each target architecture.
# 8) Execode is absolute executable binary machine instructions for the target architecture.
#
# Our task here is converting from the second to the third form.
#
# This package is the doorway between the front end,
# which is concerned with syntax and typechecking,
# and the back end, which is concerned with performance
# improvements and code generation.
#
# Deep syntax is the most abstract of the frontend
# code representations:
#
# src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.api#
# A-Normal form is the highest level code representation
# used for optimization in the back end. In particular,
# A-Normal form still explicitly represents the call hierarchy
# and is thus an apppropriate setting for code optimizations
# based on call hierarchy:
#
# src/lib/compiler/back/top/anormcode/anormcode-form.api#
# We use a polymorphically typed lambda calculus representation
# as a stepping stone to get from deep syntax to A-Normal form:
#
# src/lib/compiler/back/top/lambdacode/lambdacode-form.api#
# A-Normal is a relatively minor code representation in
# this compiler; it serves primarily as a stepping stone
# to our nextcode ("continuation passing style") code
# representation, which is the workhorse of the back
# end top half:
#
# src/lib/compiler/back/top/nextcode/nextcode-form.api#
# For higher-level context, read
#
# src/A.COMPILER.OVERVIEW
#
#
# "In this phase the deep syntax, annotated with static semantic information,
# is translated into a strict call-by-value lambda calculus augmented with
# data constructors, records and primitive operators and explicitly typed
# using a simple typelocked type system. The type information is converted
# directly from the static semantic information attached to the deep syntax.
# Coercion functions are inserted at each abstraction and instantiation site
# to correctly support abstraction and polymorphicism. In addition this phase
# also inserts the proper implementation of each equality test and assignment
# operator, and does pattern-match compilation"
# p33, "Compiling Standard ML For Efficient Execution on Modern Machines"
# http://flint.cs.yale.edu/flint/publications/zsh-thesis.pdf
#
# We get invoked (only) from
#
# src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg#
#
# Compiled by:
# src/lib/compiler/core.sublib#DO set_control "compiler::trap_int_overflow" "TRUE";
stipulate
package ds = deep_syntax; # deep_syntax is from src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.pkg package tmp = highcode_codetemp; # highcode_codetemp is from src/lib/compiler/back/top/highcode/highcode-codetemp.pkg package it = import_tree; # import_tree is from src/lib/compiler/execution/main/import-tree.pkg package lcf = lambdacode_form; # lambdacode_form is from src/lib/compiler/back/top/lambdacode/lambdacode-form.pkg package pci = per_compile_info; # per_compile_info is from src/lib/compiler/front/typer-stuff/main/per-compile-info.pkg package ph = picklehash; # picklehash is from src/lib/compiler/front/basics/map/picklehash.pkg package syx = symbolmapstack; # symbolmapstack is from src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg package vh = varhome; # varhome is from src/lib/compiler/front/typer-stuff/basics/varhome.pkgherein
api Translate_Deep_Syntax_To_Lambdacode {
# Invariant: translate_deep_syntax_to_lambdacode is always applied
# to a top-level ds::Declaration
translate_deep_syntax_to_lambdacode
:
{ declaration: ds::Declaration,
exported_highcode_variables: List( tmp::Codetemp ),
symbolmapstack: syx::Symbolmapstack,
ansi_c_prototype_convention: String, # "unix_convention" or "windows_convention"
per_compile_info: pci::Per_Compile_Info( ds::Declaration )
}
->
{ lambdacode_expression: lcf::Lambdacode_Expression,
#
imports: List( ( ph::Picklehash,
it::Import_Tree_Node
) )
};
};
end;
### "It is not the strongest of the species
### that survive, not the most intelligent,
### but the one most responsive to change."
###
### -- Charles Darwin
stipulate
package bt = type_types; # type_types is from src/lib/compiler/front/typer/types/type-types.pkg package coa = core_access; # core_access is from src/lib/compiler/front/typer-stuff/symbolmapstack/core-access.pkg package coc = compiler_controls; # compiler_controls is from src/lib/compiler/toplevel/main/compiler-controls.pkg package csy = core_symbol; # core_symbol is from src/lib/compiler/front/typer-stuff/basics/core-symbol.pkg package di = debruijn_index; # debruijn_index is from src/lib/compiler/front/typer/basics/debruijn-index.pkg package d2l = translate_deep_syntax_types_to_lambdacode; # translate_deep_syntax_types_to_lambdacode is from src/lib/compiler/back/top/translate/translate-deep-syntax-types-to-lambdacode.pkg package ds = deep_syntax; # deep_syntax is from src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.pkg package err = error_message; # error_message is from src/lib/compiler/front/basics/errormsg/error-message.pkg package hbo = highcode_baseops; # highcode_baseops is from src/lib/compiler/back/top/highcode/highcode-baseops.pkg package hcf = highcode_form; # highcode_form is from src/lib/compiler/back/top/highcode/highcode-form.pkg package tmp = highcode_codetemp; # highcode_codetemp is from src/lib/compiler/back/top/highcode/highcode-codetemp.pkg package hut = highcode_uniq_types; # highcode_uniq_types is from src/lib/compiler/back/top/highcode/highcode-uniq-types.pkg package iht = int_hashtable; # int_hashtable is from src/lib/src/int-hashtable.pkg package ij = inlining_junk; # inlining_junk is from src/lib/compiler/front/semantic/basics/inlining-junk.pkg package it = import_tree; # import_tree is from src/lib/compiler/execution/main/import-tree.pkg package lcf = lambdacode_form; # lambdacode_form is from src/lib/compiler/back/top/lambdacode/lambdacode-form.pkg package lms = list_mergesort; # list_mergesort is from src/lib/src/list-mergesort.pkg package ln = literal_to_num; # literal_to_num is from src/lib/compiler/src/stuff/literal-to-num.pkg package mld = module_level_declarations; # module_level_declarations is from src/lib/compiler/front/typer-stuff/modules/module-level-declarations.pkg package mc = translate_deep_syntax_pattern_to_lambdacode; # translate_deep_syntax_pattern_to_lambdacode is from src/lib/compiler/back/top/translate/translate-deep-syntax-pattern-to-lambdacode.pkg package pds = prettyprint_deep_syntax; # prettyprint_deep_syntax is from src/lib/compiler/front/typer/print/prettyprint-deep-syntax.pkg package peq = polyequal; # polyequal is from src/lib/compiler/back/top/translate/polyequal.pkg package ph = picklehash; # picklehash is from src/lib/compiler/front/basics/map/picklehash.pkg package phm = picklehash_map; # picklehash_map is from src/lib/compiler/front/basics/map/picklehash-map.pkg package pp = prettyprint; # prettyprint is from src/lib/prettyprint/big/src/prettyprint.pkg package sy = symbol; # symbol is from src/lib/compiler/front/basics/map/symbol.pkg package syp = symbol_path; # symbol_path is from src/lib/compiler/front/typer-stuff/basics/symbol-path.pkg package sxe = symbolmapstack_entry; # symbolmapstack_entry is from src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack-entry.pkg package td = typer_debugging; # typer_debugging is from src/lib/compiler/front/typer/main/typer-debugging.pkg package trj = typer_junk; # typer_junk is from src/lib/compiler/front/typer/main/typer-junk.pkg package ty = types; # types is from src/lib/compiler/front/typer-stuff/types/types.pkg package tyj = type_junk; # type_junk is from src/lib/compiler/front/typer-stuff/types/type-junk.pkg package uds = unparse_deep_syntax; # unparse_deep_syntax is from src/lib/compiler/front/typer/print/unparse-deep-syntax.pkg package ut = unparse_type; # unparse_type is from src/lib/compiler/front/typer/print/unparse-type.pkg package vac = variables_and_constructors; # variables_and_constructors is from src/lib/compiler/front/typer-stuff/deep-syntax/variables-and-constructors.pkg package vh = varhome; # varhome is from src/lib/compiler/front/typer-stuff/basics/varhome.pkg #
package im
=
red_black_map_g ( # red_black_map_g is from src/lib/src/red-black-map-g.pkg Key = multiword_int::Int;
compare = multiword_int::compare;
);
herein
package translate_deep_syntax_to_lambdacode
: (weak) Translate_Deep_Syntax_To_Lambdacode # Translate_Deep_Syntax_To_Lambdacode is from src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg {
#############################################################################
# CONSTANTS AND UTILITY FUNCTIONS
#############################################################################
debugging = typer_data_controls::translate_to_anormcode_debugging; # REF FALSE
#
fun bug msg
=
err::impossible("translate_deep_syntax_to_lambdacode: " + msg);
say = global_controls::print::say;
prettyprint_depth = global_controls::print::print_depth;
#
fun prettyprint_type type
=
td::with_internals
(fn ()
=
td::debug_print
debugging
( "type: ",
ut::unparse_type symbolmapstack::empty,
type
)
);
prettyprint_declaration = pds::prettyprint_declaration (symbolmapstack::empty, NULL);
prettyprint_expression = pds::prettyprint_expression (symbolmapstack::empty, NULL);
prettyprint_pattern = pds::prettyprint_pattern symbolmapstack::empty;
unparse_declaration = uds::unparse_declaration (symbolmapstack::empty, NULL);
unparse_expression = uds::unparse_expression (symbolmapstack::empty, NULL);
unparse_pattern = uds::unparse_pattern symbolmapstack::empty;
unparse_typevar_ref = ut::unparse_typevar_ref symbolmapstack::empty;
#
fun if_debugging_unparse_expression (msg, expression)
=
if *debugging
td::with_internals
(fn () = td::debug_print debugging (msg, unparse_expression, expression));
fi;
#
fun if_debugging_unparse_pattern (msg, pattern)
=
if *debugging
td::with_internals
(fn () = td::debug_print debugging (msg, unparse_pattern, pattern));
fi;
#
fun if_debugging_unparse_declaration (msg, declaration)
=
if *debugging
td::with_internals
(fn () = td::debug_print debugging (msg, unparse_declaration, declaration));
fi;
#
fun if_debugging_unparse_typevar_ref (msg, typevar_ref)
=
if *debugging # Without this 'if' (and the matching one in unify_types), compiling the compiler takes 5X as long! :-)
td::with_internals
(fn () = td::debug_print debugging (msg, unparse_typevar_ref, typevar_ref));
fi;
#
fun if_debugging_prettyprint_expression (msg, expression)
=
if *debugging
td::with_internals
(fn () = td::debug_print debugging (msg, prettyprint_expression, expression));
fi;
#
fun if_debugging_prettyprint_pattern (msg, pattern)
=
if *debugging
td::with_internals
(fn () = td::debug_print debugging (msg, prettyprint_pattern, pattern));
fi;
#
fun if_debugging_prettyprint_declaration (msg, declaration)
=
if *debugging
td::with_internals
(fn () = td::debug_print debugging (msg, prettyprint_declaration, declaration));
fi;
#
fun print_callstack
(msg: String)
(callstack: List(String))
=
{ printf "%s: callstack(%d) == " msg (list::length callstack);
apply .{ printf " -> %s" #string; } (reverse callstack);
printf "\n";
};
#
fun identity_fn x = x;
void_lexp = lcf::RECORD [];
#
fun get_name_or_null p
=
if (syp::null p) NULL;
else THE (syp::last p);
fi;
# apparently not actually used:
# Picklehash = ph::Picklehash;
# fold_backward def in src/lib/core/init/pervasive.pkg # Old-style fold for cases where
# it is partially applied:
#
fun fold f l init
=
fold_backward f init l;
# Sorting the record fields for
# record types and record expressions:
#
stipulate
#
fun elem_gtr ((ds::NUMBERED_LABEL { number=>x, ... }, _), (ds::NUMBERED_LABEL { number=>y, ... }, _))
=
x > y;
herein
#
fun sorted x = lms::list_is_sorted elem_gtr x;
fun sortrec x = lms::sort_list elem_gtr x;
#
end;
# Is given varhome external?
#
fun varhome_is_external (vh::EXTERN _) => TRUE;
varhome_is_external (vh::PATH (a, _)) => varhome_is_external a;
varhome_is_external _ => FALSE;
end;
# An exception to raise exception if
# coreDict is not available:
#
exception NO_CORE;
# This is the external entrypoint
# into this file. We are invoked
# (only) from
#
# src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg #
# All the remaining code in this file
# is nested within this function:
#
fun translate_deep_syntax_to_lambdacode
{
declaration => given_declaration: ds::Declaration,
exported_highcode_variables: List( tmp::Codetemp ),
symbolmapstack: symbolmapstack::Symbolmapstack,
ansi_c_prototype_convention: String, # "unix_convention" or "windows_convention" XXX BUGGO FIXME This should be a datatype.
#
per_compile_info
as
{ error_match,
error_fn,
...
}: per_compile_info::Per_Compile_Info( ds::Declaration )
}
:
{ lambdacode_expression: lcf::Lambdacode_Expression,
imports: List( (ph::Picklehash, it::Import_Tree_Node) )
}
=
{
if *debugging
printf "\n============= translate_deep_syntax_to_lambdacode/TOP ============= in translate-deep-syntax-to-lambdacode.pkg\n";
printf "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n\n";
if_debugging_unparse_declaration ("given_declaration unparsed at translate_deep_syntax_to_lambdacode/TOP", (given_declaration, 100) );
if_debugging_prettyprint_declaration ("given_declaration prettyprinted at translate_deep_syntax_to_lambdacode/TOP", (given_declaration, 100) );
fi;
issue_highcode_codetemp
=
per_compile_info.issue_highcode_codetemp;
#
fun make_var ()
=
issue_highcode_codetemp NULL;
# Set up a new type translator incorporating a fresh markmap:
#
(d2l::make_deep_syntax_to_lambdacode_type_translator ())
->
{ deepsyntax_typpath_to_uniqkind,
deepsyntax_typpath_to_uniqtyp,
deepsyntax_type_to_uniqtyp,
deepsyntax_type_to_uniqtype,
deepsyntax_package_to_uniqtype,
deepsyntax_generic_package_to_uniqtype,
mark_letbound_typevar
};
#
fun to_tc_lt debruijn_depth
=
( deepsyntax_type_to_uniqtyp debruijn_depth,
deepsyntax_type_to_uniqtype debruijn_depth
);
# Translate the type field in
# VALCON into Uniqtype.
#
# Constant valcons will take
# void_uniqtype as the argument.
#
fun to_dcon_lty debruijn_depth type # "dcon" == "datatype constructor"; "lty" == "lambda type".
=
case type
#
ty::TYPE_SCHEME_TYPE
{
type_scheme_arg_eq_properties => an_api,
type_scheme => ty::TYPE_SCHEME { arity, body }
}
=>
if (bt::is_arrow_type body)
#
deepsyntax_type_to_uniqtype debruijn_depth type;
else
deepsyntax_type_to_uniqtype debruijn_depth
(
ty::TYPE_SCHEME_TYPE
{
type_scheme_arg_eq_properties => an_api,
type_scheme => ty::TYPE_SCHEME
{ arity,
body => bt::(-->) (bt::void_type, body)
}
}
);
fi;
_ => if (bt::is_arrow_type type) deepsyntax_type_to_uniqtype debruijn_depth type;
else deepsyntax_type_to_uniqtype debruijn_depth (bt::(-->) (bt::void_type, type));
fi;
esac;
# The special look-up functions for the Core dictionary:
#
fun core_lookup (id, dictionary)
=
{ sp = syp::SYMBOL_PATH [ csy::core_symbol, sy::make_value_symbol id ];
err = fn _ = fn _ = fn _ = raise exception NO_CORE;
find_in_symbolmapstack::find_value_via_symbol_path (dictionary, sp, err);
};
#
fun con' ((_, vh::REFCELL_REP, lt), ts, e)
=>
lcf::APPLY (lcf::BASEOP (hbo::MAKE_REFCELL, lt, ts), e);
con' ((_, vh::SUSPENSION (THE (vh::HIGHCODE_VARIABLE d, _)), lt), ts, e)
=>
{ v = make_var ();
fe = lcf::FN (v, hcf::make_tuple_uniqtype [], e);
lcf::APPLY (lcf::APPLY_TYPEFUN (lcf::VAR d, ts), fe);
};
con' x => lcf::CONSTRUCTOR x;
end;
# The following code implements the exception tracking and
# errormsg reporting.
stipulate
source_code_region
=
REF (0, 0);
markexn = lcf::BASEOP
(
hbo::MARK_EXCEPTION_WITH_STRING, # Op
#
hcf::make_lambdacode_arrow_uniqtype # Result type
( hcf::make_tuple_uniqtype [ hcf::exception_uniqtype, hcf::string_uniqtype ],
hcf::exception_uniqtype
),
[] # Arg types.
);
herein
#
fun with_region loc f x
=
{ r = *source_code_region;
{ source_code_region := loc;
f x
before
source_code_region := r;
}
except
e = { source_code_region := r;
raise exception e;
};
};
#
fun make_raise (x, lt)
=
{ e = if *global_controls::track_exn lcf::APPLY (markexn, lcf::RECORD [ x, lcf::STRING (error_match *source_code_region) ] );
else x;
fi;
lcf::RAISE (e, lt);
};
#
fun complain s = error_fn *source_code_region s;
fun rep_err x = complain err::ERROR x err::null_error_body;
#
fun maybe_report_use_of_poly_eq ()
=
if *global_controls::poly_eq_warn
#
complain err::WARNING "calling poly_equal" err::null_error_body;
fi;
end; # markexn-local
############################################################################
# Sharing and lifting of package imports and varhomes
############################################################################
exception HASHTABLE;
Key = Int;
# * hashkey of varhomepath + varhomepath + res_var
Info = (Key, List(Int), tmp::Codetemp);
my hashtable: iht::Hashtable( List( Info ) )
= iht::make_hashtable { size_hint => 32, not_found_exception => HASHTABLE };
#
fun hashkey l
=
fold_backward
(fn (x, y) = ((x * 10 + y) % 1019)) # Are we being bloody stupid yet? XXX SUCKO FIXME.
0
l;
#
fun build_header v
=
{
fold_backward h identity_fn info
where
info = iht::get hashtable v;
#
fun h ((_, l, w), header)
=
{ le = fold_forward (fn (k, e) = lcf::GET_FIELD (k, e))
(lcf::VAR v)
l;
fn e = header (lcf::LET (w, le, e));
};
end;
}
except
_ = identity_fn;
#
fun bindvar (var, [], _)
=>
var;
bindvar (var, l, name_or_null)
=>
find_or_make_var info
where
info = (iht::get hashtable var) except _ = [];
key = hashkey l;
#
fun find_or_make_var []
=>
{ var' = issue_highcode_codetemp name_or_null;
iht::set hashtable (var, (key, l, var') ! info);
var';
};
find_or_make_var ((key', l', var') ! rest)
=>
if (key' == key)
#
if (l' == l) var';
else find_or_make_var rest;
fi;
else
find_or_make_var rest;
fi;
end;
end;
end;
Picklehash_Info
= ANON List( (Int, Picklehash_Info) )
| NAMED (tmp::Codetemp, hut::Uniqtype, List( (Int, Picklehash_Info) ))
;
#
fun make_picklehash_info
( uniqtype,
l,
name_or_null
)
=
{ v = issue_highcode_codetemp name_or_null;
#
fun h [] => NAMED (v, uniqtype, []);
h (a ! r) => ANON [(a, h r)];
end;
( h l,
v
);
};
#
fun merge_picklehash_info (pi, uniqtype, l, name_or_null)
=
h (pi, l)
where
fun h (z as NAMED (v, _, _), [])
=>
(z, v);
h (ANON xl, [])
=>
{ v = issue_highcode_codetemp name_or_null;
( NAMED (v, uniqtype, xl),
v
);
};
h (z, a ! r)
=>
{ my (xl, make_node)
=
case z
#
ANON c => (c, ANON);
#
NAMED (v, uniqtype', c)
=>
( c,
fn x = NAMED (v, uniqtype', x)
);
esac;
#
fun dump ((np, v), z, y)
=
{ nz = (a, np) ! z;
( make_node ((reverse y) @ nz),
v
);
};
#
fun get ([], y)
=>
dump ( make_picklehash_info (uniqtype, r, name_or_null),
[],
y
);
get (u as ((x as (i, pi)) ! z), y)
=>
if (i < a) get (z, x ! y);
elif (i == a) dump (h (pi, r), z, y);
else dump (make_picklehash_info (uniqtype, r, name_or_null), u, y);
fi;
end;
get (xl, []);
};
end;
end; # where (fun merge_picklehash_info)
# A map that stores information
# about external references:
#
picklehash_map
=
REF (phm::empty: phm::Map( Picklehash_Info ));
#
fun make_picklehash (picklehash, t, l, name_or_null)
=
case (phm::get (*picklehash_map, picklehash))
#
NULL =>
{ (make_picklehash_info (t, l, name_or_null))
->
(picklehash_info, var);
picklehash_map
:=
phm::set
( *picklehash_map,
picklehash,
picklehash_info
);
var;
};
THE picklehash_info
=>
{ my (new_picklehash_info, var)
=
merge_picklehash_info (picklehash_info, t, l, name_or_null);
#
fun remove (key, map)
=
{ my (new_map, _) = phm::drop (map, key);
new_map;
}
except
e = map;
picklehash_map
:=
phm::set
( remove (picklehash, *picklehash_map),
picklehash,
new_picklehash_info
);
var;
};
esac;
integer_map = REF (im::empty: im::Map( tmp::Codetemp ));
#
fun get_interface_info n
=
case (im::get (*integer_map, n))
#
THE v => v;
#
NULL => { v = make_var ();
integer_map := im::set (*integer_map, n, v);
v;
};
esac;
# Convert a varhome with type into a lambda expression
#
fun translate_varhome_with_type (p, t, name_or_null)
=
lcf::VAR (h (p, []))
where
fun h (vh::HIGHCODE_VARIABLE v, l) => bindvar (v, l, name_or_null);
h (vh::EXTERN picklehash, l) => make_picklehash (picklehash, t, l, name_or_null);
h (vh::PATH (a, i), l) => h (a, i ! l);
h _ => bug "unexpected varhome in translate_varhome_with_type";
end;
end;
# Convert a varhome into a lambda expression
#
fun translate_varhome (p, name_or_null)
=
lcf::VAR (h (p, []))
where
fun h (vh::HIGHCODE_VARIABLE v, l) => bindvar (v, l, name_or_null);
h (vh::PATH (a, i), l) => h (a, i ! l);
h _ => bug "unexpected varhome in translate_varhome";
end;
end;
# These two functions are major gross hacks.
# The NO_CORE exceptions would raised when compiling the files
# src/lib/core/init/runtime.pkg,
# src/lib/core/init/runtime.api,
# boot/core.pkg
# The assumption is that the result of core_exn and core_get
# would never be used when compiling these three files.
#
# A good way to clean this up would be to put all the core constructors
# and base ops into the base ops dictionary. XXX BUGGO FIXME (ZHONG)
exception NO_CORE;
#
fun core_exn id
=
case (coa::get_constructor' (fn () = raise exception NO_CORE) (symbolmapstack, id))
#
ty::VALCON { name, form as vh::EXCEPTION _, type, ... }
=>
{ type = to_dcon_lty di::top type;
constructor_rep = make_representation (form, type, name);
con'((name, constructor_rep, type), [], void_lexp);
};
#
_ => bug "core_exn in translate";
esac
except
NO_CORE
=
{ say "WARNING: no Core access\n";
lcf::INT 0;
}
also
fun core_get id
=
case (coa::get_variable' (fn () = raise exception NO_CORE) (symbolmapstack, id))
#
vac::ORDINARY_VARIABLE { varhome, var_type, path, ... }
=>
translate_varhome_with_type ( varhome,
deepsyntax_type_to_uniqtype di::top *var_type,
get_name_or_null path
);
_ =>
bug "core_get in translate";
esac
except
NO_CORE
=
{ say ("FATAL: Unable to fetch '" + id + "' from core.pkg! -- translate-deep-syntax-to-lambdacode.pkg\n");
lcf::INT 0;
}
# Expand the flex record pattern and convert the EXCEPTION varhome pattern
# internalize the Valcon_Form's varhome, always exceptions
#
also
fun make_representation (representation, lt, name)
=
{ fun g (vh::HIGHCODE_VARIABLE v, l, t) => bindvar (v, l, THE name);
g (vh::PATH (a, i), l, t) => g (a, i ! l, t);
g (vh::EXTERN p, l, t) => make_picklehash (p, t, l, THE name);
#
g _ => bug "unexpected varhome in make_representation";
end;
case representation
#
(vh::EXCEPTION x)
=>
{ my (argt, _) = hcf::unpack_lambdacode_arrow_uniqtype lt;
#
vh::EXCEPTION ( vh::HIGHCODE_VARIABLE ( g (x, [], hcf::make_exception_tag_uniqtype argt)));
};
#
(vh::SUSPENSION NULL)
=> # A hack to support "delay-force" base ops
case (core_get "delay", core_get "force")
#
(lcf::VAR x, lcf::VAR y)
=>
vh::SUSPENSION ( THE ( vh::HIGHCODE_VARIABLE x,
vh::HIGHCODE_VARIABLE y
)
);
#
_ => bug "unexpected case on Valcon_Form SUSPENSION 1";
esac;
#
(vh::SUSPENSION (THE _))
=>
bug "unexpected case on Valcon_Form SUSPENSION 2";
_ => representation;
esac;
};
# Convert a value of varhome+info into the lambda expression
#
fun translate_varhome_info (varhome, info, get_lty, name_or_null)
=
varhome_is_external varhome ?? translate_varhome_with_type (varhome, get_lty(), name_or_null)
:: translate_varhome (varhome, name_or_null);
#
fun fill_pattern (pattern, d)
=
fill pattern
where
fun fill (ds::TYPE_CONSTRAINT_PATTERN (p, t))
=>
fill p;
fill (ds::AS_PATTERN (p, q))
=>
ds::AS_PATTERN (fill p, fill q);
fill (ds::RECORD_PATTERN { fields, is_incomplete => FALSE, type_ref } )
=>
ds::RECORD_PATTERN
{
fields => map (fn (lab, p) = (lab, fill p)) fields,
is_incomplete => FALSE,
type_ref
};
fill (pattern as ds::RECORD_PATTERN { fields, is_incomplete => TRUE, type_ref } )
=>
{ exception DONT_BOTHER;
fields' = map (fn (l, p) = (l, fill p)) fields;
#
fun find (t as ty::TYPCON_TYPE (ty::RECORD_TYP labels, _))
=>
{ type_ref := t;
labels;
};
find _ => { complain err::ERROR "unresolved flexible record"
(fn stream
=
{ pp::newline stream;
pp::string stream "pattern: ";
uds::unparse_pattern symbolmapstack stream (pattern, *global_controls::print::print_depth);
}
);
raise exception DONT_BOTHER;
};
end;
#
fun merge (a as ((id, p) ! r), lab ! s)
=>
if (sy::eq (id, lab) ) (id, p ) ! merge (r, s);
else (lab, ds::WILDCARD_PATTERN) ! merge (a, s);
fi;
merge ([], lab ! s) => (lab, ds::WILDCARD_PATTERN) ! merge([], s);
merge ([], []) => [];
merge _ => bug "merge in translate";
end;
ds::RECORD_PATTERN
{
fields => merge (fields', find (tyj::head_reduce_type *type_ref)),
is_incomplete => FALSE,
type_ref
}
except
DONT_BOTHER
=
ds::WILDCARD_PATTERN;
};
fill (ds::VECTOR_PATTERN (pats, type)) => ds::VECTOR_PATTERN (map fill pats, type);
fill (ds::OR_PATTERN (p1, p2)) => ds::OR_PATTERN (fill p1, fill p2);
fill (ds::CONSTRUCTOR_PATTERN (ty::VALCON { name, is_constant, type, is_lazy, signature, form }, ts))
=>
ds::CONSTRUCTOR_PATTERN (
#
ty::VALCON {
#
name,
is_constant,
type,
is_lazy,
signature,
form
=>
make_representation
(
form,
to_dcon_lty d type,
name
)
},
ts
);
fill (ds::APPLY_PATTERN ( ty::VALCON { name, is_constant, type, form, signature, is_lazy },
ts,
pattern
)
)
=>
ds::APPLY_PATTERN (
#
ty::VALCON {
#
name,
is_constant,
type,
signature,
is_lazy,
form
=>
make_representation
(
form,
to_dcon_lty d type,
name
)
},
ts,
fill pattern
);
fill xp
=>
xp;
end;
end; # fun fill_pattern
# The runtime polymorphic equality
# and string equality dictionary:
#
polymorphic_equality_dictionary
=
{ get_string_eq,
get_integer_eq,
get_poly_eq
}
where
my str_eq_ref: Ref( Null_Or( lcf::Lambdacode_Expression ) ) = REF NULL;
my poly_eq_ref: Ref( Null_Or( lcf::Lambdacode_Expression ) ) = REF NULL;
my integer_eq_ref: Ref( Null_Or( lcf::Lambdacode_Expression ) ) = REF NULL;
#
fun get_string_eq ()
=
case *str_eq_ref
#
THE e => e;
NULL => { e = core_get "string_equal"; # string_equal def in src/lib/core/init/core.pkg str_eq_ref := THE e;
e;
};
esac;
#
fun get_integer_eq () # same as polyeq, but silent
=
case *integer_eq_ref
#
THE e => e;
#
NULL => { e = lcf::APPLY_TYPEFUN (core_get "poly_equal", # poly_equal def in src/lib/core/init/core.pkg [deepsyntax_type_to_uniqtyp di::top bt::multiword_int_type]);
integer_eq_ref := THE e;
e;
};
esac;
#
fun get_poly_eq ()
=
{ maybe_report_use_of_poly_eq ();
case *poly_eq_ref
#
THE e => e;
#
NULL => { e = core_get "poly_equal"; # poly_equal def in src/lib/core/init/core.pkg poly_eq_ref := (THE e);
e;
};
esac;
};
end;
eq_g = peq::equal (polymorphic_equality_dictionary, symbolmapstack);
############################################################################
#
# Translating the primops; this should be moved into a separate file
# in the future. (ZHONG) XXX BUGGO FIXME
#
############################################################################
lt_tyc = hcf::make_typ_uniqtype;
lt_arrow = hcf::make_lambdacode_arrow_uniqtype;
lt_tuple = hcf::make_tuple_uniqtype;
lt_int = hcf::int_uniqtype;
lt_int1 = hcf::int1_uniqtype;
lt_bool = hcf::bool_uniqtype;
lt_void = hcf::void_uniqtype;
lt_ipair = lt_tuple [lt_int, lt_int];
lt_i32pair = lt_tuple [lt_int1, lt_int1];
#
lt_icmp = lt_arrow (lt_ipair, lt_bool);
lt_ineg = lt_arrow (lt_int, lt_int);
lt_intop = lt_arrow (lt_ipair, lt_int);
lt_voidvoid = lt_arrow (lt_void, lt_void);
my (true_dcon', false_dcon')
=
( h bt::true_dcon,
h bt::false_dcon
)
where
lt = hcf::make_lambdacode_arrow_uniqtype (hcf::void_uniqtype, hcf::bool_uniqtype); # highcode "Void -> Bool"
#
fun h (ty::VALCON { name, form, type, ... } ) # Take name and form from basetype, plug in our Void->Bool type.
=
(name, form, lt);
end;
true_lexp = lcf::CONSTRUCTOR (true_dcon', [], void_lexp);
false_lexp = lcf::CONSTRUCTOR (false_dcon', [], void_lexp);
#
fun cond (a, b, c)
=
lcf::SWITCH
( a,
bt::bool_signature,
[ (lcf::VAL_CASETAG (true_dcon', [], make_var()), b),
(lcf::VAL_CASETAG (false_dcon', [], make_var()), c)
],
NULL
);
#
fun compose_not (eq, t)
=
{ v = make_var();
argt = lt_tuple [t, t];
lcf::FN (v, argt, cond (lcf::APPLY (eq, lcf::VAR v), false_lexp, true_lexp));
};
#
fun cmp_op p = lcf::BASEOP (p, lt_icmp, []);
fun ineg_op p = lcf::BASEOP (p, lt_ineg, []);
lessu = hbo::CMP { op=>hbo::LTU, kindbits=>hbo::UNT 31 };
lt_len = hcf::make_typeagnostic_uniqtype([hcf::plaintype_uniqkind], [lt_arrow (hcf::make_typevar_i_uniqtype 0, lt_int)]);
lt_upd
=
{ x = hcf::make_ref_uniqtype (hcf::make_typevar_i_uniqtype 0);
hcf::make_typeagnostic_uniqtype([hcf::plaintype_uniqkind],
[lt_arrow (lt_tuple [x, lt_int, hcf::make_typevar_i_uniqtype 0], hcf::void_uniqtype)]);
};
#
fun len_op (tc) = lcf::BASEOP (hbo::VECTOR_LENGTH_IN_SLOTS, lt_len, [tc]);
#
fun rshift_op k = hbo::MATH { op=>hbo::RSHIFT, overflow=>FALSE, kindbits=>k };
fun rshiftl_op k = hbo::MATH { op=>hbo::RSHIFTL, overflow=>FALSE, kindbits=>k };
fun lshift_op k = hbo::MATH { op=>hbo::LSHIFT, overflow=>FALSE, kindbits=>k };
#
fun lword0 (hbo::UNT 31) => lcf::UNT 0u0;
lword0 (hbo::UNT 32) => lcf::UNT1 0u0;
#
lword0 _ => bug "unexpected case in lword0";
end;
#
fun baselt (hbo::UNT 31) => lt_int;
baselt (hbo::UNT 32) => lt_int1;
#
baselt _ => bug "unexpected case in baselt";
end;
#
fun shift_type k
=
{ element = baselt k;
tupt = lt_tuple [element, lt_int];
lt_arrow (tupt, element);
};
#
fun inline_shift (shift_op, kindbits, clear)
=
{ fun shift_limit (hbo::UNT lim) => lcf::UNT (unt::from_int lim);
shift_limit (hbo::INT lim) => lcf::UNT (unt::from_int lim); # Yes, both coded as lcf::UNT here.
#
shift_limit _ => bug "unexpected case in shift_limit";
end;
p = make_var(); vp = lcf::VAR p;
w = make_var(); vw = lcf::VAR w;
count = make_var(); vcnt = lcf::VAR count;
argt = lt_tuple [ baselt kindbits, lt_int ];
cmp_shift_amt
=
lcf::BASEOP (hbo::CMP { op=>hbo::LEU, kindbits=>hbo::UNT 31 }, lt_icmp, []);
lcf::FN # fn (w, count) = if (shift_limit(kindbits) <= count) clear w;
( # else shift_op (w, count);
p, # Arg
argt, # Arg type
lcf::LET # Body
( w,
lcf::GET_FIELD (0, vp),
lcf::LET
( count,
lcf::GET_FIELD (1, vp),
cond
( lcf::APPLY (cmp_shift_amt, lcf::RECORD [shift_limit kindbits, vcnt]),
clear vw,
lcf::APPLY
( lcf::BASEOP (shift_op kindbits, shift_type kindbits, []),
lcf::RECORD [vw, vcnt]
)
)
)
)
);
};
#
fun inline_ops nk
=
{
my (lt_arg, zero, overflow)
=
case nk # "nk" == "number kind (and bitsize)"
#
hbo::INT 31 => (hcf::int_uniqtype, lcf::INT 0, TRUE );
hbo::UNT 31 => (hcf::int_uniqtype, lcf::UNT 0u0, FALSE);
hbo::INT 32 => (hcf::int1_uniqtype, lcf::INT1 0, TRUE );
hbo::UNT 32 => (hcf::int1_uniqtype, lcf::UNT1 0u0, FALSE);
hbo::FLOAT 64 => (hcf::float64_uniqtype, lcf::FLOAT64 "0.0", FALSE);
#
_ => bug "inline_ops: bad number_kind_and_bitsize";
esac;
lt_argpair = lt_tuple [lt_arg, lt_arg];
compare_lambda_types = lt_arrow (lt_argpair, lt_bool);
lt_neg = lt_arrow (lt_arg, lt_arg);
less = lcf::BASEOP (hbo::CMP { op => hbo::LT, kindbits => nk }, compare_lambda_types, []);
greater = lcf::BASEOP (hbo::CMP { op => hbo::GT, kindbits => nk }, compare_lambda_types, []);
negate = lcf::BASEOP (hbo::MATH { op => hbo::NEGATE, kindbits => nk, overflow }, lt_neg, []);
{ lt_arg, lt_argpair, compare_lambda_types, less, greater, zero, negate };
};
#
fun inl_minmax (nk, ismax)
=
{ (inline_ops nk) -> { lt_argpair, less, greater, compare_lambda_types, ... };
x = make_var ();
y = make_var ();
z = make_var ();
cmp_op = if ismax greater;
else less;
fi;
elsebranch
=
case nk
#
hbo::FLOAT _ => {
# testing for NaN
fequal =
lcf::BASEOP (hbo::CMP { op => hbo::EQL, kindbits => nk }, compare_lambda_types, []);
cond (lcf::APPLY (fequal, lcf::RECORD [lcf::VAR y, lcf::VAR y]), lcf::VAR y, lcf::VAR x);
};
_ => lcf::VAR y;
esac;
lcf::FN (z, lt_argpair,
lcf::LET (x, lcf::GET_FIELD (0, lcf::VAR z),
lcf::LET (y, lcf::GET_FIELD (1, lcf::VAR z),
cond (lcf::APPLY (cmp_op, lcf::RECORD [lcf::VAR x, lcf::VAR y]),
lcf::VAR x, elsebranch))));
};
#
fun inl_abs nk
=
{ (inline_ops nk) -> { lt_arg, greater, zero, negate, ... };
x = make_var ();
lcf::FN (x, lt_arg,
cond (lcf::APPLY (greater, lcf::RECORD [lcf::VAR x, zero]),
lcf::VAR x, lcf::APPLY (negate, lcf::VAR x)));
};
#
fun inl_inf_prec (what, corename, p, lt, is_from_inf) # 'inf' is probably 'indefinite-precision-integer'. 'prec' is 'precision-conversion', i.e. bitwidth change.
=
{ my (orig_arg_lt, res_lt)
=
case (hcf::unpack_arrow_uniqtype lt)
#
(_, [a], [r]) => (a, r);
_ => bug ("unexpected type of " + what);
esac;
extra_arg_lt
=
hcf::make_lambdacode_arrow_uniqtype if is_from_inf (orig_arg_lt, hcf::int1_uniqtype);
else (hcf::int1_uniqtype, orig_arg_lt);
fi;
new_arg_lt = hcf::make_tuple_uniqtype [orig_arg_lt, extra_arg_lt];
new_lt = hcf::make_lambdacode_arrow_uniqtype (new_arg_lt, res_lt);
x = make_var ();
lcf::FN (x, orig_arg_lt,
lcf::APPLY (lcf::BASEOP (p, new_lt, []),
lcf::RECORD [lcf::VAR x, core_get corename]));
};
#
fun translate_baseop (baseop, lt, ts)
=
g baseop
where
fun g (hbo::LSHIFT_MACRO k) => inline_shift (lshift_op, k, fn _ = lword0 (k));
g (hbo::RSHIFTL_MACRO k) => inline_shift (rshiftl_op, k, fn _ = lword0 (k));
g (hbo::RSHIFT_MACRO k) # Preserve sign bit with arithmetic rshift
=>
inline_shift (rshift_op, k, clear)
where
fun clear w
=
lcf::APPLY (lcf::BASEOP (rshift_op k, shift_type k, []),
lcf::RECORD [w, lcf::UNT 0u31]);
end;
g (hbo::MIN_MACRO nk) => inl_minmax (nk, FALSE);
g (hbo::MAX_MACRO nk) => inl_minmax (nk, TRUE);
g (hbo::ABS_MACRO nk) => inl_abs nk;
g hbo::NOT_MACRO
=>
{ x = make_var();
lcf::FN (x, lt_bool, cond (lcf::VAR x, false_lexp, true_lexp));
};
g hbo::COMPOSE_MACRO
=>
{ my (t1, t2, t3)
=
case ts
#
[a, b, c] => ( lt_tyc a,
lt_tyc b,
lt_tyc c
);
_ => bug "unexpected type for INLCOMPOSE";
esac;
argt = lt_tuple [ lt_arrow (t2, t3),
lt_arrow (t1, t2)
];
x = make_var ();
z = make_var ();
f = make_var ();
g = make_var ();
lcf::FN (z, argt,
lcf::LET (f, lcf::GET_FIELD (0, lcf::VAR z),
lcf::LET (g, lcf::GET_FIELD (1, lcf::VAR z),
lcf::FN (x, t1, lcf::APPLY (lcf::VAR f, lcf::APPLY (lcf::VAR g, lcf::VAR x))))));
};
g hbo::BEFORE_MACRO
=>
{ my (t1, t2)
=
case ts
#
[a, b] => (lt_tyc a, lt_tyc b);
_ => bug "unexpected type for INLBEFORE";
esac;
argt = lt_tuple [t1, t2];
x = make_var();
lcf::FN (x, argt, lcf::GET_FIELD (0, lcf::VAR x));
};
g hbo::IGNORE_MACRO
=>
{ argt =
case ts
#
[a] => lt_tyc a;
_ => bug "unexpected type for INLIGNORE";
esac;
lcf::FN (make_var (), argt, void_lexp);
};
g hbo::IDENTITY_MACRO
=>
{ argt =
case ts
#
[a] => lt_tyc a;
_ => bug "unexpected type for INLIDENTITY";
esac;
v = make_var ();
lcf::FN (v, argt, lcf::VAR v);
};
g hbo::CVT64
=>
{ v = make_var ();
lcf::FN (v, lt_i32pair, lcf::VAR v);
};
g hbo::GET_RO_VECSLOT_CONTENTS_AFTER_BOUNDS_CHECK
=>
{ my (tc1, t1)
=
case ts
#
[z] => (z, lt_tyc z);
_ => bug "unexpected type for INLSUBV";
esac;
seqtc = hcf::make_ro_vector_uniqtyp tc1;
argt = lt_tuple [lt_tyc seqtc, lt_int];
op = lcf::BASEOP (hbo::GET_RW_VECSLOT_CONTENTS, lt, ts);
p = make_var ();
a = make_var ();
i = make_var ();
vp = lcf::VAR p;
va = lcf::VAR a;
vi = lcf::VAR i;
if *coc::check_vector_index_bounds
#
lcf::FN (p, argt,
lcf::LET (a, lcf::GET_FIELD (0, vp),
lcf::LET (i, lcf::GET_FIELD (1, vp),
cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op seqtc, va)]), # if i < len(v)
lcf::APPLY (op, lcf::RECORD [va, vi]), # a[i];
make_raise (core_exn "SUBSCRIPT", t1))))); # else raise exception SUBSCRIPT; fi;
else
lcf::FN (p, argt,
lcf::LET (a, lcf::GET_FIELD (0, vp),
lcf::LET (i, lcf::GET_FIELD (1, vp),
lcf::APPLY (op, lcf::RECORD [va, vi])))); # a[i];
fi;
};
g hbo::GET_RW_VECSLOT_CONTENTS_AFTER_BOUNDS_CHECK
=>
{ my (tc1, t1)
=
case ts
#
[z] => (z, lt_tyc z);
_ => bug "unexpected type for INLSUB";
esac;
seqtc = hcf::make_rw_vector_uniqtyp tc1;
argt = lt_tuple [lt_tyc seqtc, lt_int];
op = lcf::BASEOP (hbo::GET_RW_VECSLOT_CONTENTS, lt, ts);
p = make_var();
a = make_var();
i = make_var();
vp = lcf::VAR p;
va = lcf::VAR a;
vi = lcf::VAR i;
if *coc::check_vector_index_bounds
#
lcf::FN (p, argt,
lcf::LET (a, lcf::GET_FIELD (0, vp),
lcf::LET (i, lcf::GET_FIELD (1, vp),
cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op seqtc, va)]), # if i < len(v)
lcf::APPLY (op, lcf::RECORD [va, vi]), # a[i];
make_raise (core_exn "SUBSCRIPT", t1))))); # else raise exception SUBSCRIPT; fi;
else
lcf::FN (p, argt,
lcf::LET (a, lcf::GET_FIELD (0, vp),
lcf::LET (i, lcf::GET_FIELD (1, vp),
lcf::APPLY (op, lcf::RECORD [va, vi])))); # a[i];
fi;
};
g (hbo::GET_VECSLOT_NUMERIC_CONTENTS { kindbits, checked=>TRUE, immutable } )
=>
{ my (tc1, t1, t2)
=
case ts
#
[a, b] => (a, lt_tyc a, lt_tyc b);
_ => bug "unexpected type for NUMSUB";
esac;
argt = lt_tuple [t1, lt_int];
p = make_var();
a = make_var();
i = make_var();
vp = lcf::VAR p;
va = lcf::VAR a;
vi = lcf::VAR i;
op = hbo::GET_VECSLOT_NUMERIC_CONTENTS { kindbits, checked=>FALSE,
immutable };
op' = lcf::BASEOP (op, lt, ts);
if *coc::check_vector_index_bounds
#
lcf::FN (p, argt,
lcf::LET (a, lcf::GET_FIELD (0, vp),
lcf::LET (i, lcf::GET_FIELD (1, vp),
cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op tc1, va)]), # if i < len(v)
lcf::APPLY (op', lcf::RECORD [va, vi]), # a[i];
make_raise (core_exn "SUBSCRIPT", t2))))); # else raise exception SUBSCRIPT; fi;
else
lcf::FN (p, argt,
lcf::LET (a, lcf::GET_FIELD (0, vp),
lcf::LET (i, lcf::GET_FIELD (1, vp),
lcf::APPLY (op', lcf::RECORD [va, vi])))); # a[i];
fi;
};
g hbo::SET_VECSLOT_AFTER_BOUNDS_CHECK
=>
{ my (tc1, t1)
=
case ts
#
[z] => (z, lt_tyc z);
_ => bug "unexpected type for INLSUB";
esac;
seqtc = hcf::make_rw_vector_uniqtyp tc1;
argt = lt_tuple [lt_tyc seqtc, lt_int, t1];
op = lcf::BASEOP (hbo::SET_VECSLOT, lt, ts);
x = make_var();
a = make_var();
i = make_var();
v = make_var();
vx = lcf::VAR x;
va = lcf::VAR a;
vi = lcf::VAR i;
vv = lcf::VAR v;
if *coc::check_vector_index_bounds
#
lcf::FN (x, argt,
lcf::LET (a, lcf::GET_FIELD (0, vx),
lcf::LET (i, lcf::GET_FIELD (1, vx),
lcf::LET (v, lcf::GET_FIELD (2, vx),
cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op seqtc, va)]), # if i < len(v)
lcf::APPLY (op, lcf::RECORD [va, vi, vv]), # a[i] = v;
make_raise (core_exn "SUBSCRIPT", hcf::void_uniqtype)))))); # else raise exception SUBSCRIPT; fi;
else
#
lcf::FN (x, argt,
lcf::LET (a, lcf::GET_FIELD (0, vx),
lcf::LET (i, lcf::GET_FIELD (1, vx),
lcf::LET (v, lcf::GET_FIELD (2, vx),
lcf::APPLY (op, lcf::RECORD [va, vi, vv]))))); # a[i] = v;
fi;
};
g (hbo::SET_VECSLOT_TO_NUMERIC_VALUE { kindbits, checked=>TRUE } )
=>
{ my (tc1, t1, t2)
=
case ts
#
[a, b] => (a, lt_tyc a, lt_tyc b);
_ => bug "unexpected type for SET_VECSLOT_TO_NUMERIC_VALUE";
esac;
argt = lt_tuple [t1, lt_int, t2];
p = make_var();
a = make_var();
i = make_var();
v = make_var();
vp = lcf::VAR p;
va = lcf::VAR a;
vi = lcf::VAR i;
vv = lcf::VAR v;
op = hbo::SET_VECSLOT_TO_NUMERIC_VALUE { kindbits, checked=>FALSE };
op' = lcf::BASEOP (op, lt, ts);
if *coc::check_vector_index_bounds
#
lcf::FN (p, argt,
lcf::LET (a, lcf::GET_FIELD (0, vp),
lcf::LET (i, lcf::GET_FIELD (1, vp),
lcf::LET (v, lcf::GET_FIELD (2, vp),
cond (lcf::APPLY (cmp_op (lessu), lcf::RECORD [vi, lcf::APPLY (len_op tc1, va)]), # if i < len(v)
lcf::APPLY (op', lcf::RECORD [va, vi, vv]), # a[i] = v;
make_raise (core_exn "SUBSCRIPT", hcf::void_uniqtype)))))); # else raise exception SUBSCRIPT; fi;
else
lcf::FN (p, argt,
lcf::LET (a, lcf::GET_FIELD (0, vp),
lcf::LET (i, lcf::GET_FIELD (1, vp),
lcf::LET (v, lcf::GET_FIELD (2, vp),
lcf::APPLY (op', lcf::RECORD [va, vi, vv]))))); # a[i] = v;
fi;
};
/**** ASSIGN (r, x) != UPDATE (r, 0, x) under new rw_vector reps (John H Reppy;1998-10-30)
| g (hbo::SET_REFCELL) =
let my (tc1, t1) = case ts of [z] => (z, lt_tyc z)
| _ => bug "unexpected type for ASSIGN"
seqtc = hcf::make_ref_uniqtyp tc1
argt = lt_tuple [lt_tyc seqtc, t1]
op = lcf::BASEOP (hbo::SET_VECSLOT, lt_upd, [tc1])
x = make_var()
varX = lcf::VAR x
in lcf::FN (x, argt,
lcf::APPLY (op, lcf::RECORD [lcf::GET_FIELD (0, varX), lcf::INT 0, lcf::GET_FIELD (1, varX)]))
end
****/
# Precision-conversion operations involving integer.
# These need to be translated specially by providing
# a second argument -- the routine from _Core that
# does the actual conversion to or from integer.
g (p as hbo::SHRINK_INTEGER prec)
=>
inl_inf_prec ("TEST_INF", "test_inf", p, lt, TRUE);
g (p as hbo::CHOP_INTEGER prec)
=>
inl_inf_prec ("TRUNC_INF", "trunc_inf", p, lt, TRUE);
g (p as hbo::STRETCH_TO_INTEGER prec)
=>
inl_inf_prec ("EXTEND_INF", "fin_to_inf", p, lt, FALSE);
g (p as hbo::COPY_TO_INTEGER prec)
=>
inl_inf_prec ("COPY", "fin_to_inf", p, lt, FALSE);
# Default handling for all other
# base operations:
#
g baseop
=>
lcf::BASEOP (baseop, lt, ts);
end;
end; # where (fun translate_baseop)
#
fun make_integer_switch (sv, cases, default)
=
{ v = make_var ();
# Build a chain of equality tests
# for checking large pattern values
#
fun build []
=>
default;
build ((n, e) ! r)
=>
cond ( lcf::APPLY ( polymorphic_equality_dictionary.get_integer_eq (),
lcf::RECORD [lcf::VAR v, lcf::VAR (get_interface_info n)]
),
e,
build r
);
end;
# Split pattern values into small values and large values.
# Small values can be handled directly using SWITCH:
#
fun split ([], s, l)
=>
(reverse s, reverse l);
split ((n, e) ! r, sm, lg)
=>
case (ln::low_val n)
#
THE l => split (r, (lcf::INT_CASETAG l, e) ! sm, lg);
NULL => split (r, sm, (n, e) ! lg);
esac;
end;
#
fun gen ()
=
case (split (cases, [], []))
#
([], largeints)
=>
build largeints;
(smallints, largeints)
=>
{ iv = make_var ();
lcf::LET
( iv,
lcf::APPLY (core_get "inf_low_value", lcf::VAR v),
lcf::SWITCH
(
lcf::VAR iv,
vh::NULLARY_CONSTRUCTOR,
smallints,
THE (build largeints)
)
);
};
esac;
lcf::LET (v, sv, gen ());
};
##########################################################################################
#
# Translation of various namings into lambda expressions:
#
# translate_variable: (vac::Variable, di::Debruijn_Depth) -> lcf::Lambdacode_Expression
# mkVE: (vac::var, List( t::Type )) -> lcf::Lambdacode_Expression
# mkCE: ( t::Constructor,
# List( t::Type ),
# Null_Or( lcf::Lambdacode_Expression ),
# di::Debruijn_Depth
# )
# -> l::Lambdacode_Expression
# translate_package: (mld::Package, di::Debruijn_Depth) -> lcf::Lambdacode_Expression
# translate_generic: (mld::Generic, di::Debruijn_Depth) -> lcf::Lambdacode_Expression
# translate_symbolmapstack_entry: di::Debruijn_Depth -> sxe::naming -> lcf::Lambdacode_Expression
#
##########################################################################################
fun translate_variable
( (v as vac::ORDINARY_VARIABLE { varhome, inlining_data, var_type, path }): vac::Variable,
debruijn_depth: di::Debruijn_Depth
)
: lcf::Lambdacode_Expression
=>
translate_varhome_info
(
varhome,
inlining_data,
fn () = deepsyntax_type_to_uniqtype debruijn_depth *var_type,
get_name_or_null path
);
translate_variable _
=>
bug "unexpected vars in makeVariable";
end;
#
fun translate_variable_in_expression (v, ts, d)
=
{ fun otherwise ()
=
case ts
#
[] => translate_variable (v, d);
_ => lcf::APPLY_TYPEFUN (translate_variable (v, d), map (deepsyntax_type_to_uniqtyp d) ts);
esac;
case v
#
vac::ORDINARY_VARIABLE { inlining_data, ... }
=>
ij::case_inlining_data inlining_data
{
do_inline_package => fn _ = otherwise (),
do_inline_nothing => fn () = otherwise (),
do_inline_baseop
=>
fn ( baseop: hbo::Baseop,
type
)
=
case (baseop, ts)
#
(hbo::POLY_EQL, [t])
=>
eq_g (type, t, to_tc_lt d);
(hbo::POLY_NEQ, [t])
=>
compose_not (eq_g (type, t, to_tc_lt d), deepsyntax_type_to_uniqtype d t);
(hbo::MAKE_RW_VECTOR_MACRO, [t])
=>
{ dictionary =
{ default => core_get "make_vector", # make_vector def in src/lib/core/init/core.pkg table => [ ([hcf::float64_uniqtyp], core_get "make_float_vector") ] # make_float_vector def in src/lib/core/init/core.pkg };
lcf::GENOP (
dictionary,
baseop,
deepsyntax_type_to_uniqtype d type,
map (deepsyntax_type_to_uniqtyp d) ts
);
};
(hbo::RAW_CCALL NULL, [a, b, c])
=>
{ i = THE (cprototype::decode ansi_c_prototype_convention
{ function_type => a, encoding => b }
)
except
cprototype::BAD_ENCODING = NULL;
lcf::BASEOP (
hbo::RAW_CCALL i,
deepsyntax_type_to_uniqtype d type,
map (deepsyntax_type_to_uniqtyp d) ts
);
};
_ =>
translate_baseop
(
baseop,
(deepsyntax_type_to_uniqtype d type),
map (deepsyntax_type_to_uniqtyp d) ts
);
esac
};
_ =>
otherwise ();
esac;
};
#
fun translate_constructor_expression (ty::VALCON { is_constant, form, name, type, ... }, ts, ap_op, d)
=
{ lt = to_dcon_lty d type;
form' = make_representation (form, lt, name);
dc = (name, form', lt);
ts' = map (deepsyntax_type_to_uniqtyp d) ts;
if is_constant
#
con'(dc, ts', void_lexp);
else
case ap_op
#
THE le => con'(dc, ts', le);
NULL =>
{ my (arg_t, _) = hcf::unpack_lambdacode_arrow_uniqtype (hcf::apply_typeagnostic_type_to_arglist_with_single_result (lt, ts'));
v = make_var ();
lcf::FN (v, arg_t, con'(dc, ts', lcf::VAR v));
};
esac;
fi;
};
#
fun translate_package (s as mld::A_PACKAGE { varhome, inlining_data=>info, ... }, d)
=>
translate_varhome_info
(
varhome,
info,
fn () = deepsyntax_package_to_uniqtype (s, d, per_compile_info),
NULL
);
translate_package _ => bug "unexpected packages in translate_package";
end;
#
fun translate_generic (f as mld::GENERIC { varhome, inlining_data=>info, ... }, d)
=>
translate_varhome_info
(
varhome,
info,
fn () = deepsyntax_generic_package_to_uniqtype (f, d, per_compile_info),
NULL
);
translate_generic _ => bug "unexpected generics in translate_generic";
end;
#
fun translate_symbolmapstack_entry
(debruijn_depth: di::Debruijn_Depth)
: (sxe::Symbolmapstack_Entry -> lcf::Lambdacode_Expression)
=
g
where
fun g (sxe::NAMED_VARIABLE v) => translate_variable (v, debruijn_depth);
g (sxe::NAMED_PACKAGE s) => translate_package (s, debruijn_depth);
g (sxe::NAMED_GENERIC f) => translate_generic (f, debruijn_depth);
g (sxe::NAMED_CONSTRUCTOR (ty::VALCON { form=> vh::EXCEPTION acc, name, type, ... } ))
=>
{ nt = to_dcon_lty debruijn_depth type;
my (argt, _) = hcf::unpack_lambdacode_arrow_uniqtype nt;
translate_varhome_with_type (acc, hcf::make_exception_tag_uniqtype argt, THE name);
};
g _ => bug "unexpected namings in translate_symbolmapstack_entry";
end;
end;
#################################################################################
#
# Translate core deep_syntax_tree declarations into lambda expressions:
#
# my translate_named_values: List( ds::Named_Value )
# * depth
# -> lcf::Lambdacode_Expression
# -> lcf::Lambdacode_Expression
#
# my translate_named_recursive_values
# :
# (List( ds::Named_Recursive_Values ) * )
# -> lcf::Lambdacode_Expression
# -> lcf::Lambdacode_Expression
#
# my translate_exception_declarations: List( ds::eb )
# * depth
# -> lcf::Lambdacode_Expression
# -> lcf::Lambdacode_Expression
#
#################################################################################
# lambdacode_form is from src/lib/compiler/back/top/lambdacode/lambdacode-form.pkg # deep_syntax is from src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.pkg/*x*/ fun translate_pattern_expression (expression, d, [], callstack)
=>
{
if *debugging
print_callstack "\n============= translate_pattern_expression/TOP ============= " callstack;
if_debugging_unparse_expression ("translate_pattern_expression input expression argument:", (expression,100));
printf "translate_pattern_expression bound_typevar_refs argument has 0 entries so calling translate_expression instead of translate_pattern-expression.\n";
fi;
result = translate_deep_syntax_expression_to_lambdacode (expression, d, "translate_pattern_expression" ! callstack );
if *debugging
printf "translate_pattern_expression/BOTTOM in translate-deep-syntax-to-lambdacode.pkg\n";
fi;
result;
};
/*x*/ translate_pattern_expression
/*x*/ ( expression: ds::Deep_Expression,
/*x*/ debruijn_depth: di::Debruijn_Depth,
/*x*/ bound_typevar_refs: List( types::Typevar_Ref ), # From a deep syntax NAMED_VALUE or NAMED_RECURSIVE_VALUES record.
/*x*/ callstack: List( String )
/*x*/ )
/*x*/ : lcf::Lambdacode_Expression
/*x*/ =>
/*x*/ {
if *debugging
print_callstack "\n============= translate_pattern_expression/TOP ============= " callstack;
if_debugging_unparse_expression ("translate_pattern_expression input expression argument:", (expression,100));
printf "translate_pattern_expression bound_typevar_refs argument has %d entries:\n" (length bound_typevar_refs);
apply unparse bound_typevar_refs
where
fun unparse typevar_ref
=
if_debugging_unparse_typevar_ref ("", typevar_ref);
end;
printf "\n";
fi;
/*x*/ bound_typevar_refs'
/*x*/ =
/*x*/ map f bound_typevar_refs
/*x*/ where
/*x*/ fun f { id, ref_typevar }
/*x*/ =
/*x*/ ref_typevar;
/*x*/ end;
/*x*/ old_bound_typevar_refs_values
/*x*/ =
/*x*/ map (*_) bound_typevar_refs';
# translate_types is from src/lib/compiler/back/top/translate/translate-deep-syntax-types-to-lambdacode.pkg # Assign TYPE_VARIABLE_MARK type_variables.
# We will erase these before we return.
#
# These TYPE_VARIABLE_MARK values are only
# used in translate_deep_syntax_types_to_lambdacode::deepsyntax_type_to_uniqtyp():
#
# "We have implemented a "minimum typing derivation" phase in our compiler to give
# all local variables "least" polymorphic types. The derivation is done after [typechecking]
# so that is it only applied to type-correct programs. Our algoirthm, which is similar
# to Bjorner's algorithm M, does a bottom-up traversal of the [deep syntax].
# During the traversal, we mark all variables which are local (e.g. let-bound)
# or hidden because of signature matching. For each marked polymorphic variable v
# we gather all of its actual type instantiations and reassign v a new type -- the
# lead general type scheme that generalizes [its instantiations]. The new type is
# then propagated into v's declaration d, constraining other variables referenced by d."
#
# -- p33, "Compiling Standard ML For Efficient Execution on Modern Machines"
# http://flint.cs.yale.edu/flint/publications/zsh-thesis.pdf
#
/*x*/ g (0, bound_typevar_refs)
where
fun g (i, [])
=>
();
/*x*/ g (i, { id, ref_typevar as REF (ty::META_TYPE_VARIABLE _ | ty::INCOMPLETE_RECORD_TYPE_VARIABLE _) } ! rest)
/*x*/ =>
/*x*/ { m = mark_letbound_typevar (debruijn_depth, i); # This is the only call to mark_letbound_typevar in the compiler.
if *debugging
printf "Setting [id%d]typevar_ref to (TYPE_VARIABLE_MARK (mark_letbound_typevar (d==%d, i==%d))): g() in translate_pattern_expression() in translate_deep_syntax_to_lambdacode\n" id (di::dp_toint debruijn_depth) i;
fi;
/*x*/ ref_typevar := ty::TYPE_VARIABLE_MARK m; # This is the only place TYPE_VARIABLE_MARK are created.
/*x*/ g (i+1, rest);
};
# 2009-06-01 CrT: In the parent SML/NJ compiler this case cannot happen.
# When I added OOP support, in particular generalizing mutually recursive
# functions, it became possible, but so far as I can see it is harmless,
# so now we just ignore this case:
#
/*x*/ g (i, ( typevar_ref as { id, ref_typevar as REF (ty::TYPE_VARIABLE_MARK _) } ) ! result)
/*x*/ =>
{ if *debugging
printf "Ignoring the fact that [id%d]typevar_ref is already set to (TYPE_VARIABLE_MARK (i d==%d) translate_deep_syntax_to_lambdacode\n" id i;
fi;
/*x*/ # bug (sprintf "unexpected [id%d]type_variable TYPE_VARIABLE_MARK in translate_pattern_expression i d=%d" id i);
/*x*/ ();
};
g _ => bug "unexpected type_variable MACRO_EXPANDED in translate_pattern_expression";
end;
end;
/*x*/ expression' = translate_deep_syntax_expression_to_lambdacode (expression, di::next debruijn_depth, "translate_pattern_expression" ! callstack);
if *debugging
printf "translate_pattern_expression/BBB in translate-deep-syntax-to-lambdacode.pkg\n";
fi;
# Set all bound_typevar_refs
# back to their original value:
#
restore (bound_typevar_refs', old_bound_typevar_refs_values)
where
fun restore ([], [])
=>
();
restore
( ref_typevar ! ref_typevars,
old_value ! old_values
)
=>
{ ref_typevar := old_value;
restore (ref_typevars, old_values);
};
restore _
=>
bug "unexpected cases in translate_pattern_expression";
end;
end;
len = length bound_typevar_refs';
if *debugging
printf "translate_pattern_expression/BOTTOM in translate-deep-syntax-to-lambdacode.pkg\n";
printf "translate_pattern_expression bound_typevar_refs argument %d entries restored:\n" (length bound_typevar_refs);
apply unparse bound_typevar_refs
where
fun unparse typevar_ref
=
if_debugging_unparse_typevar_ref ("", typevar_ref);
end;
fi;
lcf::TYPEFUN (hcf::n_plaintype_uniqkinds len, expression');
};
end
also
/*x*/ fun translate_named_values
/*x*/ ( named_values: List( ds::Named_Value ), # Obtained from a ds::VALUE_DECLARATIONS
/*x*/ debruijn_depth: di::Debruijn_Depth,
/*x*/ callstack: List( String )
/*x*/ )
/*x*/ : (lcf::Lambdacode_Expression -> lcf::Lambdacode_Expression)
/*x*/ =
/*x*/ {
if *debugging print_callstack "\n============= translate_named_values/TOP ============= " callstack; fi;
/*x*/ result = fold g named_values;
if *debugging print_callstack "\n============= translate_named_values/BOTTOM ============= " callstack; fi;
/*x*/ result;
/*x*/ }
where
fun eq_tvs ([], []) # "tvs" == "type variables"
=>
TRUE;
eq_tvs (a ! r, (ty::TYPE_VARIABLE_REF b) ! s)
=>
if (a==b) eq_tvs (r, s);
else FALSE;
fi;
eq_tvs _
=>
FALSE;
end;
/*x*/ fun g named_value
/*x*/ =
/*x*/ {
if *debugging printf "\ntranslate_named_values/LOOP TOP\n"; fi;
/*x*/ result = g' named_value;
if *debugging printf "\ntranslate_named_values/LOOP BOTTOM\n"; fi;
/*x*/ result;
/*x*/ }
also
fun g' ( ds::NAMED_VALUE
{
pattern => ds::VARIABLE_IN_PATTERN (vac::ORDINARY_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, ... } ),
expression as ds::VARIABLE_IN_EXPRESSION (REF (w as (vac::ORDINARY_VARIABLE _)), instys),
bound_typevar_refs,
...
},
fold_result_so_far
)
=>
if (eq_tvs (bound_typevar_refs, instys))
if *debugging printf "\nCALLING translate_variable: g()/NAMED_VALUE I in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
result = lcf::LET (v, translate_variable (w, debruijn_depth), fold_result_so_far);
if *debugging printf "\nCALLED translate_variable: g()/NAMED_VALUE I in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
result;
else
if *debugging printf "\nCALLING translate_pattern_expression: g()/NAMED_VALUE I in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
result = lcf::LET (v, translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_named_values/g/NAMED_VALUE" ! callstack), fold_result_so_far);
if *debugging printf "CALLED translate_pattern_expression: g()/NAMED_VALUE I in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
result;
fi;
/*x*/ g' ( ds::NAMED_VALUE { pattern as ds::VARIABLE_IN_PATTERN (vac::ORDINARY_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, ... } ),
/*x*/ expression,
/*x*/ bound_typevar_refs,
/*x*/ ...
/*x*/ },
/*x*/ fold_result_so_far
/*x*/ )
/*x*/ =>
/*x*/ {
if *debugging print_callstack "\n============= translate_named_values/g()/NAMED_VALUE II/TOP ============= " callstack; fi;
if_debugging_unparse_expression ("\nexpression:", (expression,100));
if_debugging_unparse_pattern ("\npattern:", (pattern, 100));
if *debugging
printf "\nbound_typevar_refs (%d entries):\n" (length bound_typevar_refs);
apply unparse bound_typevar_refs
where
fun unparse typevar_ref
=
if_debugging_unparse_typevar_ref ("", typevar_ref);
end;
printf "\n";
fi;
if_debugging_prettyprint_expression ("\nexpression:", (expression,100));
if_debugging_prettyprint_pattern ("\npattern:", (pattern, 100));
if *debugging printf "\nCALLING translate_pattern_expression: g()/NAMED_VALUE II in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
/*x*/ result = lcf::LET (v, translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_named_values.g/NAMED_VALUE II" ! callstack), fold_result_so_far);
if *debugging printf "CALLED translate_pattern_expression: g()/NAMED_VALUE II in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
if *debugging print_callstack "\n============= translate_named_values/g()/NAMED_VALUE II/BOTTOM ============= " callstack; fi;
/*x*/ result;
};
g' ( ds::NAMED_VALUE { pattern => ds::TYPE_CONSTRAINT_PATTERN (ds::VARIABLE_IN_PATTERN (vac::ORDINARY_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, ... } ), _),
expression,
bound_typevar_refs,
...
},
fold_result_so_far
)
=>
{
if *debugging printf "\nCALLING translate_pattern_expression: g()/NAMED_VALUE III (type-constrained variable) in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
result = lcf::LET (v, translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_named_values.g/NAMED_VALUE III" ! callstack), fold_result_so_far);
if *debugging printf "CALLED translate_pattern_expression: g()/NAMED_VALUE III (type-constrained variable) in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
result;
};
g' ( ds::NAMED_VALUE { pattern, expression, bound_typevar_refs, ... },
fold_result_so_far
)
=>
{
if *debugging printf "\nCALLING translate_pattern_expression: g()/NAMED_VALUE IV (type-constrained variable) in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
ee = translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_pattern_expression.g/NAMED_VALUE IV" ! callstack);
if *debugging printf "CALLED translate_pattern_expression: g()/NAMED_VALUE IV (type-constrained variable) in translate_named_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
rules = [ (fill_pattern (pattern, debruijn_depth), fold_result_so_far),
(ds::WILDCARD_PATTERN, void_lexp)
];
root_var = make_var();
#
fun finish x
=
lcf::LET (root_var, ee, x);
mc::compile_naming_pattern (
symbolmapstack,
rules,
finish,
root_var,
to_tc_lt debruijn_depth,
complain,
make_integer_switch
);
};
end;
end # where (fun translate_named_values)
also
fun translate_named_recursive_values (rvbs, debruijn_depth, callstack)
=
{
if *debugging print_callstack "\n============= translate_named_recursive_values/TOP ============= " callstack; fi;
result = fn (b: lcf::Lambdacode_Expression) = lcf::MUTUALLY_RECURSIVE_FNS (vlist, tlist, elist, b);
if *debugging print_callstack "\n============= translate_named_recursive_values/BOTTOM ============= " callstack; fi;
result;
}
where
my (vlist, tlist, elist)
=
fold_backward g ([], [], []) rvbs
where
fun g ( ds::NAMED_RECURSIVE_VALUES
{ variable => vac::ORDINARY_VARIABLE { varhome=>vh::HIGHCODE_VARIABLE v, var_type => REF type, ... },
expression,
bound_typevar_refs,
...
},
(vlist, tlist, elist)
)
=>
# { ee = translate_expression (expression, debruijn_depth); # was translate_pattern_expression (expression, debruijn_depth, tvs)
# # we no longer track type namings at NAMED_RECURSIVE_VALUES anymore !
{
if *debugging printf "\nCALLING translate_pattern_expression: g() in translate_named_recursive_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
ee = translate_pattern_expression (expression, debruijn_depth, bound_typevar_refs, "translate_named_recursive_values" ! callstack); # Restored old code 2009-04-25 CrT
if *debugging printf "CALLED translate_pattern_expression: g() in translate_named_recursive_values in translate-deep-syntax-to-lambdacode.pkg\n"; fi;
vt = deepsyntax_type_to_uniqtype debruijn_depth type;
( v ! vlist,
vt ! tlist,
ee ! elist
);
};
g _ => bug "unexpected valrec namings in makeRecursiveValueNamings";
end;
end;
end
also
fun translate_exception_declarations (ebs, debruijn_depth, callstack)
=
fold g ebs
where
fun g ( ds::NAMED_EXCEPTION {
exception_constructor => ty::VALCON {
form => vh::EXCEPTION (vh::HIGHCODE_VARIABLE v),
type,
...
},
name_string => ident,
...
},
b
)
=>
{ nt = to_dcon_lty debruijn_depth type;
my (argt, _) = hcf::unpack_lambdacode_arrow_uniqtype nt;
lcf::LET ( v,
lcf::EXCEPTION_TAG
( translate_deep_syntax_expression_to_lambdacode
( ident,
debruijn_depth,
"translate_exception_declarations" ! callstack
),
argt
),
b
);
};
g ( ds::DUPLICATE_NAMED_EXCEPTION {
exception_constructor => ty::VALCON {
form => vh::EXCEPTION (vh::HIGHCODE_VARIABLE v),
type,
name,
...
},
equal_to => ty::VALCON { form=>vh::EXCEPTION acc, ... }
},
b
)
=>
{ nt = to_dcon_lty debruijn_depth type;
my (argt, _) = hcf::unpack_lambdacode_arrow_uniqtype nt;
lcf::LET (v, translate_varhome_with_type (acc, hcf::make_exception_tag_uniqtype argt, THE name), b);
};
g _ => bug "unexpected exn namings in makeExceptionNamings";
end;
end
###########################################################################
#
# Translating module exprs and decls into lambda expressions:
#
# translate_package_expression
# :
# (ds::Package_Expression, depth)
# -> lcf::Lambdacode_Expression
#
# translate_generic_expression
# :
# (ds::Generic_Expression, depth)
# -> lcf::Lambdacode_Expression
#
# translate_package_declarations
# :
# (List( ds::Named_Package ), depth)
# -> lcf::Lambdacode_Expression
# -> lcf::Lambdacode_Expression
#
# translate_generic_namings
# :
# (List( ds::Named_Generic ), depth)
# -> lcf::Lambdacode_Expression
# -> lcf::Lambdacode_Expression
#
###########################################################################
/*x*/ also
/*x*/ fun translate_package_expression (package_expression, debruijn_depth, callstack)
=
g package_expression
where
fun g (ds::PACKAGE_BY_NAME a_package)
=>
translate_package (a_package, debruijn_depth);
g (ds::PACKAGE_DEFINITION bs)
=>
lcf::PACKAGE_RECORD
(map (translate_symbolmapstack_entry debruijn_depth)
bs
);
g (ds::COMPUTED_PACKAGE { a_generic=>op, generic_argument=>arg, parameter_types } )
=>
{ e1 = translate_generic (op, debruijn_depth);
typs = map (deepsyntax_typpath_to_uniqtyp debruijn_depth) parameter_types;
e2 = translate_package (arg, debruijn_depth);
lcf::APPLY (lcf::APPLY_TYPEFUN (e1, typs), e2);
};
/*x*/ g (ds::PACKAGE_LET { declaration, expression })
/*x*/ =>
/*x*/ translate_deep_syntax_to_lambdacode'
/*x*/ (declaration, debruijn_depth, "translate_package_expression" ! callstack)
/*x*/ (g expression);
g (ds::SOURCE_CODE_REGION_FOR_PACKAGE (b, reg))
=>
with_region reg g b;
end;
end
also
fun translate_generic_expression (fe, debruijn_depth, callstack)
=
g fe
where
fun g (ds::GENERIC_BY_NAME f)
=>
translate_generic (f, debruijn_depth);
g (ds::GENERIC_DEFINITION { parameter as mld::A_PACKAGE { varhome, ... }, parameter_types, definition=>def } )
=>
case varhome
#
vh::HIGHCODE_VARIABLE v
=>
{ knds = map deepsyntax_typpath_to_uniqkind parameter_types;
new_depth = di::next debruijn_depth;
body = translate_package_expression (def, new_depth, "translate_generic_expression" ! callstack);
header = build_header v;
# Naming of all v's components
lcf::TYPEFUN (knds, lcf::FN (v, deepsyntax_package_to_uniqtype (parameter, new_depth, per_compile_info), header body));
};
_ => bug "translate_generic_expression: unexpected varhome";
esac;
g (ds::GENERIC_LET (declaration, b))
=>
translate_deep_syntax_to_lambdacode'
( declaration,
debruijn_depth,
"translate_generic_expression" ! callstack
)
(g b);
g (ds::SOURCE_CODE_REGION_FOR_GENERIC (b, reg))
=>
with_region reg g b;
g _ => bug "unexpected generic package expressions in translate_generic_expression";
end;
end
also
/*x*/ fun translate_package_declarations (sbs, debruijn_depth, callstack)
=
/*x*/ fold g sbs
where
/*x*/ fun g (ds::NAMED_PACKAGE { a_package=>mld::A_PACKAGE { varhome, ... }, definition, ... }, b)
=>
case varhome
#
/*x*/ vh::HIGHCODE_VARIABLE v
/*x*/ =>
/*x*/ { header = build_header v; # Naming of all v's components
/*x*/ #
/*x*/ lcf::LET (v, translate_package_expression (definition, debruijn_depth, "translate_package_declarations" ! callstack), header b);
/*x*/ };
_ =>
bug "translate_package_declarations: unexpected varhome";
esac;
g _ => bug "unexpected package namings in translate_package_declarations";
end;
end
also
fun translate_generic_namings (fbs, debruijn_depth, callstack)
=
fold g fbs
where
fun g (ds::NAMED_GENERIC { a_generic=>mld::GENERIC { varhome, ... }, definition=>def, ... }, b)
=>
case varhome
#
vh::HIGHCODE_VARIABLE v
=>
{ header = build_header v;
lcf::LET (v, translate_generic_expression (def, debruijn_depth, "translate_generic_namings" ! callstack), header b);
};
_ =>
bug "translate_generic_namings: unexpected varhome";
esac;
g _ => bug "unexpected generic package namings in translate_package_declarations";
end;
end
also
/*x*/ fun translate_deep_syntax_to_lambdacode'
/*x*/ ( declaration: ds::Declaration,
/*x*/ debruijn_depth: di::Debruijn_Depth,
/*x*/ callstack: List( String )
/*x*/ )
/*x*/ : (lcf::Lambdacode_Expression -> lcf::Lambdacode_Expression)
/*x*/ =
/*x*/ g declaration
where
fun g (ds::VALUE_DECLARATIONS vbs) => translate_named_values ( vbs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);
g (ds::RECURSIVE_VALUE_DECLARATIONS rvbs) => translate_named_recursive_values (rvbs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);
g (ds::ABSTRACT_TYPE_DECLARATION { body, ... } ) => g body;
g (ds::EXCEPTION_DECLARATIONS ebs) => translate_exception_declarations (ebs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);
/*x*/ g (ds::PACKAGE_DECLARATIONS sbs) => translate_package_declarations (sbs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);
g (ds::GENERIC_DECLARATIONS fbs) => translate_generic_namings (fbs, debruijn_depth, "translate_deep_syntax_to_lambdacode'/g" ! callstack);
g (ds::LOCAL_DECLARATIONS (ld, vd)) => (g ld) o (g vd);
g (ds::SEQUENTIAL_DECLARATIONS ds) => fold_backward (o) identity_fn (map g ds);
g (ds::SOURCE_CODE_REGION_FOR_DECLARATION (x, reg))
=>
{ f = with_region reg g x;
fn y = with_region reg f y;
};
g (ds::INCLUDE_DECLARATIONS xs)
=>
{ # Special hack to make the include tree simpler:
#
apply mkos xs
where
fun mkos (_, s as mld::A_PACKAGE { varhome, ... } )
=>
if (varhome_is_external varhome)
#
translate_varhome_with_type (varhome, deepsyntax_package_to_uniqtype (s, debruijn_depth, per_compile_info), NULL);
();
fi;
#
mkos _ => ();
end;
end;
identity_fn;
};
g _ => identity_fn;
end;
end
also
/*x*/ fun translate_deep_syntax_expression_to_lambdacode
/*x*/ ( expression: ds::Deep_Expression,
/*x*/ debruijn_depth: di::Debruijn_Depth,
/*x*/ callstack: List( String )
/*x*/ )
/*x*/ : lcf::Lambdacode_Expression
/*x*/ =
/*x*/ {
/*x*/ result = translate_deep_syntax_expression_to_lambdacode' expression;
if *debugging
print_callstack "\n============= translate_deep_syntax_expression_to_lambdacode/BOTTOM ============= " callstack;
fi;
result;
}
where
if *debugging
print_callstack "\n============= translate_deep_syntax_expression_to_lambdacode/TOP ============= " callstack;
if_debugging_unparse_expression ("translate_deep_syntax_expression_to_lambdacode input expression argument:", (expression,100));
fi;
t_typ = deepsyntax_type_to_uniqtyp debruijn_depth;
t_lty = deepsyntax_type_to_uniqtype debruijn_depth;
#
fun make_rules xs
=
map (fn (ds::CASE_RULE (p, e)) = (fill_pattern (p, debruijn_depth), translate_deep_syntax_expression_to_lambdacode' e))
xs
also
/*x*/ fun translate_deep_syntax_expression_to_lambdacode' expression
=
{
if *debugging
print_callstack "\n============= translate_deep_syntax_expression_to_lambdacode'/TOP ============= " callstack;
if_debugging_unparse_expression ("translate_deep_syntax_expression_to_lambdacode' input expression argument:", (expression,100));
fi;
/*x*/ result = translate_deep_syntax_expression_to_lambdacode'' expression;
if *debugging
print_callstack "\n============= translate_deep_syntax_expression_to_lambdacode'/BOTTOM ============= " callstack;
fi;
result;
}
where
fun translate_deep_syntax_expression_to_lambdacode'' (ds::VARIABLE_IN_EXPRESSION (REF v, ts))
=>
translate_variable_in_expression (v, ts, debruijn_depth);
translate_deep_syntax_expression_to_lambdacode'' (ds::VALCON_IN_EXPRESSION (dc, ts))
=>
translate_constructor_expression (dc, ts, NULL, debruijn_depth);
translate_deep_syntax_expression_to_lambdacode'' (ds::APPLY_EXPRESSION (ds::VALCON_IN_EXPRESSION (dc, ts), e2))
=>
translate_constructor_expression (dc, ts, THE (translate_deep_syntax_expression_to_lambdacode' e2), debruijn_depth);
translate_deep_syntax_expression_to_lambdacode'' (ds::INT_CONSTANT_IN_EXPRESSION (s, t))
=>
if (tyj::types_are_equal (t, bt::int_type )) lcf::INT (ln::int s);
elif (tyj::types_are_equal (t, bt::int1_type )) lcf::INT1 (ln::one_word_int s);
elif (tyj::types_are_equal (t, bt::multiword_int_type)) lcf::VAR (get_interface_info s);
elif (tyj::types_are_equal (t, bt::int2_type ))
my (hi, lo) = ln::two_word_int s;
lcf::RECORD [lcf::UNT1 hi, lcf::UNT1 lo];
else
bug "translate INT_CONSTANT_IN_EXPRESSION";
fi
except
OVERFLOW = { rep_err "int constant too large";
lcf::INT 0;
};
translate_deep_syntax_expression_to_lambdacode'' (ds::UNT_CONSTANT_IN_EXPRESSION (s, t))
=>
if (tyj::types_are_equal (t, bt::unt_type )) lcf::UNT (ln::unt s);
elif (tyj::types_are_equal (t, bt::unt8_type )) lcf::UNT (ln::one_byte_unt s);
elif (tyj::types_are_equal (t, bt::unt1_type)) lcf::UNT1 (ln::one_word_unt s);
elif (tyj::types_are_equal (t, bt::unt2_type))
(ln::two_word_unt s) -> (hi, lo);
lcf::RECORD [lcf::UNT1 hi, lcf::UNT1 lo];
else
prettyprint_type t;
bug "translate UNT_CONSTANT_IN_EXPRESSION";
fi
except
OVERFLOW = { rep_err "word constant too large"; lcf::INT 0;};
translate_deep_syntax_expression_to_lambdacode'' (ds::FLOAT_CONSTANT_IN_EXPRESSION s)
=>
lcf::FLOAT64 s;
translate_deep_syntax_expression_to_lambdacode'' (ds::STRING_CONSTANT_IN_EXPRESSION s)
=>
lcf::STRING s;
translate_deep_syntax_expression_to_lambdacode'' (ds::CHAR_CONSTANT_IN_EXPRESSION s)
=>
lcf::INT (char::to_int (string::get (s, 0)));
# NOTE: the above won't work for cross compiling to
# multi-byte characters XXX BUGGO FIXME
translate_deep_syntax_expression_to_lambdacode'' (ds::RECORD_IN_EXPRESSION [])
=>
void_lexp;
translate_deep_syntax_expression_to_lambdacode'' (ds::RECORD_IN_EXPRESSION xs)
=>
if (sorted xs)
#
lcf::RECORD (map (fn (_, e) = translate_deep_syntax_expression_to_lambdacode' e) xs);
else
vars = map (fn (l, e) = (l, (translate_deep_syntax_expression_to_lambdacode' e, make_var())))
xs;
#
fun bind ((_, (e, v)), x)
=
lcf::LET (v, e, x);
bexp = map (fn (_, (_, v)) = lcf::VAR v)
(sortrec vars);
fold_backward
bind
(lcf::RECORD bexp)
vars;
fi;
translate_deep_syntax_expression_to_lambdacode'' (ds::RECORD_SELECTOR_EXPRESSION (ds::NUMBERED_LABEL { number=>i, ... }, e))
=>
lcf::GET_FIELD (i, translate_deep_syntax_expression_to_lambdacode' e);
translate_deep_syntax_expression_to_lambdacode'' (ds::VECTOR_IN_EXPRESSION ([], type))
=>
lcf::APPLY_TYPEFUN (core_get "zero_length_vector__global", [t_typ type]);
translate_deep_syntax_expression_to_lambdacode'' (ds::VECTOR_IN_EXPRESSION (xs, type))
=>
{ tc = t_typ type;
vars = map (fn e = (translate_deep_syntax_expression_to_lambdacode' e, make_var()))
xs;
#
fun bind ((e, v), x)
=
lcf::LET (v, e, x);
bexp = map (fn (_, v) = lcf::VAR v)
vars;
fold_backward bind (lcf::VECTOR (bexp, tc)) vars;
};
translate_deep_syntax_expression_to_lambdacode'' (ds::ABSTRACTION_PACKING_EXPRESSION (e, type, typs))
=>
translate_deep_syntax_expression_to_lambdacode' e;
# { my (nty, ks, tps)
# =
# tyj::reformatTypeAbstraction (type, typs, debruijn_depth);
#
# ts = map (tpsTypeConstructor debruijn_depth) tps;
# # * use of LtyDict::tcAbs is a temporary hack (ZHONG) *
#
# nts = paired_listyj::map LtyDict::tcAbs (ts, ks);
#
# nd = di::next debruijn_depth;
#
# case (ks, tps)
# of ([], []) => translate_deep_syntax_expression_to_lambdacode' e
# | _ => PACK (hcf::make_polymorphic_uniqtype (ks, [deepsyntax_type_to_uniqtype nd nty]),
# ts, nts, translate_deep_syntax_expression_to_lambdacode' e);
# }
translate_deep_syntax_expression_to_lambdacode'' (ds::SEQUENTIAL_EXPRESSIONS [e])
=>
translate_deep_syntax_expression_to_lambdacode' e;
translate_deep_syntax_expression_to_lambdacode'' (ds::SEQUENTIAL_EXPRESSIONS (e ! r))
=>
lcf::LET (make_var(), translate_deep_syntax_expression_to_lambdacode' e, translate_deep_syntax_expression_to_lambdacode' (ds::SEQUENTIAL_EXPRESSIONS r));
translate_deep_syntax_expression_to_lambdacode'' (ds::APPLY_EXPRESSION (e1, e2))
=>
lcf::APPLY (translate_deep_syntax_expression_to_lambdacode' e1, translate_deep_syntax_expression_to_lambdacode' e2);
translate_deep_syntax_expression_to_lambdacode'' (ds::SOURCE_CODE_REGION_FOR_EXPRESSION (expression, region))
=>
with_region region translate_deep_syntax_expression_to_lambdacode'' expression;
translate_deep_syntax_expression_to_lambdacode'' (ds::TYPE_CONSTRAINT_EXPRESSION (e, _))
=>
translate_deep_syntax_expression_to_lambdacode' e;
translate_deep_syntax_expression_to_lambdacode'' (ds::RAISE_EXPRESSION (e, type))
=>
make_raise (translate_deep_syntax_expression_to_lambdacode' e, t_lty type);
translate_deep_syntax_expression_to_lambdacode'' (ds::EXCEPT_EXPRESSION (e, (l, type)))
=>
{ root_var = make_var();
#
fun f x
=
lcf::FN (root_var, t_lty type, x);
l' = make_rules l;
lcf::EXCEPT
( translate_deep_syntax_expression_to_lambdacode' e,
mc::compile_exception_pattern
( symbolmapstack,
l',
f,
root_var,
to_tc_lt debruijn_depth,
complain,
make_integer_switch
) );
};
translate_deep_syntax_expression_to_lambdacode'' (ds::FN_EXPRESSION (l, type))
=>
{ root_var = make_var();
#
fun f x
=
lcf::FN (root_var, t_lty type, x);
mc::compile_case_pattern
(
symbolmapstack,
make_rules l,
f,
root_var,
to_tc_lt debruijn_depth,
complain,
make_integer_switch
);
};
translate_deep_syntax_expression_to_lambdacode'' (ds::CASE_EXPRESSION (ee, l, is_match))
=>
{ root_var = make_var();
ee' = translate_deep_syntax_expression_to_lambdacode' ee;
#
fun f x
=
lcf::LET (root_var, ee', x);
l' = make_rules l;
(is_match ?? mc::compile_case_pattern
:: mc::compile_naming_pattern
) (
symbolmapstack,
l',
f,
root_var,
to_tc_lt debruijn_depth,
complain,
make_integer_switch
);
};
translate_deep_syntax_expression_to_lambdacode'' (ds::IF_EXPRESSION { test_case, then_case, else_case } )
=>
cond (translate_deep_syntax_expression_to_lambdacode' test_case, translate_deep_syntax_expression_to_lambdacode' then_case, translate_deep_syntax_expression_to_lambdacode' else_case);
translate_deep_syntax_expression_to_lambdacode'' (ds::AND_EXPRESSION (e1, e2))
=>
cond (translate_deep_syntax_expression_to_lambdacode' e1, translate_deep_syntax_expression_to_lambdacode' e2, false_lexp);
translate_deep_syntax_expression_to_lambdacode'' (ds::OR_EXPRESSION (e1, e2))
=>
cond (translate_deep_syntax_expression_to_lambdacode' e1, true_lexp, translate_deep_syntax_expression_to_lambdacode' e2);
translate_deep_syntax_expression_to_lambdacode'' (ds::WHILE_EXPRESSION { test, expression } )
=>
{ fv = make_var ();
body = lcf::FN (make_var (), lt_void,
cond (translate_deep_syntax_expression_to_lambdacode' test,
lcf::LET (make_var (), translate_deep_syntax_expression_to_lambdacode' expression, lcf::APPLY (lcf::VAR fv, void_lexp)),
void_lexp));
lcf::MUTUALLY_RECURSIVE_FNS ([fv], [lt_voidvoid], [body], lcf::APPLY (lcf::VAR fv, void_lexp));
};
/*x*/ translate_deep_syntax_expression_to_lambdacode'' (ds::LET_EXPRESSION (dc, e))
/*x*/ =>
/*x*/ translate_deep_syntax_to_lambdacode' (dc, debruijn_depth, "translate_deep_syntax_expression_to_lambdacode''" ! callstack) (translate_deep_syntax_expression_to_lambdacode' e);
translate_deep_syntax_expression_to_lambdacode'' e
=>
err::impossible_with_body "untranslateable expression"
(fn stream
=
{ pp::string stream " expression: ";
uds::unparse_expression
(symbolmapstack, NULL)
stream
(e, *prettyprint_depth);
}
);
end; # fun translate_deep_syntax_expression_to_lambdacode''
end; # where
end # fun translate_deep_syntax_expression_to_lambdacode
also
fun translate_integer (debruijn_depth, callstack) s
=
# This is a temporary solution. Since integer literals
# are created using a core function call, there is
# no indication within the program that we are really
# dealing with a constant value that -- in principle --
# could be subject to such things as constant folding. XXX BUGGO FIXME
{ valcon_expression = ds::VALCON_IN_EXPRESSION (bt::cons_dcon, [bt::unt_type]);
#
fun build []
=>
ds::VALCON_IN_EXPRESSION (bt::nil_dcon, [bt::unt_type]);
build (d ! ds)
=>
{ i = unt::to_int_x d;
ds::APPLY_EXPRESSION (valcon_expression,
trj::tupleexp [ds::UNT_CONSTANT_IN_EXPRESSION (multiword_int::from_int i, bt::unt_type),
build ds]);
};
end;
#
fun small w
=
lcf::APPLY ( core_get (ln::is_negative s ?? "make_small_neg_inf"
:: "make_small_pos_inf"
),
translate_deep_syntax_expression_to_lambdacode
(
ds::UNT_CONSTANT_IN_EXPRESSION (multiword_int::from_int (unt::to_int_x w), bt::unt_type),
debruijn_depth,
"translate_integer" ! callstack
) );
case (ln::rep_digits s)
#
[] => small 0u0;
[w] => small w;
ws => lcf::APPLY (
core_get (ln::is_negative s ?? "make_neg_inf"
:: "make_pos_inf"
),
translate_deep_syntax_expression_to_lambdacode (build ws, debruijn_depth, "translate_integer" ! callstack)
);
esac;
};
# Wrap namings for multiword_int::Int literals around body.
#
fun wrap_integer (body, callstack)
=
im::keyed_fold_forward
do_one
body
*integer_map
where
fun do_one (n, v, b)
=
lcf::LET (v, translate_integer (di::top, "wrap_integer" ! callstack) n, b);
end;
#
fun wrap_picklehash_info
( body: lcf::Lambdacode_Expression,
picklehash_infos: List( (ph::Picklehash, Picklehash_Info) )
)
: ( lcf::Lambdacode_Expression,
List( (ph::Picklehash, it::Import_Tree_Node) )
)
=
{ imports
=
map
(fn (p, pi) = (p, p2itree pi))
picklehash_infos
where
fun p2itree (ANON xl)
=>
it::IMPORT_TREE_NODE
(map (fn (i, z) = (i, p2itree z))
xl
);
p2itree (NAMED _)
=>
it::IMPORT_TREE_NODE [];
end;
end;
/*
{ say "\n ****************** \n";
say "\n the current include tree is :\n";
#
fun tree (it::IMPORT_TREE_NODE [])
=
[ "\n" ];
| tree (it::IMPORT_TREE_NODE xl)
=
fold_backward (fn ((i, x), z)
=
{ ts = tree x;
u = (int::to_string i) + " ";
(map (fn y = (u + y)) ts) @ z;
}
)
[]
xl;
#
fun prettyprint (p, n)
=
{ say ("Picklehash " + (ph::to_hex p) + "\n");
apply say (tree n));
apply prettyprint imports; say "\n ****************** \n";
}
*/
lambdacode_expression
=
{ fun get ((_, ANON xl), z)
=>
fold_forward get z xl;
get ((_, u as NAMED (_, t, _)), (n, cs, ts))
=>
(n+1, (n, u) ! cs, t ! ts);
end;
# Get the fringe information
getp = fn ((_, pi), z) = get((0, pi), z);
my (finfos, lts)
=
{ my (_, fx, lx)
=
fold_forward getp (0,[],[]) picklehash_infos;
(reverse fx, reverse lx);
};
# Do the selection of all import variables:
#
fun make_selection (u, xl, be)
=
fold_backward g be xl
where
fun g ((i, pi), be)
=
{ my (v, xs)
=
case pi
#
ANON z => (make_var(), z);
NAMED (v, _, z) => (v, z);
esac;
lcf::LET (v, lcf::GET_FIELD (i, u), make_selection (lcf::VAR v, xs, be));
};
end;
impvar = make_var();
implty = hcf::make_package_uniqtype lts;
nbody = make_selection (lcf::VAR impvar, finfos, body) ;
lcf::FN (impvar, implty, nbody);
};
(lambdacode_expression, imports);
}; # fun wrap_picklehash_info
# The list of things being exported
# from the current compilation unit:
#
export_lexp = lcf::PACKAGE_RECORD (map lcf::VAR exported_highcode_variables);
# Translate the deep_syntax_declaration
# into a lambdacode expression:
#
body = translate_deep_syntax_to_lambdacode' (given_declaration, di::top, []) export_lexp;
# Add namings for integer constants:
#
body = wrap_integer (body, []);
# Wrap up the body with the imported variables:
#
my (lambdacode_expression, imports)
=
wrap_picklehash_info (body, phm::keyvals_list *picklehash_map);
print_lambdacode_expression
(global_controls::highcode::print, prettyprint_lambdacode_expression::print_lexp)
"translate_deep_syntax_to_lambdacode"
lambdacode_expression
where
fun print_lambdacode_expression (flag, print_e) s e
=
if *flag
say ("\n\n[After " + s + " ...]\n\n");
print_e e;
fi;
end;
# # Normalize the lambdacode expression
# # into A-Normal form:
# #
# anormcode
# =
# translate_lambdacode_to_anormcode::translate
# lambdacode_expression;
#
#
if *debugging
printf "\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
printf "============= translate_deep_syntax_to_lambdacode/BOTTOM ========== in translate-deep-syntax-to-lambdacode.pkg\n";
fi;
{ lambdacode_expression, imports };
# { anormcode, imports };
}; # fun translate_deep_syntax_to_lambdacode
}; # package translate_deep_syntax_to_lambdacode
end; # top-level with


