Basicprogramming(.org) > General questions and discussions

Can you write a program for this Interpreter?

(1/4) > >>

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