diff --git a/dm_lib/std/collections/collection.dm b/dm_lib/std/collections/collection.dm index bcdf014..2761ebd 100644 --- a/dm_lib/std/collections/collection.dm +++ b/dm_lib/std/collections/collection.dm @@ -1,6 +1,5 @@ ns std::collections -pub int Collection : Monad { +pub int Collection : Monad { size: Int - fn contains(element: T): Bool } diff --git a/dm_lib/std/collections/list.dm b/dm_lib/std/collections/list.dm index 03a4dcf..83ab2d3 100644 --- a/dm_lib/std/collections/list.dm +++ b/dm_lib/std/collections/list.dm @@ -2,82 +2,54 @@ ns std::collections use std::collections::Collection -pub int List : Collection { - fn add(element: T) - fn remove(element: T) - - fn index_of(element: T): Option +pub int Stack : Collection { + fn push(element: T) + fn pop(): Option fn get_at(index: Int): Option - fn remove_at(index: Int): Option } -// This implies that Int, Long, and Double don't implement Zero, because 0 could reasonably mean something -// whereas Unit means "null" for objects -pub impl ArrayList : List { +pub impl ArrayStack : Stack { + fld arr: mut Array = array::of_length(16, std::reflect::default_or_empty) + fld current_index: mut Int = 0 - mut fld arr: Array - mut fld current_index: Int = 0 - fld zero: Zero - - pub ctor(items: Array, zero: Zero) { - arr = items - self.zero = zero + impl fn map(m) { + let result: mut Array = array::of_length(arr.length, std::reflect::default_or_empty) + for (element, i) in arr.iter_with_indices() { + result[i] = m(element) + } + result } - pub ctor(size: Int, zero: Zero) { - arr = array::with_size(size, zero) - self.zero = zero + impl fn flat_map(m) { + let result: mut Array = array::of_length(arr.length, std::reflect::default_or_empty>) + for (element, i) in arr.iter_with_indices() { + result[i] = m(element) + } + array::flatten(result) } - pub ctor(zero: Zero) { - arr = array::with_size(8, zero) - self.zero = zero - } + impl fn get_size() = current_index - impl fn add(element) { + impl fn push(element) { if current_index == arr.length { - arr = array::clone_with_size(arr.length * 2, zero) + arr = array::clone(size = arr.length * 2, source = arr) } arr[current_index] = element current_index++ } - impl fn remove(element) { - let index = index_of(element).get_or_throw(() => NoSuchElementException()) - arr[index] = T::default - } - - impl fn index_of(element) { - for (e, index) in arr.iter_with_index() { - if e == element { - return Some(index) - } + impl fn pop() { + if current_index > 0 { + let element = arr[current_index - 1] + current_index-- + return Some(element) } None } - impl fn get_at(index) { - if index >= arr.length || index < 0 { - return None - } - let item = arr[index] - item == zero ? None : Some(item) - } - - impl fn remove_at(index) { - if index <= arr.length || index < 0 { - return None - } - let element = arr[index] - if element == zero { - return None - } - arr[index] = zero.item - Some(element) - } - + impl fn get_at(index) = index < arr.length ? Some(arr[index]) : None } -pub mod list { +pub mod stack { pub fn of(items: ...T): List = ArrayList(items) } diff --git a/dm_lib/std/core/array.dm b/dm_lib/std/core/array.dm index c4ae9b2..60650a5 100644 --- a/dm_lib/std/core/array.dm +++ b/dm_lib/std/core/array.dm @@ -1,6 +1,9 @@ ns std::core -pub int Array : Monad { +pub int Array : Monad + Default + Empty { + const default = array::empty + const empty = array::empty + length: Int } @@ -9,6 +12,24 @@ pub mod array { // Usage: // let int_array = array::of(1, 2, 3) // assert_eq(3, int_array.length) - decl pub fn of(ts: ...T): Array + pub extern fn of(ts: ...T): Array + + pub extern fn of_length(length: Int, init_value: T): Array + + pub extern fn empty(): Array + + pub fn flatten(ats: Array>): Array { + let total_ts = ats.map { ts -> ts.length } + .reduce { acc, current -> acc + current } + let result: mut Array = of_length(total_ts, std::reflect::default_or_empty) + let i: mut Int = 0 + for a in ats { + for element in a { + result[i] = element + i++ + } + } + result + } } diff --git a/dm_lib/std/core/character.dm b/dm_lib/std/core/character.dm index 431472f..a08dfd4 100644 --- a/dm_lib/std/core/character.dm +++ b/dm_lib/std/core/character.dm @@ -8,6 +8,6 @@ pub int Character : Display { } pub impl Utf8Character(bytes: Array) { - impl fn get_encoding() = Encoding::Utf8 + encoding = Encoding::Utf8 impl fn to_string() = string::from_utf8_bytes(bytes) } diff --git a/dm_lib/std/core/cls.dm b/dm_lib/std/core/cls.dm new file mode 100644 index 0000000..d3f1615 --- /dev/null +++ b/dm_lib/std/core/cls.dm @@ -0,0 +1,14 @@ +ns std::core + +pub cls Any { + fqn: String + simple_name: String +} + +pub cls Default { + default: Self +} + +pub cls Empty { + empty: Self +} diff --git a/dm_lib/std/core/print.dm b/dm_lib/std/core/print.dm index 0b5c401..ce19518 100644 --- a/dm_lib/std/core/print.dm +++ b/dm_lib/std/core/print.dm @@ -1,5 +1,7 @@ ns std::core -decl pub fn print(message: Any) +extern fn _print(message: Any) +extern fn _println(message: Any) -decl pub fn println(message: Any) +pub fn print(message: Any) = _print(message) +pub fn println(message: Any) = _println(message) diff --git a/dm_lib/std/core/string.dm b/dm_lib/std/core/string.dm index c07d330..317c26f 100644 --- a/dm_lib/std/core/string.dm +++ b/dm_lib/std/core/string.dm @@ -14,9 +14,11 @@ pub int String : Display { } impl Utf8String(bytes: Array) : String { - impl fn get_encoding() = Encoding::Utf8 - impl fn get_length() = bytes.length - impl fn get_characters() = todo('parse the utf8 bytes and return an Array') + encoding = Encoding::Utf8 + length = bytes.length + characters = lazy { + todo('parse the utf8 bytes and return an Array') + } } pub mod string { diff --git a/dm_lib/std/reflect/util.dm b/dm_lib/std/reflect/util.dm new file mode 100644 index 0000000..3810cd8 --- /dev/null +++ b/dm_lib/std/reflect/util.dm @@ -0,0 +1,6 @@ +ns std::reflect + +pub fn default_or_empty() { + T is Default ? T::default : T is Empty + ? T::empty : throw IllegalArgumentException("Type ${T::fqn} extends neither Default nor Empty.") +} \ No newline at end of file