diff --git a/stdlib/Collection.expr b/stdlib/Collection.expr index d16ffb2b2..069c4b26f 100644 --- a/stdlib/Collection.expr +++ b/stdlib/Collection.expr @@ -4,6 +4,8 @@ -- This package provides a simplistic implementation of immutable set/map/hashtable -- data structures. +import List; + fun insert (m, k, v, sort) { fun append (v, vs) { case sort of @@ -70,7 +72,7 @@ fun insert (m, k, v, sort) { inner (m).snd } -public fun find (m, k, sort) { +fun find (m, k, sort) { fun extract (vv) { case sort of Map -> case vv of v : _ -> Some (v) | _ -> None esac @@ -93,7 +95,7 @@ public fun find (m, k, sort) { inner (m) } -public fun remove (m, k, sort) { +fun remove (m, k, sort) { fun delete (vs) { case sort of Map -> case vs of {} -> {} | _ : vv -> vv esac @@ -200,4 +202,28 @@ public fun removeSet (s, v) { public fun elements (m) { contents (m, Set) +} + +public fun union (a, b) { + foldl (addSet, a, elements (b)) +} + +public fun diff (a, b) { + foldl (removeSet, a, elements (b)) +} + +public fun listSet (l) { + foldl (addSet, emptySet (), l) +} + +public fun iterSet (f, s) { + iter (f, elements (s)) +} + +public fun mapSet (f, s) { + listSet (map (f, elements (s))) +} + +public fun foldSet (f, acc, s) { + foldl (f, acc, elements (s)) } \ No newline at end of file diff --git a/stdlib/List.expr b/stdlib/List.expr new file mode 100644 index 000000000..4bece0362 --- /dev/null +++ b/stdlib/List.expr @@ -0,0 +1,91 @@ +public fun foldl (f, acc, l) { + case l of + {} -> acc + | x : xs -> foldl (f, f (acc, x), xs) + esac +} + +public fun foldr (f, acc, l) { + case l of + {} -> acc + | x : xs -> f (foldr (f, acc, xs), x) + esac +} + +public fun iter (f, l) { + case l of + {} -> skip + | x : xs -> f (x); iter (f, xs) + esac +} + +public fun map (f, l) { + case l of + {} -> {} + | x : xs -> f (x) : map (f, xs) + esac +} + +public infix +++ at + (x, y) { + case x of + {} -> y + | x : xs -> x : xs +++ y + esac +} + +public fun reverse (l) { + fun inner (acc, l) { + case l of + {} -> acc + | x : xs -> inner (x : acc, xs) + esac + } + + inner ({}, l) +} + +public fun assoc (l, x) { + case l of + {} -> None + | [y, z] : ys -> if compare (x, y) == 0 then Some (z) else assoc (ys, x) fi + esac +} + +public fun find (f, l) { + case l of + {} -> None + | x : xs -> if f (x) then Some (x) else find (f, xs) fi + esac +} + +public fun flatten (l) { + local res = [0, {}]; + + fun append (x) { + local new = {x}; + + res [1] := new; + res := new + } + + iter (fun (x) {iter (append, x)}, l); + + res [1] +} + +public fun zip (a, b) { + case [a, b] of + [{}, {}] -> {} + | [a : aa, b : bb] -> [a, b] : zip (aa, bb) + esac +} + +public fun unzip (a) { + case a of + {} -> [{}, {}] + | [a, b] : aa -> + case unzip (aa) of + [aa, bb] -> [a : aa, b : bb] + esac + esac +} \ No newline at end of file diff --git a/stdlib/Makefile b/stdlib/Makefile index be90deb9d..1d56d19d8 100644 --- a/stdlib/Makefile +++ b/stdlib/Makefile @@ -7,7 +7,7 @@ RC=../src/rc.opt all: $(ALL) %.o: %.expr - $(RC) -c $< + $(RC) -I . -c $< clean: rm -Rf *.s *.o *.i *~ diff --git a/stdlib/regression/orig/test01.log b/stdlib/regression/orig/test01.log index 327ba72eb..018d8559a 100644 --- a/stdlib/regression/orig/test01.log +++ b/stdlib/regression/orig/test01.log @@ -302,3 +302,8 @@ Testing 96 => 0 Testing 97 => 0 Testing 98 => 0 Testing 99 => 0 +List set: MNode (2, 1, -1, MNode (1, 1, 0, 0, 0), MNode (4, 1, 0, MNode (3, 1, 0, 0, 0), MNode (5, 1, 0, 0, 0))) +Set union: MNode (4, 1, -1, MNode (2, 1, 0, MNode (1, 1, 0, 0, 0), MNode (3, 1, 0, 0, 0)), MNode (33, 1, 0, MNode (11, 1, 0, MNode (5, 1, 0, 0, 0), MNode (22, 1, 0, 0, 0)), MNode (44, 1, -1, 0, MNode (55, 1, 0, 0, 0)))) +Elements: {1, 2, 3, 4, 5, 11, 22, 33, 44, 55} +Set difference: MNode (4, 1, -1, MNode (2, 1, 0, MNode (1, 0, 0, 0, 0), MNode (3, 0, 0, 0, 0)), MNode (33, 1, 0, MNode (11, 1, 0, MNode (5, 0, 0, 0, 0), MNode (22, 0, 0, 0, 0)), MNode (44, 0, -1, 0, MNode (55, 1, 0, 0, 0)))) +Elements: {2, 4, 11, 33, 55} diff --git a/stdlib/regression/test01.expr b/stdlib/regression/test01.expr index 23dc56efe..923db45de 100644 --- a/stdlib/regression/test01.expr +++ b/stdlib/regression/test01.expr @@ -29,5 +29,22 @@ printf ("Set elements: %s\n", elements (s).string); for i := 0, i < 100, i := i+1 do printf ("Testing %-3d => %d\n", i, memSet (s, i)) -od +od; + +printf ("List set: %s\n", listSet ({1, 2, 3, 4, 5}).string); + +{ + local u = union (listSet ({1, 2, 3, 4, 5}), listSet ({11, 22, 33, 44, 55})), u1; + + validateColl (u); + + printf ("Set union: %s\n", u.string); + printf ("Elements: %s\n", elements (u).string); + + u1 := diff (u, listSet ({1, 22, 3, 44, 5})); + validateColl (u1); + + printf ("Set difference: %s\n", u1.string); + printf ("Elements: %s\n", elements (u1).string) +}