Абриаль 2.1 Начало Выше Дальше29/09/04 А.И.Пацкин [packin.ru]
[ Абрис 1 - Руководство ] Примитивы Абриса ] Операции - справочник ] Справочник примитивов Абриса ]

Абрис 1 - Руководство


Язык программирования Абрис 1.

Версия документа 1.3

Последнее изменение 29.09.04

Данный документ является краткой "пилотной" версией руководства к языку Абрис - языку программирования гипертекстовых оболочек к базам данных системы представления знаний Абриаль. Документ рассчитан на продвинутых в программировании читателей. Требуется знание основ HTML, принципов функционирования Веба (WWW), реляционных баз данных, желательно знакомство с объектно-ориентированной идеологией, понимание концепций объекта, класса, отношения, запроса, и т.д. Необходимо хотя бы поверхностное знакомство с идеологией системы Абриаль. В конце документа приведен Словарик основных терминов. Дополнением и продолжением данного документа является Описание Примитивов, т.е. встроенных операций и операторов языка Абрис. Если Вас не пугает все сказанное выше,  желаю успешного изучения Абриса.

А.И.Пацкин (автор системы Абриаль)


Введение

Что такое Абрис.

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

Что такое Абриаль.

Абриаль 2 представляет собой среду для быстрой разработки сложных активных баз знаний и приложений на их основе. По заданной пользователем структуре данных система сама автоматически строит интерфейс для просмотра и изменения данных. Добавление новых типов данных мгновенно отражается на автоматически изменяемом интерфейсе и может быть тут же испытано, что, однако, не затрагивает ранее введенные данные и их структуру.

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

Основополагающей новацией в системе Абриаль 2 является её модель данных, имеющая ряд общих черт с объектной, реляционной и с логической (предикатной) моделями представления данных, и в то же время отличная от этих моделей в одном очень существенном аспекте: модель Абриаля изотропная , это значит, что тут полностью исключены односторонние ссылки, а вместо них используются двухсторонние и многосторонние связи, проходимые во всех направлениях качественно одинаковым образом.

Основополагающая идея языка Абрис.

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

Развитие программирования  в 20-м веке в определенном аспекте (очень грубо!) шло в трех направлениях 1) Центральное - структуры среды исполнения (ООП, списки, продукции и т.д.). 2) Базы данных (SQL, XML...) 3) Интерфейс пользователя (HTML, JScript, Дельфи...). Это фактически привело на грани веков к созданию трех различных миров (их ключевые слова приведены выше в скобках). В результате, для стержневой задачи современных информационных технологий, для работы в Сети с базами данных необходимо наличие этакого "слоеного пирога" между пользователем и объектами данных. В этом "пироге" присутствуют все три мира, каждый со своими порядками и сложностями; и между кликом пользователя по экрану и получением ответа все эти миры задействуются. Но это происходит так, что пользователь не видит объектов базы данных как таковых, они заслонены от него "слоеным пирогом". Вообще говоря, объектов может и не быть (особенно если используется строго реляционная идеология организации БД) не говоря про объекты среды исполнения, каковые являются внутренним делом конкретного программиста, и как детали реализации никого не интересуют. В итоге пользователь видит среду не как сеть логически взаимосвязанных объектов проблемных областей, а как множество страниц, не соотносимых ни с какими объектами. Всякие согласования объект-страница или ссылка-объект возникают лишь случайно и непредсказуемо. В результате, на программиста ложится огромная ответственность, забота и труд - каждый раз изобретать эту объектную среду заново, (или - не изобретать, оставляя пользователю взгляд на его среду через замочную скважину). А на пользователя ложится забота изучать от нуля каждую новую систему построенную из своих окошек и страничек, в которую конкретный программист вносит свою неповторимую индивидуальность, философию и свои взгляды на мир.

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

Среда интерфейса тоже ликвидируется, но иначе. Типичный пример среды интерфейса: Дельфи или JavaScript/DHTML, где элементы интерфейса имеют свои имена и программа читает или пишет данные по этим именам. Идея макрогенерации и функциональный стиль Абриса - убирает необходимость в именовании элементов интерфейса - всякая конструкция Абриса производит некий текст, который подставляется вместо неё, и интерпретируется, таким образом, по месту, декларативно, а функциональность полученного HTML-текста отдается на откуп стандартному броузеру. В итоге пользователь получает стандартный интерфейс и стандартную логическую среду для манипуляции с любыми существующими и будущими объектами. Причем данный интерфейс опирается на логически ясную и прозрачную среду проблемных объектов пользователя, а не каких-то непонятных страничек, изобретаемых программистом в рамках его собственной философии. Каждая страничка соответствует некоторому объекту и/или определенному аспекту сложного объекта, и каждая ссылка соответствует либо действию с логическим объектом либо навигационному переходу на него.

Принцип работы

Работа строится на основе последовательности обращений пользователя к базе данных, аналогично тому, как это происходит в рамках технологии CGI. Точнее, существует два варианта работы программы Абриаль:

  1. первый вариант - клиентский, это обычная программа Windows, эмулирующая работу CGI-скрипта,
  2. а второй вариант - серверный, это обычный CGI-скрипт, в настоящей версии работающий в среде веб-сервера MS IIS.

В первом (клиентском) варианте используется специальная версия броузера, встроенная в программу Абриаль и понимающая язык Абрис. В серверном варианте используется обычный (в данном случае - уже любой) броузер, работающий из-под любой ОС. Для языка Абрис это различие незаметно, постольку поскольку безразлична конкретная реализация, т.е. конкретная форма ссылок, используемых на страничке.

В момент написания данного руководства полноценная реализация технологии существует для её клиентского варианта, т.е. в виде программы Абриаль. Для серверного варианта существует пока только прототип с рядом существенных ограничений функциональности и с не решенным пока вопросом: будет ли сохраняться контекст пользователя, и если будет, то какими средствами, (cookie, скрытые поля...).

В целом Абрис работает по следующей схеме:

  1. Веб-страничка отображается пользователю (броузером или Абриалем).
  2. На этой страничке все ссылки устроены таким специфическим образом, что они представляют собой обращения к объектам баз данных Абриаля через протокол HTTP (или его эмуляцию в клиентском варианте).
  3. Пользователь посылает в базу данных HTTP-запрос, состоящий из некоторой ссылки в самом общем виде (URL), плюс, возможно, некоторой POST-информации, содержащую дополнительную информацию, в том случае, если пользователь перед запросом заполнял HTML-форму.
  4. Система на основе содержимого базы данных и гипертекстовых шаблонов-макросов состоящих из смеси HTML-текста и теста на языке Абрис генерирует ответ пользователю в форме динамической веб-странички. Переходим к пункту 1.

Особенности технологии

Таким образом, исполнение программы на Абрисе начинается с запроса пользователя в момент его нажатия на кнопку формы или выбора ссылки, состоит в генерации страницы и/или с возможным изменением данных в базе данных и после полного формирования страницы заканчивается. При этом существенны следующие технологические моменты:

  1. Кроме посылки HTTP-запроса (ссылки + POST информации) пользователь не имеет других каналов информации от него в направлении базы данных. (Мы не рассматриваем здесь другие виды интерфейса, представляемые программой Абриаль, например гипертаблицы, которые не имеют отношения к работе через Веб-интерфейс и к языку Абрис).
  2. Во время работы системы по формированию очередной странички, пользователь просто ждет, и пока страничка целиком не будет готова, не получает никакой информации, т.е. какие-либо сообщения, запросы, подтверждения, окна диалогов и тому подобные средства связи программы и пользователя во время исполнения данной технологией не предусмотрены. Ввести средства промежуточного диалога с программой для клиентского варианта было бы нетрудно и вероятно полезно, но это специально не было сделано для полной совместимости клиентского и серверного вариантов технологии.
  3. Контекст пользователя между шагами обращениями к системе, в клиентском варианте сохраняется: а) в виде набора значений глобальных переменных, и б) в виде набора открытых баз данных, которые могут быть изменены, но пока не сохранены. Будет ли в плане контекста полная совместимость с серверным вариантом и нужна ли она, - вопрос пока открытый.
  4. В плане генерации текста язык Абрис никак не привязан к HTML, и совершенно свободно может использоваться для генерации текстов на любом языке, на XML на Паскале, Си, русском... Однако вся мощь данной технологии проявляется в автоматическом формировании ссылок на объекты (абриалевской) базы данных, а чтобы ссылки в тексте работали - необходимо нечто похожее на HTML.

Навигации по сети и действия с сетью.

Работа системы с использованием Абриса строится из последовательности шагов: запрос-генерация-ответ. Запросы логически делятся на две разновидности: шаги навигации и действия. Каждая страница относится к определенному объекту определенной базы данных, отображаемому определенным методом, возможно с параметрами. Очередной запрос содержит новую совокупность: БД, объект, метод и параметры метода, иными словами, задает определенную точку навигации. Шаги навигации, т.е. переходы от точки к точки меняют что нибудь в запросе и соответственно изображают другую страничку, но как правило ничего не меняют в данных т.е. не меняют базу данных. Действия, напротив, не меняют отображаемую точку навигации, но меняют данные в базе данных.

Шаг навигации происходит проще. Страничка генерируется в соответствии с новым запросом и посылается пользователю. 

Действие производится в два этапа: сначала вызывается метод из запроса, который по идее должен что-то изменить в базе данных, формально он устроен так же как шаг навигации, т.е. также может генерировать некий текст, например, сообщающий пользователю что действие выполнено, или, что его не удалось выполнить. Но этот текст не посылается в страничку, а попадает в специальную системную переменную RESULT. Затем повторяется в точности предыдущий навигационный запрос, т.е. генерируется страничка соответствующая последнему шагу навигации. Внутри этой странички может быть предусмотрено место для отображения текста из переменной RESULT. При первом отображении навигационной странички переменная RESULT была пуста, она очищается в начале каждого шага. И соответственно, ничего на страничке не извещало о результате действия - ведь его пока еще не было.

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

Формально запрос действия отличается от навигационного запроса наличием параметра ACT, задающим имя метода - действия (см. раздел Структура запроса).

Структура запроса

Запрос логически представляет собой множество параметров, т.е. пар вида Имя=Значение, где Имя - идентификатор (из латинских букв, знака "_" и цифр, начинающийся с буквы или знака "_"), а Значение - любая строка символов, не содержащая нулевого символа. Регистр букв учитывается. В одном запросе каждое имя уникально с учетом регистра.

Физически, т.е. в виде текста на страничке запрос представляется в виде гиперссылки, вид которой зависит от варианта системы, например для клиентского варианта ссылка может выглядеть так:

ab://ab/D=C%3A%5CABRIAL%5C%5FBASES%2EAB&O=559

а целиком тег A, содержащий эту ссылку будет выглядеть так:

<A HREF="ab://ab/D=C%3A%5CABRIAL%5C%5FBASES%2EAB&O=559">Медицинская диагностика</A>

Данная ссылка содержит два параметра:

Имя параметра Значение Примечание
D C:\ABRIAL\_BASES.AB Имя файла базы данных
O 559 Ид объекта

Параметры D и O системные, т.е. учитываются системной для технологических нужд вне языка. Основные системные параметры приведены в следующей таблице:

Имя параметра Значение Примечания
M Имя метода просмотра (навигации) Альтернатива ACT. По умолчанию (нет ни M ни ACT) принимается: M=_HOME если не указана БД (D=) или если БД указана, но не указан объект, то M=_ROOT, а если объект указан, то M=PAGE
ACT Имя метода-действия (изменения БД) Альтернатива M. Указание этого параметра есть признак запроса - действия. В противном случае запрос навигационный.
D Имя файла базы данных. Параметры O,N,C,A,AN имеют смысл лишь при указании базы данных. Указанная БД устанавливается в качестве текущей.
O Ид объекта. Альтернатива N+C. Указанный объект устанавливается в качестве текущего.
N Имя объекта Альтернатива O. Действует совместно с C. Указанный объект устанавливается в качестве текущего.
C Имя класса объекта Альтернатива O. Действует совместно с N. Указанный объект устанавливается в качестве текущего.
A Ид аспекта Альтернатива AN. Указанный аспект устанавливается в качестве текущего
AN Имя аспекта Альтернатива A. Указанный аспект устанавливается в качестве текущего

