Выражения и типы¶
Приоритет операторов (от низшего)¶
- Тернарник
cond ? a : b or,||and,&&- Сравнения
== != < > <= >= contains is(is===) - Сложение
+ -и конкатенация<<< >>> - Умножение
* / %(деление на ноль — ошибка, а неNaN) - Унарные
- ! not ++ -- - Постфикс:
.свойство,[ключ],x++/x-- - Первичные: литералы, переменные,
f(...),( ... )
+ — это и сложение, и конкатенация: если хоть один операнд текст —
результат текст ("n: " + 5 → "n: 5"). and/or — с коротким замыканием.
Сравнения и членство¶
if n < 2:
return n
if box contains "sword":
message "Armed!"
if victim is null:
stop
contains работает для списков (через looseEquals), мап (ключ) и текста
(подстрока). Числа сравниваются численно, всё остальное — как текст.
Вызовы, свойства, индексы¶
let victim = player(target) # вызов функции/builtin
message victim.name # свойство игрока
message box[0] # индекс списка/мапы/строки
Цепочки комбинируются: player(target).health, args[0].
Неизвестная функция — ошибка компиляции unknown function '...'.
Приведение типов¶
Значения — обычные JDK-типы (Double, String, Boolean, List, Map),
при необходимости приводятся:
- в число:
Boolean→ 1/0, текст — парсинг (пустой/мусор — ошибка); - в логику:
Booleanкак есть, число —!= 0, текст — непустой и не"false"; - в текст:
null→"", целые double — без.0(5, а не5.0), списки —[a, b].
Как работает вывод типов (для любопытных)¶
Compiler.kindOf доверяет только надёжным листьям: литералам, локалам
с непротиворечивым Storage.kind и вызовам с известной сигнатурой.
number+number→ примитивныеDADD/DCMPL, без боксинга;text+textв сравнениях →String.equals/concat;- остальное боксится сразу после вычисления операнда и уходит в
Values.*; +с неизвестным операндом даёт kindANY(неNUMBER), иначе цепочкаa + b + "x"потеряла бы текстовость;- бокс — ровно в одном месте: повторный бокс уже-объекта запрещён
(проверяется фактически произведённое представление), иначе
VerifyError; - конструкторы в генерируемом коде — только
INVOKESPECIAL.