mt-lang 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/docs/index.html +4 -3
- data/lib/milk_tea/base.rb +1 -1
- data/std/asset_pack.mt +267 -0
- data/std/async/libuv_runtime.mt +539 -0
- data/std/async/mailbox.mt +191 -0
- data/std/async/runtime.mt +87 -0
- data/std/async.mt +87 -0
- data/std/base64.mt +185 -0
- data/std/behavior_tree.mt +396 -0
- data/std/binary.mt +314 -0
- data/std/binary_heap.mt +157 -0
- data/std/bitset.mt +239 -0
- data/std/box2d.mt +535 -0
- data/std/bytes.mt +46 -0
- data/std/c/box2d.mt +1254 -0
- data/std/c/cgltf.mt +647 -0
- data/std/c/cjson.mt +106 -0
- data/std/c/crypto.mt +11 -0
- data/std/c/crypto_support.h +51 -0
- data/std/c/ctype.mt +19 -0
- data/std/c/ctype_bindgen.h +29 -0
- data/std/c/curl.mt +1223 -0
- data/std/c/enet.mt +473 -0
- data/std/c/errno.mt +41 -0
- data/std/c/errno_bindgen.h +53 -0
- data/std/c/flecs.mt +2945 -0
- data/std/c/fs.linux.mt +43 -0
- data/std/c/fs.windows.mt +43 -0
- data/std/c/fs_support.h +954 -0
- data/std/c/gl.mt +2065 -0
- data/std/c/gl_registry_helpers.h +10748 -0
- data/std/c/glfw.mt +499 -0
- data/std/c/libc.mt +167 -0
- data/std/c/libuv.mt +1491 -0
- data/std/c/math.mt +22 -0
- data/std/c/math_bindgen.h +31 -0
- data/std/c/miniaudio.mt +3420 -0
- data/std/c/pcre2.mt +735 -0
- data/std/c/process.mt +58 -0
- data/std/c/process_support.h +1147 -0
- data/std/c/raygui.mt +1602 -0
- data/std/c/raylib.mt +1245 -0
- data/std/c/raymath.mt +163 -0
- data/std/c/rlgl.mt +434 -0
- data/std/c/rpng.mt +60 -0
- data/std/c/rres.mt +187 -0
- data/std/c/sdl3.mt +4132 -0
- data/std/c/sqlite3.mt +951 -0
- data/std/c/stb_image.mt +52 -0
- data/std/c/stb_image_resize2.mt +128 -0
- data/std/c/stb_image_write.mt +19 -0
- data/std/c/stb_rect_pack.mt +38 -0
- data/std/c/stb_truetype.mt +175 -0
- data/std/c/stb_vorbis.mt +31 -0
- data/std/c/stdio.mt +90 -0
- data/std/c/steamworks.h +5769 -0
- data/std/c/steamworks.mt +4771 -0
- data/std/c/string.mt +16 -0
- data/std/c/string_bindgen.h +36 -0
- data/std/c/sync.mt +33 -0
- data/std/c/sync_support.h +219 -0
- data/std/c/terminal.mt +24 -0
- data/std/c/terminal_support.h +408 -0
- data/std/c/time.mt +26 -0
- data/std/c/tls.mt +24 -0
- data/std/c/tls_support.h +626 -0
- data/std/c/tracy.mt +53 -0
- data/std/c/zlib.mt +20 -0
- data/std/c/zlib_support.h +239 -0
- data/std/c/zstd.mt +231 -0
- data/std/cell.mt +60 -0
- data/std/cgltf.mt +115 -0
- data/std/cjson.mt +90 -0
- data/std/cli.mt +768 -0
- data/std/cookie.mt +198 -0
- data/std/counter.mt +160 -0
- data/std/crypto.mt +74 -0
- data/std/cstring.mt +13 -0
- data/std/ctype.mt +52 -0
- data/std/curl/runtime.mt +261 -0
- data/std/curl.mt +38 -0
- data/std/deque.mt +348 -0
- data/std/encoding.mt +93 -0
- data/std/enet.mt +133 -0
- data/std/env.mt +41 -0
- data/std/errno.mt +47 -0
- data/std/flecs.mt +978 -0
- data/std/fmt.mt +271 -0
- data/std/fs.linux.mt +696 -0
- data/std/fs.windows.mt +711 -0
- data/std/fsm.mt +267 -0
- data/std/gl.mt +2062 -0
- data/std/glfw.mt +471 -0
- data/std/goap.mt +342 -0
- data/std/graph.mt +521 -0
- data/std/gzip.mt +77 -0
- data/std/hash.mt +429 -0
- data/std/http/server.mt +810 -0
- data/std/http.mt +1227 -0
- data/std/intern.mt +53 -0
- data/std/jobs.mt +288 -0
- data/std/json.mt +627 -0
- data/std/libc.mt +34 -0
- data/std/libuv.mt +554 -0
- data/std/linear_algebra.mt +243 -0
- data/std/linked_map.mt +372 -0
- data/std/linked_map_view.mt +49 -0
- data/std/linked_set.mt +117 -0
- data/std/log.mt +69 -0
- data/std/map.mt +418 -0
- data/std/math.mt +24 -0
- data/std/mem/arena.mt +137 -0
- data/std/mem/endian.mt +51 -0
- data/std/mem/heap.mt +298 -0
- data/std/mem/pool.mt +164 -0
- data/std/mem/stack.mt +47 -0
- data/std/mem/tracking.mt +119 -0
- data/std/miniaudio.mt +1299 -0
- data/std/multiset.mt +191 -0
- data/std/net/channel.mt +727 -0
- data/std/net/clock.mt +237 -0
- data/std/net/discovery.mt +277 -0
- data/std/net/lobby.mt +813 -0
- data/std/net/manager.mt +539 -0
- data/std/net/mux.mt +839 -0
- data/std/net/nat.mt +122 -0
- data/std/net/packet.mt +219 -0
- data/std/net/punch.mt +162 -0
- data/std/net/rpc.mt +119 -0
- data/std/net/session.mt +1157 -0
- data/std/net/stun.mt +252 -0
- data/std/net/sync.mt +183 -0
- data/std/net/turn.mt +459 -0
- data/std/net.mt +2944 -0
- data/std/oauth2.mt +408 -0
- data/std/option.mt +51 -0
- data/std/ordered_map.mt +497 -0
- data/std/ordered_set.mt +348 -0
- data/std/path.mt +368 -0
- data/std/pcre2/runtime.mt +35 -0
- data/std/pcre2.mt +78 -0
- data/std/priority_queue.mt +55 -0
- data/std/process.mt +837 -0
- data/std/queue.mt +55 -0
- data/std/random.mt +146 -0
- data/std/raygui.mt +99 -0
- data/std/raylib/debug_console.mt +71 -0
- data/std/raylib/easing.mt +388 -0
- data/std/raylib/packed_assets.mt +255 -0
- data/std/raylib/runtime.mt +30 -0
- data/std/raylib/tracy_gpu.mt +37 -0
- data/std/raylib.mt +1510 -0
- data/std/raymath.mt +153 -0
- data/std/result.mt +89 -0
- data/std/rlgl.mt +268 -0
- data/std/rpng.mt +46 -0
- data/std/rres.mt +36 -0
- data/std/sdl3/runtime.mt +54 -0
- data/std/sdl3.mt +1731 -0
- data/std/serialize.mt +68 -0
- data/std/set.mt +124 -0
- data/std/spatial.mt +176 -0
- data/std/sqlite3.mt +151 -0
- data/std/stack.mt +55 -0
- data/std/stb_image.mt +47 -0
- data/std/stb_image_resize2.mt +41 -0
- data/std/stb_image_write.mt +17 -0
- data/std/stb_rect_pack.mt +15 -0
- data/std/stb_truetype.mt +77 -0
- data/std/stb_vorbis.mt +16 -0
- data/std/stdio.mt +88 -0
- data/std/steamworks.mt +1542 -0
- data/std/str.mt +293 -0
- data/std/string.mt +234 -0
- data/std/sync.mt +194 -0
- data/std/tar.mt +704 -0
- data/std/terminal.mt +1002 -0
- data/std/testing.mt +266 -0
- data/std/thread.mt +120 -0
- data/std/time.mt +105 -0
- data/std/tls.mt +616 -0
- data/std/toml.mt +1310 -0
- data/std/tracy.mt +42 -0
- data/std/uri.mt +118 -0
- data/std/url.mt +372 -0
- data/std/vec.mt +433 -0
- data/std/zstd.mt +94 -0
- metadata +187 -2
data/std/linked_set.mt
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import std.linked_map as linked_map
|
|
2
|
+
|
|
3
|
+
public struct LinkedSet[T]:
|
|
4
|
+
values: linked_map.LinkedMap[T, bool]
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
extending LinkedSet[T]:
|
|
8
|
+
public static function create() -> LinkedSet[T]:
|
|
9
|
+
return LinkedSet[T](values = linked_map.LinkedMap[T, bool].create())
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
public static function with_capacity(capacity: ptr_uint) -> LinkedSet[T]:
|
|
13
|
+
var result = LinkedSet[T].create()
|
|
14
|
+
result.reserve(capacity)
|
|
15
|
+
return result
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
public function len() -> ptr_uint:
|
|
19
|
+
return this.values.len()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
public function capacity() -> ptr_uint:
|
|
23
|
+
return this.values.capacity()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
public function is_empty() -> bool:
|
|
27
|
+
return this.values.is_empty()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
public function get(value: T) -> const_ptr[T]?:
|
|
31
|
+
return this.values.get_key(value)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
public function at(value: T) -> Option[T]:
|
|
35
|
+
let p = this.get(value) else:
|
|
36
|
+
return Option[T].none
|
|
37
|
+
|
|
38
|
+
unsafe:
|
|
39
|
+
return Option[T].some(value = read(ptr[T]<-p))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
public function contains(value: T) -> bool:
|
|
43
|
+
return this.values.contains(value)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
public function iter() -> linked_map.Keys[T, bool]:
|
|
47
|
+
return this.values.keys()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
public function is_subset(other: LinkedSet[T]) -> bool:
|
|
51
|
+
if this.len() > other.len():
|
|
52
|
+
return false
|
|
53
|
+
|
|
54
|
+
for value in this:
|
|
55
|
+
unsafe:
|
|
56
|
+
if not other.contains(read(ptr[T]<-value)):
|
|
57
|
+
return false
|
|
58
|
+
|
|
59
|
+
return true
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
public function union_with(other: LinkedSet[T]) -> LinkedSet[T]:
|
|
63
|
+
var result = LinkedSet[T].with_capacity(this.len() + other.len())
|
|
64
|
+
|
|
65
|
+
for value in this:
|
|
66
|
+
unsafe:
|
|
67
|
+
result.insert(read(ptr[T]<-value))
|
|
68
|
+
|
|
69
|
+
for value in other:
|
|
70
|
+
unsafe:
|
|
71
|
+
result.insert(read(ptr[T]<-value))
|
|
72
|
+
|
|
73
|
+
return result
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
public function intersection(other: LinkedSet[T]) -> LinkedSet[T]:
|
|
77
|
+
var result = LinkedSet[T].with_capacity(this.len())
|
|
78
|
+
|
|
79
|
+
for value in this:
|
|
80
|
+
unsafe:
|
|
81
|
+
let current = read(ptr[T]<-value)
|
|
82
|
+
if other.contains(current):
|
|
83
|
+
result.insert(current)
|
|
84
|
+
|
|
85
|
+
return result
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
public function difference(other: LinkedSet[T]) -> LinkedSet[T]:
|
|
89
|
+
var result = LinkedSet[T].with_capacity(this.len())
|
|
90
|
+
|
|
91
|
+
for value in this:
|
|
92
|
+
unsafe:
|
|
93
|
+
let current = read(ptr[T]<-value)
|
|
94
|
+
if not other.contains(current):
|
|
95
|
+
result.insert(current)
|
|
96
|
+
|
|
97
|
+
return result
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
public editable function clear() -> void:
|
|
101
|
+
this.values.clear()
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
public editable function release() -> void:
|
|
105
|
+
this.values.release()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
public editable function reserve(min_capacity: ptr_uint) -> void:
|
|
109
|
+
this.values.reserve(min_capacity)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
public editable function insert(value: T) -> bool:
|
|
113
|
+
return this.values.set(value, true).is_none()
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
public editable function remove(value: T) -> bool:
|
|
117
|
+
return this.values.remove(value).is_some()
|
data/std/log.mt
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import std.string as string
|
|
2
|
+
import std.terminal as terminal
|
|
3
|
+
|
|
4
|
+
public enum Level: int
|
|
5
|
+
trace = 0
|
|
6
|
+
debug = 1
|
|
7
|
+
info = 2
|
|
8
|
+
warn = 3
|
|
9
|
+
error = 4
|
|
10
|
+
fatal = 5
|
|
11
|
+
|
|
12
|
+
var global_level: Level = Level.trace
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
public function set_level(level: Level) -> void:
|
|
16
|
+
global_level = level
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
public function level() -> Level:
|
|
20
|
+
return global_level
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
function level_label(level: Level) -> str:
|
|
24
|
+
return match level:
|
|
25
|
+
Level.trace: "TRACE"
|
|
26
|
+
Level.debug: "DEBUG"
|
|
27
|
+
Level.info: "INFO "
|
|
28
|
+
Level.warn: "WARN "
|
|
29
|
+
Level.error: "ERROR"
|
|
30
|
+
Level.fatal: "FATAL"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
public function log(level: Level, message: str) -> void:
|
|
34
|
+
if int<-level < int<-global_level:
|
|
35
|
+
return
|
|
36
|
+
var output = string.String.create()
|
|
37
|
+
defer output.release()
|
|
38
|
+
output.append("[")
|
|
39
|
+
output.append(level_label(level))
|
|
40
|
+
output.append("] ")
|
|
41
|
+
output.append(message)
|
|
42
|
+
output.push_byte(10)
|
|
43
|
+
let _ = terminal.write_stderr(output.as_str())
|
|
44
|
+
terminal.flush_stderr()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
public function trace(message: str) -> void:
|
|
48
|
+
log(Level.trace, message)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
public function debug(message: str) -> void:
|
|
52
|
+
log(Level.debug, message)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
public function info(message: str) -> void:
|
|
56
|
+
log(Level.info, message)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
public function warn(message: str) -> void:
|
|
60
|
+
log(Level.warn, message)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
public function error(message: str) -> void:
|
|
64
|
+
log(Level.error, message)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
public function fatal_message(message: str) -> void:
|
|
68
|
+
log(Level.fatal, message)
|
|
69
|
+
fatal(c"fatal log")
|
data/std/map.mt
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
import std.hash
|
|
2
|
+
import std.mem.heap as heap
|
|
3
|
+
|
|
4
|
+
struct Node[K, V]:
|
|
5
|
+
hash: uint
|
|
6
|
+
key: K
|
|
7
|
+
value: V
|
|
8
|
+
next: ptr[Node[K, V]]?
|
|
9
|
+
|
|
10
|
+
public struct Entry[K, V]:
|
|
11
|
+
key: const_ptr[K]
|
|
12
|
+
value: ptr[V]
|
|
13
|
+
|
|
14
|
+
public struct RemovedEntry[K, V]:
|
|
15
|
+
key: K
|
|
16
|
+
value: V
|
|
17
|
+
|
|
18
|
+
public struct Keys[K, V]:
|
|
19
|
+
buckets: ptr[ptr[Node[K, V]]?]?
|
|
20
|
+
bucket_index: ptr_uint
|
|
21
|
+
bucket_count: ptr_uint
|
|
22
|
+
node: ptr[Node[K, V]]?
|
|
23
|
+
|
|
24
|
+
public struct Values[K, V]:
|
|
25
|
+
buckets: ptr[ptr[Node[K, V]]?]?
|
|
26
|
+
bucket_index: ptr_uint
|
|
27
|
+
bucket_count: ptr_uint
|
|
28
|
+
node: ptr[Node[K, V]]?
|
|
29
|
+
|
|
30
|
+
public struct Entries[K, V]:
|
|
31
|
+
buckets: ptr[ptr[Node[K, V]]?]?
|
|
32
|
+
bucket_index: ptr_uint
|
|
33
|
+
bucket_count: ptr_uint
|
|
34
|
+
node: ptr[Node[K, V]]?
|
|
35
|
+
|
|
36
|
+
public struct Map[K, V]:
|
|
37
|
+
buckets: own[ptr[Node[K, V]]?]?
|
|
38
|
+
len: ptr_uint
|
|
39
|
+
capacity: ptr_uint
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
extending Map[K, V]:
|
|
43
|
+
public static function create() -> Map[K, V]:
|
|
44
|
+
return Map[K, V](buckets = null, len = 0, capacity = 0)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
public static function with_capacity(capacity: ptr_uint) -> Map[K, V]:
|
|
48
|
+
var result = Map[K, V].create()
|
|
49
|
+
result.reserve(capacity)
|
|
50
|
+
return result
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
static function bucket_index(entry_hash: uint, capacity: ptr_uint) -> ptr_uint:
|
|
54
|
+
let bucket_count = uint<-capacity
|
|
55
|
+
return ptr_uint<-(entry_hash % bucket_count)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
static function find_node(current: Map[K, V], key: K, key_hash: uint) -> ptr[Node[K, V]]?:
|
|
59
|
+
if current.len == 0:
|
|
60
|
+
return null
|
|
61
|
+
|
|
62
|
+
let buckets = current.buckets else:
|
|
63
|
+
fatal(c"map.Map.find_node missing buckets")
|
|
64
|
+
|
|
65
|
+
unsafe:
|
|
66
|
+
let bucket_ptr = ptr[ptr[Node[K, V]]?]<-buckets
|
|
67
|
+
let index = Map[K, V].bucket_index(key_hash, current.capacity)
|
|
68
|
+
var node = read(bucket_ptr + index)
|
|
69
|
+
while node != null:
|
|
70
|
+
let node_ptr = ptr[Node[K, V]]<-node
|
|
71
|
+
let stored_key = const_ptr_of(read(node_ptr).key)
|
|
72
|
+
if read(node_ptr).hash == key_hash and equal[K](key, stored_key):
|
|
73
|
+
return node
|
|
74
|
+
node = read(node_ptr).next
|
|
75
|
+
|
|
76
|
+
return null
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
public function len() -> ptr_uint:
|
|
80
|
+
return this.len
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
public function capacity() -> ptr_uint:
|
|
84
|
+
return this.capacity
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
public function is_empty() -> bool:
|
|
88
|
+
return this.len == 0
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
public function get(key: K) -> ptr[V]?:
|
|
92
|
+
let key_hash = hash[K](key)
|
|
93
|
+
let node = Map[K, V].find_node(this, key, key_hash) else:
|
|
94
|
+
return null
|
|
95
|
+
|
|
96
|
+
unsafe:
|
|
97
|
+
return ptr_of(read(ptr[Node[K, V]]<-node).value)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
public function at(key: K) -> Option[V]:
|
|
101
|
+
let p = this.get(key) else:
|
|
102
|
+
return Option[V].none
|
|
103
|
+
|
|
104
|
+
unsafe:
|
|
105
|
+
return Option[V].some(value = read(p))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
public function get_key(key: K) -> const_ptr[K]?:
|
|
109
|
+
let key_hash = hash[K](key)
|
|
110
|
+
let node = Map[K, V].find_node(this, key, key_hash) else:
|
|
111
|
+
return null
|
|
112
|
+
|
|
113
|
+
unsafe:
|
|
114
|
+
return const_ptr_of(read(ptr[Node[K, V]]<-node).key)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
public function get_or_else(key: K, default: V) -> V:
|
|
118
|
+
let value_ptr = this.get(key) else:
|
|
119
|
+
return default
|
|
120
|
+
|
|
121
|
+
unsafe:
|
|
122
|
+
return read(value_ptr)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
public function iter() -> Entries[K, V]:
|
|
126
|
+
return this.entries()
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
public function keys() -> Keys[K, V]:
|
|
130
|
+
return Keys[K, V](buckets = this.buckets, bucket_index = 0, bucket_count = this.capacity, node = null)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
public function values() -> Values[K, V]:
|
|
134
|
+
return Values[K, V](buckets = this.buckets, bucket_index = 0, bucket_count = this.capacity, node = null)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
public function entries() -> Entries[K, V]:
|
|
138
|
+
return Entries[K, V](buckets = this.buckets, bucket_index = 0, bucket_count = this.capacity, node = null)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
public function contains(key: K) -> bool:
|
|
142
|
+
return this.get(key) != null
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
public editable function clear() -> void:
|
|
146
|
+
if this.len == 0:
|
|
147
|
+
return
|
|
148
|
+
|
|
149
|
+
let buckets = this.buckets else:
|
|
150
|
+
fatal(c"map.Map.clear missing buckets")
|
|
151
|
+
|
|
152
|
+
unsafe:
|
|
153
|
+
let bucket_ptr = ptr[ptr[Node[K, V]]?]<-buckets
|
|
154
|
+
var index: ptr_uint = 0
|
|
155
|
+
while index < this.capacity:
|
|
156
|
+
var node = read(bucket_ptr + index)
|
|
157
|
+
while node != null:
|
|
158
|
+
let node_ptr = ptr[Node[K, V]]<-node
|
|
159
|
+
let next = read(node_ptr).next
|
|
160
|
+
heap.release(node)
|
|
161
|
+
node = next
|
|
162
|
+
read(bucket_ptr + index) = null
|
|
163
|
+
index += 1
|
|
164
|
+
|
|
165
|
+
this.len = 0
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
public editable function release() -> void:
|
|
169
|
+
this.clear()
|
|
170
|
+
heap.release(this.buckets)
|
|
171
|
+
this.buckets = null
|
|
172
|
+
this.capacity = 0
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
public editable function reserve(min_capacity: ptr_uint) -> void:
|
|
176
|
+
if min_capacity <= this.capacity:
|
|
177
|
+
return
|
|
178
|
+
|
|
179
|
+
var new_capacity = this.capacity
|
|
180
|
+
if new_capacity == 0:
|
|
181
|
+
new_capacity = 8
|
|
182
|
+
|
|
183
|
+
while new_capacity < min_capacity:
|
|
184
|
+
if new_capacity > heap.ptr_uint_max / 2:
|
|
185
|
+
new_capacity = min_capacity
|
|
186
|
+
else:
|
|
187
|
+
new_capacity *= 2
|
|
188
|
+
|
|
189
|
+
let new_buckets = heap.must_alloc_zeroed[ptr[Node[K, V]]?](new_capacity)
|
|
190
|
+
let old_buckets = this.buckets
|
|
191
|
+
let old_capacity = this.capacity
|
|
192
|
+
|
|
193
|
+
if old_buckets != null:
|
|
194
|
+
unsafe:
|
|
195
|
+
let old_ptr = ptr[ptr[Node[K, V]]?]<-old_buckets
|
|
196
|
+
let new_ptr = ptr[ptr[Node[K, V]]?]<-new_buckets
|
|
197
|
+
var index: ptr_uint = 0
|
|
198
|
+
while index < old_capacity:
|
|
199
|
+
var node = read(old_ptr + index)
|
|
200
|
+
while node != null:
|
|
201
|
+
let node_ptr = ptr[Node[K, V]]<-node
|
|
202
|
+
let next = read(node_ptr).next
|
|
203
|
+
let target = Map[K, V].bucket_index(read(node_ptr).hash, new_capacity)
|
|
204
|
+
read(node_ptr).next = read(new_ptr + target)
|
|
205
|
+
read(new_ptr + target) = node
|
|
206
|
+
node = next
|
|
207
|
+
index += 1
|
|
208
|
+
heap.release(old_buckets)
|
|
209
|
+
|
|
210
|
+
this.buckets = new_buckets
|
|
211
|
+
this.capacity = new_capacity
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
public editable function set(key: K, value: V) -> Option[V]:
|
|
215
|
+
let key_hash = hash[K](key)
|
|
216
|
+
let existing = Map[K, V].find_node(this, key, key_hash)
|
|
217
|
+
if existing != null:
|
|
218
|
+
unsafe:
|
|
219
|
+
let node_ptr = ptr[Node[K, V]]<-existing
|
|
220
|
+
let previous = read(node_ptr).value
|
|
221
|
+
read(node_ptr).value = value
|
|
222
|
+
return Option[V].some(value = previous)
|
|
223
|
+
|
|
224
|
+
if this.len == this.capacity:
|
|
225
|
+
this.reserve(this.len + 1)
|
|
226
|
+
|
|
227
|
+
let current_buckets = this.buckets else:
|
|
228
|
+
fatal(c"map.Map.set missing buckets")
|
|
229
|
+
|
|
230
|
+
unsafe:
|
|
231
|
+
let bucket_ptr = ptr[ptr[Node[K, V]]?]<-current_buckets
|
|
232
|
+
let index = Map[K, V].bucket_index(key_hash, this.capacity)
|
|
233
|
+
let node = heap.must_alloc[Node[K, V]](1)
|
|
234
|
+
let node_ptr = ptr[Node[K, V]]<-node
|
|
235
|
+
read(node_ptr) = Node[K, V](
|
|
236
|
+
hash = key_hash,
|
|
237
|
+
key = key,
|
|
238
|
+
value = value,
|
|
239
|
+
next = read(bucket_ptr + index)
|
|
240
|
+
)
|
|
241
|
+
read(bucket_ptr + index) = node
|
|
242
|
+
|
|
243
|
+
this.len += 1
|
|
244
|
+
return Option[V].none
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
public editable function get_or_insert(key: K, value: V) -> ptr[V]:
|
|
248
|
+
let key_hash = hash[K](key)
|
|
249
|
+
let existing = Map[K, V].find_node(this, key, key_hash)
|
|
250
|
+
if existing != null:
|
|
251
|
+
unsafe:
|
|
252
|
+
return ptr_of(read(ptr[Node[K, V]]<-existing).value)
|
|
253
|
+
|
|
254
|
+
let inserted = this.set(key, value)
|
|
255
|
+
match inserted:
|
|
256
|
+
Option.none:
|
|
257
|
+
let current = Map[K, V].find_node(this, key, key_hash) else:
|
|
258
|
+
fatal(c"map.Map.get_or_insert missing inserted value")
|
|
259
|
+
unsafe:
|
|
260
|
+
return ptr_of(read(ptr[Node[K, V]]<-current).value)
|
|
261
|
+
Option.some:
|
|
262
|
+
fatal(c"map.Map.get_or_insert replaced unexpectedly")
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
public editable function remove_entry(key: K) -> Option[RemovedEntry[K, V]]:
|
|
266
|
+
if this.len == 0:
|
|
267
|
+
return Option[RemovedEntry[K, V]].none
|
|
268
|
+
|
|
269
|
+
let buckets = this.buckets else:
|
|
270
|
+
fatal(c"map.Map.remove_entry missing buckets")
|
|
271
|
+
|
|
272
|
+
let key_hash = hash[K](key)
|
|
273
|
+
|
|
274
|
+
unsafe:
|
|
275
|
+
let bucket_ptr = ptr[ptr[Node[K, V]]?]<-buckets
|
|
276
|
+
let index = Map[K, V].bucket_index(key_hash, this.capacity)
|
|
277
|
+
var previous: ptr[Node[K, V]]? = null
|
|
278
|
+
var node = read(bucket_ptr + index)
|
|
279
|
+
while node != null:
|
|
280
|
+
let node_ptr = ptr[Node[K, V]]<-node
|
|
281
|
+
let stored_key = const_ptr_of(read(node_ptr).key)
|
|
282
|
+
if read(node_ptr).hash == key_hash and equal[K](key, stored_key):
|
|
283
|
+
let next = read(node_ptr).next
|
|
284
|
+
if previous == null:
|
|
285
|
+
read(bucket_ptr + index) = next
|
|
286
|
+
else:
|
|
287
|
+
read(ptr[Node[K, V]]<-previous).next = next
|
|
288
|
+
|
|
289
|
+
let removed = RemovedEntry[K, V](key = read(node_ptr).key, value = read(node_ptr).value)
|
|
290
|
+
heap.release(node)
|
|
291
|
+
this.len -= 1
|
|
292
|
+
return Option[RemovedEntry[K, V]].some(value = removed)
|
|
293
|
+
|
|
294
|
+
previous = node
|
|
295
|
+
node = read(node_ptr).next
|
|
296
|
+
|
|
297
|
+
return Option[RemovedEntry[K, V]].none
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
public editable function remove(key: K) -> Option[V]:
|
|
301
|
+
let removed = this.remove_entry(key)
|
|
302
|
+
if removed.is_none():
|
|
303
|
+
return Option[V].none
|
|
304
|
+
return Option[V].some(value = removed.unwrap().value)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
extending Keys[K, V]:
|
|
308
|
+
public function iter() -> Keys[K, V]:
|
|
309
|
+
return this
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
public editable function next() -> const_ptr[K]?:
|
|
313
|
+
let current_node = this.node
|
|
314
|
+
if current_node != null:
|
|
315
|
+
unsafe:
|
|
316
|
+
let next_node = read(ptr[Node[K, V]]<-current_node).next
|
|
317
|
+
if next_node != null:
|
|
318
|
+
this.node = next_node
|
|
319
|
+
return const_ptr_of(read(ptr[Node[K, V]]<-next_node).key)
|
|
320
|
+
|
|
321
|
+
let buckets = this.buckets else:
|
|
322
|
+
this.bucket_index = this.bucket_count
|
|
323
|
+
this.node = null
|
|
324
|
+
return null
|
|
325
|
+
|
|
326
|
+
unsafe:
|
|
327
|
+
let bucket_ptr = ptr[ptr[Node[K, V]]?]<-buckets
|
|
328
|
+
var index = this.bucket_index
|
|
329
|
+
while index < this.bucket_count:
|
|
330
|
+
let candidate = read(bucket_ptr + index)
|
|
331
|
+
index += 1
|
|
332
|
+
if candidate != null:
|
|
333
|
+
this.bucket_index = index
|
|
334
|
+
this.node = candidate
|
|
335
|
+
return const_ptr_of(read(ptr[Node[K, V]]<-candidate).key)
|
|
336
|
+
|
|
337
|
+
this.bucket_index = this.bucket_count
|
|
338
|
+
this.node = null
|
|
339
|
+
return null
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
extending Values[K, V]:
|
|
343
|
+
public function iter() -> Values[K, V]:
|
|
344
|
+
return this
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
public editable function next() -> ptr[V]?:
|
|
348
|
+
let current_node = this.node
|
|
349
|
+
if current_node != null:
|
|
350
|
+
unsafe:
|
|
351
|
+
let next_node = read(ptr[Node[K, V]]<-current_node).next
|
|
352
|
+
if next_node != null:
|
|
353
|
+
this.node = next_node
|
|
354
|
+
return ptr_of(read(ptr[Node[K, V]]<-next_node).value)
|
|
355
|
+
|
|
356
|
+
let buckets = this.buckets else:
|
|
357
|
+
this.bucket_index = this.bucket_count
|
|
358
|
+
this.node = null
|
|
359
|
+
return null
|
|
360
|
+
|
|
361
|
+
unsafe:
|
|
362
|
+
let bucket_ptr = ptr[ptr[Node[K, V]]?]<-buckets
|
|
363
|
+
var index = this.bucket_index
|
|
364
|
+
while index < this.bucket_count:
|
|
365
|
+
let candidate = read(bucket_ptr + index)
|
|
366
|
+
index += 1
|
|
367
|
+
if candidate != null:
|
|
368
|
+
this.bucket_index = index
|
|
369
|
+
this.node = candidate
|
|
370
|
+
return ptr_of(read(ptr[Node[K, V]]<-candidate).value)
|
|
371
|
+
|
|
372
|
+
this.bucket_index = this.bucket_count
|
|
373
|
+
this.node = null
|
|
374
|
+
return null
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
extending Entries[K, V]:
|
|
378
|
+
public function iter() -> Entries[K, V]:
|
|
379
|
+
return this
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
public editable function next() -> bool:
|
|
383
|
+
let current_node = this.node
|
|
384
|
+
if current_node != null:
|
|
385
|
+
unsafe:
|
|
386
|
+
let next_node = read(ptr[Node[K, V]]<-current_node).next
|
|
387
|
+
if next_node != null:
|
|
388
|
+
this.node = next_node
|
|
389
|
+
return true
|
|
390
|
+
|
|
391
|
+
let buckets = this.buckets else:
|
|
392
|
+
this.bucket_index = this.bucket_count
|
|
393
|
+
this.node = null
|
|
394
|
+
return false
|
|
395
|
+
|
|
396
|
+
unsafe:
|
|
397
|
+
let bucket_ptr = ptr[ptr[Node[K, V]]?]<-buckets
|
|
398
|
+
var index = this.bucket_index
|
|
399
|
+
while index < this.bucket_count:
|
|
400
|
+
let candidate = read(bucket_ptr + index)
|
|
401
|
+
index += 1
|
|
402
|
+
if candidate != null:
|
|
403
|
+
this.bucket_index = index
|
|
404
|
+
this.node = candidate
|
|
405
|
+
return true
|
|
406
|
+
|
|
407
|
+
this.bucket_index = this.bucket_count
|
|
408
|
+
this.node = null
|
|
409
|
+
return false
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
public function current() -> Entry[K, V]:
|
|
413
|
+
let current_node = this.node else:
|
|
414
|
+
fatal(c"map.Entries.current missing current node")
|
|
415
|
+
|
|
416
|
+
unsafe:
|
|
417
|
+
let node_ptr = ptr[Node[K, V]]<-current_node
|
|
418
|
+
return Entry[K, V](key = const_ptr_of(read(node_ptr).key), value = ptr_of(read(node_ptr).value))
|
data/std/math.mt
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import std.c.math as c
|
|
2
|
+
|
|
3
|
+
public const PI: double = 3.141592653589793
|
|
4
|
+
public const HALF_PI: double = 1.5707963267948966
|
|
5
|
+
public const QUARTER_PI: double = 0.7853981633974483
|
|
6
|
+
public const TAU: double = 6.283185307179586
|
|
7
|
+
public const E: double = 2.718281828459045
|
|
8
|
+
|
|
9
|
+
public foreign function abs(value: double) -> double = c.mt_math_abs
|
|
10
|
+
public foreign function sqrt(value: double) -> double = c.mt_math_sqrt
|
|
11
|
+
public foreign function pow(base: double, exponent: double) -> double = c.mt_math_pow
|
|
12
|
+
public foreign function exp(value: double) -> double = c.mt_math_exp
|
|
13
|
+
public foreign function log(value: double) -> double = c.mt_math_log
|
|
14
|
+
public foreign function log10(value: double) -> double = c.mt_math_log10
|
|
15
|
+
public foreign function sin(radians: double) -> double = c.mt_math_sin
|
|
16
|
+
public foreign function cos(radians: double) -> double = c.mt_math_cos
|
|
17
|
+
public foreign function tan(radians: double) -> double = c.mt_math_tan
|
|
18
|
+
public foreign function asin(value: double) -> double = c.mt_math_asin
|
|
19
|
+
public foreign function acos(value: double) -> double = c.mt_math_acos
|
|
20
|
+
public foreign function atan(value: double) -> double = c.mt_math_atan
|
|
21
|
+
public foreign function atan2(y: double, x: double) -> double = c.mt_math_atan2
|
|
22
|
+
public foreign function floor(value: double) -> double = c.mt_math_floor
|
|
23
|
+
public foreign function ceil(value: double) -> double = c.mt_math_ceil
|
|
24
|
+
public foreign function mod(value: double, divisor: double) -> double = c.mt_math_mod
|