summaryrefslogtreecommitdiff
path: root/src/syntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/syntax')
-rw-r--r--src/syntax/mod.rs87
-rw-r--r--src/syntax/parsing.rs64
-rw-r--r--src/syntax/span.rs72
3 files changed, 114 insertions, 109 deletions
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs
index 9406fdf4..33413317 100644
--- a/src/syntax/mod.rs
+++ b/src/syntax/mod.rs
@@ -2,13 +2,15 @@
use std::fmt::{self, Display, Formatter};
-use crate::func::Function;
+use crate::func::LayoutFunc;
use crate::size::Size;
mod tokens;
#[macro_use]
mod parsing;
+mod span;
+pub use span::{Span, Spanned};
pub use tokens::{tokenize, Tokens};
pub use parsing::{parse, ParseContext, ParseError, ParseResult};
@@ -90,7 +92,13 @@ pub enum Node {
#[derive(Debug)]
pub struct FuncCall {
pub header: Spanned<FuncHeader>,
- pub body: Spanned<Box<dyn Function>>,
+ pub body: Spanned<Box<dyn LayoutFunc>>,
+}
+
+impl PartialEq for FuncCall {
+ fn eq(&self, other: &FuncCall) -> bool {
+ (self.header == other.header) && (&self.body == &other.body)
+ }
}
/// Contains header information of a function invocation.
@@ -134,12 +142,6 @@ pub enum Expression {
Bool(bool),
}
-impl PartialEq for FuncCall {
- fn eq(&self, other: &FuncCall) -> bool {
- (self.header == other.header) && (&self.body == &other.body)
- }
-}
-
impl Display for Expression {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
use Expression::*;
@@ -154,72 +156,3 @@ impl Display for Expression {
}
debug_display!(Expression);
-
-/// Annotates a value with the part of the source code it corresponds to.
-#[derive(Copy, Clone, Eq, PartialEq)]
-pub struct Spanned<T> {
- pub val: T,
- pub span: Span,
-}
-
-impl<T> Spanned<T> {
- pub fn new(val: T, span: Span) -> Spanned<T> {
- Spanned { val, span }
- }
-
- pub fn value(self) -> T {
- self.val
- }
-
- pub fn span_map<F, U>(self, f: F) -> Spanned<U> where F: FnOnce(T) -> U {
- Spanned::new(f(self.val), self.span)
- }
-}
-
-impl<T> Display for Spanned<T> where T: std::fmt::Debug {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- write!(f, "({:?}:{})", self.val, self.span)
- }
-}
-
-debug_display!(Spanned; T where T: std::fmt::Debug);
-
-/// Describes a slice of source code.
-#[derive(Copy, Clone, Eq, PartialEq)]
-pub struct Span {
- pub start: usize,
- pub end: usize,
-}
-
-impl Span {
- pub fn new(start: usize, end: usize) -> Span {
- Span { start, end }
- }
-
- pub fn merge(a: Span, b: Span) -> Span {
- Span {
- start: a.start.min(b.start),
- end: a.end.max(b.end),
- }
- }
-
- pub fn at(index: usize) -> Span {
- Span { start: index, end: index + 1 }
- }
-
- pub fn pair(&self) -> (usize, usize) {
- (self.start, self.end)
- }
-
- pub fn expand(&mut self, other: Span) {
- *self = Span::merge(*self, other)
- }
-}
-
-impl Display for Span {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- write!(f, "[{}, {}]", self.start, self.end)
- }
-}
-
-debug_display!(Span);
diff --git a/src/syntax/parsing.rs b/src/syntax/parsing.rs
index 77697161..b56094e1 100644
--- a/src/syntax/parsing.rs
+++ b/src/syntax/parsing.rs
@@ -2,7 +2,7 @@
use unicode_xid::UnicodeXID;
-use crate::func::{Function, Scope};
+use crate::func::{LayoutFunc, Scope};
use crate::size::Size;
use super::*;
@@ -120,10 +120,10 @@ impl<'s> Parser<'s> {
if is_identifier(word) {
Ok(Spanned::new(word.to_owned(), span))
} else {
- perr!("invalid identifier: '{}'", word);
+ pr!("invalid identifier: '{}'", word);
}
}
- _ => perr!("expected identifier"),
+ _ => pr!("expected identifier"),
}?;
self.skip_white();
@@ -132,7 +132,7 @@ impl<'s> Parser<'s> {
let args = match self.tokens.next().map(Spanned::value) {
Some(Token::RightBracket) => FuncArgs::new(),
Some(Token::Colon) => self.parse_func_args()?,
- _ => perr!("expected arguments or closing bracket"),
+ _ => pr!("expected arguments or closing bracket"),
};
let end = self.tokens.string_index();
@@ -158,7 +158,7 @@ impl<'s> Parser<'s> {
match self.tokens.next().map(Spanned::value) {
Some(Token::Comma) => {},
Some(Token::RightBracket) => break,
- _ => perr!("expected comma or closing bracket"),
+ _ => pr!("expected comma or closing bracket"),
}
}
@@ -183,7 +183,7 @@ impl<'s> Parser<'s> {
self.skip_white();
let name = token.span_map(|_| name.to_string());
- let next = self.tokens.next().ok_or_else(|| perr!(@"expected value"))?;
+ let next = self.tokens.next().ok_or_else(|| pr!(@"expected value"))?;
let val = Self::parse_expression(next)?;
let span = Span::merge(name.span, val.span);
@@ -219,18 +219,19 @@ impl<'s> Parser<'s> {
}
}
- _ => perr!("expected expression"),
+ _ => pr!("expected expression"),
}, token.span))
}
/// Parse the body of a function.
- fn parse_func_body(&mut self, header: &FuncHeader) -> ParseResult<Spanned<Box<dyn Function>>> {
+ fn parse_func_body(&mut self, header: &FuncHeader)
+ -> ParseResult<Spanned<Box<dyn LayoutFunc>>> {
// Now we want to parse this function dynamically.
let parser = self
.ctx
.scope
.get_parser(&header.name.val)
- .ok_or_else(|| perr!(@"unknown function: '{}'", &header.name.val))?;
+ .ok_or_else(|| pr!(@"unknown function: '{}'", &header.name.val))?;
let has_body = self.tokens.peek().map(Spanned::value) == Some(Token::LeftBracket);
@@ -298,7 +299,7 @@ impl<'s> Parser<'s> {
state = NewlineState::Zero;
match token.val {
Token::LineComment(_) | Token::BlockComment(_) => self.advance(),
- Token::StarSlash => perr!("unexpected end of block comment"),
+ Token::StarSlash => pr!("unexpected end of block comment"),
_ => break,
}
}
@@ -454,7 +455,7 @@ mod tests {
#![allow(non_snake_case)]
use super::*;
- use crate::func::{CommandList, Function, Scope};
+ use crate::func::{Commands, Scope};
use crate::layout::{LayoutContext, LayoutResult};
use funcs::*;
use Node::{Func as F, Newline as N, Space as S};
@@ -464,37 +465,36 @@ mod tests {
mod funcs {
use super::*;
- /// A testing function which just parses it's body into a syntax tree.
- #[derive(Debug)]
- pub struct TreeFn(pub SyntaxTree);
-
function! {
- data: TreeFn,
+ /// A testing function which just parses it's body into a syntax
+ /// tree.
+ #[derive(Debug)]
+ pub struct TreeFn { pub tree: SyntaxTree }
+
+ parse(args, body, ctx) {
+ args.clear();
+ TreeFn {
+ tree: parse!(expected: body, ctx)
+ }
+ }
- parse(_args, body, ctx) { Ok(TreeFn(parse!(required: body, ctx))) }
- layout(_, _) { Ok(vec![]) }
+ layout() { vec![] }
}
impl PartialEq for TreeFn {
fn eq(&self, other: &TreeFn) -> bool {
- assert_tree_equal(&self.0, &other.0);
+ assert_tree_equal(&self.tree, &other.tree);
true
}
}
- /// A testing function without a body.
- #[derive(Debug)]
- pub struct BodylessFn;
-
function! {
- data: BodylessFn,
-
- parse(_args, body, _ctx) { parse!(forbidden: body); Ok(BodylessFn) }
- layout(_, _) { Ok(vec![]) }
- }
+ /// A testing function without a body.
+ #[derive(Debug, Default, PartialEq)]
+ pub struct BodylessFn;
- impl PartialEq for BodylessFn {
- fn eq(&self, _: &BodylessFn) -> bool { true }
+ parse(default)
+ layout() { vec![] }
}
}
@@ -583,7 +583,7 @@ mod tests {
func!(@$name, Box::new(BodylessFn), FuncArgs::new())
);
(name => $name:expr, body => $tree:expr $(,)*) => (
- func!(@$name, Box::new(TreeFn($tree)), FuncArgs::new())
+ func!(@$name, Box::new(TreeFn { tree: $tree }), FuncArgs::new())
);
(@$name:expr, $body:expr, $args:expr) => (
FuncCall {
@@ -789,7 +789,7 @@ mod tests {
assert_eq!(func.header.val.args.positional[0].span.pair(), (13, 16));
assert_eq!(func.header.val.args.positional[1].span.pair(), (18, 23));
- let body = &func.body.val.downcast::<TreeFn>().unwrap().0.nodes;
+ let body = &func.body.val.downcast::<TreeFn>().unwrap().tree.nodes;
assert_eq!(func.body.span.pair(), (24, 37));
assert_eq!(body[0].span.pair(), (0, 4));
assert_eq!(body[1].span.pair(), (4, 5));
diff --git a/src/syntax/span.rs b/src/syntax/span.rs
new file mode 100644
index 00000000..aa494224
--- /dev/null
+++ b/src/syntax/span.rs
@@ -0,0 +1,72 @@
+//! Spans map elements to the part of source code they originate from.
+
+use std::fmt::{self, Display, Formatter};
+
+/// Annotates a value with the part of the source code it corresponds to.
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub struct Spanned<T> {
+ pub val: T,
+ pub span: Span,
+}
+
+impl<T> Spanned<T> {
+ pub fn new(val: T, span: Span) -> Spanned<T> {
+ Spanned { val, span }
+ }
+
+ pub fn value(self) -> T {
+ self.val
+ }
+
+ pub fn span_map<F, U>(self, f: F) -> Spanned<U> where F: FnOnce(T) -> U {
+ Spanned::new(f(self.val), self.span)
+ }
+}
+
+impl<T> Display for Spanned<T> where T: std::fmt::Debug {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "({:?}:{})", self.val, self.span)
+ }
+}
+
+debug_display!(Spanned; T where T: std::fmt::Debug);
+
+/// Describes a slice of source code.
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub struct Span {
+ pub start: usize,
+ pub end: usize,
+}
+
+impl Span {
+ pub fn new(start: usize, end: usize) -> Span {
+ Span { start, end }
+ }
+
+ pub fn merge(a: Span, b: Span) -> Span {
+ Span {
+ start: a.start.min(b.start),
+ end: a.end.max(b.end),
+ }
+ }
+
+ pub fn at(index: usize) -> Span {
+ Span { start: index, end: index + 1 }
+ }
+
+ pub fn pair(&self) -> (usize, usize) {
+ (self.start, self.end)
+ }
+
+ pub fn expand(&mut self, other: Span) {
+ *self = Span::merge(*self, other)
+ }
+}
+
+impl Display for Span {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ write!(f, "[{}, {}]", self.start, self.end)
+ }
+}
+
+debug_display!(Span);