Make sure that infallible match operations come after fallible ones
Eventually we will probably want to sort by a partial ordering based on pattern subsumption to break ties between rules with the same priority. This local heuristic of making sure infallibilty comes last is good enough for now and handles the cases we care about thus far. Fixes #10
This commit is contained in:
committed by
Chris Fallin
parent
6c6b7a2b78
commit
037db8aab6
@@ -651,7 +651,7 @@ impl<'a> Codegen<'a> {
|
||||
indent: &str,
|
||||
ctx: &mut BodyContext,
|
||||
) -> bool {
|
||||
log::trace!("generate_body: trie {:?}", trie);
|
||||
log::trace!("generate_body:\n{}", trie.pretty());
|
||||
let mut returned = false;
|
||||
match trie {
|
||||
&TrieNode::Empty => {}
|
||||
@@ -692,10 +692,16 @@ impl<'a> Codegen<'a> {
|
||||
|
||||
let mut i = 0;
|
||||
while i < edges.len() {
|
||||
// Gather adjacent match variants so that we can turn these
|
||||
// into a `match` rather than a sequence of `if let`s.
|
||||
let mut last = i;
|
||||
let mut adjacent_variants = BTreeSet::new();
|
||||
let mut adjacent_variant_input = None;
|
||||
log::trace!("edge: {:?}", edges[i]);
|
||||
log::trace!(
|
||||
"edge: range = {:?}, symbol = {:?}",
|
||||
edges[i].range,
|
||||
edges[i].symbol
|
||||
);
|
||||
while last < edges.len() {
|
||||
match &edges[last].symbol {
|
||||
&TrieSymbol::Match {
|
||||
@@ -719,11 +725,11 @@ impl<'a> Codegen<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
// edges[i..last] is a run of adjacent
|
||||
// MatchVariants (possibly an empty one). Only use
|
||||
// a `match` form if there are at least two
|
||||
// adjacent options.
|
||||
// Now `edges[i..last]` is a run of adjacent `MatchVariants`
|
||||
// (possibly an empty one). Only use a `match` form if there
|
||||
// are at least two adjacent options.
|
||||
if last - i > 1 {
|
||||
eprintln!("FITZGEN: generating body matches");
|
||||
self.generate_body_matches(code, depth, &edges[i..last], indent, ctx);
|
||||
i = last;
|
||||
continue;
|
||||
@@ -738,8 +744,13 @@ impl<'a> Codegen<'a> {
|
||||
match symbol {
|
||||
&TrieSymbol::EndOfMatch => {
|
||||
returned = self.generate_body(code, depth + 1, node, indent, ctx);
|
||||
eprintln!(
|
||||
"FITZGEN: generated end-of-match; returned = {:?}",
|
||||
returned
|
||||
);
|
||||
}
|
||||
&TrieSymbol::Match { ref op } => {
|
||||
eprintln!("FITZGEN: generating [if] let");
|
||||
let id = InstId(depth);
|
||||
let infallible =
|
||||
self.generate_pattern_inst(code, id, op, indent, ctx);
|
||||
|
||||
@@ -31,15 +31,6 @@ pub enum Value {
|
||||
/// A single Pattern instruction.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum PatternInst {
|
||||
/// Get the Nth input argument, which corresponds to the Nth field
|
||||
/// of the root term.
|
||||
Arg {
|
||||
/// The index of the argument to get.
|
||||
index: usize,
|
||||
/// The type of the argument.
|
||||
ty: TypeId,
|
||||
},
|
||||
|
||||
/// Match a value as equal to another value. Produces no values.
|
||||
MatchEqual {
|
||||
/// The first value.
|
||||
@@ -83,6 +74,21 @@ pub enum PatternInst {
|
||||
variant: VariantId,
|
||||
},
|
||||
|
||||
/// Evaluate an expression and provide the given value as the result of this
|
||||
/// match instruction. The expression has access to the pattern-values up to
|
||||
/// this point in the sequence.
|
||||
Expr {
|
||||
/// The expression to evaluate.
|
||||
seq: ExprSequence,
|
||||
/// The value produced by the expression.
|
||||
output: Value,
|
||||
/// The type of the output value.
|
||||
output_ty: TypeId,
|
||||
},
|
||||
|
||||
// NB: this has to come second-to-last, because it might be infallible, for
|
||||
// the same reasons that `Arg` has to be last.
|
||||
//
|
||||
/// Invoke an extractor, taking the given values as input (the first is the
|
||||
/// value to extract, the other are the `Input`-polarity extractor args) and
|
||||
/// producing an output value for each `Output`-polarity extractor arg.
|
||||
@@ -99,16 +105,17 @@ pub enum PatternInst {
|
||||
infallible: bool,
|
||||
},
|
||||
|
||||
/// Evaluate an expression and provide the given value as the result of this
|
||||
/// match instruction. The expression has access to the pattern-values up to
|
||||
/// this point in the sequence.
|
||||
Expr {
|
||||
/// The expression to evaluate.
|
||||
seq: ExprSequence,
|
||||
/// The value produced by the expression.
|
||||
output: Value,
|
||||
/// The type of the output value.
|
||||
output_ty: TypeId,
|
||||
// NB: This has to go last, since it is infallible, so that when we sort
|
||||
// edges in the trie, we visit infallible edges after first having tried the
|
||||
// more-specific fallible options.
|
||||
//
|
||||
/// Get the Nth input argument, which corresponds to the Nth field
|
||||
/// of the root term.
|
||||
Arg {
|
||||
/// The index of the argument to get.
|
||||
index: usize,
|
||||
/// The type of the argument.
|
||||
ty: TypeId,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user