Типы данных

В языке Абрис имеется только один тип обрабатываемых данных, а именно строки или, в более общем виде последовательности строк, т.е. текст.

Числа, целые и вещественные обрабатываются непосредственно в своем строчном представлении.

Системные идентификаторы (иды, IDs) объектов БД представляются в виде строчной записи соответствующих целых положительных чисел.

Логические (булевские) значения представляются следующим образом. Пустая строка, с длиной 0, представляет логическое значение FALSE (ЛОЖЬ), любая непустая строка представляет логическое значение TRUE (ИСТИНА). Стандартное значение для TRUE, возвращаемое логическими операциями - один пробел, " ".

Методы

В языке Абрис работа программы состоит в вызове методов (т.е. функций) которые в качестве результата возвращают текст. Вызов главного метода, указанного в параметре M запроса (ссылки) возвращает текст страницы, отображаемой пользователю. В случае, если параметром ACT указан главный метод действия, всё происходит также, только результирующий текст попадает не в отображаемую страничку, а в промежуточное хранилище, - переменную RESULT.

Итак, по сути методы в Абрисе, это - функции возвращающие текст. По форме методы делятся на

  1. Примитивные методы (операции и операторы)
  2. Макросы
  3. Метод-функции или просто функции.

Примитивные методы аналогичны обычным операторам и встроенным функциям в языках программирования высокого уровня. О них речь ниже, а здесь мы рассмотрим разницу между макросами и (метод-) функциями.

Макросы и функции

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

Макро-теги

Макротег - это вызов Абрис-выражения внутри макроса. Семантика макротега такова: при макрорасширении выражение вычисляется и его результат подставляется на место макротега.

Формат макротегов

Синтаксически макротег аналогичен тегу HTML, т.е. это имя с возможными параметрами в угловых скобках <#Name[param=val]...>, но в макротеге, в отличие от простого HTML-тега, после открывающей угловой скобки непосредственно следует  знак #. Вообще говоря, в тексте макроса последовательность таких символов: 

<# здесь может идти что угодно, (но с уравновешенными "кавычками" и (круглыми) или <угловыми> скобками ) > 

считается макротегом. Если в макротеге что-то неправильно, т.е. например допущена ошибка, без нарушения формата, т.е. не выходящая за границы макротега, то в результате его вычисления получится пустая строка.

Макротеги и HTML.

С практической точки зрения макротеги Абриса и теги HTML обычно структурно согласованы, но это вообще не обязательно, т.к. с точки зрения Абриса текст HTML, как и любого другого языка, есть просто набор символов. Структура HTML-тегов для Абриса совершенно безразлична: Абрис может генерировать HTML не только целыми тегами, а любыми фрагментами тегов в произвольных комбинациях. Например: макротег может после вычисления выдать результат: строку "><", состоящий из закрывающей скобки одного тега и открывающей скобки последующего.

Операторы, закрывающий макротег.

Как и теги в HTML, макротеги могут быть сложными, объемлющими часть текста макроса. Сложными в Абрисе являются макротеги, вызывающие некоторые примитивы (примитивные методы), например, операторы цикла (FOR FORALLOBJ) или определения макроса в тексте (MACRO). Сложный макротег включает в себя "тело" т.е. следующий за макросом текст вплоть до и включая соответствующий закрывающий макротег <#/>.  Признаком закрывающего макротега является комбинация "<#/" Между знаком "/" и закрывающей скобкой ">" может находиться имя или любой другой текст с уравновешенными скобками и кавычками, который игнорируется.

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

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

Синтаксис языка Абрис 

Общая структура приложения

Приложение на Языке Абрис представляет собой набор макросов, макросы являются либо текстовыми файлами, либо текстовыми объектами базы данных. Также макрос может быть определен в момент исполнения другого макроса с помощью оператора (составного примитива) MACRO:

<#MACRO MacroName>
First string of macro
Value of 1-st paramether=<#1>
Sum of 1-st paramether and number 3='<#SUM (1) 3>'
Value of paramether AN='<#AN>'
Last string of macro
<#/>

Результатом вызова данного макроса с помощью макротега

<#MacroName 5 AN="Rel\Asp1">

Будет следующий текст:

First string of macro
Value of 1-st paramether=5
Sum of 1-st paramether and number 3='8'
Value of paramether AN='Rel\Asp1'
Last string of macro

Из примера видно как несколько макротегов внутри текста макроса заменились при вычислении на свои значения.

Итак приложение есть множество макросов, каждый из которых представляет собой множество строк текста на произвольном языке, включающих внутри себя макротеги, то есть выражения языка Абрис в специальных теговых скобках <#...>. Внутренность макротега может располагаться в нескольких строчках. Внутри макротега могут быть в качестве аргументов находиться другие выражения. Для этих внутренних выражений могут использоваться скобки трех типов:

  • Такие же скобки как у макротега, т.е. <#...>.
  • Просто угловые скобки <...>.
  • Обычные круглые скобки. (...).

Наиболее удобно и естественно использовать для внутренних выражений обычные круглые скобки, что делает синтаксис языка Абрис напоминающим язык Лисп. В следующей таблице видно различие синтаксиса между Си, Лиспом и Абрисом:

  Си Лисп Абрис
 Внутренние выражения На уровне макроса
Литерал строчный  "Это строка"   OneWord
"Два слова"
1234
<#"Строка">
Просто текст
<#"1234">
1234
Литерал числовой 1234 1234
Переменная abrial2 abrial2 (abrial2) <#abrial2>
Параметр по №2 - - (2) <#2>
Функция без параметров run(); (run) (run) <#run>
Функция с параметрами convert(x,"abcd"); (convert x "abcd") (convert (x) abcd) <#convert (x) abcd>

Как видим основные отличия синтаксиса Абриса от классических языков (Си) состоят в записи переменных, литералов и вызовов функций.

  • Обращения к значениям переменных в большинстве ЯП записывается как просто идентификатор, в Абрисе для обращения к переменной внутри выражения её имя нужно взять в круглые скобки, а в макросе - в макросные скобки.
  • Строчные литералы везде принято изображать в кавычках, в Абрисе кавычки не обязательны, если литерал является аргументом в вызове функции, не пуст и не содержит внутри себя ничего кроме букв, цифр и знака подчеркивания.
  • Обращение к функции в Абрисе аналогично лисповскому: имя функции пишется внутри скобок, а не перед ними, как это принято в математике и в классических языках программирования (таковыми здесь называются языки фортрано-алгольного происхождения, хотя Лисп, вне сомнения - тоже классика). Кроме того, для разделения аргументов используются пробелы, а не запятые.

Подробнее о синтаксисе Абриса см. следующие разделы.

Общий принцип организации текста

Текст макросов на в системе языка Абрис состоит из двух четко разделенных частей:

  1. Текст на включающем языке, это может быть HTML, но также абсолютно любой язык программирования или естественный язык. Правила языка Абрис на него никак не распространяются, если не считать правила определения границы: после любой комбинации символов "<#" начинается макротег, т.е. собственно текст на языке Абрис, и заканчивается он соответствующим знаком ">", после которого текст снова относится к включающему языку.
  2. Текст внутри макротегов, то есть собственно текст языка Абрис. Т.е. набор выражений и комментариев.

Таким образом, описание синтаксиса Абриса состоит из описания синтаксиса комментариев и синтаксиса выражений.

Синтаксис комментариев

Имеется четыре разновидности комментариев.

  1. // комментарий в стиле Си++ - от двух подряд знаков // до конца строчки
  2. /* комментарий в стиле Си */ может захватывать несколько строчек; начинается со знаков /* и заканчивается знаками */
  3. <#REM простой примитив REM - ничего не делает. Им легко временно выключать простые примитивы и обращения к методам. >
  4. <#XXX> сложный примитив XXX также ничего не делает, но его действие распространяется до соответствующего закрывающего тега <#/>

Обратим внимание: комментарии в стиле Си/Си++ (случаи 1,2) полностью игнорируются, как если бы на их месте были пробелы. Но следует учитывать, что REM и XXX все таки являются вызовами выражений, возвращающими пустоту, и будучи вставлены в качестве операнда/аргумента эти примитивы засчитывается, так что вставляя их внутрь выражения мы сдвигаем номера последующих аргументов на единицу. В качестве таких комментариев можно было бы использовать и любую абракадабру, однако это неразумно, т.к. на поиск несуществующих методов может затрачиваться значительное время.

Синтаксис выражений

 Выражение представляет собой один из следующих вариантов:

  1. Литерал
  2. Обращение к переменной или к параметру функции по имени.
  3. Обращение к параметру по номеру
  4. Вызов примитива
  5. Вызов метода
  6. Конкатенация
  7. Присваивание
  8. Выражение с переменным предикатом
  9. Конвейерное выражение

 Литералы

Литералы, т.е. строчные константы в общем виде записываются как строчки в кавычках. Кавычки внутри литерала сдваиваются. Если литерал начался с кавычки и до конца строки не встретилась закрывающая кавычка, конец строки ограничивает литерал. Таким образом переводы строк и другие знаки, отсутствующие на клавиатуре, внутри литералов не имеют представления. Другими словами, литерал не может представлять несколько строк. Но имеется отдельный вариант литерала, содержащий ровно один перевод строки, именно знак "\".

Чтобы представить несколько строчек текста, нужно использовать специальный литерал, знак "\" представляющий перевод строки, т.е. несколько литералов взять в скобки и разделить между собой знаком "\". Например запись:

("1st string"\"2nd string"\"3rd string")

представляет три строчки текста. Но это уже не литерал, а сложное выражение, требующее вычисления.

Литералы состоящие только из цифр, латинских букв обоих регистров и знака подчеркивания можно записывать без кавычек, если они не стоят на первом месте внутри скобок. Но если такой литерал стоит следом за открывающей скобкой, (круглой "(" угловой "<" или макросной "<#"), он должен браться в кавычки, чтобы не быть воспринятым как имя функции.

Также обратим внимание, что в кавычки нужно брать отрицательные и дробные числовые константы, т.к. они содержат знаки минус и точку.

Переменные

Обращение к переменным выглядит в абрисе так же как к функциям без аргументов: имя переменной заключается в скобки. Обратим внимание, что это же имя без скобок означает литерал т.е. строчную константу.

Позиционные и ключевые параметры

К методу (к функции) можно обращаться с позиционными параметрами, аргументами (method aaa bbb ccc) или с ключевыми или атрибутами в стиле HTML : (method k1=value1 k2=value2). Атрибуты (ключевые параметры) внутри вызываемой функции превращаются в обычные локальные переменные, которым при входе в функцию присваиваются значения равные результатам вычисления выражений (value1 value2) стоящих после знака "=".

К позиционным параметрам внутри функции можно обращаться по их номеру, взятому в скобки. Например, внутри функции вызванной выражением (method aaa bbb ccc) обращение (2) вернет bbb.

Вызовы методов

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

Позиционные параметры- это просто любые выражения.

Ключевые параметры- это пары Имя=выражение разделенные знаком равенства.

(MethodName (positional) Key=(attr_value))

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

Вызовы примитивов

