Files
fz-lang/docs/ru/internals/opcodes.md
2026-10-19 03:15:35 +03:00

120 lines
10 KiB
Markdown

# Опкоды
Программы, написанные на FZLang, исполняются с помощью виртуальной машины, входящей в тулчейн FZLang и компилирующейся в паре с компилятором.
Компилятор FZC может выпускать следующие опкоды, которые понимает и исполняет ВМ:
## Загрузка данных и работа со стеком
Коды: `0xF00001`..`0xF00004`
| Номер | Название | Назначение | Аргумент |
| -------- | ----------------------- | ------------------------------- | --------------------- |
| 0xF00001 | FZL_OPCODE_LOADCONST | Загрузить константу `N` на стек | `N` - номер константы |
| 0xF00002 | FZL_OPCODE_CALL_BUILTIN | Вызвать встроенную функцию `N` | `N` - номер функции |
| 0xF00003 | FZL_OPCODE_PUSHNUM | Поместить на стек число `N` | `N` - значение |
| 0xF00004 | FZL_OPCODE_PUSHBOOL | Поместить на стек булеву `B` | `B` - значение |
## Управление контекстом и окружением
Коды: `0xF10001`..`0xF10005`
| Номер | Название | Назначение |
| -------- | ---------------------- | ------------------------------------------------------------------- |
| 0xF10001 | FZL_OPCODE_MK_ENVTABLE | Создать новое окружение |
| 0xF10002 | FZL_OPCODE_RM_ENVTABLE | Уничтожить окружение |
| 0xF10003 | FZL_OPCODE_STORE | Создать в окружении имя, лежащее на вершине стека |
| 0xF10004 | FZL_OPCODE_LOOKUP_ENV | Достать из стека имя, найти в окружении и положить на стек значение |
| 0xF10005 | FZL_OPCODE_WRITE | Достать со стека имя и значение, и записать в окружение |
## Управление потоком
Коды: `0xF20001`..`0xF20002`
| Номер | Название | Назначение | Аргумент |
| -------- | -------------- | ----------------------------------------------------------------- | ------------------------ |
| 0xF20001 | FZL_OPCODE_JMP | Прыгнуть на адрес `IP` | `IP` - адрес-цель прыжка |
| 0xF20002 | FZL_OPCODE_JZ | Прыгнуть на адрес `IP`, если значение на вершине стека равно нулю | `IP` - адрес-цель прыжка |
## Вызов функций
Коды: `0xF30001`..`0xF30002`
| Номер | Название | Назначение |
| -------- | --------------- | ----------------------------------------------------------------- |
| 0xF30001 | FZL_OPCODE_CALL | Положить на стек вызовов текущий адрес и перейти к началу функции |
| 0xF30002 | FZL_OPCODE_RET | Снять со стека вызовов последний адрес и перейти к нему |
## Работа с объектами
Коды: `0xFA0001`..`0xFA0005`
| Номер | Название | Назначение | Аргумент |
| -------- | ------------------------ | -------------------------------------------------------------------------------- | --------------------- |
| 0xFA0001 | FZL_OPCODE_ALLOC_OBJECT | Аллоцировать объект под `N` значений и поместить его на стек | `N` - кол-во значений |
| 0xFA0002 | FZL_OPCODE_GET_FIELD | Снять со стека ссылку на объект и получить значение поля `N` | `N` - номер поля |
| 0xFA0003 | FZL_OPCODE_SET_FIELD | Снять со стека ссылку на объект и значение, а затем записать значение в поле `N` | `N` - номер поля |
| 0xFA0004 | FZL_OPCODE_ESCAPE_OBJECT | Перенести объект (в т.ч. дочерние ему) в родительское окружение | отсутствует |
## Арифметические операции
Коды: `0xA00001`..`0xA00007`
| Номер | Название | Назначение |
| -------- | -------------- | --------------------------------------------------------------------------------------- |
| 0xA00001 | FZL_OPCODE_ADD | Снять два числа со стека и сложить их, положив результат на стек |
| 0xA00002 | FZL_OPCODE_SUB | Снять два числа со стека и вычесть первое от второго, положив результат на стек |
| 0xA00003 | FZL_OPCODE_MUL | Снять два числа со стека и переменожить их, положив результат на стек |
| 0xA00004 | FZL_OPCODE_DIV | Снять два числа со стека и поделить первое на второе, положив результат на стек |
| 0xA00005 | FZL_OPCODE_POW | Снять два числа со стека и возвести второе в степерь первого, положив результат на стек |
| 0xA00006 | FZL_OPCODE_MOD | Снять два числа со стека и положить на стек остаток от деления второго на первое |
| 0xA00007 | FZL_OPCODE_NEG | Снять число со стека, инвертировать, и положить обратно на стек |
## Сравнение чисел
Коды: `0xB00001`..`0xB00006`
| Номер | Название | Назначение |
| -------- | ------------------- | ------------------------------------------------------------------------------------------------------------ |
| 0xB00001 | FZL_OPCODE_CMP_EQ | Снять два числа со стека, проверить на равенство и положить на стек результат |
| 0xB00002 | FZL_OPCODE_CMP_NEQ | Снять два числа со стека, проверить на неравенство и сохранить результат на стеке |
| 0xB00003 | FZL_OPCODE_CMP_LT | Снять два числа со стека, проверить, что второе меньше первого, и затем положить результат на стек |
| 0xB00004 | FZL_OPCODE_CMP_LTEQ | Снять два числа со стека, проверить, что второе меньше или равно первому, и затем положить результат на стек |
| 0xB00005 | FZL_OPCODE_CMP_GT | Снять два числа со стека, проверить, что второе больше первого, и затем положить результат на стек |
| 0xB00006 | FZL_OPCODE_CMP_GTEQ | Снять два числа со стека, проверить, что второе больше или равно первому, и затем положить результат на стек |
## Сравнение строк
Коды: `0xB10001`..`0xB10002`
| Номер | Название | Назначение |
| -------- | ---------------------- | ------------------------------------------------------------------------------ |
| 0xB10001 | FZL_OPCODE_CMP_EQ_STR | Снять две строки со стека, сравнить на равенство, положить результат на стек |
| 0xB10002 | FZL_OPCODE_CMP_NEQ_STR | Снять две строки со стека, сравнить на неравенство, положить результат на стек |
## Сравнение объектов
Коды: `0xB20001`..`0xB20002`
| Номер | Название | Назначение |
| -------- | ---------------------- | ------------------------------------------------------------------------------- |
| 0xB20001 | FZL_OPCODE_CMP_EQ_OBJ | Снять два объекта со стека, сравнить на равенство, положить результат на стек |
| 0xB20002 | FZL_OPCODE_CMP_NEQ_OBJ | Снять два объекта со стека, сравнить на неравенство, положить результат на стек |
## Бинарные логические операции
Коды: `0xC00001`..`0xC00002`
| Номер | Название | Назначение |
| -------- | -------------- | ------------------------------------------------------------------------ |
| 0xC00001 | FZL_OPCODE_AND | Взять два значения со стека и положить на стек результат логического И |
| 0xC00002 | FZL_OPCODE_OR | Взять два значения со стека и положить на стек результат логического ИЛИ |
## Унарные логические операции
Коды: `0xD00001`
| Номер | Название | Назначение |
| -------- | -------------- | ------------------------------------------------------------------ |
| 0xD00001 | FZL_OPCODE_NOT | Взять значение со стека и положить инвертированный булев результат |