summaryrefslogtreecommitdiff
path: root/src/syntax
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2020-07-29 18:09:51 +0200
committerLaurenz <laurmaedje@gmail.com>2020-07-29 18:09:51 +0200
commitbbcdeb128cce04cd95714b7bc7af5a23a7e38bd2 (patch)
treee0a1620d335982669cd7671cbd71df46d100e9ea /src/syntax
parentf34ba3dcda182d9b9c14cc94fdb48810bf18bef0 (diff)
Move, rename and switch some things (boring) 🚚
- Problems -> Diagnostics - Position -> Pos - offset_spans -> Offset trait - Size -> Length (and some more size types renamed) - Paper into its own module - scope::Parser -> parsing::CallParser - Create `Decorations` alias - Remove lots of double newlines - Switch from f32 to f64
Diffstat (limited to 'src/syntax')
-rw-r--r--src/syntax/expr.rs55
-rw-r--r--src/syntax/func/keys.rs1
-rw-r--r--src/syntax/func/maps.rs67
-rw-r--r--src/syntax/func/mod.rs8
-rw-r--r--src/syntax/func/values.rs43
-rw-r--r--src/syntax/mod.rs6
-rw-r--r--src/syntax/parsing.rs74
-rw-r--r--src/syntax/scope.rs22
-rw-r--r--src/syntax/span.rs94
-rw-r--r--src/syntax/test.rs6
-rw-r--r--src/syntax/tokens.rs52
11 files changed, 215 insertions, 213 deletions
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs
index a1b3fd62..d849366c 100644
--- a/src/syntax/expr.rs
+++ b/src/syntax/expr.rs
@@ -6,13 +6,12 @@ use std::ops::Deref;
use std::str::FromStr;
use std::u8;
-use crate::problem::Problems;
-use crate::size::Size;
+use crate::diagnostic::Diagnostics;
+use crate::length::Length;
use super::func::{Key, Value};
use super::span::{Span, Spanned};
use super::tokens::is_identifier;
-
/// An argument or return value.
#[derive(Clone, PartialEq)]
pub enum Expr {
@@ -22,8 +21,8 @@ pub enum Expr {
Str(String),
/// A number: `1.2, 200%`.
Number(f64),
- /// A size: `2cm, 5.2in`.
- Size(Size),
+ /// A length: `2cm, 5.2in`.
+ Length(Length),
/// A bool: `true, false`.
Bool(bool),
/// A color value, including the alpha channel: `#f79143ff`.
@@ -32,7 +31,7 @@ pub enum Expr {
Tuple(Tuple),
/// A named tuple: `cmyk(37.7, 0, 3.9, 1.1)`.
NamedTuple(NamedTuple),
- /// An object: `{ fit: false, size: 12pt }`.
+ /// An object: `{ fit: false, width: 12pt }`.
Object(Object),
/// An operator that negates the contained expression.
Neg(Box<Spanned<Expr>>),
@@ -54,7 +53,7 @@ impl Expr {
Ident(_) => "identifier",
Str(_) => "string",
Number(_) => "number",
- Size(_) => "size",
+ Length(_) => "length",
Bool(_) => "bool",
Color(_) => "color",
Tuple(_) => "tuple",
@@ -76,7 +75,7 @@ impl Debug for Expr {
Ident(i) => i.fmt(f),
Str(s) => s.fmt(f),
Number(n) => n.fmt(f),
- Size(s) => s.fmt(f),
+ Length(s) => s.fmt(f),
Bool(b) => b.fmt(f),
Color(c) => c.fmt(f),
Tuple(t) => t.fmt(f),
@@ -128,7 +127,7 @@ impl Debug for Ident {
///
/// # Example
/// ```typst
-/// [box: background=#423abaff]
+/// [page: background=#423abaff]
/// ^^^^^^^^
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
@@ -256,28 +255,28 @@ impl Tuple {
}
/// Extract (and remove) the first matching value and remove and generate
- /// problems for all previous items that did not match.
- pub fn get<V: Value>(&mut self, problems: &mut Problems) -> Option<V> {
+ /// diagnostics for all previous items that did not match.
+ pub fn get<V: Value>(&mut self, diagnostics: &mut Diagnostics) -> Option<V> {
while !self.items.is_empty() {
let expr = self.items.remove(0);
let span = expr.span;
match V::parse(expr) {
Ok(output) => return Some(output),
- Err(v) => problems.push(Spanned { v, span }),
+ Err(v) => diagnostics.push(Spanned { v, span }),
}
}
None
}
/// Extract and return an iterator over all values that match and generate
- /// problems for all items that do not match.
- pub fn get_all<'a, V: Value>(&'a mut self, problems: &'a mut Problems)
+ /// diagnostics for all items that do not match.
+ pub fn get_all<'a, V: Value>(&'a mut self, diagnostics: &'a mut Diagnostics)
-> impl Iterator<Item=V> + 'a {
self.items.drain(..).filter_map(move |expr| {
let span = expr.span;
match V::parse(expr) {
Ok(output) => Some(output),
- Err(v) => { problems.push(Spanned { v, span }); None }
+ Err(v) => { diagnostics.push(Spanned { v, span }); None }
}
})
}
@@ -351,13 +350,9 @@ impl Deref for NamedTuple {
/// A key-value collection of identifiers and associated expressions.
///
-/// The pairs themselves are not spanned, but the combined spans can easily be
-/// retrieved by merging the spans of key and value as happening in
-/// [`FuncArg::span`](super::func::FuncArg::span).
-///
/// # Example
/// ```typst
-/// { fit: false, size: 12cm, items: (1, 2, 3) }
+/// { fit: false, width: 12cm, items: (1, 2, 3) }
/// ```
#[derive(Default, Clone, PartialEq)]
pub struct Object {
@@ -398,9 +393,9 @@ impl Object {
///
/// Inserts an error if the value does not match. If the key is not
/// contained, no error is inserted.
- pub fn get<V: Value>(&mut self, problems: &mut Problems, key: &str) -> Option<V> {
+ pub fn get<V: Value>(&mut self, diagnostics: &mut Diagnostics, key: &str) -> Option<V> {
let index = self.pairs.iter().position(|pair| pair.v.key.v.as_str() == key)?;
- self.get_index::<V>(problems, index)
+ self.get_index::<V>(diagnostics, index)
}
/// Extract (and remove) a pair with a matching key and value.
@@ -409,12 +404,12 @@ impl Object {
/// found, no error is inserted.
pub fn get_with_key<K: Key, V: Value>(
&mut self,
- problems: &mut Problems,
+ diagnostics: &mut Diagnostics,
) -> Option<(K, V)> {
for (index, pair) in self.pairs.iter().enumerate() {
let key = Spanned { v: pair.v.key.v.as_str(), span: pair.v.key.span };
if let Some(key) = K::parse(key) {
- return self.get_index::<V>(problems, index).map(|value| (key, value));
+ return self.get_index::<V>(diagnostics, index).map(|value| (key, value));
}
}
None
@@ -425,7 +420,7 @@ impl Object {
/// Inserts errors for values that do not match.
pub fn get_all<'a, K: Key, V: Value>(
&'a mut self,
- problems: &'a mut Problems,
+ diagnostics: &'a mut Diagnostics,
) -> impl Iterator<Item=(K, V)> + 'a {
let mut index = 0;
std::iter::from_fn(move || {
@@ -434,7 +429,7 @@ impl Object {
let key = Spanned { v: key.v.as_str(), span: key.span };
Some(if let Some(key) = K::parse(key) {
- self.get_index::<V>(problems, index).map(|v| (key, v))
+ self.get_index::<V>(diagnostics, index).map(|v| (key, v))
} else {
index += 1;
None
@@ -454,20 +449,20 @@ impl Object {
/// ```
pub fn get_all_spanned<'a, K: Key + 'a, V: Value + 'a>(
&'a mut self,
- problems: &'a mut Problems,
+ diagnostics: &'a mut Diagnostics,
) -> impl Iterator<Item=Spanned<(K, V)>> + 'a {
- self.get_all::<Spanned<K>, Spanned<V>>(problems)
+ self.get_all::<Spanned<K>, Spanned<V>>(diagnostics)
.map(|(k, v)| Spanned::new((k.v, v.v), Span::merge(k.span, v.span)))
}
/// Extract the argument at the given index and insert an error if the value
/// does not match.
- fn get_index<V: Value>(&mut self, problems: &mut Problems, index: usize) -> Option<V> {
+ fn get_index<V: Value>(&mut self, diagnostics: &mut Diagnostics, index: usize) -> Option<V> {
let expr = self.pairs.remove(index).v.value;
let span = expr.span;
match V::parse(expr) {
Ok(output) => Some(output),
- Err(v) => { problems.push(Spanned { v, span }); None }
+ Err(v) => { diagnostics.push(Spanned { v, span }); None }
}
}
diff --git a/src/syntax/func/keys.rs b/src/syntax/func/keys.rs
index b8f142ee..558667dd 100644
--- a/src/syntax/func/keys.rs
+++ b/src/syntax/func/keys.rs
@@ -7,7 +7,6 @@ use super::*;
use self::AxisKey::*;
use self::PaddingKey::*;
-
/// Key types are used to extract keyword arguments from
/// [`Objects`](crate::syntax::expr::Object). They represent the key part of a
/// keyword argument.
diff --git a/src/syntax/func/maps.rs b/src/syntax/func/maps.rs
index 44d8e1aa..2ac70223 100644
--- a/src/syntax/func/maps.rs
+++ b/src/syntax/func/maps.rs
@@ -1,18 +1,17 @@
//! Deduplicating maps and keys for argument parsing.
-use crate::problem::Problems;
+use crate::diagnostic::Diagnostics;
use crate::layout::prelude::*;
-use crate::size::{PSize, ValueBox};
+use crate::length::{ScaleLength, Value4};
use crate::syntax::span::Spanned;
use super::keys::*;
use super::values::*;
use super::*;
-
/// A map which deduplicates redundant arguments.
///
/// Whenever a duplicate argument is inserted into the map, through the
-/// functions `from_iter`, `insert` or `extend` an problems is added to the error
+/// functions `from_iter`, `insert` or `extend` an diagnostics is added to the error
/// list that needs to be passed to those functions.
///
/// All entries need to have span information to enable the error reporting.
@@ -28,27 +27,27 @@ impl<K, V> DedupMap<K, V> where K: Eq {
}
/// Create a new map from an iterator of spanned keys and values.
- pub fn from_iter<I>(problems: &mut Problems, iter: I) -> DedupMap<K, V>
+ pub fn from_iter<I>(diagnostics: &mut Diagnostics, iter: I) -> DedupMap<K, V>
where I: IntoIterator<Item=Spanned<(K, V)>> {
let mut map = DedupMap::new();
- map.extend(problems, iter);
+ map.extend(diagnostics, iter);
map
}
/// Add a spanned key-value pair.
- pub fn insert(&mut self, problems: &mut Problems, entry: Spanned<(K, V)>) {
+ pub fn insert(&mut self, diagnostics: &mut Diagnostics, entry: Spanned<(K, V)>) {
if self.map.iter().any(|e| e.v.0 == entry.v.0) {
- problems.push(error!(entry.span, "duplicate argument"));
+ diagnostics.push(error!(entry.span, "duplicate argument"));
} else {
self.map.push(entry);
}
}
/// Add multiple spanned key-value pairs.
- pub fn extend<I>(&mut self, problems: &mut Problems, items: I)
+ pub fn extend<I>(&mut self, diagnostics: &mut Diagnostics, items: I)
where I: IntoIterator<Item=Spanned<(K, V)>> {
for item in items.into_iter() {
- self.insert(problems, item);
+ self.insert(diagnostics, item);
}
}
@@ -71,15 +70,15 @@ impl<K, V> DedupMap<K, V> where K: Eq {
}
/// Create a new map where keys and values are mapped to new keys and
- /// values. When the mapping introduces new duplicates, problems are
+ /// values. When the mapping introduces new duplicates, diagnostics are
/// generated.
- pub fn dedup<F, K2, V2>(&self, problems: &mut Problems, mut f: F) -> DedupMap<K2, V2>
+ pub fn dedup<F, K2, V2>(&self, diagnostics: &mut Diagnostics, mut f: F) -> DedupMap<K2, V2>
where F: FnMut(&K, &V) -> (K2, V2), K2: Eq {
let mut map = DedupMap::new();
for Spanned { v: (key, value), span } in self.map.iter() {
let (key, value) = f(key, value);
- map.insert(problems, Spanned { v: (key, value), span: *span });
+ map.insert(diagnostics, Spanned { v: (key, value), span: *span });
}
map
@@ -98,21 +97,21 @@ pub struct AxisMap<V>(DedupMap<AxisKey, V>);
impl<V: Value> AxisMap<V> {
/// Parse an axis map from the object.
pub fn parse<K>(
- problems: &mut Problems,
+ diagnostics: &mut Diagnostics,
object: &mut Object,
) -> AxisMap<V> where K: Key + Into<AxisKey> {
let values: Vec<_> = object
- .get_all_spanned::<K, V>(problems)
+ .get_all_spanned::<K, V>(diagnostics)
.map(|s| s.map(|(k, v)| (k.into(), v)))
.collect();
- AxisMap(DedupMap::from_iter(problems, values))
+ AxisMap(DedupMap::from_iter(diagnostics, values))
}
/// Deduplicate from specific or generic to just specific axes.
- pub fn dedup(&self, problems: &mut Problems, axes: LayoutAxes) -> DedupMap<SpecificAxis, V>
+ pub fn dedup(&self, diagnostics: &mut Diagnostics, axes: LayoutAxes) -> DedupMap<SpecificAxis, V>
where V: Clone {
- self.0.dedup(problems, |key, val| (key.to_specific(axes), val.clone()))
+ self.0.dedup(diagnostics, |key, val| (key.to_specific(axes), val.clone()))
}
}
@@ -124,23 +123,23 @@ pub struct PosAxisMap<V>(DedupMap<PosAxisKey, V>);
impl<V: Value> PosAxisMap<V> {
/// Parse a positional/axis map from the function arguments.
pub fn parse<K>(
- problems: &mut Problems,
+ diagnostics: &mut Diagnostics,
args: &mut FuncArgs,
) -> PosAxisMap<V> where K: Key + Into<AxisKey> {
let mut map = DedupMap::new();
for &key in &[PosAxisKey::First, PosAxisKey::Second] {
- if let Some(Spanned { v, span }) = args.pos.get::<Spanned<V>>(problems) {
- map.insert(problems, Spanned { v: (key, v), span })
+ if let Some(Spanned { v, span }) = args.pos.get::<Spanned<V>>(diagnostics) {
+ map.insert(diagnostics, Spanned { v: (key, v), span })
}
}
let keywords: Vec<_> = args.key
- .get_all_spanned::<K, V>(problems)
+ .get_all_spanned::<K, V>(diagnostics)
.map(|s| s.map(|(k, v)| (PosAxisKey::Keyword(k.into()), v)))
.collect();
- map.extend(problems, keywords);
+ map.extend(diagnostics, keywords);
PosAxisMap(map)
}
@@ -149,7 +148,7 @@ impl<V: Value> PosAxisMap<V> {
/// or specific axes to just generic axes.
pub fn dedup<F>(
&self,
- problems: &mut Problems,
+ diagnostics: &mut Diagnostics,
axes: LayoutAxes,
mut f: F,
) -> DedupMap<GenericAxis, V>
@@ -157,7 +156,7 @@ impl<V: Value> PosAxisMap<V> {
F: FnMut(&V) -> Option<GenericAxis>,
V: Clone,
{
- self.0.dedup(problems, |key, val| {
+ self.0.dedup(diagnostics, |key, val| {
(match key {
PosAxisKey::First => f(val).unwrap_or(GenericAxis::Primary),
PosAxisKey::Second => f(val).unwrap_or(GenericAxis::Secondary),
@@ -171,24 +170,24 @@ impl<V: Value> PosAxisMap<V> {
/// A map for storing padding given for a combination of all sides, opposing
/// sides or single sides.
#[derive(Debug, Clone, PartialEq)]
-pub struct PaddingMap(DedupMap<PaddingKey<AxisKey>, Option<PSize>>);
+pub struct PaddingMap(DedupMap<PaddingKey<AxisKey>, Option<ScaleLength>>);
impl PaddingMap {
/// Parse a padding map from the function arguments.
- pub fn parse(problems: &mut Problems, args: &mut FuncArgs) -> PaddingMap {
+ pub fn parse(diagnostics: &mut Diagnostics, args: &mut FuncArgs) -> PaddingMap {
let mut map = DedupMap::new();
- let all = args.pos.get::<Spanned<Defaultable<PSize>>>(problems);
+ let all = args.pos.get::<Spanned<Defaultable<ScaleLength>>>(diagnostics);
if let Some(Spanned { v, span }) = all {
- map.insert(problems, Spanned { v: (PaddingKey::All, v.into()), span });
+ map.insert(diagnostics, Spanned { v: (PaddingKey::All, v.into()), span });
}
let paddings: Vec<_> = args.key
- .get_all_spanned::<PaddingKey<AxisKey>, Defaultable<PSize>>(problems)
+ .get_all_spanned::<PaddingKey<AxisKey>, Defaultable<ScaleLength>>(diagnostics)
.map(|s| s.map(|(k, v)| (k, v.into())))
.collect();
- map.extend(problems, paddings);
+ map.extend(diagnostics, paddings);
PaddingMap(map)
}
@@ -196,13 +195,13 @@ impl PaddingMap {
/// Apply the specified padding on a value box of optional, scalable sizes.
pub fn apply(
&self,
- problems: &mut Problems,
+ diagnostics: &mut Diagnostics,
axes: LayoutAxes,
- padding: &mut ValueBox<Option<PSize>>
+ padding: &mut Value4<Option<ScaleLength>>
) {
use PaddingKey::*;
- let map = self.0.dedup(problems, |key, &val| {
+ let map = self.0.dedup(diagnostics, |key, &val| {
(match key {
All => All,
Both(axis) => Both(axis.to_specific(axes)),
diff --git a/src/syntax/func/mod.rs b/src/syntax/func/mod.rs
index 4228488d..c2631727 100644
--- a/src/syntax/func/mod.rs
+++ b/src/syntax/func/mod.rs
@@ -1,7 +1,7 @@
//! Primitives for argument parsing in library functions.
use std::iter::FromIterator;
-use crate::problem::{Problem, Problems};
+use crate::diagnostic::{Diagnostic, Diagnostics};
use super::expr::{Expr, Ident, Tuple, Object, Pair};
use super::span::{Span, Spanned};
@@ -85,13 +85,13 @@ pub enum FuncArg {
pub trait OptionExt: Sized {
/// Add an error about a missing argument `arg` with the given span if the
/// option is `None`.
- fn or_missing(self, problems: &mut Problems, span: Span, arg: &str) -> Self;
+ fn or_missing(self, diagnostics: &mut Diagnostics, span: Span, arg: &str) -> Self;
}
impl<T> OptionExt for Option<T> {
- fn or_missing(self, problems: &mut Problems, span: Span, arg: &str) -> Self {
+ fn or_missing(self, diagnostics: &mut Diagnostics, span: Span, arg: &str) -> Self {
if self.is_none() {
- problems.push(error!(span, "missing argument: {}", arg));
+ diagnostics.push(error!(span, "missing argument: {}", arg));
}
self
}
diff --git a/src/syntax/func/values.rs b/src/syntax/func/values.rs
index 7a1aa912..3269f8e9 100644
--- a/src/syntax/func/values.rs
+++ b/src/syntax/func/values.rs
@@ -4,13 +4,12 @@ use std::fmt::{self, Display, Formatter};
use toddle::query::{FontStyle, FontWeight};
use crate::layout::prelude::*;
-use crate::size::{Size, ScaleSize};
-use crate::style::Paper;
+use crate::length::{Length, ScaleLength};
+use crate::paper::Paper;
use super::*;
use self::AlignmentValue::*;
-
/// Value types are used to extract the values of positional and keyword
/// arguments from [`Tuples`](crate::syntax::expr::Tuple) and
/// [`Objects`](crate::syntax::expr::Object). They represent the value part of
@@ -24,14 +23,14 @@ use self::AlignmentValue::*;
/// An implementation for `bool` might look as follows:
/// ```
/// # use typstc::error;
-/// # use typstc::problem::Problem;
+/// # use typstc::diagnostic::Diagnostic;
/// # use typstc::syntax::expr::Expr;
/// # use typstc::syntax::func::Value;
/// # use typstc::syntax::span::Spanned;
/// # struct Bool; /*
/// impl Value for bool {
/// # */ impl Value for Bool {
-/// fn parse(expr: Spanned<Expr>) -> Result<Self, Problem> {
+/// fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> {
/// match expr.v {
/// # /*
/// Expr::Bool(b) => Ok(b),
@@ -44,11 +43,11 @@ use self::AlignmentValue::*;
pub trait Value: Sized {
/// Parse an expression into this value or return an error if the expression
/// is valid for this value type.
- fn parse(expr: Spanned<Expr>) -> Result<Self, Problem>;
+ fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic>;
}
impl<V: Value> Value for Spanned<V> {
- fn parse(expr: Spanned<Expr>) -> Result<Self, Problem> {
+ fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> {
let span = expr.span;
V::parse(expr).map(|v| Spanned { v, span })
}
@@ -58,7 +57,7 @@ impl<V: Value> Value for Spanned<V> {
macro_rules! value {
($type:ty, $name:expr, $($p:pat => $r:expr),* $(,)?) => {
impl Value for $type {
- fn parse(expr: Spanned<Expr>) -> Result<Self, Problem> {
+ fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> {
#[allow(unreachable_patterns)]
match expr.v {
$($p => Ok($r)),*,
@@ -77,13 +76,13 @@ value!(Ident, "identifier", Expr::Ident(i) => i);
value!(String, "string", Expr::Str(s) => s);
value!(f64, "number", Expr::Number(n) => n);
value!(bool, "bool", Expr::Bool(b) => b);
-value!(Size, "size", Expr::Size(s) => s);
+value!(Length, "length", Expr::Length(s) => s);
value!(Tuple, "tuple", Expr::Tuple(t) => t);
value!(Object, "object", Expr::Object(o) => o);
-value!(ScaleSize, "number or size",
- Expr::Size(size) => ScaleSize::Absolute(size),
- Expr::Number(scale) => ScaleSize::Scaled(scale as f32),
+value!(ScaleLength, "number or length",
+ Expr::Length(length) => ScaleLength::Absolute(length),
+ Expr::Number(scale) => ScaleLength::Scaled(scale as f64),
);
/// A value type that matches [`Expr::Ident`] and [`Expr::Str`] and implements
@@ -108,20 +107,20 @@ impl From<StringLike> for String {
/// # Example
/// ```
/// # use typstc::syntax::func::{FuncArgs, Defaultable};
-/// # use typstc::size::Size;
+/// # use typstc::length::Length;
/// # let mut args = FuncArgs::new();
/// # let mut errors = vec![];
-/// args.key.get::<Defaultable<Size>>(&mut errors, "size");
+/// args.key.get::<Defaultable<Length>>(&mut errors, "length");
/// ```
/// This will yield.
/// ```typst
-/// [func: size=default] => None
-/// [func: size=2cm] => Some(Size::cm(2.0))
+/// [func: length=default] => None
+/// [func: length=2cm] => Some(Length::cm(2.0))
/// ```
pub struct Defaultable<V>(pub Option<V>);
impl<V: Value> Value for Defaultable<V> {
- fn parse(expr: Spanned<Expr>) -> Result<Self, Problem> {
+ fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> {
Ok(Defaultable(match expr.v {
Expr::Ident(ident) if ident.as_str() == "default" => None,
_ => Some(V::parse(expr)?)
@@ -136,7 +135,7 @@ impl<V> From<Defaultable<V>> for Option<V> {
}
impl Value for FontStyle {
- fn parse(expr: Spanned<Expr>) -> Result<Self, Problem> {
+ fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> {
FontStyle::from_name(Ident::parse(expr)?.as_str())
.ok_or_else(|| error!("invalid font style"))
}
@@ -145,7 +144,7 @@ impl Value for FontStyle {
/// The additional boolean specifies whether a number was clamped into the range
/// 100 - 900 to make it a valid font weight.
impl Value for (FontWeight, bool) {
- fn parse(expr: Spanned<Expr>) -> Result<Self, Problem> {
+ fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> {
match expr.v {
Expr::Number(weight) => {
let weight = weight.round();
@@ -170,14 +169,14 @@ impl Value for (FontWeight, bool) {
}
impl Value for Paper {
- fn parse(expr: Spanned<Expr>) -> Result<Self, Problem> {
+ fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> {
Paper::from_name(Ident::parse(expr)?.as_str())
.ok_or_else(|| error!("invalid paper type"))
}
}
impl Value for Direction {
- fn parse(expr: Spanned<Expr>) -> Result<Self, Problem> {
+ fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> {
Ok(match Ident::parse(expr)?.as_str() {
"left-to-right" | "ltr" | "LTR" => LeftToRight,
"right-to-left" | "rtl" | "RTL" => RightToLeft,
@@ -250,7 +249,7 @@ impl AlignmentValue {
}
impl Value for AlignmentValue {
- fn parse(expr: Spanned<Expr>) -> Result<Self, Problem> {
+ fn parse(expr: Spanned<Expr>) -> Result<Self, Diagnostic> {
Ok(match Ident::parse(expr)?.as_str() {
"origin" => Align(Origin),
"center" => Align(Center),
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs
index f7321c77..b67d8cd7 100644
--- a/src/syntax/mod.rs
+++ b/src/syntax/mod.rs
@@ -20,7 +20,6 @@ pub_use_mod!(scope);
pub_use_mod!(parsing);
pub_use_mod!(tokens);
-
/// Represents a parsed piece of source that can be layouted and in the future
/// also be queried for information used for refactorings, autocomplete, etc.
#[async_trait(?Send)]
@@ -94,6 +93,9 @@ impl PartialEq for Node {
}
}
+/// A list of spanned decorations.
+pub type Decorations = SpanVec<Decoration>;
+
/// Decorations for semantic syntax highlighting.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize)]
#[serde(rename_all = "camelCase")]
@@ -110,7 +112,6 @@ pub enum Decoration {
/// ^^^^^^
/// ```
InvalidFuncName,
-
/// A key of a keyword argument:
/// ```typst
/// [box: width=5cm]
@@ -123,7 +124,6 @@ pub enum Decoration {
/// ^^^^ ^^^^^
/// ```
ObjectKey,
-
/// An italic word.
Italic,
/// A bold word.
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"]"# =>
diff --git a/src/syntax/scope.rs b/src/syntax/scope.rs
index 74c64280..c6350836 100644
--- a/src/syntax/scope.rs
+++ b/src/syntax/scope.rs
@@ -3,16 +3,14 @@
use std::collections::HashMap;
use std::fmt::{self, Debug, Formatter};
-use crate::Pass;
use crate::func::ParseFunc;
-use super::func::FuncCall;
-use super::parsing::ParseState;
+use super::parsing::CallParser;
use super::Model;
/// A map from identifiers to function parsers.
pub struct Scope {
- parsers: HashMap<String, Box<Parser>>,
- fallback: Box<Parser>,
+ parsers: HashMap<String, Box<CallParser>>,
+ fallback: Box<CallParser>,
}
impl Scope {
@@ -22,7 +20,7 @@ impl Scope {
where F: ParseFunc<Meta=()> + Model + 'static {
Scope {
parsers: HashMap::new(),
- fallback: parser::<F>(()),
+ fallback: make_parser::<F>(()),
}
}
@@ -43,17 +41,17 @@ impl Scope {
where F: ParseFunc + Model + 'static {
self.parsers.insert(
name.to_string(),
- parser::<F>(metadata),
+ make_parser::<F>(metadata),
);
}
/// Return the parser with the given name if there is one.
- pub fn get_parser(&self, name: &str) -> Option<&Parser> {
+ pub fn get_parser(&self, name: &str) -> Option<&CallParser> {
self.parsers.get(name).map(AsRef::as_ref)
}
/// Return the fallback parser.
- pub fn get_fallback_parser(&self) -> &Parser {
+ pub fn get_fallback_parser(&self) -> &CallParser {
&*self.fallback
}
}
@@ -66,11 +64,7 @@ impl Debug for Scope {
}
}
-/// A function which parses the source of a function into a model type which
-/// implements [`Model`].
-type Parser = dyn Fn(FuncCall, &ParseState) -> Pass<Box<dyn Model>>;
-
-fn parser<F>(metadata: <F as ParseFunc>::Meta) -> Box<Parser>
+fn make_parser<F>(metadata: <F as ParseFunc>::Meta) -> Box<CallParser>
where F: ParseFunc + Model + 'static {
Box::new(move |f, s| {
F::parse(f, s, metadata.clone())
diff --git a/src/syntax/span.rs b/src/syntax/span.rs
index c8e2cddb..19562fb1 100644
--- a/src/syntax/span.rs
+++ b/src/syntax/span.rs
@@ -4,16 +4,22 @@ use std::fmt::{self, Debug, Formatter};
use std::ops::{Add, Sub};
use serde::Serialize;
+/// Span offsetting.
+pub trait Offset {
+ /// Offset all spans contained in `Self` by the given position.
+ fn offset(self, by: Pos) -> Self;
+}
+
/// A vector of spanned values of type `T`.
pub type SpanVec<T> = Vec<Spanned<T>>;
-/// [Offset](Span::offset) all spans in a vector of spanned things by a start
-/// position.
-pub fn offset_spans<T>(
- vec: SpanVec<T>,
- start: Position,
-) -> impl Iterator<Item=Spanned<T>> {
- vec.into_iter().map(move |s| s.map_span(|span| span.offset(start)))
+impl<T> Offset for SpanVec<T> {
+ fn offset(mut self, by: Pos) -> Self {
+ for spanned in &mut self {
+ spanned.span = spanned.span.offset(by);
+ }
+ self
+ }
}
/// A value with the span it corresponds to in the source code.
@@ -53,6 +59,12 @@ impl<T> Spanned<T> {
}
}
+impl<T> Offset for Spanned<T> {
+ fn offset(self, by: Pos) -> Self {
+ self.map_span(|span| span.offset(by))
+ }
+}
+
impl<T: Debug> Debug for Spanned<T> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.v.fmt(f)?;
@@ -68,20 +80,25 @@ impl<T: Debug> Debug for Spanned<T> {
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
pub struct Span {
/// The inclusive start position.
- pub start: Position,
+ pub start: Pos,
/// The inclusive end position.
- pub end: Position,
+ pub end: Pos,
}
impl Span {
/// The zero span.
- pub const ZERO: Span = Span { start: Position::ZERO, end: Position::ZERO };
+ pub const ZERO: Span = Span { start: Pos::ZERO, end: Pos::ZERO };
/// Create a new span from start and end positions.
- pub fn new(start: Position, end: Position) -> Span {
+ pub fn new(start: Pos, end: Pos) -> Span {
Span { start, end }
}
+ /// Create a span including just a single position.
+ pub fn at(pos: Pos) -> Span {
+ Span { start: pos, end: pos }
+ }
+
/// Create a new span with the earlier start and later end position.
pub fn merge(a: Span, b: Span) -> Span {
Span {
@@ -90,24 +107,17 @@ impl Span {
}
}
- /// Create a span including just a single position.
- pub fn at(pos: Position) -> Span {
- Span { start: pos, end: pos }
- }
-
/// Expand a span by merging it with another span.
pub fn expand(&mut self, other: Span) {
*self = Span::merge(*self, other)
}
+}
- /// Offset a span by a start position.
- ///
- /// This is, for example, used to translate error spans from function local
- /// to global.
- pub fn offset(self, start: Position) -> Span {
+impl Offset for Span {
+ fn offset(self, by: Pos) -> Self {
Span {
- start: start + self.start,
- end: start + self.end,
+ start: self.start.offset(by),
+ end: self.end.offset(by),
}
}
}
@@ -120,34 +130,40 @@ impl Debug for Span {
/// Zero-indexed line-column position in source code.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize)]
-pub struct Position {
+pub struct Pos {
/// The zero-indexed line.
pub line: usize,
/// The zero-indexed column.
pub column: usize,
}
-impl Position {
+impl Pos {
/// The line 0, column 0 position.
- pub const ZERO: Position = Position { line: 0, column: 0 };
+ pub const ZERO: Pos = Pos { line: 0, column: 0 };
/// Create a new position from line and column.
- pub fn new(line: usize, column: usize) -> Position {
- Position { line, column }
+ pub fn new(line: usize, column: usize) -> Pos {
+ Pos { line, column }
+ }
+}
+
+impl Offset for Pos {
+ fn offset(self, by: Pos) -> Self {
+ by + self
}
}
-impl Add for Position {
- type Output = Position;
+impl Add for Pos {
+ type Output = Pos;
- fn add(self, rhs: Position) -> Position {
+ fn add(self, rhs: Pos) -> Pos {
if rhs.line == 0 {
- Position {
+ Pos {
line: self.line,
column: self.column + rhs.column
}
} else {
- Position {
+ Pos {
line: self.line + rhs.line,
column: rhs.column,
}
@@ -155,17 +171,17 @@ impl Add for Position {
}
}
-impl Sub for Position {
- type Output = Position;
+impl Sub for Pos {
+ type Output = Pos;
- fn sub(self, rhs: Position) -> Position {
+ fn sub(self, rhs: Pos) -> Pos {
if self.line == rhs.line {
- Position {
+ Pos {
line: 0,
column: self.column - rhs.column
}
} else {
- Position {
+ Pos {
line: self.line - rhs.line,
column: self.column,
}
@@ -173,7 +189,7 @@ impl Sub for Position {
}
}
-impl Debug for Position {
+impl Debug for Pos {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}:{}", self.line, self.column)
}
diff --git a/src/syntax/test.rs b/src/syntax/test.rs
index 7b1e0830..639fbb61 100644
--- a/src/syntax/test.rs
+++ b/src/syntax/test.rs
@@ -39,11 +39,11 @@ macro_rules! span_vec {
macro_rules! span_item {
(($sl:tt:$sc:tt, $el:tt:$ec:tt, $v:expr)) => ({
- use $crate::syntax::span::{Position, Span, Spanned};
+ use $crate::syntax::span::{Pos, Span, Spanned};
Spanned {
span: Span::new(
- Position::new($sl, $sc),
- Position::new($el, $ec)
+ Pos::new($sl, $sc),
+ Pos::new($el, $ec)
),
v: $v
}
diff --git a/src/syntax/tokens.rs b/src/syntax/tokens.rs
index 10200708..9bb95c97 100644
--- a/src/syntax/tokens.rs
+++ b/src/syntax/tokens.rs
@@ -2,8 +2,8 @@ use std::iter::Peekable;
use std::str::Chars;
use unicode_xid::UnicodeXID;
-use crate::size::Size;
-use super::span::{Position, Span, Spanned};
+use crate::length::Length;
+use super::span::{Pos, Span, Spanned};
use Token::*;
use TokenMode::*;
@@ -73,8 +73,8 @@ pub enum Token<'s> {
},
/// A number in a function header: `3.14`.
ExprNumber(f64),
- /// A size in a function header: `12pt`.
- ExprSize(Size),
+ /// A length in a function header: `12pt`.
+ ExprLength(Length),
/// A boolean in a function header: `true | false`.
ExprBool(bool),
/// A hex value in a function header: `#20d82a`.
@@ -129,7 +129,7 @@ impl<'s> Token<'s> {
ExprIdent(_) => "identifier",
ExprStr { .. } => "string",
ExprNumber(_) => "number",
- ExprSize(_) => "size",
+ ExprLength(_) => "length",
ExprBool(_) => "bool",
ExprHex(_) => "hex value",
Plus => "plus",
@@ -153,7 +153,7 @@ pub struct Tokens<'s> {
src: &'s str,
mode: TokenMode,
iter: Peekable<Chars<'s>>,
- position: Position,
+ pos: Pos,
index: usize,
}
@@ -172,12 +172,12 @@ impl<'s> Tokens<'s> {
///
/// The first token's span starts an the given `offset` position instead of
/// the zero position.
- pub fn new(src: &'s str, offset: Position, mode: TokenMode) -> Tokens<'s> {
+ pub fn new(src: &'s str, offset: Pos, mode: TokenMode) -> Tokens<'s> {
Tokens {
src,
mode,
iter: src.chars().peekable(),
- position: offset,
+ pos: offset,
index: 0,
}
}
@@ -190,8 +190,8 @@ impl<'s> Tokens<'s> {
/// The line-colunn position in the source at which the last token ends and
/// next token will start.
- pub fn pos(&self) -> Position {
- self.position
+ pub fn pos(&self) -> Pos {
+ self.pos
}
}
@@ -315,14 +315,14 @@ impl<'s> Tokens<'s> {
}, true, 0, -2).0)
}
- fn read_whitespace(&mut self, start: Position) -> Token<'s> {
+ fn read_whitespace(&mut self, start: Pos) -> Token<'s> {
self.read_string_until(|n| !n.is_whitespace(), false, 0, 0);
let end = self.pos();
Space(end.line - start.line)
}
- fn read_function(&mut self, start: Position) -> Token<'s> {
+ fn read_function(&mut self, start: Pos) -> Token<'s> {
let (header, terminated) = self.read_function_part(Header);
self.eat();
@@ -354,7 +354,7 @@ impl<'s> Tokens<'s> {
self.eat();
match n {
- '[' => { self.read_function(Position::ZERO); }
+ '[' => { self.read_function(Pos::ZERO); }
'/' if self.peek() == Some('/') => { self.read_line_comment(); }
'/' if self.peek() == Some('*') => { self.read_block_comment(); }
'"' if mode == Header => { self.read_string(); }
@@ -427,8 +427,8 @@ impl<'s> Tokens<'s> {
ExprNumber(num)
} else if let Some(num) = parse_percentage(text) {
ExprNumber(num / 100.0)
- } else if let Ok(size) = text.parse::<Size>() {
- ExprSize(size)
+ } else if let Ok(length) = text.parse::<Length>() {
+ ExprLength(length)
} else if is_identifier(text) {
ExprIdent(text)
} else {
@@ -476,10 +476,10 @@ impl<'s> Tokens<'s> {
self.index += c.len_utf8();
if is_newline_char(c) && !(c == '\r' && self.peek() == Some('\n')) {
- self.position.line += 1;
- self.position.column = 0;
+ self.pos.line += 1;
+ self.pos.column = 0;
} else {
- self.position.column += 1;
+ self.pos.column += 1;
}
Some(c)
@@ -543,7 +543,7 @@ mod tests {
LeftBrace as LB, RightBrace as RB,
ExprIdent as Id,
ExprNumber as Num,
- ExprSize as Sz,
+ ExprLength as Len,
ExprBool as Bool,
ExprHex as Hex,
Text as T,
@@ -557,7 +557,7 @@ mod tests {
macro_rules! t {
($mode:expr, $source:expr => [$($tokens:tt)*]) => {
let (exp, spans) = span_vec![$($tokens)*];
- let found = Tokens::new($source, Position::ZERO, $mode).collect::<Vec<_>>();
+ let found = Tokens::new($source, Pos::ZERO, $mode).collect::<Vec<_>>();
check($source, exp, found, spans);
}
}
@@ -640,13 +640,13 @@ mod tests {
t!(Header, "__main__" => [Id("__main__")]);
t!(Header, ".func.box" => [Id(".func.box")]);
t!(Header, "arg, _b, _1" => [Id("arg"), Comma, S(0), Id("_b"), Comma, S(0), Id("_1")]);
- t!(Header, "12_pt, 12pt" => [Invalid("12_pt"), Comma, S(0), Sz(Size::pt(12.0))]);
- t!(Header, "1e5in" => [Sz(Size::inches(100000.0))]);
- t!(Header, "2.3cm" => [Sz(Size::cm(2.3))]);
- t!(Header, "12e-3in" => [Sz(Size::inches(12e-3))]);
- t!(Header, "6.1cm + 4pt,a=1*2" => [Sz(Size::cm(6.1)), S(0), Plus, S(0), Sz(Size::pt(4.0)), Comma, Id("a"), Equals, Num(1.0), Star, Num(2.0)]);
+ t!(Header, "12_pt, 12pt" => [Invalid("12_pt"), Comma, S(0), Len(Length::pt(12.0))]);
+ t!(Header, "1e5in" => [Len(Length::inches(100000.0))]);
+ t!(Header, "2.3cm" => [Len(Length::cm(2.3))]);
+ t!(Header, "12e-3in" => [Len(Length::inches(12e-3))]);
+ t!(Header, "6.1cm + 4pt,a=1*2" => [Len(Length::cm(6.1)), S(0), Plus, S(0), Len(Length::pt(4.0)), Comma, Id("a"), Equals, Num(1.0), Star, Num(2.0)]);
t!(Header, "(5 - 1) / 2.1" => [LP, Num(5.0), S(0), Min, S(0), Num(1.0), RP, S(0), Slash, S(0), Num(2.1)]);
- t!(Header, "02.4mm" => [Sz(Size::mm(2.4))]);
+ t!(Header, "02.4mm" => [Len(Length::mm(2.4))]);
t!(Header, "2.4.cm" => [Invalid("2.4.cm")]);
t!(Header, "(1,2)" => [LP, Num(1.0), Comma, Num(2.0), RP]);
t!(Header, "{abc}" => [LB, Id("abc"), RB]);