Home Page   We Generate Your Software.
Products Services Company Technology Demo Contact Site Map Search

Full list of in-depth articles - Feedback and questions - Request demo -


1 October 2004 - New features of Tefigel

  1  New features of the Tefigel language
  1.1  Generation scripts and generation templates
  1.2  Dynamic data groups
  1.3  Enhanced "for each" loops
  1.4  String substitution made easy
  2  Code examples
  2.1  String table generator
  2.2  group and ungroup
  2.3  Simple string editing with replace
  2.4  A cross-platform/cross-model/cross-IDE bridge

1 - New features of the Tefigel language

The new version (099) of Tefigel introduces some useful new commands, built-in functions, and facilities that simplify the implementation of complex software generation solutions.

1.1 - Generation scripts and generation templates

When the logic of a software generator is not trivial, a clear separation between generation templates and generation scripts is recommendable: complex templates full of generation logic are difficult to read and to maintain. The new command tefigel allows to write complex generation scripts without the otherwise necessary templating syntax burden.

1.2 - Dynamic data groups

Metadata from different sources usually require different data records. Yet a software generator should be agile enough to avoid complex constructs of data type definition and declaration, as provided by most general-purpose programming languages. Tefigel now provides means to dynamically group and ungroup interrelated data items.

1.3 - Enhanced "for each" loops

for loops that scan lists of items often require special actions on the first and last items of the lists. Automatic loop variables ..._counter and ..._loops provide a useful help for such tasks.

1.4 - String substitution made easy

One of the main activities of software generators is string processing. In many cases output strings are derived from simple manipulations of one common input string. The new built-in function replace simplifies this frequent task.

2 - Code examples

The following self-contained examples demonstrate how to use the new features described in this article.

2.1 - String table generator

Your new task is to write a set of tables of strings for a number of different types of items. The strings must comply to a scheme with different casing styles: default case, lower case, upper case, and lower case with first letter in upper case. The code that you have to write should look like the code in the following listing.

String table generator - Target code [ File "string_tab.out" ]
String ElectronicMedia[] = 
   { /* 1/4 */
     "DVD.dvd.DVD.Dvd", 
     /* 2/4 */
     "CD.cd.CD.Cd", 
     /* 3/4 */
     "Videotape.videotape.VIDEOTAPE.Videotape", 
     /* 4/4 */
     "Cartridge.cartridge.CARTRIDGE.Cartridge" };

String Fruits[] = 
   { /* 1/5 */
     "apple.apple.APPLE.Apple", 
     /* 2/5 */
     "orange.orange.ORANGE.Orange", 
     /* 3/5 */
     "banana.banana.BANANA.Banana", 
     /* 4/5 */
     "grapefruit.grapefruit.GRAPEFRUIT.Grapefruit", 
     /* 5/5 */
     "strawberry.strawberry.STRAWBERRY.Strawberry" };

String Colors[] = 
   { /* 1/8 */
     "RED.red.RED.Red", 
     /* 2/8 */
     "GREEN.green.GREEN.Green", 
     /* 3/8 */
     "BLUE.blue.BLUE.Blue", 
     /* 4/8 */
     "YELLOW.yellow.YELLOW.Yellow", 
     /* 5/8 */
     "PINK.pink.PINK.Pink", 
     /* 6/8 */
     "VIOLET.violet.VIOLET.Violet", 
     /* 7/8 */
     "BLACK.black.BLACK.Black", 
     /* 8/8 */
     "WHITE.white.WHITE.White" };

As you have to write a number of such tables, you decide to write a lightweight generator that takes as input the file below.

String table generator - Input [ File "string_tab.main" ]
@ tefigel

output string_tab.out

string_tab(ElectronicMedia,DVD/CD/Videotape/Cartridge)
string_tab(Fruits,apple/orange/banana/grapefruit/strawberry)
string_tab(Colors,RED/GREEN/BLUE/YELLOW/PINK/VIOLET/BLACK/WHITE)

There are several minor details to take care of, thus the generator logic is more than the required templating. This is a good opportunity to take advantage of the tefigel and enhanced for loop of Tefigel version 099. The core generator routine "string_tab" is listed below.

String table generator - Main routine [ File "string_tab" ]
@ tefigel

interface(table_name,items)

# Use some blanks to indent table rows
set indent=   

echo String table_name[] = 

# items are slash-separated: scan the list using a
# slash-driven FOR loop
argdelim /
for item=items

   set before=  indent
   set  after=, 

   case item_counter

      when=1 
         set before=indent{ 

      when=item_loops
         set after= };

   endcase

   set lc_item=~to_lower(item)
   set UC_item=~to_UPPER(item)
   set Uc_item=~to_Upper(item)

   echo before/* item_counter/item_loops */
   echo indent  "item.lc_item.UC_item.Uc_item"after

endfor
argdelim

echo 

2.2 - group and ungroup

Codefile "groups.main" below illustrates how to use:

  • group to dynamically create lists of structured data while collecting metadata;

  • ungroup to expand the structured data while generating the required software.

