diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-07-18 18:05:45 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-18 18:05:45 +0200 |
| commit | 00266f6a58843583f2b46489d1e67d50f023d253 (patch) | |
| tree | 9edbd3cfb1ddd9d303a97c4d8deae98e997390ea /src/syntax/expr.rs | |
| parent | 6f1319e91fe18289c4f9193a4157bde9ee3c53b8 (diff) | |
| parent | 38a24247422ed433a9743e7eacf5037ccf877fa0 (diff) | |
Merge pull request #2 from typst/expressions
Add parsing capabilities for mathematical expressions
Diffstat (limited to 'src/syntax/expr.rs')
| -rw-r--r-- | src/syntax/expr.rs | 56 |
1 files changed, 37 insertions, 19 deletions
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 9d690266..1dc47d03 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<Spanned<Expr>>), + /// An operator that adds the contained expressions. + Add(Box<Spanned<Expr>>, Box<Spanned<Expr>>), + /// An operator that subtracts contained expressions. + Sub(Box<Spanned<Expr>>, Box<Spanned<Expr>>), + /// An operator that multiplies the contained expressions. + Mul(Box<Spanned<Expr>>, Box<Spanned<Expr>>), + /// An operator that divides the contained expressions. + Div(Box<Spanned<Expr>>, Box<Spanned<Expr>>), } 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) } } @@ -346,7 +364,7 @@ impl Deref for NamedTuple { #[derive(Default, Clone, PartialEq)] pub struct Object { /// The key-value pairs of the object. - pub pairs: Vec<Pair>, + pub pairs: Vec<Spanned<Pair>>, } /// A key-value pair in an object. @@ -373,7 +391,7 @@ impl Object { } /// Add a pair to object. - pub fn add(&mut self, pair: Pair) { + pub fn add(&mut self, pair: Spanned<Pair>) { self.pairs.push(pair); } @@ -383,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<V: Value>(&mut self, errors: &mut Errors, key: &str) -> Option<V> { - 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::<V>(errors, index) } @@ -396,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::<V>(errors, index).map(|value| (key, value)); } @@ -414,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) { @@ -447,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<V: Value>(&mut self, errors: &mut Errors, index: usize) -> Option<V> { - 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), @@ -456,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<Pair>> { self.pairs.iter() } } impl IntoIterator for Object { - type Item = Pair; - type IntoIter = std::vec::IntoIter<Pair>; + type Item = Spanned<Pair>; + type IntoIter = std::vec::IntoIter<Spanned<Pair>>; fn into_iter(self) -> Self::IntoIter { self.pairs.into_iter() @@ -471,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<Pair>; + type IntoIter = std::slice::Iter<'a, Spanned<Pair>>; fn into_iter(self) -> Self::IntoIter { self.iter() } } -impl FromIterator<Pair> for Object { - fn from_iter<I: IntoIterator<Item=Pair>>(iter: I) -> Self { +impl FromIterator<Spanned<Pair>> for Object { + fn from_iter<I: IntoIterator<Item=Spanned<Pair>>>(iter: I) -> Self { Object { pairs: iter.into_iter().collect() } } } @@ -488,7 +506,7 @@ impl FromIterator<Pair> 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() } } |
