1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
//! Tokenized and syntax tree representations of source code.
use std::collections::HashMap;
use crate::func::Function;
/// A logical unit of the incoming text stream.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Token<'s> {
/// One or more whitespace (non-newline) codepoints.
Space,
/// A line feed (either `\n` or `\r\n`).
Newline,
/// A left bracket: `[`.
LeftBracket,
/// A right bracket: `]`.
RightBracket,
/// A colon (`:`) indicating the beginning of function arguments.
///
/// If a colon occurs outside of the function header, it will be
/// tokenized as a [Word](Token::Word).
Colon,
/// Same as with [Colon](Token::Colon).
Equals,
/// Two underscores, indicating text in _italics_.
DoubleUnderscore,
/// Two stars, indicating **bold** text.
DoubleStar,
/// A dollar sign, indicating _mathematical_ content.
Dollar,
/// A hashtag starting a _comment_.
Hashtag,
/// Everything else is just text.
Text(&'s str),
}
/// A tree representation of the source.
#[derive(Debug, PartialEq)]
pub struct SyntaxTree {
/// The children.
pub nodes: Vec<Node>,
}
impl SyntaxTree {
/// Create an empty syntax tree.
#[inline]
pub fn new() -> SyntaxTree {
SyntaxTree { nodes: vec![] }
}
}
/// A node in the abstract syntax tree.
#[derive(Debug, PartialEq)]
pub enum Node {
/// Whitespace between other nodes.
Space,
/// A line feed.
Newline,
/// Indicates that italics were enabled/disabled.
ToggleItalics,
/// Indicates that boldface was enabled/disabled.
ToggleBold,
/// Indicates that math mode was enabled/disabled.
ToggleMath,
/// Literal text.
Text(String),
/// A function invocation.
Func(FuncCall),
}
/// A function invocation consisting of header and body.
#[derive(Debug)]
pub struct FuncCall {
pub header: FuncHeader,
pub body: Box<dyn Function>,
}
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.
#[derive(Debug, Clone, PartialEq)]
pub struct FuncHeader {
pub name: String,
pub args: Vec<Expression>,
pub kwargs: HashMap<String, Expression>
}
/// A potentially unevaluated expression.
#[derive(Debug, Clone, PartialEq)]
pub enum Expression {}
|