Previous
|
Up
|
Next
|
Memory Allocation |
Primitives and EEL Subroutines |
Built-in and User Variables |
Epsilon User's Manual and Reference >
Primitives and EEL Subroutines >
Control Primitives >
The Name Table
int final_index()
Epsilon keeps track of all EEL
variables, commands, subroutines, key tables, color schemes, and
keyboard macros in its name table. Each of these items has an
entry there that lists its name, type, value, and additional
information. An EEL program can access the table using a numeric
index, like an array index. The first valid index to the name table
is 1, and the final_index( ) primitive returns the last valid
index. The index is based on the order in which the names were
defined.
All variables appear in the name table, including primitive
variables. Primitive functions (like most of those defined in this
chapter) and EEL's #define textual macros are not in the name
table. A state file contains an exact copy of a name table (plus
some additional information).
Each entry contains the name of the item, a type code, a
debugging flag, a help file offset, and whatever information Epsilon
needs internally to make use of the item. When executing an EEL
program, Epsilon automatically uses the table to find the value of a
variable, for example, or execute a command. You can
manipulate the table with EEL functions.
int find_index(char *name)
There are two ways to get
an index if you have the name of an item. The find_index( ) primitive
takes an item name as a string and returns the index of that item, or
0 if there is no such item. If the item is an EEL command or
subroutine, casting its function pointer to a short also yields the
index. For example, (short) forward_word gives the index of the
command forward-word if forward_word() has been declared
previously in the source file the expression appears in.
char *name_name(int index)
int name_type(int index) /* codes: */
#define NT_COMMAND 1 /* normal bytecode function */
#define NT_SUBR 2 /* hidden bytecode function */
#define NT_MACRO 3 /* keyboard macro */
#define NT_TABLE 4 /* key table */
#define NT_VAR 5 /* normal variable */
#define NT_BUFVAR 6 /* buffer-specific variable */
#define NT_WINVAR 7 /* window-specific variable */
#define NT_COLSCHEME 8 /* color scheme */
#define NT_BUILTVAR 9 /* built-in variable */
#define NT_AUTOLOAD 10 /* load cmd from file */
#define NT_AUTOSUBR 11 /* load subr from file */
The primitives
name_name( ) and name_type( ) return the name and
type of a
table
entry, respectively. They each take an index
into the name table and return the desired information. The value
returned by name_name( ) is only valid until the next call to this
function. Copy the name if you want to preserve it.
The codes for name_type( ) are in the standard include file
codes.h.
int try_calling(char *name)
The try_calling( ) primitive calls a subroutine or command if it
exists and doesn't complain if the function does not exist. It takes
the name of the function to call. It returns 0 if the function doesn't
exist. The function it calls must not require arguments.
int call_with_arg_list(int func, char *argtypes, int intargs[],
char *strargs[], ?char **res)
The call_with_arg_list( ) primitive can call an EEL function
that takes only integer and string parameters, specified by its name
table index func . The caller must specify the types of the
parameters to pass in argtypes , and supply the integer and string
parameters in the arrays intargs and strargs , respectively.
The argtypes value is a list of characters: "i" for an integer,
or "s" for a string. For each "i", Epsilon uses the next entry in
the intargs array, and for each "s", the strargs array.
If the EEL function returns an integer, the call_with_arg_list( )
primitive returns it. If it returns a character pointer, pass the
address of a character pointer, and the primitive will fill it in with
the return value.
The func parameter may refer to a keyboard macro if argtypes
is empty.
int drop_name(char *name)
To delete an item from the name table, use the drop_name( )
primitive. It returns 0 if it deleted the name, 1 if there
was no such name in the name table, and 2 if there was such a
name but it couldn't be deleted because it is currently in use.
int replace_name(char *old, char *new)
The replace_name( ) primitive renames an item in the name
table. It returns 0 if the name change was successful, 1
if the original name did not exist, and 2 if the name change was
unsuccessful because another item had the new name already. Any
references to the original item result in an error, unless you
provide a new definition for it later.
Sometimes when writing an Epsilon extension, you may wish to redefine
one of Epsilon's built-in subroutines (getkey( ), for example)
to do something in addition to its usual action. You can, of
course, simply modify the definition of the function, adding whatever
you want. Unfortunately, if someone else gives you an extension that
modifies the same function, it will overwrite your version. You'll
have the same problem when you get a new version of Epsilon--you'll
have to merge your change by hand.
#define REPLACE_FUNC(ext, func) ....
/* definition omitted */
Alternatively, you can create an extension that modifies the existing
version of a function, even if it's already been modified. The trick
is to replace it with a function that calls the original function.
This can be done from a when_loading( ) function by using the
replace_name( ) and drop_name( ) primitives, but
eel.h defines a macro that does all of this. The
REPLACE_FUNC() macro takes the name of the extension you're
writing, and the name of the existing subroutine you want to replace.
It doesn't really matter what the extension name is, just so long as
no other extension uses it.
Here's an example. Suppose you're writing an extension that displays
"Hello, world" whenever you start Epsilon. You've decided to name
the extension "hello", and you want Epsilon's start_up( )
function to do the work. Here's what you do:
new_hello_start_up() /* will be renamed to start_up */
{
say("Hello, world");
hello_start_up(); /* call old (which will have this name) */
}
REPLACE_FUNC("hello", "start-up")
Notice the steps: first you have to define a function with a name of
the form
new_<extension-name>_<replaced-function-name> .
Make sure it calls a function named
<extension-name>_<replaced-function-name> .
Then do the REPLACE_FUNC( ), providing the two names. This will
rename the current <replaced-function-name> to
<extension-name>_<replaced-function-name> ,
then rename your function to <replaced-function-name> .
Previous
|
Up
|
Next
|
Memory Allocation |
Primitives and EEL Subroutines |
Built-in and User Variables |
Epsilon Programmer's Editor 14.04 manual. Copyright (C) 1984, 2021 by Lugaru Software Ltd. All rights reserved.
|