generic types, any -> opaque
This commit is contained in:
@@ -5,26 +5,24 @@ struct Array
|
||||
size: i64
|
||||
capacity: i64
|
||||
|
||||
func Array.new_preallocated_and_zeroed[size: i64] : Array
|
||||
xs := new* Array
|
||||
func Array.preallocate_and_zero[xs: Array<$>, size: i64] : void
|
||||
if size > 0
|
||||
xs->data = mem.alloc(size * 8)
|
||||
mem.zero(xs->data, size * 8)
|
||||
xs->size = size
|
||||
xs->capacity = size
|
||||
return xs
|
||||
|
||||
func Array.nth[xs: Array, n: i64] : any
|
||||
func Array.nth[xs: Array<$>, n: i64] : $
|
||||
if n < 0 || n >= xs->size
|
||||
panic("Array.nth out of bounds")
|
||||
return mem.read64(xs->data + n * 8)
|
||||
|
||||
func Array.set[xs: Array, n: i64, x: any] : void
|
||||
func Array.set[xs: Array<$>, n: i64, x: $] : void
|
||||
if n < 0 || n >= xs->size
|
||||
panic("Array.set out of bounds")
|
||||
mem.write64(xs->data + n * 8, x)
|
||||
|
||||
func Array.push[xs: Array, x: any] : void
|
||||
func Array.push[xs: Array<$>, x: $] : void
|
||||
if xs->size == xs->capacity
|
||||
new_capacity := 4
|
||||
if xs->capacity != 0
|
||||
@@ -35,54 +33,56 @@ func Array.push[xs: Array, x: any] : void
|
||||
mem.write64(xs->data + xs->size * 8, x)
|
||||
xs->size += 1
|
||||
|
||||
func Array.free[xs: Array] : void
|
||||
func Array.free[xs: Array<$>] : void
|
||||
if xs->data != 0
|
||||
xs->data->free()
|
||||
(xs as ptr)->free()
|
||||
|
||||
func Array.free_with_items[xs: Array] : void
|
||||
func Array.free_with_items[xs: Array<$>] : void
|
||||
if xs->data != 0
|
||||
for i in 0..xs->size
|
||||
(xs->nth(i) as ptr)->free()
|
||||
xs->data->free()
|
||||
(xs as ptr)->free()
|
||||
|
||||
func Array.pop[xs: Array] : any
|
||||
func Array.pop[xs: Array<$>] : $
|
||||
if xs->size == 0
|
||||
panic("Array.pop on empty array")
|
||||
x : any = Array.last(xs)
|
||||
x := Array.last(xs)
|
||||
xs->size = xs->size - 1
|
||||
return x
|
||||
|
||||
func Array.last[xs: Array] : any
|
||||
func Array.last[xs: Array<$>] : $
|
||||
if xs->size == 0
|
||||
panic("Array.last on empty array")
|
||||
return xs->nth(xs->size - 1)
|
||||
|
||||
func Array.slice[xs: Array, start: i64, length: i64] : Array
|
||||
func Array.slice[xs: Array<$>, start: i64, length: i64] : Array<$>
|
||||
if start < 0 || length < 0 || start + length > xs->size
|
||||
panic("Array.slice out of bounds")
|
||||
|
||||
new_array := Array.new_preallocated_and_zeroed(length)
|
||||
new_array := [] as Array<$>
|
||||
new_array->preallocate_and_zero(length)
|
||||
mem.copy(xs->data + start * 8, new_array->data, length * 8)
|
||||
return new_array
|
||||
|
||||
func Array.concat[a: Array, b: Array] : Array
|
||||
new_array := Array.new_preallocated_and_zeroed(a->size + b->size)
|
||||
func Array.concat[a: Array<$>, b: Array<$>] : Array<$>
|
||||
new_array := [] as Array<$>
|
||||
new_array->preallocate_and_zero(a->size + b->size)
|
||||
mem.copy(a->data, new_array->data, a->size * 8)
|
||||
mem.copy(b->data, new_array->data + a->size * 8, b->size * 8)
|
||||
return new_array
|
||||
|
||||
func Array.quicksort[arr: Array] : void
|
||||
func Array.quicksort[arr: Array<$>] : void
|
||||
arr->_do_quicksort(0, arr->size - 1)
|
||||
|
||||
func Array._do_quicksort[arr: Array, low: i64, high: i64] : void
|
||||
func Array._do_quicksort[arr: Array<$>, low: i64, high: i64] : void
|
||||
if low < high
|
||||
i := arr->_partition(low, high)
|
||||
arr->_do_quicksort(low, i - 1)
|
||||
arr->_do_quicksort(i + 1, high)
|
||||
|
||||
func Array._partition[arr: Array, low: i64, high: i64] : i64
|
||||
func Array._partition[arr: Array<$>, low: i64, high: i64] : i64
|
||||
pivot : i64 = arr->nth(high)
|
||||
i := low - 1
|
||||
for j in (low)..high
|
||||
@@ -96,41 +96,42 @@ func Array._partition[arr: Array, low: i64, high: i64] : i64
|
||||
arr->set(high, temp)
|
||||
return i + 1
|
||||
|
||||
func Array.contains_str[arr: Array, s: str] : bool
|
||||
func Array.contains_str[arr: Array<str>, s: str] : bool
|
||||
for i in 0..arr->size
|
||||
if (arr->nth(i) as str)->equal(s)
|
||||
return true
|
||||
return false
|
||||
|
||||
func Array.count[arr: Array, item: any] : i64
|
||||
func Array.count[arr: Array<$>, item: $] : i64
|
||||
count := 0
|
||||
for i in 0..arr->size
|
||||
if arr->nth(i) == item
|
||||
count += 1
|
||||
return count
|
||||
|
||||
func Array.map[arr: Array, fn: ptr] : Array
|
||||
out := Array.new_preallocated_and_zeroed(arr->size)
|
||||
func Array.map[arr: Array<$>, fn: ptr] : Array<$>
|
||||
out := [] as Array<$>
|
||||
out->preallocate_and_zero(arr->size)
|
||||
for i in 0..arr->size
|
||||
out->set(i, fn(arr->nth(i)))
|
||||
return out
|
||||
|
||||
func Array.filter[arr: Array, fn: ptr] : Array
|
||||
out := []
|
||||
func Array.filter[arr: Array<$>, fn: ptr] : Array<$>
|
||||
out := [] as Array<$>
|
||||
for i in 0..arr->size
|
||||
if fn(arr->nth(i))
|
||||
if fn(arr->nth(i)) as bool
|
||||
out->push(arr->nth(i))
|
||||
return out
|
||||
|
||||
func Array.reduce[arr: Array, fn: ptr, acc: any] : any
|
||||
func Array.reduce[arr: Array<$>, fn: ptr, acc: $] : $
|
||||
for i in 0..arr->size
|
||||
acc = fn(acc, arr->nth(i))
|
||||
return acc
|
||||
|
||||
func str.split[haystack: str, needle: str]: Array
|
||||
func str.split[haystack: str, needle: str]: Array<str>
|
||||
haystack_len := haystack->len()
|
||||
needle_len := needle->len()
|
||||
result := []
|
||||
result := [] as Array<str>
|
||||
|
||||
if !needle_len
|
||||
if !haystack_len
|
||||
@@ -162,19 +163,20 @@ func str.split[haystack: str, needle: str]: Array
|
||||
const HashMap._TABLE_SIZE = 100
|
||||
|
||||
struct HashMap
|
||||
table: Array
|
||||
table: Array<HashMap._Node>
|
||||
|
||||
struct HashMap._Node
|
||||
key: str
|
||||
value: any
|
||||
value: $
|
||||
next: HashMap._Node
|
||||
|
||||
func HashMap.new[] : HashMap
|
||||
map := new* HashMap
|
||||
map->table = Array.new_preallocated_and_zeroed(HashMap._TABLE_SIZE)
|
||||
map->table = [] as Array<HashMap._Node>
|
||||
map->table->preallocate_and_zero(HashMap._TABLE_SIZE)
|
||||
return map
|
||||
|
||||
func HashMap.insert[map: HashMap, key: str, value: any] : void
|
||||
func HashMap.insert[map: HashMap<$>, key: str, value: $] : void
|
||||
index := HashMap._djb2(key)
|
||||
current : HashMap._Node = map->table->nth(index)
|
||||
|
||||
@@ -190,7 +192,7 @@ func HashMap.insert[map: HashMap, key: str, value: any] : void
|
||||
new_node->next = map->table->nth(index)
|
||||
map->table->set(index, new_node)
|
||||
|
||||
func HashMap.get[map: HashMap, key: str] : any, bool
|
||||
func HashMap.get[map: HashMap<$>, key: str] : $, bool
|
||||
index := HashMap._djb2(key)
|
||||
current : HashMap._Node = map->table->nth(index)
|
||||
|
||||
@@ -199,9 +201,9 @@ func HashMap.get[map: HashMap, key: str] : any, bool
|
||||
return current->value, true
|
||||
current = current->next
|
||||
|
||||
return 0 as any, false
|
||||
return 0 as $, false
|
||||
|
||||
func HashMap.delete[map: HashMap, key: str] : void
|
||||
func HashMap.delete[map: HashMap<$>, key: str] : void
|
||||
index := HashMap._djb2(key)
|
||||
current : HashMap._Node = map->table->nth(index)
|
||||
prev := 0 as HashMap._Node
|
||||
@@ -220,8 +222,8 @@ func HashMap.delete[map: HashMap, key: str] : void
|
||||
prev = current
|
||||
current = current->next
|
||||
|
||||
func HashMap.keys[map: HashMap] : Array
|
||||
out := []
|
||||
func HashMap.keys[map: HashMap<$>] : Array<str>
|
||||
out := [] as Array<str>
|
||||
for i in 0..HashMap._TABLE_SIZE
|
||||
current : HashMap._Node = map->table->nth(i)
|
||||
while current as ptr
|
||||
@@ -229,7 +231,7 @@ func HashMap.keys[map: HashMap] : Array
|
||||
current = current->next
|
||||
return out
|
||||
|
||||
func HashMap.free_with_keys[map: HashMap] : void
|
||||
func HashMap.free_with_keys[map: HashMap<$>] : void
|
||||
for i in 0..HashMap._TABLE_SIZE
|
||||
current : HashMap._Node = map->table->nth(i)
|
||||
while current as ptr
|
||||
|
||||
42
std/json.zr
42
std/json.zr
@@ -9,33 +9,33 @@ const json.BOOL = 5
|
||||
|
||||
struct json.Value
|
||||
type: i64
|
||||
value: any
|
||||
value: opaque
|
||||
|
||||
func json.Value.dump[v: json.Value] : str
|
||||
s := new str.Builder
|
||||
|
||||
if v->type == json.OBJECT
|
||||
map := v->value as HashMap
|
||||
map := v->value as HashMap<json.Value>
|
||||
keys := map->keys()
|
||||
s->append_char('{')
|
||||
for i in 0..keys->size
|
||||
if i > 0
|
||||
s->append_char(',')
|
||||
s->append_char('"')
|
||||
s->append(keys->nth(i) as str)
|
||||
s->append(keys->nth(i))
|
||||
s->append_char('"')
|
||||
s->append_char(':')
|
||||
value, _ := map->get(keys->nth(i) as str)
|
||||
s->append((value as json.Value)->dump())
|
||||
value, _ := map->get(keys->nth(i))
|
||||
s->append(value->dump())
|
||||
s->append_char('}')
|
||||
keys->free()
|
||||
else if v->type == json.ARRAY
|
||||
arr := v->value as Array
|
||||
arr := v->value as Array<json.Value>
|
||||
s->append_char('[')
|
||||
for i in 0..arr->size
|
||||
if i > 0
|
||||
s->append_char(',')
|
||||
s->append((arr->nth(i) as json.Value)->dump())
|
||||
s->append(arr->nth(i)->dump())
|
||||
s->append_char(']')
|
||||
else if v->type == json.STRING
|
||||
// TODO: escape sequences
|
||||
@@ -58,25 +58,25 @@ func json.Value.dump[v: json.Value] : str
|
||||
|
||||
func json.Value.free[v: json.Value] : void
|
||||
if v->type == json.OBJECT
|
||||
map := v->value as HashMap
|
||||
map := v->value as HashMap<json.Value>
|
||||
keys := map->keys()
|
||||
for i in 0..keys->size
|
||||
value, _ := map->get(keys->nth(i) as str)
|
||||
(value as json.Value)->free()
|
||||
value, _ := map->get(keys->nth(i))
|
||||
value->free()
|
||||
keys->free()
|
||||
|
||||
map->free_with_keys()
|
||||
else if v->type == json.ARRAY
|
||||
arr := v->value as Array
|
||||
arr := v->value as Array<json.Value>
|
||||
for i in 0..arr->size
|
||||
(arr->nth(i) as json.Value)->free()
|
||||
arr->nth(i)->free()
|
||||
arr->free()
|
||||
else if v->type == json.STRING
|
||||
(v->value as str)->free()
|
||||
|
||||
(v as ptr)->free()
|
||||
|
||||
func json.val[x: any] : any
|
||||
func json.val[x: opaque] : opaque
|
||||
return (x as json.Value)->value
|
||||
|
||||
func json.parse[s: str] : json.Value
|
||||
@@ -96,7 +96,7 @@ func json._parse_value[s: str, i: ptr] : json.Value
|
||||
json._skip_whitespace(s, i)
|
||||
|
||||
out->type = json.OBJECT
|
||||
out->value = HashMap.new()
|
||||
out->value = HashMap.new() as opaque
|
||||
|
||||
if s[mem.read64(i)] != '}'
|
||||
while true
|
||||
@@ -110,7 +110,7 @@ func json._parse_value[s: str, i: ptr] : json.Value
|
||||
json._skip_whitespace(s, i)
|
||||
|
||||
value := json._parse_value(s, i)
|
||||
(out->value as HashMap)->insert(key, value)
|
||||
(out->value as HashMap<json.Value>)->insert(key, value)
|
||||
key->free()
|
||||
|
||||
json._skip_whitespace(s, i)
|
||||
@@ -128,12 +128,12 @@ func json._parse_value[s: str, i: ptr] : json.Value
|
||||
json._skip_whitespace(s, i)
|
||||
|
||||
out->type = json.ARRAY
|
||||
out->value = []
|
||||
out->value = [] as opaque
|
||||
|
||||
while s[mem.read64(i)] != ']'
|
||||
json._skip_whitespace(s, i)
|
||||
|
||||
(out->value as Array)->push(json._parse_value(s, i))
|
||||
(out->value as Array<json.Value>)->push(json._parse_value(s, i))
|
||||
json._skip_whitespace(s, i)
|
||||
|
||||
if s[mem.read64(i)] == ','
|
||||
@@ -147,7 +147,7 @@ func json._parse_value[s: str, i: ptr] : json.Value
|
||||
mem.write64(i, mem.read64(i) + 1)
|
||||
else if s[mem.read64(i)] == '"'
|
||||
out->type = json.STRING
|
||||
out->value = json._parse_string(s, i)
|
||||
out->value = json._parse_string(s, i) as opaque
|
||||
else if s[mem.read64(i)]->is_digit() || s[mem.read64(i)] == '-'
|
||||
start := mem.read64(i)
|
||||
|
||||
@@ -164,18 +164,18 @@ func json._parse_value[s: str, i: ptr] : json.Value
|
||||
|
||||
num_str := s->substr_n(start, len)
|
||||
out->type = json.NUMBER
|
||||
out->value = num_str->parse_i64()
|
||||
out->value = num_str->parse_i64() as opaque
|
||||
num_str->free()
|
||||
else if s[mem.read64(i)] == 'n' && s[mem.read64(i)+1] == 'u' && s[mem.read64(i)+2] == 'l' && s[mem.read64(i)+3] == 'l'
|
||||
out->type = json.NULL
|
||||
mem.write64(i, mem.read64(i) + 4)
|
||||
else if s[mem.read64(i)] == 't' && s[mem.read64(i)+1] == 'r' && s[mem.read64(i)+2] == 'u' && s[mem.read64(i)+3] == 'e'
|
||||
out->type = json.BOOL
|
||||
out->value = true
|
||||
out->value = true as opaque
|
||||
mem.write64(i, mem.read64(i) + 4)
|
||||
else if s[mem.read64(i)] == 'f' && s[mem.read64(i)+1] == 'a' && s[mem.read64(i)+2] == 'l' && s[mem.read64(i)+3] == 's' && s[mem.read64(i)+4] == 'e'
|
||||
out->type = json.BOOL
|
||||
out->value = false
|
||||
out->value = false as opaque
|
||||
mem.write64(i, mem.read64(i) + 5)
|
||||
else
|
||||
panic("json.parse: unexpected character")
|
||||
|
||||
18
std/mem.zr
18
std/mem.zr
@@ -23,7 +23,7 @@ func mem.Block._split[blk: mem.Block, needed: i64] : void
|
||||
if blk->next as ptr
|
||||
blk->next->prev = new_blk
|
||||
else
|
||||
mem.write64(_builtin_heap_tail(), new_blk)
|
||||
mem.write64(_builtin_heap_tail(), new_blk as ptr as i64)
|
||||
|
||||
blk->size = needed
|
||||
blk->next = new_blk
|
||||
@@ -46,7 +46,7 @@ func mem._request_space[size: i64] : mem.Block
|
||||
tail->next = blk
|
||||
blk->prev = tail
|
||||
|
||||
mem.write64(_builtin_heap_tail(), blk)
|
||||
mem.write64(_builtin_heap_tail(), blk as ptr as i64)
|
||||
return blk
|
||||
|
||||
func mem.alloc[size: i64] : ptr
|
||||
@@ -66,7 +66,7 @@ func mem.alloc[size: i64] : ptr
|
||||
blk := mem._request_space(size)
|
||||
|
||||
if !mem.read64(_builtin_heap_head())
|
||||
mem.write64(_builtin_heap_head(), blk)
|
||||
mem.write64(_builtin_heap_head(), blk as ptr as i64)
|
||||
|
||||
blk->_split(size)
|
||||
|
||||
@@ -91,7 +91,7 @@ func ptr.free[x: ptr] : void
|
||||
if next->next as ptr
|
||||
next->next->prev = blk
|
||||
if mem.read64(_builtin_heap_tail()) == next as ptr
|
||||
mem.write64(_builtin_heap_tail(), blk)
|
||||
mem.write64(_builtin_heap_tail(), blk as ptr as i64)
|
||||
|
||||
prev := blk->prev
|
||||
if prev as ptr && prev->free
|
||||
@@ -102,7 +102,7 @@ func ptr.free[x: ptr] : void
|
||||
if blk->next as ptr
|
||||
blk->next->prev = prev
|
||||
if mem.read64(_builtin_heap_tail()) == blk as ptr
|
||||
mem.write64(_builtin_heap_tail(), prev)
|
||||
mem.write64(_builtin_heap_tail(), prev as ptr as i64)
|
||||
blk = prev
|
||||
|
||||
block_total := blk->size + MEM_BLOCK_SIZE
|
||||
@@ -110,11 +110,11 @@ func ptr.free[x: ptr] : void
|
||||
if blk->prev as ptr
|
||||
blk->prev->next = blk->next
|
||||
else
|
||||
mem.write64(_builtin_heap_head(), blk->next)
|
||||
mem.write64(_builtin_heap_head(), blk->next as ptr as i64)
|
||||
if blk->next as ptr
|
||||
blk->next->prev = blk->prev
|
||||
else
|
||||
mem.write64(_builtin_heap_tail(), blk->prev)
|
||||
mem.write64(_builtin_heap_tail(), blk->prev as ptr as i64)
|
||||
_builtin_syscall(SYS_munmap, blk, block_total)
|
||||
|
||||
func ptr.realloc[x: ptr, new_size: i64] : ptr
|
||||
@@ -146,7 +146,7 @@ func ptr.realloc[x: ptr, new_size: i64] : ptr
|
||||
if next->next as ptr
|
||||
next->next->prev = blk
|
||||
if mem.read64(_builtin_heap_tail()) == next as ptr
|
||||
mem.write64(_builtin_heap_tail(), blk)
|
||||
mem.write64(_builtin_heap_tail(), blk as ptr as i64)
|
||||
blk->_split(new_size)
|
||||
return x
|
||||
|
||||
@@ -219,7 +219,7 @@ func mem.write16be[x: ptr, d: i64] : void
|
||||
x[0] = (d >> 8) & 0xff
|
||||
x[1] = d & 0xff
|
||||
|
||||
func mem.write64[x: ptr, d: any] : void
|
||||
func mem.write64[x: ptr, d: i64] : void
|
||||
_builtin_set64(x, d)
|
||||
|
||||
struct Blob
|
||||
|
||||
10
std/net.zr
10
std/net.zr
@@ -149,7 +149,7 @@ func net.resolve[domain: str] : i64, bool
|
||||
if parts->size == 4
|
||||
valid := true
|
||||
for i in 0..4
|
||||
p := parts->nth(i) as str
|
||||
p := parts->nth(i)
|
||||
if p->len() < 1 || p->len() > 3
|
||||
valid = false
|
||||
break
|
||||
@@ -160,10 +160,10 @@ func net.resolve[domain: str] : i64, bool
|
||||
if !valid
|
||||
break
|
||||
if valid
|
||||
a := (parts->nth(0) as str)->parse_i64()
|
||||
b := (parts->nth(1) as str)->parse_i64()
|
||||
c := (parts->nth(2) as str)->parse_i64()
|
||||
d := (parts->nth(3) as str)->parse_i64()
|
||||
a := parts->nth(0)->parse_i64()
|
||||
b := parts->nth(1)->parse_i64()
|
||||
c := parts->nth(2)->parse_i64()
|
||||
d := parts->nth(3)->parse_i64()
|
||||
if a >= 0 && a <= 255 && b >= 0 && b <= 255 && c >= 0 && c <= 255 && d >= 0 && d <= 255
|
||||
parts->free_with_items()
|
||||
return net.pack_addr(a, b, c, d), true
|
||||
|
||||
@@ -117,19 +117,19 @@ func os.is_a_directory[path: str] : bool
|
||||
|
||||
return (mem.read32(st + 24) & S_IFMT) == S_IFDIR
|
||||
|
||||
func os.list_directory[path: str] : Array, bool
|
||||
func os.list_directory[path: str] : Array<str>, bool
|
||||
fd := _builtin_syscall(SYS_openat, AT_FDCWD, path, O_RDONLY, 0)
|
||||
if fd < 0
|
||||
return 0 as Array, false
|
||||
return 0 as Array<str>, false
|
||||
|
||||
files := []
|
||||
files := [] as Array<str>
|
||||
buf := _stackalloc(1024)
|
||||
while true
|
||||
n := _builtin_syscall(SYS_getdents64, fd, buf, 1024)
|
||||
if n < 0
|
||||
files->free_with_items()
|
||||
_builtin_syscall(SYS_close, fd)
|
||||
return 0 as Array, false
|
||||
return 0 as Array<str>, false
|
||||
else if n == 0
|
||||
break
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ func str.format_into[..] : i64
|
||||
i += 1
|
||||
else if s[0] == 'f'
|
||||
// TODO: use arrow when we implement f64 params
|
||||
f64.to_str_buf(_var_arg(i), tmp as ptr)
|
||||
f64.to_str_buf(_var_arg(i) as i64, tmp as ptr)
|
||||
tmp_len := tmp->len()
|
||||
remaining := size - n - 1
|
||||
mem.copy(tmp as ptr, buf + n, math.min(tmp_len, remaining))
|
||||
|
||||
Reference in New Issue
Block a user