You are not logged in or registered. Please login or register to use the full functionality of this board...
SIGN IN Join Our Community For FREE


Write an Interpreter for this Interpreter!
07-23-2017, 03:55 AM (This post was last modified: 07-24-2017 12:43 PM by bplus.)
Post: #1
 (Print Post)
Write an Interpreter for this Interpreter!
(edit) I am changing the name of this thread from Write a program for this Interpreter.
reasons explained further down.

Here is a challenge!

Write a Interpreter for this Interpreter:
Code Snippet: [Select]
'BF translation.bas for QB64 fork (B+=MGA) 2017-07-23
' 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
'======================================================================
' QB64 has excellent Help wiki, thanks to all who put that together!
'======================================================================
_TITLE "Brainf***, Rosetta Code - Quick Basic translation to SB then to QB64 (fork)"
'for directory stuff
CONST ListMAX% = 20
COMMON SHARED dirList$()
COMMON SHARED DIRCount% 'returns file count if desired
memsize% = 20000
DIM memory%(memsize%)
instChars$ = "+-<>.,[]" 'valid characters
loadDirList "bf*.txt"
WHILE 1
    ptr% = 0 'memory pointer
    source$ = ""
    CLS
    IF DIRCount% THEN
        FOR i% = 1 TO DIRCount%
            PRINT i%, dirList$(i%)
        NEXT
    ELSE
        PRINT "Sorry, no bf*.txt files found."
        SLEEP
        END
    END IF
    PRINT: INPUT "Enter line number of BF Filename you desire "; ln%
    IF ln% < 1 OR ln% > DIRCount% THEN END
    filename$ = dirList$(ln%)
    OPEN filename$ FOR INPUT AS #1
    DO
        LINE INPUT #1, FLINE$
        source$ = source$ + FLINE$
    LOOP UNTIL EOF(1)
    CLOSE #1
    IF LEN(source$) < 1 THEN
        PRINT "No source code to BF."
        SLEEP
        END
    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"
        SLEEP
        END
    ELSE
        PRINT "Code:": PRINT code$: PRINT: PRINT "Output:"
    END IF
    'clear last if any
    ERASE memory%
    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 LINE INPUT 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% > memsize% THEN
                    PRINT "Memory pointer out of range"
                    SLEEP
                    END
                END IF
            CASE "<"
                ptr% = ptr% - 1
                IF ptr% < 0 THEN
                    PRINT "Memory pointer out of range"
                    SLEEP
                    END
                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
    PRINT: PRINT: INPUT "Press y for yes to do another "; yes$
    IF yes$ <> "y" THEN END
WEND
' modified function from Help files
SUB loadDirList (spec$)
CONST TmpFile$ = "DIR$INF0.INF"
STATIC Ready%, Index%
IF NOT Ready% THEN REDIM dirList$(ListMAX%): Ready% = -1 'DIM array first use
IF spec$ > "" THEN 'get file names when a spec is given
    SHELL _HIDE "DIR " + spec$ + " /b > " + TmpFile$
    Index% = 0: dirList$(Index%) = "": ff% = FREEFILE
    OPEN TmpFile$ FOR APPEND AS #ff%
    size& = LOF(ff%)
    CLOSE #ff%
    IF size& = 0 THEN KILL TmpFile$: EXIT SUB
    OPEN TmpFile$ FOR INPUT AS #ff%
    DO WHILE NOT EOF(ff%) AND Index% < ListMAX%
        Index% = Index% + 1
        LINE INPUT #ff%, dirList$(Index%)
    LOOP
    DIRCount% = Index% 'SHARED variable can return the file count
    CLOSE #ff%
    KILL TmpFile$
ELSE IF Index% > 0 THEN Index% = Index% - 1 'no spec sends next file name
END IF
END SUB

append: Included in the zip are some programs for the interpreter found at Rosetta so that you may test the menu/loading/running of files/programs.


Attached File(s)
.zip  BF translation.zip (Size: 617.76 KB / Downloads: 4)

B += _
Find all posts by this user
Like Post
07-23-2017, 07:29 AM
Post: #2
 (Print Post)
RE: Write a program for this Interpreter!
I did a Bing search for BrainF*** and couldn't turn up anything related...
Find all posts by this user
Like Post
07-23-2017, 04:14 PM
Post: #3
 (Print Post)
