September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
331
Task/Execute-Brain----/68000-Assembly/execute-brain----.68000
Normal file
331
Task/Execute-Brain----/68000-Assembly/execute-brain----.68000
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
;
|
||||
; Brainfuck interpreter by Thorham
|
||||
;
|
||||
; 68000+ AmigaOs2+
|
||||
;
|
||||
; Cell size is a byte
|
||||
;
|
||||
incdir "asminc:"
|
||||
|
||||
include "dos/dosextens.i"
|
||||
include "lvo/lvos.i"
|
||||
|
||||
execBase equ 4
|
||||
|
||||
start
|
||||
|
||||
; parse command line parameter
|
||||
|
||||
move.l a0,fileName
|
||||
|
||||
move.b (a0)+,d0
|
||||
beq exit ; no parameter
|
||||
|
||||
cmp.b #'"',d0 ; filter out double quotes
|
||||
bne .loop
|
||||
|
||||
addq.l #1,fileName
|
||||
|
||||
.loop
|
||||
move.b (a0)+,d0
|
||||
|
||||
cmp.b #'"',d0 ; filter out double quotes
|
||||
beq .done
|
||||
|
||||
cmp.b #32,d0
|
||||
bge .loop
|
||||
|
||||
.done
|
||||
clr.b -(a0) ; end of string
|
||||
|
||||
; open dos library
|
||||
|
||||
move.l execBase,a6
|
||||
|
||||
lea dosName,a1
|
||||
moveq #36,d0
|
||||
jsr _LVOOpenLibrary(a6)
|
||||
move.l d0,dosBase
|
||||
beq exit
|
||||
|
||||
; get stdin and stdout handles
|
||||
|
||||
move.l dosBase,a6
|
||||
|
||||
jsr _LVOInput(a6)
|
||||
move.l d0,stdIn
|
||||
beq exit
|
||||
|
||||
jsr _LVOOutput(a6)
|
||||
move.l d0,stdOut
|
||||
beq exit
|
||||
|
||||
move.l stdIn,d1
|
||||
jsr _LVOFlush(a6)
|
||||
|
||||
; open file
|
||||
|
||||
move.l fileName,d1
|
||||
move.l #MODE_OLDFILE,d2
|
||||
jsr _LVOOpen(a6)
|
||||
move.l d0,fileHandle
|
||||
beq exit
|
||||
|
||||
; examine file
|
||||
|
||||
lea fileInfoBlock,a4
|
||||
|
||||
move.l fileHandle,d1
|
||||
move.l a4,d2
|
||||
jsr _LVOExamineFH(a6)
|
||||
tst.w d0
|
||||
beq exit
|
||||
|
||||
; exit if the file is a folder
|
||||
|
||||
tst.l fib_DirEntryType(a4)
|
||||
bge exit
|
||||
|
||||
; allocate file memory
|
||||
|
||||
move.l execBase,a6
|
||||
|
||||
move.l fib_Size(a4),d0
|
||||
beq exit ; exit if file is empty
|
||||
clr.l d1
|
||||
jsr _LVOAllocVec(a6)
|
||||
move.l d0,program
|
||||
beq exit
|
||||
|
||||
; read file
|
||||
|
||||
move.l dosBase,a6
|
||||
|
||||
move.l fileHandle,d1
|
||||
move.l program,d2
|
||||
move.l fib_Size(a4),d3
|
||||
jsr _LVORead(a6)
|
||||
tst d0
|
||||
ble exit ; exit if read didn't succeed
|
||||
|
||||
; close file
|
||||
|
||||
move.l fileHandle,d1
|
||||
jsr _LVOClose(a6)
|
||||
clr.l fileHandle
|
||||
|
||||
; clear tape (bss section is allocated by os but not cleared)
|
||||
|
||||
lea tape,a0
|
||||
lea tapeEnd,a1
|
||||
|
||||
.loopClear
|
||||
clr.b (a0)+
|
||||
cmp.l a0,a1
|
||||
bne .loopClear
|
||||
|
||||
; interpreter
|
||||
|
||||
move.l program,a2
|
||||
lea tape,a3
|
||||
|
||||
clr.l d2
|
||||
|
||||
move.l a2,d6 ; start of program
|
||||
move.l a2,d7 ; end of program
|
||||
add.l fib_Size(a4),d7
|
||||
|
||||
loop
|
||||
move.b (a2)+,d2
|
||||
|
||||
cmp.b #">",d2
|
||||
beq .incPtr
|
||||
|
||||
cmp.b #"<",d2
|
||||
beq .decPtr
|
||||
|
||||
cmp.b #"+",d2
|
||||
beq .incMem
|
||||
|
||||
cmp.b #"-",d2
|
||||
beq .decMem
|
||||
|
||||
cmp.b #".",d2
|
||||
beq .outMem
|
||||
|
||||
cmp.b #",",d2
|
||||
beq .inMem
|
||||
|
||||
cmp.b #"[",d2
|
||||
beq .jmpForward
|
||||
|
||||
cmp.b #"]",d2
|
||||
beq .jmpBack
|
||||
|
||||
; next command
|
||||
|
||||
.next
|
||||
cmp.l d7,a2 ; test end of program
|
||||
blt loop
|
||||
|
||||
; end of program reached
|
||||
|
||||
bra exit
|
||||
|
||||
; command implementations
|
||||
|
||||
.incPtr
|
||||
addq.l #1,a3
|
||||
cmp.l #tapeEnd,a3 ; test end of tape
|
||||
bge exit
|
||||
bra .next
|
||||
|
||||
.decPtr
|
||||
subq.l #1,a3
|
||||
cmp.l #tape,a3 ; test start of tape
|
||||
blt exit
|
||||
bra .next
|
||||
|
||||
.incMem
|
||||
addq.b #1,(a3)
|
||||
bra .next
|
||||
|
||||
.decMem
|
||||
subq.b #1,(a3)
|
||||
bra .next
|
||||
|
||||
.outMem
|
||||
move.l stdOut,d1
|
||||
move.b (a3),d2
|
||||
jsr _LVOFPutC(a6)
|
||||
bra .next
|
||||
|
||||
.inMem
|
||||
move.l stdIn,d1
|
||||
jsr _LVOFGetC(a6)
|
||||
|
||||
cmp.b #27,d0 ; convert escape to 0
|
||||
bne .notEscape
|
||||
moveq #0,d0
|
||||
.notEscape
|
||||
move.b d0,(a3)
|
||||
|
||||
bra .next
|
||||
|
||||
.jmpForward
|
||||
tst.b (a3)
|
||||
bne .next
|
||||
|
||||
move.l a2,a4
|
||||
clr.l d3
|
||||
|
||||
.loopf
|
||||
cmp.l d7,a4 ; test end of program
|
||||
bge exit
|
||||
|
||||
move.b (a4)+,d2
|
||||
|
||||
cmp.b #"[",d2
|
||||
bne .lf
|
||||
|
||||
addq.l #1,d3
|
||||
bra .loopf
|
||||
.lf
|
||||
cmp.b #"]",d2
|
||||
bne .loopf
|
||||
|
||||
subq.l #1,d3
|
||||
bge .loopf
|
||||
|
||||
move.l a4,a2
|
||||
bra .next
|
||||
|
||||
.jmpBack
|
||||
tst.b (a3)
|
||||
beq .next
|
||||
|
||||
move.l a2,a4
|
||||
clr.l d3
|
||||
|
||||
.loopb
|
||||
move.b -(a4),d2
|
||||
|
||||
cmp.l d6,a4 ; test start of program
|
||||
blt exit
|
||||
|
||||
cmp.b #"]",d2
|
||||
bne .lb
|
||||
|
||||
addq.l #1,d3
|
||||
bra .loopb
|
||||
.lb
|
||||
cmp.b #"[",d2
|
||||
bne .loopb
|
||||
|
||||
subq.l #1,d3
|
||||
bgt .loopb
|
||||
|
||||
move.l a4,a2
|
||||
bra .next
|
||||
|
||||
; cleanup and exit
|
||||
|
||||
exit
|
||||
move.l dosBase,a6
|
||||
|
||||
move.l fileHandle,d1
|
||||
beq .noFile
|
||||
jsr _LVOClose(a6)
|
||||
.noFile
|
||||
|
||||
move.l execBase,a6
|
||||
|
||||
move.l program,a1
|
||||
tst.l a1
|
||||
beq .noMem
|
||||
jsr _LVOFreeVec(a6)
|
||||
.noMem
|
||||
|
||||
move.l dosBase,a1
|
||||
tst.l a1
|
||||
beq .noLib
|
||||
jsr _LVOCloseLibrary(a6)
|
||||
.noLib
|
||||
|
||||
rts
|
||||
|
||||
; data
|
||||
|
||||
section data,data_p
|
||||
|
||||
dosBase
|
||||
dc.l 0
|
||||
|
||||
fileName
|
||||
dc.l 0
|
||||
|
||||
fileHandle
|
||||
dc.l 0
|
||||
|
||||
fileInfoBlock
|
||||
dcb.b fib_SIZEOF
|
||||
|
||||
stdIn
|
||||
dc.l 0
|
||||
|
||||
stdOut
|
||||
dc.l 0
|
||||
|
||||
program
|
||||
dc.l 0
|
||||
|
||||
dosName
|
||||
dc.b "dos.library",0
|
||||
|
||||
; tape memory
|
||||
|
||||
section mem,bss_p
|
||||
|
||||
tape
|
||||
ds.b 1024*64
|
||||
tapeEnd
|
||||
89
Task/Execute-Brain----/Agena/execute-brain----.agena
Normal file
89
Task/Execute-Brain----/Agena/execute-brain----.agena
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# Brain**** interpreter
|
||||
|
||||
# execute the Brain**** program in the code string
|
||||
bf := proc( code :: string ) is
|
||||
local address := 1; # current data address
|
||||
local pc := 1; # current position in code
|
||||
local data := []; # data - initially empty
|
||||
local input := ""; # user input - initially empty
|
||||
local bfOperations := # table of operations and their implemntations
|
||||
[ ">" ~ proc() is inc address, 1 end
|
||||
, "<" ~ proc() is dec address, 1 end
|
||||
, "+" ~ proc() is inc data[ address ], 1 end
|
||||
, "-" ~ proc() is dec data[ address ], 1 end
|
||||
, "." ~ proc() is io.write( char( data[ address ] ) ) end
|
||||
, "," ~ proc() is
|
||||
# get next input character, converted to an integer
|
||||
while input = ""
|
||||
do
|
||||
# no input left - get the next line
|
||||
input := io.read()
|
||||
od;
|
||||
data[ address ] := abs( input[ 1 ] );
|
||||
# remove the latest character from the input
|
||||
if size input < 2
|
||||
then
|
||||
input := ""
|
||||
else
|
||||
input := input[ 2 to -1 ]
|
||||
fi
|
||||
end
|
||||
, "[" ~ proc() is
|
||||
if data[ address ] = 0
|
||||
then
|
||||
# skip to the end of the loop
|
||||
local depth := 0;
|
||||
do
|
||||
inc pc, 1;
|
||||
if code[ pc ] = "["
|
||||
then
|
||||
inc depth, 1
|
||||
elif code[ pc ] = "]"
|
||||
then
|
||||
dec depth, 1
|
||||
fi
|
||||
until depth < 0
|
||||
fi
|
||||
end
|
||||
, "]" ~ proc() is
|
||||
if data[ address ] <> 0
|
||||
then
|
||||
# skip to the start of the loop
|
||||
local depth := 0;
|
||||
do
|
||||
dec pc, 1;
|
||||
if code[ pc ] = "["
|
||||
then
|
||||
dec depth, 1
|
||||
elif code[ pc ] = "]"
|
||||
then
|
||||
inc depth, 1
|
||||
fi
|
||||
until depth < 0
|
||||
fi
|
||||
end
|
||||
];
|
||||
# execute the operations - ignore anything invalid
|
||||
while pc <= size code
|
||||
do
|
||||
if data[ address ] = null
|
||||
then
|
||||
data[ address ] := 0
|
||||
fi;
|
||||
if bfOperations[ code[ pc ] ] <> null
|
||||
then
|
||||
bfOperations[ code[ pc ] ]()
|
||||
fi;
|
||||
inc pc, 1
|
||||
od
|
||||
end;
|
||||
|
||||
# prompt for Brain**** code and execute it, repeating until an empty code string is entered
|
||||
scope
|
||||
local code;
|
||||
do
|
||||
io.write( "BF> " );
|
||||
code := io.read();
|
||||
bf( code )
|
||||
until code = ""
|
||||
epocs;
|
||||
88
Task/Execute-Brain----/BASIC/execute-brain-----2.basic
Normal file
88
Task/Execute-Brain----/BASIC/execute-brain-----2.basic
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
REM
|
||||
REM Brainfuck interpreter
|
||||
|
||||
REM Get the separate arguments
|
||||
SPLIT ARGUMENT$ BY " " TO arg$ SIZE dim
|
||||
|
||||
IF dim < 2 THEN
|
||||
PRINT "Usage: bf <file>"
|
||||
END
|
||||
ENDIF
|
||||
|
||||
REM Determine size
|
||||
filesize = FILELEN(arg$[1])
|
||||
|
||||
REM Get the contents
|
||||
OPEN arg$[1] FOR READING AS bf
|
||||
|
||||
REM claim memory
|
||||
txt = MEMORY(filesize)
|
||||
|
||||
REM Read file into memory
|
||||
GETBYTE txt FROM bf SIZE filesize
|
||||
|
||||
CLOSE FILE bf
|
||||
|
||||
REM Initialize work memory
|
||||
mem = MEMORY(30000)
|
||||
|
||||
REM This is The Pointer pointing to memory
|
||||
thepointer = 0
|
||||
|
||||
REM This is the cursor pointing in the current program
|
||||
cursor = 0
|
||||
|
||||
REM Start interpreting program
|
||||
WHILE cursor < filesize DO
|
||||
|
||||
command = PEEK(txt + cursor)
|
||||
|
||||
SELECT command
|
||||
CASE 62
|
||||
INCR thepointer
|
||||
|
||||
CASE 60
|
||||
DECR thepointer
|
||||
|
||||
CASE 43
|
||||
POKE mem + thepointer, PEEK(mem + thepointer) + 1
|
||||
|
||||
CASE 45
|
||||
POKE mem + thepointer, PEEK(mem + thepointer) - 1
|
||||
|
||||
CASE 46
|
||||
PRINT CHR$(PEEK(mem + thepointer));
|
||||
|
||||
CASE 44
|
||||
key = GETKEY
|
||||
POKE mem + thepointer, key
|
||||
|
||||
CASE 91
|
||||
jmp = 1
|
||||
IF ISFALSE(PEEK(mem + thepointer)) THEN
|
||||
REPEAT
|
||||
INCR cursor
|
||||
IF PEEK(txt + cursor) = 91 THEN
|
||||
INCR jmp
|
||||
ELIF PEEK(txt + cursor) = 93 THEN
|
||||
DECR jmp
|
||||
END IF
|
||||
UNTIL PEEK(txt + cursor) = 93 AND NOT(jmp)
|
||||
END IF
|
||||
|
||||
CASE 93
|
||||
jmp = 1
|
||||
IF ISTRUE(PEEK(mem + thepointer)) THEN
|
||||
REPEAT
|
||||
DECR cursor
|
||||
IF PEEK(txt + cursor) = 93 THEN
|
||||
INCR jmp
|
||||
ELIF PEEK(txt + cursor) = 91 THEN
|
||||
DECR jmp
|
||||
END IF
|
||||
UNTIL PEEK(txt + cursor) = 91 AND NOT(jmp)
|
||||
END IF
|
||||
END SELECT
|
||||
|
||||
INCR cursor
|
||||
WEND
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
pointer_alpha = 1/0
|
||||
pointer_numeric = 1/0
|
||||
tape_behind = ''
|
||||
tape_ahead = 1/0
|
||||
tape_pos = 0 # only for debugging
|
||||
array_behind = 1/0
|
||||
array_ahead = ''
|
||||
set_tape_ahead = array_ahead
|
||||
array_ahead = 1/0
|
||||
#
|
||||
shift
|
||||
comefrom if array_ahead is array_ahead
|
||||
cdr = 1/0
|
||||
cdr = array_ahead
|
||||
shift_tail = cdr
|
||||
new_cell
|
||||
comefrom shift if shift_tail is ''
|
||||
itoa = 0
|
||||
shift_tail = itoa
|
||||
car = 1/0
|
||||
car = array_ahead
|
||||
array_behind = car array_behind
|
||||
done = shift_tail
|
||||
array_ahead = shift_tail
|
||||
comefrom shift if array_ahead is done
|
||||
|
||||
set_pointer_alpha = 1/0
|
||||
set_pointer_alpha
|
||||
comefrom if set_pointer_alpha
|
||||
atoi = set_pointer_alpha
|
||||
cdr = tape_ahead
|
||||
set_tape_ahead = set_pointer_alpha cdr
|
||||
set_pointer_alpha = 1/0
|
||||
|
||||
set_tape_ahead = 1/0
|
||||
set_pointer_vals
|
||||
comefrom if set_tape_ahead
|
||||
tape_ahead = set_tape_ahead
|
||||
car = tape_ahead
|
||||
pointer_alpha = car
|
||||
atoi = pointer_alpha
|
||||
pointer_numeric = atoi
|
||||
set_tape_ahead = 1/0
|
||||
|
||||
pointer_change = 1/0
|
||||
change_pointer_val
|
||||
comefrom if pointer_change
|
||||
car = tape_ahead
|
||||
cdr = tape_ahead
|
||||
itoa = pointer_numeric + pointer_change
|
||||
set_tape_ahead = itoa cdr
|
||||
pointer_change = 1/0
|
||||
|
||||
file = 0 # initialize to something other than undefined so jump from file works when read fails
|
||||
read_path = argv
|
||||
error_reading_program
|
||||
comefrom file if file + 0 is 0
|
||||
'Error: cannot read Brainfuck program at "' read_path '"'
|
||||
''
|
||||
|
||||
program_loaded
|
||||
comefrom file if file is file
|
||||
program_behind = ''
|
||||
program_ahead = file
|
||||
|
||||
run
|
||||
comefrom program_loaded
|
||||
opcode = 1/0
|
||||
opcode_numeric = 1/0
|
||||
in_buffer = '' # cf0x10 stdin is line-buffered
|
||||
jumping = 0
|
||||
moving = 1
|
||||
comefrom run
|
||||
|
||||
comefrom execute if opcode_numeric is 0
|
||||
''
|
||||
execute
|
||||
comefrom run if moving
|
||||
# can be useful for debugging:
|
||||
#program_ahead moving ':' jumping '@' tape_pos ':' pointer_numeric
|
||||
car = program_ahead
|
||||
atoi = car
|
||||
opcode_numeric = atoi
|
||||
opcode = car
|
||||
opcode = 1/0
|
||||
|
||||
#
|
||||
|
||||
program_forward
|
||||
comefrom execute if moving > 0
|
||||
array_behind = program_behind
|
||||
array_ahead = 1/0
|
||||
array_ahead = program_ahead
|
||||
program_behind = array_behind
|
||||
program_ahead = array_ahead
|
||||
|
||||
forward_jump
|
||||
comefrom execute if opcode is '['
|
||||
|
||||
jump
|
||||
comefrom forward_jump if pointer_numeric is 0
|
||||
jumping = jumping + 1
|
||||
moving = 1
|
||||
match_brace
|
||||
comefrom forward_jump if jumping < 0
|
||||
jumping = jumping + 1
|
||||
stop_jump
|
||||
comefrom match_brace if jumping is 0
|
||||
moving = 1
|
||||
|
||||
program_backward
|
||||
comefrom execute if moving < 0
|
||||
array_behind = program_ahead
|
||||
array_ahead = 1/0
|
||||
array_ahead = program_behind
|
||||
program_behind = array_ahead
|
||||
program_ahead = array_behind
|
||||
|
||||
backward_jump
|
||||
comefrom execute if opcode is ']'
|
||||
|
||||
jump
|
||||
comefrom backward_jump if pointer_numeric > 0
|
||||
jumping = jumping - 1
|
||||
moving = -1
|
||||
match_brace
|
||||
comefrom backward_jump if jumping > 0
|
||||
jumping = jumping - 1
|
||||
stop_jump
|
||||
comefrom match_brace if jumping is 0
|
||||
moving = 1
|
||||
|
||||
op
|
||||
comefrom execute if opcode
|
||||
|
||||
moving = 1
|
||||
do_op = opcode
|
||||
comefrom op if jumping
|
||||
#
|
||||
forward
|
||||
comefrom op if do_op is '>'
|
||||
tape_pos = tape_pos + 1
|
||||
array_ahead = 1/0
|
||||
array_behind = tape_behind
|
||||
array_ahead = tape_ahead
|
||||
tape_behind = array_behind
|
||||
set_tape_ahead = array_ahead
|
||||
backward
|
||||
comefrom op if do_op is '<'
|
||||
tape_pos = tape_pos - 1
|
||||
array_ahead = 1/0
|
||||
array_behind = tape_ahead
|
||||
array_ahead = tape_behind
|
||||
tape_behind = array_ahead
|
||||
set_tape_ahead = array_behind
|
||||
|
||||
increment
|
||||
comefrom op if do_op is '+'
|
||||
pointer_change = 1
|
||||
decrement
|
||||
comefrom op if do_op is '-'
|
||||
pointer_change = -1
|
||||
|
||||
print
|
||||
comefrom op if do_op is '.'
|
||||
pointer_alpha...
|
||||
read
|
||||
comefrom op if do_op is ','
|
||||
#
|
||||
cdr = 1/0
|
||||
cdr = in_buffer
|
||||
car = in_buffer
|
||||
set_pointer_alpha = car
|
||||
cdr = in_buffer
|
||||
in_buffer = cdr
|
||||
comefrom stdin if stdin + 0 is 0
|
||||
#
|
||||
block_for_input
|
||||
comefrom read if cdr is ''
|
||||
stdin = ''
|
||||
in_buffer = stdin
|
||||
cdr = in_buffer
|
||||
comefrom stdin if stdin + 0 is 0
|
||||
243
Task/Execute-Brain----/Dodo0/execute-brain----.dodo0
Normal file
243
Task/Execute-Brain----/Dodo0/execute-brain----.dodo0
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
#Import some functions
|
||||
clojure('count', 1) -> size
|
||||
clojure('nth', 2) -> charAt
|
||||
clojure('inc', 1) -> inc
|
||||
clojure('dec', 1) -> dec
|
||||
clojure('char', 1) -> char
|
||||
clojure('int', 1) -> int
|
||||
clojure('read-line', 0) -> readLine
|
||||
|
||||
#The characters we will need
|
||||
charAt("\n", 0) -> newLine
|
||||
charAt("@", 0) -> exitCommand
|
||||
charAt("+", 0) -> incrCommand
|
||||
charAt("-", 0) -> decrCommand
|
||||
charAt("<", 0) -> shlCommand
|
||||
charAt(">", 0) -> shrCommand
|
||||
charAt(".", 0) -> printCommand
|
||||
charAt(",", 0) -> inputCommand
|
||||
charAt("[", 0) -> repeatCommand
|
||||
charAt("]", 0) -> endCommand
|
||||
|
||||
#Read a character from a line of input.
|
||||
fun readChar -> return
|
||||
(
|
||||
readLine() -> line
|
||||
size(line) -> length
|
||||
|
||||
#Return the ith character and a continuation
|
||||
fun nextFromLine -> i, return
|
||||
(
|
||||
'='(i, length) -> eol
|
||||
if (eol) ->
|
||||
(
|
||||
return(newLine, readChar) #end of line
|
||||
)
|
||||
|
|
||||
charAt(line, i) -> value
|
||||
inc(i) -> i
|
||||
fun next (-> return) nextFromLine(i, return) | next
|
||||
return(value, next)
|
||||
)
|
||||
| nextFromLine
|
||||
|
||||
nextFromLine(0, return) #first character (position 0)
|
||||
)
|
||||
| readChar
|
||||
|
||||
#Define a buffer as a value and a left and right stack
|
||||
fun empty (-> return, throw) throw("Error: out of bounds") | empty
|
||||
fun fill (-> return, throw) return(0, fill) | fill
|
||||
|
||||
fun makeBuffer -> value, left, right, return
|
||||
(
|
||||
fun buffer (-> return) return(value, left, right) | buffer
|
||||
return(buffer)
|
||||
)
|
||||
| makeBuffer
|
||||
|
||||
fun push -> value, stack, return
|
||||
(
|
||||
fun newStack (-> return, throw) return(value, stack) | newStack
|
||||
return(newStack)
|
||||
)
|
||||
| push
|
||||
|
||||
#Brainf*** operations
|
||||
fun noop -> buffer, input, return
|
||||
(
|
||||
return(buffer, input)
|
||||
)
|
||||
| noop
|
||||
|
||||
fun selectOp -> command, return
|
||||
(
|
||||
'='(command, incrCommand) -> eq
|
||||
if (eq) ->
|
||||
(
|
||||
fun increment -> buffer, input, return
|
||||
(
|
||||
buffer() -> value, left, right
|
||||
inc(value) -> value
|
||||
makeBuffer(value, left, right) -> buffer
|
||||
return(buffer, input)
|
||||
)
|
||||
| increment
|
||||
return(increment)
|
||||
)
|
||||
|
|
||||
'='(command, decrCommand) -> eq
|
||||
if (eq) ->
|
||||
(
|
||||
fun decrement -> buffer, input, return
|
||||
(
|
||||
buffer() -> value, left, right
|
||||
dec(value) -> value
|
||||
makeBuffer(value, left, right) -> buffer
|
||||
return(buffer, input)
|
||||
)
|
||||
| decrement
|
||||
return(decrement)
|
||||
)
|
||||
|
|
||||
'='(command, shlCommand) -> eq
|
||||
if (eq) ->
|
||||
(
|
||||
fun shiftLeft -> buffer, input, return
|
||||
(
|
||||
buffer() -> value, left, right
|
||||
push(value, right) -> right
|
||||
left() -> value, left
|
||||
(
|
||||
makeBuffer(value, left, right) -> buffer
|
||||
return(buffer, input)
|
||||
)
|
||||
| message
|
||||
println(message) ->
|
||||
exit()
|
||||
)
|
||||
| shiftLeft
|
||||
return(shiftLeft)
|
||||
)
|
||||
|
|
||||
'='(command, shrCommand) -> eq
|
||||
if (eq) ->
|
||||
(
|
||||
fun shiftRight -> buffer, input, return
|
||||
(
|
||||
buffer() -> value, left, right
|
||||
push(value, left) -> left
|
||||
right() -> value, right
|
||||
(
|
||||
makeBuffer(value, left, right) -> buffer
|
||||
return(buffer, input)
|
||||
)
|
||||
| message
|
||||
println(message) ->
|
||||
exit()
|
||||
)
|
||||
| shiftRight
|
||||
return(shiftRight)
|
||||
)
|
||||
|
|
||||
'='(command, printCommand) -> eq
|
||||
if (eq) ->
|
||||
(
|
||||
fun putChar -> buffer, input, return
|
||||
(
|
||||
buffer() -> value, left, right
|
||||
char(value) -> value
|
||||
'print'(value) -> dummy
|
||||
'flush'() -> dummy
|
||||
return(buffer, input)
|
||||
)
|
||||
| putChar
|
||||
return(putChar)
|
||||
)
|
||||
|
|
||||
'='(command, inputCommand) -> eq
|
||||
if (eq) ->
|
||||
(
|
||||
fun getChar -> buffer, input, return
|
||||
(
|
||||
input() -> letter, input
|
||||
int(letter) -> letter
|
||||
buffer() -> value, left, right
|
||||
makeBuffer(letter, left, right) -> buffer
|
||||
return(buffer, input)
|
||||
)
|
||||
| getChar
|
||||
return(getChar)
|
||||
)
|
||||
|
|
||||
return(noop)
|
||||
)
|
||||
| selectOp
|
||||
|
||||
#Repeat until zero operation
|
||||
fun whileLoop -> buffer, input, continue, break
|
||||
(
|
||||
buffer() -> value, left, right
|
||||
'='(value, 0) -> zero
|
||||
if (zero) ->
|
||||
(
|
||||
break(buffer, input)
|
||||
)
|
||||
|
|
||||
continue(buffer, input) -> buffer, input
|
||||
whileLoop(buffer, input, continue, break)
|
||||
)
|
||||
| whileLoop
|
||||
|
||||
#Convert the Brainf*** program into dodo0 instructions
|
||||
fun compile -> input, endmark, return
|
||||
(
|
||||
input() -> command, input
|
||||
|
||||
'='(command, endmark) -> eq
|
||||
if (eq) ->
|
||||
(
|
||||
return(noop, input) #the end, stop compiling
|
||||
)
|
||||
|
|
||||
#Put in sequence the current operation and the rest of the program
|
||||
fun chainOp -> op, input, return
|
||||
(
|
||||
compile(input, endmark) -> program, input
|
||||
fun exec -> buffer, input, return
|
||||
(
|
||||
op(buffer, input) -> buffer, input
|
||||
program(buffer, input, return)
|
||||
)
|
||||
| exec
|
||||
return(exec, input)
|
||||
)
|
||||
| chainOp
|
||||
|
||||
'='(command, repeatCommand) -> eq
|
||||
if (eq) ->
|
||||
(
|
||||
compile(input, endCommand) -> body, input #compile until "]"
|
||||
|
||||
#Repeat the loop body until zero
|
||||
fun repeat -> buffer, input, return
|
||||
(
|
||||
whileLoop(buffer, input, body, return)
|
||||
)
|
||||
| repeat
|
||||
chainOp(repeat, input, return)
|
||||
)
|
||||
|
|
||||
selectOp(command) -> op
|
||||
chainOp(op, input, return)
|
||||
)
|
||||
| compile
|
||||
|
||||
#Main program
|
||||
compile(readChar, exitCommand) -> program, input
|
||||
makeBuffer(0, empty, fill) -> buffer
|
||||
input() -> nl, input #consume newline from input
|
||||
|
||||
#Execute the program instructions
|
||||
program(buffer, input) -> buffer, input
|
||||
exit()
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
statement ::= next;
|
||||
statement ::= prev;
|
||||
statement ::= inc;
|
||||
statement ::= dec;
|
||||
statement ::= out;
|
||||
statement ::= in;
|
||||
statement ::= "[" while;
|
||||
statement ::= idle;
|
||||
|
||||
next ::= ">";
|
||||
prev ::= "<";
|
||||
inc ::= "+";
|
||||
dec ::= "-";
|
||||
out ::= ".";
|
||||
in ::= ",";
|
||||
idle ::= $any;
|
||||
|
||||
while ::= statement while_r;
|
||||
|
||||
while_r ::= "]";
|
||||
while_r ::= statement while_r;
|
||||
|
||||
tape ::= statement statements;
|
||||
|
||||
statements ::= statement statements;
|
||||
statements ::= $eps;
|
||||
|
||||
start ::= tape;
|
||||
|
||||
tape =>
|
||||
// 1: append
|
||||
&subject
|
||||
// 2: goto
|
||||
&subject
|
||||
// 3: loop
|
||||
&subject
|
||||
// 4: inc action
|
||||
&1 1 &echo
|
||||
// 5: dec action
|
||||
&1 -1 &echo
|
||||
// 6: next action
|
||||
&2 1 &echo
|
||||
// 7: prev action
|
||||
&2 -1 &echo
|
||||
// 8: output action
|
||||
&__write &nil 'program'output &wrap
|
||||
// 9: group
|
||||
&nil
|
||||
sys'dynamics'groupvariable
|
||||
&std'basic'factory'array_size &sys'vm'routines'egetprop 1024 &prop
|
||||
&std'basic'factory'pattern &sys'vm'routines'egetprop 0 std'basic'widecharvar &prop
|
||||
&union2
|
||||
std'basic'factory'patternarrayfactory
|
||||
std'basic'factory'newarray
|
||||
0 ^refer
|
||||
~ sys'dynamics'group_member ^append
|
||||
// :: append method
|
||||
&1 &__append &9 &prop
|
||||
~ sys'dynamics'group_member ^append
|
||||
// :: goto method
|
||||
&2 &__append &std'dictionary'index &9 &wrap &prop
|
||||
~ sys'dynamics'group_member ^append
|
||||
// :: loop method
|
||||
&3 &__run &std'patterns'ewhilenotzero &9 &wrap &prop
|
||||
~ sys'dynamics'group_member ^append
|
||||
|
||||
// 10: in action
|
||||
&__save &__get &nil 'program'input &nil &action &wrap
|
||||
|
||||
// build command batch
|
||||
&cast
|
||||
$body
|
||||
&9
|
||||
^ invoke;
|
||||
|
||||
inc => &4 |= $body;
|
||||
dec => &5 |= $body;
|
||||
next => &6 |= $body;
|
||||
prev => &7 |= $body;
|
||||
out => &8 |= $body;
|
||||
in => &10 |= $body;
|
||||
while => &3 &__eval &cast $body &wrap &echo |=;
|
||||
|
|
@ -10,29 +10,21 @@
|
|||
I = 1 !First element of the prog.
|
||||
|
||||
DO WHILE(I.LE.LEN(PROG)) !Off the end yet?
|
||||
C = PROG(I:I) !Load the opcode fingered by I.
|
||||
I = I + 1 !Advance one. The classic.
|
||||
SELECT CASE(C) !Now decode the instruction.
|
||||
CASE(">") !Move the data finger one place right.
|
||||
D = D + 1
|
||||
CASE("<") !Move the data finger one place left.
|
||||
D = D - 1
|
||||
CASE("+") !Add one to the fingered datum.
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 1)
|
||||
CASE("-") !Subtract one.
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) - 1)
|
||||
CASE(".") !Write a character.
|
||||
WRITE (MSG,1) STORE(D)
|
||||
CASE(",") !Read a character.
|
||||
READ (KBD,1) STORE(D)
|
||||
CASE("[") !Conditionally, surge forward.
|
||||
IF (ICHAR(STORE(D)).EQ.0) CALL SEEK(+1)
|
||||
CASE("]") !Conditionally, retreat.
|
||||
IF (ICHAR(STORE(D)).NE.0) CALL SEEK(-1)
|
||||
CASE DEFAULT !For all others,
|
||||
!Do nothing.
|
||||
END SELECT !That was simple.
|
||||
END DO !See what comes next.
|
||||
C = PROG(I:I) !Load the opcode fingered by I.
|
||||
I = I + 1 !Advance one. The classic.
|
||||
SELECT CASE(C) !Now decode the instruction.
|
||||
CASE(">"); D = D + 1 !Move the data finger one place right.
|
||||
CASE("<"); D = D - 1 !Move the data finger one place left.
|
||||
CASE("+"); STORE(D) = CHAR(ICHAR(STORE(D)) + 1) !Add one to the fingered datum.
|
||||
CASE("-"); STORE(D) = CHAR(ICHAR(STORE(D)) - 1) !Subtract one.
|
||||
CASE("."); WRITE (MSG,1) STORE(D) !Write a character.
|
||||
CASE(","); READ (KBD,1) STORE(D) !Read a character.
|
||||
CASE("["); IF (ICHAR(STORE(D)).EQ.0) CALL SEEK(+1) !Conditionally, surge forward.
|
||||
CASE("]"); IF (ICHAR(STORE(D)).NE.0) CALL SEEK(-1) !Conditionally, retreat.
|
||||
CASE DEFAULT !For all others,
|
||||
!Do nothing.
|
||||
END SELECT !That was simple.
|
||||
END DO !See what comes next.
|
||||
|
||||
1 FORMAT (A1,$) !One character, no advance to the next line.
|
||||
CONTAINS !Now for an assistant.
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ Closedown.
|
|||
END IF !Rather than just one at a time.
|
||||
END IF !Curse the double evaluation of WHILE(L < LEN(PROG) & ...)
|
||||
END FUNCTION RATTLE !Computers excel at counting.
|
||||
END SUBROUTINE BRAINFORT!They only need be direction as to what to count...
|
||||
END SUBROUTINE BRAINFORT!Their only need be direction as to what to count...
|
||||
END MODULE BRAIN !Simple in itself.
|
||||
|
||||
PROGRAM POKE !A tester.
|
||||
|
|
|
|||
|
|
@ -4,18 +4,17 @@ class BrainfuckProgram {
|
|||
def instructionPointer = 0, dataPointer = 0
|
||||
|
||||
def execute() {
|
||||
while (instructionPointer < program.size()) {
|
||||
while (instructionPointer < program.size())
|
||||
switch(program[instructionPointer++]) {
|
||||
case '>': dataPointer++; break;
|
||||
case '<': dataPointer--; break;
|
||||
case '+': memory[dataPointer] = memoryValue + 1; break;
|
||||
case '-': memory[dataPointer] = memoryValue - 1; break;
|
||||
case ',': memory[dataPointer] = System.in.read(); break;
|
||||
case '.': print((char)memoryValue); break;
|
||||
case '[': handleLoopStart(); break;
|
||||
case ']': handleLoopEnd(); break;
|
||||
case '+': memory[dataPointer] = memoryValue + 1; break
|
||||
case '-': memory[dataPointer] = memoryValue - 1; break
|
||||
case ',': memory[dataPointer] = System.in.read(); break
|
||||
case '.': print String.valueOf(Character.toChars(memoryValue)); break
|
||||
case '[': handleLoopStart(); break
|
||||
case ']': handleLoopEnd(); break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getMemoryValue() { memory[dataPointer] ?: 0 }
|
||||
|
|
@ -23,13 +22,12 @@ class BrainfuckProgram {
|
|||
private handleLoopStart() {
|
||||
if (memoryValue) return
|
||||
|
||||
int depth = 1;
|
||||
while (instructionPointer < program.size()) {
|
||||
int depth = 1
|
||||
while (instructionPointer < program.size())
|
||||
switch(program[instructionPointer++]) {
|
||||
case '[': depth++; break;
|
||||
case ']': if (!(--depth)) return;
|
||||
case '[': depth++; break
|
||||
case ']': if (!(--depth)) return
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException('Could not find matching end bracket')
|
||||
}
|
||||
|
||||
|
|
@ -37,8 +35,8 @@ class BrainfuckProgram {
|
|||
int depth = 0
|
||||
while (instructionPointer >= 0) {
|
||||
switch(program[--instructionPointer]) {
|
||||
case ']': depth++; break;
|
||||
case '[': if (!(--depth)) return; break;
|
||||
case ']': depth++; break
|
||||
case '[': if (!(--depth)) return; break
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException('Could not find matching start bracket')
|
||||
|
|
|
|||
51
Task/Execute-Brain----/Kotlin/execute-brain----.kotlin
Normal file
51
Task/Execute-Brain----/Kotlin/execute-brain----.kotlin
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
// version 1.1.2
|
||||
|
||||
class Brainf__k(val prog: String, memSize: Int) {
|
||||
private val mem = IntArray(memSize)
|
||||
private var ip = 0
|
||||
private var dp = 0
|
||||
private val memVal get() = mem.getOrElse(dp) { 0 }
|
||||
|
||||
fun execute() {
|
||||
while (ip < prog.length) {
|
||||
when (prog[ip++]) {
|
||||
'>' -> dp++
|
||||
'<' -> dp--
|
||||
'+' -> mem[dp] = memVal + 1
|
||||
'-' -> mem[dp] = memVal - 1
|
||||
',' -> mem[dp] = System.`in`.read()
|
||||
'.' -> print(memVal.toChar())
|
||||
'[' -> handleLoopStart()
|
||||
']' -> handleLoopEnd()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleLoopStart() {
|
||||
if (memVal != 0) return
|
||||
var depth = 1
|
||||
while (ip < prog.length) {
|
||||
when (prog[ip++]) {
|
||||
'[' -> depth++
|
||||
']' -> if (--depth == 0) return
|
||||
}
|
||||
}
|
||||
throw IllegalStateException("Could not find matching end bracket")
|
||||
}
|
||||
|
||||
private fun handleLoopEnd() {
|
||||
var depth = 0
|
||||
while (ip >= 0) {
|
||||
when (prog[--ip]) {
|
||||
']' -> depth++
|
||||
'[' -> if (--depth == 0) return
|
||||
}
|
||||
}
|
||||
throw IllegalStateException("Could not find matching start bracket")
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val prog = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
|
||||
Brainf__k(prog, 10).execute()
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
import strutils
|
||||
|
||||
proc jumpBackward(pos: var int, program: string) =
|
||||
var level = 1
|
||||
while pos > 0 and level != 0:
|
||||
dec pos
|
||||
case program[pos]
|
||||
of '[':
|
||||
dec level
|
||||
of ']':
|
||||
inc level
|
||||
else:
|
||||
discard 1
|
||||
dec pos
|
||||
|
||||
proc jumpForward(pos: var int, program: string) =
|
||||
var level = 1
|
||||
while pos < program.len and level != 0:
|
||||
inc pos
|
||||
case program[pos]
|
||||
of ']':
|
||||
inc level
|
||||
of '[':
|
||||
dec level
|
||||
else:
|
||||
discard 1
|
||||
|
||||
proc bf(program: string) =
|
||||
var tape: array[0..20, int]
|
||||
var pointer = 0
|
||||
var pos = 0
|
||||
var indent = 0
|
||||
|
||||
while pos < program.len:
|
||||
var token = program[pos]
|
||||
case token
|
||||
of '+':
|
||||
inc tape[pointer]
|
||||
of '-':
|
||||
dec tape[pointer]
|
||||
of ',':
|
||||
tape[pointer] = int(stdin.readChar())
|
||||
of '.':
|
||||
stdout.write(chr(tape[pointer]))
|
||||
of '[':
|
||||
if tape[pointer] == 0:
|
||||
jumpForward(pos, program)
|
||||
of ']':
|
||||
if tape[pointer] != 0:
|
||||
jumpBackward(pos, program)
|
||||
of '>':
|
||||
inc pointer
|
||||
of '<':
|
||||
dec pointer
|
||||
else:
|
||||
discard 1
|
||||
inc pos
|
||||
|
||||
var addition = ",>++++++[<-------->-],[<+>-]<."
|
||||
var hello_world = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
|
||||
|
||||
bf(addition)
|
||||
# bf(hello_world)
|
||||
70
Task/Execute-Brain----/Objeck/execute-brain----.objeck
Normal file
70
Task/Execute-Brain----/Objeck/execute-brain----.objeck
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
class Brainfu_k {
|
||||
@program : String; @mem : Int[];
|
||||
@ip : Int; @dp : Int;
|
||||
|
||||
New(program : String, size : Int) {
|
||||
@program := program;
|
||||
@mem := Int → New[size];
|
||||
}
|
||||
|
||||
function : Main(args : String[]) ~ Nil {
|
||||
if(args → Size() = 2) {
|
||||
Brainfu_k → New(args[0], args[1] → ToInt()) → Execute();
|
||||
};
|
||||
}
|
||||
|
||||
method : Execute() ~ Nil {
|
||||
while(@ip < @program → Size()) {
|
||||
instr := @program → Get(@ip);
|
||||
select(instr) {
|
||||
label '>': { @dp += 1; }
|
||||
label '<': { @dp -= 1; }
|
||||
label '+': { @mem[@dp] := @mem[@dp] + 1; }
|
||||
label '-': { @mem[@dp] := @mem[@dp] - 1; }
|
||||
label '.': { value := @mem[@dp] → As(Char); value → Print(); }
|
||||
label ',': { @mem[@dp] := Read(); }
|
||||
label '[': { JumpForward(); }
|
||||
label ']': { JumpBack(); }
|
||||
};
|
||||
@ip += 1;
|
||||
};
|
||||
}
|
||||
|
||||
method : JumpForward() ~ Nil {
|
||||
depth := 1;
|
||||
if(@mem[@dp] = 0) {
|
||||
while(@ip < @program → Size()) {
|
||||
instr := @program → Get(@ip);
|
||||
if(instr = ']') {
|
||||
depth -= 1; if(depth = 0) { return; };
|
||||
}
|
||||
else if(instr = '[') { depth += 1; };
|
||||
@ip += 1;
|
||||
};
|
||||
"*** Unbalanced jump ***" → ErrorLine();
|
||||
Runtime → Exit(1);
|
||||
};
|
||||
}
|
||||
|
||||
method : JumpBack() ~ Nil {
|
||||
depth := 1;
|
||||
if(@mem[@dp] <> 0) {
|
||||
while(@ip > 0) {
|
||||
@ip -= 1;
|
||||
instr := @program → Get(@ip);
|
||||
if(instr = '[') {
|
||||
depth -= 1; if(depth = 0) { return; };
|
||||
}
|
||||
else if(instr = ']') { depth += 1; };
|
||||
};
|
||||
"*** Unbalanced jump ***" → ErrorLine();
|
||||
Runtime → Exit(1);
|
||||
};
|
||||
}
|
||||
|
||||
method : Read() ~ Int {
|
||||
in := IO.Console → ReadString();
|
||||
if(in → Size() > 0) { return in → ToInt(); };
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
40
Task/Execute-Brain----/Ol/execute-brain----.ol
Normal file
40
Task/Execute-Brain----/Ol/execute-brain----.ol
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
(define (bf program stack-length)
|
||||
(let ((program (string-append program "]"))
|
||||
(program-counter 0)
|
||||
(stack (make-vector stack-length 0))
|
||||
(stack-pointer 0))
|
||||
(letrec ((skip (lambda (PC sp)
|
||||
(let loop ((pc PC) (sp sp))
|
||||
(let ((ch (string-ref program pc))
|
||||
(pc (+ pc 1)))
|
||||
(case ch
|
||||
(#\] (list pc sp))
|
||||
(#\[ (apply loop (skip pc sp)))
|
||||
(else
|
||||
(loop pc sp)))))))
|
||||
(step (lambda (PC SP)
|
||||
(let loop ((pc PC) (sp SP))
|
||||
(let ((ch (string-ref program pc))
|
||||
(pc (+ pc 1)))
|
||||
(case ch
|
||||
(#\] (list (- PC 1) sp))
|
||||
(#\[ (if (eq? (vector-ref stack sp) 0)
|
||||
(apply loop (skip pc sp))
|
||||
(apply loop (step pc sp))))
|
||||
(#\+ (set-ref! stack sp (+ (vector-ref stack sp) 1))
|
||||
(loop pc sp))
|
||||
(#\- (set-ref! stack sp (- (vector-ref stack sp) 1))
|
||||
(loop pc sp))
|
||||
(#\> (loop pc (+ sp 1)))
|
||||
(#\< (loop pc (- sp 1)))
|
||||
(#\. (display (make-string 1 (vector-ref stack sp)))
|
||||
(loop pc sp))
|
||||
(else
|
||||
(loop pc sp))))))))
|
||||
(step 0 0))))
|
||||
|
||||
; testing:
|
||||
; (bf ",++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>." 30000)
|
||||
; ==> Hello World!
|
||||
; (bf ">>++++[<++++[<++++>-]>-]<<.[-]++++++++++." 30000)
|
||||
; ==> @
|
||||
96
Task/Execute-Brain----/Pascal/execute-brain----.pascal
Normal file
96
Task/Execute-Brain----/Pascal/execute-brain----.pascal
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
program rcExceuteBrainF;
|
||||
|
||||
uses
|
||||
Crt;
|
||||
|
||||
Const
|
||||
DataSize= 1024; // Size of Data segment
|
||||
MaxNest= 1000; // Maximum nesting depth of []
|
||||
|
||||
procedure ExecuteBF(Source: string);
|
||||
var
|
||||
Dp: pByte; // Used as the Data Pointer
|
||||
DataSeg: Pointer; // Start of the DataSegment (Cell 0)
|
||||
Ip: pChar; // Used as instruction Pointer
|
||||
LastIp: Pointer; // Last adr of code.
|
||||
JmpStack: array[0..MaxNest-1] of pChar; // Stack to Keep track of active "[" locations
|
||||
JmpPnt: Integer; // Stack pointer ^^
|
||||
JmpCnt: Word; // Used to count brackets when skipping forward.
|
||||
|
||||
|
||||
begin
|
||||
|
||||
// Set up then data segment
|
||||
getmem(DataSeg,dataSize);
|
||||
dp:=DataSeg;
|
||||
fillbyte(dp^,dataSize,0);
|
||||
|
||||
// Set up the JmpStack
|
||||
JmpPnt:=-1;
|
||||
|
||||
// Set up Instruction Pointer
|
||||
Ip:=@Source[1];
|
||||
LastIp:=@Source[length(source)];
|
||||
if Ip=nil then exit;
|
||||
|
||||
// Main Execution loop
|
||||
repeat { until Ip > LastIp }
|
||||
Case Ip^ of
|
||||
'<': dec(dp);
|
||||
'>': inc(dp);
|
||||
'+': inc(dp^);
|
||||
'-': dec(dp^);
|
||||
'.': write(stdout,chr(dp^));
|
||||
',': dp^:=ord(readkey);
|
||||
'[': if dp^=0 then
|
||||
begin
|
||||
// skip forward until matching bracket;
|
||||
JmpCnt:=1;
|
||||
while (JmpCnt>0) and (ip<=lastip) do
|
||||
begin
|
||||
inc(ip);
|
||||
Case ip^ of
|
||||
'[': inc(JmpCnt);
|
||||
']': dec(JmpCnt);
|
||||
#0: begin
|
||||
Writeln(StdErr,'Error brackets don''t match');
|
||||
halt;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
// Add location to Jump stack
|
||||
inc(JmpPnt);
|
||||
JmpStack[jmpPnt]:=ip;
|
||||
end;
|
||||
']': if dp^>0 then
|
||||
// Jump Back to matching [
|
||||
ip:=JmpStack[jmpPnt]
|
||||
else
|
||||
// Remove Jump from stack
|
||||
dec(jmpPnt);
|
||||
end;
|
||||
inc(ip);
|
||||
until Ip>lastIp;
|
||||
freemem(DataSeg,dataSize);
|
||||
end;
|
||||
|
||||
Const
|
||||
HelloWorldWiki = '++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>'+
|
||||
'---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.';
|
||||
|
||||
pressESCtoCont = '>[-]+++++++[<++++++++++>-]<->>[-]+++++++[<+++++++++++'+
|
||||
'+>-]<->>[-]++++[<++++++++>-]+>[-]++++++++++[<++++++++'+
|
||||
'++>-]>[-]++++++++[<++++++++++++++>-]<.++.+<.>..<<.<<.'+
|
||||
'-->.<.>>.>>+.-----.<<.[<<+>>-]<<.>>>>.-.++++++.<++++.'+
|
||||
'+++++.>+.<<<<++.>+[>+<--]>++++...';
|
||||
waitForEsc = '[-]>[-]++++[<+++++++>-]<->[-]>+[[-]<<[>+>+<<-]'+'>>[<'+
|
||||
'<+>>-],<[->-<]>]';
|
||||
|
||||
begin
|
||||
// Execute "Hello World" example from Wikipedia
|
||||
ExecuteBF(HelloWorldWiki);
|
||||
|
||||
// Print text "press ESC to continue....." and wait for ESC to be pressed
|
||||
ExecuteBF(pressESCtoCont+waitForEsc);
|
||||
end.
|
||||
76
Task/Execute-Brain----/VBScript/execute-brain----.vb
Normal file
76
Task/Execute-Brain----/VBScript/execute-brain----.vb
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
'Execute BrainFuck
|
||||
'VBScript Implementation
|
||||
|
||||
'The Main Interpreter
|
||||
Function BFInpt(s, sp, d, dp, i, ip, o)
|
||||
While sp < Len(s)
|
||||
Select Case Mid(s, sp + 1, 1)
|
||||
Case "+"
|
||||
newd = Asc(d(dp)) + 1
|
||||
If newd > 255 Then newd = newd Mod 256 'To take account of values over 255
|
||||
d(dp) = Chr(newd)
|
||||
Case "-"
|
||||
newd = Asc(d(dp)) - 1
|
||||
If newd < 0 Then newd = (newd Mod 256) + 256 'To take account of negative values
|
||||
d(dp) = Chr(newd)
|
||||
Case ">"
|
||||
dp = dp + 1
|
||||
If dp > UBound(d) Then
|
||||
ReDim Preserve d(UBound(d) + 1)
|
||||
d(dp) = Chr(0)
|
||||
End If
|
||||
Case "<"
|
||||
dp = dp - 1
|
||||
Case "."
|
||||
o = o & d(dp)
|
||||
Case ","
|
||||
If ip = Len(i) Then d(dp) = Chr(0) Else ip = ip + 1 : d(dp) = Mid(i, ip, 1)
|
||||
Case "["
|
||||
If Asc(d(dp)) = 0 Then
|
||||
bracket = 1
|
||||
While bracket And sp < Len(s)
|
||||
sp = sp + 1
|
||||
If Mid(s, sp + 1, 1) = "[" Then
|
||||
bracket = bracket + 1
|
||||
ElseIf Mid(s, sp + 1, 1) = "]" Then
|
||||
bracket = bracket - 1
|
||||
End If
|
||||
WEnd
|
||||
Else
|
||||
pos = sp - 1
|
||||
sp = sp + 1
|
||||
If BFInpt(s, sp, d, dp, i, ip, o) Then sp = pos
|
||||
End If
|
||||
Case "]"
|
||||
BFInpt = Asc(d(dp)) <> 0
|
||||
Exit Function
|
||||
End Select
|
||||
sp = sp + 1
|
||||
WEnd
|
||||
End Function
|
||||
|
||||
'This Prepares the Intepreter
|
||||
Function BFuck(source, input)
|
||||
Dim data() : ReDim data(0)
|
||||
data(0) = Chr(0)
|
||||
DataPtr = 0
|
||||
SrcPtr = 0
|
||||
InputPtr = 0
|
||||
output = ""
|
||||
|
||||
BFInpt source , SrcPtr , _
|
||||
data , DataPtr , _
|
||||
input , InputPtr , _
|
||||
output
|
||||
BFuck = output
|
||||
End Function
|
||||
|
||||
|
||||
'Sample Run
|
||||
'The input is a string. The first character will be scanned by the first comma
|
||||
'in the code, the next character will be scanned by the next comma, and so on.
|
||||
|
||||
code = ">++++++++[<+++++++++>-]<.>>+>+>++>[-]+<[>[->+<<++++>]<<]>.+++++++..+++.>" & _
|
||||
">+++++++.<<<[[-]<[-]>]<+++++++++++++++.>>.+++.------.--------.>>+.>++++."
|
||||
inpstr = ""
|
||||
WScript.StdOut.Write BFuck(code, inpstr)
|
||||
29
Task/Execute-Brain----/Zkl/execute-brain-----1.zkl
Normal file
29
Task/Execute-Brain----/Zkl/execute-brain-----1.zkl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
fcn bf(pgm,input=""){ pgm=pgm.text; // handle both String and Data
|
||||
const CELLS=0d30_000;
|
||||
if(Void==pgm.span("[","]")){ println("Mismatched brackets"); return(); }
|
||||
fcn(code,z,jmpTable){ // build jump table (for [ & ])
|
||||
if(span:=code.span("[","]")){
|
||||
a,b:=span; b+=a-1; jmpTable[a+z]=b+z; jmpTable[b+z]=a+z;
|
||||
self.fcn(code[a+1,b-a-1],z+a+1,jmpTable);
|
||||
self.fcn(code[b+1,*],z+b+1,jmpTable);
|
||||
}
|
||||
}(pgm,0,jmpTable:=Dictionary());
|
||||
|
||||
tape:=CELLS.pump(Data(CELLS,Int),0);
|
||||
ip:=dp:=0; input=input.walker();
|
||||
try{
|
||||
while(1){
|
||||
switch(pgm[ip]){
|
||||
case(">"){ dp+=1 }
|
||||
case("<"){ dp-=1 }
|
||||
case("+"){ tape[dp]=tape[dp]+1 }
|
||||
case("-"){ tape[dp]=tape[dp]-1 }
|
||||
case("."){ tape[dp].toChar().print() }
|
||||
case(","){ c:=input._next(); tape[dp]=(c and input.value or 0); }
|
||||
case("["){ if(0==tape[dp]){ ip=jmpTable[ip] }}
|
||||
case("]"){ if(tape[dp]) { ip=jmpTable[ip] }}
|
||||
}
|
||||
ip+=1;
|
||||
} // while
|
||||
}catch(IndexError){} // read past end of tape == end of program
|
||||
}
|
||||
27
Task/Execute-Brain----/Zkl/execute-brain-----2.zkl
Normal file
27
Task/Execute-Brain----/Zkl/execute-brain-----2.zkl
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// print Hello World!
|
||||
bf("++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++.."
|
||||
"+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.");
|
||||
|
||||
// print @
|
||||
bf(">>++++[<++++[<++++>-]>-]<<.[-]++++++++++.");
|
||||
|
||||
// read 3 characters, inc by 1 and print: "abc"-->"bcd"
|
||||
bf(",>,>,><<<[+.>]","abc"); println();
|
||||
|
||||
bf(",>++++++[<-------->-],[<+>-]<.","23"); println(); // add two digits
|
||||
|
||||
// "Enter your name:", prints name backwards
|
||||
bf(">+++++++++++++++++++++++++++++++++++++++++"
|
||||
"++++++++++++++++++++++++++++.++++++++++++++"
|
||||
"+++++++++++++++++++++++++++.++++++.-------------"
|
||||
"--.+++++++++++++.>++++++++++++++++++++++++++"
|
||||
"++++++.<+++++++.----------.++++++.---.>.<----.----------"
|
||||
"---.++++++++++++.--------.-----------------------------------"
|
||||
"--------.>.<>>>+[>,----------]++++++++++.<[+++++++++"
|
||||
"+.<][<]","Sam Iam\n");
|
||||
|
||||
// word count
|
||||
bf(File("wc.b").read(),"This\n is a test");
|
||||
|
||||
// rot13
|
||||
bf(File("rot13.b").read(),"This is a test 123");
|
||||
Loading…
Add table
Add a link
Reference in a new issue