Краткое описание языка “Базовый SIMPLE”.
Build “Archimede”.
Алфавит языка.
Алфавит включает все доступное подмножество знаков при 8-битной кодировке. Часть знаков не может входить в состав символов, так как является синтаксическим знаком. Далее в описании такие знаки будут выделяться подчеркиванием.
Структура языка.
Данная реализация опирается на расширенный псевдокод, который исполняется ВМ. Применяемой ВМ определяется и набор типов данных реализованный в языке. Типы данных делятся на простые и составные. Для большей гибкости исходные тексты могут содержать синтаксические выражения обрабатываемые препроцессором. Это комментарии, замены и т.п.
Типы данных и операции над ними.
Типы данных в языке – это доступные для оперирования объекты.
Long – знаковое длинное целое.
Double – число с плавучей точкой двойной точности.
Эти типы данных поддерживают арифметические операции и операции сравнения.
Exp:
exp '+' exp { Сложение }
| exp '-' exp { Вычитание}
| exp '*' exp { Умножение}
| exp '/' exp { Деление}
| '-' exp { Унарный минус}
| exp '^' exp { Степень числа}
| exp '>' exp { Больше }
| exp '<' exp { Меньше}
| exp '>=' exp { Больше }
| exp '<=' exp { Меньше}
| exp '=' exp { Равно}
| exp '<>’ exp { Неравно}
Symbol – символьный тип. Предельная длина символа – 255 знаков. Все идентификаторы (например, имена переменных и функций) представляют собой символы.
Кроме этого в системе есть изначально заданные константы:
Nil – пустое значение или пустое множество.
True – истинное значение.
False – ложное значение.
Оперирование символами производится непосредственно в самом языке. Константа задается указанием перед символом апострофа. Например, ‘symbol.
String – строковый тип. Предельная длина строки - 232 любых знаков. Константа задается с помощью ограничивающих кавычек. Например, “Привет !”.
Для работы используются команды псевдоассемблера, либо предопределенные в файле STDLIB.SMP функции concstr, instr, midstr и lenstr.
List – ячейка списка аналогичная соответствующему типу в языке LISP. Состоит из двух равнозначных ячеек-указателей. Константа задается в виде скобочного выражения предваряемого знаком ~ (тильда). Например, ~(1 2 3 ~(“Это числа”)).
Для работы используются команды псевдоассемблера, либо предопределенные в файле STDLIB.SMP функции car, cdr, cons, rplaca, rplacd.
Tuple – кортеж. Состоит из n – числа ячеек указателей, где n – размерность кортежа. Константа задается в виде списка разделенного запятыми и заключенного в квадратные скобки и предваряемого знаком ~ (тильда). Например, ~[1, 2, 3, ~[“Это числа”]]. Для работы используются команды псевдоассемблера, либо предопределенные в файле STDLIB.SMP функции maketuple, addtuple, deltuple, elttuple, copytuple, resizetuple.
Остальные типы являются сложными и базируются на простых типах.
К ним относятся фреймы, функции, замыкания, окружения и стеки.
Комментарии.
Комментариями являются два знака косой черты:
// Это комментарий
Все знаки до конца строки начиная с комментария транслятором игнорируются.
Функции.
Основная синтаксическая конструкция для описания функций выглядит следующим образом:
define имя функции (аргумент 1, ..., аргумент N) {
// Здесь помещается тело функции
};
или
define имя функции (аргумент 1, ...) {
// Здесь помещается тело функции
};
где ... переменное количество аргументов с доступом по оператору argument exp где exp выражение с типом long.
или
define имя функции {
// Здесь помещается тело функции
};
Все аргументы передаются как объекты т.е. по указателю.
Разрешается указывать константные значения аргументов:
define имя функции (аргумент 1=-672) {
// Здесь помещается тело функции
};
В теле функции описываются локальные переменные, присутствуют арифметические выражения, операторы и вызовы функций.
Вызов функции выглядит следующим образом:
имя функции
(<список значений аргументов>);или
имя функции()
;Причем, при вызове можно опускать значения аргументов с конца. В этом случае они приобретут значение Nil.
Переменные.
Объявление переменных обязательно, и выглядит следующим образом:
declare имя переменной;
или
declare имя переменной=<значение переменной>;
где значение переменной – константа.
Операторы.
Оператор присваивания := аналогичен подобному оператору например, в языке Pascal:
имя переменной
:= <константа>;или
имя переменной
:= <выражение>;или
имя переменной
:= <вызов функции>;Оператор условия :
if <условное выражение> <оператор исполняемый в случае истинности>;
или
if <условное выражение> {
// Блок кода исполняемый в случае истинности
};
или
if <условное выражение> {
// Блок кода исполняемый в случае истинности
} else {
// Блок кода исполняемый в случае не истинности
};
На самом деле истинность всегда если не False.
Оператор альтернативного выбора:
cond {
<условное выражение N1> do <выражение исполняемое в случае истинности >;
<условное выражение N2> do <оператор исполняемый в случае истинности >;
<условное выражение N3> do {
// Блок кода исполняемый в случае истинности
};
{
// Блок кода исполняемый в любом случае
};
……..
};
Циклический оператор альтернативного выбора:
lcond {
<условное выражение N1> do <выражение исполняемое в случае истинности >;
<условное выражение N2> do <оператор исполняемый в случае истинности >;
<условное выражение N3> do {
// Блок кода исполняемый в случае истинности
};
{
// Блок кода исполняемый в любом случае
};
……..
};
Отличается только тем, что при отсутствии истинного условия lcond повторяет проверки снова, а cond заканчивает возвращая Nil.
Оператор псевдоассемблерной вставки:
asm {
// Блок кода на псевдоассемблере
label0001:
loadvl var1;
jnil label0001;
};
Фреймы.
Фрейм – структура состоящая из набора слотов, каждый из которых состоит из имени и значения. Слоты у которых значение не трактуется как функция или замыкание называются полями, в противном случае – методами. Фрейм описывается как
frame имя фрейма {
имя слота 1, имя слота 2, ..., имя слота N
};
Такая структура порождает базовый фрейм, который однако практически недоступен. Для порождения “нормального” экземпляра используется следующая конструкция:
имя переменной:=new имя нового фрейма;
или
имя переменной:=new имя нового фрейма as имя фрейма;
Первая конструкция порождает пустой (без слотов) фрейм.