summaryrefslogtreecommitdiff
path: root/src/func
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-01-14 20:17:50 +0100
committerLaurenz <laurmaedje@gmail.com>2020-01-14 20:17:50 +0100
commit15ad30555bdad8e7b192fdcf7d4543c0d3fb18ce (patch)
tree814a1863e6a50d433613e5b362d30ede2df0bb21 /src/func
parentdde69276d47818174c35523c8ed86b6888b6d02b (diff)
Parser testing prototype 🥥
Diffstat (limited to 'src/func')
-rw-r--r--src/func/macros.rs15
-rw-r--r--src/func/mod.rs26
2 files changed, 32 insertions, 9 deletions
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<String, Box<Parser>>,
+ debug: Option<Box<Parser>>
}
/// A function which parses the source of a function into a function type which
@@ -129,11 +130,30 @@ type Parser = dyn Fn(
ParseContext
) -> ParseResult<Box<dyn LayoutFunc>>;
+fn make_parser<F>(metadata: <F as ParseFunc>::Meta) -> Box<Parser>
+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<dyn LayoutFunc>)
+ })
+}
+
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<F>() -> Scope
+ where F: ParseFunc<Meta=()> + LayoutFunc + 'static {
+ Scope {
+ parsers: HashMap::new(),
+ debug: Some(make_parser::<F>(())),
}
}
@@ -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<dyn LayoutFunc>)
- })
+ make_parser::<F>(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))
}
}