mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-06 06:48:48 +00:00
Hash table
This commit is contained in:
parent
46dfd58bda
commit
149984f5c0
14 changed files with 258 additions and 21 deletions
73
stdlib/Array.expr
Normal file
73
stdlib/Array.expr
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import List;
|
||||
|
||||
public fun initArray (n, f) {
|
||||
local a = makeArray (n), i;
|
||||
|
||||
for i := 0, i < n, i := i + 1 do
|
||||
a [i] := f (i)
|
||||
od;
|
||||
|
||||
a
|
||||
}
|
||||
|
||||
public fun mapArray (f, a) {
|
||||
initArray (a.length, fun (i) {a[i]})
|
||||
}
|
||||
|
||||
public fun arrayList (a) {
|
||||
local i = 0, res = [0, {}], curr = res;
|
||||
|
||||
for skip, i < a.length, i := i + 1 do
|
||||
curr [1] := a [i] : curr [1];
|
||||
curr := curr [1]
|
||||
od;
|
||||
|
||||
res [1]
|
||||
}
|
||||
|
||||
public fun listArray (l) {
|
||||
local a = makeArray (l.size);
|
||||
|
||||
fun inner (i, l) {
|
||||
case l of {} -> skip | h : t -> a[i] := h; inner (i+1, t) esac
|
||||
}
|
||||
|
||||
inner (0, l);
|
||||
a
|
||||
}
|
||||
|
||||
public fun foldlArray (f, acc, a) {
|
||||
local i = 0;
|
||||
|
||||
for skip, i < a.length, i := i+1 do
|
||||
acc := f (acc, a[i])
|
||||
od;
|
||||
|
||||
acc
|
||||
}
|
||||
|
||||
public fun foldrArray (f, acc, a) {
|
||||
local i = a.length - 1;
|
||||
|
||||
for skip, i >= 0, i := i-1 do
|
||||
acc := f (acc, a[i])
|
||||
od;
|
||||
|
||||
acc
|
||||
}
|
||||
|
||||
public fun iterArray (f, a) {
|
||||
local i = 0;
|
||||
|
||||
for skip, i < a.length, i := i+1 do
|
||||
f (a [i])
|
||||
od
|
||||
}
|
||||
|
||||
public fun iteriArray (f, a) {
|
||||
local i = 0;
|
||||
|
||||
for skip, i < a.length, i := i+1 do
|
||||
f (i, a [i])
|
||||
od
|
||||
}
|
||||
|
|
@ -6,15 +6,14 @@
|
|||
|
||||
import List;
|
||||
|
||||
fun insertColl (m, k, v, sort) {
|
||||
fun insertColl (m, pk, v, sort) {
|
||||
local k = case sort of Hash -> hash (pk) | _ -> pk esac;
|
||||
|
||||
fun append (v, vs) {
|
||||
case sort of
|
||||
Map -> v : vs
|
||||
| Set -> v
|
||||
| Hash -> case find (fun (x) {x == v}, vs) of
|
||||
None -> v : vs
|
||||
| _ -> vs
|
||||
esac
|
||||
| Hash -> [pk, v] : vs
|
||||
esac
|
||||
}
|
||||
|
||||
|
|
@ -75,11 +74,17 @@ fun insertColl (m, k, v, sort) {
|
|||
inner (m).snd
|
||||
}
|
||||
|
||||
fun findColl (m, k, sort) {
|
||||
fun findColl (m, pk, sort) {
|
||||
local k = case sort of Hash -> hash (pk) | _ -> pk esac;
|
||||
|
||||
fun extract (vv) {
|
||||
case sort of
|
||||
Map -> case vv of v : _ -> Some (v) | _ -> None esac
|
||||
| Set -> Some (vv)
|
||||
Map -> case vv of v : _ -> Some (v) | _ -> None esac
|
||||
| Set -> Some (vv)
|
||||
| Hash -> case find (fun (x) {x.fst == pk}, vv) of
|
||||
Some (p) -> Some (p.snd)
|
||||
| None -> None
|
||||
esac
|
||||
esac
|
||||
}
|
||||
|
||||
|
|
@ -98,11 +103,14 @@ fun findColl (m, k, sort) {
|
|||
inner (m)
|
||||
}
|
||||
|
||||
fun removeColl (m, k, sort) {
|
||||
fun removeColl (m, pk, sort) {
|
||||
local k = case sort of Hash -> hash (pk) | _ -> pk esac;
|
||||
|
||||
fun delete (vs) {
|
||||
case sort of
|
||||
Map -> case vs of {} -> {} | _ : vv -> vv esac
|
||||
| Set -> false
|
||||
Map -> case vs of {} -> {} | _ : vv -> vv esac
|
||||
| Set -> false
|
||||
| Hash -> remove (fun (x) {x.fst == pk}, vs)
|
||||
esac
|
||||
}
|
||||
|
||||
|
|
@ -249,11 +257,45 @@ public fun foldSet (f, acc, s) {
|
|||
foldl (f, acc, elements (s))
|
||||
}
|
||||
|
||||
-- Hash structure
|
||||
-- Hash consing
|
||||
public fun emptyMemo () {
|
||||
[{}]
|
||||
}
|
||||
|
||||
public fun lookupMemo (m, v) {
|
||||
skip
|
||||
case v of
|
||||
#unboxed -> v
|
||||
| _ ->
|
||||
case findMap (m[0], v) of
|
||||
Some (w) -> w
|
||||
| None ->
|
||||
case v of
|
||||
#string -> m[0] := addMap (m[0], v, v); v
|
||||
| _ ->
|
||||
local vc = clone (v), i = case vc of #fun -> 1 | _ -> 0 esac;
|
||||
for skip, i < v.length, i := i + 1 do
|
||||
vc [i] := lookupMemo (m, vc [i])
|
||||
od;
|
||||
m[0] := addMap (m[0], vc, vc);
|
||||
vc
|
||||
esac
|
||||
esac
|
||||
esac
|
||||
}
|
||||
|
||||
-- Maps of hashed pointers
|
||||
public fun emptyHashTab () {
|
||||
{}
|
||||
}
|
||||
|
||||
public fun addHashTab (t, k, v) {
|
||||
insertColl (t, k, v, Hash)
|
||||
}
|
||||
|
||||
public fun findHashTab (t, k) {
|
||||
findColl (t, k, Hash)
|
||||
}
|
||||
|
||||
public fun removeHashTab (t, k) {
|
||||
removeColl (t, k, Hash)
|
||||
}
|
||||
|
|
@ -1,3 +1,10 @@
|
|||
public fun size (l) {
|
||||
case l of
|
||||
{} -> 0
|
||||
| _ : t -> 1 + size (t)
|
||||
esac
|
||||
}
|
||||
|
||||
public fun foldl (f, acc, l) {
|
||||
case l of
|
||||
{} -> acc
|
||||
|
|
@ -59,13 +66,13 @@ public fun find (f, l) {
|
|||
}
|
||||
|
||||
public fun flatten (l) {
|
||||
local res = [0, {}];
|
||||
local res = [0, {}], curr = [res];
|
||||
|
||||
fun append (x) {
|
||||
local new = {x};
|
||||
local new = x : {};
|
||||
|
||||
res [1] := new;
|
||||
res := new
|
||||
curr [0][1] := new;
|
||||
curr [0] := new
|
||||
}
|
||||
|
||||
iter (fun (x) {iter (append, x)}, l);
|
||||
|
|
@ -88,4 +95,18 @@ public fun unzip (a) {
|
|||
[aa, bb] -> [a : aa, b : bb]
|
||||
esac
|
||||
esac
|
||||
}
|
||||
|
||||
public fun remove (f, l) {
|
||||
case l of
|
||||
{} -> {}
|
||||
| h : t -> if f (h) then t else h : remove (f, t) fi
|
||||
esac
|
||||
}
|
||||
|
||||
public fun filter (f, l) {
|
||||
case l of
|
||||
{} -> {}
|
||||
| h : t -> if f (h) then h : filter (f, t) else filter (f, t) fi
|
||||
esac
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ all: $(ALL)
|
|||
|
||||
Collection.o: List.o
|
||||
|
||||
Array.o: List.o
|
||||
|
||||
%.o: %.expr
|
||||
$(RC) -I . -c $<
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ check: $(TESTS)
|
|||
|
||||
$(TESTS): %: %.expr
|
||||
@echo $@
|
||||
RC_RUNTIME=../../runtime $(RC) -I .. $< && ./$@ > $@.log && diff $@.log orig/$@.log
|
||||
RC_RUNTIME=../../runtime $(RC) -I .. -ds -dp $< && ./$@ > $@.log && diff $@.log orig/$@.log
|
||||
|
||||
clean:
|
||||
$(RM) test*.log *.s *~ $(TESTS) *.i
|
||||
|
|
|
|||
9
stdlib/regression/orig/test05.log
Normal file
9
stdlib/regression/orig/test05.log
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Cached: 1
|
||||
Cached: 1
|
||||
Cached: 1
|
||||
Cached: 1
|
||||
Cached: 1
|
||||
Cached: 1
|
||||
Cached: 1
|
||||
Cached: 1
|
||||
Cached: 1
|
||||
6
stdlib/regression/orig/test06.log
Normal file
6
stdlib/regression/orig/test06.log
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
Flattening: 0
|
||||
Flattening: 0
|
||||
Flattening: {1, 2, 3}
|
||||
Flattening: {1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
List to array: [1, 2, 3, 4, 5]
|
||||
Array to list: {1, 2, 3, 4, 5}
|
||||
6
stdlib/regression/orig/test07.log
Normal file
6
stdlib/regression/orig/test07.log
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
HashTab internal structure: MNode (-624426958, {[{1, 2, 3}, 100]}, 0, 0, 0)
|
||||
HashTab internal structure: MNode (-624426958, {[{1, 2, 3}, 200], [{1, 2, 3}, 100]}, 0, 0, 0)
|
||||
Searching: Some (100)
|
||||
Searching: Some (200)
|
||||
Replaced: Some (800)
|
||||
Restored: Some (100)
|
||||
22
stdlib/regression/test05.expr
Normal file
22
stdlib/regression/test05.expr
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import Collection;
|
||||
|
||||
fun f (x, y) {
|
||||
fun () {x+y}
|
||||
}
|
||||
|
||||
local t = emptyMemo (),
|
||||
a = lookupMemo (t, "abc"),
|
||||
b = lookupMemo (t, [1, 2, 3, 4, "abc"]),
|
||||
c = lookupMemo (t, f (5, 6));
|
||||
|
||||
printf ("Cached: %d\n", lookupMemo (t, "abc") == a);
|
||||
printf ("Cached: %d\n", lookupMemo (t, "abc") == a);
|
||||
printf ("Cached: %d\n", lookupMemo (t, "abc") == a);
|
||||
|
||||
printf ("Cached: %d\n", lookupMemo (t, [1, 2, 3, 4, "abc"]) == b);
|
||||
printf ("Cached: %d\n", lookupMemo (t, [1, 2, 3, 4, "abc"]) == b);
|
||||
printf ("Cached: %d\n", lookupMemo (t, [1, 2, 3, 4, "abc"]) == b);
|
||||
|
||||
printf ("Cached: %d\n", lookupMemo (t, f (5, 6)) == c);
|
||||
printf ("Cached: %d\n", lookupMemo (t, f (5, 6)) == c);
|
||||
printf ("Cached: %d\n", lookupMemo (t, f (5, 6)) == c)
|
||||
9
stdlib/regression/test06.expr
Normal file
9
stdlib/regression/test06.expr
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import List;
|
||||
import Array;
|
||||
|
||||
printf ("Flattening: %s\n", flatten ({}).string);
|
||||
printf ("Flattening: %s\n", flatten ({{}, {}, {}}).string);
|
||||
printf ("Flattening: %s\n", flatten ({1, 2, 3} : {}).string);
|
||||
printf ("Flattening: %s\n", flatten ({{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}).string);
|
||||
printf ("List to array: %s\n", listArray ({1, 2, 3, 4, 5}).string);
|
||||
printf ("Array to list: %s\n", arrayList ([1, 2,3, 4, 5]).string)
|
||||
26
stdlib/regression/test07.expr
Normal file
26
stdlib/regression/test07.expr
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import Collection;
|
||||
|
||||
local a = {1, 2, 3}, b = {1, 2, 3}, t = emptyHashTab ();
|
||||
|
||||
t := addHashTab (t, a, 100);
|
||||
validateColl ();
|
||||
printf ("HashTab internal structure: %s\n", t.string);
|
||||
|
||||
t := addHashTab (t, b, 200);
|
||||
validateColl ();
|
||||
printf ("HashTab internal structure: %s\n", t.string);
|
||||
|
||||
printf ("Searching: %s\n", findHashTab (t, a).string);
|
||||
printf ("Searching: %s\n", findHashTab (t, b).string);
|
||||
|
||||
t := addHashTab (t, a, 800);
|
||||
validateColl (t);
|
||||
|
||||
printf ("Replaced: %s\n", findHashTab (t, a).string);
|
||||
|
||||
t := removeHashTab (t, a);
|
||||
validateColl (t);
|
||||
printf ("Restored: %s\n", findHashTab (t, a).string)
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue