summaryrefslogtreecommitdiff
path: root/src/syntax/parsing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/syntax/parsing.rs')
-rw-r--r--src/syntax/parsing.rs74
1 files changed, 37 insertions, 37 deletions
diff --git a/src/syntax/parsing.rs b/src/syntax/parsing.rs
index a0d9c4e4..a8151125 100644
--- a/src/syntax/parsing.rs
+++ b/src/syntax/parsing.rs
@@ -4,9 +4,12 @@ use std::str::FromStr;
use super::expr::*;
use super::func::{FuncCall, FuncHeader, FuncArgs, FuncArg};
-use super::span::{Position, Span, Spanned};
+use super::span::{Pos, Span, Spanned};
use super::*;
+/// A function which parses a function call into a model.
+pub type CallParser = dyn Fn(FuncCall, &ParseState) -> Pass<Box<dyn Model>>;
+
/// The state which can influence how a string of source code is parsed.
///
/// Parsing is pure - when passed in the same state and source code, the output
@@ -22,7 +25,7 @@ pub struct ParseState {
/// `offset` position. This is used to make spans of a function body relative to
/// the start of the function as a whole as opposed to the start of the
/// function's body.
-pub fn parse(src: &str, offset: Position, state: &ParseState) -> Pass<SyntaxModel> {
+pub fn parse(src: &str, offset: Pos, state: &ParseState) -> Pass<SyntaxModel> {
let mut model = SyntaxModel::new();
let mut feedback = Feedback::new();
@@ -102,7 +105,7 @@ impl<'s> FuncParser<'s> {
state,
// Start at column 1 because the opening bracket is also part of
// the function, but not part of the `header` string.
- tokens: Tokens::new(header, Position::new(0, 1), TokenMode::Header),
+ tokens: Tokens::new(header, Pos::new(0, 1), TokenMode::Header),
peeked: None,
body,
feedback: Feedback::new(),
@@ -127,7 +130,7 @@ impl<'s> FuncParser<'s> {
}
};
- self.feedback.decos.push(Spanned::new(deco, header.name.span));
+ self.feedback.decorations.push(Spanned::new(deco, header.name.span));
(parser, header)
} else {
// Parse the body with the fallback parser even when the header is
@@ -186,7 +189,7 @@ impl<'s> FuncParser<'s> {
self.skip_white();
let key = ident;
- self.feedback.decos.push(
+ self.feedback.decorations.push(
Spanned::new(Decoration::ArgumentKey, key.span)
);
@@ -325,7 +328,7 @@ impl FuncParser<'_> {
}
Token::ExprNumber(n) => self.eat_span(Expr::Number(n)),
- Token::ExprSize(s) => self.eat_span(Expr::Size(s)),
+ Token::ExprLength(s) => self.eat_span(Expr::Length(s)),
Token::ExprBool(b) => self.eat_span(Expr::Bool(b)),
Token::ExprHex(s) => {
if let Ok(color) = RgbaColor::from_str(s) {
@@ -423,7 +426,7 @@ impl FuncParser<'_> {
continue;
}
- self.feedback.decos.push(
+ self.feedback.decorations.push(
Spanned::new(Decoration::ObjectKey, key.span)
);
@@ -464,7 +467,7 @@ impl FuncParser<'_> {
}
}
- fn expect_at(&mut self, token: Token<'_>, pos: Position) -> bool {
+ fn expect_at(&mut self, token: Token<'_>, pos: Pos) -> bool {
if self.check(token) {
self.eat();
true
@@ -485,11 +488,11 @@ impl FuncParser<'_> {
}
}
- fn expected_at(&mut self, thing: &str, pos: Position) {
+ fn expected_at(&mut self, thing: &str, pos: Pos) {
error!(@self.feedback, Span::at(pos), "expected {}", thing);
}
- fn expected_found_or_at(&mut self, thing: &str, pos: Position) {
+ fn expected_found_or_at(&mut self, thing: &str, pos: Pos) {
if self.eof() {
self.expected_at(thing, pos)
} else {
@@ -544,7 +547,7 @@ impl<'s> FuncParser<'s> {
self.peek().is_none()
}
- fn pos(&self) -> Position {
+ fn pos(&self) -> Pos {
self.peeked.flatten()
.map(|s| s.span.start)
.unwrap_or_else(|| self.tokens.pos())
@@ -604,13 +607,13 @@ fn unescape_raw(raw: &str) -> Vec<String> {
#[cfg(test)]
#[allow(non_snake_case)]
mod tests {
- use crate::size::Size;
+ use crate::length::Length;
use super::super::test::{check, DebugFn};
use super::super::func::Value;
use super::*;
use Decoration::*;
- use Expr::{Number as Num, Size as Sz, Bool};
+ use Expr::{Number as Num, Length as Len, Bool};
use Node::{
Space as S, ToggleItalic as Italic, ToggleBolder as Bold,
Parbreak, Linebreak,
@@ -625,7 +628,7 @@ mod tests {
p!($source => [$($model)*], []);
};
- ($source:expr => [$($model:tt)*], [$($problems:tt)*] $(, [$($decos:tt)*])? $(,)?) => {
+ ($source:expr => [$($model:tt)*], [$($diagnostics:tt)*] $(, [$($decos:tt)*])? $(,)?) => {
let mut scope = Scope::new::<DebugFn>();
scope.add::<DebugFn>("f");
scope.add::<DebugFn>("n");
@@ -633,25 +636,25 @@ mod tests {
scope.add::<DebugFn>("val");
let state = ParseState { scope };
- let pass = parse($source, Position::ZERO, &state);
+ let pass = parse($source, Pos::ZERO, &state);
// Test model.
let (exp, cmp) = span_vec![$($model)*];
check($source, exp, pass.output.nodes, cmp);
- // Test problems.
- let (exp, cmp) = span_vec![$($problems)*];
+ // Test diagnostics.
+ let (exp, cmp) = span_vec![$($diagnostics)*];
let exp = exp.into_iter()
.map(|s: Spanned<&str>| s.map(|e| e.to_string()))
.collect::<Vec<_>>();
- let found = pass.feedback.problems.into_iter()
+ let found = pass.feedback.diagnostics.into_iter()
.map(|s| s.map(|e| e.message))
.collect::<Vec<_>>();
check($source, exp, found, cmp);
// Test decos.
$(let (exp, cmp) = span_vec![$($decos)*];
- check($source, exp, pass.feedback.decos, cmp);)?
+ check($source, exp, pass.feedback.decorations, cmp);)?
};
}
@@ -664,7 +667,6 @@ mod tests {
fn Id(text: &str) -> Expr { Expr::Ident(Ident(text.to_string())) }
fn Str(text: &str) -> Expr { Expr::Str(text.to_string()) }
- fn Pt(points: f32) -> Expr { Expr::Size(Size::pt(points)) }
fn Color(r: u8, g: u8, b: u8, a: u8) -> Expr { Expr::Color(RgbaColor::new(r, g, b, a)) }
fn ColorStr(color: &str) -> Expr { Expr::Color(RgbaColor::from_str(color).expect("invalid test color")) }
fn ColorHealed() -> Expr { Expr::Color(RgbaColor::new_healed(0, 0, 0, 255)) }
@@ -878,8 +880,8 @@ mod tests {
pval!("name" => (Id("name")));
pval!("\"hi\"" => (Str("hi")));
pval!("3.14" => (Num(3.14)));
- pval!("4.5cm" => (Sz(Size::cm(4.5))));
- pval!("12e1pt" => (Pt(12e1)));
+ pval!("4.5cm" => (Len(Length::cm(4.5))));
+ pval!("12e1pt" => (Len(Length::pt(12e1))));
pval!("#f7a20500" => (ColorStr("f7a20500")));
pval!("\"a\n[]\\\"string\"" => (Str("a\n[]\"string")));
@@ -890,10 +892,10 @@ mod tests {
pval!("(hi)" => (Id("hi")));
// Math.
- pval!("3.2in + 6pt" => (Add(Sz(Size::inches(3.2)), Sz(Size::pt(6.0)))));
+ pval!("3.2in + 6pt" => (Add(Len(Length::inches(3.2)), Len(Length::pt(6.0)))));
pval!("5 - 0.01" => (Sub(Num(5.0), Num(0.01))));
- pval!("(3mm * 2)" => (Mul(Sz(Size::mm(3.0)), Num(2.0))));
- pval!("12e-3cm/1pt" => (Div(Sz(Size::cm(12e-3)), Sz(Size::pt(1.0)))));
+ pval!("(3mm * 2)" => (Mul(Len(Length::mm(3.0)), Num(2.0))));
+ pval!("12e-3cm/1pt" => (Div(Len(Length::cm(12e-3)), Len(Length::pt(1.0)))));
// Unclosed string.
p!("[val: \"hello]" => [func!("val": (Str("hello]")), {})], [
@@ -912,26 +914,24 @@ mod tests {
fn parse_complex_mathematical_expressions() {
// Valid expressions.
pval!("(3.2in + 6pt)*(5/2-1)" => (Mul(
- Add(Sz(Size::inches(3.2)), Sz(Size::pt(6.0))),
+ Add(Len(Length::inches(3.2)), Len(Length::pt(6.0))),
Sub(Div(Num(5.0), Num(2.0)), Num(1.0))
)));
pval!("(6.3E+2+4* - 3.2pt)/2" => (Div(
- Add(Num(6.3e2),Mul(Num(4.0), Neg(Pt(3.2)))),
+ Add(Num(6.3e2), Mul(Num(4.0), Neg(Len(Length::pt(3.2))))),
Num(2.0)
)));
// Associativity of multiplication and division.
- p!("[val: 3/4*5]" =>
- [func!("val": (Mul(Div(Num(3.0), Num(4.0)), Num(5.0))), {})]
- );
+ pval!("3/4*5" => (Mul(Div(Num(3.0), Num(4.0)), Num(5.0))));
// Invalid expressions.
- p!("[val: 4pt--]" => [func!("val": (Pt(4.0)))], [
+ p!("[val: 4pt--]" => [func!("val": (Len(Length::pt(4.0))))], [
(0:10, 0:11, "dangling minus"),
(0:6, 0:10, "missing right summand")
]);
p!("[val: 3mm+4pt*]" =>
- [func!("val": (Add(Sz(Size::mm(3.0)), Pt(4.0))))],
+ [func!("val": (Add(Len(Length::mm(3.0)), Len(Length::pt(4.0)))))],
[(0:10, 0:14, "missing right factor")],
);
}
@@ -976,7 +976,7 @@ mod tests {
// Nested tuples.
pval!("css(1pt, rgb(90, 102, 254), \"solid\")" => (named_tuple!(
"css",
- Pt(1.0),
+ Len(Length::pt(1.0)),
named_tuple!("rgb", Num(90.0), Num(102.0), Num(254.0)),
Str("solid"),
)));
@@ -1012,7 +1012,7 @@ mod tests {
// Missing key.
p!("[val: {,}]" => [val()], [(0:7, 0:8, "expected key, found comma")]);
- p!("[val: { 12pt }]" => [val()], [(0:8, 0:12, "expected key, found size")]);
+ p!("[val: { 12pt }]" => [val()], [(0:8, 0:12, "expected key, found length")]);
p!("[val: { : }]" => [val()], [(0:8, 0:9, "expected key, found colon")]);
// Missing colon.
@@ -1053,7 +1053,7 @@ mod tests {
Num(1.0),
object!(
"ab" => tuple!(),
- "d" => tuple!(Num(3.0), Pt(14.0)),
+ "d" => tuple!(Num(3.0), Len(Length::pt(14.0))),
),
),
Bool(false),
@@ -1085,7 +1085,7 @@ mod tests {
#[test]
fn parse_multiple_mixed_arguments() {
p!("[val: 12pt, key=value]" =>
- [func!("val": (Pt(12.0)), { "key" => Id("value") })], [],
+ [func!("val": (Len(Length::pt(12.0))), { "key" => Id("value") })], [],
[(0:12, 0:15, ArgumentKey), (0:1, 0:4, ValidFuncName)],
);
pval!("a , x=\"b\" , c" => (Id("a"), Id("c")), { "x" => Str("b"), });
@@ -1144,7 +1144,7 @@ mod tests {
fn parse_invalid_commas() {
// Missing commas.
p!("[val: 1pt 1]" =>
- [func!("val": (Pt(1.0), Num(1.0)), {})],
+ [func!("val": (Len(Length::pt(1.0)), Num(1.0)), {})],
[(0:9, 0:9, "expected comma")],
);
p!(r#"[val: _"s"]"# =>