Вызов примитива по форме ничем не отличается от вызова составного метода. Только можно отметить что некоторые примитивы являются сложными, и на уровне макроса требуют закрывающего тега. Например, примитив IF проверяет некоторое условие и весь последующий текст макроса вплоть до закрывающего макротега <#/> (включительно) относится к этому же примитивному оператору:

<#IF (condition)>
OKAY Part of operator: Condition satisfed
<#ELSE> Condition failed
<#/>

Безымянная операция

Наиболее частые операции в языке две: это конкатенация (склейка из кусков) текста и присваивание значений локальным переменным. В старых версиях языка эти операции исполнялись примитивами с именами, соответственно, TEXT и SET. Теперь эти операции объединены в одну безымянную операцию, для которой имя примитива можно опускать. Впрочем, явные имена TEXT и SET для этой операции могут использоваться как прежде.

Действие этой обобщенной операции состоит в сцеплении результирующих значений всех безымянных параметров и выдачи полученного значения в качестве результата операции, а также в последовательном исполнении всех именованных параметров, как присваиваний локальным переменным с именами, соответствующими именам параметров. Все выражения в параметрах вычисляются в порядке их  следования, так что если на N-м месте стоит присваивание некоторой переменной, то выражения в параметрах N+1 и далее могут использовать эту переменную с новым значением. Присваивания ничего не возвращают (sic! в отличие от Си, где присваивания возвращают присвоенное значение).

Имя операции считается опущенным, если сразу следом за открывающей скобкой или после знака бинарной операции нет латинского идентификатора, а находятся:

  1. Литерал в кавычках, например "вот так"
  2. Выражение в круглых скобках, например (x+y)
  3. Имя параметра (латинский идентификатор со знаком равенства), например qwerty=
  4. Целое положительное число - только после знака бинарной операции, но не после скобки.

В перечисленных случаях эти четыре варианта считаются первым параметром безымянной операции. Обратим внимание, что число не взятое в кавычки, после открывающей скобки обозначает позиционный параметр, а после бинарной операции - литерал. Данное усложнение принято для того чтобы такие часто встречающиеся выражения операции как (X+2) трактовались бы как (X+"2") а не как (X+(2)) что потенциально привело бы к большому числу трудно различимых ошибок.

Как вариант безымянной операции может рассматриваться пустая операция, когда вместо ожидаемого имени операции следует признак её конца, в виде:

  1. конца файла
  2. знака бинарной операции
  3. закрывающей скобки.

Пустая операция ничего не возвращает и эквивалентна литералу "".

Переменные предикаты.

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

  1. <Выражение в угловых скобках> - вычисляется и результат используется как имя переменной, метода или примитива. В случае возврата имени примитива, никакие особые свойства его не учитываются, в частности сложность, т.е. закрывающий тег таким сложным примитивам не требуется и более того будет мешать.
  2. <#Выражение в макротеговых скобках> - вычисляется и результат используется как текст макроса, к которому и производится обращение, также как если бы этот макрос имел имя, и здесь находилось бы именно это имя.

Бинарные операции.

Основной недостаток скобочного синтаксиса( а-ля Лисп) - трудность в слежении за числом скобок для уровней вложенности выражений больше двух-трех. Пропуск скобки или лишняя скобка это - трудно находимые ошибки, но они же - наиболее типичные. Из-за этого с текстом нетривиальных программ становится трудно работать. Для устранения этой трудности в язык введены бинарные операции, позволяющие заменять вложение выражений на последовательное исполнение, что сокращает число скобок.

Общая идея: в скобках записывается последовательность, разделенных знаками бинарных операций сегментов. Каждый сегмент представляет собой вызов обычной операции, переменной или метода. Сегменты и бинарные операции вычисляются в порядке следования. Каждая бинарная операция в качестве первого (левого) операнда берет всё, что вычислено слева от неё т.е. до этого момента. А правый операнд знака дает выражение, расположенное справа, т.е. непосредственно следом за операцией. Реализованы следующие знаки операций:

Знак Соответствует  операции Что делает операция Описание действия
; DO Отсечение результата Игнорируя первый (левый) операнд, возвращает второй
, пусто/TEXT/SET Конкатенация строк Возвращает сцепленные операнды: левый, затем правый
& AND Строчно-логическое И Если первый операнд не пуст, возвращает второй иначе - ничего
| OR Строчно-логическое ИЛИ Если первый операнд не пуст, возвращает его, иначе - второй.
+ SUM Сумма Возвращает числовую сумму аргументов
- SUB Вычитание Возвращает числовую разность аргументов
* MUL Умножение Возвращает числовое произведение аргументов
/ DIV Деление Возвращает первое, деленное на второе
. ON Контекст объекта Вычисляет второй аргумент в контексте объекта, индекс которого задает первый. Если первый операнд не выдал ид объекта, выдает сразу пусто. 

Подробнее о порядке исполнения операций.

  1. Все бинарные операции внутри одного скобочного выражения выполняются обязательно и в заданном порядке, например (X | Y| Z&A) выполняется как ( ((X | Y) | Z) & A ). Т.е. если X не пусто, следующая или операция (...|Z) всё-таки выполняется хотя и очень быстро, т.к. Z не вычисляется.
  2. После любой бинарной операции та же синтаксическая ситуация, как после открытой скобки, т.е. ожидается идентификатор.  Поэтому идентификаторы использующиеся как литералы должны заключаться в кавычки.
  3. Однако числа, написанные без точки и минуса, после знака операции рассматриваются всё же как литералы, а не как позиционные параметры (1) (2)... и их брать в кавычки не обязательно. (X+1) трактуется как (SUM X "1") а не как  (SUM X (1)). Соответственно номера, означающие позиционные параметры всегда, в том числе и в бинарных операциях должны заключаться в скобки.

Использование скобок для выражений.

Замечание. Во всех внутренних выражениях кроме самого первого после открытия скобки разрешается использовать любые из трех видов скобок, в этих случаях семантика использования скобок не различается. Таким образом, макротег (но не оператор!) можно перенести в точности 1:1 из текста макроса внутрь какого-нибудь выражения в качестве параметрического выражения.

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

Программирование на Абрисе 

Порядок вычислений

  • Начало работы. В начале работы программы система сама подает запрос M=_HOME к методу _HOME вне баз данных и без дополнительных параметров. Система ищет метод _НОМЕ на диске в виде файла с именем _HOME.txt. Найдя этот файл, система рассматривает его содержимое как текст макроса для формирования начальной страницы. (Это может быть и обычная страница, но в этом случае система будет работать как обычный броузер).
  • Выбор ссылки на главной странице. В штатном режиме начальная страница _HOME должна содержать ссылки порождающие запросы к системе, для чего в тексте макроса должны присутствовать специальные макротеги, например, типа <#REFER ...>, формирующие специальные абриалевские ссылки. Выбор (щелчок мышью) такой ссылки посылает системе запрос, обращающийся с некоторым методом M к некоторому объекту O некоторой базы данных D. Если D, O или M пропущено используются умолчания как описано выше.
  • Открытие базы данных. Первое обращение к базе данных приводит к её открытию, т.е. считыванию в память; дальнейшие обращения в частности изменяющие, производятся к открытой БД, сохранение измененной БД на диске (полностью или частями) реализуется специальной примитивной операцией SAVE. Список открытых БД в программе Абриаль 2 можно посмотреть на последней вкладке "БАЗЫ ДАННЫХ".
  • Поиск реализации метода. Обращение в запросе с некоторым методом к объекту базы данных производит поиск макроса, реализующего данный метод, в нескольких директориях и в самой базе данных. Используется та реализация, которая будет найдена первой. Порядок обхода директорий и поиска в БД будет подробно описан ниже.
  • Стандартное обрамление страницы. К найденному тексту макроса перед началом его использования присоединяются стандартный пролог и эпилог, находимые независимо по именам _prolog и _epilog аналогично поиску самого метода. Стандартное обрамление не делается для имен методов начинающихся с подчеркивания (например для _HOME). но и для таких методов его можно сделать явно используя операцию включения: <#USE _prolog> в начале и <#USE _epilog> в конце.
  • Текущие БД и объект. Те объект и база данных, что были указаны в запросе становятся текущими перед началом обработки макроса. Это значит, что макротеги в этом макросе, обращающиеся к некоторым методам примитивным или сложным, если явно не указано противное обращаются именно к данному объекту данной базы данных, и кроме того поиск реализаций методов производится по объектно-ориентированной идеологии, т.е. с учетом текущего объекта и его класса.
  • Генерация страницы. Текст макроса, вместе со стандартным обрамлением, если оно есть, просматривается строчка за строчкой, и из него формируется страница на HTML, которая представляется пользователю в броузер для просмотра. В начале текущими являются объект и БД из запроса, по мере исполнения текущие объект, аспект и база данных могут быть установлены в другие значения, специальными операциями/операторами. Поиск всех методов, не определенных прямо в тексте макроса производится по той же схеме, как и главного метода, указанного в запросе.

Переменные

Переменные хранят значения только строчного типа, т.е. строки и тексты или последовательности строк. Размеры значений не ограничены.

Есть два вида переменных локальные и глобальные. Локальные переменные образуются и изменяются операцией SET,  глобальные - операцией GLOB.

(SET n=8 abc="some word") // переменой n присвоено число "8", а переменной abc - строка  "some word"

Если SET заменить на GLOB, образуются или изменятся глобальные переменные с такими именами. Однако рекомендуется с точки зрения стиля, именовать глобальные переменные с заглавной буквы, а локальные переменные только строчными буквами.

Имя операции SET может быть опущено:

(n=8 abc="some word") // эквивалентно предыдущему примеру

Область действия локальной переменной: только текущий вызов функции; при входе, вызове других функций, локальные переменные становятся недоступными, при выходе из функции - теряются.

Именованные (ключевые) параметры вызовов методов превращаются при входе в функцию, реализующую метод, в локальные переменные с теми же именами.

Область действия глобальной переменной - от момента её образования, до момента её удаления.

В версии Абриаля 2.0 набор глобальных переменных привязан к окну броузера: у разных окон наборы глобальных переменных - разные, при закрытии окна - все набор глобальных переменных уничтожается. Вопрос о способе поддержки глобальных переменных для серверной версии, т.е. где они будут храниться, в куках или еще где-то - пока открыт. Операция удаления глобальных переменных пока в версии 2.0 не реализована.

Глобальные переменные могут быть заслонены одноименными локальными переменными.

Агрегатные значения

Значение переменной (как и вообще любое значение, возвращаемое выражением в Абрисе), это либо текстовая строка, либо множество строк (текст). Большинство операций работает с этими значениями, как с единым целым. Однако можно рассматривать текстовые значения как агрегаты, имеющие внутреннюю структуру и работать с элементами этой структуры по отдельности. В Абрисе существует два основных вида агрегатов, а именно: это  списки строк с доступом по номеру (обычные массивы), и записи или словари с доступом по ключу (ассоциативные массивы).

Т.к. терминология пока не устоялась, в дальнейшем тексте слова внутри нижеследующих групп считаются синонимами:

  • Список, список строк, массив, массив строк, текст, текстовое значение.
  • Запись, словарь, ассоциативный массив.
  • Элемент массива, строка, элементарная строка.
  • Имя элемента, ключ, ключ элемента.

Списки

Любое значение в Абрисе это текст, т.е. строка разделенная внутренними знаками перевода строки на список из строк. Абрис позволяет обращаться к элементам этого списка т.е. к элементарным строкам по их порядковому номеру в списке. Например, если значение переменной (S=("ПЕРВАЯ" \ "ВТОРАЯ" \ "ТРЕТЬЯ" \ "ЧЕТВЕРТАЯ") ) состоит из нескольких строк:

ПЕРВАЯ
ВТОРАЯ
ТРЕТЬЯ
ЧЕТВЕРТАЯ