RE: Write a program for this Interpreter!
Oh my! I read this (which I liked) but... Oh my!
https://learnxinyminutes.com/docs/brainfuck/

Letter printing is explained as well as adding and multiplying.

It has a nice visualizer (for Hello World!) but oh my! This might be too tedious to be fun. ?

How is a comparison done for a decision branch?

Already I have ideas to speed things up, make it more fun and cut the number of commands!

B += _
Find all posts by this user
Like Post
07-24-2017, 12:40 PM
Post: #4
 (Print Post)
RE: Write an Interpreter for this Interpreter!
I am renaming this challenge from
Write a program for this Interpreter!
to
Write an Interpreter for this Interpreter!

Here is why -

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 Snippet: [Select]
'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

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.

B += _
Find all posts by this user
Like Post
07-24-2017, 12:56 PM
Post: #5
 (Print Post)
RE: Write an Interpreter for this Interpreter!
Quote:
I did a Bing search for BrainF*** and couldn't turn up anything related...

Hi STxAxTIC,

My source came from Rosetta Code (RC), search BrainF**** (BF) or RCBF or is it BFRC?
http://rosettacode.org/wiki/Rosetta_Code

Due to nature of four letter word in original name it is often deemed inappropriate, which may make it difficult to find. Wiki isn't afraid to call it by it's original name linked from/to Rosetta Code.

So BF name is a little adolescent but the concepts behind it are very serious basis for computer understanding at a basic level! or is it at a super tedious level?

Aren't computers supposed to save us from tedium of repetition?

I say, Yes! so I start my mods of BF transitioning to BQ (maybe).

B += _
Find all posts by this user
Like Post
07-26-2017, 05:41 AM
Post: #6
 (Print Post)
RE: Write an Interpreter for this Interpreter!
hey ya ho Mark
YES why you do that ....asking 2 smackwithoutpantsarses from retroB
you tell him why not ...
just keep on !

basicPro forum:
http://basicpro.mipropia.com/smf/index.php
EU Radioboard forum:
http://euradioboard.createmybb3.com/index.php
AurelSoft main site:
http://aurelsoft.ucoz.com
Find all posts by this user
Like Post
The following 1 user Likes Aurel's post:
bplus
07-27-2017, 10:45 AM (This post was last modified: 07-27-2017 10:50 AM by bplus.)
Post: #7
 (Print Post)
RE: Write an Interpreter for this Interpreter!
Thanks Aurel!



Hi all, here is a teaser:

I have made such interesting improvements on BF > BQ (Be Quicker) > now EIN (Everything Is Number).

Only have 2 tests with baby EIN and just figured how to add some letter strings this morning.

The first screen shot tests 14 binary operations applied to 2 and 5.

The 2nd screen shot counts to 20 by 2's (the M6 is a dummy memory storage to prevent the print of an unwanted 0 after the count. I spent hours trying to figure out how to get rid of the bugger. Seems a dummy line patches the problem. I am going to translate into QB64 and/or JB to see what they do.)

In both screen shots the "program" is listed in the first line.

PS No more crappy browser for this forum, now testing it, so far, so much better!

WHN? might notice that I am using a draw string technique that he liked. (too bad he thinks I hate him.)


Attached File(s) Image(s)
       

B += _
Find all posts by this user
Like Post
08-12-2017, 01:38 PM (This post was last modified: 08-12-2017 02:01 PM by bplus.)
Post: #8
 (Print Post)
RE: Write an Interpreter for this Interpreter!
Update: Oh man! where was I?

Here is the QB64 package with String Handling worked out (see attached .zip package). SNH stands for Strings Now Handled. So it is possible to code a little program with just a few letter commands and numbers but need a sizable data section for string handling and doing functions.

It has the wonderful feature of being able to drag and drop a freshly edited program file onto the exe to test/run.

