ksi

Язык программирования

Виды значений

Конструкторы видов - это команды, которые создают новые функции и типы данных. Типы и функции в ksi могут быть значениями ячейки.

Команды:
.fn ~ Функция
.struct ~ Структура
.enum ~ Перечисление

Функция

@main -- Возведение в квадрат squared = .fn (x) .seq ( ret = x * x ) .do ( squared(1) write_line@std{} -- Обычный вызов функции: write_line@std( squared(3) ) -- Цепной вызов функции: 5 squared{} write_line@std{} )

Результат:

1 9 25

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

squared ~ константа, хранящая указатель на функцию

x ~ параметр функции

.seq ~ список действий (sequence)

ret ~ ячейка результата

Структура данных

Структура - это тип. Создание экземпляра структуры аналогично вызову функции.

@main coords = .struct (x y) /* указанные свойства структуры coords при создании объекта становятся свойствами экземпляра */ origin = coords(0 0) .do ( point = coords(3 4) point distance{} write_line@std{} ) distance = .fn (from, to = origin) .seq ( ret = (to.x - from.x) ^ 2 ret += (to.y - from.y) ^ 2 ret = root@std(ret, 2) )

Результат:

5

Встраивание структур, перегрузка функций

Вместо наследования структур в языке ksi используется встраивание свойств одной структуры в другую, через команду .insert . В скобках - список parent структур.

файл: data.insert.ksi

@main coords = .struct ( x y ) -- У квадрата координаты и ширина square = .struct ( .insert ( coords ) width ) -- свойства: x y width -- прямоугольник rectangle = .struct ( .insert ( square ) height ) -- x y width height

файл: functions.overloading.ksi

@main -- Масштабирование квадрата scale[square] = .fn (ret, factor) .seq ( ret.width *= factor ) -- Масштабирование прямоугольника scale[rectangle] = .fn (ret, factor) .seq ( ret.width *= factor ret.height *= factor )

файл: main.do.ksi

@main .do ( .var shape = rectangle(0 0, 10 20) -- уменьшаем в 2 раза: shape scale{0.5} -- Функция area() определена ниже shape area{} write_line@std{} -- 50 /* Вывод на экран площади под-объекта: квадрат */ shape->square area{} write_line@std{} -- 25 ) -- Площадь квадрата area[square] = .fn (shape) .seq ( ret = shape.width ^ 2 ) -- Площадь прямоугольника area[rectangle] = .fn (shape) .seq ( ret = shape.width * shape.height )

Результат:

50 25

Оператор стрелка -> выдаёт под-объект. Перед этим оператором ставится ячейка, хранящая исходный объект. А после - указывается parent тип, указанный в .insert . У под-объекта общие свойства с исходным.

В этом примере функция scale() является функцией‑модификатором, ведь имя её первого параметра ret - ячейка результата.

scale() и area() перегружены для разных типов.

Упрощённо говоря перегрузка функции - это ассоциативный массив $map, где ключом служит тип первого параметра функции (или категория типа), а значением - сама функция конкретной перегрузки.

Перечисление

@sample align_type = .enum ( left center right ) .do ( node_align = align_type.left write_line@std(node_align.name) -- Печать элементов перечисления align_type elements@std .each .var it ( it.val write_line@std{ key_separator: ': ' separator: "\n" } write_line@std() ) )

Результат:

left index: 0 name: left index: 1 name: center index: 2 name: right

Некоторые системные типы

/* -- псевдокод -- @global $range := .struct ( from to ) $iterator := .struct ( pos -- position key val -- value ) $enum_element := .struct ( index name value ) $cmp := .enum ( less = -1 equal = 0 greater = +1 ) */

Читать далее: управляющие команды ›

Top