Repair reading of simple but compound types within a simple dictionary pattern

This commit is contained in:
Tony Garnock-Jones 2021-09-11 02:53:32 +02:00
parent e43e85ce8e
commit aabe7b2623
2 changed files with 55 additions and 33 deletions

View File

@ -177,6 +177,16 @@ impl<'a, 'm> FunctionContext<'a, 'm> {
})
}
pub fn with_definite_mode<R, F: FnOnce(&mut Self) -> R>(&mut self, f: F) -> R {
let saved_mode = std::mem::replace(&mut self.capture_mode, CaptureMode::Definite);
let result = f(self);
match std::mem::replace(&mut self.capture_mode, saved_mode) {
CaptureMode::Definite => (),
CaptureMode::Indefinite(_) => panic!("corrupt capture_mode"),
}
result
}
pub fn with_indefinite_mode<F: FnOnce(&mut Self) -> ()>(&mut self, f: F) -> Vec<Item> {
let saved_mode = std::mem::replace(&mut self.capture_mode, CaptureMode::Indefinite(Vec::new()));
f(self);

View File

@ -357,45 +357,57 @@ fn simple_pattern_reader(
dest
},
SimplePattern::Seqof { pattern } => {
let boundary_tracker = BoundaryTracker::unwrap(
ctxt, body, "r.open_sequence()?;", boundary_tracker);
let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner);
let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner);
inner.push(item(seq![dest.to_owned(), ".push(",
store_wrap(true, &field_type(pattern), &item_dest), ");"]));
ctxt.declare_compound(body, &dest, item("std::vec::Vec::new()"));
boundary_tracker.emit_loop(body, inner);
let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| {
let boundary_tracker = BoundaryTracker::unwrap(
ctxt, body, "r.open_sequence()?;", boundary_tracker);
let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner);
let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner);
inner.push(item(seq![compound_dest.to_owned(), ".push(",
store_wrap(true, &field_type(pattern), &item_dest), ");"]));
ctxt.declare_compound(body, &compound_dest, item("std::vec::Vec::new()"));
boundary_tracker.emit_loop(body, inner);
});
ctxt.define_atom(body, &dest, item(compound_dest));
dest
},
SimplePattern::Setof { pattern } => {
let boundary_tracker = BoundaryTracker::new(
ctxt, body, "r.open_set()?;", "_support::B::Item::SetValue");
let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner);
let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner);
inner.push(item(seq![dest.to_owned(), ".insert(",
store_wrap(true, &field_type(pattern), &item_dest), ");"]));
ctxt.declare_compound(body, &dest, item("preserves::value::Set::new()"));
boundary_tracker.emit_loop(body, inner);
let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| {
let boundary_tracker = BoundaryTracker::new(
ctxt, body, "r.open_set()?;", "_support::B::Item::SetValue");
let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner);
let item_dest = simple_pattern_reader(ctxt, pattern, None, &mut inner);
inner.push(item(seq![compound_dest.to_owned(), ".insert(",
store_wrap(true, &field_type(pattern), &item_dest), ");"]));
ctxt.declare_compound(body, &compound_dest, item("preserves::value::Set::new()"));
boundary_tracker.emit_loop(body, inner);
});
ctxt.define_atom(body, &dest, item(compound_dest));
dest
},
SimplePattern::Dictof { key, value } => {
let mut boundary_tracker = BoundaryTracker::new(
ctxt, body, "r.open_dictionary()?;", "_support::B::Item::DictionaryKey");
let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner);
let key_dest = simple_pattern_reader(ctxt, key, None, &mut inner);
boundary_tracker.item_expr = "_support::B::Item::DictionaryValue";
boundary_tracker.emit_boundary(&mut inner);
let value_dest = simple_pattern_reader(ctxt, value, None, &mut inner);
inner.push(item(seq![
dest.to_owned(), ".insert(",
store_wrap(true, &field_type(key), &key_dest), ", ",
store_wrap(true, &field_type(value), &value_dest), ");"]));
ctxt.declare_compound(body, &dest, item("preserves::value::Map::new()"));
boundary_tracker.item_expr = "_support::B::Item::DictionaryKey";
boundary_tracker.emit_loop(body, inner);
let compound_dest = ctxt.gentempname();
ctxt.with_definite_mode(|ctxt| {
let mut boundary_tracker = BoundaryTracker::new(
ctxt, body, "r.open_dictionary()?;", "_support::B::Item::DictionaryKey");
let mut inner = Vec::new();
boundary_tracker.emit_boundary(&mut inner);
let key_dest = simple_pattern_reader(ctxt, key, None, &mut inner);
boundary_tracker.item_expr = "_support::B::Item::DictionaryValue";
boundary_tracker.emit_boundary(&mut inner);
let value_dest = simple_pattern_reader(ctxt, value, None, &mut inner);
inner.push(item(seq![
compound_dest.to_owned(), ".insert(",
store_wrap(true, &field_type(key), &key_dest), ", ",
store_wrap(true, &field_type(value), &value_dest), ");"]));
ctxt.declare_compound(body, &compound_dest, item("preserves::value::Map::new()"));
boundary_tracker.item_expr = "_support::B::Item::DictionaryKey";
boundary_tracker.emit_loop(body, inner);
});
ctxt.define_atom(body, &dest, item(compound_dest));
dest
},
SimplePattern::Ref(r) => {