From 515905d78db67005cdea1bec9e63e3a7172ce493 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 10 Jan 2021 18:22:06 +0100 Subject: [PATCH] =?UTF-8?q?Add=20angle=20value=20=F0=9F=93=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/eval/mod.rs | 3 ++- src/eval/value.rs | 16 +++++++++++----- src/parse/mod.rs | 1 + src/parse/tests.rs | 6 ++++-- src/syntax/expr.rs | 6 +++++- src/syntax/token.rs | 4 ++-- 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 68a97b43d..403fa58f9 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -18,7 +18,7 @@ use std::rc::Rc; use crate::color::Color; use crate::diag::Pass; use crate::env::SharedEnv; -use crate::geom::{Gen, Length, Relative}; +use crate::geom::{Angle, Gen, Length, Relative}; use crate::layout::{self, Expansion, NodeSpacing, NodeStack}; use crate::syntax::*; @@ -161,6 +161,7 @@ impl Eval for Spanned<&Expr> { Expr::Int(v) => Value::Int(*v), Expr::Float(v) => Value::Float(*v), Expr::Length(v, unit) => Value::Length(Length::with_unit(*v, *unit)), + Expr::Angle(v, unit) => Value::Angle(Angle::with_unit(*v, *unit)), Expr::Percent(v) => Value::Relative(Relative::new(v / 100.0)), Expr::Color(v) => Value::Color(Color::Rgba(*v)), Expr::Str(v) => Value::Str(v.clone()), diff --git a/src/eval/value.rs b/src/eval/value.rs index 708f4f044..67c468b06 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -6,7 +6,7 @@ use std::rc::Rc; use super::{Args, Eval, EvalContext}; use crate::color::Color; -use crate::geom::{Length, Linear, Relative}; +use crate::geom::{Angle, Length, Linear, Relative}; use crate::pretty::{pretty, Pretty, Printer}; use crate::syntax::{pretty_content_expr, Spanned, Tree, WithSpan}; @@ -19,10 +19,12 @@ pub enum Value { Bool(bool), /// An integer: `120`. Int(i64), - /// A floating-point number: `1.2, 200%`. + /// A floating-point number: `1.2`, `10e-4`. Float(f64), - /// A length: `2cm, 5.2in`. + /// A length: `12pt`, `3cm`. Length(Length), + /// An angle: `1.5rad`, `90deg`. + Angle(Angle), /// A relative value: `50%`. Relative(Relative), /// A combination of an absolute length and a relative value: `20% + 5cm`. @@ -62,6 +64,7 @@ impl Value { Self::Int(_) => i64::TYPE_NAME, Self::Float(_) => f64::TYPE_NAME, Self::Length(_) => Length::TYPE_NAME, + Self::Angle(_) => Angle::TYPE_NAME, Self::Relative(_) => Relative::TYPE_NAME, Self::Linear(_) => Linear::TYPE_NAME, Self::Color(_) => Color::TYPE_NAME, @@ -104,6 +107,7 @@ impl Pretty for Value { Value::Int(v) => write!(p, "{}", v).unwrap(), Value::Float(v) => write!(p, "{}", v).unwrap(), Value::Length(v) => write!(p, "{}", v).unwrap(), + Value::Angle(v) => write!(p, "{}", v).unwrap(), Value::Relative(v) => write!(p, "{}", v).unwrap(), Value::Linear(v) => write!(p, "{}", v).unwrap(), Value::Color(v) => write!(p, "{}", v).unwrap(), @@ -404,6 +408,7 @@ macro_rules! impl_primitive { impl_primitive! { bool: "boolean", Value::Bool } impl_primitive! { i64: "integer", Value::Int } impl_primitive! { Length: "length", Value::Length } +impl_primitive! { Angle: "angle", Value::Angle } impl_primitive! { Relative: "relative", Value::Relative } impl_primitive! { Color: "color", Value::Color } impl_primitive! { String: "string", Value::Str } @@ -501,8 +506,9 @@ mod tests { test_pretty(Value::None, "none"); test_pretty(false, "false"); test_pretty(12.4, "12.4"); - test_pretty(Length::ZERO, "0pt"); - test_pretty(Relative::ONE, "100%"); + test_pretty(Length::pt(5.5), "5.5pt"); + test_pretty(Angle::deg(90.0), "90deg"); + test_pretty(Relative::ONE / 2.0, "50%"); test_pretty(Relative::new(0.3) + Length::cm(2.0), "30% + 2cm"); test_pretty(Color::Rgba(RgbaColor::new(1, 1, 1, 0xff)), "#010101"); test_pretty("hello", r#""hello""#); diff --git a/src/parse/mod.rs b/src/parse/mod.rs index c03cb63db..4bf6f9257 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -331,6 +331,7 @@ fn value(p: &mut Parser) -> Option { Some(Token::Int(i)) => Expr::Int(i), Some(Token::Float(f)) => Expr::Float(f), Some(Token::Length(val, unit)) => Expr::Length(val, unit), + Some(Token::Angle(val, unit)) => Expr::Angle(val, unit), Some(Token::Percent(p)) => Expr::Percent(p), Some(Token::Hex(hex)) => Expr::Color(color(p, hex)), Some(Token::Str(token)) => Expr::Str(str(p, token)), diff --git a/src/parse/tests.rs b/src/parse/tests.rs index fd8c63ca5..ca09f4541 100644 --- a/src/parse/tests.rs +++ b/src/parse/tests.rs @@ -5,11 +5,11 @@ use std::fmt::Debug; use super::parse; use crate::color::RgbaColor; use crate::diag::{Diag, Level, Pass}; -use crate::geom::LengthUnit; +use crate::geom::{AngularUnit, LengthUnit}; use crate::syntax::*; use BinOp::*; -use Expr::{Bool, Color, Float, Int, Length, Percent}; +use Expr::{Angle, Bool, Color, Float, Int, Length, Percent}; use Node::{Emph, Expr as Block, Linebreak, Parbreak, Space, Strong}; use UnOp::*; @@ -601,6 +601,8 @@ fn test_parse_values() { t!("{50%}" Block(Percent(50.0))); t!("{4.5cm}" Block(Length(4.5, LengthUnit::Cm))); t!("{12e1pt}" Block(Length(12e1, LengthUnit::Pt))); + t!("{13rad}" Block(Angle(13.0, AngularUnit::Rad))); + t!("{45deg}" Block(Angle(45.0, AngularUnit::Deg))); // Strings. t!(r#"{"hi"}"# Block(Str("hi"))); diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 78f4feee5..268e6209d 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -1,6 +1,6 @@ use super::*; use crate::color::RgbaColor; -use crate::geom::LengthUnit; +use crate::geom::{AngularUnit, LengthUnit}; /// An expression. #[derive(Debug, Clone, PartialEq)] @@ -17,6 +17,8 @@ pub enum Expr { Float(f64), /// A length literal: `12pt`, `3cm`. Length(f64, LengthUnit), + /// An angle literal: `1.5rad`, `90deg`. + Angle(f64, AngularUnit), /// A percent literal: `50%`. /// /// _Note_: `50%` is stored as `50.0` here, but as `0.5` in the @@ -49,6 +51,7 @@ impl Pretty for Expr { Self::Int(v) => write!(p, "{}", v).unwrap(), Self::Float(v) => write!(p, "{}", v).unwrap(), Self::Length(v, u) => write!(p, "{}{}", v, u).unwrap(), + Self::Angle(v, u) => write!(p, "{}{}", v, u).unwrap(), Self::Percent(v) => write!(p, "{}%", v).unwrap(), Self::Color(v) => write!(p, "{}", v).unwrap(), Self::Str(s) => write!(p, "{:?}", &s).unwrap(), @@ -331,6 +334,7 @@ mod tests { test_pretty("{2.50}", "{2.5}"); test_pretty("{1e2}", "{100}"); test_pretty("{12pt}", "{12pt}"); + test_pretty("{90.0deg}", "{90deg}"); test_pretty("{50%}", "{50%}"); test_pretty("{#fff}", "{#ffffff}"); test_pretty(r#"{"hi\n"}"#, r#"{"hi\n"}"#); diff --git a/src/syntax/token.rs b/src/syntax/token.rs index 261f21044..7055d61a2 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -117,13 +117,13 @@ pub enum Token<'s> { Float(f64), /// A length: `12pt`, `3cm`. Length(f64, LengthUnit), + /// An angle: `90deg`. + Angle(f64, AngularUnit), /// A percentage: `50%`. /// /// _Note_: `50%` is stored as `50.0` here, as in the corresponding /// [literal](super::Expr::Percent). Percent(f64), - /// An angle: `90deg`. - Angle(f64, AngularUnit), /// A hex value: `#20d82a`. Hex(&'s str), /// A quoted string: `"..."`.