From 6dc339887a20cf058ef2e6b58cc05459f2938628 Mon Sep 17 00:00:00 2001 From: Tad Hardesty Date: Tue, 16 Nov 2021 22:46:51 -0800 Subject: [PATCH] Reduce the size of Expression --- crates/dreammaker/src/ast.rs | 19 +++++++++++-------- crates/dreammaker/src/constants.rs | 6 +++--- crates/dreammaker/src/parser.rs | 20 ++++++++++++-------- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/crates/dreammaker/src/ast.rs b/crates/dreammaker/src/ast.rs index 229e1643..65f9f7f4 100644 --- a/crates/dreammaker/src/ast.rs +++ b/crates/dreammaker/src/ast.rs @@ -84,6 +84,7 @@ impl<'a, T: fmt::Display + ?Sized> fmt::Display for Around<'a, T> { } pub type Ident = String; +pub type Ident2 = Box; /// The DM path operators. /// @@ -329,8 +330,8 @@ pub enum NewType { Prefab(Box), /// A "mini-expression" in which to find the prefab to instantiate. MiniExpr { - ident: Ident, - fields: Vec, + 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, + unary: Box<[UnaryOp]>, /// The term of the expression. term: Box>, /// The follow operations applied to this value. - follow: Vec>, + follow: Box<[Spanned]>, }, /// 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>, + args: Option>, }, /// A `list` call. Associations are represented by assignment expressions. List(Vec), @@ -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()), })) } } diff --git a/crates/dreammaker/src/constants.rs b/crates/dreammaker/src/constants.rs index d89a1289..ca3cc5e2 100644 --- a/crates/dreammaker/src/constants.rs +++ b/crates/dreammaker/src/constants.rs @@ -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, }, }, diff --git a/crates/dreammaker/src/parser.rs b/crates/dreammaker/src/parser.rs index 6f6f11de..71496e96 100644 --- a/crates/dreammaker/src/parser.rs +++ b/crates/dreammaker/src/parser.rs @@ -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), } },