Home Page   We Generate Your Software.
Products Services Company Technology Demo Contact Site Map Search
Please note: this document is currently under revision.
The information herein contained, while still valid, does not reflect the latest state of the described technology.
The Somusar/SoProTech[tm] Booklet Series
Volume IV

"somusar/Tefigel: A Tutorial Introduction"

Printer friendly


Contents
1. Introduction
2. Language Summary
3. Text File Components
4. Text File Processing
5. Modularity
5.1 Subroutines and Functions
5.2 Packages and Libraries
5.3 Filters
6. Multilanguage Applicability
7. Generating Object-oriented Languages
8. Generating Internet-oriented Languages and Protocols
9. Generating Procedural Languages
10. Generating Scripting or Special-purpose Languages
11. Advanced Features and Topics
12. A More Extensive Example
13. Further Reading

Chapter 5 - Modularity

By exploiting the hierarchical nature of the file-systems usually available on most computing platforms, Tefigel strongly encourages a modular approach to the construction of file-generation environments, such as the SoProTech[tm] projects. In particular, subroutines, functions, packages and libraries, all these modular concepts are directly mapped in Tefigel onto standard file-system capabilities, such as files and directories.

5.1 - Subroutines and Functions        top

One of the key features of Tefigel is its file-oriented implementation of modular programming: Tefigel makes it extremely easy to split the generation of a text file into reusable, modular functions, identified by plain text files that can be directly CALLed by other text files, possibly with parameters, as shown in the following code examples.

Code Example 14 - Generating Java[tm] set/get
Generate a Java code fragment with set and get methods for some class members.
Source code - File "java_setget"
    1      
    2      // Set and get methods
    3      @ java/set_get(String,Status,status)
    4      @ java/set_get(ContactInformation,ContactInformation,info)
	       
Output of "/opt/somusar/bin/tefigel java_setget"
    1      
    2      // Set and get methods
    3          public void setStatus(String status) {
    4              this.status = status;
    5          }
    6      
    7          public String getStatus() {
    8              return status;
    9          }
   10      
   11          public void setContactInformation(ContactInformation info) {
   12              this.info = info;
   13          }
   14      
   15          public ContactInformation getContactInformation() {
   16              return info;
   17          }
   18      
	       

Code Example 15 - Subroutine for Java[tm] set/get
Arguments supplied to CALL are made available to subroutines and functions via automatic positional assignments performed by the INTERFACE instruction.
Source code - File "java/set_get"
    1      @ interface(MEMBERTYPE,MEMBER,mEMBER)
    2      @ dash $
    3          public void set$MEMBER(MEMBERTYPE mEMBER) {
    4              this.mEMBER = mEMBER;
    5          }
    6      
    7          public MEMBERTYPE get$MEMBER() {
    8              return mEMBER;
    9          }
   10      
   11      @ dash
	       

Beside file-functions, Tefigel provides a set of frequently useful built-in functions, such as LENGTH, SUBSTR, DATE, and several others. These functions are particularly useful in conjunction with the current call key (default: ~), that allows on-the-fly textual substitution of function results, as shown below.

Code Example 16 - Call key and built-ins
Usage of CALLKEY and built-ins within a text file.
Source code - File "call_key"
    1      # Embed function calls into output text
    2      This sample shows how to embed call to functions, in particular
    3      built-ins like date, into plain text lines.
    4      String manipulation functions, such as length and substr are
    5      also built in tefigel: 
    6         length of "the quick brown fox" is ~length(the quick brown fox)
    7         substr from position 4 of length 5 of "the quick brown fox" is
    8         "~substr(the quick brown fox,4,5)"
    9      @ callkey $
   10         This script has been run on $date from file $cur_input
   11      @ callkey
   12      # callkey is now again the default ~
	       
Output of "/opt/somusar/bin/tefigel call_key"
    1      This sample shows how to embed call to functions, in particular
    2      built-ins like date, into plain text lines.
    3      String manipulation functions, such as length and substr are
    4      also built in tefigel: 
    5         length of "the quick brown fox" is 19
    6         substr from position 4 of length 5 of "the quick brown fox" is
    7         "quick"
    8         This script has been run on Thu Sep 27 2012 from file call_key
	       

