diff --git a/luminapath/std/list/lib.lm b/luminapath/std/list/lib.lm index 2b46b1b..429079e 100644 --- a/luminapath/std/list/lib.lm +++ b/luminapath/std/list/lib.lm @@ -2,6 +2,7 @@ use std:maybe [Maybe [..]] use std:math [Compare, Num [+]] use vec [Vec] use slice [Slice] +use ring [Deque] use std:io [crash] @![langItem(list as List)] @@ -49,10 +50,22 @@ pub fn ++ left right as List a, List a -> [a] = | _ -> Concat left right // TODO: we should remake this in a vastly more performant way by taking advantage of the concrete variants -pub fn fold f acc list as fn(b, a -> b), b, [a] -> b = +pub fn fold f acc list as fn(b, a -> b), b, List a -> b = match list - | [x : xs] -> fold #f (f acc x) xs - | [] -> acc + | Slice slice -> slice:fold #f acc slice + | Concat left right -> fold #f (fold #f acc left) right + | Singleton v -> f acc v + | Nil -> acc + // match list + // | [x : xs] -> fold #f (f acc x) xs + // | [] -> acc + +// Fold over a counter +pub fn ifold f acc n as fn(b, uint -> b), b, uint -> b = + next 0 acc + where + fn next i acc as uint, b -> b = + if n == i then acc else next (i + 1) (f acc i) // TODO: we should remake this in a vastly more performant way by taking advantage of the concrete variants pub fn map f list as fn(a -> b), [a] -> [b] = @@ -61,9 +74,26 @@ pub fn map f list as fn(a -> b), [a] -> [b] = | [] -> [] pub fn flat_map f list as fn(a -> [b]), [a] -> [b] = + fold #(\acc x -> acc ++ f x) [] list + +when a can Compare +pub fn trim v list as a, [a] -> [a] = match list - | [x : xs] -> f x ++ flat_map #f xs - | [] -> [] + | [x : xs] -> + if x == v + then trim_right v xs + else trim_right v (x : xs) + | [] -> [] + +when a can Compare +pub fn trim_right v list as a, [a] -> [a] = + match list + | [x] -> + if x == v + then [] + else [x] + | [x : xs] -> x : trim_right v xs + | [] -> [] // TODO: we should split out equality operator from Compare, then we can use a constraint here instead pub fn deduplicate f list as fn(a, a -> bool), [a] -> [a] = diff --git a/luminapath/std/list/slice.lm b/luminapath/std/list/slice.lm index 37f9fb3..8f7dd02 100644 --- a/luminapath/std/list/slice.lm +++ b/luminapath/std/list/slice.lm @@ -1,4 +1,5 @@ use std:list:vec [unsafe_take, from_range] +use std:list [ifold] pub type Slice a { // For pointer marking to work in the GC we need to hold on to the root @@ -32,6 +33,9 @@ pub fn unsafe_get i slice as uint, Slice a -> a = pub fn len {len} as Slice a -> uint = len +pub fn fold f acc slice as fn(b, a -> b), b, Slice a -> b = + ifold #(\acc i -> f acc (unsafe_get i slice)) acc slice.len + pub fn forEach f slice as fn(a -> ()), Slice a -> () = list:itimes #visit slice.len where diff --git a/luminapath/std/list/vec.lm b/luminapath/std/list/vec.lm index 7d15092..db36acb 100644 --- a/luminapath/std/list/vec.lm +++ b/luminapath/std/list/vec.lm @@ -60,6 +60,11 @@ pub fn map f vec as fn(a -> b), Vec a -> Vec b = (0, vec.len) #(\i -> unsafe_get i vec . f) +pub fn clone vec as Vec a -> Vec a = + from_range + (0, vec.len) + #(\i -> unsafe_get i vec) + when a can ToString impl ToString for Vec a fn show vec as self -> string = diff --git a/luminapath/std/ptr/lib.lm b/luminapath/std/ptr/lib.lm index e3110a7..622df7f 100644 --- a/luminapath/std/ptr/lib.lm +++ b/luminapath/std/ptr/lib.lm @@ -24,3 +24,6 @@ when t can Type pub fn box v as t -> *t = let ptr = alloc(t as t) in do write ptr v then ptr + +pub fn memcpy to from count as *a, *a, uint -> () = + builtin:memcpy to from (Type(a):size * count) diff --git a/luminapath/std/string/lib.lm b/luminapath/std/string/lib.lm index 98422a7..0d09b15 100644 --- a/luminapath/std/string/lib.lm +++ b/luminapath/std/string/lib.lm @@ -57,6 +57,9 @@ pub type string { inner List u8 } +pub fn trim v list as u8, string -> string = + { string | inner = list.inner . trim v } + pub fn len {inner} as string -> uint = inner . len pub fn take n str as uint, string -> string =