D I E S E L
Dumb Interpretively Evaluated String Expression Language
This "Dumb Interpretively Executed String Expression Language" is the
kernel of a macro language you can customise by adding C code and
embedding it into your program.
It is short, written in portable C, and is readily integrated into any
program. It is useful primarily to programs which need a very
rudimentary macro expansion facility without the complexity of a full
language such as Lisp or FORTH.
DIESEL copies its input directly to the output until a macro
character, "$" or quoted string is encountered. Quoted strings may be
used to suppress evaluation of sequences of characters which would
otherwise be interpreted as macros. Quote marks may be included in
quoted strings by two adjacent quote marks. For example:
"$(if,1,True,False)="""$(if,1,True,False)""""
Status retrieval, computation, and display are performed by DIESEL
functions. The available functions are as follows. User-defined
functions are not implemented; what you see is all you've got.
Naturally, if you embed DIESEL in your application, you'll add
functions that provide access to information and actions within your
own program. DIESEL's arithmetic functions accept either floating
point or integer arguments, and perform all calculations in floating
point.
DIESEL String Functions
- $(+,val1,val2,...valn)
- The sum of the numbers val1, val2,
...valn is returned.
- $(-,val1,val2,...valn)
- The result of subtracting the numbers val2 through valn from
val1 is returned.
- $(*,val1,val2,...valn)
- The result of multiplying the numbers val1,val2,...valn is
returned.
- $(/,val1,val2,...valn)
- The result of dividing the number val1 by val2,...valn is
returned.
- $(=,val1,val2)
- If the numbers val1 and val2 are equal 1 is returned,
otherwise 0 is returned.
- $(<,val1,val2)
- If the number val1 is less than val2 1 is returned, otherwise
0 is returned.
- $(>,val1,val2)
- If the number val1 is greater than val2 1 is returned,
otherwise 0 is returned.
- $(!=,val1,val2)
- If the numbers val1 and val2 are not equal 1 is returned,
otherwise 0 is returned.
- $(<=,val1,val2)
- If the number val1 is less than or equal to val2 1 is
returned, otherwise 0 is returned.
- $(>=,val1,val2)
- If the number val1 is greater than or equal to val2 1 is
returned, otherwise 0 is returned.
- $(AND,val1,val2,...valn)
- The bitwise logical AND of the integers val1 through valn is
returned.
- $(EQ,val1,val2)
- If the strings val1 and val2 are identical 1 is returned,
otherwise 0.
- $(EVAL,str)
- The string str is passed to the DIESEL evaluator and the result
of evaluating it is returned.
- $(FIX,value)
- The real number value is truncated to an integer by discarding
any fractional part.
- $(IF,expr,dotrue,dofalse)
- If expr is nonzero, dotrue is evaluated and returned.
Otherwise, dofalse is evaluated and returned. Note that the
branch not chosen by expr is not evaluated.
- $(INDEX,which,string)
- string is assumed to contain one or more values delimited by the
macro argument separator character, comma. which selects one of
these values to be extracted, with the first item numbered zero.
- $(NTH,which,arg0,arg1,argN)
- Evaluates and returns the argument selected by which. If
which is 0, arg0 is returned, and so on. Note the difference
between $(NTH) and $(INDEX); $(NTH) returns one of a series of
arguments to the function while $(INDEX) extracts a value from a
comma-delimited string passed as a single argument. Arguments not
selected by which are not evaluated.
- $(OR,val1,val2,...valn)
- The bitwise logical OR of the integers val1 through valn is
returned.
- $(STRFILL,string,ncopies)
- Returns the result of concatenating ncopies of string.
- $(STRLEN,string)
- Returns the length of string in characters.
- $(SUBSTR,string,start,length)
- Returns the substring of string starting at character start
and extending for length characters. Characters in the string
are numbered from 1. If length is omitted, the entire remaining
length of the string is returned.
- $(UPPER,string)
- The string is returned converted to upper case according to the
rules of the current locale.
- $(XOR,val1,val2,...valn)
- The bitwise logical XOR of the integers val1 through valn is
returned.
Starting DIESEL
You invoke DIESEL within your program by calling:
int status;
char instring[whatever], outstring[MAXSTR + 1];
status = diesel(instring, outstring);
The output from the evaluation will be stored in outstring when
control is returned to your program. If no errors were detected
during evaluation, status
will be zero. Otherwise status
gives the
character position within instring at which the error was detected.
If an error occurs, DIESEL will include an error diagnostic,
documented below, in outstring
.
DIESEL Mechanics
Generally, if you mess something up in a DIESEL expression it's pretty
obvious what went wrong. DIESEL embeds an error indication in the
output stream depending on the nature of the error:
- $?
- Syntax error (usually a missing
right parenthesis or runaway string).
- $(func,??)
- Incorrect arguments to func.
- $(func)??
- Unknown function func.
- $++
- Output string too long--evaluation truncated.
Variable Extensions
The base-line DIESEL includes no user-defined variables. This
allows DIESEL to avoid allocating any local memory and renders it
totally reentrant. If you compile DIESEL with the tag VARIABLES
defined, the following additional functions are included which
provide variable definition and access. Note that these functions
call malloc() and strdup() and thus consume heap storage.
- $(GETVAR,varname)
- Returns the value stored in varname. If no variable with the
name varname exists, a bad argument error is reported.
- $(SETVAR,varname,value)
- Stores the string value into varname. If no variable called
varname exists, a new variable is created.
Unix Extensions
If you compile DIESEL with the tag UNIXTENSIONS
defined, the following additional functions will be available:
- $(GETENV,varname)
- Returns the variable varname from the environment. If no such
variable is defined, returns the null string.
- $(TIME)
- Returns the current time in Unix fashion, as the number of seconds
elapsed since 00:00:00 GMT January 1, 1970.
- $(EDTIME,time,picture)
- Edit the Unix time time to format picture. If time is 0,
the current date and time is edited (this is just shorthand for
the equivalent "$(EDTIME,$(TIME),picture)".).
Assume the date is: Thursday, 2 September 1993 4:53:17
Format phrases:
D 2
DD 02
DDD Thu
DDDD Thursday
M 9
MO 09
MON Sep
MONTH September
YY 93
YYYY 1993
H 4
HH 04
MM 53
SS 17
AM/PM AM
am/pm am
A/P A
a/p a
If any of the "AM/PM" phrases appear in the picture, the "H"
and "HH" phrases will edit the time according to the 12 hour
civil clock (12:00-12:59-1:00-11:59) instead of the 24 hour
clock (00:00-23:59).
Distribution Details
DIESEL is in the public domain; you can do anything you like with it.
DIESEL is supplied as a GZIPped TAR archive,
diesel.tar.gz.
The following files will be present in the directory after the
extraction is complete:
BCMAKE.BAT Batch file to build with Borland C on MS-DOS.
DIESEL.C Complete source code, including a built-in test
program.
MAKEFILE Make file for Unix.
MANIFEST List of files in the distribution.
MSCMAKE.BAT Batch file to build with Microsoft C 7.0.
REGRESS.DSL Diesel regression test script.
REGRESS.MAS Regression test master output file.
UTEST.DSL Test for the Unix extensions to DIESEL.
All files are distributed in MS-DOS end of line convention
(CR/LF). You may have to convert them to the native end of line
convention of your system before compiling. DIESEL has been built
and regression tested without errors on the following systems:
Sun SPARCStation 2, SunOS 4.1.1
MS-DOS, Borland C 2.0
MS-DOS, Microsoft C 7.0
DIESEL Power Not Enough?
If DIESEL looks intriguing, but too small and simple for
the application you have in mind, please check out
ATLAST, my
FORTH-based open application toolkit. ATLAST, although much
larger and more complicated than DIESEL, is a full-fledged
programming language which provides the speed of compiled code,
multiple data types, user-defined functions and data types, and
just about everything you'll need to make a closed application
user programmable.
by John Walker
kelvin@fourmilab.ch