## adl-symboltable.pkg -- derived from ~/src/sml/nj/smlnj-110.58/new/new/src/MLRISC/Tools/ADL/mdl-env.sml
#
# architecture description symboltable.
# Compiled by:
#
src/lib/compiler/back/low/tools/arch/make-sourcecode-for-backend-packages.lib### "Use the word cybernetics, Norbert,
### because nobody knows what it means.
### This will always put you at
### an advantage in arguments."
###
### -- Claude Shannon
stipulate
package err = adl_error; # adl_error is from
src/lib/compiler/back/low/tools/line-number-db/adl-error.pkg package lnd = line_number_database; # line_number_database is from
src/lib/compiler/back/low/tools/line-number-db/line-number-database.pkg package spp = simple_prettyprinter; # simple_prettyprinter is from
src/lib/prettyprint/simple/simple-prettyprinter.pkg package mms = adl_mapstack; # adl_mapstack is from
src/lib/compiler/back/low/tools/arch/adl-mapstack.pkg package mtj = adl_type_junk; # adl_type_junk is from
src/lib/compiler/back/low/tools/arch/adl-type-junk.pkg package raw = adl_raw_syntax_form; # adl_raw_syntax_form is from
src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-form.pkg package rsu = adl_raw_syntax_unparser; # adl_raw_syntax_unparser is from
src/lib/compiler/back/low/tools/adl-syntax/adl-raw-syntax-unparser.pkgherein
# This package is used in:
#
#
src/lib/compiler/back/low/tools/arch/adl-typing.pkg #
src/lib/compiler/back/low/tools/arch/adl-gen-rewrite.pkg #
src/lib/compiler/back/low/tools/arch/sourcecode-making-junk.pkg #
src/lib/compiler/back/low/tools/arch/adl-gen-ssaprops.pkg #
src/lib/compiler/back/low/tools/arch/adl-gen-delay.pkg #
src/lib/compiler/back/low/tools/arch/architecture-description.pkg #
src/lib/compiler/back/low/tools/arch/make-sourcecode-for-translate-machcode-to-asmcode-xxx-g-package.pkg #
src/lib/compiler/back/low/tools/arch/adl-gen-rtlprops.pkg #
src/lib/compiler/back/low/tools/arch/make-sourcecode-for-translate-machcode-to-execode-xxx-g-package.pkg #
src/lib/compiler/back/low/tools/arch/adl-rtl-comp-g.pkg #
package adl_symboltable
: (weak) Adl_Symboltable # Adl_Symboltable is from
src/lib/compiler/back/low/tools/arch/adl-symboltable.api {
Symboltable
=
SYMBOLTABLE
{ te: mms::Mapstack( raw::Type ), # Type symboltable.
ve: mms::Mapstack( (raw::Expression, raw::Type) ), # Value symboltable.
ee: mms::Mapstack( (List(raw::Declaration), Symboltable) ), # Package symboltable.
de: List( raw::Declaration ), # Declarations symboltable.
se: List( raw::Declaration ) # Api symboltable.
};
infix my ++ ;
infix my @@ ;
infix my ===> ;
@@ = mms::union;
===> = mms::bind;
e = mms::empty;
empty = SYMBOLTABLE { te => e,
ve => e,
ee => e,
de => [],
se => []
};
# '++' combines two symboltables:
#
fun (SYMBOLTABLE { te=>te1, ve=>ve1, ee=>ee1, de=>de1, se=>se1 } )
++ (SYMBOLTABLE { te=>te2, ve=>ve2, ee=>ee2, de=>de2, se=>se2 } )
=
SYMBOLTABLE { te => te1 @@ te2,
ve => ve1 @@ ve2,
ee => ee1 @@ ee2,
de => de1 @ de2,
se => se1 @ se2
};
fun make_decl d = SYMBOLTABLE { te=>e, ve=>e, ee=>e, de=> [d], se=> [] };
fun make_api d = SYMBOLTABLE { te=>e, ve=>e, ee=>e, de=> [], se=> [d] };
fun make_vals vbs = SYMBOLTABLE { te=>e, ve=>vbs, ee=>e, de=> [], se=> [] };
fun named_variable (id, e, t)
=
make_vals (id ===> (e, t));
fun type_bind (id, t)
=
SYMBOLTABLE { te => id ===> t,
ve => e,
ee => e,
de => [],
se => []
};
fun named_package (id, args, e')
=
SYMBOLTABLE { te => e,
ve => e,
ee => id ===> (args, e'),
de => [],
se => []
};
# Create a new free variable; instantiation and generalization:
#
fun make_variable (SYMBOLTABLE _) = mtj::make_variable 0; # XXX
fun instantiate (SYMBOLTABLE _) t = mtj::instantiate 0 t; # XXX
fun generalize (SYMBOLTABLE _) t = mtj::generalize 0 t; # XXX
fun lambda (SYMBOLTABLE _) t = mtj::lambda 0 t; # XXX
# Extract components:
#
fun de (SYMBOLTABLE { de, ... } ) = de;
fun se (SYMBOLTABLE { se, ... } ) = se;
fun sumtype_definitions (SYMBOLTABLE { de, ... } )
=
list::fold_backward collect [] de
where
fun collect (raw::SUMTYPE_DECL (dbs, _), dbs') => dbs @ dbs';
collect (raw::SOURCE_CODE_REGION_FOR_DECLARATION (_, d), dbs') => collect (d, dbs');
collect (_, dbs') => dbs';
end;
end;
# Look up components in the symboltable:
#
fun find_type (e as SYMBOLTABLE { te, ee, ... } ) (raw::IDENT([], id))
=>
mms::get te id
except
_ = { err::error("undefined type '" + id + "'");
make_variable e;
};
find_type (SYMBOLTABLE { ee, ... } ) (raw::IDENT (s ! ss, id))
=>
find_type (find_package' ee (raw::IDENT (ss, s))) (raw::IDENT([], id));
end
also
fun find_value' err (e as SYMBOLTABLE { ve, ee, ... } ) (raw::IDENT([], id))
=>
instantiate e (mms::get ve id)
except
_ = { err id;
(raw::LITERAL_IN_EXPRESSION (raw::INT_LIT 0), make_variable e);
};
find_value' err (SYMBOLTABLE { ee, ... } ) (raw::IDENT (s ! ss, id))
=>
find_value' err (find_package' ee (raw::IDENT (ss, s))) (raw::IDENT([], id));
end
also
fun find_value e x
=
find_value' (\\ x = err::error("undefined value '" + x + "'")) e x
also
fun find_package (SYMBOLTABLE { ee, ... } ) id
=
find_package' ee id
also
fun find_package' ee (raw::IDENT([], id))
=>
#2 (mms::get ee id)
except
_ = { err::error("undefined package '" + id + "'");
empty;
};
find_package' ee (raw::IDENT (s ! ss, id))
=>
find_package (find_package' ee (raw::IDENT (ss, s))) (raw::IDENT([], id));
end;
# Interators:
#
fun fold_val f x (SYMBOLTABLE { ve, ... } )
=
mms::fold
(\\ (id, (e, type), l) = f (id, e, type, l))
x
ve;
# Elaborate a declaration in an symboltable.
# We return a delta symboltable containing only
# info from the given declaration -- use ++ to
# combine new symboltable with pre-existing one:
#
fun digest_declaration symboltable d
=
ddd symboltable lnd::dummy_loc d
where
# Elaborate a declaration:
#
make_decl = \\ (l, d) = make_decl (raw::SOURCE_CODE_REGION_FOR_DECLARATION (l, d));
make_api = \\ (l, d) = make_api (raw::SOURCE_CODE_REGION_FOR_DECLARATION (l, d));
fun ddd symboltable l (d as raw::SUMTYPE_DECL (dbs, tys)) => make_decl (l, d) ++ make_api (l, d);
ddd symboltable l (d as raw::BASE_OP_DECL cbs) => make_decl (l, d);
ddd symboltable l (d as raw::FUN_DECL _) => make_decl (l, d);
#
ddd symboltable l (d as raw::RTL_DECL _) => make_decl (l, d);
ddd symboltable l (d as raw::RTL_SIG_DECL _) => make_decl (l, d);
ddd symboltable l (d as raw::VAL_DECL _) => make_decl (l, d);
#
ddd symboltable l (d as raw::TYPE_API_DECL _) => make_api (l, d);
ddd symboltable l (d as raw::VALUE_API_DECL _) => make_api (l, d);
ddd symboltable l (d as raw::LOCAL_DECL (d1, d2)) => make_decl (l, d); # let symboltable' = Ds symboltable l d1 in Ds (symboltable ++ symboltable') l d2 end
#
ddd symboltable l (d as raw::SEQ_DECL ds') => ds symboltable l ds';
ddd symboltable l (d as raw::OPEN_DECL ids) => make_decl (l, d) ++ open_strs symboltable ids;
#
ddd symboltable l (d as raw::PACKAGE_DECL (id, args, _, raw::DECLSEXP ds'))
=>
{ symboltable' = ds symboltable l ds';
#
named_package (id, args, symboltable') ++ make_decl (l, d);
};
ddd symboltable l (raw::PACKAGE_API_DECL _) => empty;
ddd symboltable l (d as raw::INFIX_DECL _) => make_decl (l, d);
ddd symboltable l (d as raw::INFIXR_DECL _) => make_decl (l, d);
ddd symboltable l (d as raw::NONFIX_DECL _) => make_decl (l, d);
ddd symboltable _ (raw::SOURCE_CODE_REGION_FOR_DECLARATION (l, d))
=>
{ err::set_loc l;
#
ddd symboltable l d;
};
ddd symboltable l d
=>
err::fail("illegal declaration: " + (spp::prettyprint_expression_to_string (rsu::decl d)));
end
also
fun ds symboltable l [] => empty;
ds symboltable l (d ! more_ds) => { symboltable' = ddd symboltable l d;
#
symboltable' ++ ds (symboltable ++ symboltable') l more_ds;
};
end
also # open up a list of packages
fun open_strs symboltable ids
=
list::fold_backward
(\\ (id, symboltable') = find_package symboltable id ++ symboltable')
empty
ids;
end;
# Return a symboltable containing the
# original symboltable augmented by
# the given declaration:
#
fun note_declaration symboltable declaration
=
symboltable ++ digest_declaration symboltable declaration;
# Treat a type expression as a pattern
# and compute its set of namings.
# Duplicated names are assigned unique suffixes.
#
fun namings_in_type type
=
(*names, get_name)
where
names = mms::envir "names";
fun count id
=
{ my (n, total) = mms::lookup names id;
total := *total + 1;
}
except
_ = mms::set names (id, (REF 0, REF 1));
fun get_name id
=
{ my (n, total) = mms::lookup names id;
#
if (*total == 1)
#
id;
else
n := *n + 1;
id + int::to_string *n;
fi;
};
fun f (raw::IDTY (raw::IDENT(_, id))) => count id;
f (raw::REGISTER_TYPE id) => count id; # This (with id=="bar") came from a foo: $bar declaration -- the '$' distinguishes these from regular type declarations.
#
f (raw::APPTY(_,[type])) => f type;
#
f (raw::TUPLETY tys) => apply f tys;
f (raw::RECORDTY ltys) => apply (\\ (id, _) = count id) ltys;
#
f _ => ();
end;
f type;
end;
# Look up from nested symboltable:
#
fun decl_of (SYMBOLTABLE { ee, ... } ) id
=
{ (mms::get ee id) -> (_, SYMBOLTABLE { de, ... } );
#
raw::SEQ_DECL de;
}
except _ = raw::VERBATIM_CODE [];
fun generic_arg_of (SYMBOLTABLE { ee, ... } ) id
=
{ (mms::get ee id) -> (args, _);
#
raw::SEQ_DECL args;
}
except _ = raw::VERBATIM_CODE [];
fun type_of (SYMBOLTABLE { ee, ... } ) id
=
{ (mms::get ee id) -> (_, SYMBOLTABLE { se, ... } );
raw::SEQ_DECL se;
}
except _ = raw::VERBATIM_CODE [];
};
end;