diff --git a/stdlib/map.krak b/stdlib/map.krak new file mode 100644 index 0000000..8adfc98 --- /dev/null +++ b/stdlib/map.krak @@ -0,0 +1,48 @@ +import vector + +fun map(): map { + var toRet.construct(): map + return toRet +} +fun map(key:T, value:U): map { + var toRet.construct(): map + toRet.set(key, value) + return toRet +} + +obj map { + var keys: vector::vector + var values: vector::vector + + fun construct() { + keys.construct() + values.construct() + } + fun copy_construct(old: map*) { + 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) + } +} + diff --git a/stdlib/vector.krak b/stdlib/vector.krak index 44a15e7..a5b7919 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -2,17 +2,33 @@ import mem:*; import util:*; import io:*; +fun vector():vector { + var out.construct():vector + return out +} + fun vector(in:T):vector { var out.construct():vector out.add(in) return out } -fun vector():vector { +fun vector(first:T, second:T):vector { var out.construct():vector + out.add(first) + out.add(second) return out } +fun vector(first:T, second:T, third:T):vector { + var out.construct():vector + out.add(first) + out.add(second) + out.add(third) + return out +} + + obj vector (Object) { var data: T*; var size: int; @@ -112,6 +128,18 @@ obj vector (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(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; diff --git a/tests/test_map.expected_results b/tests/test_map.expected_results new file mode 100644 index 0000000..0a2df2e --- /dev/null +++ b/tests/test_map.expected_results @@ -0,0 +1,7 @@ +3 +2 +1 +3 +20 +2 +4 diff --git a/tests/test_map.krak b/tests/test_map.krak new file mode 100644 index 0000000..5a25e99 --- /dev/null +++ b/tests/test_map.krak @@ -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 +} diff --git a/tests/test_vectorTest.expected_results b/tests/test_vectorTest.expected_results index 3e90128..d9e3a47 100644 --- a/tests/test_vectorTest.expected_results +++ b/tests/test_vectorTest.expected_results @@ -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 diff --git a/tests/test_vectorTest.krak b/tests/test_vectorTest.krak index baf85d1..ea6aea6 100644 --- a/tests/test_vectorTest.krak +++ b/tests/test_vectorTest.krak @@ -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;