Author Topic: Brainfuck Interpreter  (Read 28553 times)

0 Members and 1 Guest are viewing this topic.

Offline STxAxTIC

  • Library Staff
  • Forum Resident
  • Posts: 1091
  • he lives
Re: Brainfuck Interpreter
« Reply #15 on: March 06, 2020, 08:10:22 pm »
On vacation from women for a month or two. I work, I hustle, I study. Choose two. Ya feel?
You're not done when it works, you're done when it's right.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
Re: Brainfuck Interpreter
« Reply #16 on: March 06, 2020, 09:18:07 pm »
@STxAxTIC  Here's something to help keep the women away!

https://www.qb64.org/forum/index.php?topic=2308.msg115346#msg115346

Update: I moved the post under STxAxTIC's start of new thread, it fits better there!
I have also updated the zip with some new stuff.


« Last Edit: March 07, 2020, 07:19:53 pm by bplus »

Offline romichess

  • Forum Regular
  • Posts: 145
Re: Brainfuck Interpreter
« Reply #17 on: March 07, 2020, 03:31:39 pm »
Well, I've written an interpreter for brainfuck, why? why not? But I've ran into a bug that I can't solve.
I don't understand the reason, but even though I included a line that wraps the data pointer to the upper bound of the data array, the program keeps subtracting 1 to it, this is crucial for loops to work. Here's the code

Code: QB64: [Select]
  1. dim shared prog(&hffff&) as string
  2. dim shared ostream       as _unsigned _byte
  3. dim shared arr(&hffff&)  as _unsigned _byte
  4. dim shared istream       as _unsigned _byte
  5. dim shared ptr           as integer
  6.  
  7.     sleep
  8.     do
  9.         select case inkey$
  10.             case ">"     : s$ = s$ + ">": cnt = cnt + 1: prog(cnt) = ">": exit do
  11.             case "<"     : s$ = s$ + "<": cnt = cnt + 1: prog(cnt) = "<": exit do
  12.             case "+"     : s$ = s$ + "+": cnt = cnt + 1: prog(cnt) = "+": exit do
  13.             case "-"     : s$ = s$ + "-": cnt = cnt + 1: prog(cnt) = "-": exit do
  14.             case "."     : s$ = s$ + ".": cnt = cnt + 1: prog(cnt) = ".": exit do
  15.             case ","     : s$ = s$ + ",": cnt = cnt + 1: prog(cnt) = ",": exit do
  16.             case "["     : s$ = s$ + "[": cnt = cnt + 1: prog(cnt) = "[": exit do
  17.             case "]"     : s$ = s$ + "]": cnt = cnt + 1: prog(cnt) = "]": exit do
  18.             case chr$(8) : if len(s$) then s$ = left$(s$, len(s$) - 1)  : exit do
  19.             case chr$(13): exec
  20.             case "v"     : for i = 1 to len(_clipboard$): prog(i + cnt) = chr$(asc(_clipboard$, i)): next: s$ = s$ + _clipboard$: exit do
  21.             case else    :
  22.         end select
  23.     loop
  24.     print s$;
  25.     _keyclear
  26.  
  27. sub exec
  28.     for i = 0 to ubound(prog)
  29.         select case prog(i)
  30.             case ">": ptr = ptr + 1
  31.             case "<": if ptr then ptr = ptr - 1 else ptr = ubound(arr) 'What the heck?
  32.             case "+": arr(ptr) = arr(ptr) + 1
  33.             case "-": arr(ptr) = arr(ptr) - 1
  34.             case ".": ostream  = arr(ptr)
  35.             case ",": arr(ptr) = istream
  36.             case "[":
  37.                 if arr(ptr) = 0 then
  38.                     for y = i to ubound(prog)
  39.                         if prog(x) = "]" then i = x + 1: exit for
  40.                     next
  41.                 end if
  42.             case "]":
  43.                 if arr(ptr) then
  44.                     for x = i to 0 step -1
  45.                         if prog(x) = "[" then i = x: exit for
  46.                     next
  47.                 end if
  48.         end select
  49.         updateOutput
  50.         updateConsole(i)
  51.     next
  52.  
  53. sub updateOutput     : print chr$(ostream): _display: cls: end sub
  54. sub updateInput      : istream = asc(inkey$)             : end sub
  55. sub updateConsole(i) : cout "dataptr           =" + str$(ptr)
  56.     cout "data    (current) ="  + str$(arr(ptr))
  57.     cout "program (current) = " + prog(i)
  58.     cout "---------------------"
  59. sub cout(s$)      : _dest _console: print s$: _dest 0 : end sub
  60.  

And here's the test program (paste with v, execute with [enter]):

Code: QB64: [Select]
  1. ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
  2.  

Unless you are planning to equal or top this there is not much point.

https://eli.thegreenplace.net/2017/adventures-in-jit-compilation-part-1-an-interpreter/
My name is Michael, but you can call me Mike :)

Offline romichess

  • Forum Regular
  • Posts: 145
Re: Brainfuck Interpreter
« Reply #18 on: March 07, 2020, 03:54:30 pm »
A very worthwhile project would be to write a compiler as close to BF as possible but will also use the full power of the processor. Every line would start with one character.

An if else construct:
\
> var1 var2
' code
/
e
\
' code
/

A while loop:
/
w > var1 var2
' code
\

A do while:
/
'code
w > var1 var2
\

Function call:
f name var1 var2 : var3

Function body:
{
n name var1 var2
' code
r var3
}

Something like that. The idea is every single line starts with one character that identifies the action and then a jump table jumps to where that is handled. It would be fast once it is compiled and become like  shorthand for the compiler and the human.
My name is Michael, but you can call me Mike :)