bf interpreter because lulz

This commit is contained in:
minjaesong
2020-11-30 22:26:23 +09:00
parent 0b646c4d51
commit f4c67fee30
5 changed files with 344 additions and 3 deletions

66
assets/bf.js Normal file
View File

@@ -0,0 +1,66 @@
// exec_args: bf.js input_file optional_memsize
let memsize = exec_args[2]|0;
if (memsize <= 0) memsize = (system.maxmem() < 30000) ? system.maxmem()-256 : 30000;
let nativePtr = undefined;
try {
nativePtr = sys.malloc(memsize);
}
catch (e) {
printerrln("Could not allocate memory with size "+memsize);
return 10;
}
let stubHead = "let mx="+memsize+";"+
"let fmod=function(a,b){return Number((a-(Math.floor(a/b)*b)).toPrecision(8));};"+
"let ip=function(){p=fmod(p+1,mx)};"+
"let dp=function(){p=fmod(p-1,mx)};"+
"let iv=function(){sys.poke(p,fmod(sys.peek(p)+1,256))};"+
"let dv=function(){sys.poke(p,fmod(sys.peek(p)-1,256))};"+
"let p="+nativePtr+";"
let translation = {
62: "ip();",
60: "dp();",
43: "iv();",
45: "dv();",
46: "sys.print(String.fromCharCode(sys.peek(p)));",
44: "sys.poke(p,sys.readKey());",
91: "while(sys.peek(p)!=0){",
93: "}"
};
if (exec_args[1] === undefined) {
printerrln("Usage: bf <path-to-BF-program>");
return 1;
}
let bfprg = "";
try {
filesystem.open(_G.shell.getCurrentDrive(), exec_args[1], "R");
bfprg = filesystem.readAll(_G.shell.getCurrentDrive());
}
catch(e) {
printerrln(e);
sys.free(nativePtr);
return 1;
}
try {
// translate
let tprg = stubHead;
for (let k = 0; k < bfprg.length; k++) {
tprg += (translation[bfprg.charCodeAt(k)] || "");
}
// clear memory
for (let k = 0; k < memsize; k++) {
sys.poke(nativePtr+k, 0);
}
// run
execApp(tprg);
}
catch (e) {
printerrln(e);
return 1;
}
finally {
sys.free(nativePtr);
}
return 0;

254
assets/bf/99 Normal file
View File

