Terra

Довідник синтаксису
v0.4
Цілі числа
Оголошення змінної type
app (/int4, /var) x = 42
app (/intbyte, /const) limit = 255
app (/int8-, /var) signed_val = -100   ! знаковий: суфікс "-"
app (/int4, /var) nothing = .None.    ! ініціалізація нулем
ТегLLVMДіапазон (unsigned)
/intbytei80 … 255
/int2i160 … 65535
/int4i320 … 4 294 967 295
/int8i640 … 18,4×10¹⁸
/int16i128до 3,4×10³⁸
/int64i512BigInt
/intlongi1024BigInt, завжди signed
Знаковий: додай - до тегу: /int4-, /int8-
Літерали (bin / oct / hex) type
app (/intbyte, /var) a = 0b1100   ! двійковий = 12
app (/intbyte, /var) b = 0o14    ! вісімковий = 12
app (/intbyte, /var) c = 0xC     ! шістнадцятковий = 12
Float типи
Оголошення float type
app (/float,    /var) f32  = 3.14159       ! 32-bit
app (/d-float,  /var) f64  = 2.718281828   ! 64-bit double
app (/float16,  /var) f16  = 1.5           ! 16-bit half
app (/q-float,  /var) f128 = 1.41421356   ! 128-bit quad
ТегРозмір
/float88-bit (мінімальний)
/float1616-bit half precision
/float32-bit single ← стандарт
/float4848-bit
/d-float64-bit double
/x-float80-bit extended
/q-float128-bit quad
Color тип
Оголошення / формати значення type
! Hex формат (alpha = 255 за замовчуванням)
app (/color, /var) green = #A4C639

! Hex з альфою
app (/color, /var) semi = #A4C63980

! RGB числами (0-255, alpha=255)
app (/color, /var) blue = 0, 0, 255

! RGB + alpha (0.0–1.0 → 0–255)
app (/color, /var) fade = 0, 0, 255, 0.155
Display форматів color display
/display(C)             ! 164, 198, 57, 255
/display(C(.hex.))      ! #A4C639
/display(C(.hex.a.))   ! #A4C639FF
/display(C(.rgb.))      ! 164, 198, 57
/display(C(.rgb.a.))   ! 164, 198, 57, 255
/display(C(.a.))        ! 255 (тільки alpha)
Color::Channel — модифікація каналів op
app (/color, /var) C = #A4C639

::start::
! Один канал
C::Red + (10)

! Кілька каналів в одному рядку (через кому)
C::Red + (10), Green - (5), Blue * (2)

! З saturation (&st)
C::Red + (100)&st, Alpha - (50)&st
Канали: Red, Green, Blue, Alpha (регістр не важливий). Оператори: +, -, *, /
Color + Color / Color + число op
app (/color, /var) C = #A4C639
app (/color, /var) D = #FF0000

::start::
! Векторна арифметика color + color (поканально)
C (C + D)
C (C - D)

! Color + скаляр (до кожного каналу)
C (C + 10)
C (C * 2)

! З saturation
C (C + D)&st
Внутрішній тип: <4 x i8> — LLVM вектор. Арифметика завжди unsigned (RGBA 0-255).
Color* — packed операція (32-bit) op
app (/color, /var) C = #A4C639

::start::
C* + (10)   ! всі 32 біти RGBA як одне i32
C* / (2)    ! lshr i32 (бітовий зсув вправо)
C* * (2)    ! shl i32 (бітовий зсув вліво)
Увага: packed op трактує RGBA як одне 32-бітне число. Корисно для швидких бітових операцій, але результат каналів може бути несподіваним.
Shelf — масив фіксованого розміру
Оголошення shelf shelf
app (/shelf, /intbyte, /var) S = (1, 2, 3, 4, 5)
app (/shelf, /int4-, /var)   T = (-10, 0, 10, 20)  ! знаковий
Розмір: визначається кількістю елементів при оголошенні. Максимум 16 елементів для SIMD оптимізацій.
Raster — багатоканальний масив
Оголошення та ініціалізація type
! СИНТАКСИС (не реалізовано в парсері)
app (/raster[8][4], /intbyte, /var) R
Статус: синтаксис спроектовано, але парсер ще не реалізований. Raster — багатоканальний 2D масив фіксованого розміру.
Базові операції
Присвоєння та арифметика op
::start::
x (42)          ! присвоїти 42
x (y)           ! присвоїти значення y
x + (10)        ! x = x + 10
x - (3)         ! x = x - 3
x * (2)         ! x = x * 2
x / (4)         ! x = x / 4
x (a + b)      ! x = a + b (вирази зліва направо!)
Важливо: немає пріоритету операцій — все зліва направо. 4 + 8 / 2 * 4 + 10 = 34
copy — копіювання з гарантією op
y copy x   ! y ← копія x (семантика значення)
copy гарантує незалежну копію (важливо для shelf та cross-block).
Переповнення &st (saturation)
Обмеження при переповненні op
x + (300)&st    ! якщо x=100 → 255 (не wrap)
x * (10)&st    ! clamp до max типу

