From c1320735298e2dd9e78b97f35b3f6e5d69030b35 Mon Sep 17 00:00:00 2001 From: Dmitry Boulytchev Date: Wed, 15 Jan 2020 06:12:01 +0300 Subject: [PATCH] More collection; added list functions --- stdlib/Collection.expr | 30 +++++++++- stdlib/List.expr | 91 +++++++++++++++++++++++++++++++ stdlib/Makefile | 2 +- stdlib/regression/orig/test01.log | 5 ++ stdlib/regression/test01.expr | 19 ++++++- 5 files changed, 143 insertions(+), 4 deletions(-) create mode 100644 stdlib/List.expr 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) +}