#pragma once
// описатель цепочки арифметического выражения в польской нотации

#include "BKToken.h"

enum class A_OP : uint8_t
{
	NOP,        // Нет операции
	UN_PLUS,    // унарный плюс             + (по идее, должно игнорироваться)
	UN_MINUS,   // унарный минус            -
	UN_NOT,     // унарное нет              ~ (инвертирование)
	PLUS,       // арифм.плюс               +
	MINUS,      // арифм.минус              -
	MUL,        // арифм.умножение          *
	DIV,        // арифм.деление            /
	DIV_FR,     // арифм.получение остатка  %
	SHL,        // арифм.сдвиг влево        << (плохо - совпадает со скобками, но других символов нету)
	SHR,        // арифм.сдвиг вправо       >> (плохо - совпадает со скобками, но других символов нету)
	OR,         // бинарное ИЛИ             |
	XOR,        // бинарное исключающее ИЛИ ^
	AND         // бинарное И               &

	// в принципе можно сделать ещё и логические !, &&, || и операции сравнения <= >= < > == !=
	// но не знай как решить конфликт скобок.
	// или нужно два парсера. один с треугольными скобками для арифметических выражений
	// и второй с круглыми скобками для логическо-арифметических, чтобы использовать в условных операторах
	// больше им применения пока не находится
};
enum class A_TYPE : uint8_t
{
	NUMBER,         // число
	LABEL,          // метка
	LOC_LABEL,      // локальная метка
	DOT_PC,         // ссылка на счётчик команд
	OPERATION       // операция
};

// структура узла записи арифметического выражения
class A_NODE
{
	public:
		A_TYPE      type{ A_TYPE::NUMBER };   // тип узла
		A_OP        op{ A_OP::NOP };     // вид операции
		// операнд, может быть число или метка
		uint32_t    number{ 0 };
		CBKToken    token;
	public:
		A_NODE() = default;
		A_NODE(A_TYPE _t, A_OP _o) noexcept
			: type(_t)
			, op(_o)
		{}
		A_NODE(A_TYPE _t, uint32_t _n) noexcept
			: type(_t)
			, number(_n)
		{}
		A_NODE(A_TYPE _t, CBKToken &_tok)
			: type(_t)
			, token(_tok)
		{}
		void clear();

		void Store(FILE *f) const;

		bool Load(FILE *f);
};

using RPNChain_t = std::vector<A_NODE>;

namespace RPNChainFunc
{
	void            Store(FILE *f, const RPNChain_t &rpn);  // сохранение в объектный файл
	bool            Load(FILE *f, RPNChain_t &rpn);   // чтение из объектного файла
}
