quite a few fixes, overall repo cleanup and some restructurization in the stdlib
This commit is contained in:
1
args.sl
1
args.sl
@@ -1,5 +1,4 @@
|
||||
import stdlib/stdlib.sl
|
||||
import stdlib/io.sl
|
||||
|
||||
word main
|
||||
0 argc for
|
||||
|
||||
11
c_extern.sl
11
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
|
||||
|
||||
17
f.sl
17
f.sl
@@ -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
|
||||
|
||||
@@ -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
|
||||
7
gg.sl
7
gg.sl
@@ -1,7 +0,0 @@
|
||||
import stdlib/io.sl
|
||||
|
||||
extern long labs(long n)
|
||||
|
||||
word main
|
||||
-3 labs puti
|
||||
end
|
||||
16
main.sl
16
main.sl
@@ -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
474
stdlib/core.sl
Normal 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
|
||||
}
|
||||
;
|
||||
498
stdlib/stdlib.sl
498
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
|
||||
@@ -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
|
||||
14
strcmp.sl
14
strcmp.sl
@@ -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
|
||||
35
strconcat.sl
35
strconcat.sl
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
42
|
||||
3
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
python main.py tests/call_syntax_parens.sl -o /tmp/call_syntax_parens > /dev/null && /tmp/call_syntax_parens
|
||||
@@ -30,4 +30,3 @@
|
||||
111
|
||||
222
|
||||
16
|
||||
70
|
||||
|
||||
@@ -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
|
||||
|
||||
4
tests/str.expected
Normal file
4
tests/str.expected
Normal file
@@ -0,0 +1,4 @@
|
||||
1
|
||||
g
|
||||
g
|
||||
hello world hello world hello world hello world hello world
|
||||
15
tests/str.sl
Normal file
15
tests/str.sl
Normal 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
1
tests/str.test
Normal file
@@ -0,0 +1 @@
|
||||
python main.py tests/str.sl -o /tmp/str > /dev/null && /tmp/str
|
||||
2
tests/typeconversion.expected
Normal file
2
tests/typeconversion.expected
Normal file
@@ -0,0 +1,2 @@
|
||||
1235
|
||||
1235
|
||||
9
tests/typeconversion.sl
Normal file
9
tests/typeconversion.sl
Normal file
@@ -0,0 +1,9 @@
|
||||
import stdlib.sl
|
||||
|
||||
word main
|
||||
"1234" toint 1 + dup puti cr
|
||||
tostr
|
||||
2dup
|
||||
puts
|
||||
free
|
||||
end
|
||||
1
tests/typeconversion.test
Normal file
1
tests/typeconversion.test
Normal file
@@ -0,0 +1 @@
|
||||
python main.py tests/typeconversion.sl -o /tmp/typeconversion > /dev/null && /tmp/typeconversion
|
||||
@@ -1 +0,0 @@
|
||||
7
|
||||
@@ -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
|
||||
@@ -1 +0,0 @@
|
||||
python main.py tests/word_syntax.sl -o /tmp/word_syntax > /dev/null && /tmp/word_syntax
|
||||
Reference in New Issue
Block a user