aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLizzy Fleckenstein <eliasfleckenstein@web.de>2023-08-21 21:06:34 +0200
committerLizzy Fleckenstein <eliasfleckenstein@web.de>2023-08-21 21:06:34 +0200
commit521a94c10a23fb608bd63800240fbac9429613a2 (patch)
treeaaf53c43a13eaa97235ed3cc7f45e80d26385578
parent8648ef9dd658b4e0a71d0e188260eff071fae881 (diff)
downloadparadox-521a94c10a23fb608bd63800240fbac9429613a2.tar.xz
support changing stack size and buffer size
-rw-r--r--README.md51
-rwxr-xr-xbootstrap.lua41
-rw-r--r--paradox.false66
3 files changed, 118 insertions, 40 deletions
diff --git a/README.md b/README.md
index 2282091..374c3af 100644
--- a/README.md
+++ b/README.md
@@ -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 }