! Інші модифікатори результату:
x + (5)&min   ! зберегти мінімум
x + (5)&max   ! зберегти максимум
Zero-out <<!
Швидке обнулення змінної op
<<! (x)   ! x = 0 (через бітовий зсув, оптимальний IR)
<<! (S)   ! весь shelf = 0 (тільки unsigned shelf)
Math теги
/sum, /sqrt, /margin, /mean, /max, /min op
! Math теги — застосовуються до shelf
/sum(S)          ! сума всіх елементів
/mean(S)         ! середнє арифметичне
/max(S)          ! максимальне значення
/min(S)          ! мінімальне значення
/sqrt(x)         ! квадратний корінь (float)
/margin(x)       ! відхилення від середнього
Статус: /sum, /mean, /max, /min — реалізовано в codegen для shelf. /sqrt, /margin — парсер розпізнає, codegen потребує перевірки. /sin, /cos, /log — в третій черзі реалізації.
Операції shelf
Доступ по індексу / масова операція shelf
S[2] + (10)       ! S[2] = S[2] + 10
S* + (5)          ! всі елементи + 5
S* * (2)          ! всі елементи * 2
Rotation — циклічний зсув shelf
! При оголошенні нового shelf:
app (/shelf, /intbyte, /var) Left  = S[-1]  ! rotate left 1
app (/shelf, /intbyte, /var) Right = S[+1]  ! rotate right 1

! S = (1,2,3,4,5)
! Left  → (5,1,2,3,4)
! Right → (2,3,4,5,1)
/mirror — дзеркальне відображення shelf
! S = (1,2,3,4,5,6,7,8,9)
app (/shelf, /intbyte, /var) M  = /mirror(S)
! M → (9,8,7,6,5,4,3,2,1)

app (/shelf, /intbyte, /var) M2 = /mirror(S(/s_half))
! M2 → (5,4,3,2,1,6,7,8,9) — дзеркало першої половини
/difference — різниця між сусідами shelf
! S = (1,2,3,4,5,6,7,8,9)
app (/shelf, /intbyte, /var) D1 = /difference(S(step::1))
! D1 → (1,1,1,1,1,1,1,1) — різниця між кожним

app (/shelf, /intbyte, /var) D2 = /difference(S(step::2))
! D2 → (2,2,2,2,2,2,2) — через один
/ripple — хвильова обробка shelf
! Ripple = (0,0,0,0,0,0,0,0,0,0,0,0,0)
::start::
/ripple(Ripple(step::3(3), count::+1))[2] + (4)
! → (0,0,4,4,4,5,5,5,6,6,6,0,0)
!    ↑крок 3, 3 групи, +1 між групами, стартова позиція [2]
++ конкатенація shelf
! Shelf=(1,2,3,4,5)  Shelf1=(0,0,0,0,0)
Shelf2 (Shelf ++ Shelf1)           ! 1,2,3,4,5,0,0,0,0,0
Shelf2 (Shelf ++ Shelf1(step::1))   ! 1,0,2,0,3,0,4,0,5,0
Shelf2 (Shelf(step::1) ++ Shelf1)   ! 0,1,0,2,0,3,0,4,0,5
display shelf display
/display(S)              ! всі елементи
/display(S[2])           ! елемент [2]
/display(S(.name.))     ! ім'я shelf ("S")
/display(/map(S))        ! карта індекс→значення
/display(/mean(S))      ! середнє значення
Aliasing — іменований вид на підмножину
Aliasing пакету індексів shelf
app (/shelf, /intbyte, /var) S = (0,1,2,3,4,5,6,7,8)

::start::
! Оголошуємо аліас для індексів [1,0,8]
S[*1*0*8] (aliasing::Alise)

! Далі звертаємось по імені:
Alise + (10)     ! S[1]+=10, S[0]+=10, S[8]+=10
Alise (42)       ! присвоєння пакету
Парсер захищає: індекс поза межами → помилка. Дублюючі індекси → попередження. /const або /onlyread shelf → помилка при modify.
ElseIf — умовна фільтрація shelf
Оголошення та використання в perform shelf
! Оголошення контракту (умови для елементів)
app (/elseif) Filter:
    < .True. ({int}, 5, /intbyte)   ! елемент < 5
    = .True. ({int}, 5, /intbyte)   ! елемент = 5
    > .True. ({int}, 5, /intbyte)   ! елемент > 5

