summaryrefslogtreecommitdiff
path: root/src/syntax/parsing.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-08-04 13:48:07 +0200
committerLaurenz <laurmaedje@gmail.com>2020-08-04 13:48:07 +0200
commit2467cd6272c13b618ad53c5dadff5b8c8e7885bf (patch)
tree6ad13ec06a04997564efc514b40daa3fb65233e2 /src/syntax/parsing.rs
parented4fdcb0ada909f1cc3d7436334e253f0ec14d55 (diff)
Refactor function parsing ♻
Diffstat (limited to 'src/syntax/parsing.rs')
-rw-r--r--src/syntax/parsing.rs48
1 files changed, 16 insertions, 32 deletions
diff --git a/src/syntax/parsing.rs b/src/syntax/parsing.rs
index 3c802074..bf16e146 100644
--- a/src/syntax/parsing.rs
+++ b/src/syntax/parsing.rs
@@ -8,36 +8,16 @@ use super::expr::*;
use super::scope::Scope;
use super::span::{Pos, Span, Spanned};
use super::tokens::{is_newline_char, Token, TokenMode, Tokens};
-use super::tree::{DynamicNode, SyntaxNode, SyntaxTree};
+use super::tree::{SyntaxNode, SyntaxTree};
/// A function which parses a function call into a dynamic node.
-pub type CallParser = dyn Fn(FuncCall, &ParseState) -> Pass<Box<dyn DynamicNode>>;
-
-/// Parse a function call.
-pub trait ParseCall {
- /// Metadata whose value is passed to `parse`. This allows a single function
- /// to do different things depending on the value that needs to be given
- /// when inserting the function into a scope.
- ///
- /// For example, the functions `h` and `v` are built on the same type.
- type Meta: Clone;
-
- /// Parse the function call.
- fn parse(
- call: FuncCall,
- state: &ParseState,
- metadata: Self::Meta,
- ) -> Pass<Self>
- where
- Self: Sized;
-}
+pub type CallParser = dyn Fn(FuncCall, &ParseState) -> Pass<SyntaxNode>;
/// An invocation of a function.
#[derive(Debug, Clone, PartialEq)]
pub struct FuncCall<'s> {
pub header: FuncHeader,
- /// The body as a raw string containing what's inside of the brackets.
- pub body: Option<Spanned<&'s str>>,
+ pub body: FuncBody<'s>,
}
/// The parsed header of a function (everything in the first set of brackets).
@@ -47,6 +27,10 @@ pub struct FuncHeader {
pub args: FuncArgs,
}
+/// The body of a function as a raw spanned string containing what's inside of
+/// the brackets.
+pub type FuncBody<'s> = Option<Spanned<&'s str>>;
+
/// The positional and keyword arguments passed to a function.
#[derive(Debug, Default, Clone, PartialEq)]
pub struct FuncArgs {
@@ -215,7 +199,7 @@ impl<'s> FuncParser<'s> {
let call = FuncCall { header, body: self.body };
let parsed = parser(call, self.state);
self.feedback.extend(parsed.feedback);
- Pass::new(SyntaxNode::Dyn(parsed.output), self.feedback)
+ Pass::new(parsed.output, self.feedback)
}
fn parse_func_header(&mut self) -> Option<FuncHeader> {
@@ -678,7 +662,7 @@ fn unescape_raw(raw: &str) -> Vec<String> {
mod tests {
use crate::length::Length;
use crate::syntax::span::SpanVec;
- use crate::syntax::test::{check, DebugFn};
+ use crate::syntax::test::{check, debug_func, DebugNode};
use super::*;
use Decoration::*;
@@ -697,11 +681,11 @@ mod tests {
};
($source:expr => [$($tree:tt)*], [$($diagnostics:tt)*] $(, [$($decos:tt)*])? $(,)?) => {
- let mut scope = Scope::new::<DebugFn>();
- scope.add::<DebugFn>("f");
- scope.add::<DebugFn>("n");
- scope.add::<DebugFn>("box");
- scope.add::<DebugFn>("val");
+ let mut scope = Scope::new(Box::new(debug_func));
+ scope.insert("f", Box::new(debug_func));
+ scope.insert("n", Box::new(debug_func));
+ scope.insert("box", Box::new(debug_func));
+ scope.insert("val", Box::new(debug_func));
let state = ParseState { scope };
let pass = parse($source, Pos::ZERO, &state);
@@ -798,13 +782,13 @@ mod tests {
value: Z($value),
})));)*)?
)?
- SyntaxNode::Dyn(Box::new(DebugFn {
+ SyntaxNode::boxed(DebugNode {
header: FuncHeader {
name: span_item!($name).map(|s| Ident(s.to_string())),
args,
},
body: func!(@body $($($body)*)?),
- }))
+ })
}};
(@body [$($body:tt)*]) => { Some(span_vec![$($body)*].0) };
(@body) => { None };