2015-06-15 06:42:56 -04:00
|
|
|
/*!
|
|
|
|
* Normalization processes a parse tree until it is in suitable form to
|
|
|
|
* be converted to the more canonical form. This is done as a series of
|
|
|
|
* passes, each contained in their own module below.
|
|
|
|
*/
|
|
|
|
|
|
|
|
use grammar::parse_tree as pt;
|
|
|
|
|
2015-06-15 16:58:59 -04:00
|
|
|
pub type NormResult<T> = Result<T, NormError>;
|
|
|
|
|
|
|
|
pub struct NormError {
|
|
|
|
message: String,
|
|
|
|
span: pt::Span,
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! return_err {
|
|
|
|
($span: expr, $($args:expr),+) => {
|
|
|
|
return Err(NormError {
|
|
|
|
message: format!($($args),+),
|
|
|
|
span: $span
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-15 06:42:56 -04:00
|
|
|
// These are executed *IN ORDER*:
|
|
|
|
|
|
|
|
// Expands macros
|
|
|
|
//
|
2015-06-15 07:11:32 -04:00
|
|
|
// X = ...1 Comma<X> ...2
|
2015-06-15 06:42:56 -04:00
|
|
|
//
|
|
|
|
// to
|
|
|
|
//
|
|
|
|
// X = ...1 Vec_X ...2
|
2015-06-15 07:11:32 -04:00
|
|
|
// Comma_X: Vec<<X>> = ...;
|
|
|
|
//
|
2015-06-15 07:26:38 -04:00
|
|
|
// AFTER THIS POINT: No more macros, macro references, or guarded
|
|
|
|
// alternatives, though type indirections may occur.
|
2015-06-15 11:00:15 -04:00
|
|
|
mod macro_expand;
|
2015-06-15 07:11:32 -04:00
|
|
|
|
|
|
|
// Computes types where the user omitted them (or
|
|
|
|
// from macro byproducts).
|
|
|
|
//
|
|
|
|
// AFTER THIS POINT: All explicit, simple types.
|
|
|
|
// mod tyinfer;
|
2015-06-15 06:42:56 -04:00
|
|
|
|
|
|
|
// Converts
|
|
|
|
//
|
|
|
|
// X = ...1 (A B C) ...2
|
|
|
|
//
|
|
|
|
// to
|
|
|
|
//
|
|
|
|
// X = ...1 A_B_C ...2
|
|
|
|
// A_B_C = A B C
|
2015-06-15 07:11:32 -04:00
|
|
|
//
|
|
|
|
// AFTER THIS POINT: No more Symbol::Expr remain.
|
|
|
|
// mod nonterminalize;
|
|
|
|
|
|
|
|
// Synthesizes action code for all nonterminals.
|
|
|
|
//
|
|
|
|
// AFTER THIS POINT: All nonterminals have action code, and all
|
|
|
|
// Symbol::Choose and Symbol::Name are removed.
|
|
|
|
// mod action;
|
2015-06-15 06:42:56 -04:00
|
|
|
|
|
|
|
// Converts
|
|
|
|
//
|
|
|
|
// X = ...1 Y* ...2
|
|
|
|
//
|
|
|
|
// to
|
|
|
|
//
|
|
|
|
// X = ...1 ...2
|
|
|
|
// | ...1 Y+ ...2
|
2015-06-15 07:11:32 -04:00
|
|
|
//
|
|
|
|
// AFTER THIS POINT: No more Symbol::Star remain.
|
|
|
|
// mod remove_star;
|
2015-06-15 06:42:56 -04:00
|
|
|
|
|
|
|
// Converts X+ to a new terminal X_PLUS like:
|
|
|
|
//
|
|
|
|
// X_PLUS = {
|
|
|
|
// <e:X> => { vec![x] }
|
|
|
|
// <v:X_PLUS> <e:X> => { let mut v = v; v.push(e); v }
|
|
|
|
// }
|
2015-06-15 07:11:32 -04:00
|
|
|
//
|
|
|
|
// AFTER THIS POINT: No more Symbol::Plus remain.
|
|
|
|
// mod remove_plus;
|
2015-06-15 06:42:56 -04:00
|
|
|
|
|
|
|
// Converts
|
|
|
|
//
|
|
|
|
// X = ...1 Y? ...2
|
|
|
|
//
|
|
|
|
// to
|
|
|
|
//
|
|
|
|
// X = ...1 ...2
|
|
|
|
// | ...1 Y ...2
|
2015-06-15 07:11:32 -04:00
|
|
|
//
|
|
|
|
// AFTER THIS POINT: No more Symbol::Question remain.
|
|
|
|
// mod remove_question;
|