открыть: Синтаксис 2Syntax 1

Операторы

Сравнение

a == b -- равенство a <> b -- неравенство a < b -- меньше_чем a > b -- больше_чем a <= b -- меньше_или_равно a >= b -- больше_или_равно a <=> b -- -1, если a < b; 0, если a == b; +1, если a > b;

Сравнение значений разных типов равнозначно сравнению порядковых номеров этих типов. Исключением из этого правила является сравнение значений между типами $int и $float. Чтобы узнать порядковый номер типа необходимо преобразовать этот тип в $int, используя native-функцию #as.

type_id = $null #as $int -- type_id = 0 var = #1 type_id = var #type # #as $int -- type_id = $bool #as $int

Порядковые номера у каждого типа могут различаться в разных версиях языка ksi. Однако стандарт гарантирует, что порядковый номер у типа $null всегда равен 0.

При вызове операторов сравнения по цепочке, кроме оператора <=>, работают ленивые вычисления.

-- выражение 1: a < b < c <= d == 0 > x -- почти аналогично выражению 2: (a < b) `and (b < c) `and (c <= d) `and (d == 0) `and (0 > x)

В приведённом выше примере результат выражений 1 и 2 будет одинаковым. Только выражение 1 преобразуется интерпретатором в меньшее количество инструкций, а следовательно работает быстрее.

Арифметические операторы

a + b a - b a * b a / b a `mod b -- остаток от деления

Логические

a `and b -- И * a `or b -- ИЛИ * a `xor b -- исключающее или (ЛИБО) a #not # -- отрицание

* Используются ленивые вычисления.

Результат выражения a `and b зависит от a. Если a после преобразования в тип $bool равно false #0, то результатом будет a (до преобразования), и выражение b не будет вычисляться. Иначе результатом будет b.

Выражение a `or b работает похожим образом. Если a после преобразования в тип $bool равно true #1, то результат будет a (до преобразования), и выражение b не будет вычисляться. Иначе результатом будет b.

Логика выражения a `xor b немного сложнее. Сперва вычисляются выражения a и b, а их результаты преобразуются в тип $bool – назовём их bool_a и bool_b. Если bool_b равно false #0, то результат всего выражения равен a. Если bool_b равно true #1 и bool_a равно false #0, то результат всего выражения равен b. Иначе результат всего выражения равен false #0.

Побитовые

a `_and b -- побитовое И a `_or b -- побитовое ИЛИ a `_xor b -- побитовое исключающее или a #_not # -- инвертировать биты

Текстовые

a % b -- конкатенация строк текста a %% b -- обратная конкатенация (a %% b == b % a)

Присваивание

-- Одиночное присваивание: a = 5 -- Групповое присваивание: (x y z) = # -- x = #, y = #, z = # -- Массивное присваивание: [a # c] = [1 2 3] -- a = 1, c = 3 -- Ассоциативное присваивание: {%key1:x, %key2:y} = { %key1:'раз' %key2:'два' %key3:'три' } -- x = 'раз', y = 'два'

Групповое, массивное и ассоциативное присваивание пока не реализовано в интерпретаторе.

В ksi также есть оператор присвоения вправо:

-- Одиночное: 5 => a -- Групповое: # => (x y z) -- x = #, y = #, z = # -- Массивное: [1 2 3] => [a # c] -- a = 1, c = 3 -- Ассоциативное: { %key1:'раз' %key2:'два' %key3:'три' } => {%key1:x, %key2:y} -- x = 'раз', y = 'два'

Групповое, массивное и ассоциативное присваивание вправо пока не реализовано в интерпретаторе.

Составное присвоение

a += 1 -- a = a + 1 2 /=> a -- a / 2 => a += +=> -= -=> *= *=> /= /=> `mod= `mod=> %= %=> %%= %%=> `and= `and=> -- * `or= `or=> -- * `xor= `xor=> `_and= `_and=> `_or= `_or=> `_xor= `_xor=> ??= ??=> -- *

* Используются ленивые вычисления.

Составное присвоение сможет также быть одновременно и групповым, массивным или ассоциативным, когда такая конструкция получит поддержку в интерпретаторе.

(a b) += 1 (x y) ??= array #implode "" -- Правая часть от ленивого оператора ??= будет вычислена не более одного раза. А может быть и не вычислена совсем.

