Basicprogramming(.org) > General questions and discussions
Can you write a program for this Interpreter?
B+:
--- Code: ---'BF in QB.bas for SmallBASIC 0.12.9 (B+=MGA) 2017-07-22
' I just translated some QB code from Rosetta to SmallBASIC
' and tested a couple of programs Hello World, Goodbye World
' count down also found at Rosetta Code.
CLS
memsize = 20000
instChars = "+-<>.,[]" 'valid characters
ptr = 0 'memory pointer
source = ""
INPUT "BF Filename (if blank will use lineput for program) ... "; filename
IF filename = "" THEN
? "Please enter the BF program line to intepret."
LINEINPUT source
ELSE
OPEN filename FOR INPUT AS #1
repeat
LINEINPUT #1, FLINE
source = source + FLINE
UNTIL EOF(1)
close #1
END IF
if len(source) < 1 then
? "No source code to BF."
pause
stop
'else
' ? source
end if
'let's clean the code up, check bracket balance
bktCnt = 0
code = ""
FOR i = 1 TO LEN(source)
char = MID(source, i, 1)
'check to see if this is a valid instruction character
IF INSTR(instChars, char) THEN
code = code + char
'count brackets
IF char = "[" THEN bktCnt = bktCnt + 1
IF char = "]" THEN bktCnt = bktCnt - 1
END IF
NEXT
IF bktCnt THEN 'mismatched brackets
PRINT "Uneven brackets"
pause
stop
else
? "Code: ";code
END IF
'
DIM memory(memsize)
inLine = "" 'input buffer
FOR i = 1 TO LEN(code) 'loop through the code
instruction = MID(code, i, 1) 'get the instruction we're on
SELECT CASE instruction
CASE "+"
memory(ptr) = memory(ptr) + 1
CASE "-"
memory(ptr) = memory(ptr) - 1
CASE "."
PRINT CHR(memory(ptr));
CASE ","
IF inLine = "" THEN LINEINPUT inLine 'buffer input
inChar = LEFT(inLine, 1) 'take the first char off the buffer
inLine = MID(inLine, 2) 'delete it from the buffer
memory(ptr) = ASC(inChar) 'use it
CASE ">"
ptr = ptr + 1
IF ptr > 20000 THEN
PRINT "Memory pointer out of range"
pause
stop
END IF
CASE "<"
ptr = ptr - 1
IF ptr < 0 THEN
PRINT "Memory pointer out of range"
pause
stop
END IF
CASE "["
IF memory(ptr) = 0 THEN
bktCnt = 1 'count the bracket we're on
i = i + 1 'move the code pointer to the next char
WHILE bktCnt <> 0
'count nested loops till we find the matching one
IF MID(code, i, 1) = "]" THEN bktCnt = bktCnt - 1
IF MID(code, i, 1) = "[" THEN bktCnt = bktCnt + 1
i = i + 1 'search forward
WEND
END IF
CASE "]"
IF memory(ptr) <> 0 THEN
bktCnt = -1'count the bracket we're on
i = i - 1'move the code pointer back a char
WHILE bktCnt <> 0
'count nested loops till we fine the matching one
IF MID(code, i, 1) = "]" THEN bktCnt = bktCnt - 1
IF MID(code, i, 1) = "[" THEN bktCnt = bktCnt + 1
i = i - 1 'search backwards
WEND
END IF
END SELECT
NEXT
?:? "done"
pause
--- End code ---
Feel free to change memsize!
bf count down.txt
++++++++++++++++++++++++++++++++[>+>+<<-]>>+++++++++++++++++++++++++<<++++++++++[>>.-<.<-]
bf goodbye.txt
++++++++++[>+>+++>++++>+++++++>++++++++>+++++++++>++++++++++>+++++++++++>++++++++++++<<<<<<<<<-]>>>>+.>>>>+..<.<++++++++.>>>+.<<+.<<<<++++.<++.>>>+++++++.>>>.+++.<+++++++.--------.<<<<<+.<+++.---.
bf hello.txt
++++++++[>++++[>++>+++>+++>+<<<<-]>+>->+>>+[<]<-]>>.>>---.+++++++..+++.>.<<-.>.+++.------.--------.>+.>++.+++.
ZXDunny:
I wrote an interpreter in SpecBAS a while ago:
--- Code: ---10 REM Brainfuck interpreter
20 c$="++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
30 BANK NEW bfdat,32768: i=0,d=0,a$="<>+-.,[]"
40 i+=1: IF i>LEN c$ or not (c$(i) in a$) THEN STOP else go sub code c$(i): GO TO 40
43 v=PEEK(bfdat,d): INC v,1,0 TO 255: POKE bfdat,d,v: return
44 INPUT b$: POKE bfdat,d,CODE b$:return
45 LET v=PEEK(bfdat,d): DEC v,1,0 TO 255: POKE bfdat,d,v: return
46 PRINT CHR$(PEEK(bfdat,d));:return
60 d-=1:return
62 d+=1:return
91 IF PEEK(bfdat,d)=0 THEN b=1:GO SUB 300: end if: return
93 IF PEEK(bfdat,d)<>0 THEN b=1:GO SUB 400: end if: return
300 i+=1: IF i>LEN c$ THEN STOP ELSE IF c$(i)="[" THEN b+=1
310 IF c$(i)="]" THEN b-=1: IF b=0 THEN RETURN
320 GO TO 300
400 i-=1: IF i<1 THEN STOP ELSE IF c$(i)="]" THEN b+=1
410 IF c$(i)="[" THEN b-=1: IF b=0 THEN RETURN
420 GO TO 400
--- End code ---
I'm not sure I can get it any smaller. Put your BF code into the c$ variable, and RUN to interpret.
B+:
Hi D,
That is one sweet little interpreter! Could it be the smallest Turing complete?
The question remains, How do I write programs that do things with these crazy simple interpreters.
Having only yesterday double translated BF, I have no clues but intend to look into the matter. A possible IDE?
B+:
To All,
I have started a little study of how to write a program in BF and was at once taken back by how tedious a project that might be!
Yikes! The rigmarole needed just to print one letter!
Already, I have written a transition program to eliminate counting how many + - < 0r > signs/commands you have to type in a row.
I have eliminated 2 commands and changed incrementing or decrementing the ptr with a @# command where # is a positive or negative integer.
Same deal with + - commands, replaced by ^# (^ sort of looks like delta), # again is a positive or negative integer.
I call the new Interpreter BQ for Brain Quickie or Be Quick (about it).
Hello World! program now looks like this:
^8[@1^4[@1^2@1^3@1^3@1^1@-4^-1]@1^1@1^-1@1^1@2^1[@-1]@-1^-1]@2.@2^-3.^7..^3.@1.@-2^-1.@1.^3.^-6.^-8.@1^1.@1^2.^3.
Ha! I thought it might be shorter but every single < has to be replaced by @-1 and single - replaced by ^-1, 1 for 3 is not good deal.
But at least you are saved from typing x amount of +-< or > in a row!
Alas, it also probably spoils the purity of BF with all the extra number characters added to a program.
--- Code: ---'BQ Interpreter.bas for SmallBASIC 0.12.9 (B+=MGA) 2017-07-22
' try a little mod of the BF Interpreter
CLS
memsize = 20000
instChars = "^@.,[]-1234567890" 'valid characters
ptr = 0 'memory pointer
source = ""
INPUT "BQ Filename (if blank will use lineput for program) ... "; filename
IF filename = "" THEN
? "Please enter the BF program line to intepret."
LINEINPUT source
ELSE
OPEN filename FOR INPUT AS #1
repeat
LINEINPUT #1, FLINE
source = source + FLINE
UNTIL EOF(1)
close #1
END IF
if len(source) < 1 then
? "No source code to BF."
pause
stop
'else
' ? source
end if
'let's clean the code up, check bracket balance
bktCnt = 0
code = ""
FOR i = 1 TO LEN(source)
char = MID(source, i, 1)
'check to see if this is a valid instruction character
IF INSTR(instChars, char) THEN
code = code + char
'count brackets
IF char = "[" THEN bktCnt = bktCnt + 1
IF char = "]" THEN bktCnt = bktCnt - 1
END IF
NEXT
IF bktCnt THEN 'mismatched brackets
PRINT "Uneven brackets"
pause
stop
else
? "Code: ";code
END IF
'
DIM memory(memsize)
inLine = "" 'input buffer
cmd = "" : ds = ""
FOR i = 1 TO LEN(code) 'loop through the code
c = MID(code, i, 1) 'get the instruction we're on
if instr("-1234567890", c) then ds = ds + c
if instr("^@.,[]", c) or i = len(code) then 'hit next command
if cmd <> "" then 'execute unfinished command
d = val(ds)
'exec last cmd
if cmd = "^" then memory(ptr) = memory(ptr) + d
if cmd = "@" then
ptr = ptr + d
if ptr < 0 or ptr > memsize then
? "Pointer out of range." : pause : stop
end if
end if
cmd = "" : ds = ""
end if
select case c
case "^" : cmd = "^"
case "@" : cmd = "@"
CASE "." : ? CHR(memory(ptr));
CASE ","
IF inLine = "" THEN LINEINPUT inLine 'buffer input
inChar = LEFT(inLine, 1) 'take the first char off the buffer
inLine = MID(inLine, 2) 'delete it from the buffer
memory(ptr) = ASC(inChar) 'use it
CASE "["
IF memory(ptr) = 0 THEN
bktCnt = 1 'count the bracket we're on
i = i + 1 'move the code pointer to the next char
WHILE bktCnt <> 0
'count nested loops till we find the matching one
IF MID(code, i, 1) = "]" THEN bktCnt = bktCnt - 1
IF MID(code, i, 1) = "[" THEN bktCnt = bktCnt + 1
i = i + 1 'search forward
WEND
END IF
CASE "]"
IF memory(ptr) <> 0 THEN
bktCnt = -1'count the bracket we're on
i = i - 1'move the code pointer back a char
WHILE bktCnt <> 0
'count nested loops till we fine the matching one
IF MID(code, i, 1) = "]" THEN bktCnt = bktCnt - 1
IF MID(code, i, 1) = "[" THEN bktCnt = bktCnt + 1
i = i - 1 'search backwards
WEND
END IF
END SELECT
end if
NEXT
?:? "done"
pause
--- End code ---
I call it transitional because I have an idea for two more commands to set ptr and memory values with absolute numbers instead of incrementing.
That! should save time and tedium.
They say BF is Turing Complete, so how is an IF THEN coded or decision branching handled? Seems to me that not only do you need a memory pointer, you need a program pointer.
ScriptBasic:
Why has BASIC programming turned into a lets redefine the wheel again? Doesn't anyone like BASIC programming anymore? Is creating BASIC like interpreters what BASIC is all about?
Can you imagine 100 variations of QB or VB?
Navigation
[0] Message Index
[#] Next page
Go to full version