Sample use of group/ungroup - Input [ File "groups.main" ]
@ tefigel

echo Create a list of writers using dynamic data groups

new_list(Writers)

addWriter(Mark,Twain,1835-1910)
addWriter(William,Shakespeare,1564-1616)
addWriter(Jane,Austen,1775-1817)

echo The list contains: 
echo    "~list_contents(Writers)"

echo Scan the list ungrouping the items:

for cur_writer=~list_contents(Writers)
   ungroup(cur_writer,|,FirstName,LastName,Dates)
   echo    writer #cur_writer_counter is LastName (FirstName) [Dates]
endfor

The output produced by the script above is listed below.

Sample use of group/ungroup - Output [ File "groups.out" ]
Create a list of writers using dynamic data groups
The list contains: 
   "Mark|Twain|1835-1910,William|Shakespeare|1564-1616,Jane|Austen|1775-1817"
Scan the list ungrouping the items:
   writer #1 is Twain (Mark) [1835-1910]
   writer #2 is Shakespeare (William) [1564-1616]
   writer #3 is Austen (Jane) [1775-1817]

The following listing shows the code of subroutine "addWriter".

Sample use of group/ungroup - Subroutine [ File "addWriter" ]
@ tefigel

interface(FirstName,LastName,Dates)
add_item(Writers,~group(|,FirstName,LastName,Dates))

2.3 - Simple string editing with replace

Two nested for loops expand a set of input file names into a cartesian product of output file names with different extensions.

Sample use of replace - Input [ File "replace.main" ]
@ tefigel

set base_ext=in

for file_name=table1.in,table2.in,figure1.in

   for out_ext=html,txt,ps,pdf

      set out_name=~replace(file_name,base_ext,out_ext)
      echo Would generate "out_name" from "file_name"

   endfor

   echo

endfor

The output generated by the script above is listed below.

Sample use of replace - Output [ File "replace.out" ]
Would generate "table1.html" from "table1.in"
Would generate "table1.txt" from "table1.in"
Would generate "table1.ps" from "table1.in"
Would generate "table1.pdf" from "table1.in"

Would generate "table2.html" from "table2.in"
Would generate "table2.txt" from "table2.in"
Would generate "table2.ps" from "table2.in"
Would generate "table2.pdf" from "table2.in"

Would generate "figure1.html" from "figure1.in"
Would generate "figure1.txt" from "figure1.in"
Would generate "figure1.ps" from "figure1.in"
Would generate "figure1.pdf" from "figure1.in"

2.4 - A cross-platform/cross-model/cross-IDE bridge

SoProMach can be used as a software generator with different IDEs (Integrated Development Environments) such as Eclipse 3 and Visual Basic Express 2005 Beta 1 (see articles [1] and [2]. This type of integration may involve different platforms (Windows, Linux, Mac OS X). Moreover, the input model to SoProMach can be a Sisendel entity file or an XML file.

This implies that portability has three dimensions: across platforms, across IDEs, and across model types.

The following Tefigel codefile realizes this type of 3D bridge as required for the IDE-SoProMach integration case studies described in the aforementioned articles.

Bridging different IDEs with SoProMach on different platforms [ File "ide_bridge.tfg" ]
@ tefigel

interface(file_path)

if init_tfg=
   globset init_tfg=1
else
   set init_tfg=0
endif

set running_on=~cur_platform

if running_on=Windows
   set path_slash=\
   set spm_script=w4_rungen.bat
   set cmd_concat=&&
else
   set path_slash=/
   set spm_script=u4_rungen
   set cmd_concat=;
endif

set path_depth=~field_count(file_path,path_slash)
sub path_depth 1
 
set file_name=~field(file_path,path_depth,path_slash)
set dir_length=~length(file_path)
sub dir_length ~length(file_name)
sub dir_length 1
set file_dir=~substr(file_path,0,dir_length)
 
set dot_extensions=~field_count(file_name,.)
sub dot_extensions 1
 
if dot_extensions>0
   set file_extension=~field(file_name,dot_extensions,.)
else
   set file_extension=
endif

if init_tfg=1

   dash &
   globset poc_path=file_dir&path_slash
   dash

   hook NEW_INPUT=file_path

else

   hook NEW_INPUT=

   case file_extension

      when=ef
         dash !
         system cd poc_path cmd_concat poc_path!spm_script "file_path" "file_dir" "file_name"
         dash

      when=xml
         dash !
         system cd poc_path cmd_concat poc_path!spm_script "file_path" "file_dir" "~replace(file_name,.xml,)"
         dash

      otherwise
         msg [warning] unexpected file extension "file_extension"

   endcase

   exit 0

endif


Updated on 29 October 2004
Full list of in-depth articles - Feedback and questions - Request demo -

http:// www.somusar.com  / company  / news  / in_depth  / oct01_2004  - Powered by SoProMach
Copyright © 2003-2012 Somusar - Trademarks - Legal - Privacy - Webmaster