compiler: add -O0/-O2 flags, -v 1..4, whole-word JIT, lazy init, auto-inline control

- Add -O0 (no opts) and -O2 (no opts + no checks) CLI flags
- Add -v 1..4 verbosity: timing, per-function stats, debug dump, optimization diffs
- Whole-word JIT: compile Definition bodies to native x86-64 for CT VM
- Lazy CTMemory/JIT/ctype init (defer ctypes until first CT execution)
- Stack-effect comment parsing for stack-checks
- Peephole rules refactored to module-level dicts with O(1) lookup
- _emitted_start short-circuit (O(1) vs O(n) scan)
- Add --no-auto-inline to disable auto-inlining of small asm bodies
- Fix --ct-run-main to execute after linking (prevent SIGSEGV)
- Stdlib: small optimizations like swap + drop -> nip
This commit is contained in:
igor
2026-03-09 14:04:45 +01:00
parent 819e451512
commit 2a1ae2f774
3 changed files with 1820 additions and 767 deletions

2561
main.py

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@ word alloc
-1 # fd -1 # fd
0 # offset 0 # offset
mmap mmap
swap drop nip
end end
#free [*, addr | size] -> [*] #free [*, addr | size] -> [*]
@@ -38,8 +38,7 @@ word memcpy
c! c!
swap swap
end end
swap drop
nip
r> dup -rot - swap r> dup -rot - swap
end end

View File

@@ -21,8 +21,7 @@ word strconcat
swap swap
3 pick 3 pick
- -
swap nip
drop
swap swap
0 rpick 0 rpick
nip nip
@@ -56,11 +55,11 @@ end
#toint [*, addr | len] -> [* | int] #toint [*, addr | len] -> [* | int]
# converts a string to an int # converts a string to an int
word toint word toint
swap tuck
over 0 swap 0 swap
dup >r dup >r
for for
over over + 2dup +
c@ 48 - c@ 48 -
swap rot swap rot
swap swap
@@ -72,7 +71,7 @@ word toint
digitsN>num digitsN>num
r> 1 + r> 1 +
for for
swap drop nip
end end
rdrop rdrop rdrop rdrop
end end
@@ -134,7 +133,7 @@ word indexof
while dup 3 pick < 2 pick -1 == band do # while i < len && result == -1 while dup 3 pick < 2 pick -1 == band do # while i < len && result == -1
dup 4 pick + c@ # byte = addr[i] dup 4 pick + c@ # byte = addr[i]
r@ == if # byte == char? r@ == if # byte == char?
swap drop dup # result = i nip dup # result = i
end end
1 + # i++ 1 + # i++
end end
@@ -220,7 +219,7 @@ end
#formats [*, sN_addr, sN_len, ..., s1_addr, s1_len, fmt_addr | fmt_len] -> [*, result_addr | result_len] #formats [*, sN_addr, sN_len, ..., s1_addr, s1_len, fmt_addr | fmt_len] -> [*, result_addr | result_len]
word formats word formats
2dup 37 count_char_in_str nip nip # count '%' -> n 2dup 37 count_char_in_str nip nip # count '%' -> n
dup 0 == if dup not if
drop # no substitutions needed drop # no substitutions needed
else else
1 - >r # remaining = n - 1 1 - >r # remaining = n - 1
@@ -243,7 +242,7 @@ end
#formati [*, iN, ..., i1, fmt_addr | fmt_len] -> [*, result_addr | result_len] #formati [*, iN, ..., i1, fmt_addr | fmt_len] -> [*, result_addr | result_len]
word formati word formati
2dup 37 count_char_in_str nip nip # count '%' -> n 2dup 37 count_char_in_str nip nip # count '%' -> n
dup 0 == if dup not if
drop # no substitutions needed drop # no substitutions needed
else else
1 - >r # remaining = n - 1 1 - >r # remaining = n - 1
@@ -269,7 +268,7 @@ end
word find_fmt word find_fmt
over >r dup >r # rstack: 0=len, 1=addr over >r dup >r # rstack: 0=len, 1=addr
-1 0 0 # pos=-1, type=0, i=0 -1 0 0 # pos=-1, type=0, i=0
while dup 0 rpick 1 - < 2 pick 0 == band do while dup 0 rpick 1 - < 2 pick not band do
1 rpick over + c@ # addr[i] 1 rpick over + c@ # addr[i]
37 == if # '%' 37 == if # '%'
1 rpick over + 1 + c@ # addr[i+1] 1 rpick over + 1 + c@ # addr[i+1]
@@ -363,7 +362,7 @@ end
# original format string unchanged if there are no placeholders. # original format string unchanged if there are no placeholders.
word format word format
2dup count_fmt nip nip # n = placeholder count 2dup count_fmt nip nip # n = placeholder count
dup 0 == if dup not if
drop drop
else else
>r >r