Виртуальная машина Модели данных - PenzaStreetGames/Yo GitHub Wiki
Элементарные понятия
Ячейка
Атомарная частица данных. Хранит биты, представленные в виде целого числа.
Лента памяти
Лента памяти - это список из ячеек, самая большая структурная единица виртуальной машины. В реализации она будет выглядеть в виде обычного списка, либо массива переменной длины, хранящего целые числа. Все последующие модели данных лежат внутри ленты памяти.
Типы ячеек
- Ничего
- Ссылка
- Команда
- Логическая величина (логика)
- Число
- Символ
Число
Хранит целое число со знаком. Диапазон значений: [-2^31; 2^31)
Ссылка
Хранит номер ячейки, на которую ссылается. Диапазон значений: [0; 2^32)
Символ
Хранит номер символа в кодировке Юникод. Диапазон значений: теоретический [0; 2^32) практический меньше, так как в Юникоде нет четырёх миллиардов символов.
Логическая величина
Хранит 1 если это истина или 0 если это ложь.
Команда
Хранит номер высшей команды виртуальной машины. Они перечислены здесь
Ничего
Хранит ноль. В программировании часто оправдано хранение пустоты. Она показывает на отсутствие величины в необходимом месте.
Тип
Тип ячейки, который хранит тип... Уже сложно, да? Дело в том, что сама по себе ячейка с хранимой величиной какого угодно большого размера бесценна, если мы не знаем, что это за род данных. Например, 1 может значить:
- Истина, если тип логический
- Число +1, если тип число
- Команда безусловного перехода Jump, если тип команда
- Системный символ "Начало заголовка" U+0001, если тип символ (очень плачевная ситуация, ни разу не встречал применения этого символа)
Поэтому тип данных хранится в отдельной ячейке. Он равняется номеру типа в перечислении типов ячеек
Простые конструкции из ячеек
Если просто записывать ячейки в ленту памяти, то образуется непонятный хаос из чисел, не поддающийся расшифровке. Для группировки ячеек используются простые конструкции. Почему простые - скоро поймёте.
Простой объект
Почему и он простой - тоже скоро поймёте. Если записать тип данных, а после него записать ячейку со значением, то это и будет простой объект. Зная номер ячейки в которой записан тип, всегда можно подобрать алгоритм для чтения значения после этой ячейки. В грубой форме это можно изобразить вот так:
-------------------
| тип |значение|
-------------------
Массив
Это служебный вид данных - пользователь не может создавать массивы, только списки. Но о них позже. Массивы представляют из себя начало в виде типа, некоторое количество ссылок и метка окончания - объект ничего.
---------------------------------------------------------
| тип:массив |ссылка|ссылка|...|ссылка|ссылка|ничего|
---------------------------------------------------------
Ничего может идти сразу после типа массива. В этом случае массив будет пустым.
Массив символов
Это тоже служебный вид данных - пользователь не может создавать массивы символов, только строки. О них тоже позже. Массивы символов представляют из себя начало в виде типа, некоторое количество кодов символов и метка окончания - объект ничего.
------------------------------------------------------------------
| тип:массив символов |символ|символ|...|символ|символ|ничего|
------------------------------------------------------------------
Ничего может идти сразу после типа массива символов. В этом случае массив будет пустым.
Элемент словаря
Этот объект является связкой из трёх ссылок. Ссылка на словарь, ссылка на ключ, ссылка на значение. Ссылка на словарь не является абсолютно необходимой, но позволяет говорить о "нужности" элемента.
----------------------------------------------------------------------------------------------------------------------
| тип:элемент словаря |пусто|тип:ссылка|ссылка на словарь|тип:ссылка|ссылка на ключ|тип:ссылка|ссылка на значение|
----------------------------------------------------------------------------------------------------------------------
О том, почему во второй ячейке лежит пусто будет сказано ниже.
Сегменты
Если просто записывать простые объекты в ленту памяти, то образуется вполне читаемый блок информации, но совершенно непригодный для обработки и изменения. Для группировки простых конструкций используются сложные конструкции. "Сложные конструкции" - звучит страшно и непонятно, поэтому они называются сегментами.
Типы сегментов
- Системная область
- Стек памяти
- Стек вызовов
- Сегмент данных
- Программа
- Пространство имён
- Сегмент строки
- Сегмент списка
Строение сегмента
Как любая сложная структура данных, например файл HTML, сегмент имеет заголовок и тело. Если взять за основу, то, что "заголовок" и "тело" - это некоторое количество ячеек, то сегмент можно изобразить так:
---------------------
|заголовок| тело |
---------------------
В свою очередь заголовок делится на две части: основную и особенную. Чем они отличаются? Сегменты бывают разные по назначению, но у всех есть что-то общее. Например, все знают свою длину в ячейках. Такая информация записывается в основную часть заголовка. А то, что нужно для работы конкретно этого типа сегмента записывается в особую часть сегмента. Строение заголовка можно изобразить так:
-----------------------------------
| заголовок |
-----------------------------------
|основная часть|особенная часть|
-----------------------------------
И внутри общей части заголовка, и в особенной части, и в теле хранятся простые объекты и конструкции, если вы ещё помните, что это такое.
Типы сегментов
- Системная область
- Хранит значения, контролирующие исполнение программы
- Стек вызовов
- Хранит (ссылки) переходы между подпрограммами
- Стек памяти
- Хранит (ссылки) промежуточные значения
- Программа
- Хранит байтовые команды
- Сегмент данных
- Хранит мелкие величины
- Сегмент списка
- Хранит (ссылки) часть списка
- Сегмент строки
- Хранит (символы) часть строки
- Пространство имён
- Хранит (ссылки) часть пространства имён
Красота ленты памяти
Помимо необходимого числа ячеек, в ленте памяти могут встречаться пустые ячейки, дополняющие конструкцию до чётного числа ячеек. Таким образом, создаётся гарантия, что тип может лежать только в чётной ячейке. Это так называемая красота ленты памяти
Апофеоз
Лента памяти представляет из себя совокупность сегментов, которые представляют из себя заголовок и тело, заголовок также делится на основную и особенную части, обе части заголовка и тело хранят простые конструкции и простые объекты, простые конструкции тоже хранят простые объекты, а простые объекты состоят из ячейки типа и ячеек значения.
Я не спорю, что система сложная. Но сложное лучше, чем непонятное, не так ли?
Вот обобщающий чертёж:
----------------------------------------------------------------------------------------------------------
Лента памяти
----------------------------------------------------------------------------------------------------------
|...| Сегменты |...|
----------------------------------------------------------------------------------------------------------
| Заголовок | Тело |
----------------------------------------------------------------------------------------------------------
| Общая часть | Особая часть | |
----------------------------------------------------------------------------------------------------------
|...|Простые объекты|...|...|Простые объекты|...|...|Простые конструкции|...|Простые объекты|...|
----------------------------------------------------------------------------------------------------------
|...| Простые объекты |...|
----------------------------------------------------------------------------------------------------------
| тип | значение |
----------------------------------------------------------------------------------------------------------