Tefigel's call key is another example of special character, introduced earlier in this tutorial, as it can be dynamically changed to allow for maximum flexibility with respect to the type of input and output of Tefigel itself: a constant call key like, for instance, $ would have caused syntax conflicts when generating source files of languages - such as Unix® shells - that associate a special meaning with the character $.

5.2 - Packages and Libraries        top

An extensive and modular use of Tefigel rapidly leads to a significant number of Tefigel files, or subroutines, related to one another, that can be collected together as one or more packages. Thanks to its file-oriented approach, Tefigel packages are simply sub-directories within a file-system, that can be freely grouped together at any depth level within the file-system, and then CALLed by means of their pathname.

Aimed at improving code readability, maintainability, and portability, the instruction LIBRARY allows a Tefigel program to search for packages, subroutines and functions under a specified file-system path (the library), thus allowing CALLs to use relative paths instead of absolute ones, as shown below.

Code Example 17 - Library of Tefigel packages
Use a simple list-processing package, consisting of a few subroutines and functions, to show how to use the LIBRARY instruction (on line 18) to dynamically set an entry point to a hierarchical collection of Tefigel packages. Note on lines 14 and 28 that the second parameter to subroutine "list/process" is a list item processor, namely "mkstring".
Source code - File "use_list"
    1      @ mark call .
    2      @ mark rem |
    3      @ dash &
    4      --------- Without library: use full pathnames to call tefigel functions
    5      1) Create list.
    6      . lib_root/list/create(EMPLOYEE)
    7      2) Add items to list.
    8      . lib_root/list/add(EMPLOYEE,John Smith)
    9      . lib_root/list/add(EMPLOYEE,Mark Twain)
   10      . lib_root/list/add(EMPLOYEE,Bill Young)
   11      . lib_root/list/add(EMPLOYEE,Tom Rich)
   12      3) List contents: '~lib_root/list/contents(EMPLOYEE)'
   13      4) Process list:
   14      . lib_root/list/process(EMPLOYEE,lib_root/mkstring)
   15      . lib_root/list/delete(EMPLOYEE)
   16      5) List contents after delete: '~lib_root/list/contents(EMPLOYEE)'
   17      --------- With library: use package hierarchy to call tefigel functions
   18      @ library lib_root
   19      1) Create list.
   20      . list/create(EMPLOYEE)
   21      2) Add items to list.
   22      . list/add(EMPLOYEE,John Smith)
   23      . list/add(EMPLOYEE,Mark Twain)
   24      . list/add(EMPLOYEE,Bill Young)
   25      . list/add(EMPLOYEE,Tom Rich)
   26      3) List contents: '~list/contents(EMPLOYEE)'
   27      4) Process list:
   28      . list/process(EMPLOYEE,mkstring)
   29      . list/delete(EMPLOYEE)
   30      5) List contents after delete: '~list/contents(EMPLOYEE)'
	       
Output of "/opt/somusar/bin/tefigel use_list"
    1      --------- Without library: use full pathnames to call tefigel functions
    2      1) Create list.
    3      2) Add items to list.
    4      3) List contents: 'John Smith|Mark Twain|Bill Young|Tom Rich'
    5      4) Process list:
    6         List item 1/4 - first name: "John"; last name: "Smith"
    7         List item 2/4 - first name: "Mark"; last name: "Twain"
    8         List item 3/4 - first name: "Bill"; last name: "Young"
    9         List item 4/4 - first name: "Tom"; last name: "Rich"
   10      5) List contents after delete: ''
   11      --------- With library: use package hierarchy to call tefigel functions
   12      1) Create list.
   13      2) Add items to list.
   14      3) List contents: 'John Smith|Mark Twain|Bill Young|Tom Rich'
   15      4) Process list:
   16         List item 1/4 - first name: "John"; last name: "Smith"
   17         List item 2/4 - first name: "Mark"; last name: "Twain"
   18         List item 3/4 - first name: "Bill"; last name: "Young"
   19         List item 4/4 - first name: "Tom"; last name: "Rich"
   20      5) List contents after delete: ''
	       

Generic list processor - File "lib_root/list/process"
    1      |
    2      |   General-purpose list processing function: scan a list and process
    3      |   each item applying a given item processor
    4      |
    5      @ interface(KEY,PROCESSOR)
    6      |
    7      |   Copy keyed list into CURLIST and keyed count into COUNTER.
    8      |
    9      @ set    CURLIST=~value(KEY&LIST)
   10      @ set CURCOUNTER=~value(KEY&COUNT)
   11      |
   12      |   Quit on empty lists
   13      |
   14      @ if CURCOUNTER<1
   15      @    quit
   16      @ endif
   17      |
   18      |   Loop on list, and call PROCESSOR on each item
   19      |
   20      @ set I=0
   21      @ while I<CURCOUNTER
   22      |
   23      |   Extract i-th field (0-based) from list and pass it to PROCESSOR
   24      |   as (i+1)-th, so that it is 1-based -- easier then to check for
   25      |   last item.
   26      |
   27      @    set ITEM=~field(CURLIST,I,|)
   28      @    add I 1
   29      .    PROCESSOR(I,CURCOUNTER,ITEM)
   30      @ endwhile
	       

Specific list item processor - File "lib_root/mkstring"
    1      |
    2      |   Process I-th item "REC" out of N items by splitting it into
    3      |   two blank-separated fields, "FIRST_NAME" and "LAST_NAME".
    4      |
    5      @ interface(I,N,REC)
    6      @ set FIRST_NAME=~field(REC,0, )
    7      @ set  LAST_NAME=~field(REC,1, )
    8         List item I/N - first name: "FIRST_NAME"; last name: "LAST_NAME"
	       

Therefore the task of creating, extending, and installing a library of Tefigel packages simply consists in creating, adding, and copying text files and directories to a file-system directory that implements the Tefigel library itself.

5.3 - Filters        top

Filters are Tefigel functions dynamically associated with patterns expressed as regular expressions: when an input line after processing is ready to be written out by Tefigel, a pattern check is performed against the filters currently defined (possibly none), activating the corresponding filter in case of pattern match.

Code Example 18 - Filters
Tefigel FILTERs to print out a specific subset of C preprocessor control lines: the first filter "h_control" captures lines beginning with a #, the second one "h_skip" skips all other lines. Note that the actual input file "errno.h" is specified as a command line parameter to Tefigel.
Source code - File "h_filter"
    1      @ mark rem |
    2      @ filter h_control ^#
    3      @ filter h_skip ^.*$
	       
Output of "/opt/somusar/bin/tefigel h_filter errno.h"
    1      #ifndef _ERRNO_H
    2      #ifndef __need_Emath
    3      #include <features.h>
    4      #endif
    5      #include <bits/errno.h>
    6      #ifdef  _ERRNO_H
    7      #ifndef errno
    8      #endif
    9      #ifdef __USE_GNU
   10      #endif /* __USE_GNU */
   11      #endif /* _ERRNO_H */
   12      #endif /* _ERRNO_H */
   13      #if defined __USE_GNU || defined __need_error_t
   14      # ifndef __error_t_defined
   15      # endif
   16      #endif
	       

Code Example 19 - Filter 1
Checks whether the C preprocessor control line should be printed out or not, ignoring #define and #undef. Note on lines 2 and 3 use of comparison operator ~ , pronounced "like".
Source code - File "h_control"
    1      @ interface(LINE)
    2      @ eval ignore LINE~^#[  ]*define
    3      @   or ignore LINE~^#[  ]*undef
    4      @ if ignore=0
    5      LINE
    6      @ endif
	       

Code Example 20 - Filter 2
Completely empty script, ignores input and produces no output.
Source code - File "h_skip"
	       

Filters are particularly useful in two cases:

  • To extract a subset of information out of a heterogeneous input stream, as shown in the previous example;

  • To reformat the contents of a homogeneous input stream, typically a list, or a table, as discussed later in the document.

[Previous chapter]    [Next chapter]    [Back to top]

http:// www.somusar.com  / doc  / booklets  / tefigel_tut  - Powered by SoProMach
Copyright © 2003-2012 Somusar - Trademarks - Legal - Privacy - Webmaster