Skip to the content.

Синтаксис NewLang (0.3)

Основы

Правила именования объектов и типов данных

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

Префиксы и разделители

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

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

Чтобы создать локальную перемененную, перед её именем необходимо указать знак доллара $, тогда такая переменная будет уничтожаться при выходе из текущей области видимости. Если условно классифицировать эти два варианта переменных, то можно считать, что переменная по умолчанию создается в куче, а локальная с префиксом $ на стеке.

Семантика локальных переменных, а так же аргументов у функций очень похожа на аргументы в bash скриптах, где $1 или $arg — порядковый номер или имя аргумента.

Пространства имен

NewLang одновременно поддерживает и пространства имен, как в языке C++, так и модульную структуру кода как в языках Java и Python. Синтаксис для указания пространства имен очень похож на С++. Имена разделяются двойным двоеточием, а для определение пространства имен, его нужно указать перед открывающейся фигурной скобкой.

ns {
    name {
        var := 0; # Имя переменной будет ns::name::var
        ::var := 1; # Переменная из глобального пространства имен
    }
}

Программные модули

В NewLang реализована концепция программных модулей - которая повторяет идею иерархического расположения файлов в структуре каталогов файловой системы, так же, как это сделано в языках Python и Java. Имя программного модуля начинается на префикс @, а структура каталогов указывается через точку.

Причем в именовании объектов концепции программных модулей и пространства имен объединены. Например, полное имя переменой можно записать с указанием программного модуля @root.dir.module::ns::name::var, где root и dir это каталоги в файловой системе, а module — имя файла, т.е. root/dir/module.nlp

Области видимости объектов определяются аналогично прияным в языке Python с помощью подчерков перед именем переменной. Один подчерк соответствует защищенной, а два подчерка - приватной области видимости объекта в соответствующем модуле или классе. Но так же как и в языке Python области видимости больше соответствуют “джентльменской” договоренности и при явном указании имени, доступ к защищенным объектам можно получить указав их полное имя. Системные поля и объекты начинаются и заканчиваются на два подчерка.

Макросы

Макросы в NewLang, это специальный идентификатор, который заменяется на тело макроса перед обработкой исходного текста программы парсером. Так как тело макроса может содержать любой текст или последовательность символов, то для их определения существует специальный синтаксис.

С помощью макросов можно расширять NewLang новыми языковыми формами и даже определить собственный предметно-ориентированный диалект языка для конкретной задачи, так как раскрытие макросов происходит до обработки текста парсером. Поэтому в теле парсера могут содержаться в том числе и различные части языковых конструкций.

Макросы используются и для более привычного вида текста программы, превращая базовый синтаксис NewLang в синтаксис на основе ключевых слов, так как такой тест гораздо легче воспринимается при последующем чтении исходного кода.

Макрос в исходном тексте программы всегда начинается на обратный слеш (бекслеш) \, т.е. \name или \macro(arg1, arg2). Формат определения макроса - два обратных слеша, имя определяемого макроса, аргументы (если они есть), тело макроса, три обратных слеша.

В тело макроса можно вставить переданные в макрос аргументы. К аргументу макроса можно обратиться по его имени, порядковому номеру или ко всем аргументам сразу. Чтобы вставить аргумент в тело макроса, перед его именем или порядковым номером нужно записать обратный слеш и знак доллара, т.е. \$name или \$1. А чтобы вставить в тело макроса сразу все аргументы разом, нужно указать \$*.

Например:.

\\if(...) [\$*]--> \\\
\\elif((...) ,[\$*]--> \\\
\\else ,[_]--> \\\

\\while(cond) [\$cond] <-> \\\
\\dowhile(cond) <-> [\$cond] \\\

\\return --\\\
\\return(...) -- \$* --\\\

\\true 1\\\
\\false 0\\\

Тогда цикл до 5:

count:=1;
[ 1 ] <-> {
    [count>5] --> {
        -- 42 --;
    };
count+=1;
};

будет выглядеть более привычно

count:=1;
\while( \true ) {
    \if(count>5) {
        \return(42);
    };
count+=1;
};

С полным списком макросов можно ознакомится тут или посмотреть исходный код программного модуля.

Специальные идентификаторы

Проверить, является ли текущий модуль основным, можно протестировав его нулевой аргумент. У основного модуля программы, нулевой аргумент всегда будет содержать имя исполняемого файла, а остальные аргументы соответствовать параметрам командной строки (если они есть). Если файл загружен как модуль, то нулевой аргумент у модуля будет пустым.

# Аналог проверки в Python
# if __name__ == "__main__": 

[@$.$0] --> { # или \ifmain при использовании макросов из модуля @dsl
    ...
};

Зарезервированные имена компилятора

При работе парсера NewLang автоматически генерируются несколько зарезервированных имен, которые можно использовать как обычные константы. Большинство из них соответствуют макросам препроцессора у С/С++:

Системные свойства

Несмотря на то, что не все объекты NewLang являются классами с точки зрения реализованной концепции ООП, тем не менее, каждый объект имеет системные свойства, которые можно считать во время выполнения как обычные свойства объекта:

У всех переменных (объектов) есть системные свойства

Системные свойства у модулей