Leonardus
|
Compatibility ...
Leonardus returns a language level 4. This can be used to code scripts
for both PostScript and LeoScipt. E.g.:
All the details are extracted from the source code into the chapter Operators.
The parser reads from the standard input stream, runs checks and normalizes
it into the leon-format on standard out.
Ignores the remainder of lines starting with %
.
Halts execution upon error detection.
Normalizes integer tokens by stripping leading plus signs.
Removes the opening and closing parentheses from the string.
Removes all single backslashes from the string, preserving double
backslashes (\\
) and newline sequences (\n
). These are the only
escape sequences recognized in the leon-format.
The -v option activates verbose mode.
The -h option prints a command line help.
This is a simple line-oriented format.
Each line begins with a character code followed by a colon (:
).
The code identifies the data type of the subsequent value.
The different codes and data types are:
. | Description |
---|---|
I | A signed integer |
R | A floating-point number |
B | A boolean literal |
S | An unquoted string with just two escape sequences \\ and \n |
N | A literal name token consisting of any characters but whitespaces |
X | An executable name token consisting of any characters but whitespaces |
# | The value is a comment |
E | An error message |
There are limits set by the parser to check the plausibility of the LeoScripts.
The maximum length of strings is 100,000 characters.
The maximum length of names is 1000 characters.
All strings and names can contain Unicode characters.
They are encoded using UTF-8.
Stack objects are used internally by the interpreter. They are used to
construct the data structures for the operand stack, the execution stack,
and the dictionary stack.
Additionally, stack objects are composite semantic objects such as arrays,
dictionaries, and strings.
Stack specific operators are:
Polymorphic operators working on stacks are: get, put, forall, type
Text representation for stacks: cvs, =, stack, __print, ==, pstack
Type agnostic operators: def, dup, cvx, cvlit, xcheck, where, known, exch,
load, roll, ...
Rational objects are used to store a fraction with arbitrary precision.
There is no limit check for the length of the numerator and denominator
which build the internal structure.
Specific operators for the rationals are:
Polymorphic operators working on rationals are:
Text representation for stacks: cvs, =, stack, __print, ==, pstack
Type agnostic operators: def, dup, cvx, cvlit, xcheck, where, known, exch,
load, roll, ...
The following operators extend LeoScript with OOP capabilities:
These operators are implemented in the vocabulary Prototype.
To create a new PTBO without a parent:
To create a new PTBO with a parent:
To override a member procedure of a parent PTBO:
To verify that a member procedure exists in a parent PTBO by using override
:
To enter the namespace of a PTBO and define a member:
To enter the namespace of a PTBO and define a procedure:
To enter the namespace of a PTBO and call a member procedure:
To enter the namespace of a PTBO and call a member procedure in send semantics:
To call a core code operator, if it has been overridden in a PTBO namespace:
A ctor supporting chaining:
To create an PTBO with a constructor with parameters:
To use the object chaining of the new operator:
The ctor is a normal procedure:
Object chaining:
__ctor__
is called if there is one.
__ctor__
can consume SOs from the operand stack, but must not store
an SO on the operand stack.
IDEA: details...
LeoScript supports the concept of polymorphism, implemented through operator
overloading. For example, the 'add' operator can handle integers, real
numbers, and rational numbers with the same semantics. Using polymorphic
operators allows the programming of procedures or algorithms built on top of
them, which also become polymorphic. A useful example here is the
implementation of 'binom'.
LeoScript provides generic containers. Both arrays and dictionaries can hold
objects of any type.
There are the operators '__one' and '__zero' to programm constant numeric
values.
See VOCABULARY
Leonardus supports a shebang line
#!/usr/bin/env lb
by ignoring it as first line in LeoScript files. Together with the normal
Linux executable file attibute you get the possibility to start
scripts directly. This is implemented in the Example
directory scripts.
The composite semantic objects can contain other composite semantic objects,
creating trees of objects. All existing semantic objects are part of one of
the three fundamental interpreter stacks: the operand stack, the execution
stack, and the dictionary stack. Loops are not allowed in these trees and
will be detected during runtime by a heuristic.
The loop detection is implemented as a member function
SOcomposite::treeheight()
, which calculates the height of the trees and
stops the calculation if the height reaches a threshold of maxtreeheight
.
quit )
is a valid programm. While the parser finds the syntax error, the execution
of the quit operator prevents it from taking effect.
1 { 1
is a valid programm. The interpreter exits by ignoring the open procedure.
/X { X } def X
generates an infinite loop of the intepreter. It is very hard to identify
this kind of problems, because with an exit criterion between {
and X
it was a perfectly valid script!