#pragma once

enum class OBJTags : uint32_t
{
	OBJ_Default = 0,
	OBJ_HDRTAG = 0x5501, // тег заголовка объектного файла
	OBJ_ID,             // тег блока идентификации
	OBJ_DATA,           // тег массива с данными
	OBJ_GLB,            // тег блока глобальных меток
	OBJ_LOC,            // тег блока локальных меток
	OBJ_REF,            // тег блока ссылок на метки
	OBJ_SCRIPT,         // тег блока скриптов
	OBJ_Label,          // тег элемента метки из таблиц меток
	OBJ_Refs,           // тег элемента из таблицы ссылок. Цепочка RPN и данны, где она встретилась
	OBJ_Token,          // тег токена (имя метки, внутри элемента метки)
	OBJ_Node,           // тег узла цепочки арифметического выражения
	OBJ_NodeOP,         // тег значения узла - операция
	OBJ_NodeLBL,        // тег значения узла - метка
	OBJ_NodeNMR,        // тег значения узла - число
	OBJ_NodeDotPC,      // тег значения узла - точка (ссылка на счётчик команд)
	OBJ_RPNChain,       // тег начала цепочки арифметического выражения

	OBJ_ScriptBody      // тег начала скрипта
};

// текущая версия структуры объектного файла
constexpr auto OBJVERSION = 0x1020;

// заголовок блока данных
struct OBJBlockHeader
{
	OBJTags  nHdrTag{ OBJTags::OBJ_Default };  // тэг заголовка == OBJTags::OBJ_HDRTAG - признак валидности данных заголовка
	OBJTags  nBlockTag{ OBJTags::OBJ_Default };// тэг блока. По этому тэгу определяется тип блока, и соответственно формат и структура данных
	uint32_t nBlkLen{ 0 };      // Размер данных блока в байтах (не включая размер заголовка), следующих следом за заголовком
	uint32_t nEntryCount{ 0 };  // Количество элементов данных в блоке. Например, количество меток в таблице.
	uint32_t nCheckSum{ 0 };    // Контрольная сумма блока (на данный момент не используется и == 0)
};

// блок - идентификатор
struct OBJIDBlock
{
	uint32_t nVersion{ 0 };      // Версия объектного файла, должно быть равно OBJVERSION
	int16_t nStartAddress{ 0 };  // Адрес компоновки по умолчанию объектного модуля.
	int16_t nMode{ 0 };          // Режим компоновки
};