то можно обратиться в выражении (S 3) к третьей строке, что вернет результат ТРЕТЬЯ. Заменить третью строку можно операцией: (S 3 PUT="3-я").

Записи

Записи или ассоциативные массивы состоят из пар Ключ=Значение, упорядоченные по ключу и без повторов ключей. Например, после присваивания: (P=("ИМЯ=ИВАН" \ "ОТЧЕСТВО=ИВАНОВИЧ" \ "ФАМИЛИЯ=ИВАНОВ" ) ) выражение (P "ОТЧЕСТВО") вернет результат ИВАНОВИЧ. Изменить отчество можно операцией (P "ОТЧЕСТВО" PUT="Петрович").

Индексные параметры

Обращаться к структурным частям значений переменных можно с помощью цепочки специальных индексных параметров (аналогичных индексам массивов в традиционных языках). Выражения - индексные параметры должны следовать сразу за именем переменной. Если очередной индексный параметр безымянный, то он, в зависимости от значения, означает либо числовой индекс в обычном массиве (номер в списке, начиная с 1) или идентификатор (ключ) в ассоциативном массиве. Так в приведенных выше примерах, индекс 3 (число) достает третий элемент списка, а индекс  "ОТЧЕСТВО", числом не являющийся, используется как ключ в записи (в ассоциативном массиве).

Вложенные агрегаты. Внутри строки элемента списка или записи в упакованном виде может храниться другой список или другая запись. Поэтому обычные строки в Абрисе могут использоваться как многомерные массивы или многоуровневые записи. Доступ к глубоким элементам этих структур  осуществляется цепочкой индексов, следующей за именем переменной. В разных элементах одного списка данные хранятся независимо, списки, записи и скалярные значения могут произвольно чередоваться. Никакая структурная информация по формату того, что в данный момент лежит в элементе структуры, не сохраняется. Стандартны только методы упаковки/распаковки, но данные, которые кладутся в структуры или извлекаются из них, зависят только от обращения в процессе исполнения. При недостаточном числе индексов будет возвращаться упакованная в строчку структура, а при избыточном числе индексов система будет пытаться распаковать элемент и при неудаче возвратит пустоту. Метод упаковки использует запятые для разделения и двойные "кавычки" для объединения. "Кавычки ""удваиваются"" внутри других кавычек". Для ключей в записях используется знак равенства. Точная спецификация метода упаковки в языке не фиксируется. Программист не должен рассчитывать на её преемственность в следующих версиях, за исключением того, что упакованная в строку структура будет "читабельна".

Каждый очередной индекс в цепочке индексных параметров обращается к значению, полученному на предыдущем шаге от предыдущего параметра. Все параметры кроме последнего являются параметрами чтения, последний же может быть параметром чтения или записи/изменения. Тип параметра задается его именем. Индексные параметры перечислены в следующей таблице.

Имя параметра  Назначение Описание
  Доступ по чтению
NUM=nnn Порядковый индекс в списке (в массиве) Возвращает (распакованную) строчку - элемент списка номер nnn. Нумерация начинается с 1.
KEY=name Ключ для записи (ассоциативного массива) Возвращает (распакованное) значение элемента записи с ключом name. Если name  равно "#", "L#", "C#" - см.ниже. 
отсутствует В зависимости от вычисленного значения параметра эквивалентно NUM=... или KEY=... Если значение параметра - номер, состоящий только из цифр, то отсутствие имени параметра означает индекс в массиве (номер в списке), в противном случае (в том числе для значений #, L#, C#)- эквивалентно параметру KEY.
"#" или "L#" Длина списка (число строк в тексте). Возвращает число строк (элементов списка) в переменной если" #" стоит на первой позиции, или, если параметр встретился на позиции второй и далее, то в элементе, выделенном предыдущими параметрами.
"L#" - эквивалентно "#.
 "С#" (латинское C) Размер строки в байтах. "C#" - эквивалентно "L#, но возвращается размер в байтах, а не в строках.
HAS=name Проверка наличия ключа в записи Возвращает истину, если запись имеет элемент с указанным именем ключа. В отличие от KEY возвращает непустое значение даже при наличии элемента с пустым значением.
  Доступ по записи
PUT=value Запись нового значения value. Новым значением замещается значение для всей переменной или для текущего (т.е. выделенного на предыдущих шагах) элемента.
APP=value Приписывание к старому значению значения value В исходной и добавляемой строке сохраняются переводы строк В месте склейки дополнительного перевода строки не образуется.
DEL={nnn/name} Удаление элемента с заданным именем name или номером nnn. Тип удаляемого элемента (массива или записи) определяется как при отсутствии имени параметра (см. выше). 

Создание списков

Каждое значение в Абрисе фактически представляет собой список строк. Поэтому все функции и операции возвращают списки. Но чтобы создать конкретный заранее известный список можно воспользоваться списком литералов, разделенных литералом новой строки \ например, выражение ( "8" \ 916 \ 555 \ 99 \ 99 ) задает список из пяти членов. Чтобы не вставлять разделителя строк можно для создания списков воспользоваться операцией LIST, которая создает список из упакованных в строки значений своих параметров, например,

chequerboard=(LIST (LIST a1 a2 a3 a4 a5 a6 a7 a8) (LIST b1 b2 b3 b4 b5 b6 b7 b8) ... (LIST h1 h2 h3 h4 h5 h6 h7 h8))

создает в переменной chequerboard двумерный массив имен полей шахматной доски. Выражение (chequerboard 2 3) возвращает b3.

Создание записей.

Записи можно создавать как списки литералов, разделенных знаком новой строки, например:

P=("ИМЯ=ИВАН" \ "ОТЧЕСТВО=ИВАНОВИЧ" \ "ФАМИЛИЯ=ИВАНОВ" ) 

но в этом случае нужно заботиться о правильном порядке ключей и отсутствии дублирования. Более удобна для создания записей операция REC параметры которой группируются парами где первый параметр пары означат ключ (имя) элемента, а второй - значение.

REC n1 v1 n2 v2 n3 v3 ....

Здесь за правильным порядком и отсутствием дублирования ключей в результирующей записи следит система. Например вышеприведенную запись можно создать с помощью операции REC:

P=(REC  "ФАМИЛИЯ" "ИВАНОВ"  "ИМЯ" "ПЕТР" "ОТЧЕСТВО" "ИВАНОВИЧ"   "ИМЯ" "ИВАН") 

произведет структуру:

ИМЯ=ИВАН
ОТЧЕСТВО=ИВАНОВИЧ
ФАМИЛИЯ=ИВАНОВ

Элементы вычисляются последовательно и элемент "ИМЯ=ИВАН" заменит элемент "ИМЯ=ПЕТР".

Псевдопеременные

 Всё множество локальных переменных может рассматриваться как одна псевдопеременная LOCALS, аналогично для глобальных переменных существует GLOBALS, а для параметров вызова страницы - псевдопеременная ENV (от ENVironment). обращения к псевдопеременным позволяют удалять переменные (присваивание пустой строки этого не делают) и работать с переменными с вычисляемыми именами.

(LOCALS DEL=var /* удаляет переменную var */ ; LOCALS (varname) /* возвращает значение переменной, имя которой вычисляет выражение (varname) */ )

Рассмотренные псевдопеременные организованы как записи (ассоциативные массивы) Есть также псевдопеременные RESULT и ERROR организованные как списки (обычные массивы строк, тексты). Например, следующий оператор последовательно обрабатывает все строки 

(FOR (i=1;n=(RESULT "#")) (LE (i) (n)) (ADD i 1) (val=(RESULT (i); /*  обрабатывается строка из RESULT */ ) )

Параметры запроса

Для получения любого параметра из главного запроса внутри странички может быть использована операция ENV:

(ENV имя-параметра )

На самом верхнем уровне т.е. из главного макроса параметры доступны просто по имени, как локальные переменные.

Специальная операция (MACNAME)  выдает имя главного макроса, из которого произведена данная страница.

Объекты базы данных

Идентификация и строчное представление объектов

Язык Абрис Объектно-Ориентированный (ОО), но в отличие от других ОО-языков, где  как правило существуют и активно используются объекты среды исполнения, Абрис работает с постоянными объектами базы данных. Для времени исполнения Абрис допускает только один текстово-строчный тип данных. Следовательно встает вопрос: каким образом объекты представляются в виде строк во время исполнения. Вообще говоря, объект может быть представлен или изображен в следующих текстовых (строчных) формах:

  1. в виде уникального внутри БД числового индекса (идентификатора , ида ), который имеют все объекты, в том числе дескрипторы т.е. классы, отношения, аспекты, правила и т.д.
  2. в виде имени , которое имеют все объекты категории сущностей
  3. в виде значения, которое имеют все объекты категории значений
  4. в виде ссылки которая представляет собой HTML-тег <A HREF=...>...</A>, и которая возможна для любых объектов, но осмысленна для всех объектов кроме значений.
  5. в виде изображения , т.е. некоторого фрагмента HTML-текста отображающее объект, и его свойства, т.е. связи со смежными объектами, представимыми также в одной из перечисляемых здесь форм. В частности, изображением или частью изображения объекта может быть HTML-форма, позволяющая изменять свойства объекта, или  некоторое множество ссылок, кнопок, вызывающих некоторые действия с объектом, и т.д. - в любых комбинациях.
  6. в виде страницы, т.е. наиболее полного варианта изображения .

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

  • либо тройкой: D=имя_файла_базы_данных N=имя_обекта C=имя_класса (D N и C - соответствующие стандартные имена параметров операций)
  • либо парой: D=имя_файла_базы_данных O=ид_обекта (O - соответствующий стандартный параметр операций, для задания ид[ентификатор]а объекта)

Идентификатор (ИД) объекта

В системе Абриаль все объекты имеют уникальные в БД числовые идентификаторы, иды, а все системные понятия, т.е. классы, отношения, аспекты, правила и т.д. представляются объектами дескрипторами. 

Поэтому манипуляции классами и аспектами и т.д. осуществляется через их иды. Следовательно, если функция должна возвращать объект, или должна иметь объект в качестве параметра, то на самом деле возвращается или передается не объект, а ид объекта в строчном виде. Если ид представлен пустой строкой или равен 0, это значит, что объект фактически не задан, или на выходе функции не возвращен (например - не найден). Однако, если объект на входе операции вообще не задан - вместо него, возможно, будет взят по умолчанию текущий объект, но если задан нулевой или пустой ид - умолчание не действует. Таким образом, отсутствие объекта на входе не всегда эквивалентно недействительному или пустому иду объекта.

<#REFER M=Disp> -- здесь ссылка на метод Disp, примененный к текущему объекту текущей БД<BR>
<#REFER M=Disp O=0> -- здесь ссылка просто на метод Disp без привязки к какому-либо объекту

Текущие БД, объект, аспект

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

Текущий объект используется не только для примитивных операций но и при поиске реализаций запрограммированных методов.

Аппарат вызова функций

Функции и макросы

Функции и макросы могут быть определены в исходном тексте, а не только находятся на диске.

Определение функций.

Функции определяются операцией FUNC. одна операция FUNC может определить множество функций.

<#FUNC Fname1=FunctionBody1 Fname2=FunctionBody2 ... >

Например, определим функции максимума и минимума для чисел и для строк.

<#FUNC
       Max=(GT (1) (2) (1) (2))
       Min=(IF (GT (1) (2)) (2) (1)) 
       MaxS=(AFT (1) (2) (1) (2))
       MinS=(AFT (1) (2) (2) (1)) 
>

Тогда (Max 20 100) вернет 100, а  (MaxS 20 100) вернет 20.

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

Определение макросов

Макросы определяются оператором MACRO. Один оператор определяет ровно один макрос.

<#MACRO ИмяМакроса>
.....Здесь следует текст макроса.....
.......
<#/> 

Обращения к методам, параметры методов

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

Практически, именованные (или ключевые) параметры нужны для представления необязательных параметров и свойств функций и операций. За счет именованных параметров одна и та же реализация метода может обеспечить большое разнообразие поведения, а также - постепенное развитие причем, без необходимости полного знания программистом всех деталей обращения к функции, как это неизбежно для более традиционных позиционных параметров. Так например, в Си и Паскале, чтобы пользоваться функцией, необходимо изучить все её параметры и все варианты их задания. С другой стороны, в HTML почти все теги имеют большое количество параметров, которые чаще всего бывают не нужны, и пользователь HTML чаще всего даже не знает о их существовании, пока в них не возникает надобность. Абрис, позволяя использовать обе разновидности параметров, объединяет достоинства обоих подходов: гибкость HTML и лаконичность Си.

Для обращения к позиционным параметрам внутри функции используется нотация - номер параметра в скобках, т.е. (1)  для первого (2) для второго и т.д. В тексте макроса скобки должны быть соответственно макросные: <#1>, <#2> и т.д.

К именованным (ключевым) параметрам внутри функции нужно обращаться как к локальным переменным по их имени в скобках. Фактически они и реализованы как локальные переменные, инициализируемые при входе в функцию.

Для придания имен позиционным параметрам используется операция (PARAM name1 name2 ...) с позиционными параметрами задающими имена для соответствующих позиций.

Для присваивания значений по умолчанию именованным параметрам используется операция (PARAM name1=val1 name2=val2 ...) с именованными параметрами, задающими значения для соответствующих имен.

<#FUNC
       Function1=("Значение параметра №1=" (1) ", параметра №2=" (2) "!"))
       Function2=("Значение параметра Abc=" (Abc) ", параметра Cde=" (Cde) "!"))
       Function3=((PARAM first second) "Значение параметров: №1=" (first) ", №2=" (second) "!"))
       Function4=((PARAM x=111 y=222) "Значение параметров: x=" (x) ", y=" (y) "!"))
