01 · Таблиця типів #types

Terra використовує тег-систему типів: розмір закодований прямо в імені тегу (число = байти).

Тег (беззнаковий) Розмір Байти Діапазон Тег (знаковий) Діапазон знаковий
/intbyte 8-bit 1 0 … 255 /intbyte- −128 … 127
/int2 16-bit 2 0 … 65,535 /int2- −32,768 … 32,767
/int4 32-bit 4 0 … ≈4.29×10⁹ /int4- ≈−2.14×10⁹ … ≈2.14×10⁹
/int8 64-bit 8 0 … ≈1.84×10¹⁹ /int8- ≈−9.22×10¹⁸ … ≈9.22×10¹⁸
/int16 128-bit 16 0 … ≈3.40×10³⁸ /int16- ≈−1.70×10³⁸ … ≈1.70×10³⁸
/int64 512-bit 64 0 … ≈1.34×10¹⁵⁴ /int64- ≈−6.70×10¹⁵³ … ≈6.70×10¹⁵³
1024-bit 128 /intlong ≈−8.98×10³⁰⁷ … ≈8.98×10³⁰⁷
Правило імені: число в тезі = кількість байт. /intbyte = 1 байт, /int2 = 2 байти, /int8 = 8 байт. Суфікс - робить тип знаковим.
02 · Оголошення #declaration

Всі змінні оголошуються через ключове слово app. Теги — це не зарезервовані слова, а маркери для токенізатора.

Змінна (може змінюватись) ✓ компілюється
test_01_basic.terra
! Оголошення змінної /intbyte
app (/intbyte, /var) intbyte = 12

::start::
intbyte + (12)
/display(intbyte)
output 24
Порядок тегів: спочатку тип (/intbyte), потім модифікатор (/var або /const). Операції — тільки всередині ::start::.
Константа (значення не змінюється) ✓ компілюється
приклад
app (/intbyte, /const) MAX_VAL = 200
Регістронечутливість: Terra повністю регістронечутлива. intbyte, Intbyte та INTBYTE — одна й та сама змінна.
03 · Арифметика #arithmetic

Порядок виконання — суворо зліва направо. Немає пріоритету операторів. Дужки — єдиний спосіб змінити порядок. Всі операції — тільки всередині ::start::.

Стандартна поведінка при переповненні — wrap: 255 + 1 = 0 для /intbyte.

Операція поза ::start:: — помилка ✗ E104
test_02_outside_start.terra
app (/intbyte, /var) intbyte = 12

intbyte + (5)   ! помилка: немає ::start::
error E104 · Операція поза блоком ::start::
04 · Модифікатори операцій #modifiers

Модифікатори прив'язані до конкретної операції, а не до змінної. Дозволяють контролювати поведінку при переповненні.

Модифікатор Для операцій Поведінка
&st +, -, *, / Насичення до максимуму типу (для /intbyte: 255)
&max(N) +, -, *, / Затиснути результат зверху: результат ≤ N
&min(N) +, -, *, / Затиснути результат знизу: результат ≥ N
&min(A)&max(B) +, -, *, / Затиснути в діапазоні [A, B] одночасно
&st — насичення тест 05
test_05_overflow_modifiers.terra
app (/intbyte, /var) intbyte = 200

::start::
intbyte + (100)&st   ! 200+100=300 → насичується до 255
/display(intbyte)
output 255
&min&max — затискання в діапазоні тест 06
test_06_type_expansion.terra
app (/intbyte, /var) intbyte = 1

::start::
! 1 + 495 = 496, але затискаємо в [12, 142]
intbyte + (495)&min(12)&max(142)
/display(intbyte)
output 142
Компілятор генерює llvm.umax + llvm.umin — нативні SIMD-інструкції без розгалужень.
Compile-time гарантія: Модифікатори компілюються у нативні LLVM інструкції в рідному типі (i8, i16...) — без розширення до i64. uadd.sat / usub.sat + umax / umin. Zero branches, runtime overflow неможливий.
05 · .None. значення #none-value

Якщо змінна оголошується без значення — вона отримує .None..
.None. — постійна властивість оголошення, а не поточне значення.

Назавжди: Змінна з .None. ніколи не може бути дільником — навіть після присвоєння нового значення.
Перевіряється на етапі парсингу → E600 DIVISION_BY_NONE
Оголошення без значення → .None. ✓ компілюється
приклад
app (/intbyte, /var) counter   ! = .None. (store i8 0)

::start::
counter (18)                    ! присвоєння — ОК
/display(counter)              ! виводить 18
output 18
.None. в пам'яті — store i8 0. Display показує 0 до присвоєння.
Ділення на .None. — заборонено назавжди ✗ E600
err_E600_none_after_assign.terra
app (/intbyte, /var) x = 84
app (/intbyte, /var) divisor   ! = .None.

::start::
divisor (18)                  ! присвоєння — ОК
x / (divisor)              ! .None. назавжди → E600
error [FATAL] E600 · Ділення на неініціалізовану змінну 'divisor'
05 · Display #display

Вивід значення змінної. Детальна документація — в окремому розділі Display.

Мульти-формат: hex + octal + binary в один рядок тест 03
test_03_display_multiformat.terra
app (/intbyte, /var) intbyte = 12

::start::
/display(intbyte(F, O, B))
output 0xC 0o14 0b1100
F = hex, O = octal, B = binary. Розділені пробілом, один newline в кінці.
07 · Типові помилки #errors-section

Живі приклади з тестового пакету. Повна таблиця — у розділі Коди помилок.

W106 відсутній модифікатор — автоматично /var
test_07a_no_modifier.terra
app (/intbyte) CaseA = 12   ! немає /var або /const
W106 Змінна 'CaseA' не має модифікатора — буде використано /var за замовчуванням
Попередження, не помилка — компіляція продовжується. Вивід: 12.
E107 неправильний порядок тегів
test_07b_wrong_order.terra
app (/var, /intbyte) CaseB = 12   ! /var перед типом
E107 Модифікатор '/var' перед типом
Правило: спочатку тип, потім модифікатор: (/intbyte, /var)
E203 константа без значення
test_07e_no_value.terra
app (/intbyte, /const) CaseE   ! константа без = значення
E203 Константа 'CaseE' повинна мати значення
E202 зарезервоване слово як ім'я
test_07g_reserved_name.terra
app (/intbyte, /var) APP = 14   ! APP — зарезервоване
E202 'APP' — зарезервоване слово