Краткое описание языка “Базовый 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 имя фрейма;

Первая конструкция порождает пустой (без слотов) фрейм.

 

 

Hosted by www.Geocities.ws

1