blob: 26de72cd5eb66e015d92b1bee9d80be0a12455be (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
with Ada.Text_IO;
with Ada.Direct_IO;
with Ada.Command_Line;
procedure Brainfuck is
package CL renames Ada.Command_Line;
package Text_IO renames Ada.Text_IO;
package Direct_IO is new Ada.Direct_IO(Character);
use type Direct_IO.Count;
type Cell is mod 256;
type Tape_Position is mod 5000;
type Program_Tape is array (Tape_Position'Range) of Cell;
pragma Pack (Program_Tape);
Input_File : Direct_IO.File_Type;
File_Position : Direct_IO.Positive_Count;
Counter : Integer;
Current_Char : Character;
Tape : Program_Tape;
Current_Cell : Tape_Position;
begin
if CL.Argument_Count /= 1 then
Text_IO.Put_Line(Text_IO.Standard_Error, "Please supply the filename of a brainfuck program");
CL.Set_Exit_Status(CL.Failure);
return;
end if;
begin
Direct_IO.Open( File => Input_File,
Mode => Direct_IO.In_File,
Name => CL.Argument(1) );
exception
when others =>
Text_IO.Put_Line(Text_IO.Standard_Error, "Can not open the file '" & CL.Argument(1) & "'. Does it exist?");
CL.Set_Exit_Status(CL.Failure);
return;
end;
Tape := (others => 0);
Current_Cell := Tape_Position'First;
while not Direct_IO.End_Of_File(Input_File) loop
Direct_IO.Read(Input_File, Current_Char);
case Current_Char is
when '>' =>
Current_Cell := Current_Cell + 1;
when '<' =>
Current_Cell := Current_Cell - 1;
when '+' =>
Tape(Current_Cell) := Tape(Current_Cell) + 1;
when '-' =>
Tape(Current_Cell) := Tape(Current_Cell) - 1;
when '.' =>
Text_IO.Put(Character'Val(Tape(Current_Cell)));
when ',' =>
Text_IO.Get(Current_Char);
Tape(Current_Cell) := Character'Pos(Current_Char);
when '[' =>
if Tape(Current_Cell) = 0 then
Counter := 1;
while Counter > 0 and not Direct_IO.End_Of_File(Input_File) loop
Direct_IO.Read(Input_File, Current_Char);
if Current_Char = '[' then
Counter := Counter + 1;
elsif Current_Char = ']' then
Counter := Counter - 1;
end if;
end loop;
end if;
when ']' =>
if Tape(Current_Cell) /= 0 then
Counter := 0;
File_Position := Direct_IO.Index(Input_File) - 1;
loop
Direct_IO.Set_Index(Input_File, File_Position);
Direct_IO.Read(Input_File, Current_Char);
if Current_Char = ']' then
Counter := Counter + 1;
elsif Current_Char = '[' then
Counter := Counter - 1;
end if;
File_Position := File_Position - 1;
exit when Counter < 1;
end loop;
end if;
when others =>
null;
end case;
end loop;
Direct_IO.Close(Input_File);
end Brainfuck;
|