Skip to content
pmgl edited this page Apr 7, 2022 · 1 revision

microScript

microScript - это простой язык, вдохновленный Lua. Вот некоторые общие принципы, используемые в microScript:

  • По умолчанию переменные являются глобальными. Чтобы определить локальную переменную, используйте ключевое слово "local".
  • Переносы строк не имеют особого значения, они рассматриваются как пробелы.
  • в microScript нет значений null, nil или undefined. Любая неопределенная или нулевая переменная равна 0.
  • В microScript нет булевого типа. 0 - это false, а все, что не 0 - true.
  • В microScript нет ошибок выполнения или исключения. Любая переменная, которая не определена, возвращает 0. Вызов значения, которое не является функцией, как функцию, возвращает само значение.

Переменные

Переменная - это имя (или "идентификатор"), которому можно присвоить значение. Таким образом, она позволяет хранить это значение.

Объявление

Переменные в microScript не нужно объявлять. Любая переменная, которая еще не использовалась, может считаться существующей и иметь значение 0.

Чтобы начать использовать переменную, просто присвойте ей значение с помощью знака равенства:

x = 1

Значение x теперь равно 1.

Типы значений

microScript распознает пять типов значений: числа, строки (текст), списки, объекты и функции.

Число

Значения типа "число" в microScript могут быть целыми или десятичными числами.

pi = 3.1415
x = 1
half = 1/2

Строка из символов

Строка - это текст или фрагменты текста. Она должна быть заключена в кавычки.

animal = "кот"
print("Привет "+animal)

Список

Списки могут содержать несколько значений:

empty_list = []
prime_numbers = [2, 3, 5, 5, 7, 11, 13, 17, 19]
mixed_list = [1, "кот", [1, 2, 3]]

Вы можете получить доступ к элементам списка по их индексу, т.е. их позиции в списке от 0:

list = ["кот", "собака", "мышь"]
print(list[0])
print(list[1])
print(list[2])

Также легко просматривать список с помощью цикла for:

for element in list
  print(element)
end

Объект

Объект в microScript - это форма ассоциативного списка. Объект имеет одно или несколько "полей", которые имеют ключ и значение. Ключ - это строка символов, а значение может быть любым значением microScript. Определение объекта начинается с ключевого слова "object" и заканчивается ключевым словом "end". Между этими двумя словами может быть определено несколько полей. Пример:

my_object = object
  x = 0
  y = 0
  name = "объект 1"
end

Вы можете получить доступ к полям объекта с помощью оператора . . Следовательно, приведенное выше определение также может быть записано:

my_object.x = 0
my_object.y = 0
my_object.name = "объект 1"

К нему также можно обратиться с помощью скобок []. Следовательно, приведенное выше определение также может быть записано:

my_object["x"] = 0
my_object["y"] = 0
my_object["name"] = "объект 1"

Вы можете просматривать список полей объекта с помощью цикла for:

for field in my_object
  print(field + " = " + my_object[field])
end

Более подробное описание объекта см. в разделе "Классы".

Значение функции

Значение может быть функцией. При записи draw = function() ... end создается значение функции и присваивается в переменную draw (см. раздел о функциях ниже).

Локальные переменные

По умолчанию переменные, объявленные с помощью присваивания, являются глобальными. Можно определить локальную переменную, как часть функции, используя ключевое слово "local". Пример:

myFunction = function()
  local i = 0
end

Функции

Функция - это последовательность операций, которая выполняет работу, вычисления и иногда возвращает результат.

Определение функции

Функция задается ключевым словом "function" и заканчивается ключевым словом "end". Пример:

nextNumber = function(s)
  x+1
end

Вызов функции

print(nextNumber(10))

Когда вы вызываете значение, которое не является функцией, как функцию, оно возвращает свое значение. Пример:

x = 1
x(0)

Приведенный выше код возвращает значение 1, не вызывая ошибки. Таким образом, вы даже можете вызвать функцию, которая еще не определена (тогда она будет иметь значение 0), без возникновения ошибки. Это позволяет вам начать структурировать вашу программу на самом раннем этапе с подфункций, над которыми вы будете работать позже. Например:

draw = function()
  drawSky()
  drawClouds()
  drawTrees()
  drawEnemies()
  drawHero()
end

