diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-01-21 17:09:31 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-01-21 17:09:31 +0100 |
| commit | 78da2bdd5d77d1b8572e5e9da119bfa68127a3fa (patch) | |
| tree | 020c8c39268690d34226eb7e33e75f86304988d6 /src/syntax/expr.rs | |
| parent | 1c1c994c46f7dc30ee34dbc99b02f2342c4617f3 (diff) | |
Decoupled function parser 🔗 [WIP]
Diffstat (limited to 'src/syntax/expr.rs')
| -rw-r--r-- | src/syntax/expr.rs | 105 |
1 files changed, 65 insertions, 40 deletions
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 74deda46..34a1c6bf 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -4,7 +4,7 @@ use super::*; /// An argument or return value. #[derive(Clone, PartialEq)] -pub enum Expression { +pub enum Expr { Ident(Ident), Str(String), Number(f64), @@ -14,9 +14,24 @@ pub enum Expression { Object(Object), } -impl Display for Expression { +impl Expr { + pub fn name(&self) -> &'static str { + use Expr::*; + match self { + Ident(_) => "identifier", + Str(_) => "string", + Number(_) => "number", + Size(_) => "size", + Bool(_) => "boolean", + Tuple(_) => "tuple", + Object(_) => "object", + } + } +} + +impl Display for Expr { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - use Expression::*; + use Expr::*; match self { Ident(i) => write!(f, "{}", i), Str(s) => write!(f, "{:?}", s), @@ -29,6 +44,8 @@ impl Display for Expression { } } +debug_display!(Expr); + /// An identifier. #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Ident(pub String); @@ -53,10 +70,15 @@ impl Display for Ident { } } +debug_display!(Ident); + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct StringLike(pub String); + /// A sequence of expressions. #[derive(Clone, PartialEq)] pub struct Tuple { - pub items: Vec<Spanned<Expression>>, + pub items: Vec<Spanned<Expr>>, } impl Tuple { @@ -64,7 +86,7 @@ impl Tuple { Tuple { items: vec![] } } - pub fn add(&mut self, item: Spanned<Expression>) { + pub fn add(&mut self, item: Spanned<Expr>) { self.items.push(item); } } @@ -86,6 +108,8 @@ impl Display for Tuple { } } +debug_display!(Tuple); + /// A key-value collection of identifiers and associated expressions. #[derive(Clone, PartialEq)] pub struct Object { @@ -97,7 +121,7 @@ impl Object { Object { pairs: vec![] } } - pub fn add(&mut self, key: Spanned<Ident>, value: Spanned<Expression>) { + pub fn add(&mut self, key: Spanned<Ident>, value: Spanned<Expr>) { self.pairs.push(Pair { key, value }); } @@ -127,11 +151,13 @@ impl Display for Object { } } +debug_display!(Object); + /// A key-value pair in an object. #[derive(Clone, PartialEq)] pub struct Pair { pub key: Spanned<Ident>, - pub value: Spanned<Expression>, + pub value: Spanned<Expr>, } impl Display for Pair { @@ -140,57 +166,56 @@ impl Display for Pair { } } -debug_display!(Ident); -debug_display!(Expression); -debug_display!(Tuple); -debug_display!(Object); debug_display!(Pair); -/// Kinds of expressions. -pub trait ExpressionKind: Sized { +pub trait ExprKind: Sized { /// The name of the expression in an `expected <name>` error. const NAME: &'static str; /// Create from expression. - fn from_expr(expr: Spanned<Expression>) -> ParseResult<Self>; + fn from_expr(expr: Spanned<Expr>) -> Result<Self, Error>; } +impl<T> ExprKind for Spanned<T> where T: ExprKind { + const NAME: &'static str = T::NAME; + + fn from_expr(expr: Spanned<Expr>) -> Result<Self, Error> { + let span = expr.span; + T::from_expr(expr).map(|v| Spanned { v, span }) + } +} /// Implements the expression kind trait for a type. macro_rules! kind { - ($type:ty, $name:expr, $($patterns:tt)*) => { - impl ExpressionKind for $type { + ($type:ty, $name:expr, $($p:pat => $r:expr),* $(,)?) => { + impl ExprKind for $type { const NAME: &'static str = $name; - fn from_expr(expr: Spanned<Expression>) -> ParseResult<Self> { + fn from_expr(expr: Spanned<Expr>) -> Result<Self, Error> { #[allow(unreachable_patterns)] Ok(match expr.v { - $($patterns)*, - _ => error!("expected {}", Self::NAME), + $($p => $r),*, + _ => return Err( + err!("expected {}, found {}", Self::NAME, expr.v.name()) + ), }) } } }; } -kind!(Expression, "expression", e => e); -kind!(Ident, "identifier", Expression::Ident(ident) => ident); -kind!(String, "string", Expression::Str(string) => string); -kind!(f64, "number", Expression::Number(num) => num); -kind!(bool, "boolean", Expression::Bool(boolean) => boolean); -kind!(Size, "size", Expression::Size(size) => size); -kind!(Tuple, "tuple", Expression::Tuple(tuple) => tuple); -kind!(Object, "object", Expression::Object(object) => object); - -kind!(ScaleSize, "number or size", - Expression::Size(size) => ScaleSize::Absolute(size), - Expression::Number(scale) => ScaleSize::Scaled(scale as f32) +kind!(Expr, "expression", e => e); +kind!(Ident, "identifier", Expr::Ident(i) => i); +kind!(String, "string", Expr::Str(s) => s); +kind!(f64, "number", Expr::Number(n) => n); +kind!(bool, "boolean", Expr::Bool(b) => b); +kind!(Size, "size", Expr::Size(s) => s); +kind!(Tuple, "tuple", Expr::Tuple(t) => t); +kind!(Object, "object", Expr::Object(o) => o); +kind!(ScaleSize, "number or size", + Expr::Size(size) => ScaleSize::Absolute(size), + Expr::Number(scale) => ScaleSize::Scaled(scale as f32), +); +kind!(StringLike, "identifier or string", + Expr::Ident(Ident(s)) => StringLike(s), + Expr::Str(s) => StringLike(s), ); - -impl<T> ExpressionKind for Spanned<T> where T: ExpressionKind { - const NAME: &'static str = T::NAME; - - fn from_expr(expr: Spanned<Expression>) -> ParseResult<Spanned<T>> { - let span = expr.span; - T::from_expr(expr).map(|v| Spanned { v, span }) - } -} |
