## translate-raw-syntax-to-execode-g.pkg
#
# Our apis
# Translate_Raw_Syntax_To_Execode_0
# Translate_Raw_Syntax_To_Execode
# Toplevel_Translate_Raw_Syntax_To_Execode
#
# are all defined in
#
#
src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode.api#
# Our generic is invoked (twice) from
#
#
src/lib/compiler/toplevel/compiler/mythryl-compiler-g.pkg#
# generic arguments:
#
# package backend
# is the machine-dependent code generator
# for our platform.
#
# package compiler_configuration
# is compiler configuration stuff used to
# select between interactive compiling into
# memory and production compiling to a .compiled file.
#
# It mainly selects whether we pickle, unpickle
# and generate a picklehash for everything we
# compile (regular batch-mode compilation) or
# just skip that stuff and compile direct into
# our heap (interactive compilation).
#
#
#
# Our canonical 'translate_raw_syntax_to_execode' entrypoint is from:
#
#
src/app/makelib/compile/compile-in-dependency-order-g.pkg# Compiled by:
#
src/lib/compiler/core.sublib### "I had a running compiler and nobody would touch it.
### They told me computers could only do arithmetic."
###
### -- Rear Admiral Grace Hopper
### "Every sufficiently good analogy is yearning to become a functor."
###
### -- John Baez
### http://math.ucr.edu/home/baez/quantum/node2.html
stipulate
package cos = compile_statistics; # compile_statistics is from
src/lib/compiler/front/basics/stats/compile-statistics.pkg package cs = code_segment; # code_segment is from
src/lib/compiler/execution/code-segments/code-segment.pkg package d2l = translate_deep_syntax_to_lambdacode; # translate_deep_syntax_to_lambdacode is from
src/lib/compiler/back/top/translate/translate-deep-syntax-to-lambdacode.pkg package ds = deep_syntax; # deep_syntax is from
src/lib/compiler/front/typer-stuff/deep-syntax/deep-syntax.pkg package im = inlining_mapstack; # inlining_mapstack is from
src/lib/compiler/toplevel/compiler-state/inlining-mapstack.pkg package inj = inlining_junk; # inlining_junk is from
src/lib/compiler/front/semantic/basics/inlining-junk.pkg package l2a = translate_lambdacode_to_anormcode; # translate_lambdacode_to_anormcode is from
src/lib/compiler/back/top/lambdacode/translate-lambdacode-to-anormcode.pkg package lsi = lambdasplit_inlining; # lambdasplit_inlining is from
src/lib/compiler/back/top/lsplit/lambdasplit-inlining.pkg package pcs = per_compile_stuff; # per_compile_stuff is from
src/lib/compiler/front/typer-stuff/main/per-compile-stuff.pkg package pp = standard_prettyprinter; # standard_prettyprinter is from
src/lib/prettyprint/big/src/standard-prettyprinter.pkg# package pu = unparse_junk; # unparse_junk is from
src/lib/compiler/front/typer/print/unparse-junk.pkg package raw = raw_syntax; # raw_syntax is from
src/lib/compiler/front/parser/raw-syntax/raw-syntax.pkg package sci = sourcecode_info; # sourcecode_info is from
src/lib/compiler/front/basics/source/sourcecode-info.pkg package sp = add_per_fun_byte_counters_to_deep_syntax; # add_per_fun_byte_counters_to_deep_syntax is from
src/lib/compiler/debugging-and-profiling/profiling/add-per-fun-byte-counters-to-deep-syntax.pkg package ss = special_symbols; # special_symbols is from
src/lib/compiler/front/typer/main/special-symbols.pkg package syx = symbolmapstack; # symbolmapstack is from
src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg package ti = tdp_instrument; # tdp_instrument is from
src/lib/compiler/debugging-and-profiling/profiling/tdp-instrument.pkg package tmp = highcode_codetemp; # highcode_codetemp is from
src/lib/compiler/back/top/highcode/highcode-codetemp.pkg package tp = add_per_fun_call_counters_to_deep_syntax; # add_per_fun_call_counters_to_deep_syntax is from
src/lib/compiler/debugging-and-profiling/profiling/add-per-fun-call-counters-to-deep-syntax.pkg package r2d = translate_raw_syntax_to_deep_syntax; # translate_raw_syntax_to_deep_syntax is from
src/lib/compiler/front/semantic/typecheck/translate-raw-syntax-to-deep-syntax.pkg package pds = prettyprint_deep_syntax; # prettyprint_deep_syntax is from
src/lib/compiler/front/typer/print/prettyprint-deep-syntax.pkg package uds = unparse_deep_syntax; # unparse_deep_syntax is from
src/lib/compiler/front/typer/print/unparse-deep-syntax.pkg package vh = varhome; # varhome is from
src/lib/compiler/front/typer-stuff/basics/varhome.pkg Pp = pp::Pp;
herein
# backend can be backend_pwrpc32 from
src/lib/compiler/back/low/main/pwrpc32/backend-pwrpc32.pkg # backend can be backend_sparc32 from
src/lib/compiler/back/low/main/sparc32/backend-sparc32.pkg # backend can be backend_intel32_g call from
src/lib/compiler/toplevel/compiler/mythryl-compiler-for-intel32-posix.pkg # backend can be backend_intel32_g call from
src/lib/compiler/toplevel/compiler/mythryl-compiler-for-intel32-win32.pkg # This generic is (only) invoked (twice) from:
#
#
src/lib/compiler/toplevel/compiler/mythryl-compiler-g.pkg #
generic package translate_raw_syntax_to_execode_g (
#
package backend: Backend; # Backend is from
src/lib/compiler/toplevel/main/backend.api package compiler_configuration: Compiler_Configuration; # Compiler_Configuration is from
src/lib/compiler/toplevel/main/compiler-configuration.api #
ansi_c_prototype_convention: String; # "unix_convention" "windows_convention" or "unimplemented"
)
: (weak) Translate_Raw_Syntax_To_Execode_0 # Translate_Raw_Syntax_To_Execode_0 is from
src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode.api {
# Local abbreviations:
#
package bak = backend;
package cc = compiler_configuration;
#
fun make_per_compile_stuff { sourcecode_info, deep_syntax_transform, prettyprinter_or_null, compiler_verbosity }
=
pcs::make_per_compile_stuff
{
sourcecode_info,
deep_syntax_transform,
make_fresh_stamp_maker => cc::make_fresh_stamp_maker,
prettyprinter_or_null,
compiler_verbosity
};
Pickle = cc::Pickle; # pickled format
Hash = cc::Hash; # Dictionary hash id
Picklehash = cc::Picklehash;
Compiledfile_Version = cc::Compiledfile_Version;
##########################################################################
# Debug/visulize/log support #
##########################################################################
#
fun maybe_prettyprint_anormcode (
per_compile_stuff: pcs::Per_Compile_Stuff( ds::Declaration ),
anormcode
)
=
{ per_compile_stuff -> { prettyprinter_or_null, compiler_verbosity, ... }
;
case prettyprinter_or_null
#
NULL => ();
#
THE pp
=>
if compiler_verbosity.pprint_anormcode_tree
pp.newline();
pp.newline();
# pp.lit "(Following printed by src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg.)";
pp.lit "(Following";
pp::break pp { blanks => 1, indent_on_wrap => 1 };
pp.lit "printed";
pp::break pp { blanks => 1, indent_on_wrap => 1 };
pp.lit "by";
pp::break pp { blanks => 1, indent_on_wrap => 1 };
pp.lit "src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg.)";
pp.newline();
pp.newline();
pp.lit "A-Normal form:";
pp.newline();
prettyprint_anormcode::prettyprint_prog pp anormcode;
pp.flush ();
fi;
esac;
};
#
fun maybe_prettyprint_elapsed_time (per_compile_stuff: pcs::Per_Compile_Stuff( ds::Declaration ))
=
{ per_compile_stuff -> { prettyprinter_or_null, ... };
case prettyprinter_or_null
#
NULL => ();
#
THE pp
=>
{ pp.newline();
pp.newline();
pp.lit "Elapsed time not yet implemented";
pp.newline();
};
esac;
};
##########################################################################
# Typechecking #
##########################################################################
# Several preprocessing phases done
# after parsing or after typechecking:
# my fixityparse
# =
# # cos::do_compiler_phase (cos::make_compiler_phase "Compiler 005 fixityparse")
# FixityParse::fixityparse
#
# my lazycomp
# =
# # cos::do_compiler_phase (cos::make_compiler_phase "Compiler 006 lazycomp")
# LazyComp::lazycomp
pickle_unpickle
=
cos::do_compiler_phase
(cos::make_compiler_phase "Compiler 036 pickle_unpickle")
cc::pickle_unpickle;
# compile_statistics is from
src/lib/compiler/front/basics/stats/compile-statistics.pkg # Take raw_declaration, do semantic checks, and return
# the new symbol table, deep_syntax_declaration and pickles:
#
fun typecheck_raw_declaration {
#
raw_declaration: raw::Declaration, # Actual raw syntax to compile.
symbolmapstack: syx::Symbolmapstack, # Symbol table containing info from all .compiled files we depend on.
per_compile_stuff: pcs::Per_Compile_Stuff( ds::Declaration ),
compiledfile_version: Compiledfile_Version,
sourcecode_info: sci::Sourcecode_Info
}
=
{ deep_syntax_declaration, # ds::Declaration, # Typechecked form of raw_declaration.
new_symbolmapstack, # syx::Symbolmapstack, # A symbol table delta containing (only) stuff from raw_declaration.
export_picklehash, # Null_Or( Picklehash ),
exported_highcode_variables, # List( vh::Variable ),
symbolmapstack_picklehash, # Hash,
pickle # Pickle
}
where
per_compile_stuff -> { prettyprinter_or_null, compiler_verbosity, ... };
if *log::debugging printf "calling translate_raw_syntax_to_deep_syntax [translate-raw-syntax-to-execode-g.pkg]\n"; fi;
(r2d::translate_raw_syntax_to_deep_syntax # translate_raw_syntax_to_deep_syntax def in
src/lib/compiler/front/typer/main/translate-raw-syntax-to-deep-syntax-g.pkg (
raw_declaration, # Actual raw syntax to compile.
symbolmapstack, # Symbol table containing info from all .compiled files we depend on.
per_compile_stuff
))
->
( deep_syntax_declaration, # This is the typechecked version of raw_declaration.
new_symbolmapstack # A symbol table delta containing (only) stuff from raw_declaration.
);
if *log::debugging printf "called translate_raw_syntax_to_deep_syntax [translate-raw-syntax-to-execode-g.pkg]\n"; fi;
my (deep_syntax_declaration, new_symbolmapstack)
=
if (pcs::saw_errors per_compile_stuff)
#
(ds::SEQUENTIAL_DECLARATIONS NIL, syx::empty);
else
(deep_syntax_declaration, new_symbolmapstack);
fi;
(pickle_unpickle # pickle_unpickle def in
src/lib/compiler/toplevel/compiler/mythryl-compiler-g.pkg {
context => symbolmapstack, # Combined symbol tables of all .compiled files we depend upon.
symbolmapstack => new_symbolmapstack, # Symbol table to pickle-then-unpickle.
compiledfile_version
})
->
{ picklehash => symbolmapstack_picklehash,
pickle,
exported_highcode_variables,
export_picklehash,
new_symbolmapstack
};
# Prettyprint to logfile if so requested:
#
case prettyprinter_or_null
#
NULL => ();
THE pp
=>
{ if (pcs::saw_errors per_compile_stuff)
#
pp.newline();
pp.newline();
pp.lit "(Due to syntax errors, no deep syntax tree or new symbol table available.)\n";
pp.newline();
pp::flush_prettyprinter pp;
else
if compiler_verbosity.pprint_symbol_table
pp.newline();
pp.newline();
pp.lit "(Following printed by typecheck_raw_declaration in src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg.)";
pp.newline();
pp.newline();
pp.newline();
pp.lit "ansi_c_prototype_convention: ";
pp.lit ansi_c_prototype_convention;
pp.newline();
pp.newline();
pp.newline();
pp.lit "Original symbol table:";
pp.newline();
# prettyprint_symbolmapstack is from
src/lib/compiler/front/typer-stuff/symbolmapstack/prettyprint-symbolmapstack.pkg prettyprint_symbolmapstack::prettyprint_symbolmapstack pp symbolmapstack;
pp.newline();
pp.newline();
pp.newline();
pp.lit "New symbol table:";
pp.newline();
prettyprint_symbolmapstack::prettyprint_symbolmapstack pp new_symbolmapstack;
pp.newline();
pp::flush_prettyprinter pp;
fi;
if compiler_verbosity.print_exported_highcode_variables
pp.newline();
pp.newline();
pp.lit "exported_highcode_variables:";
pp.newline();
print_lv_list exported_highcode_variables
where
fun print_lv_list (lv ! rest)
=>
{ pp.lit " ";
pp.lit (tmp::to_string lv);
#
if (tmp::highcode_codetemp_has_a_name lv)
pp.lit " (";
pp.lit (tmp::name_of_highcode_codetemp lv);
pp.lit ")";
fi;
pp.newline();
};
print_lv_list [] => ();
end;
end;
pp::flush_prettyprinter pp;
fi;
if compiler_verbosity.unparse_deep_syntax_tree
pp.newline();
pp.newline();
pp.newline();
pp.lit "Deep syntax tree, unparsed: -- translate-raw-syntax-to-execode-g.pkg";
pp.newline();
#
uds::unparse_declaration
#
(new_symbolmapstack, THE sourcecode_info)
pp
(deep_syntax_declaration, 38); # 1000 is the maximum expression nesting depth to print -- arbitrary large number.
pp::flush_prettyprinter pp;
fi;
if compiler_verbosity.pprint_deep_syntax_tree
pp.newline();
pp.newline();
pp.newline();
pp.lit "Deep syntax tree, prettyprinted: -- translate-raw-syntax-to-execode-g.pkg";
pp.newline();
#
pds::prettyprint_declaration
#
(new_symbolmapstack, THE sourcecode_info)
pp
(deep_syntax_declaration, 38); # 1000 is the maximum expression nesting depth to print -- arbitrary large number.
pp::flush_prettyprinter pp;
fi;
fi;
# pp.lit "(Above printed by typecheck_raw_declaration in src/lib/compiler/toplevel/main/translate-raw-syntax-to-execode-g.pkg.)";
# pp.newline();
# pp::flush_prettyprinter pp;
};
esac;
end; # fun typecheck_raw_declaration
typecheck_raw_declaration
=
cos::do_compiler_phase (cos::make_compiler_phase "Compiler 030 typecheck") typecheck_raw_declaration;
#########################################################################
# Deep_Syntax INSTRUMENTATION #
#########################################################################
# special_symbols is from
src/lib/compiler/front/typer/main/special-symbols.pkg stipulate
is_special
=
\\ s = list::exists (\\ s' = symbol::eq (s, s')) specials_list
where
specials_list
=
[ ss::param_id,
ss::generic_id,
ss::hidden_id,
ss::temp_package_id,
ss::temp_generic_id,
ss::generic_body_id,
ss::anonymous_generic_api_id,
ss::result_id,
ss::return_id,
ss::internal_var_id
];
end;
# list is from
src/lib/std/src/list.pkg herein
# Instrumenting the deep syntax to do time- and space-profiling: # This is off by default; controlled by if *runtime_internals::runtime_profiling_control::profiling_mode
# # runtime_internals is from
src/lib/std/src/nj/runtime-internals.pkg # # profiling_mode def in
src/lib/std/src/nj/runtime-profiling-control.pkg #
fun maybe_instrument_deep_syntax
{
sourcecode_info,
symbolmapstack,
per_compile_stuff
}
= sp::maybe_add_per_fun_byte_counters_to_deep_syntax (symbolmapstack, per_compile_stuff) sourcecode_info # This is junk code that probably should be deleted.
o tp::maybe_add_per_fun_call_counters_to_deep_syntax inj::is_callcc_baseop (symbolmapstack, per_compile_stuff) # This adds logic to each function to count calls to it.
o ti::maybe_instrument_deep_syntax is_special (symbolmapstack, per_compile_stuff);
end;
# add_per_fun_byte_counters_to_deep_syntax is from
src/lib/compiler/debugging-and-profiling/profiling/add-per-fun-byte-counters-to-deep-syntax.pkg # add_per_fun_call_counters_to_deep_syntax is from
src/lib/compiler/debugging-and-profiling/profiling/add-per-fun-call-counters-to-deep-syntax.pkg # tdp_instrument is from
src/lib/compiler/debugging-and-profiling/profiling/tdp-instrument.pkg maybe_instrument_deep_syntax
=
cos::do_compiler_phase (cos::make_compiler_phase "Compiler 039 maybe_instrument_deep_syntax") maybe_instrument_deep_syntax;
#########################################################################
# TRANSLATION INTO ANORMCODE #
#########################################################################
# Accept a typechecked deep syntax declaration
# and generate corresponding A-Normal code:
#
fun translate_deep_syntax_to_anormcode {
deep_syntax_declaration,
exported_highcode_variables,
new_symbolmapstack,
old_symbolmapstack,
per_compile_stuff
}
=
# symbolmapstack is from
src/lib/compiler/front/typer-stuff/symbolmapstack/symbolmapstack.pkg { symbolmapstack # symbolmapstack used for printing deep_syntax in messages.
=
syx::atop (new_symbolmapstack, old_symbolmapstack);
if *log::debugging printf "translate_deep_syntax_to_anormcode calling translate_deep_syntax_to_lambdacode -- translate-raw-syntax-to-execode.pkg\n"; fi;
my { lambdacode_expression, imports }
=
d2l::translate_deep_syntax_to_lambdacode
{
declaration => deep_syntax_declaration,
exported_highcode_variables,
symbolmapstack,
ansi_c_prototype_convention, # "unix_convention" "windows_convention" or "unimplemented"
per_compile_stuff
};
if *log::debugging printf "translate_deep_syntax_to_anormcode calling translate_lambdacode_to_anormcode -- translate-raw-syntax-to-execode.pkg\n"; fi;
# Normalize the lambdacode expression
# into A-Normal form:
#
anormcode
=
l2a::translate_lambdacode_to_anormcode
#
lambdacode_expression;
if *log::debugging printf "translate_deep_syntax_to_anormcode returning. -- translate-raw-syntax-to-execode.pkg\n"; fi;
{ anormcode, imports };
};
translate_deep_syntax_to_anormcode
=
cos::do_compiler_phase (cos::make_compiler_phase "Compiler 040 translate") translate_deep_syntax_to_anormcode;
#########################################################################
# CODE GENERATION #
#########################################################################
# Compile A-Normal form down to nextcode
# and thence all the way to native binary:
# translate_anormcode_to_execode def in
src/lib/compiler/back/top/main/backend-tophalf-g.pkg stipulate
increment_codebytes_count_by
=
cos::increment_counterssum_by (cos::make_counterssum' "Code Size");
herein
#
fun translate_anormcode_to_execode { anormcode, imports, inlining_mapstack, crossmodule_inlining_aggressiveness, per_compile_stuff }
=
{ code_and_data_segments => segs,
inline_expression,
import_trees => revised_import_trees
}
where
if *log::debugging printf "translate_anormcode_to_execode/top. -- translate-raw-syntax-to-execode.pkg\n"; fi;
# Do cross-module inlining and specialization:
#
(lsi::do_lambdasplit_inlining (anormcode, imports, inlining_mapstack))
->
(anormcode, revised_import_trees);
# from finished A-Normal code, generate the machine code.
my ( segs: cs::Code_And_Data_Segments,
inline_expression
)
=
bak::translate_anormcode_to_execode ( # Defined in
src/lib/compiler/back/top/main/backend-tophalf-g.pkg anormcode,
per_compile_stuff,
crossmodule_inlining_aggressiveness
);
# Obey the nosplit directive used during bootstrapping.
# inline_expression
# =
# if (not_null crossmodule_inlining_aggressivenss) inline_expression
# else NULL; # XXX BUGGO FIXME WTF?
# fi;
bytes_of_code
=
cs::get_machinecode_bytevector_size_in_bytes segs.code_segment
+
vector_of_one_byte_unts::length segs.bytecodes_to_regenerate_literals_vector;
# list is from
src/lib/std/src/list.pkg # vector_of_one_byte_unts is from
src/lib/std/src/vector-of-one-byte-unts.pkg increment_codebytes_count_by bytes_of_code;
if *log::debugging printf "translate_anormcode_to_execode/bot. -- translate-raw-syntax-to-execode.pkg\n"; fi;
end;
end; # stipulate translate_anormcode_to_execode
# translate_anormcode_to_execode
# =
# cos::do_compiler_phase (cos::make_compiler_phase "Compiler 140 translate_anormcode_to_execode") translate_anormcode_to_execode
###########################################################################
# COMPILATION
# = TYPECHECKING + TRANSLATION TO HIGHCODE + CODE GENERATION
# used only by interact/read-eval-print-loop-g.pkg
# and
src/app/makelib/compile/compile-in-dependency-order-g.pkg
###########################################################################
# Compiling the raw_declaration into absolute executable machine code.
#
# Our canonical invokation is in
#
#
src/app/makelib/compile/compile-in-dependency-order-g.pkg #
fun translate_raw_syntax_to_execode
{
sourcecode_info: sci::Sourcecode_Info,
raw_declaration: raw::Declaration, # Actual raw syntax to compile.
symbolmapstack: syx::Symbolmapstack, # Symbol table containing info from all .compiled files we depend on.
inlining_mapstack: im::Picklehash_To_Anormcode_Mapstack, # Inlining table matching symbolmapstack.
per_compile_stuff: pcs::Per_Compile_Stuff( ds::Declaration ), # E.g., counting and reporting of compile errors.
handle_compile_errors => check,
crossmodule_inlining_aggressiveness: Null_Or( Int ), # This gets used in
src/lib/compiler/back/top/improve/do-crossmodule-anormcode-inlining.pkg compiledfile_version: Compiledfile_Version
}
=
{ code_and_data_segments,
new_symbolmapstack, # A symbol table delta containing (only) stuff from raw_declaration.
deep_syntax_declaration, # Typechecked form of raw_declaration.
export_picklehash,
exported_highcode_variables,
symbolmapstack_picklehash,
pickle,
inline_expression,
import_trees => revised_import_trees
}
where
(typecheck_raw_declaration
{ raw_declaration, # Actual raw syntax to compile.
symbolmapstack, # Symbol table containing info from all .compiled files we depend on.
per_compile_stuff,
compiledfile_version,
sourcecode_info
}
then (check "typecheck")
)
->
{ deep_syntax_declaration, # Typechecked form of raw_declaration.
new_symbolmapstack, # A symbol table delta containing (only) stuff from raw_declaration.
exported_highcode_variables,
export_picklehash,
symbolmapstack_picklehash,
pickle
};
(maybe_instrument_deep_syntax
{
sourcecode_info,
symbolmapstack,
per_compile_stuff
}
deep_syntax_declaration
then
(check "maybe_instrument_deep_syntax")
)
->
deep_syntax_declaration;
(translate_deep_syntax_to_anormcode
{
deep_syntax_declaration, # Typechecked form of raw_declaration.
exported_highcode_variables,
new_symbolmapstack, # A symbol table delta containing (only) stuff from raw_declaration.
old_symbolmapstack => symbolmapstack, # Symbol table containing info from all .compiled files we depend on.
per_compile_stuff
}
then
check "translate_deep_syntax_to_anormcode"
)
->
{ anormcode, imports };
maybe_prettyprint_anormcode (per_compile_stuff, anormcode);
(translate_anormcode_to_execode
{
anormcode,
imports,
inlining_mapstack,
crossmodule_inlining_aggressiveness,
per_compile_stuff
}
then
(check "translate_anormcode_to_execode")
)
->
{ code_and_data_segments,
inline_expression,
import_trees => revised_import_trees
};
end; # function translate_raw_syntax_to_execode
}; # generic package translate_raw_syntax_to_execode_g
end;