quite a few fixes, overall repo cleanup and some restructurization in the stdlib

This commit is contained in:
IgorCielniak
2026-01-12 19:03:49 +01:00
parent 3f87f12cf1
commit 47a45c050e
25 changed files with 582 additions and 648 deletions

View File

@@ -1,5 +1,4 @@
import stdlib/stdlib.sl import stdlib/stdlib.sl
import stdlib/io.sl
word main word main
0 argc for 0 argc for

View File

@@ -1,13 +1,22 @@
import stdlib/io.sl import stdlib.sl
import float.sl
# C-style externs (auto ABI handling) # C-style externs (auto ABI handling)
extern long labs(long n) extern long labs(long n)
extern void exit(int status) extern void exit(int status)
extern double atan2(double y, double x)
word main word main
# Test C-style extern with implicit ABI handling # Test C-style extern with implicit ABI handling
-10 labs puti cr -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 # Test extern void
0 exit 0 exit
end end

17
f.sl
View File

@@ -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

View File

@@ -8,9 +8,14 @@ fn foo(int a, int b){
return a b +; return a b +;
} }
fn bar(int a, int b){
return a + b;
}
word main word main
extend-syntax extend-syntax
foo(3, 2) foo(3, 2)
puti cr puti cr
0 bar(1, 2)
puti cr
end end

7
gg.sl
View File

@@ -1,7 +0,0 @@
import stdlib/io.sl
extern long labs(long n)
word main
-3 labs puti
end

16
main.sl
View File

@@ -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;
}

474
stdlib/core.sl Normal file
View File

@@ -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
}
;

View File

@@ -1,494 +1,4 @@
# Reserve 64 bytes in .bss import core.sl
# persistent: resb 64 import mem.sl
# push the addr of it import io.sl
import utils.sl
: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
}
;

View File

@@ -1,6 +1,55 @@
import stdlib.sl
import io.sl # : strcmp ( addr len addr len -- bool addr len addr len)
import mem.sl 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) 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 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
end end
# : toint (addr len -- int ) converts a string to an int
word toint word toint
swap swap
over 0 swap over 0 swap
@@ -35,6 +84,7 @@ word toint
rdrop rdrop
end end
# : count_digits ( int -- int) returns the amount of digits of an int
word count_digits word count_digits
0 0
swap swap
@@ -44,6 +94,7 @@ word count_digits
drop drop
end end
# : tostr ( int -- addr len ) the function allocates a buffer to remember to free it
word tostr word tostr
dup dup
count_digits count_digits
@@ -75,11 +126,3 @@ word tostr
rot drop rot drop
end drop end drop
end end
word main
"1234" toint 1 + dup puti cr
tostr
2dup
puts
free
end

View File

@@ -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

View File

@@ -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

View File

@@ -1,2 +0,0 @@
42
3

View File

@@ -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;
}

View File

@@ -1 +0,0 @@
python main.py tests/call_syntax_parens.sl -o /tmp/call_syntax_parens > /dev/null && /tmp/call_syntax_parens

View File

@@ -30,4 +30,3 @@
111 111
222 222
16 16
70

View File

@@ -1,6 +1,5 @@
import ../stdlib/stdlib.sl import ../stdlib/stdlib.sl
import ../stdlib/io.sl import ../stdlib/io.sl
import ../fn.sl
:asm mem-slot { :asm mem-slot {
lea rax, [rel print_buf] lea rax, [rel print_buf]
@@ -33,12 +32,6 @@ struct: Point
field y 8 field y 8
;struct ;struct
extend-syntax
fn fancy_add(int a, int b){
return (a + b) * b;
}
word test-add word test-add
5 7 + puti cr 5 7 + puti cr
end end
@@ -161,13 +154,6 @@ word test-cmp
4 5 >= puti cr 4 5 >= puti cr
end end
word test-c-fn
3
7
fancy_add()
puti cr
end
word main word main
test-add test-add
test-sub test-sub
@@ -186,6 +172,5 @@ word main
test-for-zero test-for-zero
test-cmp test-cmp
test-struct test-struct
test-c-fn
0 0
end end

4
tests/str.expected Normal file
View File

@@ -0,0 +1,4 @@
1
g
g
hello world hello world hello world hello world hello world

15
tests/str.sl Normal file
View File

@@ -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

1
tests/str.test Normal file
View File

@@ -0,0 +1 @@
python main.py tests/str.sl -o /tmp/str > /dev/null && /tmp/str

View File

@@ -0,0 +1,2 @@
1235
1235

9
tests/typeconversion.sl Normal file
View File

@@ -0,0 +1,9 @@
import stdlib.sl
word main
"1234" toint 1 + dup puti cr
tostr
2dup
puts
free
end

View File

@@ -0,0 +1 @@
python main.py tests/typeconversion.sl -o /tmp/typeconversion > /dev/null && /tmp/typeconversion

View File

@@ -1 +0,0 @@
7

View File

@@ -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

View File

@@ -1 +0,0 @@
python main.py tests/word_syntax.sl -o /tmp/word_syntax > /dev/null && /tmp/word_syntax