diff options
author | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-08-21 21:06:34 +0200 |
---|---|---|
committer | Lizzy Fleckenstein <eliasfleckenstein@web.de> | 2023-08-21 21:06:34 +0200 |
commit | 521a94c10a23fb608bd63800240fbac9429613a2 (patch) | |
tree | aaf53c43a13eaa97235ed3cc7f45e80d26385578 | |
parent | 8648ef9dd658b4e0a71d0e188260eff071fae881 (diff) | |
download | paradox-521a94c10a23fb608bd63800240fbac9429613a2.tar.xz |
support changing stack size and buffer size
-rw-r--r-- | README.md | 51 | ||||
-rwxr-xr-x | bootstrap.lua | 41 | ||||
-rw-r--r-- | paradox.false | 66 |
3 files changed, 118 insertions, 40 deletions
@@ -59,12 +59,32 @@ Due to lack of `stderr` access in FALSE, syntax errors are emitted as `%fatal` N ### I/O Buffering -Paradox implements buffered I/O. It uses a fixed buffer size of 8192. To change this, you can use `sed -i 's/8192/YOUR_BUFSIZE_HERE/g' paradox.false`. To find out an appropriate buffer size for your system, you can use the following command, if you have a C compiler installed: +Paradox implements buffered I/O. You can use ß or B to flush buffered output. + +By default, paradox will use a buffer size of 8192, but this can be changed from the source code by using the "U" postfix on a number literal for example: + +``` +1024U +``` + +Sets the buffer size for the program to 1024 **statically, at compile time**. It is not possible to change the buffer size at runtime. If multiple of these statements are found, the one that comes last in the file will determine the buffer size. Note that there may not be a space between the integer literal and the U. + +To find out an appropriate buffer size for your system, you can use the following command, if you have a C compiler installed: ``` echo '#include <stdio.h>\nBUFSIZ' | cpp | tail -n1 ``` +### Adjusting stack size + +By default, paradox will use 8MiB for both call stack and data stack each. Changing this works similar to changing the buffer size, except S is used instead of U: + +``` +16777216S +``` + +Will set the stack size to 16MiB. This affects both call stack and data stack. + ### Inline assembly Paradox has its own inline assembly syntax: anything between backticks is emitted as assembly, like so: @@ -125,3 +145,32 @@ In the program, you can then use `2+;` at the beginning of the file to extract a Since all operations fetch 64-bits, it is recommended to set the allocation size to 7 bytes higher than desired (if you wish to fetch/write the last few bytes of the allocation individually). As an example for pointer arithmetic, see `examples/brainfuck.false` which implements brainfuck using paradox pointer arithmetic. + +### Building untrue + +For maximum FALSE meta, you can use paradox to compile the [untrue](https://github.com/appgurueu/codeguessing/blob/master/41/untrue.false) FALSE interpreter and the resulting binary can be used to run paradox. +Note: Untrue will need an increased stack size to run many programs. + +``` +# download untrue +curl https://raw.githubusercontent.com/appgurueu/codeguessing/master/41/untrue.false -o untrue.false + +# append command to set stack size to 128MiB +echo "134217728S" >> untrue.false + +# build untrue +./paradox < untrue.false > untrue.asm && nasm -f elf64 untrue.asm && ld untrue.o -o untrue + +# now, we will use untrue to run paradox to compile untrue! + +# untrue expects O and B symbols, substitute +sed 's/ø/O/g;s/ß/B/g' paradox.false > paradox_subst.false + +# untrue expects program and input to be separated by '<' +(cat paradox_subst.false && echo -n '<' && cat untrue.false) | time ./untrue | tee untrue2.asm + +# verify resulting assembly is equal +diff untrue.asm untrue2.asm +``` + +Using untrue to run paradox to build paradox has also been tested (but takes significantly longer). diff --git a/bootstrap.lua b/bootstrap.lua index aec4b0e..ac6cbc4 100755 --- a/bootstrap.lua +++ b/bootstrap.lua @@ -135,6 +135,9 @@ local current_int local line_number = 1 local line_position = 0 +local stack_size = 8388608 +local buffer_size = 8192 + local c local function read_char() @@ -174,8 +177,16 @@ local function compile_fn() current_int = current_int * 10 + tonumber(c) c = nil elseif current_int then - print("sub r12, 8") - print("mov qword[r12], " .. current_int) + if c == "S" then + stack_size = current_int + c = nil + elseif c == "U" then + buffer_size = current_int + c = nil + else + print("sub r12, 8") + print("mov qword[r12], " .. current_int) + end current_int = nil elseif c and c:match("[a-z]") then print("sub r12, 8") @@ -271,21 +282,24 @@ print("section .text") compile_fn() +print("%define STKSIZ " .. stack_size) +print("%define BUFSIZ " .. buffer_size) + io.write([[ section .data readbuf_len: dq 0 readbuf_cursor: dq 0 writebuf_len: dq 0 section .bss -readbuf: resb 8192 -writebuf: resb 8192 +readbuf: resb BUFSIZ +writebuf: resb BUFSIZ section .text read: mov rax, [readbuf_cursor] mov rbx, [readbuf_len] cmp rax, rbx jb .has -cmp rbx, 8192 +cmp rbx, BUFSIZ jb .fill xor rbx, rbx mov [readbuf_len], rbx @@ -294,7 +308,7 @@ mov [readbuf_cursor], rbx mov rax, 0 mov rdi, 0 lea rsi, [rbx+readbuf] -mov rdx, 8192 +mov rdx, BUFSIZ sub rdx, rbx syscall add [readbuf_len], rax @@ -309,7 +323,7 @@ inc qword[readbuf_cursor] ret write: mov rdi, [writebuf_len] -mov rax, 8192 +mov rax, BUFSIZ sub rax, rdi add rdi, writebuf mov rdx, rcx @@ -319,11 +333,11 @@ mov rcx, rax rep movsb push rsi push rdx -mov qword[writebuf_len], 8192 +mov qword[writebuf_len], BUFSIZ call flush pop rdx pop rsi -cmp rdx, 8192 +cmp rdx, BUFSIZ ja .direct mov rcx, rdx mov rdi, writebuf @@ -402,19 +416,18 @@ sub rcx, rsi call write add rsp, 16 ret -]]) - -io.write([[ global _start _start: -lea r12, [stack+8*1000000] +lea r12, [data_stack+STKSIZ] +lea rsp, [call_stack+STKSIZ] call fun_0 call flush mov rax, 60 mov rdi, 0 syscall section .bss -stack: resq 1000000 +data_stack: resq STKSIZ +call_stack: resq STKSIZ ]]) print("section .data") diff --git a/paradox.false b/paradox.false index 52cf9fe..8c705d1 100644 --- a/paradox.false +++ b/paradox.false @@ -12,6 +12,9 @@ l: line_number p: line_position + t: stack_size + u: buffer_size + x: compile_fn r: read_char e: error @@ -24,6 +27,9 @@ 1 l: { line_number <- 1 } 0 p: { line_position <- 0 } +8388608 t: { stack_size <- 8MiB } +8192 u: { buffer_size <- 8KiB } + { read_char() } [ ^ { input <- getchar() } @@ -86,9 +92,22 @@ { elseif current_int != -1 } i;1_=~ $[%~1_\]?[ - { emit push int } - "sub r12, 8" 10, - "mov qword[r12], " i;. 10, + { if current_char = S } + c;'S= $[ + i; t: { stack_size <- current_int } + 1_ c: { consume current_char } + ]? + { elseif current_char = U } + c;'U= $[%~1_\]?[ + i; u: { buffer_size <- current_int } + 1_ c: { consume current_char } + ]? + { else } + ~[ + { emit push int } + "sub r12, 8" 10, + "mov qword[r12], " i;. 10, + ]? 1_ i: { clear current_int } ]? @@ -470,22 +489,25 @@ x;! { call compile_fn } { if state != ERROR } q;2=~[ -{ buffered I/O } -8192 +{ emit constants } +"%define STKSIZ " t;. 10, +"%define BUFSIZ " u;. 10, + +{ emit builtin functions } "section .data readbuf_len: dq 0 readbuf_cursor: dq 0 writebuf_len: dq 0 section .bss -readbuf: resb "$." -writebuf: resb "$." +readbuf: resb BUFSIZ +writebuf: resb BUFSIZ section .text read: mov rax, [readbuf_cursor] mov rbx, [readbuf_len] cmp rax, rbx jb .has -cmp rbx, "$." +cmp rbx, BUFSIZ jb .fill xor rbx, rbx mov [readbuf_len], rbx @@ -494,7 +516,7 @@ mov [readbuf_cursor], rbx mov rax, 0 mov rdi, 0 lea rsi, [rbx+readbuf] -mov rdx, "$." +mov rdx, BUFSIZ sub rdx, rbx syscall add [readbuf_len], rax @@ -509,7 +531,7 @@ inc qword[readbuf_cursor] ret write: mov rdi, [writebuf_len] -mov rax, "$." +mov rax, BUFSIZ sub rax, rdi add rdi, writebuf mov rdx, rcx @@ -519,11 +541,11 @@ mov rcx, rax rep movsb push rsi push rdx -mov qword[writebuf_len], "$." +mov qword[writebuf_len], BUFSIZ call flush pop rdx pop rsi -cmp rdx, "$." +cmp rdx, BUFSIZ ja .direct mov rcx, rdx mov rdi, writebuf @@ -547,10 +569,7 @@ syscall mov qword[writebuf_len], 0 .return: ret -"% - -{ builtin functions } -"conditional: +conditional: add r12, 16 mov eax, [r12-8] cmp eax, 0 @@ -605,22 +624,19 @@ sub rcx, rsi call write add rsp, 16 ret -" - -{ emit _start and stack } - -1000000 -"global _start +global _start _start: -lea r12, [stack+8*"$."] +lea r12, [data_stack+STKSIZ] +lea rsp, [call_stack+STKSIZ] call fun_0 call flush mov rax, 60 mov rdi, 0 syscall section .bss -stack: resq "$." -"% +data_stack: resq STKSIZ +call_stack: resq STKSIZ +" { emit variables } |