Открыть выбор страниц

Использование

Скачайте последнюю версию Meazy и JDK версии 21.0.3 минимум

Откройте в консоли папку, в которой находится установленный файл Meazy-vVERSION.exe, далее упоминаемый как Meazy.exe

Далее, в зависимости от требований, выполните команду:

  • Выполнить код - Meazy.exe run <file_to_run>, где <file_to_run> - файл в формате .mea (либо формат .meac, если это скомпилированный код) с кодом, который вы хотите выполнить
  • Скомпилировать код - Meazy.exe compile <file_to_compile> <output_file_path>, где <file_to_compile> - файл в формате .mea с кодом, который вы хотите скомпилировать, <output_file_path> - файл со скомпилированным кодом (при необходимости Meazy создаст файл)
  • Декомпилировать код - Meazy.exe decompile <file_to_decompile> <output_file_path>, где <file_to_decompile> - файл в формате .meac с кодом, который вы хотите декомпилировать, <output_file_path> - файл с декомпилированным кодом (при необходимости Meazy создаст файл)
  • Узнать версию - Meazy.exe version

Аддоны также могут добавлять свои команды

Чтобы использовать аддоны, переместите их в папку addons, созданную при первом запуске Meazy

Код

  • В основном коде можно только создавать переменные, функции и классы
  • Каждое новое выражение (создание переменной, вызов функции, ...) начинается с новой строки
  • Все имена могут содержать только английские буквы, цифры (не должны стоять первыми) и нижние подчеркивания

Выполнение кода

  • Код выполняется сверху вниз
  • При запуске кода вызывается функция main(), которая должна быть создана внутри него. Без неё программа не несёт смысла
function main() {
//Тело функции
}

Типы данных

  • Any - любое возможное
  • Int - целые числа
  • Float - дробные числа
  • Boolean - логическое значение
  • String - строка
  • Названия всех созданных классов

Если после названия типа данных поставить ?, то под него будет подходить null значение (по умолчанию нет)

Создание

  • Переменные можно создавать в любом месте, но их имя должно быть уникально
  • Переменные, созданные внутри какого-либо тела, могут использоваться только внутри него и его наследников
  • Чтобы получить значение переменной, надо просто написать её имя
  • :TYPE - тип данных переменной, опционально. Если указан, значение должно всегда подходить под него

Создание переменной со значением:

var NAME:TYPE = VALUE

Создание переменной без значения:

var NAME:TYPE

Создание переменной с постоянным значением:

val NAME:TYPE = VALUE

Переопределение

  • Переменная с таким именем уже должна существовать
  • Значение у неизменяемой переменной не может быть переопределено
  • Новое значение должно подходить под тип данных переменной
NAME = VALUE

Сокращенная запись

Может использоваться любой арифметический знак:

NAME = NAME + VALUE
NAME += VALUE //То же самое, что и первая строчка

Может использоваться только + или -:

NAME = NAME + 1
NAME++ //То же самое, что и первая строчка

Основное условие

if (VALUE) {
//Тело условия
}
  • VALUE - значение типа Boolean
  • Если VALUE == true, то выполнится код, находящийся в теле условия

Иначе

else {
//Тело иначе
}
  • Перед этой частью обязательно должно стоять условие
  • Если условие перед этой частью не выполнилось, то выполнится код, находящийся в теле иначе

Иначе с условием

else if (VALUE) {
//Тело иначе с условием
}
  • Перед этой частью обязательно должно стоять условие
  • VALUE - значение типа boolean
  • Если условие перед этой частью не выполнилось, а VALUE == true, то выполнится код, находящийся в теле иначе с условием

Обычный цикл

for (INIT, TERMINATION, ASSIGNMENT) {
//Тело цикла
}
  • INIT - создание счётной переменной
  • TERMINATION - значение типа boolean, условие, при котором выполняется цикл
  • ASSIGNMENT - изменение значения переменной

Цикл, проходящий через все элементы коллекции

for (INIT in COLLECTION) {
//Тело цикла
}
  • Цикл будет выполняться до тех пор, пока не пройдет через всю коллекцию
  • INIT - создание переменной, используемой для хранения значения элемента коллекции. Не должна иметь изначального значения
  • COLLECTION - коллекция

Операторы

В теле цикла и в телах его детей (if, for, while) можно использовать следующие операторы:

  • continue - переход к следующей итерации
  • break - досрочное завершение выполнение цикла

Цикл while

while (VALUE) {
//Тело цикла
}

VALUE - значение типа boolean, условие, при котором выполняется цикл

Операторы

В теле цикла и в телах его детей (if, for, while) можно использовать следующие операторы:

  • continue - переход к следующей итерации
  • break - досрочное завершение выполнение цикла

Создание

function NAME(ARGS):TYPE {
//Тело функции
}
  • Создавать функции можно только в основном коде и классах
  • NAME - имя функции
  • ARGS - аргументы, которые определяются как переменные без присвоенного значения, перечисляются через запятую и не повторяются именами с другими аргументами. Их значения можно использовать только внутри определяемой функции. Если необходимости в аргументах нет, надо оставить скобочки пустыми
  • :TYPE - тип возвращаемого значения. Если функция не возвращает никакого значения, можно не указывать

Вызов

NAME(ARGS)
  • Вызываемая функция уже должна существовать
  • При вызове выполнится код, находящийся в теле функции
  • Число аргументов и их тип данных должны соответствовать указанным при создании функции

Return

В теле функции и в телах её детей (if, for, while) можно использовать return

  • Кода в теле функции после return быть не должно
  • Может иметь вид return VALUE, тогда функция вернёт VALUE

Создание

