Skip to content

Commit 31df9bc

Browse files
committed
add enum Variants list binding
1 parent 5f63c53 commit 31df9bc

File tree

7 files changed

+57
-23
lines changed

7 files changed

+57
-23
lines changed

changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ This version is not yet released. If you are reading this on the website, then t
1515
- **Breaking Change** - [`dip ⊙`](https://uiua.org/docs/dip) and [`on ⟜`](https://uiua.org/docs/on) function packs no longer apply their modifier to the leftmost function
1616
- This change makes most usecases of these function packs cleaner, as `A⊙(B|C)` changes to `⊙(A|B|C)` and likewise for [`on ⟜`](https://uiua.org/docs/on)
1717
- **Breaking Change** - The FFI function API has been changed considerably, read more in the documentation for [`&ffi`](https://uiua.org/docs/&ffi), [`&memcpy`](https://uiua.org/docs/&memcpy), and [`&memset`](https://uiua.org/docs/&memset)
18-
- [`parse ⋕`](https://uiua.org/docs/parse) can be subscripted to parse strings in different bases
18+
- Add [`parse ⋕`](https://uiua.org/docs/parse) subscripts to parse strings in different bases
1919
- Allow for private [modules](https://uiua.org/tutorial/modules#private-scoped-modules), [imports](https://uiua.org/tutorial/modules#private-imports), and [data definitions](https://uiua.org/tutorial/datadefs#visibility)
20+
- Modules containing data definition variants now contains a `Variants` binding that lists their names
2021
- Add array pack syntactic sugar. This lets you write code like `[⊃(+|×)]` as `⊃[+|×]`.
2122
- Subscripts can now be typed with `,` instead of `__`s
2223
- Add numeric subscripts for [`keep ▽`](https://uiua.org/docs/keep) to keep along a number of dimensions

site/text/data_defs.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,16 @@ If you have a lot of variants, you can put more than one on a single line.
223223
└─╴
224224
```
225225

226+
A module that contains variants has a `Variants` binding that lists their names.
227+
228+
```uiua
229+
┌─╴IpAddr
230+
|V₄ [A B C D]
231+
|V₆ [A B C D E F]
232+
└─╴
233+
IpAddr~Variants
234+
```
235+
226236
## Structs of Arrays
227237

228238
There is a well-known optimization for lower-level languages called "structs of arrays". It is a design pattern where instead of making a list of similar data structures, you make a single structure with a list for each field. This makes code faster by making data take up less memory and therefore making CPU cache misses less likely.

src/compile/binding.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ impl Compiler {
611611
}
612612
fn analyze_macro_body(
613613
&mut self,
614-
macro_name: &str,
614+
mac_name: &str,
615615
words: &[Sp<Word>],
616616
mut code_macro: bool,
617617
recursive: &mut bool,
@@ -623,24 +623,22 @@ impl Compiler {
623623
let mut name_local = None;
624624
match &word.value {
625625
Word::Strand(items) => {
626-
self.analyze_macro_body(macro_name, items, code_macro, recursive, loc)
626+
self.analyze_macro_body(mac_name, items, code_macro, recursive, loc)
627627
}
628628
Word::Array(arr) => {
629-
if self.analyze_macro_items(macro_name, &arr.lines, code_macro, recursive, loc)
630-
{
629+
if self.analyze_macro_items(mac_name, &arr.lines, code_macro, recursive, loc) {
631630
return;
632631
}
633632
}
634633
Word::Func(func) => {
635-
if self.analyze_macro_items(macro_name, &func.lines, code_macro, recursive, loc)
636-
{
634+
if self.analyze_macro_items(mac_name, &func.lines, code_macro, recursive, loc) {
637635
return;
638636
}
639637
}
640638
Word::Pack(pack) => {
641639
for branch in &pack.branches {
642640
if self.analyze_macro_items(
643-
macro_name,
641+
mac_name,
644642
&branch.value.lines,
645643
code_macro,
646644
recursive,
@@ -684,7 +682,7 @@ impl Compiler {
684682
if let Err(e) = self.in_scope(ScopeKind::AllInModule, move |comp| {
685683
comp.scope.names.extend(names);
686684
comp.analyze_macro_body(
687-
macro_name,
685+
mac_name,
688686
&m.operands,
689687
false,
690688
recursive,
@@ -698,7 +696,7 @@ impl Compiler {
698696
// Name errors are ignored in code macros
699697
let error_count = self.errors.len();
700698
self.analyze_macro_body(
701-
macro_name,
699+
mac_name,
702700
&m.operands,
703701
code_macro,
704702
recursive,
@@ -709,14 +707,13 @@ impl Compiler {
709707
}
710708
}
711709
} else {
712-
self.analyze_macro_body(macro_name, &m.operands, code_macro, recursive, loc)
710+
self.analyze_macro_body(mac_name, &m.operands, code_macro, recursive, loc)
713711
}
714712
}
715713
_ => {}
716714
}
717715
if let Some((nm, name_span, local)) = name_local {
718-
if nm.value == macro_name
719-
&& path_locals.as_ref().is_none_or(|(pl, _)| pl.is_empty())
716+
if nm.value == mac_name && path_locals.as_ref().is_none_or(|(pl, _)| pl.is_empty())
720717
{
721718
*recursive = true;
722719
}

src/compile/data.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,9 @@ impl Compiler {
278278
let mut variant_index = 0;
279279
if data.variant {
280280
let module_scope = self.higher_scopes.last_mut().unwrap_or(&mut self.scope);
281-
variant_index = module_scope.data_variants;
282-
module_scope.data_variants += 1;
281+
variant_index = module_scope.data_variants.len();
282+
let name = data.name.as_ref().unwrap().value.clone();
283+
module_scope.data_variants.insert(name);
283284
}
284285

285286
// Make getters
@@ -574,6 +575,26 @@ impl Compiler {
574575
Ok(())
575576
}
576577
pub(super) fn end_enum(&mut self) -> UiuaResult {
578+
// Add Variants binding
579+
if !self.scope.data_variants.is_empty()
580+
&& !self.scope.names.get("Variants").is_some_and(|ln| ln.public)
581+
{
582+
let index = self.next_global;
583+
self.next_global += 1;
584+
let local = LocalName {
585+
index,
586+
public: true,
587+
};
588+
let value = take(&mut self.scope.data_variants)
589+
.into_iter()
590+
.map(|s| Boxed(s.chars().collect()))
591+
.collect();
592+
let meta = BindingMeta {
593+
comment: Some("Names of the data variants of the module".into()),
594+
..Default::default()
595+
};
596+
self.compile_bind_const("Variants".into(), local, Some(value), 0, meta);
597+
}
577598
Ok(())
578599
}
579600
}

src/compile/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::{
2121
};
2222

2323
use ecow::{eco_vec, EcoString, EcoVec};
24-
use indexmap::IndexMap;
24+
use indexmap::{IndexMap, IndexSet};
2525
use serde::{Deserialize, Serialize};
2626

2727
use crate::{
@@ -217,8 +217,8 @@ pub(crate) struct Scope {
217217
names: LocalNames,
218218
/// Whether the scope has a data def defined
219219
has_data_def: bool,
220-
/// Number of named data variants
221-
data_variants: usize,
220+
/// Names of data variants
221+
data_variants: IndexSet<EcoString>,
222222
/// Whether to allow experimental features
223223
pub experimental: bool,
224224
/// Whether an error has been emitted for experimental features
@@ -266,7 +266,7 @@ impl Default for Scope {
266266
comment: None,
267267
names: IndexMap::new(),
268268
has_data_def: false,
269-
data_variants: 0,
269+
data_variants: IndexSet::new(),
270270
experimental: false,
271271
experimental_error: false,
272272
fill_sig_error: false,
@@ -812,9 +812,9 @@ impl Compiler {
812812
span: usize,
813813
meta: BindingMeta,
814814
) {
815-
let span = self.get_span(span).clone().code().unwrap();
815+
let span = self.get_span(span).clone().code();
816816
self.asm
817-
.add_binding_at(local, BindingKind::Const(value), Some(span), meta);
817+
.add_binding_at(local, BindingKind::Const(value), span, meta);
818818
self.scope.names.insert(name, local);
819819
}
820820
/// Import a module

tests/data_defs.ua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@
2525
└─╴
2626
⍤⤙≍ 5 Foo~Bar~a Foo~Bar 5
2727

28+
┌─╴Foo
29+
|Bar
30+
|Baz {A B}
31+
|Uiua [C]
32+
└─╴
33+
⍤⤙≍ {"Bar" "Baz" "Uiua"} Foo~Variants
34+
2835
┌─╴S
2936
~ {A B C}
3037
PopA ← ˜⊙∘⍜A(˜⊙∘⍜⇌°⊂)

todo.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
- LSP optimizations
55
- Fix rename
66
- Fix goto references
7-
- `Variants` field for module
8-
- Don't serialize sortedness flags
97
- Sided `join`
108
- `table` subscripts for rank selection
119
- Mixed subscripts

0 commit comments

Comments
 (0)