From 15ad30555bdad8e7b192fdcf7d4543c0d3fb18ce Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 14 Jan 2020 20:17:50 +0100 Subject: =?UTF-8?q?Parser=20testing=20prototype=20=F0=9F=A5=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/func/macros.rs | 15 ++++++++++----- src/func/mod.rs | 26 ++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 9 deletions(-) (limited to 'src/func') diff --git a/src/func/macros.rs b/src/func/macros.rs index 9e931ea2..1083e53c 100644 --- a/src/func/macros.rs +++ b/src/func/macros.rs @@ -75,6 +75,8 @@ macro_rules! function { parse($args:ident, $body:pat, $ctx:pat, $metadata:pat) $code:block $($rest:tt)* ) => { + use $crate::func::prelude::*; + impl $crate::func::ParseFunc for $type { type Meta = $meta; @@ -88,7 +90,8 @@ macro_rules! function { let mut $args = args; let val = $code; if !$args.is_empty() { - error!(unexpected_argument); + return Err($crate::TypesetError + ::with_message("unexpected arguments")); } Ok(val) } @@ -109,6 +112,8 @@ macro_rules! function { // (2-arg) Parse a layout-definition with all arguments. (@layout $type:ident | layout($this:ident, $ctx:pat) $code:block) => { + use $crate::func::prelude::*; + impl LayoutFunc for $type { fn layout<'a, 'life0, 'life1, 'async_trait>( &'a $this, @@ -138,13 +143,13 @@ macro_rules! function { macro_rules! parse { (forbidden: $body:expr) => { if $body.is_some() { - error!("unexpected body"); + return Err($crate::TypesetError::with_message("unexpected body")); } }; (optional: $body:expr, $ctx:expr) => ( if let Some(body) = $body { - Some($crate::syntax::parse(body, $ctx)) + Some($crate::syntax::parse(body, $ctx).0) } else { None } @@ -152,9 +157,9 @@ macro_rules! parse { (expected: $body:expr, $ctx:expr) => ( if let Some(body) = $body { - $crate::syntax::parse(body, $ctx)? + $crate::syntax::parse(body, $ctx).0 } else { - error!("expected body"); + Err($crate::TypesetError::with_message("unexpected body")) } ) } diff --git a/src/func/mod.rs b/src/func/mod.rs index 5f4918d9..90b2a31d 100644 --- a/src/func/mod.rs +++ b/src/func/mod.rs @@ -119,6 +119,7 @@ pub enum Command<'a> { /// A map from identifiers to function parsers. pub struct Scope { parsers: HashMap>, + debug: Option> } /// A function which parses the source of a function into a function type which @@ -129,11 +130,30 @@ type Parser = dyn Fn( ParseContext ) -> ParseResult>; +fn make_parser(metadata: ::Meta) -> Box +where F: ParseFunc + LayoutFunc + 'static { + Box::new(move |a, b, c| { + F::parse(a, b, c, metadata.clone()) + .map(|f| Box::new(f) as Box) + }) +} + impl Scope { /// Create a new empty scope. pub fn new() -> Scope { Scope { parsers: HashMap::new(), + debug: None, + } + } + + /// Create a new scope with a debug parser that is invoked if not other + /// match is found. + pub fn with_debug() -> Scope + where F: ParseFunc + LayoutFunc + 'static { + Scope { + parsers: HashMap::new(), + debug: Some(make_parser::(())), } } @@ -154,16 +174,14 @@ impl Scope { where F: ParseFunc + LayoutFunc + 'static { self.parsers.insert( name.to_owned(), - Box::new(move |a, b, c| { - F::parse(a, b, c, metadata.clone()) - .map(|f| Box::new(f) as Box) - }) + make_parser::(metadata), ); } /// Return the parser with the given name if there is one. pub(crate) fn get_parser(&self, name: &str) -> Option<&Parser> { self.parsers.get(name).map(|x| &**x) + .or(self.debug.as_ref().map(|x| &**x)) } } -- cgit v1.2.3