@@ -0,0 +1,254 @@
# 99 bottles of beer in Brainf*ck
# Copyright (C) 2008 Raphael Bois
# 1671 brainf*ck instructions.
# Published under GPL v2
Initialization
++ Counter for loop (a)
>+ unused
>++ Counter for loop (b)
> Flag for 'no more'
>+ Flag for not 'no more'
>>> (5) to (7) : temporary values
++++++++++[->+>+>++++++++++<<<]>>> 10 10 100 in (8) (9) (10)
>++++++++++ 10 in (11)
[-
>+++++ 50 in (12)
>++++++++++ 100 in (13)
>+++++++++++ 110 in (14)
>++++++++ 80 in (15)
>++++++++ 80 in (16)
>+++ 30 in (17)
>++++ 40 in (18)
>+ 10 in (19)
<<<<<<<<]
+
>-- + 48 '0' plus 1 in (12)
>++ + 102 'f' plus 1 in (13)
>+++++ + 115 's' plus 1 in (14)
>-- + 78 'N' plus 1 in (15)
>++++ + 84 'T' plus 1 in (16)
>++ + 32 ' ' plus 1 in (17)
>++++ + 44 comma plus 1 in (18)
> + 10 LF plus 1 in (19)
stuff for writing parts of the song
>+ select stuff
>+ select stuff
>+ write song part 3
>++ write song part 1
>+ write song part 2
>+ Flag for 'end of song'
>++ Flag for not 'end of song'
All bytes are at val plus 1
Go back to (7) with final initialization step (remove 1 to all bytes)
[-<]
<<<<<<< at (0)
[ loop (a)
-
>> at (2)
[ loop (b)
>>>>>>>> at (10)
[ start loop
<<<<<<< at (3)
[->[-]
print '(N|n)o more'
>>>>>>>>>>>. '(N|n)'
<----. 'o'
>>>. ' '
<<<--. 'm'
++. 'o'
+++.+ 'r'
<-.+ 'e'
<<+<<<<<<<<
]+> at (4)
[-<[-]>>>>> at (9)
prints number (using (9) and (10))
[>>>+<<<<+<+<+>>>-]<<<[->>>+<<<]> at (6)
[>>>>>>+<<<<<<-]>>>>>[[-]>.<]<<<<[>>>>>-<<<<<-]>> at (9)
[<<+<+<+>>>>-]<<<<[->>>>+<<<<]> at (6)
[>>>>>>+<<<<<<-]>>>>>>.<<<<<[>>>>>-<<<<<-] at (7)
memorize in (11) if (10) not 1
>>>[-<<<+<+>>>>]<<<<[->>>>+<<<<]>-[[-]>>>>+<<<<]<<< at (4)
]+
>>>>>>>> at (12)
print ' bottle(s) of beer'
>>>>>. ' '
<<<<----. 'b'
>----. 'o'
+++++..- 'tt'
<++++++++++. 'l'
-------. 'e'
<<[[-]>>>.<<<]>> 's' if (11)==1 ie if (10)!=1
>>>>. ' '
<<<----. 'o'
<+. 'f'
>>>>. ' '
<<<<----. 'b'
+++..+ 'ee'
>+++.+ 'r'
[>] at (20)
+>+>[->+<<-<-
print ' on the wall' DOT LF LF
<<<. ' '
<<<----. 'o'
-. 'n'
>>>. ' '
<<<++++++. 't'
<++. 'h'
---. 'e'
>>>>. ' '
<<<+++. 'w'
<----. 'a'
+++++++++++.. 'll'
------>---- reset to 'f' and 's'
>---------- ---------- ---------- -- sets (15) to 'N'
>>>++.-- DOT
>.. LF LF
>>>] at (22)
>>>[->[-]<<<<<<<[<]<[-]>>[>]>>>>>]+ if end of song reset bottles counter
>[-<[-] at (25)
<<<< at (21)
[->>[->+<<<<-
print ' on the wall' COMMA ' '
<<<. ' '
<<<----. 'o'
-. 'n'
>>>. ' '
<<<++++++. 't'
<++. 'h'
---. 'e'
>>>>. ' '
<<<+++. 'w'
<----. 'a'
+++++++++++.. 'll'
------>---- reset (13) and (14) to 'f' and 's'
>++++++++++ ++++++++++ ++++++++++ ++ sets (15) to 'n'
>>>. comma
<. ' '
>>>>>>]<<]< at (20)
[->>>>[-<<+< at (21)
<<<++.-- DOT
>. LF
[<]<<<<<<<< at (3)
[->[-]<]+> at (4)
[-<[-]>
>>>>>>>>>>>>. 'T'
<<<-----. 'a'
++++++++++. 'k'
------. 'e'
>>>>. ' '
<<<----. 'o'
-. 'n'
<. 'e'
>>>>. ' '
<<<<-. 'd'
>+. 'o'
++++++++. 'w'
---------. 'n'
>>>. ' '
<<<<---. 'a'
>. 'n'
<+++. 'd'
>>>>. ' '
<<<++. 'p'
<---. 'a'
>+++.. 'ss'
>>>. ' '
<<<<++++++++. 'i'
>+. 't'
>>>. ' '
<<<<--------. 'a'
>--. 'r'
---. 'o'
++++++. 'u'
-------. 'n'
<+++. 'd'
++>+++++ reset (13) and (14) to 'f' and 's'
>>>>. comma
<. ' '
[<]<<<<<<< at (4)
]+
>>>>>> at (10)
decrements values
-<<<+>>[<<[-]<+<+>>>>-]<<<<[>-<[-]]>[->>>+<<<]>[->->+++++++++<<]>>> at (10)
>>[>]>>>>] at (24)
<<<<] at (20)
>>>>>>]+ at (26)
<<<<<<<[<]< at (10)
]
+<+
<<<<<<+< at (2)
-
]
print 'Go to the store and buy some more' comma ' '
>>>>>>>>>>[>]>>>>> at (25)
[->[-]<]+> at (26)
[-<[-]
<<<<<<<<< at (16)
-------------. 'G'
<<----. 'o'
>>>. ' '
<<<+++++. 't'
-----. 'o'
>>>. ' '
<<<+++++. 't'
<++. 'h'
---. 'e'
>>>>. ' '
<<<-. 's'
+. 't'
-----. 'o'
+++. 'r'
<. 'e'
>>>>. ' '
<<<<----. 'a'
>----. 'n'
<+++. 'd'
>>>>. ' '
<<<<--. 'b'
>+++++++. 'u'
++++. 'y'
>>>. ' '
<<<------. 's'
----. 'o'
--. 'm'
<+++. 'e'
>>>>. ' '
<<<. 'm'
++. 'o'
+++.+ 'r'
<.+ 'e'
>>>>>. coma
<. ' '
>>>>>>>>>
]+
Initialize last loop to print final '99 bottles of beer on the wall' DOT
<[-]+<[-]<[-]<[-]+<<< at (19)
[<]<[-]<[-]<[-]<[-] at (7)
++++++++++[->+>+>++++++++++<<<]>->->-
<<<<<<[-]+<[-]<+<< at (0)
]

2
assets/bf/hello Normal file
View File

@@ -0,0 +1,2 @@
>++++++++[-<+++++++++>]<.>>+>-[+]++>++>+++[>[->+++<<+++>]<<]>-----.>->
+++..+++.>-.<<+[>[+>+]>>]<--------------.>>.+++.------.--------.>+.>+.

21
assets/bf/scan Normal file
View File

@@ -0,0 +1,21 @@
Calculate the value 256 and test if it's zero
If the interpreter errors on overflow this is where it'll happen
++++++++[>++++++++<-]>[<++++>-]
+<[>-<
Not zero so multiply by 256 again to get 65536
[>++++<-]>[<++++++++>-]<[>++++++++<-]
+>[>
# Print "32"
++++++++++[>+++++<-]>+.-.[-]<
<[-]<->] <[>>
# Print "16"
+++++++[>+++++++<-]>.+++++.[-]<
<<-]] >[>
# Print "8"
++++++++[>+++++++<-]>.[-]<
<-]<
# Print " bit cells\n"
+++++++++++[>+++>+++++++++>+++++++++>+<<<<-]>-.>-.+++++++.+++++++++++.<.
>>.++.+++++++..<-.>>-
Clean up used cells.
[[-]<]

View File

@@ -11,9 +11,7 @@ import java.lang.RuntimeException
internal class Firmware(val vm: VM) : TwoArgFunction() {
class ErrorIllegalAccess(val addr: Long) : RuntimeException() {
}
class ErrorIllegalAccess(val addr: Long) : RuntimeException("Segmentation fault at 0x${addr.toString(16).padStart(8, '0')}")
companion object {
internal fun translateAddr(vm : VM, addr: LuaValue): Pair<Any?, Long> {