Предыдущая серия была тут - Кодогенерация. Выводим каждый дочерний элемент в свой файл.
Вынесем почти всё, что касается мета-модели во внешние словари.
Оставим только то, что относится к конкретной модели и её генерации.
Вот что получается:
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
Комментариев нет:
Отправить комментарий