>
<#  
    (Function1 qwerty asdfg) // возвращает:Значение параметра №1=qwerty, параметра №2=asdfg!
    (Function2 Abc=123 Cde=456) // возвращает:Значение параметра Abc=123, параметра Cde=456!
    (Function3 qwerty asdfg) // возвращает:Значение параметров: №1=qwerty, №2=asdfg!
    (Function4 x=123)        // возвращает:Значение параметров: x=123, y=222!
    (Function4 y=789)        // возвращает:Значение параметров: x=111, y=789!
    (Function4)              // возвращает:Значение параметров: x=111, y=222!
>

Включения, примитив USE

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

(USE имя_библиотечного_макроса )

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

Объектно-ориентированный подход при поиске реализации метода

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

Это реализуется следующим образом. Допустим, вызывается метод Foo при текущем объекте с именем Nam из класса Cla. Причем, класс Cla происходит от классов Base1 и Base2 а класс Base1 - от класса Super. Тогда, вообще говоря, поиск реализации осуществляется в таком порядке:

  1. Ищем Cla_Nam_Foo если нашли, выполняем, иначе 
  2. Ищем Cla_Foo если нашли, выполняем, иначе
  3. Ищем Base1_Foo если нашли, выполняем, иначе
  4. Ищем Super_Foo если нашли, выполняем, иначе
  5. Ищем Base2_Foo если нашли, выполняем, иначе
  6. Ищем Foo если нашли, выполняем.

Если найдена реализация метода, то она и выполняется, а метод больше не ищется. Т.е. специальная реализация метода для конкретного объекта загораживает более общую реализацию этого метода для класса, а реализация для класса загораживает самую общую (универсальную) реализацию метода.

<#FUNC
    Speak="Silence..." 
    Аnimal_Speak="I don't know how I must Speak"
    Dog_Speak=Hau_Hau
    Cat_Speak=Miaou
    Bird_Speak=Chirik
    Parrot_Speak=(OR(1) (Bird_Speak))
    Cat_Barsik_Speak="Waooooo!"
    Dog_Mumu_Speak=Bulk
>
<#  // function call             // returns (comments)
  (Speak)                       // Silence...
  (ON (OBJ Murka  Cat) (Speak)) //  Miaou (as all Cats)
  (ON (OBJ Kuzia  Cat) (Speak)) //  Miaou (as all Cats)
  (ON (OBJ Barsik Cat) (Speak)) //  Waooooo! (only Barsik can say)
  (ON (OBJ Popka Parrot) (Speak) ) //  Chirik (as all birds, since no question)
  (ON (OBJ Popka Parrot) (Speak Please)) //  Please 
  (ON (OBJ Gena Croc)  (Speak)) // I don't know how I must Speak (no special method for crocs)
  (ON (OBJ Sharik Dog) (Speak)) // Hau_Hau (as normal dog says)
  (ON (OBJ Mumu Dog) (Speak))   // Bulk (special sound)
  (ON (OBJ Volga River) (Speak))// Silence... (Volga is not an animal)
>

Порядок поиска реализации метода

Общий порядок поиска реализации имени foo для выражения (foo ....) или тега <#foo ...>

Ищем  foo ...

  1. ... среди примитивных операций и операторов
  2. ... среди локальных переменных (и именованных параметров)
  3. ... среди глобальных переменных
  4. ... в определениях функций и макросов выше по тексту, каждое имя: (foo и производные/объектные имена) ищется начиная от самой глубокой вызывающей функции выше - до вызова главного макроса.
  5. ... внутри текущей базы данных
  6. ... в библиотечных директориях 

Далее уточняется, как производится поиск внутри перечисленных пунктов.

Поиск в динамических определениях (в тексте программы).

