2016-05-19 Brainfuck interpreter in COBOL

At work we were discussing conversions of esoteric programming languages. Amongst things like Malbolge, the Brainfuck language was discussed. I then suggested to see if we can write a "brainfuck" interpreter in COBOL.
Since I work at Cornerstone, I learned the basics of COBOL (Cornerstone performs automatic conversions of e.g. COBOL to other languages) so it looked like an interesting endeavor!

So after 20 minutes of hacking I present you: a Brainfuck interpreter in COBOL. It compiles and runs with at least the GNU Cobol compiler and also compiles with the Micro Focus compiler but I did not try to run it with that product.
This program may very well run on your IBM z/OS system!

       IDENTIFICATION DIVISION.
       PROGRAM-ID. BRAINFUCK.
       AUTHOR. Folkert van Heusden - Cornerstone BV.
       DATE-WRITTEN.     16/05/19.
       
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-TABLE.
         05 DATA-MEM                        PIC 9(3) OCCURS 32768 TIMES.
       01 DATA-MEM-LEN                      PIC 9(5) VALUE 32768.
       01 DATA-PTR                          PIC 9(5) VALUE 1.
       01 CMD-MEM                           PIC X(32768).
       01 CMD-MEM-LEN                       PIC 9(5) VALUE 32768.
       01 CMD-PTR                           PIC 9(5) VALUE 1.
       01 TEMP                              PIC 9(5).
       01 COUNTER                           PIC 9(5).
            
       PROCEDURE DIVISION.
           DISPLAY 'BRAINFUCK INTERPRETER IN COBOL'
           DISPLAY 'WRITTEN BY FOLKERT VAN HEUSDEN AT CORNERSTONE B.V.'
           
           DISPLAY 'INIT DATA'
           MOVE 1 TO TEMP
           PERFORM UNTIL TEMP > DATA-MEM-LEN
               MOVE 0 TO DATA-MEM(TEMP)
               ADD 1 TO TEMP
           END-PERFORM
           
           DISPLAY 'RETRIEVE PROGRAM'
           ACCEPT CMD-MEM FROM COMMAND-LINE

           MOVE CMD-MEM-LEN TO TEMP
           PERFORM UNTIL CMD-MEM(TEMP:1) <> ' '
               SUBTRACT 1 FROM TEMP
           END-PERFORM

           MOVE TEMP TO CMD-MEM-LEN

           DISPLAY 'PROGRAM       : ', CMD-MEM(1:CMD-MEM-LEN)
           DISPLAY 'PROGRAM-LENGTH: ', CMD-MEM-LEN
       
           PERFORM UNTIL CMD-PTR > CMD-MEM-LEN
               EVALUATE CMD-MEM(CMD-PTR:1)
               WHEN '>'
                   ADD 1 TO DATA-PTR
                   
                   IF DATA-PTR > 32768
                       MOVE 1 TO DATA-PTR
                   END-IF
               
               WHEN '<'
                   SUBTRACT 1 FROM DATA-PTR
                   
                   IF DATA-PTR < 1
                       MOVE 32768 TO DATA-PTR
                   END-IF
               
               WHEN '+'
                   ADD 1 TO DATA-MEM(DATA-PTR)
                   IF DATA-MEM(DATA-PTR) > 255
                       MOVE 1 TO DATA-MEM(DATA-PTR)
                   END-IF
                   
               WHEN '-'
                   SUBTRACT 1 FROM DATA-MEM(DATA-PTR)
                   IF DATA-MEM(DATA-PTR) < 0
                       MOVE 255 TO DATA-MEM(DATA-PTR)
                   END-IF
                   
               WHEN '.'
                   MOVE DATA-MEM(DATA-PTR) TO TEMP
                   ADD 1 TO TEMP
                   DISPLAY FUNCTION CHAR(TEMP) WITH NO ADVANCING
               
               WHEN ','
                   DISPLAY ', IS NOT IMPLEMENTED'
                   
               WHEN '['
                   IF DATA-MEM(DATA-PTR) = 0
                       MOVE 1 TO COUNTER
                       
                       PERFORM UNTIL COUNTER = 0
                           ADD 1 TO CMD-PTR
                           
                           IF CMD-MEM(CMD-PTR:1) = '['
                               ADD 1 TO COUNTER
                           END-IF
                           
                           IF CMD-MEM(CMD-PTR:1) = ']'
                               SUBTRACT 1 FROM COUNTER
                           END-IF
                       END-PERFORM
                   END-IF

               WHEN ']'
                   IF DATA-MEM(DATA-PTR) <> 0
                       MOVE 1 TO COUNTER
                       
                       PERFORM UNTIL COUNTER = 0
                           SUBTRACT 1 FROM CMD-PTR
                           
                           IF CMD-MEM(CMD-PTR:1) = ']'
                               ADD 1 TO COUNTER
                           END-IF
                           IF CMD-MEM(CMD-PTR:1) = '['
                               SUBTRACT 1 FROM COUNTER
                           END-IF
                       END-PERFORM
                   END-IF
                   
      *         WHEN OTHER
      *             DISPLAY 'IGNORING ', DATA-MEM(DATA-PTR)
               END-EVALUATE
               
               ADD 1 TO CMD-PTR
           END-PERFORM.
           
           STOP RUN.

To run it, the first command line parameter should be the entire brainfuck source code.

In this screendump you will see it run the "hello world"-example from wikipedia:

Download link: run-brainfuck.cbl






Checkout my Mandelbrot fractal implementation in COBOL


feedback