diff --git a/main.py b/main.py index c99c16a..bcf8f90 100644 --- a/main.py +++ b/main.py @@ -2290,18 +2290,18 @@ class Assembler: "%define RSTK_BYTES 65536", "%define PRINT_BUF_BYTES 128", "global _start", - "global argc", - "global argv", + "global sys_argc", + "global sys_argv", "section .data", - "argc: dq 0", - "argv: dq 0", + "sys_argc: dq 0", + "sys_argv: dq 0", "section .text", "_start:", " ; Linux x86-64 startup: argc/argv from stack", " mov rdi, [rsp]", # argc " lea rsi, [rsp+8]", # argv - " mov [rel argc], rdi", - " mov [rel argv], rsi", + " mov [rel sys_argc], rdi", + " mov [rel sys_argv], rsi", " ; initialize data/return stack pointers", " lea r12, [rel dstack_top]", " mov r15, r12", @@ -2480,6 +2480,7 @@ def macro_with(ctx: MacroContext) -> Optional[List[Op]]: for name in reversed(names): helper = helper_for[name] emitted.append(helper) + emitted.append("swap") emitted.append("!") i = 0 @@ -2491,6 +2492,7 @@ def macro_with(ctx: MacroContext) -> Optional[List[Op]]: next_tok = body[i + 1] if i + 1 < len(body) else None if next_tok is not None and next_tok.lexeme == "!": emitted.append(helper) + emitted.append("swap") emitted.append("!") i += 2 continue @@ -3210,7 +3212,7 @@ def macro_struct_begin(ctx: MacroContext) -> Optional[List[Op]]: generated, name_token, f"{struct_name}.{field.name}!", - [offset_word, "+", "!"], + ["swap", offset_word, "+", "swap", "!"], ) parser.tokens[parser.pos:parser.pos] = generated diff --git a/nob.sl b/nob.sl index d678f45..46a5a80 100644 --- a/nob.sl +++ b/nob.sl @@ -31,25 +31,20 @@ word sh 0 c! + mem "/bin/sh" drop - 0 - mem + ! + mem 8 + "-c" drop - 8 - mem + ! + mem 16 + 0 rpick - 16 - mem + ! + mem 24 + 0 - 24 - mem + ! + mem 32 + 0 - 32 - mem + ! syscall.fork diff --git a/stdlib/core.sl b/stdlib/core.sl index a405e62..4bd173b 100644 --- a/stdlib/core.sl +++ b/stdlib/core.sl @@ -11,8 +11,8 @@ # : argc ( -- n ) :asm argc { - extern argc - mov rax, [rel argc] + extern sys_argc + mov rax, [rel sys_argc] sub r12, 8 mov [r12], rax ret @@ -21,8 +21,8 @@ # : argv ( -- ptr ) :asm argv { - extern argv - mov rax, [rel argv] + extern sys_argv + mov rax, [rel sys_argv] sub r12, 8 mov [r12], rax ret @@ -31,9 +31,9 @@ # : argv@ ( n -- ptr ) :asm argv@ { - extern argv + extern sys_argv mov rbx, [r12] ; n - mov rax, [rel argv] + mov rax, [rel sys_argv] mov rax, [rax + rbx*8] mov [r12], rax ret @@ -54,6 +54,7 @@ mov rax, [r12] ; get address from stack add r12, 8 ; pop address mov rbx, [r12] ; get byte value + add r12, 8 mov [rbx], al ; store byte at address ret } @@ -310,11 +311,11 @@ # : ! ( 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 + mov rax, [r12] ; get value (TOS) add r12, 8 ; pop value + mov rbx, [r12] ; get addr (NOS) + add r12, 8 ; pop addr + mov [rbx], rax ; store value at address } ; diff --git a/stdlib/mem.sl b/stdlib/mem.sl index a26d28e..9091258 100644 --- a/stdlib/mem.sl +++ b/stdlib/mem.sl @@ -8,6 +8,7 @@ word alloc -1 # fd 0 # offset mmap + swap drop end word free @@ -21,7 +22,6 @@ word memcpy #(dst_addr src_addr len -- dst_addr len) dup c@ 3 pick swap c! - drop swap for 1 + dup @@ -33,10 +33,30 @@ word memcpy #(dst_addr src_addr len -- dst_addr len) dup rot c! - drop swap end swap nip r> dup -rot - swap +end + +word memset #( value len addr -- ) + swap + 0 swap for + -rot swap 2 pick + 2dup swap ! 1 + -rot swap + end + 2drop drop +end + +word memdump #( len addr -- addr ) + for + dup c@ puti cr 1 + + end +end + +word realloc #( addr old_len new_len -- new_addr ) + 2 pick swap alloc + rot rot swap + memcpy + swap -rot free end \ No newline at end of file diff --git a/stdlib/utils.sl b/stdlib/utils.sl index 5adb3a2..1cc6695 100644 --- a/stdlib/utils.sl +++ b/stdlib/utils.sl @@ -99,7 +99,7 @@ word tostr dup count_digits 2dup >r alloc - nip swap rot swap + swap rot swap for dup 10 % swap 10 / end @@ -114,7 +114,6 @@ word tostr 2 + pick 3 pick rot + swap 48 + swap 1 - swap c! - drop swap 1 + swap diff --git a/tests/alloc.sl b/tests/alloc.sl index e34f791..1362e82 100644 --- a/tests/alloc.sl +++ b/tests/alloc.sl @@ -3,7 +3,7 @@ import ../stdlib/io.sl import ../stdlib/mem.sl word test-mem-alloc - 4096 alloc dup 1337 swap ! # allocate 4096 bytes, store 1337 at start + 4096 alloc dup 1337 ! # allocate 4096 bytes, store 1337 at start dup @ puti cr # print value at start 4096 free # free the memory end @@ -16,9 +16,9 @@ end word main 32 alloc # allocate 32 bytes (enough for a Point struct) dup - dup 111 swap Point.x! - dup 222 swap Point.y! - dup Point.x@ puti cr - Point.y@ puti cr + dup 111 Point.x! # store 111 at offset 0 (Point.x) + dup 222 Point.y! # store 222 at offset 8 (Point.y) + dup Point.x@ puti cr # print x + dup Point.y@ puti cr # print y 32 free # free the memory end diff --git a/tests/integration_core.sl b/tests/integration_core.sl index a6810bd..f5de7a8 100644 --- a/tests/integration_core.sl +++ b/tests/integration_core.sl @@ -66,7 +66,7 @@ end word test-store mem-slot dup - 123 swap ! + 123 ! @ puti cr end @@ -80,7 +80,7 @@ word test-mmap 0 # offset mmap dup - 1337 swap ! + 1337 ! dup @ puti cr 4096 munmap drop @@ -132,10 +132,10 @@ end word test-struct mem-slot - dup 111 swap Point.x! - dup 222 swap Point.y! - dup Point.x@ puti cr - Point.y@ puti cr + dup 111 ! # Point.x = 111 + dup 8 + 222 ! # Point.y = 222 + dup @ puti cr # print Point.x + dup 8 + @ puti cr # print Point.y Point.size puti cr end diff --git a/tests/mem.expected b/tests/mem.expected index 1f7a723..f995be8 100644 --- a/tests/mem.expected +++ b/tests/mem.expected @@ -1,2 +1,9 @@ 5 -6 \ No newline at end of file +6 +aaaaaaaaaa +111 +222 +111 +222 +333 +444 diff --git a/tests/mem.sl b/tests/mem.sl index b834e36..bad9859 100644 --- a/tests/mem.sl +++ b/tests/mem.sl @@ -1,9 +1,39 @@ import ../stdlib/stdlib.sl -import ../stdlib/io.sl word main - mem 5 swap ! - mem 8 + 6 swap ! + mem 5 ! + mem 8 + 6 ! mem @ puti cr mem 8 + @ puti cr + + 10 alloc + dup + 10 97 memset + 10 2dup puts + free + + + # Test realloc: allocate 16 bytes, fill with data, then grow to 32 bytes + 16 alloc + dup 111 ! # Store 111 at offset 0 + dup 8 + 222 ! # Store 222 at offset 8 + + # Realloc to 32 bytes + 16 32 realloc # ( addr old_len=16 new_len=32 ) -> ( new_addr ) + + # Verify old data is preserved + dup @ puti cr # Should print 111 + dup 8 + @ puti cr # Should print 222 + + # Write new data to the expanded region + dup 16 + 333 ! # Store 333 at offset 16 + dup 24 + 444 ! # Store 444 at offset 24 + + # Print all values to verify + dup @ puti cr # 111 + dup 8 + @ puti cr # 222 + dup 16 + @ puti cr # 333 + dup 24 + @ puti cr # 444 + + 32 free end