331 lines
4.6 KiB
Text
331 lines
4.6 KiB
Text
;
|
|
; 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
|