Merge pull request #3369 from rtfeldman/pure-roc-list-walk

List.walk and friends in pure Roc
This commit is contained in:
Folkert de Vries 2022-07-03 02:32:43 +02:00 committed by GitHub
commit 2a82d24847
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 344 additions and 1630 deletions

View file

@ -1304,35 +1304,49 @@ impl<'a> WasmBackend<'a> {
storage: &StoredValue,
fields: &'a [Symbol],
) {
if matches!(layout, Layout::Struct { .. }) {
match storage {
StoredValue::StackMemory { location, size, .. } => {
if *size > 0 {
let (local_id, struct_offset) =
location.local_and_offset(self.storage.stack_frame_pointer);
let mut field_offset = struct_offset;
for field in fields.iter() {
field_offset += self.storage.copy_value_to_memory(
&mut self.code_builder,
local_id,
field_offset,
*field,
);
match layout {
Layout::Struct { .. } => {
match storage {
StoredValue::StackMemory { location, size, .. } => {
if *size > 0 {
let (local_id, struct_offset) =
location.local_and_offset(self.storage.stack_frame_pointer);
let mut field_offset = struct_offset;
for field in fields.iter() {
field_offset += self.storage.copy_value_to_memory(
&mut self.code_builder,
local_id,
field_offset,
*field,
);
}
} else {
// Zero-size struct. No code to emit.
// These values are purely conceptual, they only exist internally in the compiler
}
} else {
// Zero-size struct. No code to emit.
// These values are purely conceptual, they only exist internally in the compiler
}
_ => {
internal_error!("Cannot create struct {:?} with storage {:?}", sym, storage)
}
};
}
Layout::LambdaSet(lambdaset) => {
self.expr_struct(sym, &lambdaset.runtime_representation(), storage, fields)
}
_ => {
if !fields.is_empty() {
// Struct expression but not Struct layout => single element. Copy it.
let field_storage = self.storage.get(&fields[0]).to_owned();
self.storage.clone_value(
&mut self.code_builder,
storage,
&field_storage,
fields[0],
);
} else {
// Empty record. Nothing to do.
}
_ => internal_error!("Cannot create struct {:?} with storage {:?}", sym, storage),
};
} else if !fields.is_empty() {
// Struct expression but not Struct layout => single element. Copy it.
let field_storage = self.storage.get(&fields[0]).to_owned();
self.storage
.clone_value(&mut self.code_builder, storage, &field_storage, fields[0]);
} else {
// Empty record. Nothing to do.
}
}
}

View file

@ -289,8 +289,8 @@ impl<'a> LowLevelCall<'a> {
ListIsUnique => self.load_args_and_call_zig(backend, bitcode::LIST_IS_UNIQUE),
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListWalk
| ListWalkUntil | ListWalkBackwards | ListSortWith | ListFindUnsafe | DictWalk => {
ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListSortWith
| DictWalk => {
internal_error!("HigherOrder lowlevels should not be handled here")
}
@ -2061,15 +2061,7 @@ pub fn call_higher_order_lowlevel<'a>(
*owns_captured_environment,
),
ListMapWithIndex { .. }
| ListWalk { .. }
| ListWalkUntil { .. }
| ListWalkBackwards { .. }
| ListSortWith { .. }
| ListAny { .. }
| ListAll { .. }
| ListFindUnsafe { .. }
| DictWalk { .. } => todo!("{:?}", op),
ListMapWithIndex { .. } | ListSortWith { .. } | DictWalk { .. } => todo!("{:?}", op),
}
}

View file

@ -3,11 +3,12 @@ use roc_std::{RocDec, RocList, RocOrder, RocStr};
pub trait Wasm32Sized: Sized {
const SIZE_OF_WASM: usize;
const ALIGN_OF_WASM: usize;
const ACTUAL_WIDTH: usize = if (Self::SIZE_OF_WASM % Self::ALIGN_OF_WASM) == 0 {
Self::SIZE_OF_WASM
} else {
Self::SIZE_OF_WASM + (Self::ALIGN_OF_WASM - (Self::SIZE_OF_WASM % Self::ALIGN_OF_WASM))
};
const ACTUAL_WIDTH: usize =
if (Self::ALIGN_OF_WASM == 0) || (Self::SIZE_OF_WASM % Self::ALIGN_OF_WASM) == 0 {
Self::SIZE_OF_WASM
} else {
Self::SIZE_OF_WASM + (Self::ALIGN_OF_WASM - (Self::SIZE_OF_WASM % Self::ALIGN_OF_WASM))
};
}
macro_rules! wasm32_sized_primitive {