// Я могу реализовать вышеуказанные функции в своем собственном темпе.

Условия

Простое условие

Условный оператор позволяет программе проверить гипотезу и выполнить различные операции в зависимости от результата проверки. В microScript условия записываются следующим образом:

if age<18 then
  print("ребенок")
else
  print("взрослый")
end

"if" означает "если"; "then" означает "тогда"; "else" означает "иначе"; "end" означает "конец".

В приведенном выше примере, если значение переменной age меньше 18, то будет выполнена команда print("ребенок"), иначе будет выполнена команда print("взрослый").

Бинарные операторы сравнения

Здесь перечислены бинарные операторы, которые можно использовать для сравнения:

Оператор Описание
== a == b истинно, только если a равно b
!= a != b истинно, только если a отличается от b
< a < b истинно, только если a строго меньше b
> a > b истинно, только если a строго больше b
<= a <= b истинно, только если a меньше или равно b
>= a >= b истинно, только если a больше или равно b

Логические операторы

Оператор Описание
and логическое И: a and b истинно, только если a и b истинны
or логическое ИЛИ: a or b истинно, если a истинно или b истинно
not логическое НЕ: not a истинно, если a ложно, и ложно, если a истинно

Логические значения

В языке microScript нет булевых типов. Значение 0 считается ложным, а любое другое значение - истинным. Операторы сравнения возвращают 1 для true или 0 для false. Для удобства, microScript также позволяет вам использовать эти две предопределенные переменные:

Переменная Значение
true 1
false 0

Множественные условия

Можно проверить несколько гипотез, используя ключевое слово "elsif" (сокращение от "else if")

if age<10 then
  print("ребенок")
elsif age<18 then
  print("подросток")
elsif age<30 then
  print("молодой взрослый")
else
  print("солидный возраст")
end

Циклы

Циклы позволяют выполнять многократные обработки.

Цикл for

Цикл for широко используется в программировании. Он позволяет выполнять одну и ту же обработку всех элементов списка или последовательности значений.

for i=1 to 10
  print(i)
end

Приведенный выше пример выведет в консоль каждое число от 1 до 10.

for i=0 to 10 by 2
  print(i)
end

Приведенный выше пример выведет в консоль числа от 0 до 10 с шагом 2.

list =[2, 3, 5, 7, 11]
for number in list
  print(number)
end

В приведенном выше примере создается список, а затем выводится каждый элемент списка.

Цикл while

Цикл while позволяет выполнять операции многократно до тех пор, пока не будет получен удовлетворительный результат.

x = 1
while x*x<100
  print(x*x)
  x += 1
end

В приведенном выше примере выводится квадрат x, затем инкрементируется x (т.е. прибавляется 1 к x) до тех пор, пока квадрат x меньше 100.

Прервать или продолжить цикл

Вы можете преждевременно завершить цикл for или while с помощью оператора break. Пример:

while true
  x += 1
  if x >= 100 then break end
end

Вы можете пропустить оставшиеся операции цикла и перейти к следующей итерации цикла с помощью оператора continue. Пример:

for i=0 to 10000
  if i%10 == 0 then continue end // это пропустит обработку чисел, кратных 10
  doSomeProcessing(i)
end

Операторы

Вот список бинарных операторов в microScript (исключая операторы сравнения, уже упомянутые выше)

Оператор Описание
+ Сложение
- Вычитание
* Умножение
/ Деление
% Модуль: x % y равно остатку от деления x на y
^ Степень: x ^ y равно x в степени y - pow(x, y)

Предустановленные функции

Функции

Функция Описание
max(a, b) Возвращает наибольшее число a или b
min(a, b) Возвращает наименьшее число a или b
round(a) Возвращает значение a, округленное до ближайшего целого значения
floor(a) Возвращает значение a, округленное до нижнего целого числа
ceil(a) Возвращает значение a, округленное вверх
abs(a) Возвращает абсолютное значение a
sqrt(a) Возвращает квадратный корень из a
pow(a, b) Возвращает a в степени b (другие возможные обозначения: a ^ b)
PI Константа, равная числу Pi
log(a) Возвращает натуральный логарифм от a
exp(a) Возвращает число Эйлера, возведенное в степень a

Функции тригонометрии в радианах

