Execute Brain****/COBOL: Difference between revisions
Content added Content deleted
(Added COBOL interpreter.) |
(Re-factored interpreter, removing subprogram and replacing with a REDEFINES.) |
||
Line 3: | Line 3: | ||
<lang cobol> IDENTIFICATION DIVISION. |
<lang cobol> IDENTIFICATION DIVISION. |
||
PROGRAM-ID. Brainfuck-Interpreter. |
PROGRAM-ID. Brainfuck-Interpreter. |
||
DATA DIVISION. |
DATA DIVISION. |
||
LOCAL-STORAGE SECTION. |
LOCAL-STORAGE SECTION. |
||
01 Nesting-Level PIC 999. |
01 Nesting-Level PIC 999. |
||
01 Array. |
01 Array-Area. |
||
03 Array |
03 Array OCCURS 30000 TIMES INDEXED BY Table-Index. |
||
05 Array-Table USAGE BINARY-CHAR. |
|||
⚫ | |||
01 Input-Char PIC X. |
01 Input-Char PIC X. |
||
* *>> Note: This limit is mostly arbitrary. |
* *>> Note: This limit is mostly arbitrary. |
||
01 Max-Program-Size CONSTANT 2048. |
01 Max-Program-Size CONSTANT 2048. |
||
01 Input-Program PIC X(Max-Program-Size). |
01 Input-Program PIC X(Max-Program-Size). |
||
01 Program-Index USAGE |
01 Program-Index USAGE BINARY-LONG UNSIGNED. |
||
PROCEDURE DIVISION. |
PROCEDURE DIVISION. |
||
Main. |
Main. |
||
DISPLAY "Enter program: " WITH NO ADVANCING |
DISPLAY "Enter program: " WITH NO ADVANCING |
||
ACCEPT Input-Program |
ACCEPT Input-Program |
||
PERFORM Process-Statement VARYING Program-Index FROM 1 BY 1 |
PERFORM Process-Statement VARYING Program-Index FROM 1 BY 1 |
||
UNTIL Max-Program-Size < Program-Index |
UNTIL Max-Program-Size < Program-Index |
||
GOBACK |
GOBACK |
||
. |
. |
||
Process-Statement. |
Process-Statement. |
||
EVALUATE Input-Program (Program-Index:1) |
EVALUATE Input-Program (Program-Index:1) |
||
WHEN ">" |
WHEN ">" |
||
SET Table-Index UP BY 1 |
SET Table-Index UP BY 1 |
||
WHEN "<" |
WHEN "<" |
||
SET Table-Index DOWN BY 1 |
SET Table-Index DOWN BY 1 |
||
WHEN "+" |
WHEN "+" |
||
ADD 1 TO Array-Table (Table-Index) |
ADD 1 TO Array-Table (Table-Index) |
||
WHEN "-" |
WHEN "-" |
||
SUBTRACT 1 FROM Array-Table (Table-Index) |
SUBTRACT 1 FROM Array-Table (Table-Index) |
||
WHEN "." |
WHEN "." |
||
DISPLAY |
DISPLAY Array-Table-Char (Table-Index) |
||
Array-Table (Table-Index), 1)) |
|||
WITH NO ADVANCING |
|||
WHEN "," |
WHEN "," |
||
ACCEPT |
ACCEPT Array-Table-Char (Table-Index) |
||
* *> See below. |
|||
CALL "Ascii-Char-To-Num" |
|||
⚫ | |||
WHEN "[" |
WHEN "[" |
||
IF Array-Table (Table-Index) = ZERO |
IF Array-Table (Table-Index) = ZERO |
||
PERFORM Jump-To-Block-End |
PERFORM Jump-To-Block-End |
||
END-IF |
END-IF |
||
WHEN "]" |
WHEN "]" |
||
IF Array-Table (Table-Index) NOT = ZERO |
IF Array-Table (Table-Index) NOT = ZERO |
||
Line 67: | Line 63: | ||
END-EVALUATE |
END-EVALUATE |
||
. |
. |
||
* *>> Move Program-Index back to position of matching '[' |
* *>> Move Program-Index back to position of matching '[' |
||
Jump-To-Block-Start. |
Jump-To-Block-Start. |
||
Line 78: | Line 74: | ||
WHEN "[" |
WHEN "[" |
||
SUBTRACT 1 FROM Nesting-Level |
SUBTRACT 1 FROM Nesting-Level |
||
WHEN "]" |
WHEN "]" |
||
ADD 1 TO Nesting-Level |
ADD 1 TO Nesting-Level |
||
END-EVALUATE |
END-EVALUATE |
||
END-PERFORM |
END-PERFORM |
||
PERFORM Check-Mismatched-Brackets |
PERFORM Check-Mismatched-Brackets |
||
. |
. |
||
* *>> Move Program-Index forward to position of matching ']' |
* *>> Move Program-Index forward to position of matching ']' |
||
Jump-To-Block-End. |
Jump-To-Block-End. |
||
Line 94: | Line 90: | ||
AND (Nesting-Level = 0)) |
AND (Nesting-Level = 0)) |
||
OR (Input-Program (Program-Index:1) = SPACE) |
OR (Input-Program (Program-Index:1) = SPACE) |
||
EVALUATE Input-Program (Program-Index:1) |
EVALUATE Input-Program (Program-Index:1) |
||
WHEN "[" |
WHEN "[" |
||
ADD 1 TO Nesting-Level |
ADD 1 TO Nesting-Level |
||
WHEN "]" |
WHEN "]" |
||
SUBTRACT 1 FROM Nesting-Level |
SUBTRACT 1 FROM Nesting-Level |
||
END-EVALUATE |
END-EVALUATE |
||
END-PERFORM |
END-PERFORM |
||
PERFORM Check-Mismatched-Brackets |
PERFORM Check-Mismatched-Brackets |
||
. |
. |
||
Check-Mismatched-Brackets. |
Check-Mismatched-Brackets. |
||
IF (Program-Index = 0) |
IF (Program-Index = 0) |
||
OR (Input-Program (Program-Index:1) = SPACE) |
OR (Input-Program (Program-Index:1) = SPACE) |
||
DISPLAY "Mismatched |
DISPLAY "Mismatched square brackets. Aborting..." |
||
GOBACK |
GOBACK |
||
END-IF |
END-IF |
||
. |
.</lang> |
||
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> |