Используются определения функций и макросов (операторами MACRO и FUNC) выше текущей точки исполнения в текущей и потом - в вызывающих функциях, начиная от самой глубокой, до самого высшего уровня. На одном уровне самое последнее определение с искомым именем имеет силу. Поиск происходит по ОО-процедуре. Сначала реализации для данного объекта, затем для класса объекта, затем для всех старших классов по порядку (каждый из старших классов обрабатывается до конца, т.е. перебор типа "сначала вглубь", затем ищется универсальная реализация метода - для собственно имени метода. 

Для каждого очередного составного имени поиск производится до самого верху и потом только берется следующее имя. Таким образом, если Cla_Foo будет определена на самом верхнем вызове а Foo - в текущей функции, то будет использоваться реализация с именем Cla_Foo.

Если не установлены текущая БД или текущий объект, ищется только само имя метода, без производных имен.

Поиск макроса внутри текущей БД.

Если не установлены текущая БД или текущий объект, данный вид поиска пропускается. 

Макросы в БД хранятся в виде объектов класса MACRO, которые имеют текстовый (строковый) атрибут "MACRO\MACRO", значением  которого является тело макроса. Таким образом, множество объектов класса MACRO представляют собой библиотеку макросов.

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

Поиск реализаций методов в директориях.

После неудачи поиска имени и его объектно-ориентированных производных в памяти и в БД - в последнюю очередь метод ищется на диске в нескольких специальных директориях:

Допустим, вызывается метод Foo при текущем объекте с именем Nam из класса Cla. Причем, класс Cla происходит от классов Base1 и Base2 а класс Base1 - от класса Super. Порядок полного поиска имени name в директориях (где поочередно name=Cla_Nam_Foo, Cla_Foo, Base1_Foo, Super_Foo, Base2_Foo, Foo):

Для каждого варианта name реализация ищется в следующих файлах.

      currpath\name.HTM  
      currpath\name.TXT 
   ?  dbpath\dbname.TEM\name.HTM  
   ?  dbpath\dbname.TEM\name.TXT 
   ?  dbpath\name.HTM  
   ?  dbpath\name.TXT 
   ?  dbpath\TEM\dbname.TEM\name.HTM  
   ?  dbpath\TEM\dbname.TEM\name.TXT 
   ?  dbpath\TEM\name.HTM  
   ?  dbpath\TEM\name.TXT 
   ?  exepath\dbname.TEM\name.HTM  
   ?  exepath\dbname.TEM\name.TXT 
      exepath\name.HTM  
      exepath\name.TXT 
   ?  exepath\TEM\dbname.TEM\name.HTM  
   ?  exepath\TEM\dbname.TEM\name.TXT 
      exepath\TEM\name.HTM  
      exepath\TEM\name.TXT 
 
   ? -- поиск только при наличии открытой (текущей) БД

где

  • name - искомое имя метода или производное от него: 
    • name=Cla_Nam_Foo, Cla_Foo, Base1_Foo, Super_Foo, Base2_Foo, Foo
  • currpath - текущей (если она не совпадает с exepath, иначе - пропускается)
  • dbpath -  папка, где находится текущая БД (? - если есть открытая БД)
  • exepath -  папка, где находится исполняемый exe-файл программы Абриаль.
  • dbname - имя файла текущей БД без расширения

Глобальные команды

Существует ряд команд, которые вызываются как методы запроса, например так: <#REFER _BACK  "Назад" > но не являются ни запрограммированными макросами ни примитивными операциями: эти команды касаются самого интерфейса пользователя и стоят, таким образом, особняком от других примитивов, обращения к которым могут вставляться внутрь генерируемой страницы. Например команду _BACK, приводящую к возврату броузера Абриаля на шаг назад нет смысла вставлять внутрь генерируемого текста. но эта команда может быть в запросе, так что пользователь может её вызвать нажав на определенную кнопку/ссылку на странице. Команды для текущей версии:

  • _BACK - делает один шаг навигации назад: если это был просмотр обычной страницы броузера, например какого-то сайта, то шаг назад делается в точности как в броузере (страница берется из кеша), если же это была страница сгенерированная Абрисом, то страничка генерируется заново с тем же запросом.
  • _FORWARD - аналогично _BACK но шаг вперед (возврат на шаг вперед после возврата назад). Действует то же, как для _BACK разделение операций обычного и эмулированного броузера.
  • _REFRESH - обновляет текущую страницу, т.е. повторяет тот же запрос, который привел к генерации данной страницы. (полезно при разработке: можно изменить макрос и вызывать данную функцию).
  • _LOAD - догружает в текущую (открытую ранее) БД текст кода из некоторого файла (если процесс загрузки начинается, предлагается диалог выбора файла, если процесс был приостановлен,
  • _SAVE - сохранить текущую базу данных в её исходном файле.
  • _SAVEMEM - сохранить текущую базу данных в заданном пользователем двоичном файле (образа памяти).
  • _SAVETXT - сохранить текущую базу данных в заданном пользователем текстовом файле.
  • _LOADMEM - загрузить новую базу данных, ранее сохраненную в файле образа памяти.
  • _NEW - Создает новую базу данных с заданным пользователем именем, и по заданной пользователю базе-прототипу.
  • _OPEN - Открывает БД из заданного файла, если эта БД была открыта ранее, просто переключает просмотр на неё.

Команды, работающие с базой данных следует отличать от одноименных операций: команды не являются примитивами языка, и работают только в запросах, но не в генерируемом тексте. Но в запросах имена команд являются более приоритетными. Поэтому если в запросе встретится _OPEN будет исполняться команда, а не операция.

Примитивы языка Абрис

Операции с базами данных

Способы обращения к объектам базы данных

Способы работы с БД варьируются в трех измерениях, содержащих по два варианта каждое:

  1. Просмотр (навигация) vs. изменение. Вообще говоря, обращаться к базе данных можно двумя способами: во-первых считывать объекты и их связи визуализируя эту информацию на отображаемой пользователю станице в виде текстов и/или навигационных ссылок, и во-вторых - изменять информацию в базе данных, т.е. добавлять в неё или удалять из неё объекты и связи и/или изменять текстовые значения внутри объектов-значений.
  2. Навигационный метод (M=...) vs. действие (ACT=...). Можно использовать запросы двух типов: при запросе навигационном, изменяется текущая точка в базе данных. При запросе через действие срабатывает некоторый метод-действие, но точка навигации после этого отображается неизменная.
  3. HTML-ссылка (http метод GET) vs. HTML-форма (http метод POST). С точки зрения HTML запрос может инициализироваться либо выбором некоторой ссылки, либо, после изменения некоторых данных в форме нажатием некоторой кнопки в форме такого примерно вида: . В первом случае в запрос поступают данные из ссылки, во втором - из элементов формы.

Все восемь сочетаний этих альтернатив теоретически могут работать, но на практике используются не все комбинации вариантов, а лишь некоторые:

  • Навигация чаще осуществляется через методы (а не действия) и чаще через ссылку чем через форму, однако в некоторых случаях когда например нужно найти объект задаваемый пользователем, а не предусмотренный на странице заранее, для ввода навигационных данных могут использоваться и формы.
  • Изменение целесообразно производить через действия и чаще всего изменение требует от пользователя ввода (через форму) данных, которые нельзя было заранее предусмотреть на странице, хотя могут быть и предусмотренные заранее изменяющие действия, которые можно задавать в форме ссылки.

Рассмотрим все эти случаи и варианты по отдельности.

Просмотр и навигация по базе данных

Для просмотра базы данных используются следующие операции и операторы:

  • REFER - выдает ссылку на текущий (REFER) или заданный (REFER O=ObjId ) объект
  • NAME - Выдает имя или текстовое значение объекта
  • ASP - Выдает ссылку или значение некоторого атрибута объекта (атрибут - это одиночный бинарный аспект объекта; на другом конце такой связи находится ровно один объект, называемый значением атрибута).
  • ASPECT - выдает стандартное изображение аспекта объекта либо в виде одиночного значения или ссылки или в виде списка, таблички. (в силу жесткого формата используется для отладки)
  • AT - переход от объекта к объекту по одиночной связи - аналогичен ASP, но вместо ссылки или значения выдает ид объекта
  • OBJ - выдает ид объекта - текущего (OBJ) или с заданным именем и классом (OBJ ObjName ClassName )
  • ON, FOROBJ - установка текущего объекта (ON obj body ) - как операция, <#FOROBJ obj>body <#/>- как оператор.
  • OBJFORM - используемая для отладки стандартная табличка с изображением всех связей объекта.
  • FOR... - группа операторов цикла для обхода классов, аспектов объекта, и связей для множественных и списочных аспектов объектов.

Изменения в базе данных

Операции, изменяющие базу данных могут вызваться двумя способами: 

  1. Как обычные операции в тексте некоторого сложного макроса, выполняющего действие ACT=Action_Macros_Name (или в любом макросе т.е. не макросе действия, но последнее не типично).
  2. Как самостоятельное действие, в этом случае имя операции указывается как имя действия и его параметры указываются в запросе (в ссылке или в POST-данных).

Например, внутри теста макроса может быть операция связывания двух объектов, задаваемых переменными,  (father) (son)  связью типа Parent:

<#_LINK R="Parent" O1=(father) O2=(son)>

Но такую же операцию как цельное действие можно инициировать ссылкой:

<#REFER  ACT=_LINK   R="Parent" O1=(father) O2=(son) ("Make "(NAME(father)) " parent for " (NAME(son)) "!" )  >

Ссылка в тексте странички будет выглядеть примерно так: Make Pavel parent for Nikolay!

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

Основные операции изменяющие базу данных

  • _BLNK Добавление или изменение бинарной связи.
  • _DELA Удаление аспекта объекта.
  • _DELK Удаление одной связи объекта.
  • _DELI Удаление объекта.
  • _EDIT Добавление или изменение текстового значения атрибута объекта.
  • _LINK Добавление или изменение связи (события) любой размерности.
  • _NITM  Добавление нового объекта
  • _TEXT Изменение значения объекта.
  • _SWAP Переключение унарный аспект. (Создать унарную связь объекта, если ее не было, или удалить, если она была) .

Обращение к базе данных через HTML-ссылку

Ссылки в форме A-тега используются в тех случаях, когда задаваемая в запросе пользователя информация известна заранее, еще при генерации страницы. 

Ссылочные теги генерируются следующими примитивами: операциями REFER, ASP, оператором HREF. Собственно ссылка без тега генерируется: ROOTREF, URL, или _HREF; структуры, потенциально содержащие много ссылок выдают: ASPECT, OBJFORM.

Обращение к базе данных через HTML-форму

Данные в HTML-формах используются в тех случаях, когда в запросе пользователя должна быть информация не известная заранее, при генерации страницы. Она задается пользователем либо в виде текста либо выбором из альтернатив или пометкой признаков. Форма для пользователя генерируется в основном на низком уровне за счет HTML-средств, например так для связывания текущего объекта (OBJ) с отношением (relat) с представителем класса Person. Направление связи задается переменными (from) и (to). Если связь прямая, Relname(текущий-объект,выбираемый ), то from=O1 и to=O2 для обратного направления (Relname(выбираемый,текущий-объект ),) наоборот: from=O2 и  to=O1.

Данная форма для пользователя будет представлена примерно в таком виде:

А в тексте макроса задается кодом:

<FORM action="<#URL ACT=_LINK R=(relat)>" method=post>
<input type=hidden name=(from) value=(OBJ)>
<SELECT name=(to)>
<OPTION value=0> -- Выбрать здесь -- </OPTION>
 <#FORALLOBJ "NAME\ITEMS" O=(OBJ Person CLASS)>
  <OPTION value=<#OBJ>><#NAME></OPTION>
 <#/>
</SELECT>
<input type=submit value='Создать связь!'>
</form>

Рассмотрим эту форму по порядку. В первом теге FORM записано HTML-действие (action) в виде макротега <#URL ACT=_LINK R=(relat) > генерирующего ссылку с запросом на действие, содержащее заранее известные параметры действия, т.е. имя действия ACT и имя отношения R.

Остальные параметры запроса содержатся внутри формы, а именно: следующая строка содержит тег для скрытого поля  <input type=hidden...>, имя которого (from) переменно, т.е равно либо O1 либо O2, а значение - ид текущего объекта. 

Далее следует сложный тег SELECT, создающий поле выбора значения для имени (to) равному O1 либо O2. Внутри тега выбора находятся несколько тегов опций выбора (OPTION), первая из которых - холостая опция "Выбрать здесь" - которой приписано нулевое (т.е. никакое) значение ида объекта. Остальные опции выбора генерируются оператором цикла, обходящим все представители класса Person, т.е. объекты соответствующие людям. В итоге поле выбора позволяет выбрать элемент связи O2 среди всех "людей" в базе данных. 

Следующий за тегом SELECT тег <input type=submit...> задает кнопку для запуска запроса. После выбора этой кнопки  страница будет обновлена, но перед этим обновлением будет проделано действие Абриса, имя и параметры которого определяются из ссылки в заголовке формы, с добавлением так называемых POST-данных из элементов формы.

POST-данные - это множество пар вида Имя=Значение (Name=Value), в которых именам полей формы сопоставляются значения, заданные пользователем в форме или приписанные им по умолчанию в видимых или скрытых полях формы.

В данном примере POST-данные для имен O1 и O2 задают теги  <input type=hidden...> и  <SELECT...>. Они вносят в запрос  элементы вида: ...O1=1234&O2=4567.... Полностью параметры запроса складываются из ссылки в заголовке формы и из POST-данных, что для данного примера эквивалентно примитивной операции:

<#_LINK R=Parent O1=1234 O2=4567 D=data_base_file >

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

Навигация или действие?

Признаком, отличающим запрос-действия от навигационного запроса является наличие параметра ACT с непустым значением, задающим примитивное действие или метод-действие. Если в запросе есть параметр ACT (неважно откуда - из ссылки или из POST-даных), то сначала выполняется действие и его результат помещается в переменную RESULT, а затем повторяется в точности тот же предыдущий навигационный запрос, что и привел к отображению странички, т.е. страничка для пользователя обновляется. При этом в отображении странички в любом месте может быть предусмотрено отображение содержимого RESULT. Его можно показывать всегда, т.к. при отсутствии действия переменная RESULT бывает пуста. Её содержимое действительно только на данном шаге, перед обработкой очередного запроса RESULT очищается.

Операции со всей базой данных

Группа операций с целой базой данных.

  • _LOAD, LOAD - догрузить в  БД текст кода из некоторого файла или из непосредственно заданного текста
  • _NEW, NEW - Создает новую базу данных с заданным именем, и по заданной базе-прототипу.
  • _OPEN, OPEN - Открывает БД из заданного файла.
  • _SAVE, SAVE - Сохранить базу данных полностью или частично в файле. В отличие от других операций данной группы позволяет сохранять в файле часть данных, объекты или связи.
  • CODE - аналогично SAVE, но текст DDL-кода из базы данных возвращается в виде результата операции, а не записывается в файл.

Комбинация CODE+FILESAVE/FILEAPPEND позволяет записывать в файл код базы данных частями.

Строчные операции

Строки в Абрисе - это единственно допустимый тип данных. Строкой мы называем либо простую строка, не содержащая внутри себя никаких невидимых символов кроме пробела, либо множество (последовательность) строк, называемое в данной инструкции текстом. Для обработки строк используются следующие операции

  • APP - наращивание значения переменной
  • ASLITERAL - преобразование текста в вид литерала JavaScript
  • TEXT - конкатенация
  • CAT - конкатенирующее преобразование текстов в строчку
  • (FIND стр1 стр2 ) - нахождение в строке стр1 позиции подстроки стр2  
  • LEN - длина строки, заданной аргументом
  • (SUBSTR стр поз длн ) - выделение подстроки из стр длиной длн начиная с позиции поз  
  • CONV - различные виды преобразований текстов и строк
  • (CONV MATCH=стр MASK=маска ) - проверяет в строках, составляющих стр соответствие маске (образцу) маска .

Операция APP стоит особняком, т.к. она работает не как функция, выдающая некое значение, а как процедура, производящая побочный эффект. А именно: она прицепляет к (локальной) переменной, имя которой задано первым аргументом - текст, заданный вторым аргументом.

TEXT - это по сути самая главная и важная операция языка, поэтому если операция пропущена именно TEXT  подразумевается по умолчанию, операция TEXT выдает объединенное значение сцепленное из своих аргументов.

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

FIND, LEN, SUBSTR - достаточно типичные операции чтобы на них останавливаться.

CONV - операция, проделывающая множество типов преобразования строк/текстов, причем тип преобразования задается именем параметра а исходный текст - значением этого параметра. Важно отметить, что если исходный текст состоит из нескольких строк, преобразование проделывается с каждой из составляющих строк по отдельности.

Арифметические операции

Арифметические операции с числами производятся на их строчными представлениями. Если строка не содержит числа то её числовое значение воспринимается как ноль. Целые от дробных (вещественных) чисел отличаются только наличием точек, отделяющим дробную часть. При записи в виде литералов дробные числа лучше брать в кавычки, чтобы они не были спутаны с обращениями к параметрам. Основные арифметические операции:

  • SUM сумма значений аргументов
  • (ADD перем знач ) добавление значения знач к значению переменной перем
  • (SUB n1 n2) вычитание n2 из n1
  • MUL умножение значений аргументов
  • (DIV n1 n2 ) деление n1 на n2
  • NEG отрицание

Операция ADD стоит особняком, т.к. она работает не как функция, выдающая некое значение, а как процедура, производящая побочный эффект. А именно: она прибавляет к значению (локальной) переменной, имя которой задано первым аргументом - число, заданное вторым аргументом.

Логические операции

Логические значения представляются в виде строк следующим образом: пустая строка представляет FALSE (Ложь). Любая непустая строка представляет TRUE (ИСТИНА). Стандартное значение для TRUE - знак пробела. Это позволяет реализовать несколько обобщенное понимание логических операций в Абрисе.

Операция OR (ИЛИ) выдает первое истинное, т.е. непустое значение среди всех своих аргументов, или пустоту (ЛОЖЬ) если все аргументы ложны (пусты).

Операция AND (И) последовательно проверяет значение своих аргументов и если один из них окажется ложным (пустым) выдает пустоту (ложь). Если же все аргументы не пусты, AND выдает значение самого последнего.

Операция NOT выдает пустое значение (ложь) если его аргумент непуст, и стандартную ИСТИНУ т.е. пробел, если аргумента нет или его значение пусто.

Таким образом, логическими операциями AND и OR можно пользоваться вместо условных операторов.

Операции с целыми файлами

Операции с файлами позволяют читать и писать содержание текстовых файлов. Чтение осуществляется только целиком. Записывать данные в файл можно частями.

  • (FILELOAD файл) - возвращает содержимое заданного файла
  • (FILESAVE файл текст ) - замещает содержимое файла 
  • (FILEAPPEND файл  текст )
  • (FILEEXIST файл ) - (именно так, не EXISTS:) проверка что файл с заданным именем существует в случае существования выдает это имя, иначе - ничего не выдает.
  • (FILEPATH опция =путь ) - проделывает различные операции с именами файлов и директорий операция задается именем параметра опция, значение путь задает исходное имя.

Операции с файлами (отдельными записями)

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

Разновидности файлов

Тип файла указывается в операции открытия именем первого ключевого парамтера:

  • (FILE IN=fid  FROM=path) - открытие входного файла на чтение
  • (FILE OUT=fid TO=path) - открытие выводного файла на запись (создание)
  • (FILE APP=fid  TO=path) - открытие выводного файла на дописывание в конец
  • (FILE LIST=fid  PATH=path) - открытие текстового файла с произвольным доступом для чтения/записи
  • (FILE LIST=fid ) - открытие временного текстового массива в памяти
  • (FILE REC=fid  PATH=path) - открытие ключевого файла (состоящего из пар Ключ=Значение) для чтения/записи
  • (FILE REC=fid ) - открытие временного ассоциативного массива в памяти
  • (FILE NDX=fid  PATH=path) - открытие индексного файла (состоящего из пар Ключ=целое-число) для чтения/записи
  • (FILE NDX=fid ) - открытие временного индексного массива в памяти

Идентификатор файла

Для идентификации открытых файлов используются специальные глобально видимые имена, идентификаторы файлов. Идентификатор файла всегда указывается в первом по порядку параметре операции FILE. Т.к. параметр может при необходимости как литерал браться в кавычки, для идентификаторов позволено использовать больший набор символов, чем для переменных, идентификатор не должен включать символа "=" и начинаться или оканчиваться пробелом. Для входных и выходных последовательных файлов в качестве идентификатора может использоваться путь, но с условием, что при всех обращениях к одному файлу этот путь записывается одинаково, включая регистр букв.

Входные файлы

Входной файл открывается операцией:(FILE IN=fid FROM="filename.ext"). Если путь в FROM не указан, то в качестве имени файла берется его идентификатор fid. Записи входного файла (строки текста) читаются операцией  (FILE GET=fid). Конец входного файла проверяется операцией:(FILE EOF=fid), возвращающей непусто, если файл прочитан или чтение невозможно по любой причине. Входные файлы целесообразно закрывать после прочтения операцией:  (FILE CLOSE=fid)

Выводные файлы

Выводной файл открывается на запись операцией: (FILE OUT=fid TO="filename.ext") и на дописывание - операцией  (FILE APP=fid TO="filename.ext"). Если путь в TO не указан, то в качестве имени файла берется его идентификатор fid. Очередная строка текста в выводной файла записывается операцией  (FILE fid PUT=value). Выводные файлы необходимо закрывать после полного записывания операцией:  (FILE CLOSE=fid).

Списочные файлы

Списочный (текстовый с произвольным доступом) файл открывается операцией: (FILE LIST=fid ...). Если файл нужно взять из уже существующего, то используется параметр открытия FROM=путь Если файл при закрытии необходимо автоматически сохранить, используется параметр открытия TO=путь Если входной и выходной файлы совпадают, вместо двух параметров можно использовать один: PATH=путь

Обращение к i-й строке списочного файла осуществляется операциями: (FILE fid NUM=(i)) для чтения и (FILE fid NUM=(i) PUT=(newvalue)) для записи. Вообще, для списочных файлов применимо обращение (FILE fid индексные-параметры)), где индексные-параметры те же, что используются при доступе к структурным значениям переменных. (см. раздел Индексные параметры).

При закрытии файла операцией: (FILE CLOSE=fid) файл автоматически сохраняется, если для него при открытии был указан путь сохранения (параметром PATH или TO). Для сохранения без закрытия используется операция (FILE SAVE=fid) или (FILE fid SAVETO=путь), последнее для записи в файл с новым именем. Для закрытия файла без сохранения используется операция (FILE DEL=fid).

Ключевые файлы

Словарный (ключевой, состоящий из пар Ключ=Значение с уникальными ключами) файл открывается операцией: (FILE REC=fid ...). Если файл нужно прочесть из уже существующего, то используется параметр открытия FROM=путь. Если файл при закрытии необходимо автоматически сохранить, используется параметр открытия TO=путь Если исходный и результирующий файлы совпадают, вместо двух параметров можно использовать один: PATH=путь

Обращение к записи словарного файла с ключом в переменной key осуществляется операциями: (FILE fid KEY=(key)) для чтения и (FILE fid KEY=(key) PUT=(newvalue)) для записи. Вообще, для этих файлов применимо обращение (FILE fid индексные-параметры)), где индексные-параметры те же, что используются при доступе к структурным значениям переменных. (см. раздел Индексные параметры).

