summaryrefslogtreecommitdiff
path: root/src/func.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-05-01 19:47:43 +0200
committerLaurenz <laurmaedje@gmail.com>2019-05-01 19:47:43 +0200
commit37c336063ba77d27b65d876f0161855517a6efb7 (patch)
treeaee8b33461fa8aa7daed43990bb27f5f314161d5 /src/func.rs
parent27947e212cf217005059c4d31fa4301e92cfd3cc (diff)
Simplify the parsing model 🔋
Diffstat (limited to 'src/func.rs')
-rw-r--r--src/func.rs85
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)
- }
-}