Reduce the size of Expression

This commit is contained in:
Tad Hardesty 2021-11-16 22:46:51 -08:00
parent ce0345efc0
commit 6dc339887a
3 changed files with 26 additions and 19 deletions

View file

@ -84,6 +84,7 @@ impl<'a, T: fmt::Display + ?Sized> fmt::Display for Around<'a, T> {
}
pub type Ident = String;
pub type Ident2 = Box<str>;
/// The DM path operators.
///
@ -329,8 +330,8 @@ pub enum NewType {
Prefab(Box<Prefab>),
/// A "mini-expression" in which to find the prefab to instantiate.
MiniExpr {
ident: Ident,
fields: Vec<Field>,
ident: Ident2,
fields: Box<[Field]>,
},
}
@ -341,11 +342,11 @@ pub enum Expression {
/// then its follows, then its unary operators in reverse order.
Base {
/// The unary operations applied to this value, in reverse order.
unary: Vec<UnaryOp>,
unary: Box<[UnaryOp]>,
/// The term of the expression.
term: Box<Spanned<Term>>,
/// The follow operations applied to this value.
follow: Vec<Spanned<Follow>>,
follow: Box<[Spanned<Follow>]>,
},
/// A binary operation.
BinaryOp {
@ -435,12 +436,14 @@ impl Expression {
match self {
Expression::Base { unary, term, follow: _ } => {
guard!(let Some(truthy) = term.elem.is_truthy() else {
return None
return None;
});
let mut negation = false;
for u in unary {
for u in unary.iter() {
if let UnaryOp::Not = u {
negation = !negation;
} else {
return None;
}
}
if negation {
@ -538,7 +541,7 @@ pub enum Term {
/// The type to be instantiated.
type_: NewType,
/// The list of arguments to pass to the `New()` proc.
args: Option<Vec<Expression>>,
args: Option<Box<[Expression]>>,
},
/// A `list` call. Associations are represented by assignment expressions.
List(Vec<Expression>),
@ -1011,7 +1014,7 @@ impl VarSuffix {
} else {
Some(Expression::from(Term::New {
type_: NewType::Prefab(Box::new(Prefab::from(vec![(PathOp::Slash, "list".to_owned())]))),
args: Some(args),
args: Some(args.into_boxed_slice()),
}))
}
}

View file

@ -562,10 +562,10 @@ impl<'a> ConstantFolder<'a> {
None
};
let mut term = self.term(term.elem, base_type_hint)?;
for each in follow {
for each in Vec::from(follow).into_iter() {
term = self.follow(term, each.elem)?;
}
for each in unary.into_iter().rev() {
for each in Vec::from(unary).into_iter().rev() {
term = self.unary(term, each)?;
}
term
@ -717,7 +717,7 @@ impl<'a> ConstantFolder<'a> {
NewType::MiniExpr { .. } => return Err(self.error("non-constant new expression")),
},
args: match args {
Some(args) => Some(self.arguments(args)?),
Some(args) => Some(self.arguments(args.into())?),
None => None,
},
},

View file

@ -1900,9 +1900,9 @@ impl<'ctx, 'an, 'inp> Parser<'ctx, 'an, 'inp> {
}*/
success(Expression::Base {
unary: unary_ops,
unary: unary_ops.into_boxed_slice(),
term: Box::new(term),
follow,
follow: follow.into_boxed_slice(),
})
}
@ -1934,9 +1934,10 @@ impl<'ctx, 'an, 'inp> Parser<'ctx, 'an, 'inp> {
NewType::Prefab(require!(self.prefab_ex(vec![(PathOp::Dot, ident)])))
} else {
// bare dot
let fields = Vec::new();
let ident = ".".to_owned();
NewType::MiniExpr { ident, fields }
NewType::MiniExpr {
ident: ".".into(),
fields: Default::default(),
}
}
} else if let Some(ident) = self.ident()? {
let mut fields = Vec::new();
@ -1944,7 +1945,10 @@ impl<'ctx, 'an, 'inp> Parser<'ctx, 'an, 'inp> {
while let Some(item) = self.field(&mut belongs_to, false)? {
fields.push(item);
}
NewType::MiniExpr { ident, fields }
NewType::MiniExpr {
ident: ident.into(),
fields: fields.into_boxed_slice(),
}
} else if let Some(path) = self.prefab()? {
NewType::Prefab(path)
} else {
@ -1953,11 +1957,11 @@ impl<'ctx, 'an, 'inp> Parser<'ctx, 'an, 'inp> {
// try to read an arglist
// TODO: communicate what type is being new'd somehow
let a = self.arguments(&[], "New")?;
let args = self.arguments(&[], "New")?;
Term::New {
type_: t,
args: a,
args: args.map(Vec::into_boxed_slice),
}
},