First run at a dead-simple map library. Writing this has reminded me of the need for a []= operator as well as automatic generation of functions for objects, which really should also include ==

This commit is contained in:
Nathan Braswell
2015-06-27 10:04:09 -04:00
parent f3c0c8a705
commit b18c18ec30
6 changed files with 112 additions and 1 deletions

48
stdlib/map.krak Normal file
View File

@@ -0,0 +1,48 @@
import vector
fun map<T,U>(): map<T,U> {
var toRet.construct(): map<T,U>
return toRet
}
fun map<T,U>(key:T, value:U): map<T,U> {
var toRet.construct(): map<T,U>
toRet.set(key, value)
return toRet
}
obj map<T,U> {
var keys: vector::vector<T>
var values: vector::vector<T>
fun construct() {
keys.construct()
values.construct()
}
fun copy_construct(old: map<T,U>*) {
keys.copy_construct(&old->keys)
values.copy_construct(&old->values)
}
fun destruct() {
keys.destruct()
values.destruct()
}
fun find_index(key: T): int {
return keys.find_index(key)
}
fun set(key: T, value: U) {
var keyIdx = find_index(key)
if (keyIdx >= 0) {
values.set(keyIdx, value)
return;
}
keys.add(key)
values.add(value)
}
fun get(key: T): U {
return values.get(keys.find_index(key))
}
fun operator[](key: T): U {
return get(key)
}
}

View File

@@ -2,17 +2,33 @@ import mem:*;
import util:*;
import io:*;
fun vector<T>():vector<T> {
var out.construct():vector<T>
return out
}
fun vector<T>(in:T):vector<T> {
var out.construct():vector<T>
out.add(in)
return out
}
fun vector<T>():vector<T> {
fun vector<T>(first:T, second:T):vector<T> {
var out.construct():vector<T>
out.add(first)
out.add(second)
return out
}
fun vector<T>(first:T, second:T, third:T):vector<T> {
var out.construct():vector<T>
out.add(first)
out.add(second)
out.add(third)
return out
}
obj vector<T> (Object) {
var data: T*;
var size: int;
@@ -112,6 +128,18 @@ obj vector<T> (Object) {
fun getBackingMemory(): T* { return data; }
// This is a template for the interesting reason that structs
// can not be compared for equality in C, and maybe we haven't defined equality
// on an object that we want to put in a vector. In this way we avoid the problem
// by not generating this function unless it's called - we also get the ability to
// do a find index using a different type, which could be fun.
fun find_index<U>(value: U): int {
for (var i = 0; i < size; i++;)
if (data[i] == value)
return i;
return -1;
}
fun set(index: int, dataIn: T): void {
if (index < 0 || index >= size)
return;

View File

@@ -0,0 +1,7 @@
3
2
1
3
20
2
4

18
tests/test_map.krak Normal file
View File

@@ -0,0 +1,18 @@
import io:*
import map:*
fun main():int {
var m = map(3,1)
m.set(2,2)
m.set(1,3)
println(m[1])
println(m[2])
println(m[3])
m.set(3,4)
m.set(4,20)
println(m[1])
println(m[4])
println(m[2])
println(m[3])
return 0
}

View File

@@ -21,5 +21,9 @@ middle: 23
all but first: 234
all but last: 123
just some: 2
find test
0
1
2
done
Destroyed: 0

View File

@@ -105,6 +105,12 @@ fun main(): int {
sliceTest.slice(1,2).do(fun(it:int):void print(it);)
println()
println("find test")
var multipleFindTest = vector(1,2,3)
println(multipleFindTest.find_index(1))
println(multipleFindTest.find_index(2))
println(multipleFindTest.find_index(3))
println("done")
return 0;