Цілі числа
Оголошення змінної
type
▶
app (/int4, /var) x = 42 app (/intbyte, /const) limit = 255 app (/int8-, /var) signed_val = -100 ! знаковий: суфікс "-" app (/int4, /var) nothing = .None. ! ініціалізація нулем
| Тег | LLVM | Діапазон (unsigned) |
|---|---|---|
| /intbyte | i8 | 0 … 255 |
| /int2 | i16 | 0 … 65535 |
| /int4 | i32 | 0 … 4 294 967 295 |
| /int8 | i64 | 0 … 18,4×10¹⁸ |
| /int16 | i128 | до 3,4×10³⁸ |
| /int64 | i512 | BigInt |
| /intlong | i1024 | BigInt, завжди 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
| Тег | Розмір |
|---|---|
| /float8 | 8-bit (мінімальний) |
| /float16 | 16-bit half precision |
| /float | 32-bit single ← стандарт |
| /float48 | 48-bit |
| /d-float | 64-bit double |
| /x-float | 80-bit extended |
| /q-float | 128-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 координат. Оновлення лейблів після кліку — ще не реалізовано.