Предыдущая серия была тут - Кодогенерация. Выводим каждый дочерний элемент в свой файл.
Вынесем почти всё, что касается мета-модели во внешние словари.
Оставим только то, что относится к конкретной модели и её генерации.
Вот что получается:
https://bitbucket.org/lulinalex/mindstream/src/ebbf27e8918717c982d0b756118a081620155d71/Examples/Scripts/CodeGeneration/CodeGen67.ms.script?at=B284
Вынесем почти всё, что касается мета-модели во внешние словари.
Оставим только то, что относится к конкретной модели и её генерации.
Вот что получается:
https://bitbucket.org/lulinalex/mindstream/src/ebbf27e8918717c982d0b756118a081620155d71/Examples/Scripts/CodeGeneration/CodeGen67.ms.script?at=B284
USES
metaMACRO.ms.dict
classRelations.ms.dict
EngineTypes.ms.dict
Object.ms.dict
;
Test CodeGen
%REMARK
'
CodeGen - это функция в которой мы будем тестировать наш функционал
'
%REMARK
'
%SUMMARY это мета-информация, которая позволяет привязывать документацию
к элементам кода. Эта документация доступна потом из скриптовой машины.
'
%SUMMARY '
Тут будем тестировать построение сначала мета-модели, потом модели, а потом и
кодогенерации
'
; // %SUMMARY
USES
Templates.ms.model
;
// ---------------------------------------------------------------------------
concrete-model-begin 'Модель конкретного проекта Project1'
'Тут будем определять аксиоматику конкретной модели конкретного проекта.
А потом вынесем её
в отдельный словарь.
'
<<Project>> Project1
%SUMMARY '
Это наш первый проект - Project1
'
; // %SUMMARY
<<Library>> Library1
%SUMMARY '
Наверное наш проект содержит какие-то проектные библиотеки.
Так вот Library1 - это наша первая проектная библиотека
'
; // %SUMMARY
; // Library1
<<Library>> Library2
%SUMMARY '
Наверное наш проект достаточно серьёзен и содержит НЕ ОДНУ библиотеку.
Так вот Library2 - это наша вторая проектная библиотека.
'
; // %SUMMARY
; // Library2
<<Library>> Library3
%SUMMARY '
Наверное наш проект НАСТОЛЬКО серьёзен, что содержит даже НЕ ДВЕ библиотеки.
Так вот Library3 - это наша третья проектная библиотека.
'
; // %SUMMARY
; // Library3
<<Program>> Program1
%SUMMARY '
Наверное наш проект реализует какую-то программу.
Иначе - зачем бы он нам был бы нужен?
Так вот Program1 - это программа внутри нашего проекта Project1.
'
; // %SUMMARY
<<Class>> Class1
%SUMMARY '
Наверное наша программа содержит какие-то классы реализации.
Иначе - кто будет реализовывать наш функционал?
Так вот Class1 - это наш ПЕРВЫЙ класс реализации внутри нашей программы Program1.
'
; // %SUMMARY
; // Class1
<<Interface>> Interface1
%SUMMARY '
Наверное наша программа настолько серьёзна, что реализует какие-то интерфейсы.
Так вот Interface1 - это наш ПЕРВЫЙ интерфейс.
'
; // %SUMMARY
; // Interface1
<<Interface>> Interface2
%SUMMARY '
Наверное наша программа настолько серьёзна, что реализует НЕ ОДИН интерфейс, а несколько.
Так вот Interface2 - это наш ВТОРОЙ интерфейс.
'
; // %SUMMARY
; // Interface2
<<Class>> Class2
%SUMMARY '
Наверное наша программа достаточно серьёзна и содержит НЕ ОДИН классы реализации.
Так вот Class2 - это наш ВТОРОЙ класс реализации внутри нашей программы Program1.
'
; // %SUMMARY
%INHERITS
Addr Class1
%REMARK 'Возможно наш проектный класс Class2 наследуется от класса Class1'
; // %INHERITS
%IMPLEMENTS
Addr Interface1
%REMARK 'Возможно наш проектный класс Class2 реализует интерфейс Interface1'
Addr Interface2
%REMARK 'Возможно наш проектный класс Class2 реализует ещё и интерфейс Interface2'
; // %IMPLEMENTS
; // Class2
<<Class>> Class3
%SUMMARY '
Возможно, что у нас такая непростая программа, что в ней даже больше, чем ДВА класса реализации.
Так вот Class3 - это наш ТРЕТИЙ класс реализации внутри нашей программы Program1.
'
; // %SUMMARY
; // Class3
<<Class>> Class4
%SUMMARY '
Возможно, что мы настолько офигенно круты, что у на даже НЕ ТРИ класса реализации.
Так вот Class4 - это наш ЧЕТВЁРТЫЙ класс реализации внутри нашей программы Program1.
'
; // %SUMMARY
%INHERITS
Addr Class2
Addr Class3
%REMARK
'
Возможно, что мы нстолько ОФИГЕННЫЕ перцы, что используем МНОЖЕСТВЕННОЕ наследование.
И даже ПОНИМАЕМ - ЗАЧЕМ это нужно.
Так вот Class4 - наследуется от Class2 и Class3.
'
; // %INHERITS
; // Class4
; // Program1
; // Project1
%REMARK
'
РЕМАРКА.
Все эти слова "наверное" вообще говоря должны проистекать из требований, ТЗ и UseCase
Но мы про это позже поговорим.
'
model-end
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
concrete-model-begin 'Модель конкретного проекта Project2'
'Тут будем определять аксиоматику конкретной модели конкретного проекта.
А потом вынесем её
в отдельный словарь.
'
<<Project>> Project2
%SUMMARY '
Это наш ВТОРОЙ проект - Project2
'
; // %SUMMARY
; // Project2
model-end
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
concrete-model-begin 'Модель конкретного проекта Project3'
'Тут будем определять аксиоматику конкретной модели конкретного проекта.
А потом вынесем её
в отдельный словарь.
'
<<Project>> Project3
%SUMMARY '
Это наш ТРЕТИЙ проект - Project3
'
; // %SUMMARY
; // Project3
model-end
// ---------------------------------------------------------------------------
USES
CodeDump.ms.dict
// - тут подключаем словарь CodeDump.ms.dict, чтобы "увидеть" слово DumpElement
;
this.method.addr DumpElement
%REMARK
'
- тут дампим элемент CodeGen и его содержимое
в стандартное устройство вывода.
Чисто для отладки того, что мы сейчас написали.
'
help
%REMARK
'
Выводим всю доступную аксиоматику в стандартное устройство вывода.
Чисто для отладки того, что мы сейчас написали.
'
USES
Generation.ms.dict
;
elem_proc DumpAsIs
%SUMMARY 'Процедура печатающая содержимое элемента модели. Рекурсивно.' ;
[
g_CurrentGeneratorName ':'
%REMARK 'Выводим имя текущего генератора. Для отладки'
for ( Self LIST %ST Reverted ) .Name
%REMARK 'Выводим стереотип элемента, рекурсивно'
Self .Name
%REMARK 'Выводим имя элемента'
] ' ' strings:CatSep OutToFile
[
'Родители элемента '
for ( Self .Parents >reverted> ) .Name
%REMARK 'Выводим родителей элемента, рекурсивно'
] '::' strings:CatSep OutToFile
for ( Self .Inherited ) ( .Name OutToFile )
for ( Self .Implements ) ( .Name OutToFile )
TRY
Self .CallChildrenCurrentGen
%REMARK 'Выводим детей элемента, тем же самым генератором'
FINALLY
[ '; // ' Self .Name ] OutToFile
%REMARK 'Выводим закрывающую скобку элемента'
END
; // DumpAsIs
elem_generator dump
%SUMMARY 'Генератор выводящий дамп элемента модели.' ;
%GEN_PROPERTY Name 'dump'
%REMARK 'Имя генератора и расширение файла целевого языка. Потом мы сделаем так, чтобы они могли не совпадать'
Self .DumpAsIs
%REMARK 'Пока выводим всё "как есть", без трансформации в целевой язык'
; // dump
elem_generator pas
%SUMMARY 'Генератор выводящий элементы модели в Паскаль.' ;
%GEN_PROPERTY Name 'pas'
%REMARK 'Имя генератора и расширение файла целевого языка. Потом мы сделаем так, чтобы они могли не совпадать'
Self .DumpAsIs
%REMARK 'Пока выводим всё "как есть", без трансформации в целевой язык'
; // pas
elem_generator script
%SUMMARY 'Генератор выводящий элементы модели в ms.script.' ;
%GEN_PROPERTY Name 'ms.script'
%REMARK 'Имя генератора и расширение файла целевого языка. Потом мы сделаем так, чтобы они могли не совпадать'
Self .DumpAsIs
%REMARK 'Пока выводим всё "как есть", без трансформации в целевой язык'
; // script
elem_generator c++
%SUMMARY '
Генератор выводящий элементы модели в c++.
Про файлы *.h мы потом поговорим отдельно.
' ;
%GEN_PROPERTY Name 'cpp'
%REMARK 'Имя генератора и расширение файла целевого языка. Потом мы сделаем так, чтобы они могли не совпадать'
Self .DumpAsIs
%REMARK 'Пока выводим всё "как есть", без трансформации в целевой язык'
; // c++
elem_generator h
%SUMMARY '
Генератор выводящий элементы модели в *.h.
Про файлы *.h мы потом поговорим отдельно.
' ;
%GEN_PROPERTY Name 'h'
%REMARK 'Имя генератора и расширение файла целевого языка. Потом мы сделаем так, чтобы они могли не совпадать'
Self .DumpAsIs
%REMARK 'Пока выводим всё "как есть", без трансформации в целевой язык'
; // h
( Project1 Project2 Project3 )
%REMARK 'Список всех наших корневых элементов (проектов)'
( .dump .pas .c++ .h .script )
%REMARK 'Список всех наших генераторов'
CallGensList
%REMARK '- запускаем список генераторов на списке "рутовых элементов" модели.'
; // CodeGen
CodeGen
Комментариев нет:
Отправить комментарий