Функция Описание
sin(a) Возвращает синус от a (a в радианах)
cos(a) Возвращает косинус от a (a в радианах)
tan(a) Возвращает тангенс от a (a в радианах)
acos(a) Возвращает арккосинус от a (результат в радианах)
asin(a) Возвращает арксинус a (результат в радианах)
atan(a) Возвращает арктангенс a (результат в радианах)
atan2(y, x) Возвращает арктангенс y/x (результат в радианах)

Функции тригонометрии в градусах

Функция Описание
sind(a) Возвращает синус от a (a в градусах)
cosd(a) Возвращает косинус от a (a в градусах)
tand(a) Возвращает тангенс от a (a в градусах)
acosd(a) Возвращает арккосинус от a (результат в градусах)
asind(a) Возвращает арксинус от a (результат в градусах)
atand(a) Возвращает арктангенс a (результат в градусах)
atan2d(y, x) Возвращает арктангенс y/x (результат в градусах)

Случайные числа

Объект random используется для генерации псевдослучайных чисел. Генератор можно инициализировать функцией seed, чтобы при каждом выполнении получать одну и ту же последовательность чисел или наоборот, каждый раз разную.

Функция Описание
random.next() Выдает новое случайное число в диапазоне от 0 до 1
random.nextInt(a) Возвращает новое целое случайное число от 0 до a-1
random.seed(a) Переустановка последовательности случайных чисел с помощью значения a; если вы используете одно и то же инициализирующее значение дважды, вы получите одну и ту же последовательность случайных чисел. Если a == 0, генератор случайных чисел инициализируется случайным образом и поэтому невоспроизводим.

Операции со строками

Операция Описание
string1 + string2 Оператор + может использоваться для объединения строк
string.length Значение, которое хранит длину строки
string.substring(i1, i2) Возвращает подстроку символьной строки, начинающуюся с индекса i1 и заканчивающуюся индексом i2
string.startsWith(s) Возвращает 1 (true), если строка начинается точно с s
string.endsWith(s) Возвращает 1 (true), если строка заканчивается точно на s
string.indexOf(s) Возвращает индекс первого вхождения s в string или -1, если string не содержит такого вхождения
string.lastIndexOf(s) Возвращает индекс последнего вхождения s в string или -1, если string не содержит ни одного такого вхождения
string.replace(s1, s2) Возвращает новую строку, в которой первое вхождение s1 (если оно есть) заменено на s2
string.toUpperCase() Возвращает строку, преобразованную в верхний регистр
string.toLowerCase() Возвращает строку, преобразованную в нижний регистр
string.split(s) Функция split делит строку на список подстрок путем поиска подстроки-разделителя, заданного в качестве аргумента, и возвращает этот список

Операции со списком

Операция Описание
list.length Хранит длину списка (количество элементов в списке)
list.push(element) Добавляет элемент в конец списка
list.insert(element) Вставляет элемент в начало списка
list.insertAt(element, index) Вставляет элемент в список по заданному индексу
list.indexOf(element) Возвращает позицию элемента в списке (0 для первого элемента, 1 для второго элемента и т.д.). Возвращает -1, если элемент не найден в списке.
list.contains(element) Возвращает 1 (true), если element находится в списке или 0 (false), если элемент не найден в списке
list.removeAt(index) Удаляет из списка элемент по заданному index
list.removeElement(element) Удаляет из списка element, если он найден в списке
list1.concat(list2) Возвращает новый список, полученный путем добавления list2 к list1

Сортировка списка

Вы можете сортировать элементы списка с помощью функции list.sortList(compareFunction). Предоставляемая вами функция compareFunction должна принимать два аргумента (которые мы будем называть a и b) и возвращать:

Возвращаемое значение Когда возвращается
Отрицательное число Когда a должно быть отсортировано перед b (a меньше b)
Ноль Когда a и b имеют равное положение относительно желаемого критерия упорядочения
Положительное число Когда a должны быть отсортированы после b (a больше b)
Пример

В примере ниже предполагается, что список содержит точки, каждая из которых имеет координату x. Мы хотим отсортировать точки от меньшего значения point.x к большему значению point.x:

compare = function(point1,point2)
  return point1.x - point2.x
end

list.sortList(compare)

Обратите внимание, что приведенный выше код можно сделать короче:

