diff --git a/SPEC.md b/SPEC.md index 82ce033..4005b41 100644 --- a/SPEC.md +++ b/SPEC.md @@ -21,6 +21,13 @@ This document reflects the implementation that ships in this repository today (` - **Lists** – `[` begins a list literal, `]` ends it. The compiler captures the intervening stack segment into a freshly `mmap`'d buffer that stores `(len followed by qword items)`, drops the captured values, and pushes the buffer address. Users must `munmap` the buffer when done. - **Token customization** – Immediate words can call `add-token` or `add-token-chars` to teach the reader about new multi-character tokens. `fn.sl` uses this in combination with token hooks to recognize `foo(1, 2)` syntax. +### Stack-effect comments +- **Location and prefix** – Public words in `stdlib/` (and most user code should) document its stack effect with a line comment directly above the definition: `#word_name …`. +- **Before/after form** – Use `[before] -> [after]`, where each side is a comma-separated list. Items sitting to the left of `|` are deeper in the stack; the segment to the right of `|` runs all the way to the current top-of-stack. Omit the `|` only when a side is empty (`[*]`). +- **Tail sentinel** – `*` represents the untouched rest of the stack. By convention it is always the first entry on each side so readers can quickly see which values are consumed/produced. +- **Alternatives** – Separate multiple outcomes with `||`. Each branch repeats the `[before] -> [after]` structure (e.g., `#read_file [*, path | len] -> [*, addr | len] || [*, tag | neg_errno]`). +- **Examples** – `#dup [* | x] -> [*, x | x]` means a word consumes the top value `x` and returns two copies with the newest copy at TOS; `#arr_pop [* | arr] -> [*, arr | x]` states that the array pointer remains just below the popped element. This notation keeps stack order resonably easy to read and grep. + ## 4. Runtime Model - **Stacks** – `r12` holds the data stack pointer, `r13` the return stack pointer. Both live in `.bss` buffers sized by `DSTK_BYTES`/`RSTK_BYTES` (default 64 KiB each). `stdlib/core.sl` implements all standard stack shuffles, arithmetic, comparisons, boolean ops, `@`/`!`, `c@`/`c!`, and return-stack transfers (`>r`, `r>`, `rdrop`, `rpick`). - **Calling convention** – Words call each other using the System V ABI. `extern` words marshal arguments into registers before `call symbol`, then push results back onto the data stack. Integer results come from `rax`; floating results come from `xmm0` and are copied into a qword slot. diff --git a/fn.sl b/fn.sl index f7b32c4..ebdb140 100644 --- a/fn.sl +++ b/fn.sl @@ -1,4 +1,5 @@ -word call-syntax-rewrite # ( fnameToken -- handled ) +#call-syntax-rewrite [* | fnameToken] -> [* | handled] +word call-syntax-rewrite dup token-lexeme identifier? 0 == if drop 0 exit end peek-token dup nil? if drop drop 0 exit end dup token-lexeme "(" string= 0 == if drop drop 0 exit end diff --git a/nob.sl b/nob.sl index 46a5a80..2c9cbc9 100644 --- a/nob.sl +++ b/nob.sl @@ -2,7 +2,7 @@ import stdlib/stdlib.sl import stdlib/linux.sl import stdlib/mem.sl -# sh ( cmd_addr cmd_len -- exit_code | neg_errno ) +# sh [*, cmd_addr | cmd_len ] -> [* | exit_code ] word sh swap >r # save cmd_addr diff --git a/stdlib/arr.sl b/stdlib/arr.sl index 3345fe3..c33432c 100644 --- a/stdlib/arr.sl +++ b/stdlib/arr.sl @@ -11,7 +11,7 @@ import mem.sl -# : arr_new ( cap -- arr ) +#arr_new [* | cap] -> [* | arr] # Create a new array with given initial capacity (minimum 1) word arr_new dup 1 < if drop 1 end @@ -22,21 +22,21 @@ word arr_new nip end -# : arr_len ( arr -- len ) +#arr_len [* | arr] -> [* | len] word arr_len @ end -# : arr_cap ( arr -- cap ) +#arr_cap [* | arr] -> [* | cap] word arr_cap 8 + @ end -# : arr_data ( arr -- ptr ) +#arr_data [* | arr] -> [* | ptr] word arr_data 16 + @ end -# : arr_free ( arr -- ) +#arr_free [* | arr] -> [*] word arr_free dup arr_cap 8 * 24 + free end -# Helper: copy n qwords from src to dst (dst src n --) +# Helper: copy n qwords from src to dst [*, dst, src | n] -> [*] word arr_copy_elements while dup 0 > do over @ 3 pick swap ! # dst = *src @@ -47,7 +47,7 @@ word arr_copy_elements drop 2drop end -# : arr_reserve ( cap arr -- arr ) +#arr_reserve [*, cap | arr] -> [* | arr] # Ensures capacity >= cap; returns (possibly moved) arr pointer. word arr_reserve swap dup 1 < if drop 1 end swap # reqcap arr @@ -77,7 +77,7 @@ word arr_reserve end end -# : arr_push ( x arr -- arr ) +#arr_push [*, x | arr] -> [* | arr] # Push element onto array, growing if needed word arr_push dup arr_len over arr_cap >= if @@ -94,27 +94,26 @@ word arr_push dup @ 1 + over swap ! end -# : arr_pop ( arr -- x arr ) +#arr_pop [* | arr] -> [*, arr | x] # Pop element from array (returns 0 if empty) word arr_pop dup arr_len 0 == if - 0 swap + 0 else # Decrement len dup @ 1 - over swap ! # Get element at new len position dup arr_data over arr_len 8 * + @ - swap end end -# : arr_get ( i arr -- x ) +#arr_get [*, i | arr] -> [* | x] # Get element at index i word arr_get arr_data swap 8 * + @ end -# : arr_set ( x i arr -- ) +#arr_set [*, x, i | arr] -> [*] # Set element at index i to x word arr_set arr_data swap 8 * + swap ! diff --git a/stdlib/arr_asm.sl b/stdlib/arr_asm.sl index 48c7327..acd5f71 100644 --- a/stdlib/arr_asm.sl +++ b/stdlib/arr_asm.sl @@ -9,7 +9,7 @@ # Allocation: mmap; free: munmap. # Growth: allocate new block, copy elements, munmap old block. -# : arr_new ( cap -- arr ) +#arr_new [* | cap] -> [* | arr] :asm arr_new { mov r14, [r12] ; requested cap cmp r14, 1 @@ -42,7 +42,7 @@ } ; -# : arr_len ( arr -- len ) +#arr_len [* | arr] -> [* | len] :asm arr_len { mov rax, [r12] mov rax, [rax] @@ -51,7 +51,7 @@ } ; -# : arr_cap ( arr -- cap ) +#arr_cap [* | arr] -> [* | cap] :asm arr_cap { mov rax, [r12] mov rax, [rax + 8] @@ -60,7 +60,7 @@ } ; -# : arr_data ( arr -- ptr ) +#arr_data [* | arr] -> [* | ptr] :asm arr_data { mov rax, [r12] mov rax, [rax + 16] @@ -69,7 +69,7 @@ } ; -# : arr_free ( arr -- ) +#arr_free [* | arr] -> [*] :asm arr_free { mov rbx, [r12] ; base mov rcx, [rbx + 8] ; cap @@ -84,7 +84,7 @@ } ; -# : arr_reserve ( cap arr -- arr ) +#arr_reserve [*, cap | arr] -> [* | arr] # Ensures capacity >= cap; returns (possibly moved) arr pointer. :asm arr_reserve { mov rbx, [r12] ; arr @@ -151,7 +151,7 @@ } ; -# : arr_push ( x arr -- arr ) +#arr_push [*, x | arr] -> [* | arr] :asm arr_push { mov rbx, [r12] ; arr mov rcx, [rbx] ; len @@ -227,7 +227,7 @@ } ; -# : arr_pop ( arr -- x arr ) +#arr_pop [* | arr] -> [*, arr | x] :asm arr_pop { mov rbx, [r12] ; arr mov rcx, [rbx] ; len @@ -245,4 +245,4 @@ mov [r12], rax ret } -; \ No newline at end of file +; diff --git a/stdlib/core.sl b/stdlib/core.sl index 356c734..9728df0 100644 --- a/stdlib/core.sl +++ b/stdlib/core.sl @@ -2,6 +2,7 @@ # persistent: resb 64 # push the addr of it +#mem [*] -> [* | ptr] :asm mem { lea rax, [rel persistent] sub r12, 8 @@ -9,7 +10,7 @@ } ; -# : argc ( -- n ) +#argc [*] -> [* | n] :asm argc { extern sys_argc mov rax, [rel sys_argc] @@ -19,7 +20,7 @@ } ; -# : argv ( -- ptr ) +#argv [*] -> [* | ptr] :asm argv { extern sys_argv mov rax, [rel sys_argv] @@ -29,7 +30,7 @@ } ; -# : argv@ ( n -- ptr ) +#argv@ [* | n] -> [* | ptr] :asm argv@ { extern sys_argv mov rbx, [r12] ; n @@ -40,7 +41,7 @@ } ; -# : c@ ( addr -- byte ) +#c@ [* | addr] -> [* | byte] :asm c@ { mov rax, [r12] ; get address from stack movzx rax, byte [rax] ; load byte at address, zero-extend to rax @@ -49,7 +50,7 @@ } ; -# : c! ( byte addr -- ) +#c! [*, byte | addr] -> [*] :asm c! { mov rax, [r12] ; get address from stack add r12, 8 ; pop address @@ -60,7 +61,7 @@ } ; -# : r@ ( -- x ) +#r@ [*] -> [* | x] :asm r@ { mov rax, [r13] ; get value from return stack sub r12, 8 ; make room on data stack @@ -69,7 +70,7 @@ } ; -# : dup ( x -- x x ) +#dup [* | x] -> [*, x | x] :asm dup { mov rax, [r12] ; get top of stack sub r12, 8 ; make room @@ -77,13 +78,13 @@ } ; -# : drop ( x -- ) +#drop [* | x] -> [*] :asm drop { add r12, 8 ; remove top of stack } ; -# : over ( x1 x2 -- x1 x2 x1 ) +#over [*, x1 | x2] -> [*, x1, x2 | x1] :asm over { mov rax, [r12 + 8] ; get second item sub r12, 8 ; make room @@ -91,7 +92,7 @@ } ; -# : swap ( x1 x2 -- x2 x1 ) +#swap [*, x1 | x2] -> [*, x2 | x1] :asm swap { mov rax, [r12] ; get top mov rbx, [r12 + 8] ; get second @@ -100,7 +101,7 @@ } ; -# : rot ( x1 x2 x3 -- x2 x3 x1 ) +#rot [*, x1, x2 | x3] -> [*, x2, x3 | x1] :asm rot { mov rax, [r12] ; x3 (top) mov rbx, [r12 + 8] ; x2 @@ -111,7 +112,7 @@ } ; -# : -rot ( x1 x2 x3 -- x3 x1 x2 ) +#-rot [*, x1, x2 | x3] -> [*, x3, x1 | x2] :asm -rot { mov rax, [r12] ; x3 (top) mov rbx, [r12 + 8] ; x2 @@ -122,7 +123,7 @@ } ; -# : nip ( x1 x2 -- x2 ) +#nip [*, x1 | x2] -> [* | x2] :asm nip { mov rax, [r12] ; get top add r12, 8 ; drop lower @@ -130,7 +131,7 @@ } ; -# : tuck ( x1 x2 -- x2 x1 x2 ) +#tuck [*, x1 | x2] -> [*, x2, x1 | x2] :asm tuck { mov rax, [r12] ; x2 (top) mov rbx, [r12 + 8] ; x1 @@ -141,7 +142,7 @@ } ; -# : 2dup ( x1 x2 -- x1 x2 x1 x2 ) +#2dup [*, x1 | x2] -> [*, x1, x2, x1 | x2] :asm 2dup { mov rax, [r12] ; b (top) mov rbx, [r12 + 8] ; a @@ -152,13 +153,13 @@ } ; -# : 2drop ( x1 x2 -- ) +#2drop [*, x1 | x2] -> [*] :asm 2drop { add r12, 16 ; remove two items } ; -# : 2swap ( x1 x2 x3 x4 -- x3 x4 x1 x2 ) +#2swap [*, x1, x2, x3 | x4] -> [*, x3, x4, x1 | x2] :asm 2swap { mov rax, [r12] ; d (top) mov rbx, [r12 + 8] ; c @@ -171,7 +172,7 @@ } ; -# : 2over ( x1 x2 x3 x4 -- x3 x4 x1 x2 x3 x4 ) +#2over [*, x1, x2, x3 | x4] -> [*, x3, x4, x1, x2, x3 | x4] :asm 2over { mov rax, [r12 + 16] ; b mov rbx, [r12 + 24] ; a @@ -182,7 +183,7 @@ } ; -# : + ( x1 x2 -- x3 ) +#+ [*, x1 | x2] -> [* | x3] :asm + { mov rax, [r12] ; get top add r12, 8 ; pop @@ -190,7 +191,7 @@ } ; -# : - ( x1 x2 -- x3 ) +#- [*, x1 | x2] -> [* | x3] :asm - { mov rax, [r12] ; get top add r12, 8 ; pop @@ -198,7 +199,7 @@ } ; -# : * ( x1 x2 -- x3 ) +#* [*, x1 | x2] -> [* | x3] :asm * { mov rax, [r12] ; get top add r12, 8 ; pop @@ -207,7 +208,7 @@ } ; -# : / ( x1 x2 -- x3 ) +#/ [*, x1 | x2] -> [* | x3] :asm / { mov rbx, [r12] ; divisor add r12, 8 ; pop @@ -218,7 +219,7 @@ } ; -# : % ( x1 x2 -- x3 ) +#% [*, x1 | x2] -> [* | x3] :asm % { mov rbx, [r12] ; divisor add r12, 8 ; pop @@ -229,7 +230,7 @@ } ; -# : == ( x1 x2 -- flag ) +#== [*, x1 | x2] -> [* | flag] :asm == { mov rax, [r12] ; get top add r12, 8 ; pop @@ -241,7 +242,7 @@ } ; -# : != ( x1 x2 -- flag ) +#!= [*, x1 | x2] -> [* | flag] :asm != { mov rax, [r12] ; get top add r12, 8 ; pop @@ -253,7 +254,7 @@ } ; -# : < ( x1 x2 -- flag ) +#< [*, x1 | x2] -> [* | flag] :asm < { mov rax, [r12] ; get top add r12, 8 ; pop @@ -265,7 +266,7 @@ } ; -# : > ( x1 x2 -- flag ) +#> [*, x1 | x2] -> [* | flag] :asm > { mov rax, [r12] ; get top add r12, 8 ; pop @@ -277,7 +278,7 @@ } ; -# : <= ( x1 x2 -- flag ) +#<= [*, x1 | x2] -> [* | flag] :asm <= { mov rax, [r12] ; get top add r12, 8 ; pop @@ -289,7 +290,7 @@ } ; -# : >= ( x1 x2 -- flag ) +#>= [*, x1 | x2] -> [* | flag] :asm >= { mov rax, [r12] ; get top add r12, 8 ; pop @@ -301,7 +302,7 @@ } ; -# : @ ( addr -- x ) +#@ [* | addr] -> [* | x] :asm @ { mov rax, [r12] ; get address mov rax, [rax] ; load value @@ -309,7 +310,7 @@ } ; -# : ! ( x addr -- ) +#! [*, x | addr] -> [*] :asm ! { mov rax, [r12] ; get value (TOS) add r12, 8 ; pop value @@ -319,7 +320,7 @@ } ; -# : mmap ( addr len prot flags fd offset -- addr ) +#mmap [*, addr, len, prot, flags, fd | offset] -> [* | addr] :asm mmap { mov r9, [r12] ; offset add r12, 8 @@ -339,7 +340,7 @@ } ; -# : munmap ( addr len -- res ) +#munmap [*, addr | len] -> [* | res] :asm munmap { mov rsi, [r12] ; len add r12, 8 @@ -352,7 +353,7 @@ } ; -# : exit ( code -- ) +#exit [* | code] -> [*] :asm exit { mov rdi, [r12] ; exit code add r12, 8 @@ -361,7 +362,7 @@ } ; -# : and ( x1 x2 -- flag ) +#and [*, x1 | x2] -> [* | flag] :asm and { mov rax, [r12] ; get top add r12, 8 ; pop @@ -377,7 +378,7 @@ } ; -# : or ( x1 x2 -- flag ) +#or [*, x1 | x2] -> [* | flag] :asm or { mov rax, [r12] ; get top add r12, 8 ; pop @@ -393,7 +394,7 @@ } ; -# : not ( x -- flag ) +#not [* | x] -> [* | flag] :asm not { mov rax, [r12] ; get value test rax, rax @@ -403,7 +404,7 @@ } ; -# : >r ( x -- ) +#>r [* | x] -> [*] :asm >r { mov rax, [r12] ; get value add r12, 8 ; pop @@ -412,7 +413,7 @@ } ; -# : r> ( -- x ) +#r> [*] -> [* | x] :asm r> { mov rax, [r13] ; get value from return stack add r13, 8 ; pop return stack @@ -421,13 +422,13 @@ } ; -# : rdrop ( -- ) +#rdrop [*] -> [*] :asm rdrop { add r13, 8 ; pop return stack } ; -# : pick ( n -- x ) +#pick [* | n] -> [* | x] :asm pick { mov rcx, [r12] ; get index add r12, 8 ; pop @@ -437,7 +438,7 @@ } ; -# : rpick ( n -- x ) +#rpick [* | n] -> [* | x] :asm rpick { mov rcx, [r12] ; get index add r12, 8 ; pop @@ -447,7 +448,7 @@ } ; -# : neg ( x -- -x ) +#neg [* | x] -> [* | -x] :asm neg { mov rax, [r12] ; get value neg rax ; arithmetic negation @@ -455,7 +456,7 @@ } ; -# : abs ( x -- |x| ) +#abs [* | x] -> [* | |x|] :asm abs { mov rax, [r12] ; get value test rax, rax ; check sign @@ -466,7 +467,7 @@ } ; -# : bitnot ( 0|1 -- 1|0 ) +#bitnot [* | bool] -> [* | bool] :asm bitnot { mov rax, [r12] ; get value xor rax, 1 ; flip lowest bit @@ -474,7 +475,7 @@ } ; -# : band ( x1 x2 -- x3 ) +#band [*, x1 | x2] -> [* | x3] :asm band { mov rax, [r12] ; get top add r12, 8 ; pop @@ -482,7 +483,7 @@ } ; -# : bor ( x1 x2 -- x3 ) +#bor [*, x1 | x2] -> [* | x3] :asm bor { mov rax, [r12] ; get top add r12, 8 ; pop @@ -490,7 +491,7 @@ } ; -# : bxor ( x1 x2 -- x3 ) +#bxor [*, x1 | x2] -> [* | x3] :asm bxor { mov rax, [r12] ; get top add r12, 8 ; pop @@ -498,13 +499,13 @@ } ; -# : bnot ( x -- x ) +#bnot [* | x] -> [* | x] :asm bnot { not qword [r12] ; bitwise not } ; -# : shl ( x1 x2 -- x3 ) +#shl [*, x1 | x2] -> [* | x3] :asm shl { mov rcx, [r12] ; shift count add r12, 8 ; pop @@ -512,7 +513,7 @@ } ; -# : sal ( x1 x2 -- x3 ) +#sal [*, x1 | x2] -> [* | x3] :asm sal { mov rcx, [r12] ; shift count add r12, 8 ; pop @@ -520,7 +521,7 @@ } ; -# : shr ( x1 x2 -- x3 ) +#shr [*, x1 | x2] -> [* | x3] :asm shr { mov rcx, [r12] ; shift count add r12, 8 ; pop @@ -528,7 +529,7 @@ } ; -# : sar ( x1 x2 -- x3 ) +#sar [*, x1 | x2] -> [* | x3] :asm sar { mov rcx, [r12] ; shift count add r12, 8 ; pop @@ -536,7 +537,7 @@ } ; -# : rol ( x1 x2 -- x3 ) +#rol [*, x1 | x2] -> [* | x3] :asm rol { mov rcx, [r12] ; shift count add r12, 8 ; pop @@ -544,7 +545,7 @@ } ; -# : ror ( x1 x2 -- x3 ) +#ror [*, x1 | x2] -> [* | x3] :asm ror { mov rcx, [r12] ; shift count add r12, 8 ; pop @@ -552,19 +553,19 @@ } ; -# : inc ( x -- x+1 ) +#inc [* | x] -> [* | x+1] :asm inc { inc qword [r12] } ; -# : dec ( x -- x-1 ) +#dec [* | x] -> [* | x-1] :asm dec { dec qword [r12] } ; -# : min ( x1 x2 -- x3 ) +#min [*, x1 | x2] -> [* | x3] :asm min { mov rax, [r12] ; x2 add r12, 8 ; pop @@ -575,7 +576,7 @@ } ; -# : max ( x1 x2 -- x3 ) +#max [*, x1 | x2] -> [* | x3] :asm max { mov rax, [r12] ; x2 add r12, 8 ; pop @@ -586,7 +587,7 @@ } ; -# : clamp ( x lo hi -- y ) +#clamp [*, x, lo | hi] -> [* | y] :asm clamp { mov rax, [r12] ; hi mov rbx, [r12 + 8] ; lo @@ -600,7 +601,7 @@ } ; -# : time ( -- t ) +#time [*] -> [* | t] :asm time { mov rax, 201 ; syscall: time xor rdi, rdi @@ -611,7 +612,7 @@ } ; -# : rand ( -- n ) +#rand [*] -> [* | n] :asm rand { lea rbx, [rel persistent] mov rax, [rbx] ; state diff --git a/stdlib/debug.sl b/stdlib/debug.sl index 4a3009f..6922374 100644 --- a/stdlib/debug.sl +++ b/stdlib/debug.sl @@ -1,7 +1,7 @@ import stdlib.sl import io.sl -# : dump ( n -- ) +#dump [* | n] -> [*] # dump takes the firts element from the stack # and prints that much consequent elements @@ -28,7 +28,7 @@ word rdump drop end -# : int3 ( -- ) +#int3 [*] -> [*] :asm int3 { int3 } diff --git a/stdlib/io.sl b/stdlib/io.sl index fd77c09..4da4dce 100644 --- a/stdlib/io.sl +++ b/stdlib/io.sl @@ -1,8 +1,8 @@ # L2 IO Primitives -# : read_file ( path_addr path_len -- addr len | 0 0 ) +#read_file [*, path_addr | path_len] -> [*, addr | len] || [*, tag | neg_errno] # Reads the file at the given path (pointer+length, not null-terminated), -# returns (addr len) of mapped file, or (0 0) on error. +# returns (addr len) of mapped file, or (tag neg_errno) on error. :asm read_file { ; stack: path_addr (NOS), path_len (TOS) @@ -79,7 +79,7 @@ } ; -# : write_file ( path_ptr path_len buf_ptr buf_len -- bytes_written | neg_errno ) +#write_file [*, path_ptr, path_len, buf_ptr | buf_len] -> [* | bytes_written] || [* | neg_errno] :asm write_file { ; stack: path_addr, path_len, buf_addr, buf_len (TOS) mov r13, [r12] ; buf_len @@ -132,7 +132,7 @@ } ; -# : read_stdin ( max_len -- addr len | neg_errno 0 ) +#read_stdin [* | max_len] -> [*, addr | len] || [*, tag | neg_errno] :asm read_stdin { ; stack: max_len mov r14, [r12] ; max_len @@ -268,7 +268,7 @@ } ; -# : write_buf ( addr len -- ) +#write_buf [*, addr | len] -> [*] :asm write_buf (effects string-io) { mov rdx, [r12] ; len mov rsi, [r12 + 8] ; addr @@ -280,7 +280,7 @@ } ; -# : ewrite_buf ( addr len -- ) +#ewrite_buf [*, addr | len] -> [*] :asm ewrite_buf (effects string-io) { mov rdx, [r12] ; len mov rsi, [r12 + 8] ; addr @@ -292,7 +292,7 @@ } ; -# : putc ( char -- ) +#putc [* | char] -> [*] :asm putc { mov rax, [r12] add r12, 8 @@ -306,7 +306,7 @@ } ; -# : puti ( int -- ) +#puti [* | int] -> [*] :asm puti { mov rax, [r12] ; get int add r12, 8 ; pop diff --git a/stdlib/linux.sl b/stdlib/linux.sl index 8601122..98badc2 100644 --- a/stdlib/linux.sl +++ b/stdlib/linux.sl @@ -2,7 +2,7 @@ # Provides syscall constants and helpers for L2 programs # swap impl is provided so this can be used without the need for stdlib -# : ___linux_swap ( x1 x2 -- x2 x1 ) +#___linux_swap [*, x1 | x2] -> [*, x2 | x1] :asm ___linux_swap { mov rax, [r12] ; get top mov rbx, [r12 + 8] ; get second diff --git a/stdlib/mem.sl b/stdlib/mem.sl index 9091258..05a1b88 100644 --- a/stdlib/mem.sl +++ b/stdlib/mem.sl @@ -1,5 +1,6 @@ import stdlib.sl +#alloc [* | size] -> [* | addr] word alloc 0 # addr hint (NULL) swap # size @@ -11,11 +12,13 @@ word alloc swap drop end +#free [*, addr | size] -> [*] word free munmap drop end -word memcpy #(dst_addr src_addr len -- dst_addr len) +#memcpy [*, dst_addr, src_addr | len] -> [*, dst_addr | len] +word memcpy dup >r swap @@ -40,7 +43,8 @@ word memcpy #(dst_addr src_addr len -- dst_addr len) r> dup -rot - swap end -word memset #( value len addr -- ) +#memset [*, value, len | addr] -> [*] +word memset swap 0 swap for -rot swap 2 pick + 2dup swap ! 1 + -rot swap @@ -48,15 +52,17 @@ word memset #( value len addr -- ) 2drop drop end -word memdump #( len addr -- addr ) +#memdump [*, len | addr] -> [* | addr] +word memdump for dup c@ puti cr 1 + end end -word realloc #( addr old_len new_len -- new_addr ) +#realloc [*, addr, old_len | new_len] -> [* | new_addr] +word realloc 2 pick swap alloc rot rot swap memcpy swap -rot free -end \ No newline at end of file +end diff --git a/stdlib/utils.sl b/stdlib/utils.sl index 1f5a256..3d2a8fb 100644 --- a/stdlib/utils.sl +++ b/stdlib/utils.sl @@ -1,10 +1,10 @@ -# : strcmp ( addr len addr len -- bool addr len addr len) +#strcmp [*, addr, len, addr | len] -> [*, addr, len, addr, len | bool] word strcmp 3 pick 2 pick @ swap @ == end -# : strconcat ( addr len addr len -- addr len) +#strconcat [*, addr, len, addr | len] -> [*, addr | len] word strconcat 0 pick 3 pick + dup @@ -31,7 +31,7 @@ word strconcat rdrop rdrop rdrop end -# : strlen ( addr -- len ) +#strlen [* | addr] -> [* | len] # for null terminated strings word strlen 0 swap # len addr @@ -42,7 +42,8 @@ word strlen drop # drop addr, leave len end -word digitsN>num # ( d_{n-1} ... d0 n -- value ), digits bottom=MSD, top=LSD, length on top (MSD-most significant digit, LSD-least significant digit) +#digitsN>num [*, d_{n-1}, d0 | n] -> [* | value] +word digitsN>num # digits bottom=MSD, top=LSD, length on top (MSD-most significant digit, LSD-least significant digit) 0 swap # place accumulator below length for # loop n times using the length on top r@ pick # fetch next digit starting from MSD (uses loop counter as index) @@ -52,7 +53,8 @@ word digitsN>num # ( d_{n-1} ... d0 n -- value ), digits bottom=MSD, top=LSD, l end end -# : toint (addr len -- int ) converts a string to an int +#toint [*, addr | len] -> [* | int] +# converts a string to an int word toint swap over 0 swap @@ -75,7 +77,8 @@ word toint rdrop rdrop end -# : count_digits ( int -- int) returns the amount of digits of an int +#count_digits [* | int] -> [* | int] +# returns the amount of digits of an int word count_digits 0 swap @@ -85,7 +88,8 @@ word count_digits drop end -# : tostr ( int -- addr len ) the function allocates a buffer to remember to free it +#tostr [* | int] -> [*, addr | len] +# the function allocates a buffer, remember to free it word tostr dup count_digits @@ -115,4 +119,4 @@ word tostr over for rot drop end drop -end \ No newline at end of file +end