From 47a45c050ecbabd204ac0a2af98b67fb46d1d977 Mon Sep 17 00:00:00 2001 From: IgorCielniak Date: Mon, 12 Jan 2026 19:03:49 +0100 Subject: [PATCH] quite a few fixes, overall repo cleanup and some restructurization in the stdlib --- args.sl | 1 - c_extern.sl | 11 +- f.sl | 17 - t.sl => fn_test.sl | 7 +- gg.sl | 7 - main.sl | 16 - stdlib/core.sl | 474 +++++++++++++++++++++++++ stdlib/stdlib.sl | 498 +-------------------------- typeconversion.sl => stdlib/utils.sl | 69 +++- strcmp.sl | 14 - strconcat.sl | 35 -- tests/call_syntax_parens.expected | 2 - tests/call_syntax_parens.sl | 16 - tests/call_syntax_parens.test | 1 - tests/integration_core.expected | 1 - tests/integration_core.sl | 15 - tests/str.expected | 4 + tests/str.sl | 15 + tests/str.test | 1 + tests/typeconversion.expected | 2 + tests/typeconversion.sl | 9 + tests/typeconversion.test | 1 + tests/word_syntax.expected | 1 - tests/word_syntax.sl | 12 - tests/word_syntax.test | 1 - 25 files changed, 582 insertions(+), 648 deletions(-) delete mode 100644 f.sl rename t.sl => fn_test.sl (71%) delete mode 100644 gg.sl delete mode 100644 main.sl create mode 100644 stdlib/core.sl rename typeconversion.sl => stdlib/utils.sl (55%) delete mode 100644 strcmp.sl delete mode 100644 strconcat.sl delete mode 100644 tests/call_syntax_parens.expected delete mode 100644 tests/call_syntax_parens.sl delete mode 100644 tests/call_syntax_parens.test create mode 100644 tests/str.expected create mode 100644 tests/str.sl create mode 100644 tests/str.test create mode 100644 tests/typeconversion.expected create mode 100644 tests/typeconversion.sl create mode 100644 tests/typeconversion.test delete mode 100644 tests/word_syntax.expected delete mode 100644 tests/word_syntax.sl delete mode 100644 tests/word_syntax.test diff --git a/args.sl b/args.sl index e303fca..909aa17 100644 --- a/args.sl +++ b/args.sl @@ -1,5 +1,4 @@ import stdlib/stdlib.sl -import stdlib/io.sl word main 0 argc for diff --git a/c_extern.sl b/c_extern.sl index 1b8cbad..1fde1a1 100644 --- a/c_extern.sl +++ b/c_extern.sl @@ -1,13 +1,22 @@ -import stdlib/io.sl +import stdlib.sl +import float.sl # C-style externs (auto ABI handling) extern long labs(long n) extern void exit(int status) +extern double atan2(double y, double x) word main # Test C-style extern with implicit ABI handling -10 labs puti cr + + # Basic math + 1.5 2.5 f+ fputln # Outputs: 4.000000 + # External math library (libm) + 10.0 10.0 atan2 # Result is pi/4 + 4.0 f* fputln # Outputs: 3.141593 (approx pi) + # Test extern void 0 exit end diff --git a/f.sl b/f.sl deleted file mode 100644 index df28ba0..0000000 --- a/f.sl +++ /dev/null @@ -1,17 +0,0 @@ -import stdlib/stdlib.sl -import stdlib/io.sl -import stdlib/float.sl - -extern double atan2(double y, double x) - -word main - # Basic math - 1.5 2.5 f+ fputln # Outputs: 4.000000 - - # External math library (libm) - 10.0 10.0 atan2 # Result is pi/4 - 4.0 f* fputln # Outputs: 3.141593 (approx pi) - - 0 -end - diff --git a/t.sl b/fn_test.sl similarity index 71% rename from t.sl rename to fn_test.sl index e5893db..c06a64a 100644 --- a/t.sl +++ b/fn_test.sl @@ -8,9 +8,14 @@ fn foo(int a, int b){ return a b +; } +fn bar(int a, int b){ + return a + b; +} + word main extend-syntax foo(3, 2) puti cr - 0 + bar(1, 2) + puti cr end \ No newline at end of file diff --git a/gg.sl b/gg.sl deleted file mode 100644 index e175188..0000000 --- a/gg.sl +++ /dev/null @@ -1,7 +0,0 @@ -import stdlib/io.sl - -extern long labs(long n) - -word main - -3 labs puti -end \ No newline at end of file diff --git a/main.sl b/main.sl deleted file mode 100644 index 4e802d3..0000000 --- a/main.sl +++ /dev/null @@ -1,16 +0,0 @@ -import stdlib/stdlib.sl -import stdlib/io.sl -import fn.sl - -word main - 2 40 + - puti cr - extend-syntax - foo(1, 2) - puti cr - 0 -end - -fn foo(int a, int b){ - return a + b; -} \ No newline at end of file diff --git a/stdlib/core.sl b/stdlib/core.sl new file mode 100644 index 0000000..a405e62 --- /dev/null +++ b/stdlib/core.sl @@ -0,0 +1,474 @@ +# Reserve 64 bytes in .bss +# persistent: resb 64 +# push the addr of it + +:asm mem { + lea rax, [rel persistent] + sub r12, 8 + mov [r12], rax +} +; + +# : argc ( -- n ) +:asm argc { + extern argc + mov rax, [rel argc] + sub r12, 8 + mov [r12], rax + ret +} +; + +# : argv ( -- ptr ) +:asm argv { + extern argv + mov rax, [rel argv] + sub r12, 8 + mov [r12], rax + ret +} +; + +# : argv@ ( n -- ptr ) +:asm argv@ { + extern argv + mov rbx, [r12] ; n + mov rax, [rel argv] + mov rax, [rax + rbx*8] + mov [r12], rax + ret +} +; + +# : c@ ( addr -- byte ) +:asm c@ { + mov rax, [r12] ; get address from stack + movzx rax, byte [rax] ; load byte at address, zero-extend to rax + mov [r12], rax ; store result back on stack + ret +} +; + +# : c! ( byte addr -- ) +:asm c! { + mov rax, [r12] ; get address from stack + add r12, 8 ; pop address + mov rbx, [r12] ; get byte value + mov [rbx], al ; store byte at address + ret +} +; + +# : r@ ( -- x ) +:asm r@ { + mov rax, [r13] ; get value from return stack + sub r12, 8 ; make room on data stack + mov [r12], rax ; push value to data stack + ret +} +; + +# : dup ( x -- x x ) +:asm dup { + mov rax, [r12] ; get top of stack + sub r12, 8 ; make room + mov [r12], rax ; duplicate value +} +; + +# : drop ( x -- ) +:asm drop { + add r12, 8 ; remove top of stack +} +; + +# : over ( x1 x2 -- x1 x2 x1 ) +:asm over { + mov rax, [r12 + 8] ; get second item + sub r12, 8 ; make room + mov [r12], rax ; push copy +} +; + +# : swap ( x1 x2 -- x2 x1 ) +:asm swap { + mov rax, [r12] ; get top + mov rbx, [r12 + 8] ; get second + mov [r12], rbx ; swap + mov [r12 + 8], rax +} +; + +# : rot ( x1 x2 x3 -- x2 x3 x1 ) +:asm rot { + mov rax, [r12] ; x3 (top) + mov rbx, [r12 + 8] ; x2 + mov rcx, [r12 + 16] ; x1 (bottom) + mov [r12], rcx ; new top = x1 + mov [r12 + 8], rax ; new 2nd = x3 + mov [r12 + 16], rbx ; new 3rd = x2 +} +; + +# : -rot ( x1 x2 x3 -- x3 x1 x2 ) +:asm -rot { + mov rax, [r12] ; x3 (top) + mov rbx, [r12 + 8] ; x2 + mov rcx, [r12 + 16] ; x1 (bottom) + mov [r12], rbx ; new top = x2 + mov [r12 + 8], rcx ; new 2nd = x1 + mov [r12 + 16], rax ; new 3rd = x3 +} +; + +# : nip ( x1 x2 -- x2 ) +:asm nip { + mov rax, [r12] ; get top + add r12, 8 ; drop lower + mov [r12], rax ; keep original top +} +; + +# : tuck ( x1 x2 -- x2 x1 x2 ) +:asm tuck { + mov rax, [r12] ; x2 (top) + mov rbx, [r12 + 8] ; x1 + sub r12, 8 ; make room + mov [r12], rax ; x2 + mov [r12 + 8], rbx ; x1 + mov [r12 + 16], rax ; x2 +} +; + +# : 2dup ( x1 x2 -- x1 x2 x1 x2 ) +:asm 2dup { + mov rax, [r12] ; b (top) + mov rbx, [r12 + 8] ; a + sub r12, 8 ; make room + mov [r12], rbx ; push a + sub r12, 8 ; make room + mov [r12], rax ; push b +} +; + +# : 2drop ( x1 x2 -- ) +:asm 2drop { + add r12, 16 ; remove two items +} +; + +# : 2swap ( x1 x2 x3 x4 -- x3 x4 x1 x2 ) +:asm 2swap { + mov rax, [r12] ; d (top) + mov rbx, [r12 + 8] ; c + mov rcx, [r12 + 16] ; b + mov rdx, [r12 + 24] ; a (bottom) + mov [r12], rcx ; new top = b + mov [r12 + 8], rdx ; new 2nd = a + mov [r12 + 16], rax ; new 3rd = d + mov [r12 + 24], rbx ; new 4th = c +} +; + +# : 2over ( x1 x2 x3 x4 -- x3 x4 x1 x2 x3 x4 ) +:asm 2over { + mov rax, [r12 + 16] ; b + mov rbx, [r12 + 24] ; a + sub r12, 8 ; make room + mov [r12], rbx ; push a + sub r12, 8 ; make room + mov [r12], rax ; push b +} +; + +# : + ( x1 x2 -- x3 ) +:asm + { + mov rax, [r12] ; get top + add r12, 8 ; pop + add qword [r12], rax ; add to next +} +; + +# : - ( x1 x2 -- x3 ) +:asm - { + mov rax, [r12] ; get top + add r12, 8 ; pop + sub qword [r12], rax ; subtract from next +} +; + +# : * ( x1 x2 -- x3 ) +:asm * { + mov rax, [r12] ; get top + add r12, 8 ; pop + imul qword [r12] ; multiply + mov [r12], rax ; store result +} +; + +# : / ( x1 x2 -- x3 ) +:asm / { + mov rbx, [r12] ; divisor + add r12, 8 ; pop + mov rax, [r12] ; dividend + cqo ; sign-extend + idiv rbx ; divide + mov [r12], rax ; store quotient +} +; + +# : % ( x1 x2 -- x3 ) +:asm % { + mov rbx, [r12] ; divisor + add r12, 8 ; pop + mov rax, [r12] ; dividend + cqo ; sign-extend + idiv rbx ; divide + mov [r12], rdx ; store remainder +} +; + +# : == ( x1 x2 -- flag ) +:asm == { + mov rax, [r12] ; get top + add r12, 8 ; pop + mov rbx, [r12] ; get next + cmp rbx, rax ; compare + mov rbx, 0 + sete bl ; set if equal + mov [r12], rbx ; store flag +} +; + +# : != ( x1 x2 -- flag ) +:asm != { + mov rax, [r12] ; get top + add r12, 8 ; pop + mov rbx, [r12] ; get next + cmp rbx, rax ; compare + mov rbx, 0 + setne bl ; set if not equal + mov [r12], rbx ; store flag +} +; + +# : < ( x1 x2 -- flag ) +:asm < { + mov rax, [r12] ; get top + add r12, 8 ; pop + mov rbx, [r12] ; get next + cmp rbx, rax ; compare + mov rbx, 0 + setl bl ; set if less + mov [r12], rbx ; store flag +} +; + +# : > ( x1 x2 -- flag ) +:asm > { + mov rax, [r12] ; get top + add r12, 8 ; pop + mov rbx, [r12] ; get next + cmp rbx, rax ; compare + mov rbx, 0 + setg bl ; set if greater + mov [r12], rbx ; store flag +} +; + +# : <= ( x1 x2 -- flag ) +:asm <= { + mov rax, [r12] ; get top + add r12, 8 ; pop + mov rbx, [r12] ; get next + cmp rbx, rax ; compare + mov rbx, 0 + setle bl ; set if less or equal + mov [r12], rbx ; store flag +} +; + +# : >= ( x1 x2 -- flag ) +:asm >= { + mov rax, [r12] ; get top + add r12, 8 ; pop + mov rbx, [r12] ; get next + cmp rbx, rax ; compare + mov rbx, 0 + setge bl ; set if greater or equal + mov [r12], rbx ; store flag +} +; + +# : @ ( addr -- x ) +:asm @ { + mov rax, [r12] ; get address + mov rax, [rax] ; load value + mov [r12], rax ; store on stack +} +; + +# : ! ( x addr -- ) +:asm ! { + mov rax, [r12] ; get address + add r12, 8 ; pop address + mov rbx, [r12] ; get value + mov [rax], rbx ; store value at address + add r12, 8 ; pop value +} +; + +# : mmap ( addr len prot flags fd offset -- addr ) +:asm mmap { + mov r9, [r12] ; offset + add r12, 8 + mov r8, [r12] ; fd + add r12, 8 + mov r10, [r12] ; flags + add r12, 8 + mov rdx, [r12] ; prot + add r12, 8 + mov rsi, [r12] ; len + add r12, 8 + mov rdi, [r12] ; addr + mov rax, 9 ; syscall: mmap + syscall + sub r12, 8 + mov [r12], rax ; return addr +} +; + +# : munmap ( addr len -- res ) +:asm munmap { + mov rsi, [r12] ; len + add r12, 8 + mov rdi, [r12] ; addr + add r12, 8 + mov rax, 11 ; syscall: munmap + syscall + sub r12, 8 + mov [r12], rax ; return value +} +; + +# : exit ( code -- ) +:asm exit { + mov rdi, [r12] ; exit code + add r12, 8 + mov rax, 60 ; syscall: exit + syscall +} +; + +# : and ( x1 x2 -- flag ) +:asm and { + mov rax, [r12] ; get top + add r12, 8 ; pop + mov rbx, [r12] ; get next + test rax, rax + setz cl + test rbx, rbx + setz dl + movzx rcx, cl + movzx rdx, dl + and rcx, rdx ; logical and + mov [r12], rcx ; store flag +} +; + +# : or ( x1 x2 -- flag ) +:asm or { + mov rax, [r12] ; get top + add r12, 8 ; pop + mov rbx, [r12] ; get next + test rax, rax + setz cl + test rbx, rbx + setz dl + movzx rcx, cl + movzx rdx, dl + or rcx, rdx ; logical or + mov [r12], rcx ; store flag +} +; + +# : not ( x -- flag ) +:asm not { + mov rax, [r12] ; get value + test rax, rax + setz al ; set if zero + movzx rax, al + mov [r12], rax ; store flag +} +; + +# : >r ( x -- ) +:asm >r { + mov rax, [r12] ; get value + add r12, 8 ; pop + sub r13, 8 ; make room on return stack + mov [r13], rax ; push to return stack +} +; + +# : r> ( -- x ) +:asm r> { + mov rax, [r13] ; get value from return stack + add r13, 8 ; pop return stack + sub r12, 8 ; make room on data stack + mov [r12], rax ; push to data stack +} +; + +# : rdrop ( -- ) +:asm rdrop { + add r13, 8 ; pop return stack +} +; + +# : pick ( n -- x ) +:asm pick { + mov rcx, [r12] ; get index + add r12, 8 ; pop + mov rax, [r12 + rcx * 8] ; get value at index + sub r12, 8 ; make room + mov [r12], rax ; push value +} +; + +# : rpick ( n -- x ) +:asm rpick { + mov rcx, [r12] ; get index + add r12, 8 ; pop + mov rax, [r13 + rcx * 8] ; get value from return stack + sub r12, 8 ; make room + mov [r12], rax ; push value +} +; + +# : neg ( x -- -x ) +:asm neg { + mov rax, [r12] ; get value + neg rax ; arithmetic negation + mov [r12], rax ; store result +} +; + +# : abs ( x -- |x| ) +:asm abs { + mov rax, [r12] ; get value + test rax, rax ; check sign + jge .done ; keep if non-negative + neg rax ; flip sign when negative +.done: + mov [r12], rax ; store result +} +; + +# : bitnot ( 0|1 -- 1|0 ) +:asm bitnot { + mov rax, [r12] ; get value + xor rax, 1 ; flip lowest bit + mov [r12], rax ; store result +} +; diff --git a/stdlib/stdlib.sl b/stdlib/stdlib.sl index 1bd11b1..27eff06 100644 --- a/stdlib/stdlib.sl +++ b/stdlib/stdlib.sl @@ -1,494 +1,4 @@ -# Reserve 64 bytes in .bss -# persistent: resb 64 -# push the addr of it - -:asm mem { - lea rax, [rel persistent] - sub r12, 8 - mov [r12], rax -} -; - -# : strlen ( addr -- len ) -# for null terminated strings - -:asm strlen { - mov rsi, [r12] ; address - xor rcx, rcx ; length counter -.strlen_loop: - mov al, [rsi] - test al, al - jz .strlen_done - inc rcx - inc rsi - jmp .strlen_loop -.strlen_done: - mov rax, rcx - mov [r12], rax ; store length on stack - ret -} -; - -# : argc ( -- n ) -:asm argc { - extern argc - mov rax, [rel argc] - sub r12, 8 - mov [r12], rax - ret -} -; - -# : argv ( -- ptr ) -:asm argv { - extern argv - mov rax, [rel argv] - sub r12, 8 - mov [r12], rax - ret -} -; - -# : argv@ ( n -- ptr ) -:asm argv@ { - extern argv - mov rbx, [r12] ; n - mov rax, [rel argv] - mov rax, [rax + rbx*8] - mov [r12], rax - ret -} -; - -# : c@ ( addr -- byte ) -:asm c@ { - mov rax, [r12] ; get address from stack - movzx rax, byte [rax] ; load byte at address, zero-extend to rax - mov [r12], rax ; store result back on stack - ret -} -; - -# : c! ( byte addr -- ) -:asm c! { - mov rax, [r12] ; get address from stack - add r12, 8 ; pop address - mov rbx, [r12] ; get byte value - mov [rbx], al ; store byte at address - ret -} -; - -# : r@ ( -- x ) -:asm r@ { - mov rax, [r13] ; get value from return stack - sub r12, 8 ; make room on data stack - mov [r12], rax ; push value to data stack - ret -} -; - -# : dup ( x -- x x ) -:asm dup { - mov rax, [r12] ; get top of stack - sub r12, 8 ; make room - mov [r12], rax ; duplicate value -} -; - -# : drop ( x -- ) -:asm drop { - add r12, 8 ; remove top of stack -} -; - -# : over ( x1 x2 -- x1 x2 x1 ) -:asm over { - mov rax, [r12 + 8] ; get second item - sub r12, 8 ; make room - mov [r12], rax ; push copy -} -; - -# : swap ( x1 x2 -- x2 x1 ) -:asm swap { - mov rax, [r12] ; get top - mov rbx, [r12 + 8] ; get second - mov [r12], rbx ; swap - mov [r12 + 8], rax -} -; - -# : rot ( x1 x2 x3 -- x2 x3 x1 ) -:asm rot { - mov rax, [r12] ; x3 (top) - mov rbx, [r12 + 8] ; x2 - mov rcx, [r12 + 16] ; x1 (bottom) - mov [r12], rcx ; new top = x1 - mov [r12 + 8], rax ; new 2nd = x3 - mov [r12 + 16], rbx ; new 3rd = x2 -} -; - -# : -rot ( x1 x2 x3 -- x3 x1 x2 ) -:asm -rot { - mov rax, [r12] ; x3 (top) - mov rbx, [r12 + 8] ; x2 - mov rcx, [r12 + 16] ; x1 (bottom) - mov [r12], rbx ; new top = x2 - mov [r12 + 8], rcx ; new 2nd = x1 - mov [r12 + 16], rax ; new 3rd = x3 -} -; - -# : nip ( x1 x2 -- x2 ) -:asm nip { - mov rax, [r12] ; get top - add r12, 8 ; drop lower - mov [r12], rax ; keep original top -} -; - -# : tuck ( x1 x2 -- x2 x1 x2 ) -:asm tuck { - mov rax, [r12] ; x2 (top) - mov rbx, [r12 + 8] ; x1 - sub r12, 8 ; make room - mov [r12], rax ; x2 - mov [r12 + 8], rbx ; x1 - mov [r12 + 16], rax ; x2 -} -; - -# : 2dup ( x1 x2 -- x1 x2 x1 x2 ) -:asm 2dup { - mov rax, [r12] ; b (top) - mov rbx, [r12 + 8] ; a - sub r12, 8 ; make room - mov [r12], rbx ; push a - sub r12, 8 ; make room - mov [r12], rax ; push b -} -; - -# : 2drop ( x1 x2 -- ) -:asm 2drop { - add r12, 16 ; remove two items -} -; - -# : 2swap ( x1 x2 x3 x4 -- x3 x4 x1 x2 ) -:asm 2swap { - mov rax, [r12] ; d (top) - mov rbx, [r12 + 8] ; c - mov rcx, [r12 + 16] ; b - mov rdx, [r12 + 24] ; a (bottom) - mov [r12], rcx ; new top = b - mov [r12 + 8], rdx ; new 2nd = a - mov [r12 + 16], rax ; new 3rd = d - mov [r12 + 24], rbx ; new 4th = c -} -; - -# : 2over ( x1 x2 x3 x4 -- x3 x4 x1 x2 x3 x4 ) -:asm 2over { - mov rax, [r12 + 16] ; b - mov rbx, [r12 + 24] ; a - sub r12, 8 ; make room - mov [r12], rbx ; push a - sub r12, 8 ; make room - mov [r12], rax ; push b -} -; - -# : + ( x1 x2 -- x3 ) -:asm + { - mov rax, [r12] ; get top - add r12, 8 ; pop - add qword [r12], rax ; add to next -} -; - -# : - ( x1 x2 -- x3 ) -:asm - { - mov rax, [r12] ; get top - add r12, 8 ; pop - sub qword [r12], rax ; subtract from next -} -; - -# : * ( x1 x2 -- x3 ) -:asm * { - mov rax, [r12] ; get top - add r12, 8 ; pop - imul qword [r12] ; multiply - mov [r12], rax ; store result -} -; - -# : / ( x1 x2 -- x3 ) -:asm / { - mov rbx, [r12] ; divisor - add r12, 8 ; pop - mov rax, [r12] ; dividend - cqo ; sign-extend - idiv rbx ; divide - mov [r12], rax ; store quotient -} -; - -# : % ( x1 x2 -- x3 ) -:asm % { - mov rbx, [r12] ; divisor - add r12, 8 ; pop - mov rax, [r12] ; dividend - cqo ; sign-extend - idiv rbx ; divide - mov [r12], rdx ; store remainder -} -; - -# : == ( x1 x2 -- flag ) -:asm == { - mov rax, [r12] ; get top - add r12, 8 ; pop - mov rbx, [r12] ; get next - cmp rbx, rax ; compare - mov rbx, 0 - sete bl ; set if equal - mov [r12], rbx ; store flag -} -; - -# : != ( x1 x2 -- flag ) -:asm != { - mov rax, [r12] ; get top - add r12, 8 ; pop - mov rbx, [r12] ; get next - cmp rbx, rax ; compare - mov rbx, 0 - setne bl ; set if not equal - mov [r12], rbx ; store flag -} -; - -# : < ( x1 x2 -- flag ) -:asm < { - mov rax, [r12] ; get top - add r12, 8 ; pop - mov rbx, [r12] ; get next - cmp rbx, rax ; compare - mov rbx, 0 - setl bl ; set if less - mov [r12], rbx ; store flag -} -; - -# : > ( x1 x2 -- flag ) -:asm > { - mov rax, [r12] ; get top - add r12, 8 ; pop - mov rbx, [r12] ; get next - cmp rbx, rax ; compare - mov rbx, 0 - setg bl ; set if greater - mov [r12], rbx ; store flag -} -; - -# : <= ( x1 x2 -- flag ) -:asm <= { - mov rax, [r12] ; get top - add r12, 8 ; pop - mov rbx, [r12] ; get next - cmp rbx, rax ; compare - mov rbx, 0 - setle bl ; set if less or equal - mov [r12], rbx ; store flag -} -; - -# : >= ( x1 x2 -- flag ) -:asm >= { - mov rax, [r12] ; get top - add r12, 8 ; pop - mov rbx, [r12] ; get next - cmp rbx, rax ; compare - mov rbx, 0 - setge bl ; set if greater or equal - mov [r12], rbx ; store flag -} -; - -# : @ ( addr -- x ) -:asm @ { - mov rax, [r12] ; get address - mov rax, [rax] ; load value - mov [r12], rax ; store on stack -} -; - -# : ! ( x addr -- ) -:asm ! { - mov rax, [r12] ; get address - add r12, 8 ; pop address - mov rbx, [r12] ; get value - mov [rax], rbx ; store value at address - add r12, 8 ; pop value -} -; - -# : mmap ( addr len prot flags fd offset -- addr ) -:asm mmap { - mov r9, [r12] ; offset - add r12, 8 - mov r8, [r12] ; fd - add r12, 8 - mov r10, [r12] ; flags - add r12, 8 - mov rdx, [r12] ; prot - add r12, 8 - mov rsi, [r12] ; len - add r12, 8 - mov rdi, [r12] ; addr - mov rax, 9 ; syscall: mmap - syscall - sub r12, 8 - mov [r12], rax ; return addr -} -; - -# : munmap ( addr len -- res ) -:asm munmap { - mov rsi, [r12] ; len - add r12, 8 - mov rdi, [r12] ; addr - add r12, 8 - mov rax, 11 ; syscall: munmap - syscall - sub r12, 8 - mov [r12], rax ; return value -} -; - -# : exit ( code -- ) -:asm exit { - mov rdi, [r12] ; exit code - add r12, 8 - mov rax, 60 ; syscall: exit - syscall -} -; - -# : and ( x1 x2 -- flag ) -:asm and { - mov rax, [r12] ; get top - add r12, 8 ; pop - mov rbx, [r12] ; get next - test rax, rax - setz cl - test rbx, rbx - setz dl - movzx rcx, cl - movzx rdx, dl - and rcx, rdx ; logical and - mov [r12], rcx ; store flag -} -; - -# : or ( x1 x2 -- flag ) -:asm or { - mov rax, [r12] ; get top - add r12, 8 ; pop - mov rbx, [r12] ; get next - test rax, rax - setz cl - test rbx, rbx - setz dl - movzx rcx, cl - movzx rdx, dl - or rcx, rdx ; logical or - mov [r12], rcx ; store flag -} -; - -# : not ( x -- flag ) -:asm not { - mov rax, [r12] ; get value - test rax, rax - setz al ; set if zero - movzx rax, al - mov [r12], rax ; store flag -} -; - -# : >r ( x -- ) -:asm >r { - mov rax, [r12] ; get value - add r12, 8 ; pop - sub r13, 8 ; make room on return stack - mov [r13], rax ; push to return stack -} -; - -# : r> ( -- x ) -:asm r> { - mov rax, [r13] ; get value from return stack - add r13, 8 ; pop return stack - sub r12, 8 ; make room on data stack - mov [r12], rax ; push to data stack -} -; - -# : rdrop ( -- ) -:asm rdrop { - add r13, 8 ; pop return stack -} -; - -# : pick ( n -- x ) -:asm pick { - mov rcx, [r12] ; get index - add r12, 8 ; pop - mov rax, [r12 + rcx * 8] ; get value at index - sub r12, 8 ; make room - mov [r12], rax ; push value -} -; - -# : rpick ( n -- x ) -:asm rpick { - mov rcx, [r12] ; get index - add r12, 8 ; pop - mov rax, [r13 + rcx * 8] ; get value from return stack - sub r12, 8 ; make room - mov [r12], rax ; push value -} -; - -# : neg ( x -- -x ) -:asm neg { - mov rax, [r12] ; get value - neg rax ; arithmetic negation - mov [r12], rax ; store result -} -; - -# : abs ( x -- |x| ) -:asm abs { - mov rax, [r12] ; get value - test rax, rax ; check sign - jge .done ; keep if non-negative - neg rax ; flip sign when negative -.done: - mov [r12], rax ; store result -} -; - -# : bitnot ( 0|1 -- 1|0 ) -:asm bitnot { - mov rax, [r12] ; get value - xor rax, 1 ; flip lowest bit - mov [r12], rax ; store result -} -; +import core.sl +import mem.sl +import io.sl +import utils.sl \ No newline at end of file diff --git a/typeconversion.sl b/stdlib/utils.sl similarity index 55% rename from typeconversion.sl rename to stdlib/utils.sl index cc639eb..cdf6f3e 100644 --- a/typeconversion.sl +++ b/stdlib/utils.sl @@ -1,6 +1,55 @@ -import stdlib.sl -import io.sl -import mem.sl + +# : strcmp ( addr len addr len -- bool addr len addr len) +word strcmp + 3 pick 2 pick @ swap @ == +end + +# : strconcat ( addr len addr len -- addr len) +word strconcat + 0 pick 3 pick + + dup + >r >r >r >r >r >r + 5 rpick + alloc + r> r> + dup >r + memcpy + swap + r> dup -rot + + r> r> + memcpy + swap + 3 pick + - + swap + drop + swap + 0 rpick + nip + rot + drop + rdrop rdrop rdrop +end + +# : strlen ( addr -- len ) +# for null terminated strings + +:asm strlen { + mov rsi, [r12] ; address + xor rcx, rcx ; length counter +.strlen_loop: + mov al, [rsi] + test al, al + jz .strlen_done + inc rcx + inc rsi + jmp .strlen_loop +.strlen_done: + mov rax, rcx + mov [r12], rax ; store length on stack + ret +} +; 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) 0 swap # place accumulator below length @@ -12,7 +61,7 @@ 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 word toint swap over 0 swap @@ -35,6 +84,7 @@ word toint rdrop end +# : count_digits ( int -- int) returns the amount of digits of an int word count_digits 0 swap @@ -44,6 +94,7 @@ word count_digits drop end +# : tostr ( int -- addr len ) the function allocates a buffer to remember to free it word tostr dup count_digits @@ -74,12 +125,4 @@ word tostr over for rot drop end drop -end - -word main - "1234" toint 1 + dup puti cr - tostr - 2dup - puts - free -end +end \ No newline at end of file diff --git a/strcmp.sl b/strcmp.sl deleted file mode 100644 index ff0e481..0000000 --- a/strcmp.sl +++ /dev/null @@ -1,14 +0,0 @@ -import stdlib/stdlib.sl -import stdlib/io.sl - -word strcmp - 3 pick 2 pick @ swap @ == -end - -word main - "g" "g" - strcmp - puti cr - puts - puts -end \ No newline at end of file diff --git a/strconcat.sl b/strconcat.sl deleted file mode 100644 index b52dc34..0000000 --- a/strconcat.sl +++ /dev/null @@ -1,35 +0,0 @@ -import stdlib/stdlib.sl -import stdlib/mem.sl -import stdlib/io.sl - -word strconcat - 0 pick 3 pick + - dup - >r >r >r >r >r >r - 5 rpick - alloc - r> r> - dup >r - memcpy - swap - r> dup -rot + - r> r> - memcpy - swap - 3 pick - - - swap - drop - swap - 0 rpick - nip - rot - drop - rdrop rdrop rdrop -end - -word main - "hello world hello world hello " "world hello world hello world" - strconcat - puts -end diff --git a/tests/call_syntax_parens.expected b/tests/call_syntax_parens.expected deleted file mode 100644 index 72350c3..0000000 --- a/tests/call_syntax_parens.expected +++ /dev/null @@ -1,2 +0,0 @@ -42 -3 diff --git a/tests/call_syntax_parens.sl b/tests/call_syntax_parens.sl deleted file mode 100644 index 6f9b5ae..0000000 --- a/tests/call_syntax_parens.sl +++ /dev/null @@ -1,16 +0,0 @@ -import ../stdlib/stdlib.sl -import ../stdlib/io.sl -import ../fn.sl - -word main - 2 40 + - puti cr - extend-syntax - foo(1, 2) - puti cr - 0 -end - -fn foo(int a, int b){ - return a + b; -} diff --git a/tests/call_syntax_parens.test b/tests/call_syntax_parens.test deleted file mode 100644 index d5cb6e7..0000000 --- a/tests/call_syntax_parens.test +++ /dev/null @@ -1 +0,0 @@ -python main.py tests/call_syntax_parens.sl -o /tmp/call_syntax_parens > /dev/null && /tmp/call_syntax_parens diff --git a/tests/integration_core.expected b/tests/integration_core.expected index 430631c..a0eb90a 100644 --- a/tests/integration_core.expected +++ b/tests/integration_core.expected @@ -30,4 +30,3 @@ 111 222 16 -70 diff --git a/tests/integration_core.sl b/tests/integration_core.sl index 46a6ea0..c5a894b 100644 --- a/tests/integration_core.sl +++ b/tests/integration_core.sl @@ -1,6 +1,5 @@ import ../stdlib/stdlib.sl import ../stdlib/io.sl -import ../fn.sl :asm mem-slot { lea rax, [rel print_buf] @@ -33,12 +32,6 @@ struct: Point field y 8 ;struct -extend-syntax - -fn fancy_add(int a, int b){ - return (a + b) * b; -} - word test-add 5 7 + puti cr end @@ -161,13 +154,6 @@ word test-cmp 4 5 >= puti cr end -word test-c-fn - 3 - 7 - fancy_add() - puti cr -end - word main test-add test-sub @@ -186,6 +172,5 @@ word main test-for-zero test-cmp test-struct - test-c-fn 0 end diff --git a/tests/str.expected b/tests/str.expected new file mode 100644 index 0000000..2c9891f --- /dev/null +++ b/tests/str.expected @@ -0,0 +1,4 @@ +1 +g +g +hello world hello world hello world hello world hello world diff --git a/tests/str.sl b/tests/str.sl new file mode 100644 index 0000000..4d2483a --- /dev/null +++ b/tests/str.sl @@ -0,0 +1,15 @@ +import stdlib.sl + +word main + "g" "g" + strcmp + puti cr + puts + puts + + "hello world hello world hello " "world hello world hello world" + strconcat + 2dup + puts + free +end diff --git a/tests/str.test b/tests/str.test new file mode 100644 index 0000000..92c8e0a --- /dev/null +++ b/tests/str.test @@ -0,0 +1 @@ +python main.py tests/str.sl -o /tmp/str > /dev/null && /tmp/str \ No newline at end of file diff --git a/tests/typeconversion.expected b/tests/typeconversion.expected new file mode 100644 index 0000000..a06ca4f --- /dev/null +++ b/tests/typeconversion.expected @@ -0,0 +1,2 @@ +1235 +1235 diff --git a/tests/typeconversion.sl b/tests/typeconversion.sl new file mode 100644 index 0000000..a29ccbd --- /dev/null +++ b/tests/typeconversion.sl @@ -0,0 +1,9 @@ +import stdlib.sl + +word main + "1234" toint 1 + dup puti cr + tostr + 2dup + puts + free +end diff --git a/tests/typeconversion.test b/tests/typeconversion.test new file mode 100644 index 0000000..8688996 --- /dev/null +++ b/tests/typeconversion.test @@ -0,0 +1 @@ +python main.py tests/typeconversion.sl -o /tmp/typeconversion > /dev/null && /tmp/typeconversion diff --git a/tests/word_syntax.expected b/tests/word_syntax.expected deleted file mode 100644 index 7f8f011..0000000 --- a/tests/word_syntax.expected +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/tests/word_syntax.sl b/tests/word_syntax.sl deleted file mode 100644 index b1566ba..0000000 --- a/tests/word_syntax.sl +++ /dev/null @@ -1,12 +0,0 @@ -import ../stdlib/stdlib.sl -import ../stdlib/io.sl - -word add-two - + -end - -word main - 3 4 add-two - puti cr - 0 -end diff --git a/tests/word_syntax.test b/tests/word_syntax.test deleted file mode 100644 index 1599bd9..0000000 --- a/tests/word_syntax.test +++ /dev/null @@ -1 +0,0 @@ -python main.py tests/word_syntax.sl -o /tmp/word_syntax > /dev/null && /tmp/word_syntax