Составное присвоение с вызовом функции

Пока не реализовано в интерпретаторе.

a &fn_call = b -- a = a &fn_call b a #implode = b -- a = a #implode b a &fn_call> = b -- a = b &fn_call a a #implode> = b -- a = b #implode a

Префиксная форма

Открывающая скобочка, префиксный оператор, список выражений, перечисленных через необязательную запятую, закрывающая скобочка. Перед закрывающей скобкой можно поставить запятую – она ни на что не повлияет.

(+ 1,2,3) => x -- x = 6 (+ 1 2 3) => x -- запятые не обязательны (% %hello, ' ', "world!") => t #echo # -- вывод: hello world! (`and a b c) -- a `and b `and c (?? #, (x = [], x.0), 'default') -- # ?? (x = [], x.0) ?? 'default'

Количество выражений после префиксного оператора должно быть не меньше двух, иначе будет ошибка загрузки скрипта. Присваивание не может быть использовано в качестве префиксного оператора.

Обращение к элементам составных типов

Для обращения к элементу составного типа (массив, мапа, объект класса) в языке ksi существуют два оператора – это точка . и квадратные скобочки var[key]. Между переменной и квадратными скобочками не должно быть пробелов, иначе произойдёт разделение на два выражения.

После оператора точка может следовать целое число или слово. Однако в контексте присвоения значения после точки может идти дополнительно и такие значения, как: #0, #1, #. Контекст присвоения – это операнд слева от оператора = (а также их составных вариантов), или справа от оператора => (а также их составных вариантов).

-- следующие три строки аналогичны: var.# = 5 var[] = 5 var[#] = 5 -- следующие две строки аналогичны: var.#1 = # var[#1] = # -- следующие две строки аналогичны: var.0 = 1 var[0] = 1 -- следующие три строки аналогичны: var.x = 'hello' var[%x] = 'hello' var['x'] = 'hello' x = var[#0] -- ошибки нет x = var.#0 -- ошибка этапа загрузки скрипта 'parse error' x = var.# -- тоже ошибка 'parse error'

Внутри оператора var[] может быть несколько выражений, перечисленных через необязательную запятую.

-- следующие пять строчек аналогичны: x = var[1 2 3] x = var[1][2][3] x = var[1].2[3] x = var[1 2].3 x = var[1, 1+1, 3]

Оператор взятия типа

Для того, чтобы получить тип значения, которое хранится в переменной – поставьте символ $ непосредственно после этой переменной.

a = "hello" type_of_a = a$

Таким образом можно также определять тип константы или элемента коллекции.

type = $float.pi#$ -- type = $float array = [10] type = array[0]$ -- type = $int map = {%msg: 'hello'} type = map.msg$ -- type = $text

Работа с функциями

Оператор восклицательный знак ! служит для вызова функции через указатель.

&sum a b ~ ret = a + b ; `plain fn = &sum& -- указатель на функцию x = 10 y = 10_ -- отрицательное число (минус десять) z = x fn! y -- вызов &sum через указатель z #echo # -- Выдаст: 0

Указатель на функцию и оператор восклицательный знак ! пока не реализованы в интерпретаторе.

Оператор сцепления с null

Выражение a ?? b возвращает a, если оно не null. Иначе вернёт b.

n = # array = [0, 1] map = {%x:0, %y:0} check = n ?? array.10 ?? map.z ?? 'default' check #echo # -- выдаст 'default'

Оператор ?? использует ленивые вычисления. Это значит если результат всего выражения известен после вычисления только левой части, то правая часть не будет выполнена.

n = #1 ret = n ?? ([%hello s# %world] #implode #) -- Здесь функция #implode не будет вызвана совсем.

Оператор сцепления с null можно использовать в сочетании с присваиванием: _переменная_ ??= _выражение_ или _выражение_ ??=> _переменная_. Такая конструкция использует ленивые вычисления, это значит что если _переменная_ не равна null, то всё _выражение_ не будет вычисляться и присвоение не произойдёт.

items = [] items.0 ??= 1 -- Присвоит 1, так как (items.0 == #) items.0 ??= 2 -- Не присвоит 2, так как (items.0 <> #) items #dump #0 -- Выдаст: [1]