Avoid quite a bit of boxing
This commit is contained in:
parent
c7dbbdc178
commit
7546ba29ad
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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" => {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue