From 506f9d9989464eff56978ee4ba381b40bfb3e1d9 Mon Sep 17 00:00:00 2001 From: amatgil Date: Tue, 1 Oct 2024 22:46:20 +0200 Subject: [PATCH 1/8] Basic around implementation --- src/primitive/defs.rs | 4 ++++ src/primitive/mod.rs | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/primitive/defs.rs b/src/primitive/defs.rs index d7a5216ea..0412a5440 100644 --- a/src/primitive/defs.rs +++ b/src/primitive/defs.rs @@ -488,6 +488,10 @@ primitive!( /// [over] is often used in examples of functions with two inputs to show both inputs and the output. /// ex: [+,, +3 4 5] (2(3), Over, Stack, ("over", ',')), + /// Duplicate the top of the stack to the third-to-top position, around the second element + /// + /// ex: [' 1 2 3 4 5] + (2(3), Around, Stack, ("around", '\'')), /// Swap the top two values on the stack /// /// ex: [: 1 2 3 4 5] diff --git a/src/primitive/mod.rs b/src/primitive/mod.rs index d2f77dfdb..3d7c7a9a1 100644 --- a/src/primitive/mod.rs +++ b/src/primitive/mod.rs @@ -792,6 +792,13 @@ impl Primitive { env.push(a); env.push(b); } + Primitive::Around => { + let a = env.pop(1)?; + let b = env.pop(2)?; + env.push(a.clone()); + env.push(b); + env.push(a); + } Primitive::Pop => { env.pop(1)?; } From 95b312fa8d27adac0ef64a0b73d68164163f93d1 Mon Sep 17 00:00:00 2001 From: amatgil Date: Tue, 1 Oct 2024 22:46:36 +0200 Subject: [PATCH 2/8] Swizzles begone --- src/algorithm/invert.rs | 15 ------ src/assembly.rs | 20 +------ src/ast.rs | 8 +-- src/check.rs | 1 - src/compile/mod.rs | 117 ---------------------------------------- src/format.rs | 4 -- src/function.rs | 91 ------------------------------- src/lex.rs | 80 ++------------------------- src/lsp.rs | 56 +------------------ src/main.rs | 4 +- src/parse.rs | 4 -- src/run.rs | 19 ------- 12 files changed, 8 insertions(+), 411 deletions(-) diff --git a/src/algorithm/invert.rs b/src/algorithm/invert.rs index e90b41198..be5c33f5c 100644 --- a/src/algorithm/invert.rs +++ b/src/algorithm/invert.rs @@ -308,7 +308,6 @@ static INVERT_PATTERNS: &[&dyn InvertPattern] = { &InvertPatternFn(invert_split_pattern, "split"), &InvertPatternFn(invert_rows_pattern, "rows"), &InvertPatternFn(invert_dup_pattern, "dup"), - &InvertPatternFn(invert_stack_swizzle_pattern, "stack swizzle"), &InvertPatternFn(invert_select_pattern, "select"), &pat!(Sqrt, (Dup, Mul)), &pat!((Dup, Add), (2, Div)), @@ -1394,20 +1393,6 @@ fn under_dup_pattern<'a>( Ok((input, (befores, afters))) } -fn invert_stack_swizzle_pattern<'a>( - input: &'a [Instr], - _: &mut Compiler, -) -> InversionResult<(&'a [Instr], EcoVec)> { - let [Instr::StackSwizzle(swizzle, span), input @ ..] = input else { - return generic(); - }; - let instrs = eco_vec![Instr::StackSwizzle( - swizzle.inverse().ok_or(Generic)?, - *span - )]; - Ok((input, instrs)) -} - fn invert_select_pattern<'a>( input: &'a [Instr], _: &mut Compiler, diff --git a/src/assembly.rs b/src/assembly.rs index 94be0eee9..9891dc0ab 100644 --- a/src/assembly.rs +++ b/src/assembly.rs @@ -6,7 +6,7 @@ use serde::*; use crate::{ is_ident_char, CodeSpan, DynamicFunction, FuncSlice, Function, Ident, ImplPrimitive, InputSrc, - Instr, IntoInputSrc, LocalName, Module, Primitive, Signature, Span, StackSwizzle, TempStack, + Instr, IntoInputSrc, LocalName, Module, Primitive, Signature, Span, TempStack, Uiua, UiuaResult, Value, }; @@ -743,7 +743,6 @@ enum InstrRep { Switch(usize, Signature, usize, bool), Format(EcoVec, usize), MatchFormatPattern(EcoVec, usize), - StackSwizzle(EcoVec, Vec, usize), Label(EcoString, usize, bool), ValidateType(usize, EcoString, u8, usize), Dynamic(DynamicFunction), @@ -786,15 +785,6 @@ impl From for InstrRep { } => Self::Switch(count, sig, span, under_cond), Instr::Format { parts, span } => Self::Format(parts, span), Instr::MatchFormatPattern { parts, span } => Self::MatchFormatPattern(parts, span), - Instr::StackSwizzle(swizzle, span) => { - let fix_indices: Vec = swizzle - .fix - .iter() - .enumerate() - .filter_map(|(i, f)| f.then_some(i)) - .collect(); - Self::StackSwizzle(swizzle.indices, fix_indices, span) - } Instr::Label { label, span, @@ -842,14 +832,6 @@ impl From for Instr { }, InstrRep::Format(parts, span) => Self::Format { parts, span }, InstrRep::MatchFormatPattern(parts, span) => Self::MatchFormatPattern { parts, span }, - InstrRep::StackSwizzle(indices, fix_indices, span) => { - let mut fix = eco_vec![false; indices.len()]; - let slice = fix.make_mut(); - for i in fix_indices { - slice[i] = true; - } - Self::StackSwizzle(StackSwizzle { indices, fix }, span) - } InstrRep::Label(label, span, remove) => Self::Label { label, span, diff --git a/src/ast.rs b/src/ast.rs index 1750a86b4..660d44dd3 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -7,7 +7,7 @@ use crate::{ function::{FunctionId, Signature}, lex::{CodeSpan, Sp}, parse::ident_modifier_args, - ArraySwizzle, Ident, Primitive, SemanticComment, StackSwizzle, SUBSCRIPT_NUMS, + Ident, Primitive, SemanticComment, SUBSCRIPT_NUMS, }; /// A top-level item @@ -137,8 +137,6 @@ pub enum Word { Primitive(Primitive), Modified(Box), Placeholder(PlaceholderOp), - StackSwizzle(StackSwizzle), - ArraySwizzle(ArraySwizzle), Comment(String), Spaces, BreakLine, @@ -191,8 +189,6 @@ impl PartialEq for Word { } (Self::Placeholder(_), Self::Placeholder(_)) => false, (Self::Comment(a), Self::Comment(b)) => a == b, - (Self::StackSwizzle(a), Self::StackSwizzle(b)) => a == b, - (Self::ArraySwizzle(a), Self::ArraySwizzle(b)) => a == b, _ => discriminant(self) == discriminant(other), } } @@ -266,8 +262,6 @@ impl fmt::Debug for Word { Word::Spaces => write!(f, "' '"), Word::Comment(comment) => write!(f, "# {comment}"), Word::Placeholder(op) => write!(f, "{op}"), - Word::StackSwizzle(swizzle) => write!(f, "{swizzle}"), - Word::ArraySwizzle(swizzle) => write!(f, "{swizzle}"), Word::BreakLine => write!(f, "break_line"), Word::FlipLine => write!(f, "unbreak_line"), Word::SemanticComment(comment) => write!(f, "{comment}"), diff --git a/src/check.rs b/src/check.rs index f06533ed6..de9e7db2a 100644 --- a/src/check.rs +++ b/src/check.rs @@ -365,7 +365,6 @@ impl VirtualEnv { Instr::MatchFormatPattern { parts, .. } => { self.handle_args_outputs(1, parts.len().saturating_sub(1))? } - Instr::StackSwizzle(sw, _) => self.handle_sig(sw.signature())?, Instr::Dynamic(f) => self.handle_sig(f.signature)?, Instr::Unpack { count, .. } => self.handle_args_outputs(1, *count)?, Instr::TouchStack { count, .. } => self.handle_args_outputs(*count, *count)?, diff --git a/src/compile/mod.rs b/src/compile/mod.rs index 33fa41ae9..1795ac6c0 100644 --- a/src/compile/mod.rs +++ b/src/compile/mod.rs @@ -1425,8 +1425,6 @@ code: Word::Placeholder(_) => { // We could error here, but it's easier to handle it higher up } - Word::StackSwizzle(sw) => self.stack_swizzle(sw, word.span, call), - Word::ArraySwizzle(sw) => self.array_swizzle(sw, word.span, call)?, Word::SemanticComment(sc) => match sc { SemanticComment::Experimental => self.scope.experimental = true, SemanticComment::NoInline => { @@ -2254,121 +2252,6 @@ code: } Ok(()) } - fn stack_swizzle(&mut self, swiz: StackSwizzle, span: CodeSpan, call: bool) { - self.experimental_error(&span, || { - "Swizzles are experimental. To use them, add \ - `# Experimental!` to the top of the file." - }); - self.emit_diagnostic( - "Stack swizzles are deprecated and will be removed in the future.", - DiagnosticKind::Warning, - span.clone(), - ); - let sig = swiz.signature(); - let spandex = self.add_span(span.clone()); - let equivalent = match (swiz.indices.as_slice(), swiz.fix.as_slice()) { - ([0], [false]) => Some(Primitive::Identity), - ([0], [true]) => Some(Primitive::Fix), - ([1, 0], [false, false]) => Some(Primitive::Flip), - ([0, 0], [false, false]) => Some(Primitive::Dup), - ([1, 0, 1], [false, false, false]) => Some(Primitive::Over), - _ => None, - }; - let mut instr = if let Some(prim) = equivalent { - self.emit_diagnostic( - format!( - "This swizzle is equivalent to {}. \ - Use that instead.", - prim.format() - ), - DiagnosticKind::Style, - span.clone(), - ); - Instr::Prim(prim, spandex) - } else { - Instr::StackSwizzle(swiz, spandex) - }; - if !call { - instr = Instr::PushFunc(self.make_function( - FunctionId::Anonymous(span), - sig, - eco_vec![instr].into(), - )); - } - self.push_instr(instr); - } - fn array_swizzle(&mut self, swiz: ArraySwizzle, span: CodeSpan, call: bool) -> UiuaResult { - if !self.scope.experimental { - self.add_error( - span.clone(), - "Swizzles are experimental. To use them, add \ - `# Experimental!` to the top of the file.", - ); - } - self.emit_diagnostic( - "Array swizzles are deprecated and will be removed in the future.", - DiagnosticKind::Warning, - span.clone(), - ); - let sig = swiz.signature(); - let mut instrs = EcoVec::new(); - let normal_ordered = (swiz.indices.iter().enumerate()).all(|(i, &idx)| i == idx as usize); - let spandex = self.add_span(span.clone()); - if normal_ordered { - let val = Value::from(swiz.indices.len()); - instrs.extend([Instr::push(val), Instr::Prim(Primitive::Take, spandex)]); - } else { - let arr = Array::from_iter(swiz.indices.iter().map(|&i| i as f64)); - instrs.extend([Instr::push(arr), Instr::Prim(Primitive::Select, spandex)]); - } - if swiz.unbox.iter().all(|&b| b) { - instrs.push(Instr::Unpack { - count: sig.outputs, - span: spandex, - unbox: true, - }) - } else { - instrs.push(Instr::Unpack { - count: sig.outputs, - span: spandex, - unbox: false, - }); - if !swiz.unbox.iter().all(|&b| !b) { - let mut boxed_indices: Vec = (swiz.unbox.iter().enumerate()) - .filter_map(|(i, b)| b.then_some(i)) - .collect(); - let mut curr_index = boxed_indices.pop().unwrap(); - if curr_index != 0 { - instrs.push(Instr::PushTemp { - stack: TempStack::Inline, - count: curr_index, - span: spandex, - }); - } - instrs.push(Instr::ImplPrim(ImplPrimitive::UnBox, spandex)); - for i in boxed_indices.into_iter().rev() { - let diff = curr_index - i; - instrs.extend([ - Instr::pop_inline(diff, spandex), - Instr::ImplPrim(ImplPrimitive::UnBox, spandex), - ]); - curr_index = i; - } - if curr_index != 0 { - instrs.push(Instr::pop_inline(curr_index, spandex)); - } - } - } - if !call { - instrs = eco_vec![Instr::PushFunc(self.make_function( - FunctionId::Anonymous(span), - sig, - instrs.into(), - ))]; - } - self.push_all_instrs(instrs); - Ok(()) - } pub(crate) fn inlinable(&self, instrs: &[Instr], flags: FunctionFlags) -> bool { use ImplPrimitive::*; use Primitive::*; diff --git a/src/format.rs b/src/format.rs index 66a6c48e1..40f7a224a 100644 --- a/src/format.rs +++ b/src/format.rs @@ -1097,8 +1097,6 @@ impl<'a> Formatter<'a> { self.format_words(&m.operands, true, depth); } Word::Placeholder(op) => self.push(&word.span, &op.to_string()), - Word::StackSwizzle(s) => self.push(&word.span, &s.to_string()), - Word::ArraySwizzle(s) => self.push(&word.span, &s.to_string()), Word::Subscript(sub) => match &sub.word.value { Word::Modified(m) => { self.format_modifier(&m.modifier); @@ -1406,8 +1404,6 @@ pub(crate) fn word_is_multiline(word: &Word) -> bool { Word::Modified(m) => m.operands.iter().any(|word| word_is_multiline(&word.value)), Word::Placeholder(_) => false, Word::Subscript(sub) => word_is_multiline(&sub.word.value), - Word::StackSwizzle(_) => false, - Word::ArraySwizzle(_) => false, Word::Comment(_) => true, Word::Spaces => false, Word::BreakLine | Word::FlipLine => false, diff --git a/src/function.rs b/src/function.rs index 4c3a95ef2..0660a9e28 100644 --- a/src/function.rs +++ b/src/function.rs @@ -75,8 +75,6 @@ pub enum Instr { parts: EcoVec, span: usize, }, - /// Execute a stack swizzle - StackSwizzle(StackSwizzle, usize), /// Label an array Label { label: EcoString, @@ -192,7 +190,6 @@ impl PartialEq for Instr { Self::MatchFormatPattern { parts: a, .. }, Self::MatchFormatPattern { parts: b, .. }, ) => a == b, - (Self::StackSwizzle(a, _), Self::StackSwizzle(b, _)) => a == b, (Self::Label { label: a, .. }, Self::Label { label: b, .. }) => a == b, ( Self::ValidateType { @@ -297,7 +294,6 @@ impl Hash for Instr { } => (12, count, sig, under_cond).hash(state), Instr::Format { parts, .. } => (13, parts).hash(state), Instr::MatchFormatPattern { parts, .. } => (14, parts).hash(state), - Instr::StackSwizzle(swizzle, _) => (15, swizzle).hash(state), Instr::Label { label, .. } => (16, label).hash(state), Instr::ValidateType { index, @@ -421,92 +417,6 @@ impl<'a> fmt::Display for FmtInstrs<'a> { } } -/// A swizzle for the stack -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize)] -pub struct StackSwizzle { - /// The indices of the stack elements - pub indices: EcoVec, - /// The fix mask - pub fix: EcoVec, -} - -impl fmt::Display for StackSwizzle { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "λ")?; - for (&i, &fix) in self.indices.iter().zip(&self.fix) { - let mut c = b'a' + i; - if fix { - c = c.to_ascii_uppercase(); - } - write!(f, "{}", c as char)?; - } - Ok(()) - } -} - -impl StackSwizzle { - pub(crate) fn args(&self) -> usize { - (self.indices.iter().max().copied()).map_or(0, |max| max as usize + 1) - } - /// Get the signature of the swizzle - pub fn signature(&self) -> Signature { - Signature::new(self.args(), self.indices.len()) - } - /// Get the inverse of the swizzle - pub fn inverse(&self) -> Option { - if self.args() != self.indices.len() { - return None; - } - let set: HashSet<_> = self.indices.iter().copied().collect(); - if set.len() != self.indices.len() { - return None; - } - let mut indices = eco_vec![0; self.indices.len()]; - let slice = indices.make_mut(); - for (i, &j) in self.indices.iter().enumerate() { - slice[j as usize] = i as u8; - } - Some(Self { - indices, - fix: self.fix.clone(), - }) - } -} - -/// A swizzle for an array -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Serialize, Deserialize)] -pub struct ArraySwizzle { - /// The indices of the array elements - pub indices: EcoVec, - /// The (un)box mask - pub unbox: EcoVec, -} - -impl fmt::Display for ArraySwizzle { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "⋊")?; - for (&i, &b) in self.indices.iter().zip(&self.unbox) { - let mut c = if i < 0 { - b'z' + 1 - i.unsigned_abs() - } else { - b'a' + i.unsigned_abs() - }; - if b { - c = c.to_ascii_uppercase(); - } - write!(f, "{}", c as char)?; - } - Ok(()) - } -} - -impl ArraySwizzle { - /// Get the signature of the swizzle - pub fn signature(&self) -> Signature { - Signature::new(1, self.indices.len()) - } -} - /// Levels of purity for an operation #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum Purity { @@ -686,7 +596,6 @@ impl fmt::Display for Instr { Instr::CopyToTemp { stack, count, .. } => { write!(f, "") } - Instr::StackSwizzle(swizzle, _) => write!(f, "{swizzle}"), Instr::SetOutputComment { i, n, .. } => write!(f, ""), Instr::PushSig(sig) => write!(f, "{sig}"), Instr::PopSig => write!(f, "-|"), diff --git a/src/lex.rs b/src/lex.rs index 09ec3dde2..0f2575cd8 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -17,7 +17,7 @@ use serde_tuple::*; use unicode_segmentation::UnicodeSegmentation; use crate::{ - ast::PlaceholderOp, ArraySwizzle, Ident, Inputs, Primitive, StackSwizzle, WILDCARD_CHAR, + ast::PlaceholderOp, Ident, Inputs, Primitive, WILDCARD_CHAR, }; /// Subscript digit characters @@ -509,8 +509,6 @@ pub enum Token { MultilineFormatStr(Vec), Simple(AsciiToken), Glyph(Primitive), - StackSwizzle(StackSwizzle), - ArraySwizzle(ArraySwizzle), Subscript(usize), LeftArrow, LeftStrokeArrow, @@ -582,18 +580,6 @@ impl Token { _ => None, } } - pub(crate) fn as_stack_swizzle(&self) -> Option<&StackSwizzle> { - match self { - Token::StackSwizzle(s) => Some(s), - _ => None, - } - } - pub(crate) fn as_array_swizzle(&self) -> Option<&ArraySwizzle> { - match self { - Token::ArraySwizzle(s) => Some(s), - _ => None, - } - } pub(crate) fn as_subscript(&self) -> Option { match self { Token::Subscript(n) => Some(*n), @@ -634,8 +620,6 @@ impl fmt::Display for Token { } Ok(()) } - Token::StackSwizzle(s) => s.fmt(f), - Token::ArraySwizzle(s) => s.fmt(f), Token::Simple(t) => t.fmt(f), Token::Glyph(p) => p.fmt(f), Token::LeftArrow => write!(f, "←"), @@ -909,28 +893,8 @@ impl<'a> Lexer<'a> { ";" if self.next_char_exact(";") => self.end(DoubleSemicolon, start), ";" => self.end(Semicolon, start), "-" if self.next_chars_exact(["-", "-"]) => self.end(TripleMinus, start), - "'" if self.next_char_exact("'") => { - if let Some(swiz) = self.array_swizzle() { - self.end(ArraySwizzle(swiz), start) - } else { - self.end(Quote2, start) - } - } - "'" => { - if let Some(swiz) = self.stack_swizzle() { - self.end(StackSwizzle(swiz), start) - } else { - self.end(Quote, start) - } - } - "λ" => { - let swiz = self.stack_swizzle().unwrap_or_default(); - self.end(StackSwizzle(swiz), start) - } - "⋊" => { - let swiz = self.array_swizzle().unwrap_or_default(); - self.end(ArraySwizzle(swiz), start) - } + "'" if self.next_char_exact("'") => self.end(Quote2, start), + "'" => self.end(Quote, start), "~" => self.end(Tilde, start), "`" => { if self.number("-") { @@ -1457,44 +1421,6 @@ impl<'a> Lexer<'a> { c.into() })) } - fn stack_swizzle(&mut self) -> Option { - let mut indices = EcoVec::new(); - let mut fix = EcoVec::new(); - while let Some(c) = self.next_char_if(|c| c.chars().all(|c| c.is_ascii_alphabetic())) { - for c in c.chars() { - let is_upper = c.is_ascii_uppercase(); - let c = c.to_ascii_lowercase(); - indices.push(c as u8 - b'a'); - fix.push(is_upper); - } - } - if indices.is_empty() { - None - } else { - Some(StackSwizzle { indices, fix }) - } - } - fn array_swizzle(&mut self) -> Option { - let mut indices = EcoVec::new(); - let mut unbox = EcoVec::new(); - while let Some(c) = self.next_char_if(|c| c.chars().all(|c| c.is_ascii_alphabetic())) { - for c in c.chars() { - let is_upper = c.is_ascii_uppercase(); - let c = c.to_ascii_lowercase(); - if c <= 'm' { - indices.push(c as i8 - b'a' as i8); - } else { - indices.push(c as i8 - b'z' as i8 - 1); - } - unbox.push(is_upper); - } - } - if indices.is_empty() { - None - } else { - Some(ArraySwizzle { indices, unbox }) - } - } fn parse_string_contents( &mut self, start: Loc, diff --git a/src/lsp.rs b/src/lsp.rs index 221892596..0f911a598 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -14,8 +14,8 @@ use crate::{ ident_modifier_args, instrs_are_pure, is_custom_glyph, lex::{CodeSpan, Sp}, parse::parse, - ArraySwizzle, Assembly, BindingInfo, BindingKind, Compiler, DocComment, Ident, InputSrc, - Inputs, PreEvalMode, Primitive, Purity, SafeSys, Shape, Signature, StackSwizzle, SysBackend, + Assembly, BindingInfo, BindingKind, Compiler, DocComment, Ident, InputSrc, + Inputs, PreEvalMode, Primitive, Purity, SafeSys, Shape, Signature, SysBackend, UiuaError, Value, CONSTANTS, }; @@ -41,8 +41,6 @@ pub enum SpanKind { Placeholder(PlaceholderOp), Delimiter, FuncDelim(Signature), - StackSwizzle(StackSwizzle), - ArraySwizzle(ArraySwizzle), Subscript(Option, usize), } @@ -568,12 +566,6 @@ impl Spanner { spans.push(sub.n.clone().map(|n| SpanKind::Subscript(None, n))); } }, - Word::StackSwizzle(sw) => { - spans.push(word.span.clone().sp(SpanKind::StackSwizzle(sw.clone()))) - } - Word::ArraySwizzle(sw) => { - spans.push(word.span.clone().sp(SpanKind::ArraySwizzle(sw.clone()))) - } } } spans.retain(|sp| !sp.span.as_str(self.inputs(), str::is_empty)); @@ -870,26 +862,6 @@ mod server { inline_function_sig = Some(span.clone().sp(inline.sig)); } } - // Hovering a stack swizzle - let mut stack_swizzle: Option> = None; - for span_kind in &doc.spans { - if let SpanKind::StackSwizzle(s) = &span_kind.value { - if span_kind.span.contains_line_col(line, col) && span_kind.span.src == path { - stack_swizzle = Some(span_kind.span.clone().sp(s)); - break; - } - } - } - // Hovering an array swizzle - let mut array_swizzle: Option> = None; - for span_kind in &doc.spans { - if let SpanKind::ArraySwizzle(s) = &span_kind.value { - if span_kind.span.contains_line_col(line, col) && span_kind.span.src == path { - array_swizzle = Some(span_kind.span.clone().sp(s)); - break; - } - } - } // Hovering an array let mut array_shape: Option> = None; for (span, arr_meta) in &doc.code_meta.array_shapes { @@ -1007,22 +979,6 @@ mod server { }), range: Some(uiua_span_to_lsp(&sig.span)), } - } else if let Some(sw) = stack_swizzle { - Hover { - contents: HoverContents::Markup(MarkupContent { - kind: MarkupKind::Markdown, - value: format!("stack swizzle `{}`", sw.value.signature()), - }), - range: Some(uiua_span_to_lsp(&sw.span)), - } - } else if let Some(sw) = array_swizzle { - Hover { - contents: HoverContents::Markup(MarkupContent { - kind: MarkupKind::Markdown, - value: format!("array swizzle `{}`", sw.value.signature()), - }), - range: Some(uiua_span_to_lsp(&sw.span)), - } } else if let Some(shape) = array_shape { Hover { contents: HoverContents::Markup(MarkupContent { @@ -1453,14 +1409,6 @@ mod server { }, BindingDocsKind::Module { .. } => MODULE_STT, }, - SpanKind::StackSwizzle(sw) => match sw.signature().args { - 1 => MONADIC_FUNCTION_STT, - 2 => DYADIC_FUNCTION_STT, - 3 => TRIADIC_FUNCTION_STT, - 4 => TETRADIC_FUNCTION_STT, - _ => continue, - }, - SpanKind::ArraySwizzle(_) => MONADIC_FUNCTION_STT, SpanKind::Subscript(Some(prim), n) => { let Some(stt) = for_prim(*prim, prim.subscript_sig(*n)) else { continue; diff --git a/src/main.rs b/src/main.rs index cacc8d777..677cd1641 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1086,9 +1086,7 @@ fn color_code(code: &str, compiler: &Compiler) -> String { | SpanKind::Whitespace | SpanKind::Placeholder(_) | SpanKind::Delimiter - | SpanKind::FuncDelim(_) - | SpanKind::StackSwizzle(_) - | SpanKind::ArraySwizzle(_) => None, + | SpanKind::FuncDelim(_) => None, }; span.span.as_str(&inputs, |s| { colored.push_str(&if let Some(color) = color { diff --git a/src/parse.rs b/src/parse.rs index 1c6a3f4fe..839179fe4 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -994,10 +994,6 @@ impl<'i> Parser<'i> { span.sp(Word::BreakLine) } else if let Some(sc) = self.next_token_map(Token::as_semantic_comment) { sc.map(Word::SemanticComment) - } else if let Some(pack) = self.next_token_map(Token::as_stack_swizzle) { - pack.cloned().map(Word::StackSwizzle) - } else if let Some(pack) = self.next_token_map(Token::as_array_swizzle) { - pack.cloned().map(Word::ArraySwizzle) } else { return None; }; diff --git a/src/run.rs b/src/run.rs index 9a5900b0f..05ef42efe 100644 --- a/src/run.rs +++ b/src/run.rs @@ -547,10 +547,6 @@ code: let parts = parts.clone(); self.with_span(*span, |env| invert::match_format_pattern(parts, env)) } - Instr::StackSwizzle(swizzle, span) => { - let swizzle = swizzle.clone(); - self.with_span(*span, |env| env.stack_swizzle(&swizzle)) - } &Instr::Label { ref label, span, @@ -1647,21 +1643,6 @@ code: .channel }) } - fn stack_swizzle(&mut self, swizzle: &StackSwizzle) -> UiuaResult { - let args = swizzle.args(); - self.touch_array_stack(args)?; - let end = self.rt.stack.len(); - let start = end - args; - for (&i, &fix) in swizzle.indices.iter().zip(&swizzle.fix).rev() { - let mut val = self.rt.stack[end - 1 - i as usize].clone(); - if fix { - val.fix(); - } - self.rt.stack.push(val); - } - self.rt.stack.drain(start..start + args); - Ok(()) - } } /// A trait for types that can be used as argument specifiers for [`Uiua::pop`] From 49ef3d98400b3d05ee1fc4b7c9110b82eb3b68e1 Mon Sep 17 00:00:00 2001 From: amatgil Date: Tue, 1 Oct 2024 23:07:05 +0200 Subject: [PATCH 3/8] Finish nuking swizzles --- site/src/editor/utils.rs | 16 ---------------- src/lex.rs | 6 ------ 2 files changed, 22 deletions(-) diff --git a/site/src/editor/utils.rs b/site/src/editor/utils.rs index 0b9aa8f8e..19da51d20 100644 --- a/site/src/editor/utils.rs +++ b/site/src/editor/utils.rs @@ -457,8 +457,6 @@ pub fn gen_code_view(code: &str) -> View { SpanKind::String => "string-literal-span", SpanKind::Comment | SpanKind::OutputComment => "comment-span", SpanKind::Strand => "strand-span", - SpanKind::StackSwizzle(sw) => sig_class(sw.signature()), - SpanKind::ArraySwizzle(sw) => sig_class(sw.signature()), SpanKind::Subscript(None, _) => "number-literal", SpanKind::Subscript(Some(prim), n) => { prim_sig_class(*prim, prim.subscript_sig(*n)) @@ -570,20 +568,6 @@ pub fn gen_code_view(code: &str) -> View { view!({text}).into_view(), ) } - SpanKind::StackSwizzle(sw) => { - let class = format!("code-span {}", color_class); - let title = format!("stack swizzle {}", sw.signature()); - frag_views.push( - view!({text}).into_view(), - ) - } - SpanKind::ArraySwizzle(sw) => { - let class = format!("code-span {}", color_class); - let title = format!("array swizzle {}", sw.signature()); - frag_views.push( - view!({text}).into_view(), - ) - } SpanKind::Label => { let label = text.trim_start_matches('$'); let mut components = [0f32; 3]; diff --git a/src/lex.rs b/src/lex.rs index 0f2575cd8..22a5f1c5c 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -665,8 +665,6 @@ pub enum AsciiToken { Backtick, Tilde, TripleMinus, - Quote, - Quote2, Placeholder(PlaceholderOp), } @@ -694,8 +692,6 @@ impl fmt::Display for AsciiToken { AsciiToken::Backtick => write!(f, "`"), AsciiToken::Tilde => write!(f, "~"), AsciiToken::TripleMinus => write!(f, "---"), - AsciiToken::Quote => write!(f, "'"), - AsciiToken::Quote2 => write!(f, "''"), AsciiToken::Placeholder(op) => write!(f, "{op}"), } } @@ -893,8 +889,6 @@ impl<'a> Lexer<'a> { ";" if self.next_char_exact(";") => self.end(DoubleSemicolon, start), ";" => self.end(Semicolon, start), "-" if self.next_chars_exact(["-", "-"]) => self.end(TripleMinus, start), - "'" if self.next_char_exact("'") => self.end(Quote2, start), - "'" => self.end(Quote, start), "~" => self.end(Tilde, start), "`" => { if self.number("-") { From 9d1080903aa05bc2f864742fb4233dc8f7ed4d2a Mon Sep 17 00:00:00 2001 From: amatgil Date: Tue, 1 Oct 2024 23:47:43 +0200 Subject: [PATCH 4/8] Add (placeholder) glyph for around --- src/lex.rs | 3 +++ src/primitive/defs.rs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lex.rs b/src/lex.rs index 22a5f1c5c..b51eeb3e3 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -664,6 +664,7 @@ pub enum AsciiToken { GreaterEqual, Backtick, Tilde, + Quote, TripleMinus, Placeholder(PlaceholderOp), } @@ -692,6 +693,7 @@ impl fmt::Display for AsciiToken { AsciiToken::Backtick => write!(f, "`"), AsciiToken::Tilde => write!(f, "~"), AsciiToken::TripleMinus => write!(f, "---"), + AsciiToken::Quote => write!(f, "'"), AsciiToken::Placeholder(op) => write!(f, "{op}"), } } @@ -890,6 +892,7 @@ impl<'a> Lexer<'a> { ";" => self.end(Semicolon, start), "-" if self.next_chars_exact(["-", "-"]) => self.end(TripleMinus, start), "~" => self.end(Tilde, start), + "'" => self.end(Quote, start), "`" => { if self.number("-") { self.end(Number, start) diff --git a/src/primitive/defs.rs b/src/primitive/defs.rs index 0412a5440..a8e446e7d 100644 --- a/src/primitive/defs.rs +++ b/src/primitive/defs.rs @@ -491,7 +491,7 @@ primitive!( /// Duplicate the top of the stack to the third-to-top position, around the second element /// /// ex: [' 1 2 3 4 5] - (2(3), Around, Stack, ("around", '\'')), + (2(3), Around, Stack, ("around", AsciiToken::Quote, '’')), /// Swap the top two values on the stack /// /// ex: [: 1 2 3 4 5] From 2a0381594e5ea22746f84f31816b5bf789cd7436 Mon Sep 17 00:00:00 2001 From: amatgil Date: Tue, 1 Oct 2024 23:50:11 +0200 Subject: [PATCH 5/8] Fix documentation --- src/primitive/defs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/primitive/defs.rs b/src/primitive/defs.rs index a8e446e7d..00f5c9c40 100644 --- a/src/primitive/defs.rs +++ b/src/primitive/defs.rs @@ -488,7 +488,7 @@ primitive!( /// [over] is often used in examples of functions with two inputs to show both inputs and the output. /// ex: [+,, +3 4 5] (2(3), Over, Stack, ("over", ',')), - /// Duplicate the top of the stack to the third-to-top position, around the second element + /// Duplicate the top of the stack around the second element /// /// ex: [' 1 2 3 4 5] (2(3), Around, Stack, ("around", AsciiToken::Quote, '’')), From c1e64a2333399fedfec4074c76455c91f322d06c Mon Sep 17 00:00:00 2001 From: amatgil Date: Wed, 2 Oct 2024 17:38:02 +0200 Subject: [PATCH 6/8] Mark around as experimental --- src/primitive/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/primitive/mod.rs b/src/primitive/mod.rs index 3d7c7a9a1..a2edb71a4 100644 --- a/src/primitive/mod.rs +++ b/src/primitive/mod.rs @@ -468,7 +468,7 @@ impl Primitive { use SysOp::*; matches!( self, - (Anti | Off | Backward | Above) + (Anti | Off | Backward | Above | Around) | (Tuples | Choose | Permute) | Struct | (Last | Sort | Chunks | Base | Coordinate | Fft | Case | Layout) From ab2c46b38acf3857a7e955bcf3bd3940a1051844 Mon Sep 17 00:00:00 2001 From: amatgil Date: Wed, 2 Oct 2024 19:59:06 +0200 Subject: [PATCH 7/8] Around must be marked as Experimental in its own docs as well --- src/primitive/defs.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/primitive/defs.rs b/src/primitive/defs.rs index 41c0120dd..7a09ef83f 100644 --- a/src/primitive/defs.rs +++ b/src/primitive/defs.rs @@ -506,7 +506,8 @@ primitive!( (2(3), Over, Stack, ("over", ',')), /// Duplicate the top of the stack around the second element /// - /// ex: [' 1 2 3 4 5] + /// ex: # Experimental! + /// : [' 1 2 3 4 5] (2(3), Around, Stack, ("around", AsciiToken::Quote, '’')), /// Swap the top two values on the stack /// From c32063f97cf45eda80047ab3877e66eba964bc8f Mon Sep 17 00:00:00 2001 From: amatgil Date: Wed, 2 Oct 2024 20:02:30 +0200 Subject: [PATCH 8/8] cargo fmt --- src/assembly.rs | 4 ++-- src/lex.rs | 4 +--- src/lsp.rs | 5 ++--- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/assembly.rs b/src/assembly.rs index e2af8c468..eab566614 100644 --- a/src/assembly.rs +++ b/src/assembly.rs @@ -6,8 +6,8 @@ use serde::*; use crate::{ is_ident_char, CodeSpan, DynamicFunction, FuncSlice, Function, Ident, ImplPrimitive, InputSrc, - Instr, IntoInputSrc, LocalName, Module, Primitive, Signature, Span, TempStack, - Uiua, UiuaResult, Value, + Instr, IntoInputSrc, LocalName, Module, Primitive, Signature, Span, TempStack, Uiua, + UiuaResult, Value, }; /// A compiled Uiua assembly diff --git a/src/lex.rs b/src/lex.rs index b3bf03409..39ec29bb1 100644 --- a/src/lex.rs +++ b/src/lex.rs @@ -16,9 +16,7 @@ use serde::*; use serde_tuple::*; use unicode_segmentation::UnicodeSegmentation; -use crate::{ - ast::PlaceholderOp, Ident, Inputs, Primitive, WILDCARD_CHAR, -}; +use crate::{ast::PlaceholderOp, Ident, Inputs, Primitive, WILDCARD_CHAR}; /// Subscript digit characters pub const SUBSCRIPT_NUMS: [char; 10] = ['₀', '₁', '₂', '₃', '₄', '₅', '₆', '₇', '₈', '₉']; diff --git a/src/lsp.rs b/src/lsp.rs index ff4e47322..87c3c08d8 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -14,9 +14,8 @@ use crate::{ ident_modifier_args, instrs_are_pure, is_custom_glyph, lex::{CodeSpan, Sp}, parse::parse, - Assembly, BindingInfo, BindingKind, Compiler, DocComment, Ident, InputSrc, - Inputs, PreEvalMode, Primitive, Purity, SafeSys, Shape, Signature, SysBackend, - UiuaError, Value, CONSTANTS, + Assembly, BindingInfo, BindingKind, Compiler, DocComment, Ident, InputSrc, Inputs, PreEvalMode, + Primitive, Purity, SafeSys, Shape, Signature, SysBackend, UiuaError, Value, CONSTANTS, }; /// Kinds of span in Uiua code, meant to be used in the language server or other IDE tools