app (/shelf, /intbyte, /var) S = (1,2,3,4,5,6,7,8,9)

! perform: гілки обробки по умовах
perform Jenni()(S)(Filter):
    .True. = S.N(Filter(<, =, >(.N.))),(+10)/(*5)/(−4)&rw
    end Jenni
!                              ↑<5  ↑=5  ↑>5
!                                   операції для кожної гілки

::start::
call Jenni()()():
perform / call — функції
Оголошення та виклик func
! perform Назва()(параметри)(ElseIf):
perform Calc()(x, y)():
    x + (1)
    y * (2)
    end Calc

::start::
call Calc()(a, b)():   ! передати конкретні змінні
unitperform — однократне виконання (inline). Синтаксис ідентичний до perform.
return — повернення значення func
perform GetVal()(src)():
    src + (10)
    return src       ! передає значення в onlyread приймач
    end GetVal
cross-block — чиста трансформація
Оголошення та виклик func
! Оголошення: чиста трансформація без побічних ефектів
app (/cross-block) cb:
    __enter = 2          ! кількість вхідних аргументів
    __out   = 1          ! кількість вихідних аргументів
    __type  = /intbyte  ! тип елементів
    cross.0 (__enter.0 + __enter.1)  ! проміжний результат
    __out.0 (cross.0 * 2)&st          ! вихідний результат
    end cb

! Оголошення змінних
app (/intbyte, /var) result = .None.
app (/intbyte, /var) a = 10
app (/intbyte, /var) b = 20

! Виклик: call name(inputs)(outputs):
::start::
call cb(a, b)(result):
/display(result)  ! 60
Гарантія: side effects структурно неможливі — cross-block копіює дані, не має доступу до зовнішніх змінних.
Ланцюгові cross-block (/left, /right) func
! /left, /right — векторизовані операції між сусідніми блоками
! (синтаксис спроектовано, реалізація в процесі)
app (/cross-block) ShiftLeft:
    __enter = 8
    __out   = 8
    __type  = /intbyte
    __out.0 (__enter.0 /left (1))
    end ShiftLeft
Статус /left /right: IR генерується правильно, математика верифікована вручну. Наскрізний тест (IR → бінарник) потребує clang.
Python виклик
&Python — виклик Python stdlib func
! Виклик Python stdlib — значення присвоюється через &Python
app (/intbyte, /var) Intbyte = .None.

::start::
Intbyte (randint(12, 18))&Python   ! ціле від 12 до 18
/display(Intbyte)
Функція randint береться напряму з Python stdlib без import. Парсер перевіряє наявність &Python після виклику — без нього помилка з підказкою.
Display — вивід значень
Формати виводу display
/display(x)       ! за типом
/display(x(B))    ! binary  → 0b101010
/display(x(O))    ! octal   → 0o52
/display(x(F))    ! hex     → 0x2A
/display(x(*))    ! decimal (примусово)
B та O — тільки для unsigned типів.
Timing — вимірювання тактів CPU
::time:: та /display(UA/EN(::end_time::)) timing
::start::
::time::               ! старт RDTSC
x + (1)
x * (2)
/display(UA(::end_time::))   ! стоп + вивід укр.
! → "Час виконання операції: XXXXX тактів процесора"

/display(EN(::end_time::))   ! або англ.
! → "Execution time: XXXXX CPU cycles"
RDTSC — нульовий overhead, без syscall. Генерує один рядок LLVM IR.
::end_time:: без /display — просто закриває блок без виводу.
limit:: — права доступу
Групові та індивідуальні права access
! Групові права — список функцій через кому
app (/intbyte, /var) x = 100 limit::(Jenni, Ginny)&r

! Індивідуальні права
app (/intbyte, /var) y = 200 limit::Jenni&rw

! Комбінація: група тільки-читати + один читати-писати
app (/intbyte, /var) z = 200 limit::(Jenni, Ginny)&r, Astra&rw
МодЗначення
&rтільки читання
&wтільки запис
&rwчитання і запис
limit:: пишеться в кінці рядка оголошення змінної. Парсер перевіряє права статично — помилка під час компіляції.
onlyread — ексклюзивний приймач
.FuncName. та .perform. access
! Ексклюзивний приймач — тільки конкретна функція
app (/intbyte, /onlyread) jenni_excl = ( .Jenni. )

! Будь-яка perform функція може читати
app (/intbyte, /onlyread) any_fn = ( .perform. )

! Без обмежень (всі функції мають доступ)
app (/intbyte, /var) public = 150
.FuncName. — крапки з обох боків = маркер ексклюзивного приймача. Використовується разом з /onlyread.
GUI — MainWindow
/mainwindow — структура вікна gui
app (/intbyte, /var) temp = 42
app (/intbyte, /var) pressure = 50

