69 lines
1.9 KiB
Ada
69 lines
1.9 KiB
Ada
with Ada.Text_IO;
|
|
|
|
procedure Subleq is
|
|
|
|
Storage_Size: constant Positive := 2**8; -- increase or decrease memory
|
|
Steps: Natural := 999; -- "emergency exit" to stop endless loops
|
|
|
|
subtype Address is Integer range -1 .. (Storage_Size-1);
|
|
subtype Memory_Location is Address range 0 .. Address'Last;
|
|
|
|
type Storage is array(Memory_Location) of Integer;
|
|
|
|
package TIO renames Ada.Text_IO;
|
|
package IIO is new TIO.Integer_IO(Integer);
|
|
|
|
procedure Read_Program(Mem: out Storage) is
|
|
Idx: Memory_Location := 0;
|
|
begin
|
|
while not TIO.End_Of_Line loop
|
|
IIO.Get(Mem(Idx));
|
|
Idx := Idx + 1;
|
|
end loop;
|
|
exception
|
|
when others => TIO.Put_Line("Reading program: Something went wrong!");
|
|
end Read_Program;
|
|
|
|
procedure Execute_Program(Mem: in out Storage) is
|
|
PC: Integer := 0; -- program counter
|
|
function Source return Integer is (Mem(PC));
|
|
function Dest return Integer is (Mem(PC+1));
|
|
function Branch return Integer is (Mem(PC+2));
|
|
function Next return Integer is (PC+3);
|
|
begin
|
|
while PC >= 0 and Steps >= 0 loop
|
|
Steps := Steps -1;
|
|
if Source = -1 then -- read input
|
|
declare
|
|
Char: Character;
|
|
begin
|
|
TIO.Get (Char);
|
|
Mem(Dest) := Character'Pos (Char);
|
|
end;
|
|
PC := Next;
|
|
elsif Dest = -1 then -- write output
|
|
TIO.Put(Character'Val(Mem(Source)));
|
|
PC := Next;
|
|
else -- subtract and branch if less or equal
|
|
Mem(Dest) := Mem(Dest) - Mem(Source);
|
|
if Mem(Dest) <= 0 then
|
|
PC := Branch;
|
|
else
|
|
PC := Next;
|
|
end if;
|
|
end if;
|
|
end loop;
|
|
TIO.Put_Line(if PC >= 0 then "Emergency exit: program stopped!" else "");
|
|
exception
|
|
when others => TIO.Put_Line("Failure when executing Program");
|
|
end Execute_Program;
|
|
|
|
Memory: Storage := (others => 0); -- no initial "junk" in memory!
|
|
|
|
begin
|
|
|
|
Read_Program(Memory);
|
|
Execute_Program(Memory);
|
|
|
|
end Subleq;
|