Here is sample Hi Lo Game in SNH program:
Code Snippet: [Select]
Once again, my favorite little game for testing tiny interpreters.
{100}* * * Hi Lo Game * * *;
{101}(0 quits) Enter a guess for my number between 1 and 100 ;
{102}That was too high.;
{103}That was too low.;
{104}That was just right!;
{105}RND;
{106}INT;
{107}100;
{108}1;
{109}* * * B+ "Thanks for playing!" * * *;
{110}CTR;
{0}
A105 F10
A10 B107 * M10
A106 B10 F10
A10 B108 + M10
A110 B100 F9 P
[P A110 B101 F 9 ?11
    A11 B1000 =
    I
        X
    N
    A11 B10 >
    I
        A110 B102 F9 P
    E
        A11 B10 <
        I
            A110 B103 F9 P
        E
            A110 B104 F9 P
            X
        N
    N
]
P A110 B109 F9 P P



Nice novelty but Still NOT Enough Fun Coding, so I have moved back to doing command words like in Nano  with long string handling and variable naming so no longer restricted to 26 lower case letters for variables. Just need to add EVAL 2 worked out in FB to QB64 for standalone Nano like programs.

I have some of it worked out in Just Basic (without any EVAL like function) that has built-in text editor GUI so can edit and run programs straight out of the JB interpreter.

Here is Hi Lo Game in JB version (back to Nano like word commands, no EVAL but variable name, values table and recursive gosub calls working)
Code Snippet: [Select]
Hi lo game for do loop nest test  (B+=MGA) 2017-08-06
v prompt$ ls
{(O quits) Guess my number from 1 to 100.}
v sp1$ space 1
do
   v secret# rnd
   v secret# * secret# 100
   v secret# int secret#
   v secret# + secret# 1
   v count# @ 0
   do
       p
       p prompt$
       v guess# input
       v testGuess# #= guess# 0
       if testGuess#
           end
       fi
       v count# + count# 1
       v testGuess# #> guess# secret#
       if testGuess#
           p High!
       else
           v testGuess# #< guess# secret#
           if testGuess#
                   p Low!
           else
                   p; Guessed
                   p; sp1$
                   p; in
                   p; sp1$
                   p; count#
                   p; sp1$
                   p guesses!
                   p
                   exit
               fi
           fi
   loop
loop

What a difference it makes to be able to give your variables meaningful names!


Attached File(s)
.zip  SNH Pack.zip (Size: 635.14 KB / Downloads: 4)

B += _
Find all posts by this user
Like Post



Forum Jump:


User(s) browsing this thread: 1 Guest(s)




QB64 Member Project - Rubix's Magic
QB64 Member Project - Exit
QB64 Member Project - Othello
QB64 Member Project - Score 4
QB64 Member Project - Splatter
QB64 Member Project - Martin Fractals version four
QB64 Member Project - Quarto
QB64 Member Project - Qubic
QB64 Member Project - Foursight
QB64 Member Project - Isolation
QB64 Member Project - Kings Vallery version two
QB64 Member Project - Connect Four
QB64 Member Project - Dreamy Clock
QB64 Member Project - Kobolts Monopoly
QB64 Member Project - STxAxTIC 3D World
QB64 Member Project - 9 Board
QB64 Member Project - Amazon
QB64 Member Project - Domain
QB64 Member Project - RGB Color Wheel
QB64 Member Project - Input
QB64 Member Project - Martin Fractals version one
QB64 Member Project - MAPTRIANGLE
QB64 Member Project - Red Scrolling LED Sign
QB64 Member Project - Bowditch curve
QB64 Member Project - Martin Fractals version three
QB64 Member Project - Touche
QB64 Member Project - Pivet version one
QB64 Member Project - Blokus
QB64 Member Project - Pivot version two
QB64 Member Project - Kings Valley verion one
QB64 Member Project - ARB Checkers
QB64 Member Project - Overboard
QB64 Member Project - Kings Court
QB64 Member Project - Color Triangles
QB64 Member Project - Dakapo
QB64 Member Project - Swirl
QB64 Member Project - Basic Dithering
QB64 Member Project - Spinning Color Wheel
QB64 Member Project - Algeria Weather
QB64 Member Project - Inside Moves
QB64 Member Project - Color Rotating Text
QB64 Member Project - Point Blank
QB64 Member Project - OpenGL Triangles
QB64 Member Project - Sabotage
QB64 Member Project - Martin Fractals version two
QB64 Member Project - Line Thickness
QB64 Member Project - Spiro Roses
QB64 Member Project - Full Color LED Sign
QB64 Member Project - Rotating Background