class NAME {
//Тело класса
}
  • Создавать классы можно только в основном коде
  • NAME - имя класса
  • Внутри тела можно объявлять только переменные, функции и конструкторы
  • Переменные внутри класса могут быть константами без значения, но должны обязательно быть проинициализированы в конструкторе

Создание экземпляра

new NAME(ARGS)

При создании экземпляра вызывается конструктор с подходящими аргументами

  • Вызываемый конструктор уже должен существовать
  • При вызове создаётся новый экземпляр класса, значения которого уникальны только для него самого
  • Если у класса нет ни одного конструктора, будет вызван пустой по умолчанию

Ключевое слово this

this будет возвращать экземпляр класса, в котором сейчас выполняется код

  • Ключевое слово this можно использовать только внутри конструкторов и не-shared функциях

Конструкторы

constructor(ARGS) {
//Тело конструктора
}
  • Создавать конструкторы можно только внутри класса
  • ARGS - аргументы, которые определяются как переменные без присвоенного значения, перечисляются через запятую и не повторяются именами с другими аргументами. Их значения можно использовать только внутри определяемого конструктора. Если необходимости в аргументах нет, надо оставить скобочки пустыми
  • После выполнения тела конструктора не должно остаться ни одной константы без значения

Модификаторы

Переменные, функции, классы и конструкторы могут иметь модификаторы, которые будут изменять их поведение

Созданные модификаторы:

  • private - можно использовать у переменных, функциях и конструкторах, созданных внутри класса - ограничивает доступ только изнутри класса
  • shared - можно использовать у переменных и функциях, созданных внутри класса - делает цель общей среди всех экземпляров класса

Количество слов

function main() {
val string = Input.readLine()
var ans:Int = 0
var isWaitingNewWord:Boolean = true

for (var i = 0; i < string.length(); i++) {
var char = string.getCharAt(i)

if (char != " " && isWaitingNewWord) {
ans++
isWaitingNewWord = false
}

if (char == " ") {
isWaitingNewWord = true
}
}

println(ans)
}

или

function main() {
println(Input.readLine().split(" ").size())
}
  • Ввод: Лучший язык программирования
  • Вывод: 3

Факториал

function main() {
println(factorial(Input.readInt()))
}

function factorial(var a:Int):Int {
if (a > 1) {
return factorial(a - 1) * a
}
return 1
}

или

function main() {
println(Math.factorial(Input.readInt()))
}
  • Ввод: 5
  • Вывод: 120

Уже известные ошибки

Нет :)

Чтение ошибок

  • Если ошибка возникла при парсинге кода, будет указан номер строки
  • Если ошибка произошла во время выполнения кода, будет просто написано, что пошло не так
  • Но если ошибка не имеет логики, то надо обязательно сообщить о ней

Создание проекта

Так как Meazy написан на Java, аддоны тоже должны использовать этот язык

Скачайте версию Meazy и импортируйте её в проект как jar-файл

Данные аддона

Создайте файл addon.json в папке resources и добавьте в него следующее содержимое:

{
"id": "ADDON_ID",
"version": "VERSION",
"main": "MAIN_CLASS"
}

Замените ADDON_ID на айди своего аддона, VERSION на версию, а MAIN_CLASS на путь к главному классу аддона

Список всех возможных данных:

  • id - айди аддона (обязательно)
  • version - версия аддона (обязательно)
  • main - главный класс аддона (обязательно)
  • description - описание аддона
  • author - автор аддона
  • authors - авторы аддона (если больше двух и не указан author)
  • depend - аддоны, которые должны обязательно быть, чтобы этот аддон работал. Аддон загрузится только после того, как все аддоны из списка будут загружены
  • softDepend - аддоны, после которых загрузится этот аддон
  • loadBefore - аддоны, перед которыми загрузится этот аддон

Главный класс

До этого вы указали путь к главному классу аддона в файле addon.json

Теперь, если этот класс не был создан, создайте его. Обязательно сделайте, чтобы он наследовал класс me.itzisonn_.meazy.addons.Addon

Переопределите метод onInitialize(). Он будет вызываться, когда аддон запускается. Теперь можно приступать к разработке аддона

Registries

Meazy работает на системе Registries, который даёт возможность регистрировать новые команды, типы токенов, модификаторы и т.д.

Существует класс Registries, в котором содержатся все Registry, используемые Meazy

Основной метод класса Registry - register(RegistryIdentifier identifier, T value, boolean overridable), с помощью которого можно зарегистрировать новое вхождение

RegistryIdentifier

RegistryIdentifier - уникальный айди вхождения. Чтобы его создать, надо вызвать метод RegistryIdentifier#of(String namespace, String id), в котором:

  • namespace - айди вашего аддона
  • id - айди самого вхождения

Создание команды

Чтобы создать команду, необходимо инициализировать абстрактный класс me.itzisonn_.meazy.command.Command

new Command(List.of("name")) {
@Override
public String execute(String[] args) {
MeazyMain.LOGGER.log(Level.INFO, "Hello, {}", args[0]);
return null;
}
}

В этом примере:

  • Команда требует один аргумент - имя. Выводит в консоль строку 'Hello, ИМЯ'
  • List.of("name") - список аргументов, которые будут показываться в консоли при неправильно введённой команде
  • Команда возвращает null, так как она уже выводит что-то в консоль. Если надо, чтобы строка вывелась вместе с информацией про длительность загрузки - верните её через return

Регистрация команды

Уже созданную команду можно зарегистрировать:

Registries.COMMANDS.register(RegistryIdentifier.of(NAMESPACE, ID), COMMAND);

Не забудьте заменить:

  • NAMESPACE - айди вашего аддона
  • ID - айди команды, по которому она будет вызываться
  • COMMAND - ваша команда