Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 uid=99(nobody) gid=98(nobody) groups=98(nobody) Safe-mode: OFF (not secure) /usr/doc/slang-1.4.5/html/ drwxr-xr-x | |
| Viewing file: Select action/file-type: 3. Interpreter Interface
The S-Lang library provides an interpreter that when embedded into an application, makes the application extensible. Examples of programs that embed the interpreter include the jed editor and the slrn newsreader. Embedding the interpreter is easy. The hard part is to decide what application specific built-in or intrinsic functions should be provided by the application. The S-Lang library provides some pre-defined intrinsic functions, such as string processing functions, and simple file input-output routines. However, the basic philosophy behind the interpreter is that it is not a standalone program and it derives much of its power from the application that embeds it.
3.1 Embedding the Interpreter
Only one function needs to be called to embed the S-Lang interpreter
into an application:
This function does not provide file input output intrinsic nor does
it provide mathematical functions. To make these as well as some
posix system calls available use
If you intend to enable all intrinsic functions, then it is simpler
to initialize the interpreter via
See the \slang-run-time-library for more information about the
intrinsic functions.
3.2 Calling the Interpreter
There are several ways of calling the interpreter. The most common
method used by both jed and slrn is to use the
The SLang_load_file function returns zero upon if successful, or -1
upon failure. The SLang_restart function resets the
interpreter back to its default state; however, it does not reset
SLang_Error to zero. It is up to the application to
re-initialize the SLang_Error variable.
There are several other mechanisms for interacting with the
interpreter. For example, the
Typically, an interactive application will load a file via
Both jed and slrn use another method of interacting with the interpreter. They read key sequences from the keyboard and map those key sequences to interpreter functions via the S-Lang keymap interface.
3.3 Intrinsic Functions
An intrinsic function is simply a function that is written in C and is made available to the interpreter as a built-in function. For this reason, the words `intrinsic' and `built-in' are often used interchangeably. Applications are expected to add application specific functions to the interpreter. For example, jed adds nearly 300 editor-specific intrinsic functions. The application designer should think carefully about what intrinsic functions to add to the interpreter.
Restrictions on Intrinsic Functions
Intrinsic functions are required to follow a few rules to cooperate with the interpreter. Intrinsic function must take only pointer arguments. This is because when the interpreter calls an intrinsic function, it passes value to the function by reference and not by value. For example, intrinsic with the declarations:
are all valid. However,
is not valid since the len parameter is not a pointer.
Intrinsic functions can only return
is not permitted since it does not return one of these types. The
current implementation limits the number of arguments to 7.
Another restriction is that the intrinsic should regard all its parameters as pointers to constant objects and make no attempt to modify the value to which they point. For example,
is illegal since the function modifies the string s.
Adding a New Intrinsic
There are two basic mechanisms for adding an intrinsic function to the
interpreter: As an specific example, consider a function that will cause the
program to exit via the
This function may be made available to the interpreter as as an
intrinsic via the SLadd_intrinsic_function routine:
This statement basically tells the interpreter that
intrin_exit is a function that returns nothing and takes a
single argument: a pointer to an integer (SLANG_INT_TYPE).
A user can call this function from within the interpreter
via
After printing a message, this will cause the intrin_exit
function to execute, which in turn calls exit.
The most convenient mechanism for adding new intrinsic functions is
to create a table of
Construction of the table entries may be facilitated using a set of
MAKE_INTRINSIC macros defined in slang.h. The main
macro is called MAKE_INTRINSIC_N and takes ?? arguments:
Here name is the name of the intrinsic function that the
interpreter is to give to the function. func-ptr is a pointer
to the intrinsic function taking num-args and returning
ret-type. The final 7 arguments specifiy the argument
types. For example, the intrin_exit intrinsic described above
may be added to the table using
While
See slang.h for related macros. You are also encouraged to
look at, e.g., slang/src/slstd.c for a more extensive examples.
The table may be added via the
Please note that there is no need to load a given table more than
once, and it is considered to be an error on the part of the
application it adds the same table multiple times. For performance
reasons, no checking is performed by the library to see if a table
has already been added.
Earlier it was mentioned that intrinsics may be added to a specified
namespace. To this end, one must first get a pointer to the
namespace via the
More Complicated IntrinsicsThe intrinsic functions described in the previous example were functions that took a fixed number of arguments. In this section we explore more complex intrinsics such as those that take a variable number of arguments. Consider a function that takes two double precision numbers and returns the lesser:
This function may be added to a table of intrinsics using
It is useful to extend this function to take an arbitray number of
arguments and return the lesser. Consider the following variant:
Here the number to compare is passed to the function and the actual
numbers are removed from the stack via the SLang_pop_double
function. A suitable table entry for it is
This function would be used in an interpreter script via a statement
such as
which computes the smallest of 5 values.
The problem with this intrinsic function is that the user must explicitly specify how many numbers to compare. It would be more convenient to simply use
An intrinsic function can query the value of the variable
SLang_Num_Function_Args to obtain the necessary information:
This may be declared as an intrinsic using:
3.4 Intrinsic Variables
It is possible to access an application's global variables from
within the interpreter. The current implementation supports the
access of variables of type There are two basic methods of making an intrinsic variable
available to the interpreter. The most straight forward method is
to use the function
For example, suppose that I is an integer variable, e.g.,
One can make it known to the interpreter as I_Variable via a
statement such as
Similarly, if S is declared as
then
makes S available as a read-only variable with the name
S_Variable. Note that if a pointer variable is made available
to the interpreter, its value is managed by the interpreter and
not the application. For this reason, it is recommended that such
variables be declared as read-only.
It is important to note that if
then it would not be possible to make it directly available to the
interpreter. However, one could create a pointer to it, i.e.,
and make S_Ptr available as a read-only variable.
One should not make the mistake of trying to use the same address for different variables as the following example illustrates:
Not only does this piece of code create intrinsic variables that use
the same address, it also uses the address of a local variable that
will go out of scope.
The most convenient method for adding many intrinsic variables to
the interpreter is to create an array of
may be added via
It should be rather obvious that the arguments to the
MAKE_VARIABLE macro correspond to the parameters of the
SLadd_intrinsic_variable function.
Finally, variables may be added to a specific namespace via the SLns_add_intrin_var_table and SLns_add_intrinsic_variable functions.
3.5 Aggregate Data ObjectsAn aggregate data object is an object that can contain more than one data value. The S-Lang interpreter supports several such objects: arrays, structure, and associative arrays. In the following sections, information about interacting with these objects is given.
ArraysAn intrinsic function may interact with an array in several different ways. For example, an intrinsic may create an array and return it. The basic functions for manipulating arrays include:
The use of these functions will be illustrated via a few simple
examples.
The first example shows how to create an return an array of strings to the interpreter. In particular, the names of the four seasons of the year will be returned:
This example illustrates several points. First of all, the
SLang_create_array function was used to create a 1 dimensional
array of 4 strings. Since this function could fail, its return value
was checked. Then the SLang_set_array_element function was
used to set the elements of the newly created array. Note that the
address containing the value of the array element was passed and not
the value of the array element itself. That is,
was not used. The return value from this function was also checked
because it too could also fail. Finally, the array was pushed onto
the interpreter's stack and then it was freed. It is important to
understand why it was freed. This is because arrays are
reference-counted. When the array was created, it was returned with
a reference count of 1. When it was pushed, the reference
count was bumped up to 2. Then since it was nolonger needed by
the function, SLang_free_array was called to decrement the
reference count back to 1. For convenience, the second
argument to SLang_push_array determines whether or not it is to
also free the array. So, instead of the two function calls:
it is preferable to combine them as
The second example returns a diagonal array of a specified size to the stack. A diagonal array is a 2-d array with all elements zero except for those along the diagonal, which have a value of one:
In this example, only the diagonal elements of the array were set.
This is bacause when the array was created, all its elements were
set to zero.
Now consider an example that acts upon an existing array. In particular, consider one that computes the trace of a 2-d matrix, i.e., the sum of the diagonal elements:
In this example, SLang_pop_array_of_type was used to pop an
array of doubles from the stack. This function will make implicit
typecasts in order to return an array of the requested type.
Structures
For the purposes of this section, we shall differentiate structures according to whether or not they correspond to an application defined C structure. Those that do are called intrinsic structures, and those do not are called S-Lang interpreter structures.
Interpreter Structures
The following simple example shows how to create and return a structure to the stack with a string an integer field:
Here, SLstruct_create_struct was used to push a
structure with the specified field names and values onto the
interpreter's stack.
Intrinsic Structures
Here we show how to make intrinsic structures available to the interpreter. The simplest interface is to structure pointers and not to the actual structures themselves. The latter would require the interpreter to be involved with the creation and destruction of the structures. Dealing with the pointers themselves is far simpler. As an example, consider an object such as
which defines a window object with a title, size (width,
height), and location (row, col).
We can make variables of type
More precisely, this defines the layout of the Window_Type structure.
Here, the title has been declared as a read-only field. Using
would allow read-write access.
Now suppose that
We can make this variable available to the interpreter via the
SLadd_istruct_table function:
This creates a S-Lang interpreter variable called My_Win whose value
corresponds to to the My_Win structure. This would permit one to
access the fields of My_Window via S-Lang statements such as
It is extremely important to understand that the interface described in
this section does not allow the interpreter to create new instances of
One should be careful in allowing read/write access to character string
fields. If read/write access is allowed, then the application should
always use the
is not permitted since char name[32] is not a
SLANG_STRING_TYPE object.
Next Previous Contents |
:: Command execute :: | |
--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0251 ]-- |