вторник, 13 октября 2015 г.

#843. Code generation. Extracting almost everything to external dictionaries

Original in Russian: http://programmingmindstream.blogspot.ru/2015/08/blog-post_35.html
The previous series was here – Code generation. Extracting each child element to separate files.

Let’s extract almost everything related to the meta-model to external dictionaries.

We will not touch anything related to the specific model and its generation.

Here’s what we get:

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 - function to test functionality
  '
 
 %REMARK
  '
  %SUMMARY is meta information that allows binding the documentation to the code elements. Consequently, the documentation is available from the script engine.
  '
 %SUMMARY '
'That is where we test meta-model building, model building and then code generation.
 '
 ; // %SUMMARY
 
USES
 Templates.ms.model
;
 
// ---------------------------------------------------------------------------
 
concrete-model-begin 'Model of the specific project Project1'
' This is where we determine axiomatic of the specific model of the specific project
  We will separate it in a dictionary later.
 '
<<Project>> Project1
 %SUMMARY '
 This is our first project - Project1
 '
 ; // %SUMMARY
 
 <<Library>> Library1
  %SUMMARY '
  Probably, there are design libraries in our project.
  The Library1 is our first design library.
  '
  ; // %SUMMARY
 ; // Library1
 
 <<Library>> Library2
  %SUMMARY '
  Our project is probably serious enough and has MORE THAN ONE library.
  The Library2 is our second design library.
  '
  ; // %SUMMARY
 ; // Library2
 
 <<Library>> Library3
  %SUMMARY '
  Our project is probably SO serious that it has even MORE THAN TWO libraries.
  The Library3 is our third design library.
  '
  ; // %SUMMARY
 ; // Library3
 
 <<Program>> Program1
  %SUMMARY '
  Our project probably implements some program.
  Otherwise, why would we need it?
  The Program1 is a program in our Project1.
  '
  ; // %SUMMARY
 
  <<Class>> Class1
   %SUMMARY '
  Our program probably has some implementation classes.
  Otherwise, how would we implement our functionality?
  The Class1 is our FIRST implementation class in our Program1.
   '
   ; // %SUMMARY
  ; // Class1
 
  <<Interface>> Interface1
   %SUMMARY '
  Our program is probably SO serious that implements some interfaces.
  The Interface1 is our FIRST interface.
   '
   ; // %SUMMARY
  ; // Interface1
 
  <<Interface>> Interface2
   %SUMMARY '
   Our program is probably SO serious that it implements MORE THAN ONE interface.
  The Interface2 is our second interface.
   '
   ; // %SUMMARY
  ; // Interface2
 
  <<Class>> Class2
   %SUMMARY '
    Our program is probably serious enough and has MORE THAN ONE implementation class.
  The Class2 is our second implementation class in Program1.
   '
   ; // %SUMMARY
   %INHERITS
    Addr Class1
    %REMARK 'Perhaps the design Class2 is inherited from Class1'
   ; // %INHERITS
   %IMPLEMENTS
    Addr Interface1
    %REMARK 'Perhaps the design Class2 implements Interface1'
    Addr Interface2
    %REMARK 'Perhaps the design Class2 implements Interface2, too'
   ; // %IMPLEMENTS
  ; // Class2
 
  <<Class>> Class3
   %SUMMARY '
   Our program is probably so complex that it has even more than TWO implementation classes.
   The Class3 is the THIRD implementation class within the Program1.
   '
   ; // %SUMMARY
  ; // Class3
 
  <<Class>> Class4
   %SUMMARY '
   We are probably so cool that we have even more than THREE implementation classes.
   The Class4 is the FOURTH implementation class within the Program1.
   ; // %SUMMARY
   %INHERITS
    Addr Class2
    Addr Class3
    %REMARK 
     '
   We are probably cool enough to use MULTIPLE INHERITANCE and, moreover, to UNDERSTAND WHY we need it.
   The Class4 is inherited from Class2 and Class3.  
     '
   ; // %INHERITS
  ; // Class4
 
 ; // Program1
 
; // Project1
 
%REMARK
 '
  These words should “probably” be based on requirements specification and UseCase.
  Well, we will talk it over later. 
 '  
model-end
 
// ---------------------------------------------------------------------------
 
// ---------------------------------------------------------------------------
 
concrete-model-begin 'Model of the specific project Project2'
 ' This is where we determine axiomatic of the specific model of the specific project
  We will separate it in a dictionary later.
 '
