Execute Brain****/COBOL

From Rosetta Code
Revision as of 19:30, 16 June 2013 by rosettacode>Edward H (Added COBOL interpreter.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This is a simple Brainf*** interpreter written in COBOL, which receives its program from standard input.

Works with: OpenCOBOL

<lang cobol> IDENTIFICATION DIVISION.

      PROGRAM-ID. Brainfuck-Interpreter.
      DATA DIVISION.
      LOCAL-STORAGE SECTION.
      01  Nesting-Level   PIC 999.
      01  Array.
          03  Array-Table USAGE BINARY-CHAR OCCURS 30000 TIMES
              INDEXED BY Table-Index.
      01  Input-Char       PIC X.
  • *>> Note: This limit is mostly arbitrary.
      01  Max-Program-Size CONSTANT 2048.
      01  Input-Program    PIC X(Max-Program-Size).
      01  Program-Index    USAGE UNSIGNED-INT.
      PROCEDURE DIVISION.
      Main.
          DISPLAY "Enter program: " WITH NO ADVANCING
          ACCEPT Input-Program
          PERFORM Process-Statement VARYING Program-Index FROM 1 BY 1
                  UNTIL Max-Program-Size < Program-Index
          GOBACK
          .
      Process-Statement.
          EVALUATE Input-Program (Program-Index:1)
              WHEN ">"
                  SET Table-Index UP BY 1
              WHEN "<"
                  SET Table-Index DOWN BY 1
              WHEN "+"
                  ADD 1 TO Array-Table (Table-Index)
              WHEN "-"
                  SUBTRACT 1 FROM Array-Table (Table-Index)
              WHEN "."
                  DISPLAY FUNCTION CHAR(FUNCTION SUM(
                      Array-Table (Table-Index), 1))
                      WITH NO ADVANCING
              WHEN ","
                  ACCEPT Input-Char
  • *> See below.
                  CALL "Ascii-Char-To-Num"
                      USING Input-Char Array-Table (Table-Index)
               WHEN "["
                   IF Array-Table (Table-Index) = ZERO
                       PERFORM Jump-To-Block-End
                   END-IF
               WHEN "]"
                   IF Array-Table (Table-Index) NOT = ZERO
                       PERFORM Jump-To-Block-Start
                   END-IF
          END-EVALUATE
          .
  • *>> Move Program-Index back to position of matching '['
      Jump-To-Block-Start.
          SUBTRACT 1 FROM Program-Index
          PERFORM VARYING Program-Index FROM Program-Index BY -1
                  UNTIL ((Input-Program (Program-Index:1) = "[")
                      AND (Nesting-Level = 0))
                  OR (Program-Index = 0)
              EVALUATE Input-Program (Program-Index:1)
                  WHEN "["
                      SUBTRACT 1 FROM Nesting-Level
                  WHEN "]"
                      ADD 1 TO Nesting-Level
              END-EVALUATE
          END-PERFORM
          PERFORM Check-Mismatched-Brackets
          .
  • *>> Move Program-Index forward to position of matching ']'
      Jump-To-Block-End.
          ADD 1 TO Program-Index
          PERFORM VARYING Program-Index FROM Program-Index BY 1
                  UNTIL ((Input-Program (Program-Index:1) = "]")
                      AND (Nesting-Level = 0))
                  OR (Input-Program (Program-Index:1) = SPACE)
              EVALUATE Input-Program (Program-Index:1)
                  WHEN "["
                      ADD 1 TO Nesting-Level
                  WHEN "]"
                      SUBTRACT 1 FROM Nesting-Level
              END-EVALUATE
          END-PERFORM
          PERFORM Check-Mismatched-Brackets
          .
      Check-Mismatched-Brackets.
          IF (Program-Index = 0)
                  OR (Input-Program (Program-Index:1) = SPACE)
              DISPLAY "Mismatched squre brackets. Aborting..."
              GOBACK
          END-IF
          .
      END PROGRAM Brainfuck-Interpreter.</lang>

When accepting input from the user, the character entered must be converted by the function below because moving it straight into a numeric data item would cause the character to be parsed as a number, causing non-numeric characters to be converted to zero. <lang cobol> IDENTIFICATION DIVISION.

      PROGRAM-ID. Ascii-Char-To-Num.
      DATA DIVISION.
      WORKING-STORAGE SECTION.
      01  Ascii PIC X(128) VALUE X"0102030405060708090A0B0C0D0E0F"
          & X"101112131415161718191A1B1C1D1E1F" & " !" & QUOTE
          & "#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ["
          & "\]^_`abcdefghijklmnopqrstuvwxyz{|}~" & X"7F".
      LOCAL-STORAGE SECTION.
      01  I PIC 999.
      LINKAGE SECTION.       
      01  Input-Char PIC X.
      01  Ascii-Num  USAGE BINARY-CHAR.
     *>> Converts an ASCII character to its corresponding numerical value,
     *>> placing the result in Ascii-Num.
      PROCEDURE DIVISION USING Input-Char Ascii-Num.
          IF Input-Char = X"00"
              MOVE ZERO TO Ascii-Num
              GOBACK
          END-IF
          PERFORM VARYING I FROM 1 BY 1 UNTIL 128 < I
              IF Ascii (I:1) = Input-Char
                  MOVE I TO Ascii-Num
                  GOBACK
              END-IF
          END-PERFORM
          DISPLAY "The character could not be matched."
          MOVE -1 TO Ascii-Num
          
          GOBACK
          .
      END PROGRAM Ascii-Char-To-Num.</lang>