From bb1350cff5f1cf4da0332b72ec0703689645649c Mon Sep 17 00:00:00 2001 From: Martin Haug Date: Sat, 18 Jul 2020 14:04:58 +0200 Subject: Parsing mathematical expressions :heavy_plus_sign: --- src/syntax/expr.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'src/syntax/expr.rs') diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 9d690266..c340d9b0 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -1,6 +1,6 @@ //! Expressions in function headers. -use std::fmt::{self, Write, Debug, Formatter}; +use std::fmt::{self, Debug, Formatter}; use std::iter::FromIterator; use std::ops::Deref; use std::str::FromStr; @@ -26,7 +26,7 @@ pub enum Expr { Size(Size), /// A bool: `true, false`. Bool(bool), - /// A color value, including the alpha channel: `#f79143ff` + /// A color value, including the alpha channel: `#f79143ff`. Color(RgbaColor), /// A tuple: `(false, 12cm, "hi")`. Tuple(Tuple), @@ -34,6 +34,16 @@ pub enum Expr { NamedTuple(NamedTuple), /// An object: `{ fit: false, size: 12pt }`. Object(Object), + /// An operator that negates the contained expression. + Neg(Box>), + /// An operator that adds the contained expressions. + Add(Box>, Box>), + /// An operator that subtracts contained expressions. + Sub(Box>, Box>), + /// An operator that multiplies the contained expressions. + Mul(Box>, Box>), + /// An operator that divides the contained expressions. + Div(Box>, Box>), } impl Expr { @@ -50,6 +60,11 @@ impl Expr { Tuple(_) => "tuple", NamedTuple(_) => "named tuple", Object(_) => "object", + Neg(_) => "negation", + Add(_, _) => "addition", + Sub(_, _) => "subtraction", + Mul(_, _) => "multiplication", + Div(_, _) => "division", } } } @@ -67,6 +82,11 @@ impl Debug for Expr { Tuple(t) => t.fmt(f), NamedTuple(t) => t.fmt(f), Object(o) => o.fmt(f), + Neg(e) => write!(f, "-{:?}", e), + Add(a, b) => write!(f, "({:?} + {:?})", a, b), + Sub(a, b) => write!(f, "({:?} - {:?})", a, b), + Mul(a, b) => write!(f, "({:?} * {:?})", a, b), + Div(a, b) => write!(f, "({:?} / {:?})", a, b), } } } @@ -102,9 +122,7 @@ impl Ident { impl Debug for Ident { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.write_char('`')?; - f.write_str(&self.0)?; - f.write_char('`') + write!(f, "`{}`", self.0) } } -- cgit v1.2.3 From e9a9581252080853418d386992cdadecbce9f7dc Mon Sep 17 00:00:00 2001 From: Martin Haug Date: Sat, 18 Jul 2020 16:57:58 +0200 Subject: =?UTF-8?q?Spanned=20object=20pairs=20and=20refactoring=20?= =?UTF-8?q?=F0=9F=A7=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/syntax/expr.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/syntax/expr.rs') diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index c340d9b0..1dc47d03 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -364,7 +364,7 @@ impl Deref for NamedTuple { #[derive(Default, Clone, PartialEq)] pub struct Object { /// The key-value pairs of the object. - pub pairs: Vec, + pub pairs: Vec>, } /// A key-value pair in an object. @@ -391,7 +391,7 @@ impl Object { } /// Add a pair to object. - pub fn add(&mut self, pair: Pair) { + pub fn add(&mut self, pair: Spanned) { self.pairs.push(pair); } @@ -401,7 +401,7 @@ impl Object { /// Inserts an error if the value does not match. If the key is not /// contained, no error is inserted. pub fn get(&mut self, errors: &mut Errors, key: &str) -> Option { - let index = self.pairs.iter().position(|pair| pair.key.v.as_str() == key)?; + let index = self.pairs.iter().position(|pair| pair.v.key.v.as_str() == key)?; self.get_index::(errors, index) } @@ -414,7 +414,7 @@ impl Object { errors: &mut Errors, ) -> Option<(K, V)> { for (index, pair) in self.pairs.iter().enumerate() { - let key = Spanned { v: pair.key.v.as_str(), span: pair.key.span }; + let key = Spanned { v: pair.v.key.v.as_str(), span: pair.v.key.span }; if let Some(key) = K::parse(key) { return self.get_index::(errors, index).map(|value| (key, value)); } @@ -432,7 +432,7 @@ impl Object { let mut index = 0; std::iter::from_fn(move || { if index < self.pairs.len() { - let key = &self.pairs[index].key; + let key = &self.pairs[index].v.key; let key = Spanned { v: key.v.as_str(), span: key.span }; Some(if let Some(key) = K::parse(key) { @@ -465,7 +465,7 @@ impl Object { /// Extract the argument at the given index and insert an error if the value /// does not match. fn get_index(&mut self, errors: &mut Errors, index: usize) -> Option { - let expr = self.pairs.remove(index).value; + let expr = self.pairs.remove(index).v.value; let span = expr.span; match V::parse(expr) { Ok(output) => Some(output), @@ -474,14 +474,14 @@ impl Object { } /// Iterate over the pairs of this object. - pub fn iter<'a>(&'a self) -> std::slice::Iter<'a, Pair> { + pub fn iter<'a>(&'a self) -> std::slice::Iter<'a, Spanned> { self.pairs.iter() } } impl IntoIterator for Object { - type Item = Pair; - type IntoIter = std::vec::IntoIter; + type Item = Spanned; + type IntoIter = std::vec::IntoIter>; fn into_iter(self) -> Self::IntoIter { self.pairs.into_iter() @@ -489,16 +489,16 @@ impl IntoIterator for Object { } impl<'a> IntoIterator for &'a Object { - type Item = &'a Pair; - type IntoIter = std::slice::Iter<'a, Pair>; + type Item = &'a Spanned; + type IntoIter = std::slice::Iter<'a, Spanned>; fn into_iter(self) -> Self::IntoIter { self.iter() } } -impl FromIterator for Object { - fn from_iter>(iter: I) -> Self { +impl FromIterator> for Object { + fn from_iter>>(iter: I) -> Self { Object { pairs: iter.into_iter().collect() } } } @@ -506,7 +506,7 @@ impl FromIterator for Object { impl Debug for Object { fn fmt(&self, f: &mut Formatter) -> fmt::Result { f.debug_map() - .entries(self.pairs.iter().map(|p| (&p.key.v, &p.value.v))) + .entries(self.pairs.iter().map(|p| (&p.v.key.v, &p.v.value.v))) .finish() } } -- cgit v1.2.3