diff --git a/a.out b/a.out index 8bc6f17..723c48f 100755 Binary files a/a.out and b/a.out differ diff --git a/a.sl b/a.sl index 5ce78b8..9f3cb37 100644 --- a/a.sl +++ b/a.sl @@ -1,5 +1,5 @@ import stdlib.sl : main - "hello world" puts_str + "hello world" puts ; \ No newline at end of file diff --git a/build/a.asm b/build/a.asm index 26aed90..f676e86 100644 --- a/build/a.asm +++ b/build/a.asm @@ -19,6 +19,36 @@ _start: mov rax, 60 syscall word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end) + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret + +puts_print_int: mov rax, [r12] add r12, 8 mov rbx, rax @@ -65,25 +95,6 @@ puts_finish_digits: mov rsi, r9 syscall ret -word_puts_str: - ; expects (addr, len) on data stack - mov rdx, [r12] - add r12, 8 - mov rsi, [r12] - add r12, 8 - cmp rdx, 0 - je puts_str_write_newline - mov rax, 1 - mov rdi, 1 - syscall -puts_str_write_newline: - mov byte [rel print_buf], 10 - mov rax, 1 - mov rdi, 1 - lea rsi, [rel print_buf] - mov rdx, 1 - syscall - ret word_dup: mov rax, [r12] sub r12, 8 @@ -267,11 +278,13 @@ word_main: ; push 11 sub r12, 8 mov qword [r12], 11 - call word_puts_str + call word_puts ret section .data +data_start: str_0: db 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0 str_0_len equ 11 +data_end: section .bss align 16 dstack: resb DSTK_BYTES diff --git a/build/a.o b/build/a.o index 515fd45..fb71081 100644 Binary files a/build/a.o and b/build/a.o differ diff --git a/build/call_syntax_parens.asm b/build/call_syntax_parens.asm index 7df47c7..031a9dd 100644 --- a/build/call_syntax_parens.asm +++ b/build/call_syntax_parens.asm @@ -19,6 +19,36 @@ _start: mov rax, 60 syscall word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end) + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret + +puts_print_int: mov rax, [r12] add r12, 8 mov rbx, rax @@ -65,25 +95,6 @@ puts_finish_digits: mov rsi, r9 syscall ret -word_puts_str: - ; expects (addr, len) on data stack - mov rdx, [r12] - add r12, 8 - mov rsi, [r12] - add r12, 8 - cmp rdx, 0 - je puts_str_write_newline - mov rax, 1 - mov rdi, 1 - syscall -puts_str_write_newline: - mov byte [rel print_buf], 10 - mov rax, 1 - mov rdi, 1 - lea rsi, [rel print_buf] - mov rdx, 1 - syscall - ret word_dup: mov rax, [r12] sub r12, 8 @@ -296,6 +307,9 @@ word_foo: call word_rdrop call word_rdrop ret +section .data +data_start: +data_end: section .bss align 16 dstack: resb DSTK_BYTES diff --git a/build/call_syntax_parens.o b/build/call_syntax_parens.o index 4f2a189..4cfec6c 100644 Binary files a/build/call_syntax_parens.o and b/build/call_syntax_parens.o differ diff --git a/build/loops_and_cmp.asm b/build/loops_and_cmp.asm index 58926cf..02100b5 100644 --- a/build/loops_and_cmp.asm +++ b/build/loops_and_cmp.asm @@ -19,6 +19,36 @@ _start: mov rax, 60 syscall word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end) + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret + +puts_print_int: mov rax, [r12] add r12, 8 mov rbx, rax @@ -65,25 +95,6 @@ puts_finish_digits: mov rsi, r9 syscall ret -word_puts_str: - ; expects (addr, len) on data stack - mov rdx, [r12] - add r12, 8 - mov rsi, [r12] - add r12, 8 - cmp rdx, 0 - je puts_str_write_newline - mov rax, 1 - mov rdi, 1 - syscall -puts_str_write_newline: - mov byte [rel print_buf], 10 - mov rax, 1 - mov rdi, 1 - lea rsi, [rel print_buf] - mov rdx, 1 - syscall - ret word_dup: mov rax, [r12] sub r12, 8 @@ -305,6 +316,9 @@ L_for_end_1: sub r12, 8 mov qword [r12], 0 ret +section .data +data_start: +data_end: section .bss align 16 dstack: resb DSTK_BYTES diff --git a/build/loops_and_cmp.o b/build/loops_and_cmp.o index 8e4f71d..9fbed6f 100644 Binary files a/build/loops_and_cmp.o and b/build/loops_and_cmp.o differ diff --git a/build/main.asm b/build/main.asm index 0bd0700..031a9dd 100644 --- a/build/main.asm +++ b/build/main.asm @@ -19,6 +19,36 @@ _start: mov rax, 60 syscall word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end) + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret + +puts_print_int: mov rax, [r12] add r12, 8 mov rbx, rax @@ -277,6 +307,9 @@ word_foo: call word_rdrop call word_rdrop ret +section .data +data_start: +data_end: section .bss align 16 dstack: resb DSTK_BYTES diff --git a/build/main.o b/build/main.o index 1c49082..b867902 100644 Binary files a/build/main.o and b/build/main.o differ diff --git a/build/override_dup_compile_time.asm b/build/override_dup_compile_time.asm index 99c6ae4..98ad08c 100644 --- a/build/override_dup_compile_time.asm +++ b/build/override_dup_compile_time.asm @@ -19,6 +19,36 @@ _start: mov rax, 60 syscall word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end) + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret + +puts_print_int: mov rax, [r12] add r12, 8 mov rbx, rax @@ -65,25 +95,6 @@ puts_finish_digits: mov rsi, r9 syscall ret -word_puts_str: - ; expects (addr, len) on data stack - mov rdx, [r12] - add r12, 8 - mov rsi, [r12] - add r12, 8 - cmp rdx, 0 - je puts_str_write_newline - mov rax, 1 - mov rdi, 1 - syscall -puts_str_write_newline: - mov byte [rel print_buf], 10 - mov rax, 1 - mov rdi, 1 - lea rsi, [rel print_buf] - mov rdx, 1 - syscall - ret word_dup: mov rax, [r12] sub r12, 8 @@ -269,6 +280,9 @@ word_main: sub r12, 8 mov qword [r12], 0 ret +section .data +data_start: +data_end: section .bss align 16 dstack: resb DSTK_BYTES diff --git a/build/override_dup_compile_time.o b/build/override_dup_compile_time.o index 388f9eb..2b38b61 100644 Binary files a/build/override_dup_compile_time.o and b/build/override_dup_compile_time.o differ diff --git a/build/string_puts.asm b/build/string_puts.asm index edace3c..e868593 100644 --- a/build/string_puts.asm +++ b/build/string_puts.asm @@ -19,6 +19,36 @@ _start: mov rax, 60 syscall word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end) + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret + +puts_print_int: mov rax, [r12] add r12, 8 mov rbx, rax @@ -65,25 +95,6 @@ puts_finish_digits: mov rsi, r9 syscall ret -word_puts_str: - ; expects (addr, len) on data stack - mov rdx, [r12] - add r12, 8 - mov rsi, [r12] - add r12, 8 - cmp rdx, 0 - je puts_str_write_newline - mov rax, 1 - mov rdi, 1 - syscall -puts_str_write_newline: - mov byte [rel print_buf], 10 - mov rax, 1 - mov rdi, 1 - lea rsi, [rel print_buf] - mov rdx, 1 - syscall - ret word_dup: mov rax, [r12] sub r12, 8 @@ -267,32 +278,34 @@ word_main: ; push 11 sub r12, 8 mov qword [r12], 11 - call word_puts_str + call word_puts ; push str_1 sub r12, 8 mov qword [r12], str_1 ; push 11 sub r12, 8 mov qword [r12], 11 - call word_puts_str + call word_puts ; push str_2 sub r12, 8 mov qword [r12], str_2 ; push 0 sub r12, 8 mov qword [r12], 0 - call word_puts_str + call word_puts ; push 0 sub r12, 8 mov qword [r12], 0 ret section .data +data_start: str_0: db 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 0 str_0_len equ 11 str_1: db 108, 105, 110, 101, 49, 10, 108, 105, 110, 101, 50, 0 str_1_len equ 11 str_2: db 0 str_2_len equ 0 +data_end: section .bss align 16 dstack: resb DSTK_BYTES diff --git a/build/string_puts.o b/build/string_puts.o index 8b8d1c8..a845daf 100644 Binary files a/build/string_puts.o and b/build/string_puts.o differ diff --git a/build/test.asm b/build/test.asm index 81c4db2..522ba94 100644 --- a/build/test.asm +++ b/build/test.asm @@ -19,6 +19,36 @@ _start: mov rax, 60 syscall word_puts: + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end) + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret + +puts_print_int: mov rax, [r12] add r12, 8 mov rbx, rax @@ -730,6 +760,9 @@ word_main: sub r12, 8 mov qword [r12], 0 ret +section .data +data_start: +data_end: section .bss align 16 dstack: resb DSTK_BYTES diff --git a/build/test.o b/build/test.o index 03b5da4..b4a5541 100644 Binary files a/build/test.o and b/build/test.o differ diff --git a/hello.sl b/hello.sl index 5ce78b8..9f3cb37 100644 --- a/hello.sl +++ b/hello.sl @@ -1,5 +1,5 @@ import stdlib.sl : main - "hello world" puts_str + "hello world" puts ; \ No newline at end of file diff --git a/main.py b/main.py index 1ea71d1..dd0d125 100644 --- a/main.py +++ b/main.py @@ -1114,13 +1114,25 @@ class Assembler: for definition in runtime_defs: self._emit_definition(definition, emission.text) + if self._data_section is not None: + if not self._data_section: + self._data_section.append("data_start:") + if not self._data_section or self._data_section[-1] != "data_end:": + self._data_section.append("data_end:") emission.bss.extend(self._bss_layout()) self._data_section = None return emission + def _ensure_data_start(self) -> None: + if self._data_section is None: + raise CompileError("data section is not initialized") + if not self._data_section: + self._data_section.append("data_start:") + def _intern_string_literal(self, value: str) -> Tuple[str, int]: if self._data_section is None: raise CompileError("string literal emission requested without data section") + self._ensure_data_start() if value in self._string_literals: return self._string_literals[value] label = f"str_{len(self._string_literals)}" diff --git a/stdlib.sl b/stdlib.sl index d7b2c85..25a96b6 100644 --- a/stdlib.sl +++ b/stdlib.sl @@ -1,4 +1,34 @@ :asm puts { + ; detects string if top is len>=0 and next is a pointer in [data_start, data_end) + mov rax, [r12] ; len or int value + mov rbx, [r12 + 8] ; possible address + cmp rax, 0 + jl puts_print_int + lea r8, [rel data_start] + lea r9, [rel data_end] + cmp rbx, r8 + jl puts_print_int + cmp rbx, r9 + jge puts_print_int + ; treat as string: (addr below len) + mov rdx, rax ; len + mov rsi, rbx ; addr + add r12, 16 ; pop len + addr + test rdx, rdx + jz puts_str_newline_only + mov rax, 1 + mov rdi, 1 + syscall +puts_str_newline_only: + mov byte [rel print_buf], 10 + mov rax, 1 + mov rdi, 1 + lea rsi, [rel print_buf] + mov rdx, 1 + syscall + ret + +puts_print_int: mov rax, [r12] add r12, 8 mov rbx, rax @@ -47,27 +77,6 @@ puts_finish_digits: } ; -:asm puts_str { - ; expects (addr, len) on data stack - mov rdx, [r12] - add r12, 8 - mov rsi, [r12] - add r12, 8 - cmp rdx, 0 - je puts_str_write_newline - mov rax, 1 - mov rdi, 1 - syscall -puts_str_write_newline: - mov byte [rel print_buf], 10 - mov rax, 1 - mov rdi, 1 - lea rsi, [rel print_buf] - mov rdx, 1 - syscall -} -; - :asm dup { mov rax, [r12] sub r12, 8 diff --git a/tests/run_tests.py b/tests/run_tests.py index 4578995..cb66aa3 100644 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -105,9 +105,9 @@ compile-only import {ROOT / 'stdlib.sl'} : main - \"hello world\" puts_str - \"line1\\nline2\" puts_str - \"\" puts_str + \"hello world\" puts + \"line1\\nline2\" puts + \"\" puts 0 ; """,