Work on standard library.

This commit is contained in:
Jesse Brault 2024-12-04 20:57:46 -06:00
parent bb2edc1d49
commit d99ccf8807
8 changed files with 82 additions and 66 deletions

View File

@ -1,6 +1,5 @@
ns std::collections
pub int Collection<T : PartialEq> : Monad {
pub int Collection<T> : Monad {
size: Int
fn contains(element: T): Bool
}

View File

@ -2,82 +2,54 @@ ns std::collections
use std::collections::Collection
pub int List<T : PartialEq> : Collection<T> {
fn add(element: T)
fn remove(element: T)
fn index_of(element: T): Option<Int>
pub int Stack<T> : Collection<T> {
fn push(element: T)
fn pop(): Option<T>
fn get_at(index: Int): Option<T>
fn remove_at(index: Int): Option<T>
}
// 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<T : PartialEq> : List<T> {
pub impl ArrayStack<T : Default | Empty> : Stack<T> {
fld arr: mut Array<T> = array::of_length(16, std::reflect::default_or_empty<T>)
fld current_index: mut Int = 0
mut fld arr: Array<T>
mut fld current_index: Int = 0
fld zero: Zero<T>
pub ctor(items: Array<T>, zero: Zero<T>) {
arr = items
self.zero = zero
impl fn <U> map(m) {
let result: mut Array<U> = array::of_length(arr.length, std::reflect::default_or_empty<U>)
for (element, i) in arr.iter_with_indices() {
result[i] = m(element)
}
result
}
pub ctor(size: Int, zero: Zero<T>) {
arr = array::with_size(size, zero)
self.zero = zero
impl fn <U> flat_map(m) {
let result: mut Array<U> = array::of_length(arr.length, std::reflect::default_or_empty<Array<U>>)
for (element, i) in arr.iter_with_indices() {
result[i] = m(element)
}
array::flatten(result)
}
pub ctor(zero: Zero<T>) {
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 get_at(index) = index < arr.length ? Some(arr[index]) : None
}
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)
}
}
pub mod list {
pub mod stack {
pub fn of<T : PartialEq>(items: ...T): List<T> = ArrayList(items)
}

View File

@ -1,6 +1,9 @@
ns std::core
pub int Array<T> : Monad {
pub int Array<T> : Monad + Default + Empty {
const default = array::empty<Self>
const empty = array::empty<Self>
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<T>(ts: ...T): Array<T>
pub extern fn of<T>(ts: ...T): Array<T>
pub extern fn of_length<T>(length: Int, init_value: T): Array<T>
pub extern fn empty<T>(): Array<T>
pub fn flatten<T>(ats: Array<Array<T>>): Array<T> {
let total_ts = ats.map { ts -> ts.length }
.reduce { acc, current -> acc + current }
let result: mut Array<T> = of_length(total_ts, std::reflect::default_or_empty<T>)
let i: mut Int = 0
for a in ats {
for element in a {
result[i] = element
i++
}
}
result
}
}

View File

@ -8,6 +8,6 @@ pub int Character : Display {
}
pub impl Utf8Character(bytes: Array<Byte>) {
impl fn get_encoding() = Encoding::Utf8
encoding = Encoding::Utf8
impl fn to_string() = string::from_utf8_bytes(bytes)
}

14
dm_lib/std/core/cls.dm Normal file
View File

@ -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
}

View File

@ -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)

View File

@ -14,9 +14,11 @@ pub int String : Display {
}
impl Utf8String(bytes: Array<Byte>) : 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<Character>')
encoding = Encoding::Utf8
length = bytes.length
characters = lazy {
todo('parse the utf8 bytes and return an Array<Character>')
}
}
pub mod string {

View File

@ -0,0 +1,6 @@
ns std::reflect
pub fn <T> default_or_empty() {
T is Default ? T::default : T is Empty
? T::empty : throw IllegalArgumentException("Type ${T::fqn} extends neither Default nor Empty.")
}