Full list of in-depth articles -
Feedback and questions -
Request demo -
14 May 2004 - New version of SoProMach
1
| New versions of Sisendel and Tefigel |
|
|
|
|
|
|
|
|
SoProMach has significantly
been enhanced and improved, and now features Sisendel version 067 and
Tefigel version 098. Previous versions (Sisendel 066 and Tefigel 097)
had been released on February 6, 2004.
The new version of the Sisendel processor
generates intermediate
metadata files that improve and simplify the construction
of software molds, exploiting the list processing
capabilities and the new control flow constructs of Tefigel.
The new intermediate files allow mold makers to more easily
access design information from the collections of fields (such as
DB.table columns or LOGIC.class attributes)
listed in each entity file (.ef file) in input to the Sisendel
processor.
This change has no impacts on Sisendel
intended as a language.
Tefigel now features a richer set of
control flow constructs: two new loop constructs and a flexible multiple
choice construct have been added to the WHILE..ENDWHILE loop
and IF..ELSE..ENDIF control structures already available in the
previous version.
Moreover, two new instructions allow
to dynamically associate function calls to textual identifiers, and
a new built-in function allows to embed control characters within
string variables.
Finally, it is no longer necessary to explicitly
distinguish between Tefigel native instructions and external macros.
Tefigel's FOR loop resembles well-known "for each" loops of
other languages: on each loop iteration a loop variable is set
to a new value taken from a list. This construct
is particularly useful in conjunction
with Tefigel's lists, that will typically contain metadata
information, such as class attributes, or a list of schema tables.
An example follows.
Sample use of FOR loop - Input [ File "for.in" ]
|
Here's a simple loop on a list of values:
@ FOR fruit=apples,pears,strawberries
I love fruit.
@ ENDFOR
Now create a list of types of fruit:
@ NEW_LIST(FRUIT)
@ ADD_ITEM(FRUIT,apples)
@ ADD_ITEM(FRUIT,pears)
@ ADD_ITEM(FRUIT,strawberries)
The new list contains: ~LIST_CONTENTS(FRUIT).
Now scan the list using a FOR loop:
@ FOR fruit=~LIST_CONTENTS(FRUIT)
Did I say that I really love fruit?
@ ENDFOR
Use this construct to generate a set of PHP assignments:
@ FOR fruit=~LIST_CONTENTS(FRUIT)
$fruit = $values[ 'fruit' ];
@ ENDFOR
Use this construct to generate a Java switch (TO_UPPER is
a Tefigel built-in function):
switch (f) {
@ FOR fruit=~LIST_CONTENTS(FRUIT)
case F_~TO_UPPER(fruit):
System.out.println("fruit"); break;
@ ENDFOR
}
|
The Tefigel script above produces the following output.
Sample use of FOR loop - Output [ File "for.out" ]
|
Here's a simple loop on a list of values:
I love apples.
I love pears.
I love strawberries.
Now create a list of types of fruit:
The new list contains: apples,pears,strawberries.
Now scan the list using a FOR loop:
Did I say that I really love apples?
Did I say that I really love pears?
Did I say that I really love strawberries?
Use this construct to generate a set of PHP assignments:
$apples = $values[ 'apples' ];
$pears = $values[ 'pears' ];
$strawberries = $values[ 'strawberries' ];
Use this construct to generate a Java switch (TO_UPPER is
a Tefigel built-in function):
switch (f) {
case F_APPLES:
System.out.println("apples"); break;
case F_PEARS:
System.out.println("pears"); break;
case F_STRAWBERRIES:
System.out.println("strawberries"); break;
}
|
The numeric loop is syntactically similar to the FOR loop, but
on each iteration a numeric increment (or decrement) gets added to
the loop variable
value until it reaches or exceeds the loop range limit.
An example follows.
Sample use of LOOP - Input [ File "loop.in" ]
|
Basic numeric loop with default increment (=1) and
integer values.
@ LOOP x=1,3
We are now on loop x, that is, "x".
@ ENDLOOP
Numeric loop with explicit decrement value (=-0.3) and
floating point values.
@ LOOP x=0,-1,-0.3
We are now on loop x, that is, "x".
@ ENDLOOP
|
The Tefigel script above produces the following output.
Sample use of LOOP - Output [ File "loop.out" ]
|
Basic numeric loop with default increment (=1) and
integer values.
We are now on loop 1, that is, "1".
We are now on loop 2, that is, "2".
We are now on loop 3, that is, "3".
Numeric loop with explicit decrement value (=-0.3) and
floating point values.
We are now on loop 0, that is, "0".
We are now on loop -0.300000000000000, that is, "-0.300000000000000".
We are now on loop -0.600000000000000, that is, "-0.600000000000000".
We are now on loop -0.900000000000000, that is, "-0.900000000000000".
|
The multiple choice construct of Tefigel is syntactically defined
as a CASE..WHEN..WHEN..OTHERWISE..ENDCASE statement.
The peculiarity of Tefigel's CASE construct lies in the
evaluation of the case variable, which may be tested for being equal,
not equal, or even similar to a given value. This logically
relates to Tefigel's IF and EVAL statements, that allow that same
set of different tests.
The following Tefigel script shows two examples of CASE use.
Sample use of CASE - Input [ File "case.in" ]
|
---
--- Simple CASE example
---
@ FOR color=red,yellow,green,blue
The traffic light now suggests you to...
@ CASE color
@ WHEN=red
stop, as it is color.
@ WHEN=yellow
hurry up or wait, as it is color.
@ WHEN=green
go, as it is color.
@ OTHERWISE
call the traffic light repairing service,
as it is color.
@ ENDCASE
@ ENDFOR
---
--- More sophisticated CASE example
---
@ FOR fruit=banana,strawberry,apple,pineapple
Let's compare this fruit with an apple:
@ CASE fruit
@ WHEN=apple
This <fruit> is definitely an apple.
@ WHEN~apple
This <fruit> sounds like an apple.
@ WHEN#apple
This <fruit> is not an apple.
@ WHEN>apple
This <fruit> comes after an apple.
@ ENDCASE
@ ENDFOR
|
The Tefigel script above produces the following output.
Sample use of CASE - Output [ File "case.out" ]
|
---
--- Simple CASE example
---
The traffic light now suggests you to...
stop, as it is red.
The traffic light now suggests you to...
hurry up or wait, as it is yellow.
The traffic light now suggests you to...
go, as it is green.
The traffic light now suggests you to...
call the traffic light repairing service,
as it is blue.
---
--- More sophisticated CASE example
---
Let's compare this banana with an apple:
This <banana> is not an apple.
This <banana> comes after an apple.
Let's compare this strawberry with an apple:
This <strawberry> is not an apple.
This <strawberry> comes after an apple.
Let's compare this apple with an apple:
This <apple> is definitely an apple.
This <apple> sounds like an apple.
Let's compare this pineapple with an apple:
This <pineapple> sounds like an apple.
This <pineapple> is not an apple.
This <pineapple> comes after an apple.
|
Additional details on these control flow
constructs are available in Tefigel's reference manual,
chapter 9.
The new instructions LINK and TRAP (and the corresponding UNLINK and
UNTRAP) allow to associate calls to Tefigel functions or subroutines
with textual variable identifiers. This feature allows to
seamlessly mix function and subroutine calls within text blocks,
and trigger thier execution, as shown in the example below.
These instructions are designed for advanced file-generation tasks,
such as associating special actions to pseudo-keywords or
pseudo-functions that can
be embedded within comments in the input files, and expanded at
generation time.
Sample use of LINK and TRAP - Input [ File "link_trap.in" ]
|
---
--- TRAP example
---
@ TRAP tb=text_block
Using the trapped identifier results in the associated
function being called. Parameters are not passed to the function.
When referring to string tb,
funny things may happen or not.
Try it with params: "tb(with,3,params)".
@ UNTRAP tb
Using the previously trapped identifier has no special effect.
When referring to string tb,
funny things may happen or not.
Try it with params: "tb(with,3,params)".
---
--- LINK example
---
@ LINK tb=text_block
Using the linked identifier results in the associated
function being called. Parameters are passed to the function.
When referring to string tb,
funny things may happen or not.
Try it with params: "tb(with,3,params)".
@ UNLINK tb
Using the previously linked identifier has no special effect.
When referring to string tb,
funny things may happen or not.
Try it with params: "tb(with,3,params)".
|
The Tefigel script above produces the following output.
Sample use of LINK and TRAP - Output [ File "link_trap.out" ]
|
---
--- TRAP example
---
Using the trapped identifier results in the associated
function being called. Parameters are not passed to the function.
When referring to string Return a plain text block,
funny things may happen or not.
Try it with params: "Return a plain text block(with,3,params)".
Using the previously trapped identifier has no special effect.
When referring to string tb,
funny things may happen or not.
Try it with params: "tb(with,3,params)".
---
--- LINK example
---
Using the linked identifier results in the associated
function being called. Parameters are passed to the function.
When referring to string Return a plain text block,
funny things may happen or not.
Try it with params: "Return reverted params [params,with,3]".
Using the previously linked identifier has no special effect.
When referring to string tb,
funny things may happen or not.
Try it with params: "tb(with,3,params)".
|
The Tefigel script above uses the following function.
Sample use of LINK and TRAP - External function [ File "text_block" ]
|
@ INTERFACE(P1,P2,P3)
@ IF REG_COUNT=0
@ RETVALUE=Return a plain text block
@ ELSE
@ RETVALUE=Return reverted params [P3,P1,P2]
@ ENDIF
|
Additional details on these instructions
are available in Tefigel's reference manual,
chapter 16.
A new built-in function CHR returns the ASCII/ISO 8859-1 character
for the given integer number, which can be decimal, octal or hexadecimal.
This function helps embed control characters (typically, carriage return
and line feed) within variable values for later output.
Moreover, it is no longer necessary to explicitly
distinguish between Tefigel native instructions (lines
beginning with a "@") and user-defined instructions
associated with external macro files (lines
beginning with a "$").
The following example shows the changes described above.
Sample use of CHR and user-defined instructions - Input [ File "instr_chr.in" ]
|
---
--- Using built-in CHR
---
@ SET NEWLINE=10
@ SET TAB=9
@ SET s=This~CHR(NEWLINE)gets split~CHR(NEWLINE)~CHR(TAB)and tabbed.
---
s
---
Function CHR is particularly useful in conjunction with
LIST_CONTENTS, for instance to generate an HTML table row,
as follows.
@ NEW_LIST(FRUIT)
@ ADD_ITEM(FRUIT,apples)
@ ADD_ITEM(FRUIT,pears)
@ ADD_ITEM(FRUIT,strawberries)
A fruit list contains ~LIST_CONTENTS(FRUIT).
With additional parameters you can get more out of LIST_CONTENTS:
<tr>
~LIST_CONTENTS(FRUIT, <td>,</td>,,~CHR(NEWLINE))
</tr>
---
--- Native instructions and user-defined instructions
---
With tefigel 097 you had to call user-defined instructions
like this:
$ newinstr(Old mode)
With tefigel 098 you can call user-defined instructions
like this:
@ newinstr(New mode)
|
The Tefigel script above produces the following output.
Sample use of CHR and user-defined instructions - Output [ File "instr_chr.out" ]
|
---
--- Using built-in CHR
---
---
This
gets split
and tabbed.
---
Function CHR is particularly useful in conjunction with
LIST_CONTENTS, for instance to generate an HTML table row,
as follows.
A fruit list contains apples,pears,strawberries.
With additional parameters you can get more out of LIST_CONTENTS:
<tr>
<td>apples</td>
<td>pears</td>
<td>strawberries</td>
</tr>
---
--- Native instructions and user-defined instructions
---
With tefigel 097 you had to call user-defined instructions
like this:
Subroutine called with this "Old mode".
With tefigel 098 you can call user-defined instructions
like this:
Subroutine called with this "New mode".
|
The Tefigel script above uses the following macro.
User-defined instruction "newinstr" - External macro [ File "newinstr" ]
|
@ INTERFACE(message)
Subroutine called with this "message".
|
Full list of in-depth articles -
Feedback and questions -
Request demo -
|