Skip to content

Commit

Permalink
add experimental or function and increase dev version
Browse files Browse the repository at this point in the history
  • Loading branch information
kaikalii committed Nov 25, 2024
1 parent 80bd870 commit 0ed96c2
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ name = "uiua"
readme = "readme.md"
repository = "https://github.com/uiua-lang/uiua"
rust-version = "1.78"
version = "0.14.0-dev.2"
version = "0.14.0-dev.3"

[dependencies]
# Core dependencies
Expand Down
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ This version is not yet released. If you are reading this on the website, then t
- Getting the last row is a very common operation
- 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
- It has a useful reduction identity
- It is also GCD
- Add experimental [inline macros](https://www.uiua.org/docs/experimental#inline-macros)
- Deprecate the experimental `stringify` and `signature` modifiers in favor of inline code macros
- Add experimental [`binary`](https://uiua.org/docs/binary) function, which encodes and decodes arrays into a compact binary representation
Expand Down
8 changes: 8 additions & 0 deletions site/primitives.json
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,14 @@
"class": "Stack",
"description": "Call a function but keep its first argument on the top of the stack"
},
"or": {
"glyph": "",
"args": 2,
"outputs": 1,
"class": "DyadicPervasive",
"description": "Logical OR and greatest common divisor",
"experimental": true
},
"orient": {
"glyph": "",
"args": 2,
Expand Down
86 changes: 85 additions & 1 deletion src/algorithm/pervade.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! Algorithms for pervasive array operations

use std::{cmp::Ordering, convert::Infallible, fmt::Display, iter::repeat, marker::PhantomData};
use std::{
cmp::Ordering, convert::Infallible, fmt::Display, iter::repeat, marker::PhantomData, mem::swap,
};

use ecow::eco_vec;

Expand Down Expand Up @@ -1332,6 +1334,88 @@ pub mod modulus {
env.error(format!("Cannot modulo {a} and {b}"))
}
}

pub mod or {

use super::*;

pub fn num_num(a: f64, b: f64) -> f64 {
if (1.0..=u128::MAX as f64).contains(&a)
&& (1.0..=u128::MAX as f64).contains(&b)
&& a.fract() == 0.0
&& b.fract() == 0.0
{
let mut a = a as u128;
let mut b = b as u128;
let shift = (a | b).trailing_zeros();
a >>= shift;
b >>= shift;
a >>= a.trailing_zeros();
loop {
b >>= b.trailing_zeros();
if a > b {
swap(&mut a, &mut b);
}
b -= a;
if b == 0 {
break;
}
}
return (a << shift) as f64;
}
fn recurse(a: f64, b: f64) -> f64 {
if b.abs() <= 8.0 * f64::EPSILON {
return a;
}
recurse(b, a.rem_euclid(b))
}
recurse(a, b)
}
pub fn num_byte(a: f64, b: u8) -> f64 {
num_num(b.into(), a)
}
pub fn byte_num(a: u8, b: f64) -> f64 {
num_num(a.into(), b)
}
pub fn byte_byte(mut a: u8, mut b: u8) -> u8 {
if a == 0 {
return b;
}
if b == 0 {
return a;
}
let shift = (a | b).trailing_zeros();
a >>= shift;
b >>= shift;
a >>= a.trailing_zeros();
loop {
b >>= b.trailing_zeros();
if a > b {
swap(&mut a, &mut b);
}
b -= a;
if b == 0 {
break;
}
}
a << shift
}
pub fn bool_bool(a: u8, b: u8) -> u8 {
a | b
}
pub fn com_x(a: Complex, b: impl Into<Complex>) -> Complex {
let b = b.into();
Complex::new(num_num(a.re, b.re), num_num(a.im, b.im))
}
pub fn x_com(a: impl Into<Complex>, b: Complex) -> Complex {
let a = a.into();
Complex::new(num_num(a.re, b.re), num_num(a.im, b.im))
}
pub fn error<T: Display>(a: T, b: T, env: &Uiua) -> UiuaError {
env.error(format!("Cannot or {a} and {b}"))
}
}

bin_op_mod!(
atan2,
a,
Expand Down
13 changes: 13 additions & 0 deletions src/algorithm/reduce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,17 @@ pub(crate) fn reduce_impl(f: SigNode, depth: usize, env: &mut Uiua) -> UiuaResul
modulus::num_byte,
)
.into(),
Primitive::Or => {
let byte_fill = env.scalar_fill::<u8>().ok();
if fill.is_some() && byte_fill.is_none() {
fast_reduce_different(bytes, 0.0, fill, depth, or::num_num, or::num_byte)
.into()
} else if bytes.meta().flags.is_boolean() {
fast_reduce(bytes, 0, byte_fill, depth, or::bool_bool).into()
} else {
fast_reduce(bytes, 0, byte_fill, depth, or::byte_byte).into()
}
}
Primitive::Atan if flipped => fast_reduce_different(
bytes,
0.0,
Expand Down Expand Up @@ -332,6 +343,7 @@ macro_rules! reduce_math {
Primitive::Modulus => {
fast_reduce(xs, f64::INFINITY.into(), fill, depth, modulus::$f)
}
Primitive::Or => fast_reduce(xs, 0.0.into(), fill, depth, or::$f),
#[cfg(feature = "opt")]
Primitive::Atan if _flipped => {
fast_reduce(xs, 0.0.into(), fill, depth, flip(atan2::$f))
Expand Down Expand Up @@ -1046,6 +1058,7 @@ pub fn adjacent(ops: Ops, env: &mut Uiua) -> UiuaResult {
Primitive::Div => fast_adjacent(nums, n, env, div::num_num),
Primitive::Modulus if flipped => fast_adjacent(nums, n, env, flip(modulus::num_num)),
Primitive::Modulus => fast_adjacent(nums, n, env, modulus::num_num),
Primitive::Or => fast_adjacent(nums, n, env, or::num_num),
Primitive::Atan if flipped => fast_adjacent(nums, n, env, flip(atan2::num_num)),
Primitive::Atan => fast_adjacent(nums, n, env, atan2::num_num),
Primitive::Max => fast_adjacent(nums, n, env, max::num_num),
Expand Down
19 changes: 19 additions & 0 deletions src/primitive/defs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,25 @@ primitive!(
/// If you prefer the negative modulo instead of the remainder, you may use [under]:
/// ex: ⍜⊙⌵◿ 4 ¯21
(2, Modulus, DyadicPervasive, ("modulus", '◿')),
/// Logical OR and greatest common divisor
///
/// ex: # Experimental!
/// : ∨ [0 1 0 1] [0 0 1 1]
/// ex: # Experimental!
/// : ⊞∨.[0 1]
/// Non boolean values give the GCD
/// ex: # Experimental!
/// : ∨ 16 24
/// ex: # Experimental!
/// : ∨ 51 85
/// The [reduce] identity of [or] is `0`. This makes it betta than [max] as a logical OR.
/// ex: # Experimental!
/// : /∨ []
/// ex: # Experimental!
/// : [⊃/∨/↥] [0 0]
/// : [⊃/∨/↥] [0]
/// : [⊃/∨/↥] []
(2, Or, DyadicPervasive, ("or", '∨')),
/// Raise a value to a power
///
/// The second value is raised to the power of the first.
Expand Down
4 changes: 3 additions & 1 deletion src/primitive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ static ALIASES: Lazy<HashMap<Primitive, &[&str]>> = Lazy::new(|| {
(Primitive::Pi, &["pi"]),
(Primitive::Fix, &["fx"]),
(Primitive::Box, &["bx"]),
(Primitive::Mul, &["and"]),
(Primitive::IndexOf, &["idx"]),
(Primitive::Switch, &["sw"]),
(Primitive::Floor, &["flr", "flor"]),
Expand Down Expand Up @@ -545,7 +546,7 @@ impl Primitive {
self,
(Off | Backward | Above | Around)
| (Tuples | Choose | Permute)
| (Chunks | Base | Fft | Case | Layout | Binary)
| (Or | Chunks | Base | Fft | Case | Layout | Binary)
| (Astar | Triangle)
| (Derivative | Integral)
| Sys(Ffi | MemCopy | MemFree | TlsListen)
Expand Down Expand Up @@ -783,6 +784,7 @@ impl Primitive {
Primitive::Mul => env.dyadic_oo_00_env(Value::mul)?,
Primitive::Div => env.dyadic_oo_00_env(Value::div)?,
Primitive::Modulus => env.dyadic_oo_00_env(Value::modulus)?,
Primitive::Or => env.dyadic_oo_00_env(Value::or)?,
Primitive::Pow => env.dyadic_oo_00_env(Value::pow)?,
Primitive::Log => env.dyadic_oo_00_env(Value::log)?,
Primitive::Min => env.dyadic_oo_00_env(Value::min)?,
Expand Down
1 change: 1 addition & 0 deletions src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1692,6 +1692,7 @@ value_bin_math_impl!(
);
value_bin_math_impl!(div, (Num, Char, num_char), (Byte, Char, byte_char),);
value_bin_math_impl!(modulus, (Complex, Complex, com_com));
value_bin_math_impl!(or, [|meta| meta.flags.is_boolean(), Byte, bool_bool]);
value_bin_math_impl!(pow);
value_bin_math_impl!(root);
value_bin_math_impl!(log);
Expand Down

0 comments on commit 0ed96c2

Please sign in to comment.