From c43997de0a4fa958bc6bdfd5c29a47e1ba14800d Mon Sep 17 00:00:00 2001 From: Malo <57839069+MDLC01@users.noreply.github.com> Date: Thu, 15 Aug 2024 22:04:50 +0200 Subject: [PATCH] Move `calc.nan` to `float.nan` and add `float.inf` (#4733) --- crates/typst-macros/src/scope.rs | 73 +++++++++++++-------- crates/typst/src/foundations/calc.rs | 1 - crates/typst/src/foundations/float.rs | 18 +++-- crates/typst/src/foundations/repr.rs | 6 +- tests/ref/float-repr.png | Bin 2443 -> 2497 bytes tests/ref/grid-rowspan-split-15.png | Bin 2948 -> 3058 bytes tests/ref/ops-multiply-inf-with-length.png | Bin 2414 -> 2479 bytes tests/suite/foundations/float.typ | 18 ++--- tests/suite/scripting/ops.typ | 4 +- 9 files changed, 74 insertions(+), 46 deletions(-) diff --git a/crates/typst-macros/src/scope.rs b/crates/typst-macros/src/scope.rs index 07a0efe05..d86c6aea9 100644 --- a/crates/typst-macros/src/scope.rs +++ b/crates/typst-macros/src/scope.rs @@ -13,11 +13,26 @@ pub fn scope(_: TokenStream, item: syn::Item) -> Result { let self_ty = &item.self_ty; + let mut primitive_ident_ext = None; + if let syn::Type::Path(syn::TypePath { path, .. }) = self_ty.as_ref() { + if let Some(ident) = path.get_ident() { + if is_primitive(ident) { + let ident_ext = quote::format_ident!("{ident}Ext"); + primitive_ident_ext = Some(ident_ext); + } + } + } + + let self_ty_expr = match &primitive_ident_ext { + None => quote! { #self_ty }, + Some(ident_ext) => quote! { <#self_ty as #ident_ext> }, + }; + let mut definitions = vec![]; let mut constructor = quote! { None }; for child in &mut item.items { let def = match child { - syn::ImplItem::Const(item) => handle_const(self_ty, item)?, + syn::ImplItem::Const(item) => handle_const(&self_ty_expr, item)?, syn::ImplItem::Fn(item) => match handle_fn(self_ty, item)? { FnKind::Member(tokens) => tokens, FnKind::Constructor(tokens) => { @@ -33,14 +48,10 @@ pub fn scope(_: TokenStream, item: syn::Item) -> Result { item.items.retain(|item| !matches!(item, syn::ImplItem::Verbatim(_))); - let mut base = quote! { #item }; - if let syn::Type::Path(syn::TypePath { path, .. }) = self_ty.as_ref() { - if let Some(ident) = path.get_ident() { - if is_primitive(ident) { - base = rewrite_primitive_base(&item, ident); - } - } - } + let base = match &primitive_ident_ext { + None => quote! { #item }, + Some(ident_ext) => rewrite_primitive_base(&item, ident_ext), + }; Ok(quote! { #base @@ -60,7 +71,7 @@ pub fn scope(_: TokenStream, item: syn::Item) -> Result { } /// Process a const item and returns its definition. -fn handle_const(self_ty: &syn::Type, item: &syn::ImplItemConst) -> Result { +fn handle_const(self_ty: &TokenStream, item: &syn::ImplItemConst) -> Result { let ident = &item.ident; let name = ident.to_string().to_kebab_case(); Ok(quote! { scope.define(#name, #self_ty::#ident) }) @@ -117,31 +128,39 @@ fn is_primitive(ident: &syn::Ident) -> bool { } /// Rewrite an impl block for a primitive into a trait + trait impl. -fn rewrite_primitive_base(item: &syn::ItemImpl, ident: &syn::Ident) -> TokenStream { +fn rewrite_primitive_base(item: &syn::ItemImpl, ident_ext: &syn::Ident) -> TokenStream { let mut sigs = vec![]; let mut items = vec![]; for sub in &item.items { - let syn::ImplItem::Fn(mut func) = sub.clone() else { continue }; - func.vis = syn::Visibility::Inherited; - items.push(func.clone()); + match sub.clone() { + syn::ImplItem::Fn(mut func) => { + func.vis = syn::Visibility::Inherited; + items.push(func.clone()); - let mut sig = func.sig; - let inputs = sig.inputs.iter().cloned().map(|mut input| { - if let syn::FnArg::Typed(typed) = &mut input { - typed.attrs.clear(); + let mut sig = func.sig; + let inputs = sig.inputs.iter().cloned().map(|mut input| { + if let syn::FnArg::Typed(typed) = &mut input { + typed.attrs.clear(); + } + input + }); + sig.inputs = parse_quote! { #(#inputs),* }; + + let ident_data = quote::format_ident!("{}_data", sig.ident); + sigs.push(quote! { #sig; }); + sigs.push(quote! { + fn #ident_data() -> &'static #foundations::NativeFuncData; + }); } - input - }); - sig.inputs = parse_quote! { #(#inputs),* }; - let ident_data = quote::format_ident!("{}_data", sig.ident); - sigs.push(quote! { #sig; }); - sigs.push(quote! { - fn #ident_data() -> &'static #foundations::NativeFuncData; - }); + syn::ImplItem::Const(cons) => { + sigs.push(quote! { #cons }); + } + + _ => {} + } } - let ident_ext = quote::format_ident!("{ident}Ext"); let self_ty = &item.self_ty; quote! { trait #ident_ext { diff --git a/crates/typst/src/foundations/calc.rs b/crates/typst/src/foundations/calc.rs index d07b23c5a..287bc828a 100644 --- a/crates/typst/src/foundations/calc.rs +++ b/crates/typst/src/foundations/calc.rs @@ -50,7 +50,6 @@ pub fn module() -> Module { scope.define_func::(); scope.define_func::(); scope.define("inf", f64::INFINITY); - scope.define("nan", f64::NAN); scope.define("pi", std::f64::consts::PI); scope.define("tau", std::f64::consts::TAU); scope.define("e", std::f64::consts::E); diff --git a/crates/typst/src/foundations/float.rs b/crates/typst/src/foundations/float.rs index d346c3296..fd094950b 100644 --- a/crates/typst/src/foundations/float.rs +++ b/crates/typst/src/foundations/float.rs @@ -13,6 +13,9 @@ use crate::layout::Ratio; /// /// You can convert a value to a float with this type's constructor. /// +/// NaN and positive infinity are available as `{float.nan}` and `{float.inf}` +/// respectively. +/// /// # Example /// ```example /// #3.14 \ @@ -24,6 +27,13 @@ type f64; #[scope] impl f64 { + /// Positive infinity. + const INF: f64 = f64::INFINITY; + + /// A NaN value, as defined by the + /// [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754). + const NAN: f64 = f64::NAN; + /// Converts a value to a float. /// /// - Booleans are converted to `0.0` or `1.0`. @@ -58,7 +68,7 @@ impl f64 { /// ```example /// #float.is-nan(0) \ /// #float.is-nan(1) \ - /// #float.is-nan(calc.nan) + /// #float.is-nan(float.nan) /// ``` #[func] pub fn is_nan(self) -> bool { @@ -73,7 +83,7 @@ impl f64 { /// ```example /// #float.is-infinite(0) \ /// #float.is-infinite(1) \ - /// #float.is-infinite(calc.inf) + /// #float.is-infinite(float.inf) /// ``` #[func] pub fn is_infinite(self) -> bool { @@ -84,13 +94,13 @@ impl f64 { /// /// - If the number is positive (including `{+0.0}`), returns `{1.0}`. /// - If the number is negative (including `{-0.0}`), returns `{-1.0}`. - /// - If the number is `{calc.nan}`, returns `{calc.nan}`. + /// - If the number is `{float.nan}`, returns `{float.nan}`. /// /// ```example /// #(5.0).signum() \ /// #(-5.0).signum() \ /// #(0.0).signum() \ - /// #calc.nan.signum() + /// #float.nan.signum() /// ``` #[func] pub fn signum(self) -> f64 { diff --git a/crates/typst/src/foundations/repr.rs b/crates/typst/src/foundations/repr.rs index 68c94c56d..9c098bd19 100644 --- a/crates/typst/src/foundations/repr.rs +++ b/crates/typst/src/foundations/repr.rs @@ -76,7 +76,7 @@ pub fn format_int_with_base(mut n: i64, base: i64) -> EcoString { /// unit, all with a single allocation. /// /// The returned string is always valid Typst code. As such, it might not be a -/// float literal. For example, it may return `"calc.inf"`. +/// float literal. For example, it may return `"float.inf"`. pub fn format_float( mut value: f64, precision: Option, @@ -91,10 +91,10 @@ pub fn format_float( // when necessary. let unit_multiplication = if unit.is_empty() { "" } else { " * 1" }; if value.is_nan() { - eco_format!("calc.nan{unit_multiplication}{unit}") + eco_format!("float.nan{unit_multiplication}{unit}") } else if value.is_infinite() { let sign = if value < 0.0 { "-" } else { "" }; - eco_format!("{sign}calc.inf{unit_multiplication}{unit}") + eco_format!("{sign}float.inf{unit_multiplication}{unit}") } else if force_separator { eco_format!("{value:?}{unit}") } else { diff --git a/tests/ref/float-repr.png b/tests/ref/float-repr.png index 7b49e9d1520f09b2b3b67da2bc7a59073eeb3bf8..e73ee3280c35174077c685770890f51f5ae71a6c 100644 GIT binary patch delta 2487 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 BufhNT delta 2432 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 delta 2403 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 (0, 1, "a")) --- ops-compare-array-nested-failure --- -// Error: 3-42 cannot compare 3.5 with calc.nan +// Error: 3-42 cannot compare 3.5 with float.nan #((0, "a", 3.5) <= (0, "a", float("nan"))) --- ops-divide-by-zero-float ---