doc: add builtins and errors_print documents
This commit is contained in:
@@ -0,0 +1,120 @@
|
|||||||
|
# Вывод ошибок
|
||||||
|
|
||||||
|
Если во время работы программы происходит ошибка рантайма, то ВМ выводит своё состояние на момент остановки.
|
||||||
|
Среди выводимой информации есть:
|
||||||
|
|
||||||
|
1. Указатель на адрес инструкции;
|
||||||
|
2. Стек данных;
|
||||||
|
3. Стек окружений;
|
||||||
|
4. Стек вызовов.
|
||||||
|
|
||||||
|
## Указатель на адрес инструкции (IP)
|
||||||
|
|
||||||
|
Он может быть полезен для отладки, в паре с выводом опкодов программы.
|
||||||
|
Если подать в ВМ флаг `--debug` (`-d`) вместе с путём к скомпилированной программой, то ВМ выведет список опкодов программы без её запуска.
|
||||||
|
|
||||||
|
Выглядит вывод программы примерно так:
|
||||||
|
|
||||||
|
```
|
||||||
|
0000: MK_ENVTABLE
|
||||||
|
0001: JMP IP: 53
|
||||||
|
0003: MK_ENVTABLE
|
||||||
|
0004: LOADCONST #0 ('a')
|
||||||
|
0006: STORE
|
||||||
|
0007: LOADCONST #0 ('a')
|
||||||
|
0009: WRITE
|
||||||
|
0010: MK_ENVTABLE
|
||||||
|
0011: LOADCONST #0 ('a')
|
||||||
|
0013: LOOKUP_ENV
|
||||||
|
0014: GET_FIELD #0
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Порядковый номер позволяет быстро найти инструкцию, на которой произошло исключение.
|
||||||
|
Полный список опкодов и их описание можно найти в документе [списка опкодов](../internals/opcodes.md).
|
||||||
|
|
||||||
|
## Стек данных
|
||||||
|
|
||||||
|
Стек данных выводится как список значений в стиле `[T] V`, где `T` - номер типа, `V` - значение.
|
||||||
|
Если значение является строкой или объектом, то в начале дописывается `str: V` и `ref: V` соответственно.
|
||||||
|
|
||||||
|
Вот, как выглядит пример вывода стека:
|
||||||
|
|
||||||
|
```
|
||||||
|
> Data stack:
|
||||||
|
> [2] str: 'this'
|
||||||
|
```
|
||||||
|
|
||||||
|
Важно учесть, что значения выводятся сверху вниз. То есть, первыми будут выведены самые свежие значения.
|
||||||
|
|
||||||
|
## Стек окружения
|
||||||
|
|
||||||
|
Стек окружения выводится как два списка: объекты во владении и локальные для окружения имена.
|
||||||
|
|
||||||
|
Пример окружения:
|
||||||
|
|
||||||
|
```
|
||||||
|
> Environments:
|
||||||
|
> [1] 0x55a9d8196a20:
|
||||||
|
> Owned objects (0/2):
|
||||||
|
> Local entries (3/4):
|
||||||
|
> [14] b = 4
|
||||||
|
> [1] a = ref 0x55a9d81969e0
|
||||||
|
> [0] this = 0
|
||||||
|
> [0] 0x55a9d8196930:
|
||||||
|
> Owned objects (1/2):
|
||||||
|
> ref: 0x55a9d81969e0 (entries: 1)
|
||||||
|
> Local entries (1/2):
|
||||||
|
> [1] sum = ref 0x55a9d81969e0
|
||||||
|
```
|
||||||
|
|
||||||
|
`> [N] A` - это сама таблица окружения.
|
||||||
|
`N` - это уровень таблицы, который тем выше, чем глубже само окружение.
|
||||||
|
`A` - это адрес таблицы в памяти.
|
||||||
|
|
||||||
|
Внутри идёт первый список - "Owned objects", с указанием количества элементов и аллоцированным размером массива `(<кол-во>/<размер>)`.
|
||||||
|
Перечисление объектов идёт форматом `ref: A (entries: N)`, где `A` - адрес объекта в памяти, `N` - количество хранимых полей.
|
||||||
|
|
||||||
|
Далее идёт список локальных имён - "Local entries", с таким же указанием количества элементов к аллоцированному размеру.
|
||||||
|
Формат элемента - `[T] N = V`, где `T` - номер типа, `N` - имя элемента, а `V` - его значение.
|
||||||
|
|
||||||
|
## Стек вызовов
|
||||||
|
|
||||||
|
На стеке вызовов лежат точки возврата, которые попадают на стек при инструкции `CALL` и съедаются инструкцией `RET`.
|
||||||
|
|
||||||
|
```
|
||||||
|
> Call stack:
|
||||||
|
> [0] 53
|
||||||
|
```
|
||||||
|
|
||||||
|
Формат записи простой: `[L] IP`, где `L` - уровень вложенности (больше = глубже), а `IP` - указатель на номер инструкции, на которую нужно прыгнуть после возврата.
|
||||||
|
|
||||||
|
## Полный вывод
|
||||||
|
|
||||||
|
Итого, полный вывод ошибки выглядит следующим образом:
|
||||||
|
|
||||||
|
```
|
||||||
|
===== ERROR =====
|
||||||
|
> Caused on IP: 21
|
||||||
|
|
||||||
|
> Data stack:
|
||||||
|
> [2] str: 'this'
|
||||||
|
|
||||||
|
> Environments:
|
||||||
|
> [1] 0x55a9d8196a20:
|
||||||
|
> Owned objects (0/2):
|
||||||
|
> Local entries (3/4):
|
||||||
|
> [14] b = 4
|
||||||
|
> [1] a = ref 0x55a9d81969e0
|
||||||
|
> [0] this = 0
|
||||||
|
> [0] 0x55a9d8196930:
|
||||||
|
> Owned objects (1/2):
|
||||||
|
> ref: 0x55a9d81969e0 (entries: 1)
|
||||||
|
> Local entries (1/2):
|
||||||
|
> [1] sum = ref 0x55a9d81969e0
|
||||||
|
|
||||||
|
> Call stack:
|
||||||
|
> [0] 53
|
||||||
|
Error: runtime error - expected 2 values in data stack
|
||||||
|
```
|
||||||
|
|
||||||
@@ -1 +1,23 @@
|
|||||||
# Встроенные функции
|
# Встроенные функции
|
||||||
|
|
||||||
|
В языке FZLang предусмотрены встроеные функции, доступные для использования в любой программе.
|
||||||
|
|
||||||
|
## Выход `exit`
|
||||||
|
|
||||||
|
```
|
||||||
|
fn exit(uint code)
|
||||||
|
```
|
||||||
|
|
||||||
|
Функция принимает аргументом беззнаковое число и выходит из программы с указанным кодом.
|
||||||
|
|
||||||
|
## Вывод в stdout `printline`
|
||||||
|
|
||||||
|
```
|
||||||
|
fn printline(value)
|
||||||
|
```
|
||||||
|
|
||||||
|
Принимает аргументом любое значение и выводит в стандартный вывод указанное значение.
|
||||||
|
Для примитивы выводятся чисто, на основе типа.
|
||||||
|
Объекты выводятся как `obj<...>`, где `...` - перечисление значений полей.
|
||||||
|
Поля выводятся по типу и значению в формате: `T<V>`, где `T` - название типа, `V` - текущее значение.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user