library ieee;
use ieee.std_logic_1164.all;

use work.util.all;

entity parser is
	port (
		clk : in std_logic;
		reset : in std_logic;

		is_data   : out std_logic;
		record_end : out std_logic;

		char : in character;
		input_valid : in std_logic;

		num1, num2 : out natural range 0 to 99;
		letter : out character
	);
end entity;

architecture behaviour of parser is
	type state_t is (S_NUM1, S_NUM2, S_LETTER, S_COLON, S_END_SPACE, S_DATA);
	signal state : state_t := S_NUM1;

	type multiples_lookup_t is array(digit_t) of natural range 0 to 90;
	constant TEN_MULTIPLES : multiples_lookup_t := (0, 10, 20, 30, 40, 50, 60, 70, 80, 90);

	-- most significant digit of number
	signal prev_digit : digit_t := 0;
	signal current_digit : digit_t;
	signal complete_num : natural range 0 to 99;
begin
	current_digit <= char_to_digit(char);
	complete_num <= TEN_MULTIPLES(prev_digit) + current_digit;

	process(clk)
	begin
		if rising_edge(clk) then
			record_end <= '0';

			if reset then
				prev_digit <= 0;
				state <= S_NUM1;
			elsif input_valid then
				prev_digit <= 0;

				case state is
					when S_NUM1 =>
						if char = '-' then
							state <= S_NUM2;
						else
							num1 <= complete_num;
							prev_digit <= current_digit;
						end if;
					when S_NUM2 =>
						if char = ' ' then
							state <= S_LETTER;
						else
							num2 <= complete_num;
							prev_digit <= current_digit;
						end if;
					when S_LETTER =>
						letter <= char;
						state <= S_COLON;
					when S_COLON =>
						state <= S_END_SPACE;
					when S_END_SPACE =>
						state <= S_DATA;
					when S_DATA =>
						if char = LF then
							state <= S_NUM1;
							record_end <= '1';
						end if;
				end case;
			end if;
		end if;
	end process;

	is_data <= '1' when state = S_DATA else '0';
end architecture;
