Skip to content

Commit

Permalink
add epsilon constant
Browse files Browse the repository at this point in the history
  • Loading branch information
kaikalii committed Nov 29, 2024
1 parent 42724b4 commit 95fc683
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ This version is not yet released. If you are reading this on the website, then t
- Stabilize [`last ⊣`](https://uiua.org/docs/last)
- Getting the last row is a very common operation
- Negative indices to [`pick ⊡`](https://uiua.org/docs/pick) and [`select ⊏`](https://uiua.org/docs/select) now always use a fill value if available
- Add an `ε` shadowable constant for the machine epsilon
- You can type it as `Epsilon`
- Add [`&ep`](https://uiua.org/docs/&ep) and [`&epf`](https://uiua.org/docs/&epf) system functions for easier printing to stderr
- Change [`backward 𝄈`](https://uiua.org/docs/backward)'s glyph to `𝄈`. Code using `˜` will continue to work and will be formatted as `𝄈`.
- Add the experimental [`or ∨`](https://uiua.org/docs/or) function
Expand Down
46 changes: 42 additions & 4 deletions src/lex.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! The Uiua lexer

use std::{
collections::VecDeque,
collections::{BTreeMap, VecDeque},
error::Error,
fmt,
hash::Hash,
Expand Down Expand Up @@ -1615,7 +1615,7 @@ pub fn is_custom_glyph(c: &str) -> bool {
}

pub(crate) fn canonicalize_ident(ident: &str) -> Ident {
canonicalize_subscripts(&canonicalize_exclams(ident))
canonicalize_special(canonicalize_subscripts(canonicalize_exclams(ident)))
}

/// Rewrite the identifier with the same number of exclamation points
Expand All @@ -1640,9 +1640,9 @@ fn place_exclams(ident: &str, count: usize) -> Ident {
}

/// Rewrite the identifier with numerals preceded by `__` replaced with subscript characters
fn canonicalize_subscripts(ident: &str) -> Ident {
fn canonicalize_subscripts(ident: Ident) -> Ident {
if !ident.contains('_') {
return ident.into();
return ident;
}
// This hasty canonicalization is okay because the stricter
// rules about the syntax are handled in the lexer
Expand All @@ -1657,6 +1657,44 @@ fn canonicalize_subscripts(ident: &str) -> Ident {
.collect()
}

thread_local! {
static SPECIAL: BTreeMap<&'static str, &'static str> = [
("Alpha", "α"),
("Beta", "β"),
("Gamma", "γ"),
("Delta", "δ"),
("Epsilon", "ε"),
("Zeta", "ζ"),
("Iota", "ι"),
("Kappa", "κ"),
("Lambda", "λ"),
("Mu", "μ"),
("Nu", "ν"),
("Xi", "ξ"),
("Omicron", "ο"),
("Rho", "ρ"),
("Sigma", "σ"),
("Upsilon", "υ"),
("Phi", "φ"),
("Chi", "χ"),
("Psi", "ψ"),
("Omega", "ω"),
].into()
}

fn canonicalize_special(ident: Ident) -> Ident {
let end = ident
.find(|c: char| "!‼₋".contains(c) || SUBSCRIPT_DIGITS.contains(&c))
.unwrap_or(ident.len());
if let Some(replacement) = SPECIAL.with(|map| map.get(&ident[..end]).copied()) {
let mut new = Ident::from(replacement);
new.push_str(&ident[end..]);
new
} else {
ident
}
}

fn pick_subscript(neg: bool, n: Option<i32>, overflow: bool) -> Subscript {
if overflow {
return Subscript::TooLarge;
Expand Down
4 changes: 4 additions & 0 deletions src/primitive/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ constant!(
("W", Math, WILDCARD_NAN),
/// The maximum integer that can be represented exactly
("MaxInt", Math, 2f64.powi(53)),
/// The machine epsilon for Uiua numbers
///
/// It is the difference between 1 and the next larger representable number.
("ε", Math, f64::EPSILON),
/// A string identifying the operating system
("Os", System, std::env::consts::OS),
/// A string identifying family of the operating system
Expand Down

0 comments on commit 95fc683

Please sign in to comment.