Extending Structure Language (Moved)

From IT SPb Academy

Jump to: navigation, search

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

Случай 1

Надо вставить блок кода baseLanguage-а в модель (solution) написанную на языке ортогональном baseLanguage-у. Например в описание едиторов.

Случай 2

В языке, котороый расширяет baseLanguage (напр. SModelLanguage), хочется использовать нотацию с точкой (как при вызове методов в baseLanguage).


Реализация.

Случай 1 (на примере 'cell rendering condition' в editorLanguage ):

Сейчас такая inline-function описывается так:

1. в structure-model editorLanguage-а декларируется концепт: QueryFunction_NodeCondition extends abstract ConceptFunction (baseLang)

2. декларируется тип возвращаемого значения: вставляется concept link 'conceptFunctionReturnType' со ссылкой на тип (в данном случае - boolean)

3. декларируются параметры функции

В данном случае это:

- node с типом "вычислимый, но приводимый к snode"
- scope с типом IScope (обычный интерфейс)

Каждый параметр декларируется как child-concept с ролью 'conceptFunctionParameter' и extends abstract ConceptFunctionParameter (baseLang).

Свойства параметра (имя, тип) задаются с помощью соответствующих concept-property/concept-link

4. для концепта функции пишется едитор (опционально, иначе используется едитор базового концепта (т.е. abstract ConceptFunction (baseLang)))

5. для вычислимых типов пишутся рулы в typesystem (в данном случае для типа выражения 'node'. этот тип зависит от того, в каком едиторе используется этот блок кода)

6. описывается генератор для концепта функции.

Обычно генерится 2 сущности:

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


Проблема:

structureLanguage ничего незнает о

- семантике базовых концептов (abstract ConceptFunction (baseLang), abstract ConceptFunctionParameter (baseLang))
- семантике концептуальных пропертей и линков (типа alias, conceptFunctionReturnType, conceptFunctionParameter)
- семантике типов
- семантике самого концепта (что генерится)

Соответственно, писать такой концепт крайне трудно, поскольку тул никак в этом не помогает.


Как хотелось-бы описывать такой класс концептов (т.е. встроенные блоки кода или inline-functions):


В опиании editorLanguage-а (в каком месте?) на специальном DSL (типа InlineFunctionSpecificationLanguage) задекларировать inline-function способом, который напоминает декларацию обычных функций.

Например:


inline-function boolean cell_rendering_condition( <? : snode> node , IScope scope)


как минимум, из такого описания должны сгенериться концепты с начинкой (см пп 1-3 выше).

дополнительно надо чтобы:

- для типа <? : snode<>>  можно было-бы легко создать правило вычисления типа (в typesystem)
- для всей функции и ее параметров можно было-бы легко понять, какие концепты им сответствуют (с тем, что-бы использовать их в других местах MPS-a: делать на них ссылки, определять едиторы, генераторы, констраинтсы итд.).

Кроме того, желательно чтобы не надо было каждый раз писать генератор, а просто сконфигурить заготовленные шаблоны (типа: static или instance method, имя метода итд.)


Как это могло-бы работать:


1. надо создать небольшой DSL (типа InlineFunctionSpecificationLanguage) специально приспособленный для декларирования inline-function и для него написать генератор --> structureLanguage

2. где-то в специальном месте в editorLanguage-е пользуясь InlineFunctionSpecificationLanguage задекларировать нужные inline-functions

3. после этого MPS должен сгенерить соответствующие концепты. они будут находиться не в structure-model editorLanguage, а в специальной модели, которая, возможно, не будет сохраняться (подобно тому, как сейчас делается с java_stub-ами).

4. далее со сгенеренными концептами можно работать как с обычными (едиторы и прочее для них совершенно обычные)

5. концепт для вычисляемого типа (его экземпляр в примере выглядит как <? : snode>), скорее всего, стоит создать в baseLanguage, т.к. он может реюзаться.

6. как конфигурить шаблоны генератора пока не рассматривается (какой-то dsl со ссылками на шаблоны и параметрами). на первом этапе это не обязательно.


Случай 2

в smodelLanguage слева от точки находится выражение smodelLanguage-а (это, например, preperty-access, которое записывается как node.property_name), а справа помещается операция.

Например, для property-access можно применить операцию 'set' с параметром Expression (baseLang):

node.name.set( "aaa" )

Это очень похоже на вызов метода класса, хотя на самом деле и для proprty-access и для set-operation определены концепты, а в выражение подставляются экземпляры этих концептов.

Как и в случае 1, здесь используются базовые концепты, concept-links и concept-propeties, которые несут в себе специфическую семантическую нагрузку и, неявно, образуют небольшой 'framework' для описания класса концептов типа smodel-expression.


И, как и в случае 1, хотелось бы этот 'framework' оформить в виде DSL, где эта семантика выражалась бы явно.

Видно, что тип выражения property-access имеет анологию с classifier-type, а операция 'set' напоминает метод. Поэтому все обисание могло бы походить на декларацию класса с методами.

Например (упрощенно):

typeclass PropertyAccess {
void set ( Expression )
}
Views