app (/mainwindow) Main:
    /size = 400x300
    /background = (20, 20, 20)
    app (/label(style::DANGER)) templabel = (temp)
    app (/label) presslabel = (pressure)&mm_color((100+, #E32636), (5-, (93, 138, 168)))
    app (/button(style::PRIMARY)) resetbtn = Main.reset("Reset")
perform .reset ()(temp, pressure)():
    temp + (0)
    end .reset
    end Main

::start::
Main.return
perform .reset — всередині блоку app (/mainwindow), між кнопкою і end Main. Це навмисний синтаксис — метод вікна.
Codegen: базовий X11 рендер реалізовано. Обробка кліків — реалізовано через координатний hit-test. Threshold-колір (LUT) — реалізовано. Але весь GUI pipeline ще потребує наскрізного тестування.
GUI — Label
/label — базові форми gui
! Простий label
app (/label) lbl = (x)

! З іменованим стилем
app (/label(style::DANGER)) lbl = (temp)
Порогове підсвічування — &max_color / &min_color / &mm_color gui
! Червоний якщо значення >= 129 (перескочило поріг 128)
app (/label) lbl = (int1)&max_color(128+, #E32636)

! Те саме але кольор через змінні
app (/label) lbl = (int1)&max_color(stopline+, color_value)

! Синій якщо значення <= 128
app (/label) lbl = (int1)&min_color(128-, #E32636)

! Обидва пороги одночасно: >=100 червоний, <=5 синій
app (/label) lbl = (pressure)&mm_color((100+, #E32636), (5-, (93, 138, 168)))
128+ = значення >= 128+1 → колір змінюється. Перевірку може виконувати GPU.
/label, /shelf — відображення масивів gui
! Числові значення shelf
app (/label, /shelf) shelf_lbl = (S)

! Кольорові квадратики замість чисел
app (/label, /shelf) shelf_lbl = (S)&color_data

! Числа у кольорових квадратиках (потребує style)
app (/label, /shelf(style::ENDS)) shelf_lbl = (S)&data

! Тільки квадратики зі стилем
app (/label, /shelf(style::ENDS)) shelf_lbl = (S)&color_data
&color_data і &data зі style потребують визначеного style::/label(ENDS) — без нього помилка парсера.
GUI — Button
/button — оголошення та обробник gui
! Звичайна кнопка
app (/button) btn = Main.click("Click me!")

! З іменованим стилем
app (/button(style::PRIMARY)) resetbtn = Main.reset("Reset")
Main.reset → шукає perform .reset всередині блоку вікна.
GUI — style:: блок
style::/label — властивості gui
style::/label(DANGER)
    /border(5pt)              ! товщина бордера
    /border(5pt, #E32636)    ! + колір бордера
    /background(#1E1E1E)     ! фон hex ✅
    /max_color(128+, #E32636)
    /min_color(10-, #0088FF)
    /mm_color((128+, #E32636), (10-, #0088FF))
Баг парсера: /background(30, 30, 30) — RGB в style блоці не працює. Використовуй hex: /background(#1E1E1E)
/wave — анімований фон gui
style::/label(WAVE)
    /wave(/background(#E32636, #00DDDD))        ! анімація за замовчуванням
    /wave(/background(#E32636, #00DDDD), stop)   ! статична хвилька
    /wave(/background(#E32636, #00DDDD), 18)     ! швидкість 18 пт/сек
/color_data — діапазони кольорів для shelf gui
style::/label(ENDS)
    /color_data(0...5(#FF9966), 6...255(127, 255, 0))
    ! значення 0-5 → помаранчевий квадрат
    ! значення 6-255 → зелений квадрат
Використовується з &color_data або &data на shelf label.
style::/button — властивості gui
style::/button(PRIMARY)
    /border(2pt)
    /background(#FFFFFF)
Ім'я стилю довільне. Застосовується через /button(style::PRIMARY).
GUI — perform .click (обробник)
Повний приклад вікна з обробником gui
app (/intbyte, /var) counter = 0

app (/mainwindow) Main:
    /size = 400x300
    /background = (20, 20, 20)
    app (/label) lbl = (counter)
    app (/button) btn = Main.click("Click me!")
perform .click ()(counter)():
    counter + (1)
    /display(counter)
    end .click
    end Main

::start::
Main.return
perform .click — всередині блоку між кнопкою і end Main. Крапка = GUI обробник. Відповідає Main.click("...").
Статус codegen: X11 вікно відкривається, рендер лейблів і кнопок — реалізовано. Виклик perform при кліку — реалізовано через hit-test координат. Оновлення лейблів після кліку — ще не реалізовано.