added async and hashmap lib to the stdlib as well as tests for them, improved the performance of the compiler, improved the buildt in doc tool and fixed some other small issues

This commit is contained in:
igor
2026-03-11 14:41:40 +01:00
parent 4e51e8803f
commit 0ac7f26a18
7 changed files with 3377 additions and 265 deletions

27
tests/async.expected Normal file
View File

@@ -0,0 +1,27 @@
0
1
8192
1
1
0
0
1
1
2
1
2
3
4
5
6
99
42
3
1
2
42
3
4
5
6
100

79
tests/async.sl Normal file
View File

@@ -0,0 +1,79 @@
import ../stdlib/stdlib.sl
import ../stdlib/io.sl
import ../stdlib/mem.sl
import ../stdlib/async.sl
# ── Worker words for scheduler tests ─────────────────────────
word worker_a
1 puti cr
yield
3 puti cr
yield
5 puti cr
end
word worker_b
2 puti cr
yield
4 puti cr
yield
6 puti cr
end
word worker_single
42 puti cr
end
word main
# ── task_new / task_status / task_entry_fn / task_stack_base/size ──
&worker_single task_new
dup task_status puti cr # 0 (TASK_READY)
dup task_stack_base 0 != puti cr # 1 (non-null)
dup task_stack_size puti cr # 8192
dup task_entry_fn 0 != puti cr # 1 (non-null fn ptr)
dup task_data_sp 0 != puti cr # 1 (non-null)
dup task_ret_sp puti cr # 0 (not yet started)
task_free
# ── sched_new / sched_task_count ──
8 sched_new
dup sched_task_count puti cr # 0
dup sched_tasks_ptr 0 != puti cr # 1 (non-null)
# ── sched_spawn ──
&worker_a sched_spawn
dup sched_task_count puti cr # 1
&worker_b sched_spawn
dup sched_task_count puti cr # 2
# ── sched_run (interleaved output) ──
sched_run # prints: 1 2 3 4 5 6
# ── post-run: verify we returned cleanly ──
99 puti cr # 99
sched_free
# ── single-task scheduler (no yield in worker) ──
4 sched_new
&worker_single sched_spawn
sched_run # prints: 42
sched_free
# ── three workers to test round-robin with more tasks ──
8 sched_new
&worker_a sched_spawn
&worker_b sched_spawn
&worker_single sched_spawn
dup sched_task_count puti cr # 3
sched_run # worker_a:1, worker_b:2, worker_single:42
# worker_a:3, worker_b:4
# worker_a:5, worker_b:6
sched_free
100 puti cr # 100 (clean exit)
end

28
tests/hashmap.expected Normal file
View File

@@ -0,0 +1,28 @@
0
8
3
100
200
300
00
1
0
111
3
1
0
0
2
999
3
1
1
1
0
0
1
7
10
40
70
77

80
tests/hashmap.sl Normal file
View File

@@ -0,0 +1,80 @@
import ../stdlib/stdlib.sl
import ../stdlib/io.sl
import ../stdlib/mem.sl
import ../stdlib/hashmap.sl
word main
# ── hm_new / hm_count / hm_capacity ──
8 hm_new
dup hm_count puti cr # 0
dup hm_capacity puti cr # 8
# ── hm_set / hm_get ──
dup 42 100 hm_set
dup 99 200 hm_set
dup 7 300 hm_set
dup hm_count puti cr # 3
dup 42 hm_get drop puti cr # 100
dup 99 hm_get drop puti cr # 200
dup 7 hm_get drop puti cr # 300
# ── hm_get miss ──
dup 999 hm_get # should be 0, 0
puti dup puti cr drop # 00
# ── hm_has ──
dup 42 hm_has puti cr # 1
dup 999 hm_has puti cr # 0
# ── hm_set overwrite ──
dup 42 111 hm_set
dup 42 hm_get drop puti cr # 111
dup hm_count puti cr # 3 (no new entry)
# ── hm_del ──
dup 99 hm_del puti cr # 1 (deleted)
dup 99 hm_del puti cr # 0 (already gone)
dup 99 hm_has puti cr # 0
dup hm_count puti cr # 2
# ── insert after delete (tombstone reuse) ──
dup 99 999 hm_set
dup 99 hm_get drop puti cr # 999
dup hm_count puti cr # 3
# ── hm_keys / hm_vals / hm_flags raw access ──
dup hm_keys 0 != puti cr # 1 (non-null pointer)
dup hm_vals 0 != puti cr # 1
dup hm_flags 0 != puti cr # 1
# ── hm_clear ──
hm_clear
dup hm_count puti cr # 0
dup 42 hm_has puti cr # 0 (cleared)
# ── rehash (force growth) ──
# insert enough to trigger rehash on the cleared map
dup 1 10 hm_set
dup 2 20 hm_set
dup 3 30 hm_set
dup 4 40 hm_set
dup 5 50 hm_set
dup 6 60 hm_set # load > 70% → rehash
dup 7 70 hm_set
dup hm_capacity 8 > puti cr # 1 (grew)
dup hm_count puti cr # 7
# verify all entries survived rehash
dup 1 hm_get drop puti cr # 10
dup 4 hm_get drop puti cr # 40
dup 7 hm_get drop puti cr # 70
# ── large key values ──
dup 1000000 77 hm_set
dup 1000000 hm_get drop puti cr # 77
hm_free
end