Здравствуйте, я разработчик нового языка программирования с динамической типизацией под названием ksi. Надеюсь вы мне поможете определиться с приоритетом операторов в этом языке.
Введение
В ksi есть разграничение имён функций, типов, переменных и ключевых слов.
Имена типов начинаются с символа $ ($int $float $text $bool $null)
Имена пользовательских функций — с символа & (&my_func_1)
У native функций это символ # (#implode #echo #dump #not #_not)
Для ключевых слов это символ обратной кавычки (backtick) `and `or `xor `while `_and `_or `_xor
Переменные же без спец. символа (x y z msg)
Однострочные комментарии начинаются с последовательности -- (это как в 3ds max script)
Многострочные комментарии могут быть вложенными и они как в c++ /* comment */
Специальные значения:
# -- null
#0 -- false
#1 -- true
Отрицательные значения:
1_ -- минус один
0.5_ -- минус ноль целых пять десятых
В ksi есть оператор присвоения вправо:
1 + 2 => x
Вызов функций у ksi отличается от других языков программирования. Функции принимают два аргумента — левый и правый.
x = [1 2 3] -- массив
y = x #implode ", "
-- y = "1, 2, 3"
Это позволяет вызывать функции по цепочке слева-на-право.
[1 2 3] => array #implode ' ' #dump #0
-- выдаст: "1 2 3"
Функция #dump выводит левый аргумент на экран. Правый аргумент отвечает за многострочность вывода значений составных типов (если #1 то будет несколько строк, иначе вывод в одну строку). Функция #dump возвращает левый аргумент.
Вызов пользовательских функций осуществляется аналогичным образом. А когда надо передать больше двух значений в функцию можно воспользоваться массивом, ассоциативным массивом или объектом класса (классы пока не реализованны в интерпретаторе).
Побитовые операторы:
a `_and b
a `_xor b
a `_or b
Логические операторы:
a `and b
a `xor b
a `or b
Операторы `and и `or используют ленивые вычисления.
Приоритет операторов на данный момент такой:
// precedence
enum n_prec {
prec_leaf, // (leaf)
prec_x_then, // ? `each `for (if-then, loop)
prec_member, // a.key a[key]
prec_rtx_assign,// => +=> -=> *=> /=> %=> %%=> ??=>
prec_x_assign, // = += -= *= /= %= %%= ??=
prec_invoke, // ! & (fn call, fn ref)
prec_mult, // * / `mod
prec_plus, // + - % %% &user_fn #native_fn
prec_cmp, // <=>
prec_less, // < <= > >=
prec_eq, // == <>
prec_and_, // `_and (bitwise)
prec_xor_, // `_xor
prec_or_, // `_or
prec_throw, // `throw
prec_and, // `and (logical)
prec_xor, // `xor
prec_or, // `or
prec_nullc, // ?? (null coalescing)
prec_assign, // = += -= *= /= %= %%= ??=
prec_rt_assign, // => +=> -=> *=> /=> %=> %%=> ??=>
prec_then, // ? `each `for (if-then, loop)
prec_pair, // : (key-value pair)
prec_root, // (top)
};
Как видно из си++ перечисления вызов функций имеет тот-же приоритет, что и у сложения.
Итак суть вопроса 1. Приоритет побитовых операторов.
2 + 2 `_and 1 #dump #0
-- Это выражение на данный момент аналогично выражению:
(2 + 2) `_and (1 #dump #0)
-- вывод на экран: 1
Что на мой взгляд не совсем интуитивно. И я подумываю
изменить приоритет побитовых операторов в ksi, чтобы они находились между умножением и сложением.
-- И тогда:
2 + 2 `_and 1 #dump #0
-- будет аналогично выражению:
(2 + (2 `_and 1) ) #dump #0
-- что выдаст: 2
Вопрос 2. Приоритет операторов сравнения.
Я сделал так, что операторы сравнения больше/меньше/больше-или-равно/меньще-или-равно в ksi можно вызывать по цепочке.
a < b < c < d -- выражение 1
-- не идентичный аналог:
(a < b) `and (b < c) `and (c < d) -- выражение 2
Выражения 1 и 2 аналогичны, но не идентичны. Их результаты одинаковы, только выражение 1 будет вычисляться быстрее, так как оно преобразуется интерпретатором в меньшее кол-во инструкций.
Операторы сравнения == <> тоже можно вызывать по цепочке.
a == b <> c
-- аналог:
a == b `and b <> c
Теперь если использовать оператор < и оператор == в одной цепочке:
a < b == c < d
-- на данный момент будет аналогично:
(a < b) == (c < d)
-- ведь у оператора < и == разные приоритеты.
Но я подумываю над тем, чтобы это изменить. Возможно стОит сделать приоритет == и <> такой-же как у < как считаете?
-- тогда выражение:
a < b == c < d
-- будет аналогично выражению:
(a < b) `and (b == c) `and (c < d)
Стоит ли так поступить с операторами сравнения, или оставить как есть?