mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
dict and set layouts
This commit is contained in:
parent
047514bf39
commit
6c1f3eedb7
2 changed files with 139 additions and 13 deletions
64
cli_utils/Cargo.lock
generated
64
cli_utils/Cargo.lock
generated
|
@ -191,6 +191,18 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitvec"
|
||||||
|
version = "0.22.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527"
|
||||||
|
dependencies = [
|
||||||
|
"funty",
|
||||||
|
"radium",
|
||||||
|
"tap",
|
||||||
|
"wyz",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block"
|
name = "block"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -968,6 +980,12 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
|
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "funty"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
|
@ -1919,6 +1937,28 @@ dependencies = [
|
||||||
"ttf-parser 0.13.2",
|
"ttf-parser 0.13.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "packed_struct"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c48e482b9a59ad6c2cdb06f7725e7bd33fe3525baaf4699fde7bfea6a5b77b1"
|
||||||
|
dependencies = [
|
||||||
|
"bitvec",
|
||||||
|
"packed_struct_codegen",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "packed_struct_codegen"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56e3692b867ec1d48ccb441e951637a2cc3130d0912c0059e48319e1c83e44bc"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "page_size"
|
name = "page_size"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -2210,6 +2250,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radium"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.4"
|
version = "0.8.4"
|
||||||
|
@ -2603,6 +2649,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"object 0.26.2",
|
"object 0.26.2",
|
||||||
|
"packed_struct",
|
||||||
"roc_builtins",
|
"roc_builtins",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
|
@ -2771,6 +2818,7 @@ dependencies = [
|
||||||
name = "roc_solve"
|
name = "roc_solve"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
|
@ -2787,6 +2835,7 @@ version = "0.1.0"
|
||||||
name = "roc_types"
|
name = "roc_types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_region",
|
"roc_region",
|
||||||
|
@ -3163,6 +3212,12 @@ dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tap"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "target-lexicon"
|
name = "target-lexicon"
|
||||||
version = "0.12.2"
|
version = "0.12.2"
|
||||||
|
@ -3807,6 +3862,15 @@ dependencies = [
|
||||||
"rand_core 0.6.3",
|
"rand_core 0.6.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wyz"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188"
|
||||||
|
dependencies = [
|
||||||
|
"tap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x11-clipboard"
|
name = "x11-clipboard"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::collections::hash_map::Entry;
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
use crate::layout::{ext_var_is_empty_record, ext_var_is_empty_tag_union};
|
use crate::layout::{ext_var_is_empty_record, ext_var_is_empty_tag_union};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct Index<T> {
|
pub struct Index<T> {
|
||||||
index: u32,
|
index: u32,
|
||||||
_marker: std::marker::PhantomData<T>,
|
_marker: std::marker::PhantomData<T>,
|
||||||
|
@ -24,7 +24,7 @@ impl<T> Index<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct Slice<T> {
|
pub struct Slice<T> {
|
||||||
start: u32,
|
start: u32,
|
||||||
length: u16,
|
length: u16,
|
||||||
|
@ -347,7 +347,7 @@ impl LambdaSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum Layout {
|
pub enum Layout {
|
||||||
// theory: we can zero out memory to reserve space for many layouts
|
// theory: we can zero out memory to reserve space for many layouts
|
||||||
Reserved,
|
Reserved,
|
||||||
|
@ -401,7 +401,30 @@ fn round_up_to_alignment(unaligned: u16, alignment_bytes: u16) -> u16 {
|
||||||
|
|
||||||
impl Layouts {
|
impl Layouts {
|
||||||
const VOID_INDEX: Index<Layout> = Index::new(0);
|
const VOID_INDEX: Index<Layout> = Index::new(0);
|
||||||
// const UNIT_INDEX: Index<Layout> = Index::new(1);
|
const VOID_TUPLE: Index<(Layout, Layout)> = Index::new(0);
|
||||||
|
const UNIT_INDEX: Index<Layout> = Index::new(2);
|
||||||
|
|
||||||
|
pub fn new(usize_int_width: IntWidth) -> Self {
|
||||||
|
let mut layouts = Vec::with_capacity(64);
|
||||||
|
|
||||||
|
layouts.push(Layout::VOID);
|
||||||
|
layouts.push(Layout::VOID);
|
||||||
|
layouts.push(Layout::UNIT);
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
debug_assert_eq!(layouts[Self::VOID_INDEX.index as usize], Layout::VOID);
|
||||||
|
debug_assert_eq!(layouts[Self::VOID_TUPLE.index as usize + 1], Layout::VOID);
|
||||||
|
debug_assert_eq!(layouts[Self::UNIT_INDEX.index as usize], Layout::UNIT);
|
||||||
|
|
||||||
|
Layouts {
|
||||||
|
layouts: Vec::default(),
|
||||||
|
layout_slices: Vec::default(),
|
||||||
|
lambda_sets: Vec::default(),
|
||||||
|
symbols: Vec::default(),
|
||||||
|
recursion_variable_to_structure_variable_map: MutMap::default(),
|
||||||
|
usize_int_width,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// sort a slice according to elements' alignment
|
/// sort a slice according to elements' alignment
|
||||||
fn sort_slice_by_alignment(&mut self, layout_slice: Slice<Layout>) {
|
fn sort_slice_by_alignment(&mut self, layout_slice: Slice<Layout>) {
|
||||||
|
@ -539,6 +562,8 @@ impl Layout {
|
||||||
pub const VOID: Self = Self::UnionNonRecursive(Slice::new(0, 0));
|
pub const VOID: Self = Self::UnionNonRecursive(Slice::new(0, 0));
|
||||||
|
|
||||||
pub const EMPTY_LIST: Self = Self::List(Layouts::VOID_INDEX);
|
pub const EMPTY_LIST: Self = Self::List(Layouts::VOID_INDEX);
|
||||||
|
pub const EMPTY_DICT: Self = Self::Dict(Layouts::VOID_TUPLE);
|
||||||
|
pub const EMPTY_SET: Self = Self::Set(Layouts::VOID_INDEX);
|
||||||
|
|
||||||
pub fn from_var(
|
pub fn from_var(
|
||||||
layouts: &mut Layouts,
|
layouts: &mut Layouts,
|
||||||
|
@ -558,6 +583,19 @@ impl Layout {
|
||||||
Self::from_content(layouts, subs, var, content)
|
Self::from_content(layouts, subs, var, content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_var_help_or_void(
|
||||||
|
layouts: &mut Layouts,
|
||||||
|
subs: &Subs,
|
||||||
|
var: Variable,
|
||||||
|
) -> Result<Layout, LayoutError> {
|
||||||
|
let content = &subs.get_ref(var).content;
|
||||||
|
match Self::from_content(layouts, subs, var, content) {
|
||||||
|
Ok(layout) => Ok(layout),
|
||||||
|
Err(LayoutError::UnresolvedVariable(_)) => Ok(Layout::VOID),
|
||||||
|
Err(other) => Err(other),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn from_content(
|
fn from_content(
|
||||||
layouts: &mut Layouts,
|
layouts: &mut Layouts,
|
||||||
subs: &Subs,
|
subs: &Subs,
|
||||||
|
@ -640,16 +678,40 @@ impl Layout {
|
||||||
debug_assert_eq!(arguments.len(), 1);
|
debug_assert_eq!(arguments.len(), 1);
|
||||||
|
|
||||||
let element_var = subs.variables[arguments.slice.start as usize];
|
let element_var = subs.variables[arguments.slice.start as usize];
|
||||||
match Self::from_var_help(layouts, subs, element_var) {
|
let element_layout = Self::from_var_help_or_void(layouts, subs, element_var)?;
|
||||||
Ok(element_layout) => {
|
|
||||||
let element_index = Index::new(layouts.layouts.len() as _);
|
let element_index = Index::new(layouts.layouts.len() as _);
|
||||||
layouts.layouts.push(element_layout);
|
layouts.layouts.push(element_layout);
|
||||||
|
|
||||||
Ok(Layout::List(element_index))
|
Ok(Layout::List(element_index))
|
||||||
}
|
}
|
||||||
Err(UnresolvedVariable(_)) => Ok(Layout::EMPTY_LIST),
|
|
||||||
Err(other) => Err(other),
|
FlatType::Apply(Symbol::DICT_DICT, arguments) => {
|
||||||
|
debug_assert_eq!(arguments.len(), 2);
|
||||||
|
|
||||||
|
let key_var = subs.variables[arguments.slice.start as usize];
|
||||||
|
let value_var = subs.variables[arguments.slice.start as usize + 1];
|
||||||
|
|
||||||
|
let key_layout = Self::from_var_help_or_void(layouts, subs, key_var)?;
|
||||||
|
let value_layout = Self::from_var_help_or_void(layouts, subs, value_var)?;
|
||||||
|
|
||||||
|
let index = Index::new(layouts.layouts.len() as _);
|
||||||
|
layouts.layouts.push(key_layout);
|
||||||
|
layouts.layouts.push(value_layout);
|
||||||
|
|
||||||
|
Ok(Layout::Dict(index))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlatType::Apply(Symbol::SET_SET, arguments) => {
|
||||||
|
debug_assert_eq!(arguments.len(), 1);
|
||||||
|
|
||||||
|
let element_var = subs.variables[arguments.slice.start as usize];
|
||||||
|
let element_layout = Self::from_var_help_or_void(layouts, subs, element_var)?;
|
||||||
|
|
||||||
|
let element_index = Index::new(layouts.layouts.len() as _);
|
||||||
|
layouts.layouts.push(element_layout);
|
||||||
|
|
||||||
|
Ok(Layout::Set(element_index))
|
||||||
}
|
}
|
||||||
|
|
||||||
FlatType::Apply(symbol, _) => {
|
FlatType::Apply(symbol, _) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue