diff --git a/changelog.md b/changelog.md index dc58723cd..6527fba52 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,7 @@ This version is not yet released. If you are reading this on the website, then t - Add the [`# External!`](https://www.uiua.org/tutorial/documentation#external) semantic comment to mark functions that are provided via Rust code - These functions don't require a Uiua implementation and will show up in the LSP - Calling an `# External!` function that hasn't been bound will throw an error +- Add experimental [`self ˙`](https://uiua.org/docs/self) modifier - Add experimental subscripts to [`negate ¯`](https://uiua.org/docs/negate) - This will [`multiply ×`](https://uiua.org/docs/multiply) a number by the Nth root of unity ### Interpreter diff --git a/src/compile/modifier.rs b/src/compile/modifier.rs index 1381630ea..aefd09f3f 100644 --- a/src/compile/modifier.rs +++ b/src/compile/modifier.rs @@ -682,6 +682,34 @@ impl Compiler { let span = self.add_span(modified.modifier.span.clone()); Node::Mod(prim, eco_vec![sn], span) } + Slf => { + let (SigNode { mut node, sig }, _) = self.monadic_modifier_op(modified)?; + match sig.args { + 0 => { + let span = self.add_span(modified.modifier.span.clone()); + node.push(Node::Prim(Dup, span)); + node + } + 1 => { + self.emit_diagnostic( + format!( + "Remove {} here, as it does nothing for monadic functions", + Slf.format(), + ), + DiagnosticKind::Style, + modified.modifier.span.clone(), + ); + node + } + n => { + let span = self.add_span(modified.modifier.span.clone()); + for _ in 0..n - 1 { + node.prepend(Node::Prim(Dup, span)) + } + node + } + } + } Backward => { let (SigNode { mut node, sig }, _) = self.monadic_modifier_op(modified)?; match sig.args { diff --git a/src/primitive/defs.rs b/src/primitive/defs.rs index c39c46ed1..e945e7884 100644 --- a/src/primitive/defs.rs +++ b/src/primitive/defs.rs @@ -1938,6 +1938,19 @@ primitive!( /// /// See also: [above] ([1], Below, Stack, ("below", '◡')), + /// Call a function with the same array as all arguments + /// + /// ex: # Experimental! + /// : ˙+ 5 + /// ex: # Experimental! + /// : ˙⊞+ 1_2_3 + /// ex: # Experimental! + /// : ˙(⊂⊂) π + /// [self] on a noadic function duplicates the output. This makes it distinct from [both] on a monadic function. + /// ex: # Experimental! + /// : ⌊×10[˙⚂] + /// : ⌊×10[∩⚂] + ([1], Slf, Stack, ("self", '˙')), /// Call a function with its arguments reversed /// /// This is a modifier version of [flip]. diff --git a/src/primitive/mod.rs b/src/primitive/mod.rs index 3a95cd5df..1a2118f82 100644 --- a/src/primitive/mod.rs +++ b/src/primitive/mod.rs @@ -406,6 +406,7 @@ static ALIASES: Lazy> = Lazy::new(|| { (Primitive::Utf8, &["utf", "utf__8"]), (Primitive::First, &["fst"]), (Primitive::Last, &["lst"]), + (Primitive::Slf, &["slf"]), (Primitive::ImageEncode, &["&ime", "imen"]), (Primitive::GifEncode, &["&gife", "gifen"]), (Primitive::AudioEncode, &["&ae", "auden"]), @@ -540,7 +541,7 @@ impl Primitive { use SysOp::*; matches!( self, - (Reach | Backward | Above | Around) + (Reach | Slf | Backward | Above | Around) | (Or | Base | Fft | Layout | Binary) | Astar | (Derivative | Integral)