Вот пример простейшей программы, которая выводит на экран сообщение "Привет, мир!".
стат метод Запустить() Целое:
Кар.Печатать("Привет, мир!\н")
вернуть 0
Данный текст программы должен быть записан в кодировке UTF-8 и помещен в файл с раширением "кар", например: ПриветМир.кар. Далее его можно откомпилировать с помощью программы
kar ПриветМир -o hello.exe
и запустить из командной строки
hello.exe
После запуска программа выведен на экран строку "Привет, мир!".
Язык программирования Картарика или Картарский язык является строго-типизированным объектно-ориентированным языком с обязательной инициализацией переменных с ограниченным сборщиком мусора и запретом кольцевых зависимостей.
(??? Дать ссылку на раздел, описывающий запрет кольцевых зависимостей.)
Файловая структура проекта. Проект состоит из одного или множества файлов модулей (один или более) а также может содержать файл проекта (ноль или один). Модули могут располагатся в каталогах или подкаталогах.
Результатом компиляции проекта является исполняемая программа либо библиотека.
Пример построения проекта.
Каталог1
Подкаталог1
Модуль.кар
Модуль11А.кар
Модуль11Б.кар
Подкаталог2
Модуль.кар
Модуль12А.кар
Каталог2
Модуль2.кар
...
КаталогН
Модуль.кар
ЕщёОдинМодуль.кар
Модуль1.кар
Модуль2.кар
Модуль3.кар
Проект.проект
В модулях записывается непосредственно код программы.
В картарском языке модуль = файл = класс. Это означает, что если необходимо создать два разных класса, то для них необходимо создать два разных файла и в них соответственно описать эти классы.
Файл модуля имеет расширение кар. Имя файла (без расширения) должен соответствовать правилам токена (см. ???).
Подробное описание синтаксиса модулей смотри в ???.
Имена каталогов должны быть без расширения и должны соответствовать правилам токена (см. ???). Основное назначение каталогов - разбивать модули на логические группы.
В файле проекта находятся настройки проекта, свойства, параметры компиляции и прочее, что не может быть описано в непосредственно в коде программы. Более подробное описание смотри в ???
Если в одном модуле необходима ссылка на другой модуль, то он записывается в виде пути и имени файла (без расширения), разделенных точкой. Например, если модуль с именем Модуль.кар
лежит в каталоге Каталог1
, который в свою очередь лежит в каталоге Каталог2
, то путь к модулю записывается так: Каталог2.Каталог1.Модуль
.
Алгоритм поиска модуля. При поиске модуля программа пытается найти модуль в текущем каталоге, затем в каталоге проекта, затем в каталоге библиотек, затем в каталоге стандартной библиотеки.
В сообщениях об ошибках или в других случаях, когда нужно однозначно описать какой конкретно модуль имеется в виду можно написать:
Стандарт:Модуль.Подмодуль
Библиотека.<ИмяБиблиотеки>.<ВерсияБиблиотеки>:Модуль.Подмодуль
Проект:Модуль.Подмодуль
Написанные программы используют ЮНИКОД (UNICODE) (??? Какая версия), описание которого можно найти на сайте
Используемая кодировка: UTF-8. Соответствующий стандарт находится здесь:
https://tools.ietf.org/rfc/rfc3629.txt
Для описания грамматики используется расширенная форма Бэкуса-Наура, с некоторыми дополнениями.
Описание отдельных символов:
- Переменная, состоящая из одного символа, обозначает этот символ. Например: ф - русская буква ф, z - латинская буква z и т.д.
- Для различения похожих букв русского и английского алфавита, там где не понятен контекст, перед русской буквой ставится префикс р (русский), перед английской буквой ставится префикс l (latin). Например ра обозначает русскую букву а, la - обозначает латинскую букву a.
- Переменной "юникод" обозначается любой символ Юникода.
- Переменной "буква" обозначается любая буква любого алфавита Юникода.
- Символ Юникода также можно записать в виде \uHEX. То есть значала записывается обратная косая черта, затем английская буква u и после неё номер символа в таблицце Юникода в шестнадцатеричном формате. Например \u5F обозначает символ нижнего подчеркивания.
Правила записи расширенной формы Бэкуса-Наура, используемые в этом документе:
- Конкатенация. Конкатенируемые символы заключены в двойные кавычки. Правило вида A = "BCD". обозначает, что нетерминал A состоит из трех символов — B, C и D.
- Выбор. Обозначается вертикальной чертой. Правило вида A = B|C|D. Обозначает, что нетерминал A может состоять либо из B, либо из C, либо из D.
- Для сокращения записи выбора, если символы стоят рядом в таблице Юникод, можно обозначить промежуток символом тире. Правило вида 1-3. Обозначает либо 1, либо 2, либо 3.
- Кроме. Исключения в выборе обозначается восклицаетльным знаком. Правило 0-9!3!5 обозначает все цифры от 0 до 9, кроме 3 и 5. То есть 0, 1, 2, 4, 6, 7, 8, 9.
- Условное вхождение. Квадратные скобки выделяют необязательный элемент выражения, который может присутствовать, а может и отсутствовать. Правило вида A = [B]. обозначает, что нетерминал A либо является пустым, либо состоит из символа B.
- Повторение. Фигурные скобки обозначают конкатенацию любого числа (включая нуль) записанных в ней элементов. Правило вида A = {B}. обозначает, что A — либо пустой, либо представляет собой конкатенацию любого числа символов B (то есть A — это либо пустой элемент, либо B, либо BB, либо BBB и так далее). Если требуется, чтобы A представлял собой либо B, либо произвольное число B, но не мог быть пустым, используется запись A = B{B}.
- Круглые скобки. Они применяются для группировки элементов при формировании сложных выражений. Например, правило A = (B|C)(D|E). обозначает, что A состоит из двух символов, первым из которых является либо B, либо C, вторым — либо D, либо E, то есть A может быть одной из цепочек BD, BE, CD, CE.
Грамматическое описание конца строки:
КонецСтроки = (\u0A)|(\u0D \u0A)
Конец строки может быть либо символов перевода строки либо сочетанием символов возврата каретки и перевода строки (\n или \r\n в обозначении языков с С-подобным синтаксисом).
Комментарии могут быть однострочными и многострочными.
Грамматическое описание однострочного комментария:
ОднострочныйКомментарий = "//" {Юникод!КонецСтроки}
Перед началом однострочного комментария ставится удвоенный символ "/" послечего идёт любая последовательность символов до символов конца строки.
Грамматическое описание многострочного комментария:
Многострочный комментарий = "/*" {Юникод!"!"} "*/"
Многострочный комментарий заключен в символы "/" и "/" внутри которого может быть любая комбинация текстовых символов за исключением последовательности "*/".
Комментарий можно поставить в любое место, где можно поставить пробельный символ.
Грамматическое описание пробельных символов:
ПробельныйСимвол = \u20 | \u09 | Комментарий
Пробел = ПробельныйСимвол{ПробельныйСимвол}
Пробел состоит из одного или более пробельных символов. Пробельным символом является символ пробела или символ горизонтальной табуляции.
В начале строки Пробел выполняет также дополнительную функцию определения к какому блоку принадлежит строка. Один символ горизонтальной табуляции является табуляцией длиной в четыре пробела, комментарий - пробельный сисмвол длиной в ноль пробелов. (??? Возможно нужен отдельный раздел для описания блоков.)
(??? добавить список ключевых слов из последующих глав: числа, поля, пусто, модификаторы полей и методов, модификаторы для класса и т.д. и т.п.)
КлючевоеСлово = "Целое8" | "Целое16" | "Целое32" ... ( и т.д.)
Грамматическое описание идентификатора:
Буква = а-я | a-z | _
Цифра = 0-9
Идентификатор = (Буква{Буква | Цифра})!КлючевоеСлово
Идентификатор - это набор букв и цифр неограниченной длины, начинающийся с буквы. Набор букв и цифр не должен совпадать с ключевыми словами.
В одном идентификаторе нельзя одновременно использовать русские и английские символы (??? Нужно ли такое условие).
Грамматическое описание:
Цифра = 0-9
Знак = + | -
ЦелоеЧисло = [Знак] Цифра{Цифра}
Вначале целого числа может стоять знак "+" или "-". Далее идет набор цифр от 0 до 9.
Грамматическое описание:
ШестнадцатиричнаяЦифра = 0-9 | А | Б | В | Г | Д | Е
ШестнадцатиричноеЧисло = "0ш" ШестнадцатиричнаяЦифра{ШестнадцатиричнаяЦифра}
Шестнадцатиричное число начинается с символов 0ш а затем идут одна или несколько шестнадцатиричных цифр: от нуля до девяти и далее A=10, Б=11, В=12, Г=13, Д=14, Е=15. Буквы могут быть как заглавные, так и маленькие.
??? Выглядит трешово, конечно. Другие варианты обсуждаемы. Вообще нужны ли шестнадцатиричные цифры? И как насчет двоичных и восмеричных чисел? Нужен ли знак перед началом числа?
Грамматическое описание:
Цифра = 0-9
Точка = \u2E
Знак = + | -
ЦелоеЧисло = [Знак] Цифра{Цифра} Точка Цифра{Цифра}
Вначале числа с плавающей точкой может стоять знак "+" или "-". Далее идет набор цифр от 0 до 9, обозначающий целую часть числа, затем символ ".", затем цифры от 0 до 9, обозначающие дробную часть числа.
В программе будет точка, при печати на экран печатается запятая.
??? Добавить состояния плюс бесконечность, минус бесконечность, не число и возможно другие.
??? Нужна ли экспоненциальная форма для чисел с плавающей точкой и какой будет формат. 3.35э4
Грамматическое описание:
БулевоЗначение = "Да" | "Нет"
Булево значение может принимать одно из двух значений "Да" или "Нет", соответствующие булевым значениям "Правда" и "Ложь" соответственно.
Грамматическое описание:
ДвойныеКавычки = \u22
СимволИсключения = \u5C
СтрочныйСимвол = Юникод!ДвойныеКавычки!СимволИсключения
Строка = ДвойныеКавычки {СтрочныйСимвол | ИсключающиеСимволы} ДвойныеКавычки
Двойные кавычки используются для обозначения строкового литерала. Внутри могут стоять любые символы кроме символа двойной кавычки и символа исключения. Символ исключения используется для создания исключающих символов, описанных в (??? ссылка на следующий пункт.)
Грамматическое описание:
СимволИсключения = \u5C
СимволВозвратаКаретки = СимволИсключения к
СимволНовойСтроки = СимволИсключения н
СимволГоризонтальнойТабуляции = СимволИсключения т
СимволДвойныхКавычек = СимволИсключения ДвойныеКавычки
СимволОбратногоСлеша = СимволИсключения СимволИсключения
ИсключающиеСимволы = СимволНовойСтроки | СимволГоризонтальнойТабуляции | СимволДвойныхКавычек | СимволОбратногоСлеша
В строке можно записать сивол новой строки или сивол табуляции, напрямую написав их внутри строки или добавив сочетание сиволов "\н" или "\т" соответственно. Если необходимо добавить двойные кавычки внутри строки, необходимо добавить в строку сочетание """. Для добавления обратного слеша, необходимо просто его удвоить: "\".
Также можно добавить юникод-символы, записав их шестнадцатиричные коды с помощью исключающего символа "\ш". Сначала пишется ключевое буквосочетание "\ш", затем пишутся шестнадцатиричный код символа. Можно написать сразу несколько кодов, для этого их надо писать через запятую. По окончании записи юникод-символов ставится пробел, либо любой другой символ, не использующийся в написании шестнадцатиричного символа. Если в конце шестнадцатиричных символов ставится пробел, то он съедается.
Пример:
"Маленькая греческая буква альфа \ш3Б1"
"Маленькие греческие буквы альфа и бетта \ш3Б1,3Б2 22"
Конечное преобразование этих строк будет таким:
"Маленькая греческая буква альфа α"
"Маленькие греческие буквы альфа и бетта αβ 22"
Обратите внимание, что в конце второй строки перед символами "22" два пробела. Первый из них обозначает конец исключающего символа "\ш" и как бы "съедается". Второй пробел остаётся.
Грамматическое описание:
ОткрывающиесяСкобки = \u28
ЗакрывающиесяСкобки = \u29
Запятая = \u2C
Следующие токены являются операторами:
!"№;%:?*() ., -_=+\/*
Плюс = \u2B
Минус = \u2D
Умножить = \u2A
Разделить = \u2F
Присвоение = \u3D
Точка = \u2E
Двоеточие= \u3A
Равно = "=="
НеРавно = "!="
Больше = "больше"
Меньше = "меньше"
БольшеИлиРавно = "бир"
МеньшеИлиРавно = "мир"
??? Более читаемо "больше", "меньше" и "равно", чем "б", "м" и "р". А вот "бир" и "мир" можно оставить.
(??? Собрать все операторы из последующих глав)
??? Если что можно использовать двойные скобки для чего-нибудь (( )).
??? Здесь должно быть общее синтаксическое описание всего модуля.
Как описывалось выше (??? ссылка) один модуль = один файл = один класс. Соответственно здесь будет описана общая структура файла.
Модуль состоит из строковых выражений, корневых блоков и пустых строк.
Пустые строки состоят из пробелов и комментариев. Пустые строки при компиляции игнорируются.
Строковое выражение может быть описанием класса (??? ссылка), назначением псевдонима (??? ссылка), описанием поля или константы (??? ссылка). (??? возможно что-то ещё добавить).
У строкового описания нет единых правил оформления, особенности оформления смотрите в соответствующих главах.
Корневым блоком может быть описанием метода (??? ссылка), юнит-тестом (??? ссылка), описанием импорта (??? ссылка). (??? возможно что-то ещё добавить).
Блок состоит из более чем одной строки, блоки могут быть вложенные. Общая лексическая структура такова:
<Описание блока>:
<Строковое описание>
<Строковое описание>
...
<Строковое описание>
То есть, в первой строке идёт описание блока, заканчивающееся двоеточием. Далее в последующих строках идут одинаковые отступы и строковые описания. После окончания блока идут строковые описания блока верхнего уровня с отступами блока верхнего уровня. У корневых блоков модуля отступ равен 0 символов. У блоков более нижнего уровня отступ всегда больше чем у блоков верхнего уровня.
Пример программы:
класс расширяет Базовый
использовать Кар как Ат
стат метод Запустить(Массив(Строка) параметры) Целое:
константа КоличествоПараметров = 3
// Пустая строка. Здесь может быть сколько угодно пробелов и комментов.
если (Параметры.Длина не равно КоличествоПараметров):
Ат.Печатать("Количество параметров программы должно быть равно 3.%н")
В данном примере первая строка является строковым выражением, описывающим класс. Далее другое строковое выражение с назначением псевдонима. И, наконец, идет блок, описывающий метод запустить. Внутри блока метода находится строковое выражение, описывающее константу, пустая строка и далее вложенный блок "если".
Способы разбить одну строку на несколько:
- Комментарий сильнее символа новой строки. Это означает, что в любом месте, где разрешен пробельный символ можно с помощью комментария разделить одну строку на две. Например:
поле Количество = /*
*/ 5
- Скобки сильнее символа новой строки:
стат метод ПосчитатьСумму(
Целое Слагаемое1,
Целое Слагаемое2
) Целое:
Картарский язык программирования является языком с ограниченным сборщиком мусора. На самом деле как таковой сборщик мусора отсутствует. Фактически каждый ссылочный объект имеет свой счётчик и удаляется, если он становится равен нулю.
Однако, при таком подходе возникает проблема кольцевых зависимостей. Так как если объект А ссылается на объект Б, а объект Б ссылается на объект А, то счётчики ссылок на эти объекты никогда не удалятся. В том числе если эти объекты имеют один и тот же тип.
Чтобы обойти эту проблему, компилятор будет искать такие зависимости в проекте и выдавать ошибки времени компиляции при их нахождении.
Часто бывает все-таки нужно создать структуру с кольцевой зависимостью. Для этого есть "хак" - типы данных дерево и граф. Этого вполне достаточно практически для любой задачи.
Остается только проблема кольцевых зависимостей проекта. Проект А создает класс из проекта Б, а тот в свою очередь создает класс из проекта А. Задача поиска и исправления таких зависимостей остается на плечах разработчика. Надеемся на Вашу пряморукость :)
Картарский язык программирования - это строго типизированный язык. Это означает, что каждая переменная и выражение имеет свой тип, известный на этапе компиляции.
Простые типы данных делятся на беззнаковые целые, знаковые целые, числа с плавающей точкой, булевы выражения и перечисления.
Типы знаковых целых чисел:
- Целое8 - 8-ми битное знаковое целое число. Принимает целочисленные значения от -128 до 127 включительно.
- Целое16 - 16-ти битное знаковое целое число. Принимает целочисленные значения от -32768 до 32767 включительно.
- Целое32 - 32-ти битное знаковое целое число. Принимает целочисленные значения от -2147483648 до 2147483647 включительно.
- Целое64 - 64-ти битное знаковое целое число. Принимает целочисленные значения от -9223372036854775808 до 9223372036854775807 включительно.
- Целое - синоним для типа число32 (??? обсуждаемо).
Типы беззнаковых целых чисел:
- Счётное8 - 8-ми битное беззнаковое целое число. Принимает целочисленные значения от 0 до 255 включительно.
- Счётное16 - 16-ми битное беззнаковое целое число. Принимает целочисленные значения от 0 до 65535 включительно.
- Счётное32 - 32-ми битное беззнаковое целое число. Принимает целочисленные значения от 0 до 4294967295 включительно.
- Счётное64 - 64-ми битное беззнаковое целое число. Принимает целочисленные значения от 0 до 18446744073709551615 включительно.
- Счётное - синоним для типа счётное32 (??? обсуждаемо).
Типы чисел с плавающей запятой:
- Дробное32 - числа с плавающей точкой одинарной точности (single precision) согласно стандарту IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Standard 754-1985 (IEEE, New York).
- Дробное64 - числа с плавающей точкой двойной точности (double precision) согласно стандарту IEEE Standard for Binary Floating-Point Arithmetic, ANSI/IEEE Standard 754-1985 (IEEE, New York).
- Дробное - синоним для типа дробное64 (??? обсуждаемо).
Булевый тип:
- Буль - булево число, принимающее два значения: "Да" и "Нет".
Перечисления:
- перечисление - тип определяемый пользователем. Принимает одно из перечисленных значений.
Пример объявления перечисления:
перечисление ДеньНедели:
Понедельник
Вторник
Среда
Четверг
Пятница
Суббота
Воскресенье
(??? Надо ли смещать соответствие перечисления целому числу. Например Понедельник = 1)
Пример использования:
поле ДеньЗаседания = ДеньНедели.Четверг
(??? обсуждаемо. Возможно лучше писать не ДеньНедели.Четверг, а просто Четверг.)
Предназначен для хранения адреса памяти. Тип ссылка необходим для работы с библиотеками. Необходим для того, чтобы принимать ссылки из библиотек и передавать библиотекам. Ничего с ними делать нельзя, используются только для хранения значений. Возможно также для хранения хандлеров.
Экземпляр класса "Строка" представляет набор символов Юникод. Строковый объект имеет константное (неизменяемое) значение. Строковые литералы ссылаются на экземпляры класса "Строка".
Неопределенность - это тип тип данных, который модифицирует другой тип данных. Тип неопределенность может принимать либо специальное значение "Пусто", либо значение класса.
поле Количество = Целое?(Пусто)
поле Цена = Целое?(35)
Перевод из неопределенного типа в соответствующий ему определенный можно совершить с помощью вызова метода "или" (??? ссылка на подробное описание) или с помощью блока "раскрыть" (??? ссылка на подробное описание). Пример:
поле Количество = Целое?(Пусто)
Кар.Напечатать(Количество.или(-1))
раскрыть Количество как Кол:
Кар.Напечатать(Кол)
иначе:
Кар.Напечатать("Количество не определено")
Объединение - это структура, которая может иметь один из возможных типов, в зависимости от связанного с ним перечисления. Для того, чтобы создать экземпляр объединения, необходимо создать тип перчесления, тип объединения, связанный, с типом перечисления, далее экземпляр перечисления, и экземпляр объединения, связанный с перечислением. Например:
перечисление ИмяПоля:
Имя
ГодРождения
Улица
Дом
объединение Поле(ИмяПоля):
ИмяПоля.Имя Имя = ""
ИмяПоля.ГодРождения Год = 1900
ИмяПоля.Улица Улица = ""
ИмяПоля.Дом Дом = 0
поле Наименование = ИмяПоля.Улица
поле Значение = Поле.Создать(Наименование)
??? Не слишком ли сложно? Может лучше убрать связь с перечислением? Может есть смысл через неопределенность реализовать.
Структура - это набор нескольких полей. В отличие от класса не могут иметь методов и все поля открыты. (??? Нужен ли такой тип в программе? Фактически это просто обрезанный класс.)
Пример:
структура Дата:
поле Год = 1900
поле Месяц = 1
поле День = 1
Массив является псевдошаблоном для хранения последовательности переменных одинакового типа.
Объявление:
поле ПростыеЧисла = Массив!(Целое)(2, 3, 5, 7, 11, 13, 17, 19)
Использование:
раскрыть ПростыеЧисла.0 как ПростоеЧисло:
Кар.Напечатать(ПростоеЧисло)
Этот пример напечатает число 2.
Обратите внимание, что каждый элемент массива является типом неопределенность от элемента массива, который надо раскрыть.
??? Надо ли отдельно вводить статические и динамические массивы. ??? Возможно после шаблонов описать.
Дерево является псевдошаблоном для хранения переменных одинакового типа в структуре дерево.
Обявление может быть внешнее или внутреннее.
При внешнем объявлении дерева элементы массива не знают о том, что они находятся в дереве и нет возможности из класса обращаться к предку или потомкам дерева:
поле Каталог = Дерево!(Строка)("")
Но может быть также внутренним. Для этого необходимо отнаследовать класс от дерева:
класс Каталог наследуется от Дерево
внешнее поле Имя = ""
Возможно описать после шаблонов и наследования классов.
Граф является псевдошаблоном для хранения переменных в структуре типо граф. Можно хранить в структуре либо узлы, либо ребра, либо и то и другое. (??? Какие будут графы и как их хранить. Однонаправленные, двунаправленные. между двум узлами может быть одно ребро или множество.).
Обявление может быть внешнее или внутреннее.
При внешнем объявлении графа элементы массива не знают о том, что они находятся в графе и нет возможности из класса обращаться к предку или потомкам дерева:
поле Каталог = Граф!(Строка)("") (??? Продумать)
Но может быть также внутренним. Для этого необходимо отнаследовать класс от графа:
класс Каталог наследуется от Дерево (??? Продумать)
внешнее поле Имя = ""
Возможно описать после шаблонов и наследования классов.
Класс - это тип, содержащий поля и методы. Более подробное описание в главе класса (??? ссылка на главу с описанием класса)
Для конастанты применяется ключевое слово "конст", для перенной ключевое слово "поле". Любая константа и переменная должна быть проинициализированна. Поэтому, несмотря на строгую типизацию, тип константы и переменной записывать необязательно. Его можно однозначно вывести из правой части присвоения. Это будет либо возвращаемый тип метода или выражения, либо соответствующий литерал. Пример:
поле а = НОД(36, 24) // Зависит от типа, который возвращает метод НОД
конст б = 3 + 5 // Тип Целое.
Целое число объявляет переменную типа Целое, дробное число объявляет переменную типа Дробное, строка переменную типа Строка.
поле Количество = 34
поле Строка = "Привет, мир!"
поле ПримерМногострочнойПеременной = "Привет,\нмир!"
поле ДругойМногострочный пример = "Привет
мир!"
Ключевое слово "поле" необходимо только для провеки, что это новая переменная.
Если поле является полем класса, то он имеет модификаторы
Модификаторы статичности:
- стат - статическое
- динамическое - динамическое поле (значение по-умолчанию)
Модификаторы области видимости:
- закрытое - видимо только внутри класса (значение по-умолчанию)
- защищённое - видимо внутри класса и его наследников.
- открытое - видимо всем.
При обнаружении в команде поля, сначала ищется обявление этого поля в текущем блоке, затем в блоке на уровень выше, и так далее до корневого блока. Потом ищется в поле текущего класса, далее родительские классы по цепочке (если есть). Далее в текущем каталоге, в текущем проекте, в библиотеках, в стандартной библиотеке.
Все преобразования являются явными. Неявные преобразования запрещены.
Пример преобразования типа Целое в тип Целое8:
Целое8(45)
Преобразования между целыми и счётными идут по простому пути. Просто преобразование. Большие числа просто обрезаются.
Из целых/счетных в плавающие тоже по простому. Из плавающих в целые/счетные преобразуется с неопределенностью, так как у чисел с плавающей точкой есть состояние "не число". (??? Как обрабатывать слишком большие числа? Например 257.3 в Целое8. Обрезать до нуля? И вообще округлять или к меньшему целому преобразовывать?)
Из любого числа в строку - простое преобразование. Из строки в число - неопределенность.
Из булевого в число: Да = 1, Нет = 0. Из числа в буль с неопределенностью. (??? другой вариант праверка на неравенство нулю)
Из булевого в строку Да = "Да", Нет = "Нет". Обратно с неопределенностью. (??? возможны другие варианты: Правда/Ложь, 0/1)
Из перечисления в число по простому пути, обратно неопределенность.
Из перечисления в строку по простому пути, обратно неопределенность. (??? Надо ли зависимость от регистра закладывать. "понедельник" в ДеньНедели.Понедельник и "ПоНеДеЛьНиК" в ДеньНедели.Понедельник).
Операция скобок меняет приоритет выполнения операций.
Операция выбора элемента обозначается через символ "." и необходим для выбора поля, метода или другого элемента класса. (??? что такое другой элемент? Тесты можно вызывать?)
<Имя метода>([Параметр1 [, Параметр2 [..., ПараметрН]]])
Операция обращения к методу обозначается через символ имя метода и последующим за ним круглых скобок. Внутри скобок перечисляются параметры метода, если они есть.
Используется в методах или в шаблонах методов. Как в объявлении так и при вызове. Перечисление выражений через запятую:
ВызовМетода(поле1, поле2, поле3)
"?" - оператор, обозначающий неопределенность типа. "!" - оператор разрешающий неопределенность.
Например:
поле к = Целое?(Пусто)
...
Кар.Печатать(к ! 0)
В этом примере печатается значение к или 0, если к имеет значение пусто.
Лучше сделать так:
к = если(условие, позитивное_значение, негативное_значение)
- "+" - унарный плюс
- "-" - унарный минус
- "+" - сложение
- "-" - вычитание
- "*" - умножение
- "*!" - защищенное умножение
- "/" - деление
- "/!" - защищенное деление
- "%" - остаток от деления
- "%!" - защищенный остаток от деления
Защищенное деление. Так как на ноль делить нельзя, то деление возвращает неопределенность Целое?. При защищенном делении если делитель равен нулю, то просто возвращает делимое. (??? Надо ли такое? Или луше возвращать единицу, или вообще убрать такое).
Для чисел в плавающей точкой из-за состояний бесконечности и не числа также необходимо ввести защищенное умножение. (??? Надо подробно расписать правила.)
Любая арифметическая операция выполняется над одинаковыми типами переменных. Если типы разные, используйте преобразование типов.
??? Возможно, нужно сделать аналоги в виде вызова методов для использования в шаблонах.
Операции только над числами и счётными (??? надо ли числа с плавающей запятой добавить?)
- би - побитовое и
- били - побитовое или
- билине - побитовое исключающее или
- бне - побитовое не
- операции выше выполняются только над числами/счетными одного и того же типа.
- вправо - битовый сдвиг вправо
- влево - битовый сдвиг влево
1 вправо 2
Здесь левая и правая часть может быть разных типов. возвращает тот же тип что и у числа слева.
??? Возможно стоит добавить функции для чисел Установить(Целое бит), Снять(Целое бит) и Инвертировать(Целое бит).
??? Возможно, нужно сделать аналоги в виде вызова методов для использования в шаблонах.
- == - проверка на равенство.
- != - не равно
- больше - больше
- бир - больше или равно
- меньше - меньше
- мир - меньше или равно
Любая арифметическая операция выполняется над одинаковыми типами переменных. Если типы разные, используйте преобразование типов.
- и - логическое и
- или - логическое или
- не - логическое не
и, или, не - выполняются только над булевыми типами.
??? Возможно, нужно сделать аналоги в виде вызова методов для использования в шаблонах.
- "+" - конкатенация
методы строк:
Строка.Длина() счётное - длина строки в символах
Строка.Размер() счётное - длина строки в байтах
Строка.Символ(Целое ч) символ? - возвращает символ по номеру.
??? Возможно, нужно сделать аналоги в виде вызова методов для использования в шаблонах.
Ниже описан приоритет операций а также ассоциативность.
Приоритет | Операция | Ассоциативность | Описание |
---|---|---|---|
1 | () | слева направо | изменение приоритета операции, параметры при вызове метода, преобразование типов |
2 | . .метод(,,) | слева направо | обращение к элементу, вызов метода |
3 | ? | неопределенность | |
4 | ! | слева направо | разрешение неопределенности |
5 | + - не бне | унарный плюс, унарный минус, логическое НЕ, побитовое НЕ | |
6 | * *! / /! % %! | слева направо | умножение, защищенное умножение, деление, защищенное деление, остаток от деления, защищенный остаток от деления |
7 | + - | слева направо | сложение, вычитание |
8 | вправо влево | слева направо | сдвиг вправо, сдвиг влево |
9 | больше бир меньше мир | слева направо | больше, больше или равно, меньше, меньше или равно |
10 | == != | слева направо | равно, не равно |
11 | би | слева направо | побитовое И |
12 | билине | слева направо | побитовое исключающее ИЛИ |
13 | били | слева направо | побитовое ИЛИ |
14 | и | слева направо | логическое И |
15 | или | слева направо | логическое ИЛИ |
??? Кроме вызова метода (оператор .метод(,,)) нужно потом добавить оператор обращения к элементу массива (оператор .()).
Раздел документа в разработке.
Инициализация локальной переменной.
Раздел документа в разработке.
Присваивает переменной, стоящей слева некоторое значение, вычисляемое по формуле справа. обозначается символом "=". Множественное присваивание запрещено. При объявлении любого поля оно обязательно должно быть инициализировано.
Поле1 = [Поле2 = [Поле3 = ... [ПолеН = ] ] ] Выражение
??? Потом можно добавить присваивание с дополнительным действием, с тем же пироритетом, что и простое присваивание. = *= /= %= += -= вправо= влево= би= билине= били= справа налево присваивание, умножение с присваиванием, деление с присваиванием, остаток от деления с присваиванием, сложение с присваиванием, вычитание с присваиванием, сдвиг вправо с присваиванием, сдвиг влево с присваиванием, побитовое И с присваиванием, побитовое исключающее ИЛИ с присваиванием, побитовое ИЛИ с присваиванием
??? Возможно надо добавить ещё больше присваивания. Например, с защищенным умножением, делением, остатком. + логическое присваивание и=, или= не=. Возможно что-то ещё, возможно лишнее и даже текущее можно сократить.
??? По идее это команда, которую надо будет описать в разделе алгоритм.
Общий вид метода:
[Модификаторы] метод [ИмяМетода] ([ВходныеДанные]) [ВыходнойТип]:
Сначала следуют модификаторы, затем ключевое слово "метод" (??? возможно можно удалить), затем имя метода, затем в скобках перечисление входных переменных или простые скобки без входных данных, затем тип возвращаемого значения, затем ставится двоеточие.
Метод может не возвращать никаких данных. В этом случае не надо писать ВыходнойТип
Модификаторы статичности:
- стат - статическая
- динамический - не статический метод (значение по-умолчанию)
Модификаторы области видимости:
- закрытый - видима только внутри класса (значение по-умолчанию)
- защищённый - видима внутри класса и его наследников.
- открытый - видима всем.
Модификаторы финализации:
- финализированный - финализированное (значение по-умолчанию)
- наследуемый - не финализирована. (Сразу же становится динамическим методом.)
Модификатор перегруженности метода:
- перегруженный - обязательный модификтор, если метод перекрывает родительский. В этом случае он также становится финализируемым по-умолчанию. Необходимо добавить в родительский метод модификатор "наследуемый", если от него будут наследоваться.
Входные данные метод перечисляются через запятую, где сначала пишется тип переменной, а затем имя переменной:
метод Обработать(Целое а, Строка с, Буль б) Буль:
Передаваемые данные являются константными. То есть нельзя изменять эти переменные и поля в классе. Можно вызывать только константные методы. Константными методами называются те методы класса, которые не изменяются поля класса. Эти константные методы вычисляются компилятором (??? сложно ли это будет сделать).
(??? Возможно для не ссылочных типов разрешить модификацию внутри метода, но изменения не влияют на переменные вне метода).
метод Сумма(Целое а, Целое б) Целое:
вернуть а + б
Если переменную надо изменить, то перед именем параметра метода ставится знак *. Например:
метод Сумма(Целое *а, Целое б) Целое:
а = а + 1
вернуть а + б
При вызове такого метода перед изменяемой переменной также ставится знак *. Пример:
поле а = Сумма(*3, 5)
поле а = Сумма(*б, в)
Возвращаемое значение может присутствовать или отсутствовать. В случае присутствия возвращаемого значения, оно имеет имя "результат", с которым можно работать в методе. (??? следить, чтобы перед работой с результатом ему должно буть присвоено значение. Сложно ли будет реализовать?)
метод Проверить(Целое а) Буль:
если а меньше 0:
результат = Нет
иначе:
результат = Да
вернуть результат
Синтаксис условного блока:
если [условие]:
[тело блока]
иначе если [условие]:
[тело блока]
...
иначе:
[тело блока]
Условный блок разделяется на одно или несколько подблоков. Сначала идёт обязательный подблок "если", затем могут идти подблоки "иначе если" (от 0 до бесконечности), и затем может идти подблок "иначе" (0 или 1).
Подблок "если". Сначала пишется ключевое слово "если" затем идет условие, а затем двоеточие. Условие - это выражение, которое возвращает переменную типа буль.
Подблок "иначе если" работает подобным способом. Сначала пишутся ключевые слова "иначе если" затем идет условие, а затем двоеточие. Условие - это выражение, которое возвращает переменную типа буль.
В подблоке иначе сначала пишется ключевое слово "иначе", а затем идет двоеточие.
Общая схема работы блока. Проверяется условие в блоке "если". Если условие возвращает значение "да", то выполняется тело блока и блок завершает свою работу, в противном случае поочередно проверяются условия подблоков "иначе если". Если какое-либо условие возвращает значение "да", то выполняется соответствующее ему тело подблока и блок завершает свою работу. Если ни одно условие не вернуло значение "да" и есть подблок "иначе", то выполняется тело подблока "иначе" и блок завершает работу. Если ни одно условие не вернуло значение "да" и нет подблока "иначе", то блок завершает работу.
повторить [выражение] раз для [ИмяПеременной]:
[тело блока]
Поторяет тело блока определенное количество раз, которое описано в выражении. Выражение должно возвращать положительное число группы типов Целое или Счётное. Выражение "для ИмяПеременной" является необязательным. Оно необходимо, если в теле блока нужно знать номер цикла. В этом случае в цикле появляется переменная типа счётное с именем ИмяПеременной. Номера цикла начинаются с нуля.
обойти [переменная] взять [имяЭлемента], [номерЦикла]:
[тело блока]
Переменная - это любой класс, который имеет интерфейс обхода. В частности массивы. ИмяЭлемента - это именование элемента обхода, используемое внутри тела блока. Запятая и номерЦикла - необязательны. номерЦикла - переменная типа счётное, добавляется, если нужно кроме самого элемента знать и его номер.
Интерфейс обхода. Класс должен иметь следующие методы:
Счётное количество()
Ш? элемент(счётное Номер)
Ш? - это неопределенность типа элемента.
??? возможен второй вариант
Пусто инициализироватьЦикл()
Ш? взятьСледующий()
Во втором варианте можно заранее не знать количество элементов. И потом даже добавить блок типа "продолжить обход". Но цикл в цикле для одного и того же класса нельзя взять. Может подумать над добавлением типа итераторов как в STL в C++.
пока [условие]:
[тело блока]
Условие - это выражение, возвращающее тип буль. Цикл выполняется, пока условие возвращает "да".
Внутри цикла можно использовать ключевые слова "следующий" и "прервать". Ключевое слово "следующий" пропускает оставшуюся часть текущей итерации цикла и переходит к следующей итерации. Ключевое слово "прервать" выходит из цикла полностью.
Можно прервать не только текущий цикл, но и стоящие выше. Для этого надо написать ключевое слово "прервать" столько раз, из скольки циклов вы хотите выйти. И даже добавить после этого ключевое слово "следующий". Но ключевое слово "следующий" можно добавить только 1 раз. (??? подумать есть ли смысл так делать и сложно ли будет реализовать. Имеется в виду весь абзац целиком.)
Пример:
обойти МойМассив взять Элемент:
повторить 5 раз:
пока Элемент.Цвет != Цвет.Красный:
Элемент.ИзменитьЦвет()
если Элемент.Цвет == Цвет.Черный:
прервать прервать следующий
Кар.Печатать("Итерация завершена нормально")
Здесь 3 вложенных друг в друга цикла. В случае выполнения условия в блоке "если" программа выходит из 2 внутренних циклов, а в третьем цикле переходит на следующую итерацию.
Синтаксис:
раскрыть [переменная1], [переменная2], ..., [переменнаяН]:
[тело блока]
иначе [переменная1]:
[тело блока]
иначе [переменная2]:
[тело блока]
...
иначе [переменнаяН]:
[тело блока]
иначе:
[тело блока]
Блок пытается раскрыть переменные с неопределённостью (со знаком?). Если все переменные раскрыты (не имеют значение "Пусто"), то выполняется тело блока. В теле блока все раскрытые переменные уже имеют определённый тип. (??? вариант писать "переменная1 как раскрытая1" и в теле блока использовать уже переменную с именем "раскрытая1"). Если какая-то переменная не раскрыта, то ищется соответствующий ей блок "иначе". Если соответствующий блок не найден, то запускается блок "иначе" без переменной. Блоки "иначе" являются необязательными. Переменные пытаются раскрываться в том порядке, в котором они перечислены в объявлении блока. В блоке "иначе" все переменные которые уже были раскрыты (которые перечислены до нераскрытой переменной в объявлении) можно использовать как уже раскрытые.
Бывают попадаются нераскрытые переменные внутри других переменных. В этом случае надо писать:
раскрыть Переменная1, Переменная1.Переменная2:
[тело блока]
??? Возможно лучше дать возможность сразу писать так:
раскрыть Переменная1.Переменная2:
[тело блока]
иначе Переменная1:
[тело блока]
иначе Переменная1.Переменная2:
[тело блока]
Синтаксис:
блок:
[тело блока]
Принцип работы: выполняется тело блока. Единственная причина, по которой вводится такой блок - локализация области видимости переменных, объявленных внутри блока. При выходе из блока такие переменные уничтожаются.
Синтаксис:
тест [имяТеста]:
[тело блока]
Тест фактически представляет собой статический метод без входных параметров, на выходе выдаёт переменную типа буль (??? Можно на выходе выдавать строку сообщения об ошибке. Пустая строка - всё хорошо, если есть строка - то это сообщение об ошибке). Тесты нельзя вызывать из других методов и из других тестов.
Внутри теста можно проверять поля, и если проверка не прошла, то тест возвращает сообщение об ошибке.
методы, изпользуемые внутри теста:
тест(выражение)
тестНет(выражение)
тестРавно(выражение1, выражение2)
тестНеРавно(выражение1, выражение2)
тестБольше(выражение1, выражение2)
тестБольшеИлиРавно(выражение1, выражение2)
тестМеньше(выражение1, выражение2)
тестМеньшеИлиРавно(выражение1, выражение2)
тестПусто(выражение)
тестНеПусто(выражение)
??? Набор методов обсуждаем
??? Написать названия методов на основе глаголов. Тестировать, проверить или как-то по-другому.
??? Как тесты запускать из командной строки. Билдинг и запуск.
В программе можно создать шаблон класса и шаблон метода.
Синтаксис шаблон метода:
[атрибуты] шаблон [имяМетода] ([параметры Шаблона])([параметры метода]) [возвращаемый тип]:
[тело метода]
Пример:
стат шаблон Массив(Тип Т, Счётное К)() Массив(Т):
вернуть Массив(Т)(К)
Пример вызова шаблона метода:
поле к = Массив(Целое, 60)
Возможно даже просто перечислять параметры шаблона как параметры метода. Надо подумать над этим.
Синтаксис:
шаблон класса [ИмяКласса] ([параметрыШаблона]) расширяет [базовыйКласс]
Пример:
шаблон класса Сумматор(Тип Т, Т начальноеЗначение)
поле сумма = Т.Создать(начальноеЗначение)
видимый метод Добавить(Т слагаемое):
сумма = сумма.Сложить(слагаемое)
видимый метод Сумма() возвращает Т:
вернуть сумма
Пример создания и использования экземпляра класса:
поле сумматор = Сумматор(Целое, 0).Создать()
сумматор.Добавить(3)
сумматор.Добавить(-5)
поле сумма = сумматор.Сумма()
Методы могут быть с переменным количеством параметров. (??? Это шаблон вообще? Как реализуется?)
Пример:
метод Печатать(Целое):
[телоМетода]
метод Печатать(Строка):
[телоМетода]
шаблон метода Печатать(Тип Т)(Т поле, ...):
Печатать(Т)
Печатать(аргументы)
Пример вызова:
Печатать("С чешуёй, как жар, горя ", 33, " богатыря.")
Так как у нас нет циклических зависимостей в программе, то возможен цикл по полям типа Т. Возможно зайти в каждое поле и выполнить над ним вложенный цикл.
Пример:
поля т из Т:
Кар.Печатать(т)
оператор препроцессора условие.
Макросы используют только константы и настройки проекта.
Макрос Кар.Макрос.ОС.Имя выдаёт строку операционной системы, для которой компилируется программа.
Возможные значения: "Виндовз", "Линукс", "МакОС", "Андроид", "Айфон". (??? Ну или что там сейчас для Эппла производят.)
Также под каждую ОС есть булево поле: Кар.Макрос.ОС.Виндовз Кар.Макрос.ОС.Линукс Кар.Макрос.ОС.МакОС Кар.Макрос.ОС.Андроид Кар.Макрос.ОС.Айфон
Любое поле принимает значение да, если компиляция идёт под эту систему. Принимает нет в противном случае.
??? Наверно надо ещё подсистему и версию ОС добавить. Наприме, подсистемы для Виндовз - Десктоп, Сервер, Мобайл, В Линуксе там вообще сборная солянка. ??? Ещё можно добавить разрядность системы. Типа 32-бит, 64-бит.
Кар.Макрос.Файл - выдаёт строку, текущее место файла. Например: библиотека:СТЛ.Картинка.Бмп Кар.Макрос.Строка - выдает тип счётное. Текущая строка в программе. Кар.Макрос.ВремяМодуля - возвращает строку. время компиляции модуля в формате ??? Кар.Макрос.ВремяПроекта - возвращает строку. время сборки проекта в формате ???
Синтаксис:
условие([условноеВыжение])
Подставляется перед полем или методом. Пример:
условие(Кар.Макрос.ОС.Виндовз) публичное поле ВерсияДотНет = 3
Пример использования:
если (Кар.Макрос.ОС.Виндовз и ВерсияДотНет больше 2):
[тело условия]
поле ВерсияДотНет в классе будет появляться только для Виндовз, но при этом надо всегда проверять на тип ОС перед использованием этого поля. В условиях с макросами, макросы автоматически подставляются и, если получается, то полностью выпадают, оставляя только если или иначе.
Основная задача импорта в классе - сократить путь к объекту. Фактически просто синтаксический сахар. Так как пути фактически могут быть длинными, то часто это сильно упрощает разработку.
импорт Кар
импорт Кар как К
Также меняется порядок поиска (??? надо ли это). Сначала идёт поиск в текущем классе, затем в текущем каталоге, затем в импорте в порядке их встречаемости, затем в проекте и так далее (??? нужен ли такой порядок, или импорт на пункт выше поставить?) (??? Порядок записан ещё в одном месте выше, надо всё перенести в одно место)
Класс состоит из заголовка, блока импорта, статических и динамических полей а также статических и динамических методов и тестов.
Заголовок класса необязателен, но должен стоять вначале класса.
Пример заголовка.
класс от [БазовыйКласс]
Если заголовок не написан, то класс не является наследников ни от какого класса (??? второй вариант - все классы являются наследниками от класса объект. Хороший вариант, так как можно туда добавить некоторые процедуры и методы типа имени класса, возможности узнать, является ли он производным от другого класса и т.п.)
Наследование может происходить только от одного класса. (??? Аналогов интерфейсов, как в Java или C# не предусмотрено. Возможно есть смысл ввести.)
Инициализация статических полей идёт в порядке, записанном в классе. Таким образом нельзя инициализировать поле на основе поля, которое стоит ниже в списке полей. Например:
стат поле А = Б + 5 // Ошибка периода компиляции. Поле Б ещё не финализировано.
стат поле Б = 3
Тоже касается и динамических полей при инициализации экземпляра класса (??? Надо продумать варианты как сделать так, чтобы в конструкторе всегда инициализировались все динамические поля. Можно ли такое проверить на этапе компиляции. Все команды если циклов и входы в другие методы?).
Все методы в классе по-умолчанию финализированные. Если необходимо изменить поведение метода в наследнике, то в методе базового класса необбходимо написать соответствующее ключевое слово, разрешающее наследование, а в наследуемый метод должен иметь те же атрибуты, что и базовый метод. Заметьте, что нельзя, например, изменить область видимости метода в наследуемом классе.
Таким образом ООП дается достаточно ограниченно, возможна наследование только от одного класса и перегрузка методов. Никаких множественных наследований, интерфейсов, изменений области видимости. ??? Хотя насчёт интерфейсов надо подумать.
??? Пока не обдумывал. Не понятно, можно ли как-то реализовать защещённую многопоточность, но чтобы при этом не сильно страдала гибкость работы с данными и производительность. Возможно как-то надо продумать передачу данных только через семафоры или что-то такое.
Сборка. Синтаксис:
Сборка: Виндовз, Андроид
Возможные значения: "Виндовз", "Линукс", "МакОС", "Андроид", "Айфон". (??? Ну или что там сейчас для Эппла производят.)
(??? Вообще по аналогии с макросами посмотреть варианты сборки)
Подключаемые каталоги. Синтаксис:
Проект: [Путь]
Библиотека: [Путь]
Библиотеки: [Путь]
Проект - путь до корня проекта.
Библиотека - путь до каталога, в котором подкаталогами являются версии библиотек, а их подкаталогами корни проектов.
Библиотеки - путь до каталога, где подкаталогами являются названия библиотек, их подкаталогами версия, а подкаталоги версий являются корнями проектов.
Версия. Синтаксис:
Версия: [ИмяБиблиотеки], [ВерсияПоУмолчанию]
Версия библиотеки для данного проекта. Так как библиотеки хранятся в разных версиях и могут выйти новые, то версия библиотек для построения проекта может измениться, если вышла более новая. Если версия не указана, то по-умолчанию применяется последняя версия библиотеки. (??? Возможно можно указывать только версию или не все подверсии, тогда будет выбираться последняя версия библиотеки из подходящих по описанию)
Связывание с библиотекой и вызов метода происходит по тем же правилам, что и в extern "C" в языках C/C++. (??? Достаточно ли будет такого типа связывания? или надо что-то добавлять?) (??? Расписать, что сие конкретно означает?)
Для подключения сторонних библиотек используется специальный модуль экспорта. Синтаксис:
Библиотека "kernel32.dll"
// BOOL GetComputerNameA(LPSTR lpBuffer, LPDWORD nSize);
экспорт GetComputerNameA/ПолучитьИмяКомпьютера(Строка Буфер, Счётное32* Размер) Буль
В первой строке пишется название библиотеки, далее перечисляются методы через ключевое слово экспорт.
Любому методу можно дать перевод через символ "/". В этом случае в программе можно использовать уже переведенное имя.
Пример вызова:
Строка ИмяКомпьютера = ""
ИмяКомпьютера.Зарезервировать(128)
ПолучитьИмяКомпьютера(ИмяКомпьютера, ИмяКомпьютера.Зарезервировано())
// А можно и так:
GetComputerNameA(ИмяКомпьютера, ИмяКомпьютера.Зарезервировано())
(??? Тут в примере надо подумать, можно ли передавать строки более элегантно. Это касается и строк, и массивов, и методов, и других объектов.)
(??? Статическое и динамическое подключение библиотек. Вообще здесь много чего надо обдумать.)
Библиотеки можно хранить на ftp.
Структура каталогов:
[Библиотека1]
[Версия1]
[Версия2]
[Версия3]
[Версия4]
...
[ВерсияН]
[Библиотека2]
[Библиотека3]
[Библиотека4]
...
[БиблиотекаН]
Скачивать без паролей, изменение под паролем для создателей библиотеки.
Библиотека1 - БиблиотекаН - это каталоги.
Версия1 - ВерсияН - это zip-архивы с названием вида Число.Число.Число.Число. То есть 4 числа, разделенных точками, обозначающими версию, подверсию 1 уровня, подверсию 2 уровня и подверсию 3 уровня соответственно.
Библиотеки можно передавать в виде открытого кода (файлы типа *
.кар), в виде объектных файлов (файлы *
.obj) и в виде динамически подключаемых библиотек (типа *.dll
или *.a
). В любом случае рядом прикладывается описание библиотеки в виде модуля экспорта.
Внутри zip-архива - корневой каталог проекта (библиотеки). (??? Необходима утилита для работы с библиотеками.)
- В разработке.
Кар.Тип.[ЛюбойСтандартныйТип]
Кар.Время Кар.Макрос Кар.ГенераторСлучайныхЧисел Кар.Поток
??? Посмотреть стандартные библиотеки C/C++, Java, C#, Python. Может ещё какие-нибудь языки.
Если(Буль условие, Тип результатДа, Тип результатНет) Тип