dict and set layouts

This commit is contained in:
Folkert 2021-11-26 21:39:36 +01:00
parent 047514bf39
commit 6c1f3eedb7
2 changed files with 139 additions and 13 deletions

64
cli_utils/Cargo.lock generated
View file

@ -191,6 +191,18 @@ dependencies = [
"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]]
name = "block"
version = "0.1.6"
@ -968,6 +980,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
[[package]]
name = "funty"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e"
[[package]]
name = "futures"
version = "0.3.17"
@ -1919,6 +1937,28 @@ dependencies = [
"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]]
name = "page_size"
version = "0.4.2"
@ -2210,6 +2250,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "radium"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
[[package]]
name = "rand"
version = "0.8.4"
@ -2603,6 +2649,7 @@ version = "0.1.0"
dependencies = [
"bumpalo",
"object 0.26.2",
"packed_struct",
"roc_builtins",
"roc_collections",
"roc_module",
@ -2771,6 +2818,7 @@ dependencies = [
name = "roc_solve"
version = "0.1.0"
dependencies = [
"bumpalo",
"roc_can",
"roc_collections",
"roc_module",
@ -2787,6 +2835,7 @@ version = "0.1.0"
name = "roc_types"
version = "0.1.0"
dependencies = [
"bumpalo",
"roc_collections",
"roc_module",
"roc_region",
@ -3163,6 +3212,12 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "target-lexicon"
version = "0.12.2"
@ -3807,6 +3862,15 @@ dependencies = [
"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]]
name = "x11-clipboard"
version = "0.5.3"

View file

@ -9,7 +9,7 @@ use std::collections::hash_map::Entry;
#[cfg(debug_assertions)]
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> {
index: u32,
_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> {
start: u32,
length: u16,
@ -347,7 +347,7 @@ impl LambdaSet {
}
}
#[derive(Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Layout {
// theory: we can zero out memory to reserve space for many layouts
Reserved,
@ -401,7 +401,30 @@ fn round_up_to_alignment(unaligned: u16, alignment_bytes: u16) -> u16 {
impl Layouts {
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
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 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(
layouts: &mut Layouts,
@ -558,6 +583,19 @@ impl Layout {
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(
layouts: &mut Layouts,
subs: &Subs,
@ -640,16 +678,40 @@ impl Layout {
debug_assert_eq!(arguments.len(), 1);
let element_var = subs.variables[arguments.slice.start as usize];
match Self::from_var_help(layouts, subs, element_var) {
Ok(element_layout) => {
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::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, _) => {