⚠️ Warning: This is a draft ⚠️
This means it might contain formatting issues, incorrect code, conceptual problems, or other severe issues.
If you want to help to improve and eventually enable this page, please fork RosettaGit's repository and open a merge request on GitHub.
{{implementation|Brainfuck}}{{collection|RCBF}}
This interpreter (in [[Modula-3]]) is a [[Rosetta Code:Example Translation|translation]] of the [[RCBF/Ada|Ada RCBF interpreter]], and has the same limits.
MODULE Bfi EXPORTS Main;
IMPORT Stdio, Wr, Rd, Params, FileRd, Text;
<*FATAL ANY*>
TYPE TData = [Bottom..LAST(INTEGER)];
CONST
Bottom = -1;
MemLast = 30000;
ProgLast = 30000;
VAR
M := ARRAY [0..MemLast] OF TData {0, ..};
progName := Params.Get(1);
program: FileRd.T;
P: ARRAY [0..ProgLast] OF CHAR;
Px: TEXT; (* workaround for char arrays. *)
mp, pp, progLen, level: INTEGER;
data: CHAR;
OK: BOOLEAN;
endInput := FALSE;
endOutput := FALSE;
PROCEDURE MsgErr(msg: TEXT) =
BEGIN
Wr.PutText(Stdio.stdout, "\n");
Wr.PutText(Stdio.stderr, "** Error: " & msg & "\n");
OK := FALSE;
END MsgErr;
BEGIN
program := FileRd.Open(progName);
Px := Rd.GetText(program, LAST(P));
Rd.Close(program);
progLen := Text.Length(Px);
(* Px has type TEXT, but we want ARRAY OF CHAR, so we write
the characters of Px into the char array P. *)
Text.SetChars(P, Px);
pp := 0;
mp := 0;
OK := TRUE;
WHILE OK AND (pp < progLen) DO
CASE P[pp] OF
| '+' =>
M[mp] := M[mp] + 1;
| '-' =>
IF M[mp] <= Bottom THEN
MsgErr("Arithmetic underflow");
ELSE
M[mp] := M[mp] - 1;
END;
| '.' =>
IF endOutput THEN
MsgErr("Attempt to write past EOF");
ELSIF M[mp] < 0 THEN
endOutput := TRUE;
ELSE
Wr.PutChar(Stdio.stdout, VAL(M[mp], CHAR));
END;
| ',' =>
IF endInput THEN
MsgErr("Attempt to read past EOF");
ELSE
LOOP
IF Rd.EOF(Stdio.stdin) THEN
M[mp] := Bottom;
endInput := TRUE;
EXIT;
ELSE
data := Rd.GetChar(Stdio.stdin);
M[mp] := ORD(data);
IF data >= ' ' THEN
EXIT;
END;
END;
END;
END;
| '>' =>
mp := mp + 1;
IF mp > MemLast THEN
MsgErr("Memory pointer overflow");
END;
| '<' =>
mp := mp - 1;
IF mp < 0 THEN
MsgErr("Memory pointer underflow");
END;
| '[' =>
IF M[mp] = 0 THEN
pp := pp + 1;
level := 0;
WHILE pp < progLen AND (level > 0 OR P[pp] # ']') DO
IF P[pp] = '[' THEN
level := level + 1;
END;
IF P[pp] = ']' THEN
level := level - 1;
END;
pp := pp + 1;
END;
IF pp >= progLen THEN
MsgErr("No matching ']'");
END;
END;
| ']' =>
IF M[mp] # 0 THEN
pp := pp - 1;
level := 0;
WHILE pp >= 0 AND (level > 0 OR P[pp] # '[') DO
IF P[pp] = ']' THEN
level := level + 1;
END;
IF P[pp] = '[' THEN
level := level - 1;
END;
pp := pp - 1;
END;
IF pp < 0 THEN
MsgErr("No matching '['");
END;
END;
ELSE
(* ignore *)
END;
pp := pp + 1;
END;
Wr.PutText(Stdio.stdout, "\n");
END Bfi.