Re: Refal+ abstract syntax


Subject: Re: Refal+ abstract syntax
From: Arkady Klimov (klimovark@mail.ru)
Date: Fri Dec 17 1999 - 17:24:01 MSK


Андрей, спасибо, это уже почти то, что надо.
"У целом" принимается.

А теперь перейдем к постатейному обсуждению.

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

Сначала по изменениям.

----- Original Message -----
From: Andrey Slepuhin <pooh@msu.ru>
To: Arkady Klimov <klark@bagirra.rinet.ru>
Cc: Sergei M. Abramov <abram@botik.ru>; <refal@botik.ru>
Sent: Thursday, December 16, 1999 6:11 AM
Subject: Re: Refal+ abstract syntax

> Добрый день всем!
>
> Извиняюсь за некоторую паузу в дискуссии.
> Я еще раз внимательно посмотрел на проект абстрактного синтаксиса
> и сделал свой вариант. Он лежит на
>
> http://forest.nmd.msu.ru/~pooh/refal_abstract_syntax.html
>
> На самом деле принципиальных различий практически нет, так что
> я думаю, что утверждение окончательного варианта не за горами.
> Что я изменил (по порядку):
>
> 1) t.ProgramFile заменено на t.Module (чисто косметическая замена :-))
> 2) t.Source удалено - вместо этого нужно использовать прагмы
> (тем более, что абстрактный синтаксис не обязательно может
> иметь какой-то исходный текст)
ОК
> 3) t.Import удалено - на уровне абстрактного синтаксиса нельзя ничего
> вытащить из других модулей, т.к. их представление в АС может и не
> существовать. Вместо этого каждый объект имеет свой описатель
> IMPORT/EXPORT/LOCAL. Если нужно сохранить информацию о том,
> из каких модулей импортировались объекты - можно использовать прагмы.
Это, конечно же, нужно, поэтому непонятно,
почему для этого надо прибегать к прагмам.
Причем это нужно будет сохранять не только в АС, но и в загрузочном модуле.
Нам наконец пора иметь возможность (не обязательно в любой реализации,
но хотя бы в некоторых) обеспечить цивилизованную динамическую загрузку.
Цивилизованной я называю такую, когда при загрузке модуля автоматически
могут быть подзагружены все используемые в нем модули, если они еще
не загружены. При этом также не нужно будет перечислять имена всех
модулей для начальной загрузки. (Сейчас в рефале-6 загрузка не является
цивилизованной)
Поэтому предлагаю.
а) Оставить список (USE e.ModuleNames).
б) В имени функции (REF s.name) разрешить использовать полные имена для
внешних функций: (REF s.ModuleName s.Name). Имена таких функций s.Name
могут безболезненно пересекаться с другими локальными или внешними
фунциями. Можно ввести стадию разрешения, которая будет пополнять все
ссылки (REF s.Name) до полных.
в) В s.ModuleName можно использовать точку, которая при превращении в имя
файла переходит в слеш.
г) Считать ошибкой, если есть простая ссылка с именем, которое не
определено
ни локально, ни в одном из USEd модулей.
д) Декларации внешних функций пополнить именем модуля, где обнаружено
определение функции. Эти декларации вставляются на стадии разрешения,
а изначально могут отсутствовать (см.ниже).

> 4) Описания определений всех объектов изменены в соответствии с 3).

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

> 5) Добавлен оператор FLUSH - см. мое письмо от 26 ноября в 16:14.
> В принципе возможна альтернатива - результаты по умолчанию
> замещаются, но есть оператор CONC.
Я не понимаю, зачем он нужен. Давайте лучше введем расширение для
t.ResultTerm:

t.ResultTerm ::= ...
                            | t.Block

А Flush пусть всегда присутствует "по умолчанию". Если же нужно
сконкатенировать
предыдущий результат со следующим t.Result или t.Block, то сделать это надо
явно.

(Возникает вопрос, а как вставить непрозрачный блок? Ответ: поставить
NOFAIL,
но не перед блоком, а перед всем результатным выражением.)

> 6) NOT и ITER сохранены как есть. С моей точки зрения их раскрытие
> слишком далеко двигает нас в сторону виртуального кода и может
> привести к менее удобному представлению при компиляции в
> императивные языки.
Это нормально. Но не отменяет возможности на ранней стадии компиляции
устранить NOT и ITER путем их раскрытия в АС же. Я не вижу почему эти
раскрытия специфичны для какого-то одного типа реализации. Полагаю,
они универсальны.
> 7) Немного изменены прагмы - но это не существенно.
> 8) В конце приведен вариант синтаксиса, в котором есть нераскрытые
> константы.
Это хорошо. Неясно теперь, как используются константы в теле программы.
Например, можно как (REF name), имея в виду, что такая конструкция всегда
подразумевает ее замену на значение константы по имени name. В случае
фукнций
и объектов следует считать, что строятся автоматически определения
констант,
значениями которых являются настоящие символы-ссылки.
Однако, обращаю внимание, что значением константы в общем случае будет
не обязательно символ, и даже не обязательно терм. Но всегда - объектное
(в смысле - ground) выражение, которое может быть всюду, включая жесткий
образец.
>
> Кроме того, он, мне кажется, красивее выглядит :-)))
> Так что изменения лучше будет вносить туда.
Согласен.
>
> Всего доброго,
> Андрей.
>
> P.S. Вопрос: Что такое t.Initializer и с чем его едят? По смыслу это
> похоже на конструкторы глобальных объектов в C++. Верно ли, что это
> расширение из Рефала-6?
Да, это расширение из Рефала-6. Он означает, что выражение должно быть
вычислено в момент загрузки. Вычисляется ради побочного эффекта,
значение игнорируется. Есть одна тонкость: момент вычисления определяется
положением среди других элементов. При этом нет гарантии, что нижеследующие
определения функций уже загружены и могут выполняться. Также уже должны
быть загружены целиком другие модули, которые используются из данного.
А это, в частности, означает, что в графе использований модулями друг друга
не должно быть циклов.
Вообще, я думаю, это полезная конструкция, посколку позволяют делать
модули,
которые содержат в себе свою инициализацию (содержимого ящиков, например),
и не требуют от пользователя вызывать инициализацию явно.
Кроме того, такие модули могут представлять самодостаточные программы, не
требующие указывать их входные точки (GO, Main, и т.п.).

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

А теперь несколько новых замечаний-дополнений.

1. Для объектов типов BOX, STRING, VECTOR и, возможно, TABLE - вести
понятие начального значения:

t.Object ::= (s.Linkage s.ObjectType s.ObjectName e.InitialValue)

e.InitialValue ::= e.ResultExpression

(ограничения - те же, что и для initializer'а.

2. PragmaTrace. Отсутствует traceAll. Преднамеренно?

3. В последнем письме от 17.12 ты предлагаешь разделить декларацию и
определения.
Мне кажется, это тоже можно вводить как стадию обработки в рамках АС. Но
может
компилятору это и не требуется?

Кажется все.

Надеюсь, не слишком утомил?

Наилучшие пожелания.
Аркадий.

PS. В интернете я никаких изменений не делал, да наверно я и не вправе.
Поэтому,
все изменения, который сочтешь нужными, внеси, пожалуйста, сам.
>
>



This archive was generated by hypermail 2b25 : Mon Oct 25 2004 - 21:24:58 MSD