При закрытии файла операцией: (FILE CLOSE=fid) файл автоматически сохраняется, если для него при открытии был указан путь сохранения (параметром PATH или TO). Для сохранения без закрытия используется операция (FILE SAVE=fid) или (FILE fid SAVETO=путь), последнее для записи в файл с новым именем. Для закрытия файла без сохранения используется операция (FILE DEL=fid).

Индексные файлы

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

 

Операции сравнения

  • IS строчное равно
  • BEF строчное менее (BEFORE)
  • AFT строчное более (AFTER)
  • NB строчное не менее
  • NA строчное не более
  • NI строчное не равно
  • LT числовое менее
  • GT числовое более
  • LE числовое не более
  • GE числовое не менее
  • EQ числовое равно
  • NE числовое не равно

Операции сравнения делятся на числовые и строковые. Числовое сравнение "2" < "10" а строковое:  "2" > "10". Числовое 100 = 00100 но как строки они различаются. Смысл операции значительно более общий чем для обычных операций сравнения в языках программирования. Семантика операций сравнения зависит от количества аргументов, и только при двух аргументах смысл тот же, что обычно:

  • Обычно операции сравнения сравнивают два операнда. При успехе сравнения возвращается логическая истина, стандартно обозначаемая символом пробел.( Любая непустая строка представляет истину, а пустая - ложь. )
  • Если аргумента три или четыре, то третий аргумент задает представление истины (успеха) операции, а четвертый - представление неуспеха, т.е. как бы - действие по умолчанию.
  • Если аргументов более четырех, и нечетное число, то значение первого аргумента поочередно сравнивается со вторым и далее, со всеми четными аргументами и при первом успехе возвращается значение очередного нечетного аргумента.
  • Если аргументов четное число более трех, то всё происходит как в прошлом варианте, но с добавлением возврата последнего значения по умолчанию, если все предыдущие сравнения оказались неуспешными.

Примеры:

<# (IS (SUBSTR(X)1 1) Y)  // возвращает пробел, если значение переменной Х начинается с Y
  (IS (opt) Y (func1) N (func2) y (func1) n (func2) "ДА" (func1) "HET" (func2)  
    ) // вызвывет func1 при значениях Y,y,ДА, и func2 - при значениях N,n,НЕТ 
   (LT (p) 0 Negative // разделяет диапазон изменения p на три части: менее 0,
           1 Portion  // от 0 до 1
             Large )  // и больше или равно 1
 >
 

Условные операторы

Кроме операций сравнения, которые как видно выше, обобщены до условных операций, есть более традиционные условные  операторы:

  • IF условный оператор ЕСЛИ.
  • IFNOT условный оператор ЕСЛИ HET
  • COND множественная условная развилка.

Операторы IF и IFNOT проверяют некоторое условие и выполняют (возвращая значение) свое тело и/или второй аргумент при выполнении для IF или невыполнении для IFNOT этого условия (Выполнением считается, когда возвращена Истина, т.е. непустое значение). Когда оператор IF (IFNOT) задается в макроформе, то тело определяется до закрывающего тега <#/>. Внутри тела в этом случае может присутствовать разделительный макротег <#ELSE> который ничего не возвращает, но после него записана альтернативная часть тела оператора, которая выполняется, если не выполняется основная часть тела - до  <#ELSE>

<#IF (condition)> 
   здесь идут строчки, выполняемые при успехе условия (condition)
<#ELSE>
 
   а это выполняется при неуспехе
условия (condition)
<#/>

Операция COND, в отличие от IF это именно операция, а не оператор, проверяет множество условий задаваемых нечетными аргументами и при успехе одного из них возвращает значение следующего по порядку четного аргумента. В случае неуспеха всех условий может быть возвращено значение последнего нечетного (непарного) аргумента, если таковой имеется.

(COND (IsANumber) (ShowNumber) (IsAString) (ShowStr)  (IsARef) (REFER) (ErrorMsg))

Операторы цикла

Операторы цикла делятся на две группы:

  1. Классические циклы: FOR и WHILE,:
    • FOR имеет три выражения в качестве аргументов: для инициализации, проверки условия и итерации.
    • WHILE - проще: он только проверяет условие цикла.
  2. Операторы для сканирования (обходов внутри) базы данных:
    • FORALLASP - Цикл по всем аспектам объекта. Обходит все аспекты, назначенные классу данного объекта с учетом наследования.
    • FORALLOBJ - Цикл по всем объектам - значениям атрибута. Обходит все объекты, являющиеся значениями бинарного аспекта для некоторого объекта, т.е. все объекты находящиеся на противоположных сторонах связей.
    • FORASP - Цикл по всем связям аспекта. Обходит все связи любого, не обязательно бинарного аспекта, давая возможность на каждом шаге обращаться (с помощью AT TO=) ко всем объектам данных связей.
    • FORCLASSES - Цикл по всем классам БД. Поочередно обходит все классы данной базы данных, минуя системные.
    • FORNEMPASP - Цикл по всем непустым аспектам объекта. В отличие от  обходит не теоретически допустимые, а фактически присутствующие аспекты некоторого объекта.

Все операторы цикла имеют внутри себя тело, которое определяется либо закрывающим тегом <#/>, либо является последним (безымянным!) аргументом оператора (заголовка).

Порции внутри цикла

Часто возникает потребность расположить результаты, выдаваемые некоторым циклом, в виде таблицы (на языке HTML) или аналогичной регулярной структуры. В этих случаях поток текста, выводимый оператором цикла, делится на порции. Формально оператор порции PORTION вставляется внутрь тела оператора цикла:

<#FOR...> заголовок порции <#PORTION размер >тело порции=шаг цикла<#/>завершение порции <#/>

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

Например, если мы имеем класс Месяцы состоящий из 12-ти объектов, то обойти этот класс и изобразить его в виде таблицы из трех столбцов по пять ячеек (мы намерено делаем форму некратной содержанию) можно следующим образом:

<TABLE border=2 width="100%">
 <#FORALLOBJ "NAME\ITEMS" N="Месяцы" C=CLASS>
    <TR>
    <#PORTION 3>
      <TD valign=top> <TABLE>
        <#PORTION 5> 
          <TR><TD><#GT (OBJ) 0 (REFER) "&nbsp;"> 
        <#/>
      </TABLE></TD>
    <#/>
    </TR>
 <#/>
</TABLE>

В результате должна получиться примерно такая таблица (вместо ссылок - простые имена объектов): 

Январь 
Февраль
Март
Апрель
Май
Июнь 
Июль
Август
Сентябрь
Октябрь
Ноябрь 
Декабрь 
 
 
 

Разбиение длинных циклов

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

Для поддержки механизма листания в операторы цикла (в версии 2.01 только в FORALLOBJ и FORASP, но в следующих версиях будут во все операторы цикла ) введены параметры POS=позиция и NUM=размер, задающие позицию начала окна просмотра в списке и размер этого окна. Кроме того, имеется операция ROOTREF, выдающая ссылку на текущую страницу с возможным добавлением или заменой этих же параметров (POS=позиция и NUM=размер ). Если первый аргумент ROOTREF указан с именем <#ROOTREF POS= ...>, то позиция в списке абсолютная, т.е. это просто номер первого отображаемого элемента, но если первый аргумент без имени <#ROOTREF nnn ...> , то он указывает положительное или отрицательное приращение позиции по отношению к текущей. Например: 15 означает добавление к позиции числа 15.

 Таким образом можно сделать такой стандартный элемент - макрос с именем _pagebar для листания страниц.

<!-- Листание страницы p=<#p> n=<#n> a=<#a> 
AspSize=<#(SET asz=(OR (AspSize A=(a)) 0) // переименование функции считающей число связей у аспекта объекта
               pre=(GT (p) 1) 
               nex=(LE (SUM (p) (n)) (asz) ) )
          (asz)> -->
<#IF (NEMPTY (a))>
 <#LT (p) 1 (SET p=1)>
 <TABLE width="100%"><TR>
  <TH width="25%">
      1<#IF (pre)>&lt;--<#p>&nbsp;<A HREF="<#ROOTREF (NEG (SUB (p) 1) (n))>"> 1-я стр.</A><#/>&nbsp;</TH>
  <TH width="25%">   <#IF (pre)><A HREF="<#ROOTREF (NEG (n))>">Пред.стр.</A><#/>&nbsp;</TH>
  <TH width="25%"><#IF (nex)><A HREF="<#ROOTREF (n) (n)>">След.стр.</A><#/>&nbsp;</TH>
  <TH width="25%"><#IF (nex)><A HREF="<#ROOTREF (SUM (asz) (NEG (p)) (NEG (n)) 1 ) (n)>">Посл.стр.</A>
        &nbsp;<#SUM (p) (n) "-1">--&gt;<#/>&nbsp;<#asz></TH>
 </TR></TABLE>
<#/>

Вставка этого элемента в виде макроса с именем _pagebar перед таблицей таким образом:

 <#SET pos=(OR (POS) 1) seg=48>
<HR> <h3>Префиксы для буквы (<#NAME>)</h3>
<#_pagebar p=(pos) a="a\a1" n=(seg)>
<TABLE border=1 width="100%">
<#FORALLOBJ "a\a1" POS=(pos) NUM=(seg)>
 <TR>
  <#PORTION 6>
   <TD width="16%"><TABLE>
     <#PORTION 8> 
      <TR><TD><#REFER></TD></TR>
     <#/>
   </TABLE></TD>
  <#/>
 </TR>
<#/>
</TABLE>
<HR>

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

Префиксы для буквы (П)

1 <--49 1-я стр.  Пред.стр.   След.стр.   Посл.стр.   96-->  148
поду
подъ
поза
позав
позапро
поиз
поис
пона
понад
поне
пони
поо
пооб
пообо
поот
попо
попри
попро
пораз
поразъ
порас
пораспро
порасс
пос
посо
поспо
поу
пре
прев
превоз
превос
пред
предв
предвз
предвоз
предвос
предвы
преддо
предис
предна
предо
предоб
предот
предпо
предпри
предрас
предраспо
предс

Приложения

Абриаль в 10 тезисах

  1. База данных в системе Абриаль представляет собой множество объектов, соединенных между собой многоместными связями различных типов. Тип объекта называется классом а тип связи - отношением.
  2. Одна связь представляется логически (и фактически в хранимой на диске текстовой базе данных) фактом: Rel(ob1,ob2,...) где Rel - обозначает отношение (тип связи), а ob1,ob2,... обозначения или значения объектов.
  3. Определенная позиция  объекта в связях некоторого отношения называется аспектом этого отношения, аспект отношения это аналог атрибута в реляционной теории.
  4. Аспектом объекта называется множество связей одного и того же отношения в которых данный объект занимает определенное место, например первое, или второе.
  5. Основным методом доступа в системе Абриаль и Абрис является обход одного аспекта определенного объекта. Реализация этого доступа в Абриале одинаково эффективна для всех аспектов всех объектов.
  6. Все классы, отношения аспекты и другие понятия описания структуры данных хранятся в базе данных в виде системных объектов - дескрипторов соответствующих понятий. Поэтому все эти понятия так же как любые объекты базы данных идентифицируются своим идом. Объекты и связи, описывающие структуру данных называются схемой базы данных или метаданными.
  7. Метаданные для метаданных называются ядром, присутствуют в базе данных изначально и не могут быть удалены или изменены.
  8. База данных Абриаль (или её часть) хранится на диске в виде текстового файла содержащего запись фактов, и идентификацию объектов. Описание базы данных также входит в её состав в виде определений классов и отношений.
  9. База данных целиком может хранится на диске в виде двоичного файла образа памяти с расширением *.AM, такой файл загружается в память значительно быстрее текстового.
  10. Абриаль поддерживает вычисления, основанные на виртуальных отношениях - ассоциациях и на эффективном продукционном механизме правил , контролирующих ввод данных, и производящих сложные расчеты в области ИИ. Ассоциации с точки зрения пользователя выглядят и работают как истинные отношения.

Словарик

  • Аргумент выражение играющее роль параметра в вызове метода , переменной или примитива . Аргументы могут быть именованными (ключевыми) или позиционными .
  • Аспект - определенная позиция в связях определенного типа.
  • Аспект объекта - множество связей определенного типа, в которых данный объект занимает определенную позицию.
  • База данных - в Абриале файл в текстовом формате (*.AB) или в двоичном (*.AM) содержащий множество взаимосвязанных объектов и связей.
  • Броузер программа для просмотра системы гипертекстовых страничек , в частности Веба (WWW) в интернете. Отдельный броузер Internet Explorer (IE) входит в состав Windows. Программа Абриаль имеет встроенный броузер на базе IE.
  • Вызов выражение обращающееся к методу, переменной или примитиву и состоящее из заключенных в круглые (...), теговые <...> или макротеговые <#...> скобки: предиката, (т.е. либо имени того к чему обращается, либо другого выражения, для случая переменного предиката), и возможно нескольких аргументов .
  • Выражение синтаксическая конструкция выдающая вместо себя некоторое текстовое значение, существующая в виде литерала, выдающего самого себя или в виде вызова, выдающего результаты вычислений. Выражения либо играют роль аргументов, либо в качестве макротегов вставляются в текст макроса.
  • Действие - разновидность запроса которая выполняется системой сразу после действия пользователя, но перед началом генерации обновления текущей странички .
  • Запрос- множество пар вида Имя=значение, посылаемое в систему для производства ею вычислений и с намерением получить в результате этих вычислений страничку .
  • Литерал выражение выдающее само себя, т.е. некоторая строка в кавычках или натуральное число или латинский идентификатор, которые можно писать без кавычек в качестве аргумента.
  • Ид, Идентификатор объекта - целое число более нуля однозначно идентифицирующее данный объект внутри одной базы данных.
  • Идентификатор - слово из латинских букв, цифр и знака подчеркивания начинающееся не с цифры.
  • Макрос - реализация метода в виде текста, содержащего внутри себя макротеги . Макросы либо хранятся на диске в виде файлов, либо в базе данных, либо могут определяться динамически в тексте других макросов.
  • Макротег - конструкция, заключенная в макротеговые <#...> скобки, вставляемая в текст макроса, и в процессе макрогенерации заменяющая себя вычисленным значением.
  • Метод - имя функциональной сущности играющее роль первого члена, предиката, в вызове
  • Объект - единица хранения информации в базе данных Абриаля. Определяется базой данных и своим ид -ом.
  • Операнд - позиционный аргумент операции.
  • Оператор1 - примитивное действие с текстом имеющее вид заголовка, т.е. макротега , затем тела, т.е. любого макро-текста, затем закрывающего тега <#/>
  • Оператор2 - тип (предикат) для оператора1 .
  • Операция - примитивная т.е. встроенная в систему функция или выражение - вызов такой функции. Отличается от оператора отсутствием тела и необходимости закрывающего тега.
  • Отношение - тип связей в базе данных Абриаля.
  • Параметр - тип или роль аргумента, предусмотренная в методе (макросе, функции) или в примитиве (операции, операторе). Роль определяется либо порядковым номеров после предиката, для позиционных параметров или именем параметра для ключевых параметров.
  • Параметр ключевой - ссылка (Name) внутри макроса или функции на аргумент вызова, задаваемый в форме Name=value где Name - идентификатор, а value - выражение, выдающее начальное значение. Может получить значение по умолчанию
  • Параметр позиционный - ссылка внутри макроса или функции на позиционный аргумент вызова, определяемый в форме обычного неименованного выражения; может быть превращен в ключевой параметр с помощью операции PARAM
  • Предикат - первый член вызова в виде имени (простой предикат) или макротега (переменный предикат), если первым членом является литерал в кавычках, именованный аргумент или выражение в круглых скобках, считается что предикат пропущен и он подразумевается по умолчанию: TEXT или SET.
  • Примитив - встроенные в систему операции или операторы.
  • Ссылка - конструкция в гипертексте отображаемая как подчеркнутый синий текст, и фактически являющаяся оформленным в виде тега A <A HREF=....> скрытым запросом к системе, активизируемым после щелчка мышью по этому тексту; Ссылки делятся на обычные, которые переводят броузер в режим стандартного обозревателя интернета и/или файлов, или абриалевские ссылки, активизирующие запрос к макрогенератору Абриаля/Абриса .
  • Страничка - Единица обмена информацией между пользователем и системой - порция гипертекста отображаемая пользователю броузером за один шаг навигации, в ответ на запрос. Страничка может соответствовать конкретному HTML-файлу на диске или в интернете (Вебе), или соответствовать некоторой точке навигации; в двух последних случаях страничка воспроизводима при таком же запросе или УРЛе. Но некоторые странички могут отображаться системой однократно, т.к. вообще говоря принцип формирования страниц системой динамический.
  • Функция - реализация метода в виде выражения, описанного в тексте макроса с помощью примитива FUNC.
  • CGI - протокол взаимодействия броузера пользователя с веб-сервером, при котором вместо статического документа пользователю посылается динамически формируемая страничка.
  • HTML - стандартный язык разметки гипертекстовых документов.
  • HTTP - стандартный протокол, по которому взаимодействуют, клиент, т.е. программа броузер и веб-сервер.
  • POST-данные - данные которые пользователь вводит в гипертекстовую форму, и которые посылаются на сервер вдобавок к данным внутри ссылки. POST - данные эмулируются и для клиентского варианта системы.
 

Все права защищены. © 2000-2004 РосНИИ ИИ
http://artint.ru
Copyright. © 2000-2004 by RRIAI
Александр Иосифович Пацкин [mailto:aleksandr@tochka.ru].
29/09/04

К началу документа.