<<Project>> Project2
 %SUMMARY '
 This is our SECOND project - Project2
 '
 ; // %SUMMARY
; // Project2
model-end
 
// ---------------------------------------------------------------------------
 
// ---------------------------------------------------------------------------
 
concrete-model-begin 'Model of the specific project Project3'
 ' This is where we determine axiomatic of the specific model of the specific project.
  We will separate it in a dictionary later.
 '
<<Project>> Project3
 %SUMMARY '
 This is our THIRD project - Project3
 '
 ; // %SUMMARY
; // Project3
model-end
 
// ---------------------------------------------------------------------------
 
USES
 CodeDump.ms.dict
 // - the CodeDump.ms.dict is loaded so we can “see” the DumpElement word
;
 
this.method.addr DumpElement
%REMARK
 '
 - the CodeGen element and its contents are dumped in a standard output device.
   We only do it to debug what we’ve written.
 '
 
help
%REMARK
 '
 The available axiomatic is output to a standard output device.
 We only do it to debug what we’ve written.
 '
 
USES
 Generation.ms.dict
;
 
elem_proc DumpAsIs
 %SUMMARY 'Printing procedure for model element content, recursively.' ;
 
 [
  g_CurrentGeneratorName ':'
   %REMARK 'Outputs the name of the current generator for debugging'
  for ( Self LIST %ST Reverted ) .Name
   %REMARK 'Outputs  the stereotype of the element, recursively'
  Self .Name 
   %REMARK 'Outputs  the element name'
 ] ' ' strings:CatSep OutToFile
 [
  'Element’s parents '
  for ( Self .Parents >reverted> ) .Name
  %REMARK 'Outputs the parents of the element, recursively'
 ] '::' strings:CatSep OutToFile
 for ( Self .Inherited ) ( .Name OutToFile )
 for ( Self .Implements ) ( .Name OutToFile )
 TRY
  Self .CallChildrenCurrentGen
  %REMARK 'Outputs the element’s children with the same generator'
 FINALLY
  [ '; // ' Self .Name ] OutToFile
  %REMARK 'Outputs the closing bracket of the element'
 END
; // DumpAsIs
 
elem_generator dump
 %SUMMARY 'Output generator for of the model’s element’s dump.' ;
 %GEN_PROPERTY Name 'dump'
 %REMARK 'Generator name and file extension for target language. Later, we try to avoid coincidence'
 
 Self .DumpAsIs
 %REMARK 'For now, output “as it is” without transformation to target language'
; // dump
 
elem_generator pas
 %SUMMARY 'Generator to output model elements to Pascal.' ;
 %GEN_PROPERTY Name 'pas'
 %REMARK 'Generator name and file extension for target language. Later, we try to avoid coincidence'
 
 Self .DumpAsIs
 %REMARK 'For now, output “as it is” without transformation to target language'
; // pas
 
elem_generator script
 %SUMMARY 'Generator to output model elements to ms.script.' ;
 %GEN_PROPERTY Name 'ms.script'
 %REMARK 'Generator name and file extension for target language. Later, we try to avoid coincidence'
 
 Self .DumpAsIs
 %REMARK 'For now, output “as it is” without transformation to target language'
; // script
 
elem_generator c++
 %SUMMARY '
'Generator to output model elements to c++. 
 Later we will specially talk about *.h files.
 ' ;
 %GEN_PROPERTY Name 'cpp'
 %REMARK 'Generator name and file extension for target language. Later, we try to avoid coincidence'
 
 Self .DumpAsIs
 %REMARK 'For now, output “as it is” without transformation to target language'
; // c++
 
elem_generator h
 %SUMMARY '
 Generator to output model elements to *.h. 
 Later we will specially talk about *.h files.
 ' ;
 %GEN_PROPERTY Name 'h'
 %REMARK 'Generator name and file extension for target language. Later, we try to avoid coincidence'
 
 Self .DumpAsIs
 %REMARK 'For now, output “as it is” without transformation to target language'
; // h
 
( Project1 Project2 Project3 )
%REMARK 'Full list of root elements (projects)'
 ( .dump .pas .c++ .h .script )
 %REMARK 'Full list of generators'
  CallGensList
  %REMARK '- launches the list of generators on the model’s “root elements” list'
 
; // CodeGen
 
CodeGen

Комментариев нет:

Отправить комментарий