diff --git a/assets/bf.js b/assets/bf.js new file mode 100644 index 0000000..738bd6a --- /dev/null +++ b/assets/bf.js @@ -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 "); + 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; \ No newline at end of file diff --git a/assets/bf/99 b/assets/bf/99 new file mode 100644 index 0000000..d632d40 --- /dev/null +++ b/assets/bf/99 @@ -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) +] \ No newline at end of file diff --git a/assets/bf/hello b/assets/bf/hello new file mode 100644 index 0000000..db5525f --- /dev/null +++ b/assets/bf/hello @@ -0,0 +1,2 @@ +>++++++++[-<+++++++++>]<.>>+>-[+]++>++>+++[>[->+++<<+++>]<<]>-----.>-> ++++..+++.>-.<<+[>[+>+]>>]<--------------.>>.+++.------.--------.>+.>+. \ No newline at end of file diff --git a/assets/bf/scan b/assets/bf/scan new file mode 100644 index 0000000..41102ad --- /dev/null +++ b/assets/bf/scan @@ -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. +[[-]<] \ No newline at end of file diff --git a/src/net/torvald/tsvm/firmware/Firmware.kt b/src/net/torvald/tsvm/firmware/Firmware.kt index 1dac192..551460c 100644 --- a/src/net/torvald/tsvm/firmware/Firmware.kt +++ b/src/net/torvald/tsvm/firmware/Firmware.kt @@ -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 {