Avoid quite a bit of boxing

This commit is contained in:
Tony Garnock-Jones 2021-06-28 17:26:41 +02:00
parent c7dbbdc178
commit 7546ba29ad
4 changed files with 63 additions and 69 deletions

View File

@ -19,6 +19,7 @@ pub struct FunctionContext<'a> {
pub struct Capture {
pub field_name: String,
pub ty: types::TField,
pub source_expr: String,
}
@ -56,10 +57,11 @@ impl<'a> FunctionContext<'a> {
}
}
pub fn capture(&mut self, field_name: &str, source_expr: &str) {
pub fn capture(&mut self, field_name: String, ty: types::TField, source_expr: String) {
self.captures.push(Capture {
field_name: field_name.to_owned(),
source_expr: source_expr.to_owned(),
field_name: field_name,
ty: ty,
source_expr: source_expr,
})
}

View File

@ -23,7 +23,7 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &IOValue) {
let mut body = Vec::new();
let dest = pattern_parser(&mut ctxt, pat, "value", None, &mut body);
let dest = dest.as_ref().map(String::as_str);
construct(&ctxt, ctorname, &TDefinition::Simple(simple_type(pat).unwrap()), dest, &mut body);
construct(&ctxt, ctorname, false, &TDefinition::Simple(simple_type(pat).unwrap()), dest, &mut body);
item(seq!["fn ", fname.clone(), "(value: &preserves::value::IOValue) -> ",
"std::result::Result<", names::render_constructor(n), ", ()> ",
block(body)])
@ -35,11 +35,11 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &IOValue) {
for e in fs[0].value().to_sequence().unwrap() {
pattern_parser(&mut ctxt, e, "value", None, &mut body);
}
construct(&ctxt, item(names::render_constructor(n)), &definition_type(d).unwrap(), None, &mut body);
construct(&ctxt, item(names::render_constructor(n)), true, &definition_type(d).unwrap(), None, &mut body);
} else {
let dest = pattern_parser(&mut ctxt, d, "value", None, &mut body);
let dest = dest.as_ref().map(String::as_str);
construct(&ctxt, item(names::render_constructor(n)), &definition_type(d).unwrap(), dest, &mut body);
construct(&ctxt, item(names::render_constructor(n)), true, &definition_type(d).unwrap(), dest, &mut body);
}
item(seq!["impl std::convert::TryFrom", anglebrackets!["&preserves::value::IOValue"], " for ",
@ -54,6 +54,7 @@ pub fn gen_definition_parser(m: &mut ModuleContext, n: &str, d: &IOValue) {
fn construct(
ctxt: &FunctionContext,
ctorname: Item,
is_struct: bool,
ty: &TDefinition,
dest: Option<&str>,
body: &mut Vec<Item>,
@ -62,33 +63,27 @@ fn construct(
TDefinition::Simple(TSimple::Field(TField::Unit)) =>
body.push(item(seq!["Ok(", ctorname, ")"])),
TDefinition::Simple(TSimple::Field(fieldty)) =>
body.push(item(seq!["Ok(", ctorname, parens![store_wrap(fieldty, dest.unwrap())], ")"])),
body.push(item(seq!["Ok(", ctorname, parens![store_wrap(is_struct, fieldty, dest.unwrap())], ")"])),
_ =>
body.push(item(seq!["Ok(", ctorname, " ", braces(
ctxt.captures.iter().map(
|c| item(seq![c.field_name.clone(), ": ", c.source_expr.clone()])).collect()),
|c| item(seq![c.field_name.clone(), ": ", store_wrap(is_struct, &c.ty, &c.source_expr)])).collect()),
")"])),
}
}
fn store_wrap(ty: &TField, expr: &str) -> String {
fn store_wrap(is_struct: bool, ty: &TField, expr: &str) -> String {
match ty {
TField::Unit
| TField::Array(_)
| TField::Set(_)
| TField::Map(_, _) => expr.to_owned(),
TField::Ref(_) => format!("std::boxed::Box::new({})", expr),
TField::Base(_) => format!("{}.clone()", expr),
}
}
fn item_store_wrap(ty: &TField, expr: &str) -> String {
match ty {
TField::Unit
| TField::Array(_)
| TField::Set(_)
| TField::Map(_, _)
| TField::Ref(_) => expr.to_owned(),
TField::Ref(_) =>
if is_struct {
expr.to_owned()
} else {
format!("std::boxed::Box::new({})", expr)
},
TField::Base(_) => format!("{}.clone()", expr),
}
}
@ -139,7 +134,7 @@ fn simple_pattern_parser(
let item_dest = simple_pattern_parser(ctxt, &fs[0], &tmp, None, &mut inner);
inner.push(item(seq![
dest.to_owned(), ".push(",
item_store_wrap(&field_type(&fs[0]).unwrap().unwrap(), &item_dest.unwrap()), ");"]));
store_wrap(true, &field_type(&fs[0]).unwrap().unwrap(), &item_dest.unwrap()), ");"]));
push_let_mut(body, &dest, item("std::vec::Vec::new()"));
body.push(item(seq!["for ", tmp.to_owned(),
" in &", src.to_owned(), brackets![seq![n.to_string() , ".."]],
@ -151,7 +146,7 @@ fn simple_pattern_parser(
let item_dest = simple_pattern_parser(ctxt, &fs[0], &tmp, None, &mut inner);
inner.push(item(seq![
dest.to_owned(), ".insert(",
item_store_wrap(&field_type(&fs[0]).unwrap().unwrap(), &item_dest.unwrap()), ");"]));
store_wrap(true, &field_type(&fs[0]).unwrap().unwrap(), &item_dest.unwrap()), ");"]));
push_let_mut(body, &dest, item("preserves::value::Set::new()"));
body.push(item(seq!["for ", tmp.to_owned(),
" in ", src.to_owned(), ".value().to_set().map_err(|_| ())?",
@ -165,8 +160,8 @@ fn simple_pattern_parser(
let value_dest = simple_pattern_parser(ctxt, &fs[1], &tmp_value, None, &mut inner);
inner.push(item(seq![
dest.to_owned(), ".insert(",
item_store_wrap(&field_type(&fs[0]).unwrap().unwrap(), &key_dest.unwrap()), ", ",
item_store_wrap(&field_type(&fs[1]).unwrap().unwrap(), &value_dest.unwrap()), ");"]));
store_wrap(true, &field_type(&fs[0]).unwrap().unwrap(), &key_dest.unwrap()), ", ",
store_wrap(true, &field_type(&fs[1]).unwrap().unwrap(), &value_dest.unwrap()), ");"]));
push_let_mut(body, &dest, item("preserves::value::Map::new()"));
body.push(item(seq!["for (", tmp_key.to_owned(), ", ", tmp_value.to_owned(), ")",
" in ", src.to_owned(), ".value().to_dictionary().map_err(|_| ())?",
@ -234,9 +229,10 @@ fn pattern_parser(
match r.label().value().as_symbol().unwrap().as_ref() {
"named" => {
let dest = simple_pattern_parser(ctxt, &r.fields()[1], src, sequence_base, body).unwrap();
let capture_expr = store_wrap(&field_type(&r.fields()[1]).unwrap().unwrap(), &dest);
ctxt.capture(&names::render_fieldname(r.fields()[0].value().as_symbol().unwrap()),
&capture_expr);
let capture_ty = field_type(&r.fields()[1]).unwrap().unwrap();
ctxt.capture(names::render_fieldname(r.fields()[0].value().as_symbol().unwrap()),
capture_ty,
dest.to_owned());
Some(dest)
}
"rec" => {

View File

@ -6,19 +6,19 @@ use super::names;
use preserves::value::{IOValue, NestedValue};
use preserves::error::Error;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum TDefinition {
Union(Vec<(String, TSimple)>),
Simple(TSimple),
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum TSimple {
Field(TField),
Record(TRecord),
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub enum TField {
Unit,
Array(Box<TField>),
@ -28,7 +28,7 @@ pub enum TField {
Base(String),
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
pub struct TRecord(pub Vec<(String, TField)>);
pub fn definition_type(d: &IOValue) -> Result<TDefinition, Error> {
@ -156,15 +156,15 @@ pub fn render_recordlike_type(is_struct: bool, n: &str, d: &TSimple) -> impl Emi
seq![names::render_constructor(n), match d {
TSimple::Record(TRecord(fs)) => seq![" ", braces(
fs.iter().map(|(n, d)| item(
seq![ppub, names::render_fieldname(n), ": ", render_field_type(true, d)]
seq![ppub, names::render_fieldname(n), ": ", render_field_type(!is_struct, d)]
)).collect())],
TSimple::Field(TField::Unit) => semi,
TSimple::Field(t) => seq![parens![seq![ppub, render_field_type(true, t)]], semi],
TSimple::Field(t) => seq![parens![seq![ppub, render_field_type(!is_struct, t)]], semi],
}]
}
pub fn render_definition_type(n: &str, t: &TDefinition) -> impl Emittable {
seq!["#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]\n",
seq!["#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]\n",
match t {
TDefinition::Union(items) =>
seq!["pub enum ", names::render_constructor(n), " ", braces(

View File

@ -36,16 +36,16 @@ lazy_static! {
pub static ref LIT20: preserves::value::IOValue = /* version */ preserves::value::PackedReader::decode_bytes(&vec![179, 7, 118, 101, 114, 115, 105, 111, 110]).demand_next(false).unwrap();
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum AtomKind {Boolean, Float, Double, SignedInteger, String, ByteString, Symbol}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Binding {pub name: std::string::String, pub pattern: std::boxed::Box<SimplePattern>}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct Binding {pub name: std::string::String, pub pattern: SimplePattern}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Bundle {pub modules: std::boxed::Box<Modules>}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct Bundle {pub modules: Modules}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum CompoundPattern {
Rec {label: std::boxed::Box<NamedPattern>, fields: std::boxed::Box<NamedPattern>},
Tuple {patterns: std::vec::Vec<NamedPattern>},
@ -56,7 +56,7 @@ pub enum CompoundPattern {
Dict {entries: std::boxed::Box<DictionaryEntries>}
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum Definition {
Or {
pattern_0: std::boxed::Box<NamedAlternative>,
@ -71,47 +71,47 @@ pub enum Definition {
Pattern(std::boxed::Box<Pattern>)
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct Definitions(pub preserves::value::Map<std::string::String, Definition>);
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct DictionaryEntries(pub preserves::value::Map<preserves::value::IOValue, NamedSimplePattern>);
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum EmbeddedTypeName {Ref(std::boxed::Box<Ref>), False}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct ModulePath(pub std::vec::Vec<std::string::String>);
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct Modules(pub preserves::value::Map<ModulePath, Schema>);
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct NamedAlternative {pub variant_label: std::string::String, pub pattern: std::boxed::Box<Pattern>}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct NamedAlternative {pub variant_label: std::string::String, pub pattern: Pattern}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum NamedPattern {Named(std::boxed::Box<Binding>), Anonymous(std::boxed::Box<Pattern>)}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum NamedSimplePattern {Named(std::boxed::Box<Binding>), Anonymous(std::boxed::Box<SimplePattern>)}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum Pattern {
SimplePattern(std::boxed::Box<SimplePattern>),
CompoundPattern(std::boxed::Box<CompoundPattern>)
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Ref {pub module: std::boxed::Box<ModulePath>, pub name: std::string::String}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct Ref {pub module: ModulePath, pub name: std::string::String}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct Schema {
pub definitions: std::boxed::Box<Definitions>,
pub embedded_type: std::boxed::Box<EmbeddedTypeName>,
pub version: std::boxed::Box<Version>
pub definitions: Definitions,
pub embedded_type: EmbeddedTypeName,
pub version: Version
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub enum SimplePattern {
Any,
Atom {atom_kind: std::boxed::Box<AtomKind>},
@ -123,7 +123,7 @@ pub enum SimplePattern {
Ref(std::boxed::Box<Ref>)
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq)]
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone)]
pub struct Version;
fn _parse_atom_kind_boolean(value: &preserves::value::IOValue) -> std::result::Result<AtomKind, ()> {if value != &*LIT0 { return Err(()); } let _tmp0 = (); Ok(AtomKind::Boolean)}
@ -171,7 +171,7 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Binding {
if _tmp1.fields().len() - 0 < 2 { return Err(()); }
let _tmp5 = (&_tmp1.fields()[0]).value().to_symbol().map_err(|_| ())?;
let _tmp7 = SimplePattern::try_from((&_tmp1.fields()[1]))?;
Ok(Binding {name: _tmp5.clone(), pattern: std::boxed::Box::new(_tmp7)})
Ok(Binding {name: _tmp5.clone(), pattern: _tmp7})
}
}
@ -183,7 +183,7 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Bundle {
let _tmp2 = ();
if _tmp1.fields().len() - 0 < 1 { return Err(()); }
let _tmp5 = Modules::try_from((&_tmp1.fields()[0]))?;
Ok(Bundle {modules: std::boxed::Box::new(_tmp5)})
Ok(Bundle {modules: _tmp5})
}
}
@ -370,7 +370,7 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for NamedAlternative {
if _tmp1.len() - 0 < 2 { return Err(()); }
let _tmp3 = (&_tmp1[0]).value().to_string().map_err(|_| ())?;
let _tmp5 = Pattern::try_from((&_tmp1[1]))?;
Ok(NamedAlternative {variant_label: _tmp3.clone(), pattern: std::boxed::Box::new(_tmp5)})
Ok(NamedAlternative {variant_label: _tmp3.clone(), pattern: _tmp5})
}
}
@ -440,7 +440,7 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Ref {
if _tmp1.fields().len() - 0 < 2 { return Err(()); }
let _tmp5 = ModulePath::try_from((&_tmp1.fields()[0]))?;
let _tmp7 = (&_tmp1.fields()[1]).value().to_symbol().map_err(|_| ())?;
Ok(Ref {module: std::boxed::Box::new(_tmp5), name: _tmp7.clone()})
Ok(Ref {module: _tmp5, name: _tmp7.clone()})
}
}
@ -458,11 +458,7 @@ impl std::convert::TryFrom<&preserves::value::IOValue> for Schema {
let _tmp11 = EmbeddedTypeName::try_from(_tmp9)?;
let _tmp12 = _tmp5.get(&*LIT20).ok_or(())?;
let _tmp14 = Version::try_from(_tmp12)?;
Ok(Schema {
definitions: std::boxed::Box::new(_tmp8),
embedded_type: std::boxed::Box::new(_tmp11),
version: std::boxed::Box::new(_tmp14)
})
Ok(Schema {definitions: _tmp8, embedded_type: _tmp11, version: _tmp14})
}
}