![]() |
![]() |
Running the SeL interpreter
The SeL interpreter can be executed as an Apache Content Handler or
manually form a shell command line. The following command line options
are defined:
Interpreter, compile- and runtime mode
Since version 0.5 the compilation of SeL programs can be done separately
from their execution. The command
|
|
Compiled SeL files have a couple of nice features:
(The stack machine's specification is available from the author.)
|
The following is a comparison of a SeL object file execution to a full SeL source code compilation. The tests were run on the same file (the GhK homepage). This is the output of UNIX "time".
Timings for SeL source code:real 0m0.603s user 0m0.430s sys 0m0.100s real 0m0.570s user 0m0.440s sys 0m0.060s real 0m0.577s user 0m0.450s sys 0m0.060s real 0m0.557s user 0m0.420s sys 0m0.090s real 0m0.563s user 0m0.450s sys 0m0.070s real 0m0.572s user 0m0.450s sys 0m0.080s real 0m0.565s user 0m0.430s sys 0m0.080s real 0m0.567s user 0m0.440s sys 0m0.060s real 0m0.562s user 0m0.430s sys 0m0.080s real 0m0.555s user 0m0.430s sys 0m0.070s |
Timings for compiled object file:real 0m0.204s user 0m0.100s sys 0m0.030s real 0m0.188s user 0m0.090s sys 0m0.050s real 0m0.172s user 0m0.090s sys 0m0.040s real 0m0.168s user 0m0.090s sys 0m0.050s real 0m0.168s user 0m0.100s sys 0m0.040s real 0m0.186s user 0m0.090s sys 0m0.060s real 0m0.170s user 0m0.100s sys 0m0.040s real 0m0.168s user 0m0.100s sys 0m0.050s real 0m0.164s user 0m0.090s sys 0m0.050s real 0m0.183s user 0m0.090s sys 0m0.040s |
=GRUSS "Hello"; |
Every declaration ends with a semicolon (";"). The semicolon is required as SeL allows declaration nesting (see below). Forgetting a semicolon after a declaration may not necessarily cause syntax errors, as SeL will probably still see a legal synatx. But this syntax contains unexpected declaration nestings which will cause consequent errors or strange behaviour. Please make sure to finish every declaration by a semicolon.
More than one value may be assigned to a variable. Old values will be overwritten by new ones::
=GRUSS "Hello"; =GRUSS "Good morning"; |
=GRUSS "He said "Hello""; |
=GRUSS <SQD>He said "Hello"</SQD>; |
=GRUSS "SeL strings can be delimited by <SQD> sequences!"; |
=GRUSS "first line second line third line" ; |
In SeL, quotation marks always have the same meaning. The only exception are HTML triggers (see below).
The comment syntax is C like. As is C, comments may not be nested. Comments start with /*and end with */:
/* The following is a declatation of a three line string. BTW: This is a comment. */ =GRUSS "first line second line third line" ; |
Another way to comment source code is the "#if 0" syntax. As nesting of "/* foo */"-like comments is illegal, this (also C-like) construct allows to out-comment entire source blocks including contained comments. This is especially useful to de-activate parts of SeL code during development. It works like this:
#if 0 /* The following is a declaration of a three line string. BTW: This is a comment. */ =GRUSS "first line second line third line" ; #endif =GRUSS "Hallo"; |
#if 1 /* The following is a declaration of a three line string. BTW: This is a comment. */ =GRUSS "first line second line third line" ; #endif =GRUSS "Hello"; |
In contrast to C, after "#if" no other expressions are evaluated. Only "0" and "1" are legal.
$GRUSS |
=NAME "Andreas"; =GRUSS "Hello, my name is "$NAME; |
Declarations by implicit variable/value linkage can become very long and complex. Within the right side of declarations, further declarations, function calls, loops etc. may occur (these are discussed below). All these constructs return values which are included into the superior declaration. The following is an example of a complex declaration. In detail, it might be incomprehensible at this point of this reference, but it can give an impression of the possible complexity of declarations in SeL:
=c if ($a!=$b) then "not equal" else "equal" fi " " $_env("PATH") " " <SQD>Now a substring of "Hello", starting with character 1 with a length of 3 characters: </SQD> $_copy( "Hello", 1, 3 ) <SQD> The same with a length of 99 characters: </SQD> $_copy( "Hello", 1, 99 ) " Character No. 4 (should be o): " $_copy( "Hello", 4, 1 ) " Let's see where de matches uni-kassel.de: " $_match( "uni-kassel.de", "de" ) " Let's see where com matches uni-kassel.de: " $_match( "uni-kassel.de", "com" ) " Let's see where kassel matches uni-kassel.de: " $_match( "uni-kassel.de", "kassel" ) " And now again the last four characters of Hello: " =startpos $_len("Hello")-4; $_copy( "Hallo", $startpos, 999 ) ; |
=a "A"; =b =b1 "B1"; =b2 "B2"; ; =c $a$b; |
=a "Hello "; =b "world"; =c $a$b; $c. |
The program begins its visible execution at the expression "$c". "$c" is evaluated and expanded to "$a$b". $a is "Hello " and $b contains the value "world". Therefore, $c is "Hello World" and as $c is the start symbol, its content is returned as this SeL program's output.
Actually, a SeL program does not need a start symbol. The following example is syntactically correct:
=a "Hello "; =b "world"; =c $a$b; |
!a(void) "Hello "; !b(void) "world"; =c $a()$b(); $c. |
Here, we are interested in the runtime model. Again, at first the start symbol "$c" is evaluated, which calls the functions "a" and "b", which generate the values "Hello " and "world". So far, everything sounds pretty much like the program using plain variable declarations and the program output is the same. Now, where is the difference?
In one sentence: Variable declarations are executed immediately, wherever the interpreter finds a declaration. Functions are only evaluated when they are called. Now both programs again, this time with line numbers. Below we are going to discuss both versions' runtime and the order of line execution.
Variante A: Variablen
A1: =a "Hallo "; A2: =b "world"; A3: =c $a$b; A4: $c. |
Variante B: Funktionen
B1: !a(void) "Hello "; B2: !b(void) "world"; B3: =c $a()$b(); B4: $c. |
As a conclusion: The most secure way to write a SeL program is using functions. Under all conditions, they are more likely to work as expected. But they are a bit less handy to program and their runtime might be slower (as multiple calls will result in multiple executions whereas multiple variable references are based on single assignments). Authors who have understood this, will be able to optimize their code by replacing functions by variable assignments where it makes sense.
lib "ghk.mas"; |
Library test.mas
fwd NAME; !main(void) "Your name is: "$NAME ; $main(). |
Content file test.sel
lib "test.mas"; =NAME "Andreas"; |
In this case we also need a "forward" declaration (fwd) for the symbol NAME (first line in masterfile). A detailed discussion of forward declarations can be found in the following section.
It is possible (not unlike C) to include libraries in order to use functions which are not built into SeL. An example of such a library is percentbars.lib. It is part of this distribution. After including this library using the "lib" command, in the following part of the program the function $percentbar is available (please note the function name does not start with "$_" as this is not a built-in function). This function is implemented in percentbars.lib and based on function call arguments it returns HTML code, which graphic HTML browsers render as nice percent bars.
lib "percentbars.lib"; =BAR $percentbar("42","0","CENTER"); |
Result:
|
Copying the form of the example library it should be easily possible for you to develop your own libraries and to share them with other users. Please document your library's syntax and functionality within a comment in the library's top part and follow the naming converntion for library variable names shown in the example: Variable names in libraries always start with "lib.", then follows the name of the library, a "." and then an arbitrary string (see percentbars.lib). If you wrote a useful library you want to share with other users and developers, you may send it to us as an eMail and we will include it into the SeL distribution and publish it (eMail addresses at the start of this Documentation).
File ./test.mas Line 3: Error: Reference to undefined symbol /main/NAME at `NAME' |
"Your name is: "$NAME |
Therefore, we need the "fwd" command. Using
fwd NAME; |
=NAME ""; |
fwd LAYOUT INDEX URL KEYWORDS TITLE AUTHOR MAILTO DATE INSTITUTION INSTLOGO ADDRESS WIDTH UPLINK HELP HELPURL SEARCH SEARCHURL REMINDER SCRIPT CONTENT LANGUAGE LOCATION ADDTOBODY; |
If you know Turbo-Pascal, you will recognize "fwd" as a FORWARD declaration. In C there is a similar construct: the extern declaration of variables.
=GRUSS if ($NAME=="Andreas") then "Hello" else "Good morning" fi ; |
The else-branch is optional (not required):
=GRUSS if ($NAME=="Andreas") then "Hello" fi ; |
Relational operators
SeL's relational operators are C-like. This is an overview:
relational operation SeL symbol
Equal ==
Not equal !=
Less <
Greater >
Less or equal <=
Greater or equal >=
=NUMBERS for (i,1,9) do $i" " done ; |
In order to count with iterations other than 1, a fourth (optional) argument declaring the iteration (step) is required:
=NUMBERS for (i,9,1,"-2") do $i" " done ; |
=RESULT :again "loop content..." if ($repeat()!="no") then goto again fi ; |
A position label (anchor) is defined like this:
:jumphere |
goto jumphere |
Function call: | _hex( digits, decimal ) |
Description: | converts decimal to hexadecimal |
Example: | $_hex(2,15) |
Result: | 0F |
Parameters: | digits: number of result digits decimal: decimal value which is to be converted |
Function call: | _dec( digits, hex ) |
Description: | converts hexadecimal to decimal |
Example: | $_dec(2,"A") |
Result: | 10 |
Parameters: | digits: number of result digits hex: hexadecimal value which is to be converted |
Function call: | _len( string ) |
Description: | returns the length of a string |
Example: | $_len("Hello") |
Result: | 5 |
Parameters: | string: string of which the length is to be evaluated |
Function call: | _copy( string, startpos, count ) |
Description: | Returns a part of a string |
Example: | $_copy( "Hello", 1, 3 ) |
Result: | ell |
Parameters: | string: original string startpos: first character of the result (starts at 0!) count:number of characters to be extracted |
Function call: | _match( string, substring ) |
Description: | Searches for a substring in a string and returns the start postion of a match. Returns "-1" if no match was found. |
Example: | $_match("uni-kassel.de", "de") |
Result: | 11 |
Parameters: | string: Original string substring: substrung to be searched for |
Function call: | _bstrip( text ) |
Description: | Returns the part of "text" which occurs between <BODY> and </BODY>. |
Example: | $_bstrip($_include("http://www.uni-kassel.de")) |
Result: | Text between <BODY> and </BODY> (exclusively) |
Parameters: | text: A text variable, text constant or function value (containing HTML source code). |
Anmerkung: |
Also see functions _include() and _frl. If no <BODY> occurs in "text", the entire content of "text" (if need be including a closing </BODY>) is returned. If "text" contains <BODY> but no </BODY>, "text" is returned beginning at <BODY> to string end. |
Function call: | _frl( text ) |
Description: | Replaces relative HTTP links with abslute ones ("Fix Relative Links"). |
Example: | $bstrip($_frl($_include("http://www.uni-kassel.de"))) |
Result: | The BODY section of document http://www.uni-kassel.de, in which all relative hyperlinks are replaced with absolute ones. |
Parameters: | text: A text variable, text constant or function value (containing HTML source code with a BASE-HREF-Tag). |
Anmerkung: | Also see functions _include() and _bstrip(). For the expansion of relative links a BASE HREF tag is required in "text" (this is generated by $_include which uses Lynx). If no BASE-HREF tag is found, links are not converted. |
Function call: | _toupper( text ) |
Description: | Converts lowercase characters in "text" to uppercase characters. |
Example: | $_toupper("SeL") |
Result: | SEL |
Parameters: | text: A variable containing text, a constant or a function value. |
Remarks: | See also function _tolower(). |
Function call: | _tolower( text ) |
Description: | Converts uppercase characters in "text" to lowercase characters. |
Example: | $_toupper("SeL") |
Result: | sel |
Parameters: | text: A variable containing text, a constant or a function value. |
Remark: | See also function _toupper(). |
Function call: | _env( name ) |
Description: | Returns the value on an environment variable. |
Example: | $_env("REMOTE_HOST") |
Result: | hrz-ws48.hrz.uni-kassel.de |
Parameters: | name: Name of environment variable |
Function call: | _date( format ) |
Description: | Returns system time |
Example: | $_date("%d %h %Y: %H:%M:%S") |
Result: | 26 May 1999: 17:17:23 |
Parameters: | format: Output format. This parameter is evaluated as parameters of the C funcation strftime(). See man page for details. |
Function call: | _dirname( pfad ) |
Description: | Returns directory path section of a UNIX file path. |
Example: | $_dirname("/home/WWW/docs/Welcome.ghk") |
Result: | /home/WWW/docs |
Parameters: | pfad: absolute path. The directory path section is given as of the UNIX command "dirname". The path does not have to exist.. |
Function call: | _include( path ) |
Description: | Returns the content of a file |
Example: | $_include("/etc/motd") |
Result: | [file content] |
Parameters: | path: absolute path of a file which is to be included. Th epath is security-checked and has to be released by the SeL Administrator. In case of an error the error message is returned. SeL commands contained in included files are not evaluated and quoted as plain text. To include SeL code (libraries) see lib. |
Remark: | In earlier SeL versions this function was called _source. For compatibility reasons, this name is still recognized, but _include should be used. |
Function call: | _include( URL ) |
Description: | Returns HTML source code of online document "URL" |
Example: | $_include("http://www.uni-kassel.de") |
Result: | [HTML text] |
Parameters: | URL: complete and valid URL. This function is only available if it was activated by the SeL administrator. Otherwise an error occurs. Currently, only the protocol "http" is supported. |
Remark: | Also see functions _bstrip() and _frl(). |
Function call: | $_read() |
Description: | Reads CGI post query string from standard input. |
Example: | =cgi.in $_read(); |
Result: | CGI post query string |
Parameters: | none |
Remark: | See also $_cgiparse() for parsing of CGI variables/values und $_cgival() for evaluation of particular CGI variables. |
Function call: | $_cgiparse() |
Description: | Converts CGI query strings to variable/value pairs and converts contained special character hex codings back to ASCII. |
Example: | $_cgiparse($_read) |
Result: | Internally resolved CGI variables and their values. |
Parameters: | text: a string in CGI query syntax (POST). |
Remark: | $_cgiparse() typically first requires $_read(). See also $_read() for parsing of CGI query strings and $_cgival() for extraction of contained values. Parts of this builtin function are based on Thomas Boutell's C library "cgic" . |
Function call: | $_cgival() |
Description: | Returns the value of a CGI variable.. |
Example: | $_cgival("element") |
Result: | The value, which was assigned to a HTML form element before submission to the current document. |
Parameters: | text: A CGI variable name (the name of a submitted form element). |
Remark: | $_cgival() typically first requires $_read() and then $_cgiparse(). See also $_read() for reading the CGI query string and $_cgiparse() for parsing it. Parts of this builtin function are based on Thomas Boutell's C library "cgic" |
Function call: | _setcookie( name, value ) |
Description: | Generates HTML code to set a Cookie with the name "name" and value "value". |
Example: | $_setcookie( "prinzen", "rolle" ) |
Result: | <meta http-equiv="set-cookie" content="prinzen=rolle;path=/;"> |
Parameters: | name: Name of the Cookie value: value which is to be assigned to the Cookie. |
Remark: | SeL only generates the HTML code required toset the Cookie. The masterfile is responsible to include this code in the HEAD of its HTML output (Cookies will not work in HTML s). Currently, this functions provides no means to set a Cookie's Expiration-Date. |
Function call: | _getcookie( name ) |
Description: | Returns the value of a Cookie with the name "name". |
Example: | $_getcookie( "prinzen" ) |
Result: | rolle |
Parameters: | name: Name of the Cookie |
Anmerkung: | If no Cookie was set, this function returns an empty string. |
Function call: | _selversion |
Description: | Returns the verion number of the SeL interpreter |
Example: | $_selversion |
Result: | $Id: sprache.html,v 1.5 2000/03/24 23:29:39 andy Exp $ |
Parameters: | none |
Remark: | Actually, _selversion is a predefined variable and not a function. |
Name: | #if |
Description: | Conditional compiling of SeL code |
Example: | #if 0 ... ... #endif |
Result: | The code between "#if 0" and "#endif" will be ignored. Changing "#if 0" to "#if 1" activates the section. |
Parameters: | 0 or 1 |
Remark: | In contrast to the analog construct in C, 0 and 1 are the only legal parameters. |
Function call: | lib "file" |
Description: | Includes an external file containing SeL code (library) into te program. |
Example: | lib "ghk.mas" |
Result: | [content of file ghk.mas] |
Parameters: | file: file name. A file with this name has to exist in a directory which was released by the SeL administrator for this purpose. It can be expressed relatively of absolutely. Relatively expressed names are assumed to reside an a search path specified by the SeL administrator. |
Remark: | In contrast to _include() the content of the file is executed, not only included. In previous SeL versions, this directive was called "#include". For compatibility reasons, this syntax is still supported, bt it should not be used anymore. |
Triggers are defined with the command html_trigger:
Arrays
References to invalid array elements
User defined functions
References to functions as variables
HTML-Trigger
Since version 05-11 SeL supports Triggers: They provide a simple means
to replace HTML tags by functions which, instead of being displayed directly,
are replaced by arbitrary SeL code.
html_trigger tag; |
html_trigger H1; |
html_trigger H1; html_trigger H2; html_trigger BODY; |
html_start_tag( attributes ) |
html_end_tag( attributes ) |
!html_start_H1( attributes ) ... ... ; |
Trigger functions are automatically called with the tag attributes as a parameter (e.g. BGCOLOR in BODY). If no attrubutes are given, the parameter string is empty.
Trigger function return values always replace the original trigger tag in the SeL source file before the compilation continues. Therefore, trigger tags can be replaced by SeL command sequences of arbitrary comlexity.
Please note also, that SeL has no knowledge of HTML tags. Therefore trigger tags are also executed by non-standard pseudo tags and arbitrary XML tags. You may freely invent tags to trigger SeL functions.
An example for trigger usage is included in the SeL distribution as test19.sel.