diff options
| author | Laurenz <laurmaedje@gmail.com> | 2019-05-01 19:47:43 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2019-05-01 19:47:43 +0200 |
| commit | 37c336063ba77d27b65d876f0161855517a6efb7 (patch) | |
| tree | aee8b33461fa8aa7daed43990bb27f5f314161d5 /src/func.rs | |
| parent | 27947e212cf217005059c4d31fa4301e92cfd3cc (diff) | |
Simplify the parsing model 🔋
Diffstat (limited to 'src/func.rs')
| -rw-r--r-- | src/func.rs | 85 |
1 files changed, 37 insertions, 48 deletions
diff --git a/src/func.rs b/src/func.rs index 7558a124..769c77bf 100644 --- a/src/func.rs +++ b/src/func.rs @@ -5,12 +5,9 @@ use std::collections::HashMap; use std::fmt::{self, Debug, Formatter}; use crate::syntax::{FuncHeader, Expression}; -use crate::parsing::{BodyTokens, ParseResult}; +use crate::parsing::{FuncContext, ParseResult}; -/// A function which transforms a parsing context into a boxed function. -type ParseFunc = dyn Fn(ParseContext) -> ParseResult<Box<dyn Function>>; - /// Types that act as functions. /// /// These types have to be able to parse tokens into themselves and store the @@ -20,17 +17,52 @@ type ParseFunc = dyn Fn(ParseContext) -> ParseResult<Box<dyn Function>>; /// used as functions, that is they fulfill the bounds `Debug + PartialEq + 'static`. pub trait Function: FunctionBounds { /// Parse the tokens of the context with the given header and scope into self. - fn parse(context: ParseContext) -> ParseResult<Self> where Self: Sized; + fn parse(context: FuncContext) -> ParseResult<Self> where Self: Sized; /// Execute the function and optionally yield a return value. fn typeset(&self, header: &FuncHeader) -> Option<Expression>; } +impl PartialEq for dyn Function { + fn eq(&self, other: &dyn Function) -> bool { + self.help_eq(other) + } +} + +/// A helper trait that describes requirements for types that can implement [`Function`]. +/// +/// Automatically implemented for all types which fulfill to the bounds +/// `Debug + PartialEq + 'static`. There should be no need to implement this manually. +pub trait FunctionBounds: Debug { + /// Cast self into `Any`. + fn help_cast_as_any(&self) -> &dyn Any; + + /// Compare self with another function. + fn help_eq(&self, other: &dyn Function) -> bool; +} + +impl<T> FunctionBounds for T where T: Debug + PartialEq + 'static { + fn help_cast_as_any(&self) -> &dyn Any { + self + } + + fn help_eq(&self, other: &dyn Function) -> bool { + if let Some(other) = other.help_cast_as_any().downcast_ref::<Self>() { + self == other + } else { + false + } + } +} + /// A map from identifiers to functions. pub struct Scope { parsers: HashMap<String, Box<ParseFunc>>, } +/// A function which transforms a parsing context into a boxed function. +type ParseFunc = dyn Fn(FuncContext) -> ParseResult<Box<dyn Function>>; + impl Scope { /// Create a new empty scope. pub fn new() -> Scope { @@ -59,46 +91,3 @@ impl Debug for Scope { write!(f, "{:?}", self.parsers.keys()) } } - -/// The context for parsing a function. -#[derive(Debug)] -pub struct ParseContext<'s, 't> { - /// The header of the function to be parsed. - pub header: &'s FuncHeader, - /// Tokens if the function has a body, otherwise nothing. - pub tokens: Option<&'s mut BodyTokens<'t>>, - /// The current scope containing function definitions. - pub scope: &'s Scope, -} - -/// A helper trait that describes requirements for types that can implement [`Function`]. -/// -/// Automatically implemented for all types which fulfill to the bounds -/// `Debug + PartialEq + 'static`. There should be no need to implement this manually. -pub trait FunctionBounds: Debug { - /// Cast self into `Any`. - fn help_cast_as_any(&self) -> &dyn Any; - - /// Compare self with another function. - fn help_eq(&self, other: &dyn Function) -> bool; -} - -impl<T> FunctionBounds for T where T: Debug + PartialEq + 'static { - fn help_cast_as_any(&self) -> &dyn Any { - self - } - - fn help_eq(&self, other: &dyn Function) -> bool { - if let Some(other) = other.help_cast_as_any().downcast_ref::<Self>() { - self == other - } else { - false - } - } -} - -impl PartialEq for dyn Function { - fn eq(&self, other: &dyn Function) -> bool { - self.help_eq(other) - } -} |