list.sortList(function(point1,point2) point1.x - point2.x end)

Если функция сравнения не задана, элементы списка будут отсортированы в алфавитном порядке.

Комментарии

Комментарии в microScript могут быть добавлены после двойного слеша: //; все, что следует за ними до следующего перевода строки, игнорируется при анализе программы.

Пример
myFunction = function()
  // мои заметки о роли функции myFunction
end

Классы

Класс в языке программирования - это своего рода чертеж или шаблон для создания объектов. Класс определяет свойства и функции по умолчанию, которые представляют собой состояние и поведение по умолчанию всех объектов, которые будут созданы на его основе. Вы можете создавать экземпляры объектов, производные от класса, которые будут наследовать все свойства класса. Использование классов и их производных объектов в программе называется объектно-ориентированным программированием (ООП).

Чтобы наглядно продемонстрировать эти понятия, мы рассмотрим, как можно использовать классы для управления врагами в вашей игре:

Создание класса

Мы начнем с создания класса Enemy, который будет общим для всех наших врагов. Каждый враг будет иметь позицию (на экране). Он будет иметь очки здоровья hp и двигаться с определенной скоростью velocity:

Enemy = class
  constructor = function(position)
    this.position = position
  end

  hp = 10
  velocity = 1

  move = function()
    position += velocity
  end

  hit = function(damage)
    hp -= damage
  end
end

В языке microScript классы и объекты являются очень похожими понятиями и могут использоваться практически взаимозаменяемо. Таким образом, определение класса начинается с ключевого слова class и заканчивается ключевым словом end. Первое свойство, которое мы определили в приведенном выше классе - это функция "constructor". Эта функция вызывается, когда создается экземпляр класса. Она установит свойство position объекта. this относится к экземпляру объекта, на котором будет вызвана функция, поэтому установка this.position означает, что объект устанавливает свойство position на себя.

Создание экземпляров объектов из класса

Давайте создадим два объекта-врага, производных от нашего класса:

enemy_1 = new Enemy(50)
enemy_2 = new Enemy(100)

Оператор new используется для создания нового экземпляра объекта, производного от класса. Аргумент, который мы передаем здесь, будет направлен на функцию конструктора нашего класса. Таким образом, мы создали экземпляр врага в позиции 50 и другой экземпляр врага в позиции 100.

Оба врага имеют одинаковую скорость или очки здоровья (hp). Однако мы можем задать второму врагу другую скорость:

enemy_2.velocity = 2

Теперь мы можем заставить наших врагов двигаться, вызвав:

enemy_1.move()
enemy_2.move()

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

Наследование

Мы можем заставить класс наследоваться от другого класса. Например, если мы хотим создать разновидность нашего Enemy, мы можем поступить следующим образом:

Boss = class extends Enemy
  constructor = function(position)
    super(position)
    hp = 50
  end

  move = function()
    super()
    hp += 1
  end
end

Мы создали новый класс Boss, расширив класс Enemy. Наш новый класс разделяет все свойства класса Enemy, за исключением того, что он заменяет некоторые из этих свойств своими собственными значениями. Вызов super(position) в конструкторе нашего нового класса гарантирует, что конструктор нашего родительского класса Enemy также будет вызван.

Мы создали новое поведение move для нашего Босса, которое переопределяет поведение Врага по умолчанию. В этой новой функции мы вызываем super(), чтобы сохранить поведение по умолчанию, которое было определено в классе Enemy; затем мы увеличиваем значение hp, что подразумевает, что наши Боссы будут восстанавливать очки здоровья при перемещении.

Теперь мы можем создать экземпляр нашего Босса в позиции 120:

the_final_boss = new Boss(120)
Примечания
  • пространство переменных: когда функция вызывается на объекте (например, enemy_1.move()), переменные, на которые ссылаются в теле вызываемых функций, являются свойствами объекта. Например, в теле функции move, position += 1 увеличит свойство position самого объекта.

  • Иногда необходимо использовать this, чтобы убедиться, что мы правильно ссылаемся на свойство нашего объекта. Вот почему в конструкторе нашего класса Enemy мы используем this.position = position, потому что position также относится к аргументу функции и, таким образом, "скрывает" свойство нашего объекта.

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

Clone this wiki locally