± Оператори & модифікатори
Арифметика зліва направо без пріоритетів. &-модифікатори — окрема категорія синтаксису: вони не змінюють змінну, вони задають правила конкретної операції.
x + (5) — взяти x, виконати + 5, результат назад у x. Операції всередині дужок продовжують ланцюг зліва направо — лівий операнд завжди x.
app (/intbyte, /var) x = 12 ::start:: x + (5 * 5 + 4) ! x+5=17 → 17*5=85 → 85+4=89 /display(x)
app (/intbyte, /var) x = 12 ::start:: x + (5 * (5 + 4)) ! (5+4)=9 спочатку → x+5=17 → 17*9=153 /display(x)
app (/intbyte, /var) x = 2 ::start:: x + ((3 * (2 + 2)) * 2 + 1) ! парсер: (2+2)=4 → (3*4)=12 ! ланцюг: x+12=14 → 14*2=28 → 28+1=29 /display(x)
app (/intbyte, /var) x = 1 ::start:: x + (2 * 3 + 10 * 2) ! ланцюг: x+2=3 → 3*3=9 → 9+10=19 → 19*2=38 ! НЕ математика: 2*3+10*2=26, x+26=27 /display(x)
%tN залежить від попереднього. LLVM не може переоптимізувати.
app (/intbyte, /var) x = 12 ::start:: x (x + (5 * 2)) ! 5*2=10 → 12+10=22 → x = 22 (старе 12 затирається) /display(x)
x як початковий операнд нового ланцюга. Результат замінює старе значення x.
app (/intbyte, /var) x = 12 ::start:: x + 5 ! Немає акумулятора @. Немає виділеного регістру. ! Memory layout x не передбачає куди писати. ! Паніка парсера — не runtime.
x + 5 легально — @ вже виділений. В ::start:: без функції — немає куди писати.
255 + 1 = 0. Для контролю — &-модифікатори.
&-модифікатори — це окрема категорія синтаксису Terra. Ключова відмінність від звичайних умов: вони описують правило конкретної операції, а не стан змінної. Компілятор перетворює їх у нативні LLVM-інструкції без жодних умовних переходів у runtime.
/intbyte — кільце від 0 до 255: 255+1=0, 0-1=255.&-модифікатор перетворює кільце у відрізок з двома стелями — вийти за межі неможливо.
x + (a * 76 - 12 + 7)&max(212) — кожен проміжний результат затискається в [0..212].
llvm.uadd.sat / llvm.usub.sat (насичення) + llvm.umax / llvm.umin (затискання).Все в рідному типі (
i8, i16...) — без розширення до i64. Zero branches, zero overhead.
+ - * /
Насичення до максимуму типу. Для /intbyte: результат > 255 стає 255.
Може використовуватись самостійно або разом з &min.
app (/intbyte, /var) x = 1 ::start:: x + (300)&st ! 1+300=301 → 255 /display(x)
call i8 @llvm.uadd.sat.i8(i8 %x, i8 %val)+ - * /
Якщо результат > N — він стає N.
Неявно включає насичення — переповнення неможливе до застосування межі.
Може використовуватись без &min.
app (/intbyte, /var) x = 12 ::start:: x + (200)&max(150) ! sat(12+200)=212 → umin(212,150)=150 /display(x)
call i8 @llvm.uadd.sat.i8 → call i8 @llvm.umin.i8(i8 %sat, i8 150)+ - * /
Якщо результат < N — він стає N.
Неявно включає насичення знизу.
Може використовуватись без &max.
app (/intbyte, /var) x = 12 ::start:: x - (200)&min(10) ! sat(12-200)=0 → umax(0,10)=10 /display(x)
call i8 @llvm.usub.sat.i8 → call i8 @llvm.umax.i8(i8 %sat, i8 10)+ - * /
Повний відрізок — результат завжди в [A, B].
Еквівалентний синтаксис: &min&max(A, B)
Маска застосовується до кожного кроку ланцюга.
app (/intbyte, /var) x = 12 ::start:: ! sat(12+50)=62 → umax(62,10)=62 → umin(62,100)=62 x + (50)&min(10)&max(100) /display(x) ! Еквівалентний запис: ! x + (50)&min&max(10, 100)
uadd.sat.i8 → umax.i8(_, 10) → umin.i8(_, 100) — все в i8
Оператор <<! скидає змінну до нуля. Працює тільки з беззнаковими типами — для знакових типів виникає помилка парсера.
app (/intbyte, /var) x = 200 ::start:: <<! (x) ! x стає 0 /display(x)
app (/intbyte-, /var) y = 100 ::start:: <<! (y) ! помилка: знаковий тип
Terra підтримує числа в різних системах числення прямо в коді. Компілятор перетворює їх у десяткові значення на етапі лексингу — жодних runtime перетворень.
| Префікс | База | Приклад | Десяткове значення |
|---|---|---|---|
| 0b | двійкова (2) | 0b1100 | = 12 |
| 0o | вісімкова (8) | 0o14 | = 12 |
| 0x | шістнадцяткова (16) | 0xC | = 12 |
| (без префіксу) | десяткова (10) | 12 | = 12 |
app (/intbyte, /const) a = 12 app (/intbyte, /const) b = 0b1100 app (/intbyte, /const) c = 0o14 app (/intbyte, /const) d = 0xC ! a == b == c == d == 12
Математичні функції Terra — /sum, /sqrt, /median, /min, /max — окрема категорія синтаксису.
Більшість обробляється парсером до LLVM IR і компілюється у звичайну константу.
x.