mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-21 20:12:51 -08:00
new-doc: objects: finish objects (dev) module
This commit is contained in:
parent
ee5733b4a0
commit
d8f8f6bca9
2 changed files with 592 additions and 3 deletions
|
|
@ -1,11 +1,23 @@
|
|||
@node Manipulating Lisp objects
|
||||
@section Manipulating Lisp objects
|
||||
|
||||
@menu
|
||||
* Integers (dev)::
|
||||
* Characters (dev)::
|
||||
* Arrays (dev)::
|
||||
* Strings (dev)::
|
||||
* Bit-vectors (dev)::
|
||||
* Streams (dev)::
|
||||
* Structures (dev)::
|
||||
* Instances (dev)::
|
||||
* Bytecodes (dev)::
|
||||
@end menu
|
||||
|
||||
If you want to extend, fix or simply customize ECL for your own needs,
|
||||
you should understand how the implementation works.
|
||||
|
||||
@cppindex cl_lispunion
|
||||
@deftp {C/C++ index} cl_lispunion cons big ratio SF DF longfloat complex symbol pack hash array vector base_string string stream random readtable pathname bytecodes bclosure cfun cfunfixed cclosure d instance process queue lock rwlock condition_variable semaphore barrier mailbox cblock foreign frame weak sse
|
||||
@deftp {@cind} cl_lispunion cons big ratio SF DF longfloat complex symbol pack hash array vector base_string string stream random readtable pathname bytecodes bclosure cfun cfunfixed cclosure d instance process queue lock rwlock condition_variable semaphore barrier mailbox cblock foreign frame weak sse
|
||||
|
||||
Union containing all first-class ECL types.
|
||||
@end deftp
|
||||
|
|
@ -194,9 +206,12 @@ denoting the type that lisp object. That integer is one of the values of
|
|||
the enumeration type @code{cl_type}.
|
||||
@end deftypefun
|
||||
|
||||
@c XXX: add all predicate macros to the index
|
||||
@cppindex ECL_FIXNUMP
|
||||
@cppindex ECL_CHARACTERP
|
||||
@cppindex CODE_CHAR_P
|
||||
@cppindex ECL_BASE_CHAR_P
|
||||
@cppindex ECL_BASE_CHAR_CODE_P
|
||||
@cppindex ECL_NUMBER_TYPE_P
|
||||
@cppindex ECL_REAL_TYPE_P
|
||||
@cppindex ECL_REAL_TYPE_P
|
||||
|
|
@ -212,6 +227,8 @@ the enumeration type @code{cl_type}.
|
|||
@deftypefun bool ECL_FIXNUMP (cl_object o)
|
||||
@deftypefunx bool ECL_CHARACTERP (cl_object o)
|
||||
@deftypefunx bool ECL_BASE_CHAR_P (cl_object o)
|
||||
@deftypefunx bool ECL_CODE_CHAR_P (cl_object o)
|
||||
@deftypefunx bool ECL_BASE_CHAR_CODE_P (cl_object o)
|
||||
@deftypefunx bool ECL_NUMBER_TYPE_P (cl_object o)
|
||||
@deftypefunx bool ECL_REAL_TYPE_P (cl_object o)
|
||||
@deftypefunx bool ECL_CONSP (cl_object o)
|
||||
|
|
@ -228,10 +245,580 @@ type. These checks have been optimized, and are preferred over several
|
|||
calls to @code{ecl_t_of}.
|
||||
@end deftypefun
|
||||
|
||||
@cppindex ECL_IMMEDIATE
|
||||
@deftypefun bool ECL_IMMEDIATE (cl_object o)
|
||||
Tells whether @var{x} is an immediate datatype.
|
||||
@end deftypefun
|
||||
|
||||
@deftp {@cind} cl_objectxx
|
||||
@end deftp
|
||||
|
||||
@subsection Constructing objects
|
||||
|
||||
On each of the following sections we will document the standard
|
||||
interface for building objects of different types. For some objects,
|
||||
though, it is too difficult to make a C interface that resembles all of
|
||||
the functionality in the lisp environment. In those cases you need to
|
||||
|
||||
@enumerate
|
||||
@item build the objects from their textual representation, or
|
||||
@item use the evaluator to build these objects.
|
||||
@end enumerate
|
||||
|
||||
The first way makes use of a C or Lisp string to construct an
|
||||
object. The two functions you need to know are the following ones.
|
||||
|
||||
@cppindex c_string_to_object
|
||||
@cppindex string_to_object
|
||||
@deftypefun cl_object c_string_to_object (const char *s)
|
||||
@deftypefunx cl_object string_to_object (cl_object o)
|
||||
@code{c_string_to_object} builds a lisp object from a C string which
|
||||
contains a suitable representation of a lisp
|
||||
object. @code{string_to_object} performs the same task, but uses a lisp
|
||||
string, and therefore it is less useful.
|
||||
|
||||
@subsubheading Example
|
||||
@exindex @code{c_string_to_object} constructing Lisp objects in C
|
||||
|
||||
Using a C string
|
||||
@example
|
||||
cl_object array1 = c_string_to_object("#(1 2 3 4)");
|
||||
@end example
|
||||
|
||||
Using a Lisp string
|
||||
@example
|
||||
cl_object string = make_simple_string("#(1 2 3 4)");
|
||||
cl_object array2 = string_to_object(string);
|
||||
@end example
|
||||
@end deftypefun
|
||||
|
||||
@node Integers (dev)
|
||||
@subsection Integers (dev)
|
||||
Common-Lisp distinguishes two types of integer types: @code{bignum}s and
|
||||
@code{fixnum}s. A fixnum is a small integer, which ideally occupies only
|
||||
a word of memory and which is between the values
|
||||
@code{MOST-NEGATIVE-FIXNUM} and @code{MOST-POSITIVE-FIXNUM}. A
|
||||
@code{bignum} is any integer which is not a @code{fixnum} and it is only
|
||||
constrained by the amount of memory available to represent it.
|
||||
|
||||
In ECL a @code{fixnum} is an integer that, together with the tag bits,
|
||||
fits in a word of memory. The size of a word, and thus the size of a
|
||||
@code{fixnum}, varies from one architecture to another, and you should
|
||||
refer to the types and constants in the ecl.h header to make sure that
|
||||
your C extensions are portable. All other integers are stored as
|
||||
@code{bignum}s, they are not immediate objects, they take up a variable
|
||||
amount of memory and the GNU Multiprecision Library is required to
|
||||
create, manipulate and calculate with them.
|
||||
|
||||
@cppindex cl_fixnum
|
||||
@deftp {@cind} cl_fixnum
|
||||
This is a C signed integer type capable of holding a whole @code{fixnum}
|
||||
without any loss of precision. The opposite is not true, and you may
|
||||
create a @code{cl_fixnum} which exceeds the limits of a fixnum and
|
||||
should be stored as a @code{bignum}.
|
||||
@end deftp
|
||||
|
||||
@cppindex cl_index
|
||||
@deftp {@cind} cl_index
|
||||
This is a C unsigned integer type capable of holding a non-negative
|
||||
@code{fixnum} without loss of precision. Typically, a @code{cl_index} is
|
||||
used as an index into an array, or into a proper list, etc.
|
||||
@end deftp
|
||||
|
||||
@cppindex MOST_NEGATIVE_FIXNUM
|
||||
@cppindex MOST_POSITIVE_FIXNUM
|
||||
@lspindex MOST-NEGATIVE-FIXNUM
|
||||
@lspindex MOST-POSITIVE-FIXNUM
|
||||
@defvr {Constant} MOST_NEGATIVE_FIXNUM
|
||||
@defvrx {Constant} MOST_POSITIVE_FIXNUM
|
||||
These constants mark the limits of a @code{fixnum}.
|
||||
@end defvr
|
||||
|
||||
@cppindex ecl_fixnum_lower
|
||||
@cppindex ecl_fixnum_greater
|
||||
@cppindex ecl_fixnum_leq
|
||||
@cppindex ecl_fixnum_geq
|
||||
@cppindex ecl_fixnum_plusp
|
||||
@cppindex ecl_fixnum_minusp
|
||||
@deftypefun bool ecl_fixnum_lower (cl_fixnum a, cl_fixnum b)
|
||||
@deftypefunx bool ecl_fixnum_greater (cl_fixnum a, cl_fixnum b)
|
||||
@deftypefunx bool ecl_fixnum_leq (cl_fixnum a, cl_fixnum b)
|
||||
@deftypefunx bool ecl_fixnum_geq (cl_fixnum a, cl_fixnum b)
|
||||
@deftypefunx bool ecl_fixnum_plusp (cl_fixnum a)
|
||||
@deftypefunx bool ecl_fixnum_minusp (cl_fixnum a)
|
||||
Operations on @code{fixnums} (comparison and predicates).
|
||||
@end deftypefun
|
||||
|
||||
@cppindex ecl_make_fixnum
|
||||
@cppindex ecl_fixnum
|
||||
@cppindex MAKE_FIXNUM
|
||||
@cppindex fix
|
||||
@deftypefun cl_object ecl_make_fixnum (cl_fixnum n)
|
||||
@deftypefunx cl_fixnum ecl_unfix (cl_object o)
|
||||
@code{ecl_make_fixnum} converts from an integer to a lisp object, while
|
||||
the @code{ecl_fixnum} does the opposite (converts lisp object fixnum to
|
||||
integer). These functions do @strong{not} check their arguments.
|
||||
@itemize @bullet
|
||||
@item @strong{DEPRECATED} @code{MAKE_FIXNUM} – equivalent to @code{cl_make_fixnum}
|
||||
@item @strong{DEPRECATED} @code{fix} – equivalent to @code{cl_fixnum}
|
||||
@end itemize
|
||||
@end deftypefun
|
||||
|
||||
@cppindex cl_fixnum
|
||||
@cppindex cl_index
|
||||
@deftypefun cl_fixnum fixint (cl_object o)
|
||||
@deftypefunx cl_index fixnint (cl_object o)
|
||||
Safe conversion of a lisp @code{fixnum} to a C integer of the
|
||||
appropriate size. Signals an error if @var{o} is not of fixnum type.
|
||||
|
||||
@code{fixnint} additionally ensure that @var{o} is not negative.
|
||||
@end deftypefun
|
||||
|
||||
@node Characters (dev)
|
||||
@subsection Characters (dev)
|
||||
|
||||
@cfindex --enable-unicode (YES|no|32)
|
||||
|
||||
ECL has two types of characters – one fits in the C type char, while the
|
||||
other is used when ECL is built with a configure option
|
||||
@code{--enable-unicode}.
|
||||
|
||||
@cppindex ecl_character
|
||||
@cppindex ecl_base_char
|
||||
@deftp {@cind} ecl_character
|
||||
Immediate type @code{t_character}. If ECL built with Unicode support,
|
||||
then may be either base or extended character, which may be
|
||||
distinguished with the predicate @code{ECL_BASE_CHAR_P}.
|
||||
|
||||
Additionally we have @code{ecl_base_char} for base strings, which is an
|
||||
equivalent to the ordinary char.
|
||||
|
||||
@subsubheading Example
|
||||
@exindex distinguishing between base and Unicode character
|
||||
@example
|
||||
if (ECL_CHARACTERP(o) && ECL_BASE_CHAR_P(o))
|
||||
printf("Base character: %c\n", ECL_CHAR_CODE(o));
|
||||
@end example
|
||||
@end deftp
|
||||
|
||||
@cppindex ECL_CHAR_CODE_LIMIT
|
||||
@cppindex CHAR_CODE_LIMIT
|
||||
@defvr {Constant} ECL_CHAR_CODE_LIMIT
|
||||
Each character is assigned an integer code which ranges from 0 to
|
||||
(ECL_CHAR_CODE_LIMIT-1).
|
||||
@itemize @bullet
|
||||
@item @strong{DEPRECATED} @code{CODE_CHAR_LIMIT} – equivalent to @code{ECL_CHAR_CODE_LIMIT}
|
||||
@end itemize
|
||||
@end defvr
|
||||
|
||||
@cppindex ecl_char_code
|
||||
@cppindex ecl_base_char_code
|
||||
@cppindex ECL_CHAR_CODE
|
||||
@cppindex ECL_CODE_CHAR
|
||||
@cppindex CODE_CHAR
|
||||
@cppindex CHAR_CODE
|
||||
@deftypefun cl_fixnum ECL_CHAR_CODE (cl_object o)
|
||||
@deftypefunx cl_fixnum ECL_CODE_CHAR (cl_object o)
|
||||
@code{ECL_CHAR_CODE}, @code{ecl_char_code} and @code{ecl_base_char_code}
|
||||
return the integer code associated to a lisp
|
||||
character. @code{ecl_char_code} and @code{ecl_base_char_code} perform a
|
||||
safe conversion, while ECL_CHAR_CODE doesn't check it's
|
||||
argument. @code{ecl_base_char_code} is an optimized version for base
|
||||
chars. Checks it's argument.
|
||||
|
||||
@code{ECL_CODE_CHAR} returns the lisp character associated to an integer
|
||||
code. It does not check its arguments.
|
||||
|
||||
@itemize @bullet
|
||||
@item @strong{DEPRECATED} @code{CHAR_CODE} – equivalent to @code{ECL_CHAR_CODE}
|
||||
@item @strong{DEPRECATED} @code{CODE_CHAR} – equivalent to @code{ECL_CODE_CHAR}
|
||||
@end itemize
|
||||
@end deftypefun
|
||||
|
||||
@cppindex ecl_char_eq
|
||||
@cppindex ecl_char_equal
|
||||
@deftypefun bool ecl_char_eq (cl_object x, cl_object y)
|
||||
@deftypefunx bool ecl_char_equal (cl_object x, cl_object y)
|
||||
Compare two characters for equality. char_eq take case into account and
|
||||
char_equal ignores it.
|
||||
@end deftypefun
|
||||
|
||||
@cppindex ecl_char_cmp
|
||||
@cppindex ecl_char_compare
|
||||
@deftypefun bool ecl_char_cmp (cl_object x, cl_object y)
|
||||
@deftypefunx bool ecl_char_compare (cl_object x, cl_object y)
|
||||
Compare the relative order of two characters. @code{char_cmp} takes care
|
||||
of case and @code{char_compare} converts all characters to uppercase
|
||||
before comparing them.
|
||||
@end deftypefun
|
||||
|
||||
@node Arrays (dev)
|
||||
@subsection Arrays (dev)
|
||||
|
||||
An array is an aggregate of data of a common type, which can be accessed
|
||||
with one or more non-negative indices. ECL stores arrays as a C structure
|
||||
with a pointer to the region of memory which contains the actual
|
||||
data. The cell of an array datatype varies depending on whether it is a
|
||||
vector, a bit-vector, a multidimensional array or a string.
|
||||
|
||||
@cppindex ECL_ADJUSTABLE_ARRAY_P
|
||||
@cppindex ECL_ARRAY_HAS_FILL_POINTER_P
|
||||
@deftypefun bool ECL_ADJUSTABLE_ARRAY_P (cl_object x)
|
||||
@deftypefunx bool ECL_ARRAY_HAS_FILL_POINTER_P (cl_object x)
|
||||
All arrays (arrays, strings and bit-vectors) may be tested for being
|
||||
adjustable and whenever they have a fill pointer with this two
|
||||
functions.
|
||||
@end deftypefun
|
||||
|
||||
@cppindex ecl_vector
|
||||
@deftp {@cind} ecl_vector
|
||||
If @code{x} contains a vector, you can access the following fields:
|
||||
|
||||
@table @code
|
||||
@item x->vector.elttype
|
||||
The type of the elements of the vector.
|
||||
@item x->vector.displaced
|
||||
Boolean indicating if it is displaced.
|
||||
@item x->vector.dim
|
||||
The maximum number of elements.
|
||||
@item x->vector.fillp
|
||||
Actual numer of elements in the vector or @code{fill pointer}.
|
||||
@item x->vector.self
|
||||
Union of pointers of different types. You should choose the right
|
||||
pointer depending on @var{x->vector.elttype}.
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@cppindex ecl_array
|
||||
@deftp {@cind} ecl_array
|
||||
If @code{x} contains a multidimensional array, you can access the
|
||||
following fields:
|
||||
|
||||
@table @code
|
||||
@item x->array.elttype
|
||||
The type of the elements of the array.
|
||||
@item x->array.rank
|
||||
The number of array dimensions.
|
||||
@item x->array.displaced
|
||||
Boolean indicating if it is displaced.
|
||||
@item x->vector.dim
|
||||
The maximum number of elements.
|
||||
@item x->array.dims[]
|
||||
Array with the dimensions of the array. The elements range from
|
||||
@code{x->array.dim[0]} to @code{x->array.dim[x->array.rank-1]}.
|
||||
@item x->array.fillp
|
||||
Actual numer of elements in the array or @code{fill pointer}.
|
||||
@item x->array.self
|
||||
Union of pointers of different types. You should choose the right
|
||||
pointer depending on @var{x->array.elttype}.
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@cppindex cl_elttype
|
||||
@deftp {@cind} cl_elttype ecl_aet_object ecl_aet_sf ecl_aet_df ecl_aet_bit ecl_aet_fix ecl_aet_index ecl_aet_b8 ecl_aet_i8 ecl_aet_b16 ecl_aet_i16 ecl_aet_b32 ecl_aet_i32 ecl_aet_b64 ecl_aet_i64 ecl_aet_ch ecl_aet_bc
|
||||
|
||||
Each array is of an specialized type which is the type of the elements
|
||||
of the array. ECL has arrays only a few following specialized types, and
|
||||
for each of these types there is a C integer which is the corresponding
|
||||
value of @code{x->array.elttype} or @code{x->vector.elttype}. We list
|
||||
some of those types together with the C constant that denotes that type:
|
||||
|
||||
@table @var
|
||||
@item T
|
||||
@code{ecl_aet_object}
|
||||
@item BASE-CHAR
|
||||
@code{ecl_aet_object}
|
||||
@item SIGNLE-FLOAT
|
||||
@code{ecl_aet_sf}
|
||||
@item DOUBLE-FLOAT
|
||||
@code{ecl_aet_df}
|
||||
@item BIT
|
||||
@code{ecl_aet_bit}
|
||||
@item FIXNUM
|
||||
@code{ecl_aet_fix}
|
||||
@item INDEX
|
||||
@code{ecl_aet_index}
|
||||
@item CHARACTER
|
||||
@code{ecl_aet_ch}
|
||||
@item BASE-CHAR
|
||||
@code{ecl_aet_bc}
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@cppindex ecl_array_elttype
|
||||
@deftypefun cl_elttype ecl_array_elttype (cl_object array)
|
||||
Returns the element type of the array @code{o}, which can be a string, a
|
||||
bit-vector, vector, or a multidimensional array.
|
||||
|
||||
@subsubheading Example
|
||||
@exindex @code{ecl_array_elttype} different types of objects
|
||||
For example, the code
|
||||
|
||||
@example
|
||||
ecl_array_elttype(c_string_to_object("\"AAA\"")); /* returns ecl_aet_ch */
|
||||
ecl_array_elttype(c_string_to_object("#(A B C)")); /* returns ecl_aet_object */
|
||||
@end example
|
||||
@end deftypefun
|
||||
|
||||
@cppindex ecl_aref
|
||||
@cppindex ecl_aset
|
||||
@deftypefun cl_object ecl_aref (cl_object x, cl_index index)
|
||||
@deftypefunx cl_object ecl_aset (cl_object x, cl_index index, cl_object value)
|
||||
These functions are used to retrieve and set the elements of an
|
||||
array. The elements are accessed with one index, index, as in the lisp
|
||||
function ROW-MAJOR-AREF.
|
||||
|
||||
@subsubheading Example
|
||||
@exindex @code{ecl_aref} and @code{ecl_aset} accessing arrays
|
||||
@example
|
||||
cl_object array = c_string_to_object("#2A((1 2) (3 4))");
|
||||
cl_object x = aref(array, 3);
|
||||
cl_print(1, x); /* Outputs 4 */
|
||||
aset(array, 3, MAKE_FIXNUM(5));
|
||||
cl_print(1, array); /* Outputs #2A((1 2) (3 5)) */
|
||||
@end example
|
||||
@end deftypefun
|
||||
|
||||
@cppindex ecl_aref1
|
||||
@cppindex ecl_aset1
|
||||
@deftypefun cl_object ecl_aref (cl_object x, cl_index index)
|
||||
@deftypefunx cl_object ecl_aset (cl_object x, cl_index index, cl_object value)
|
||||
These functions are similar to aref and aset, but they operate on vectors.
|
||||
|
||||
@subsubheading Example
|
||||
@exindex @code{ecl_aref1} and @code{ecl_aset1} accessing vectors
|
||||
@example
|
||||
cl_object array = c_string_to_object("#(1 2 3 4)");
|
||||
cl_object x = aref1(array, 3);
|
||||
cl_print(1, x); /* Outputs 4 */
|
||||
aset1(array, 3, MAKE_FIXNUM(5));
|
||||
cl_print(1, array); /* Outputs #(1 2 3 5) */
|
||||
@end example
|
||||
@end deftypefun
|
||||
|
||||
@node Strings (dev)
|
||||
@subsection Strings (dev)
|
||||
|
||||
A string, both in Common-Lisp and in ECL is nothing but a vector of
|
||||
characters. Therefore, almost everything mentioned in the section of
|
||||
arrays remains valid here.
|
||||
|
||||
The only important difference is that ECL stores the base-strings
|
||||
(non-Unicode version of a string) as a lisp object with a pointer to a
|
||||
zero terminated C string. Thus, if a string has n characters, ECL will
|
||||
reserve n+1 bytes for the base-string. This allows us to pass the
|
||||
base-string self pointer to any C routine.
|
||||
|
||||
@cppindex ecl_string
|
||||
@cppindex ecl_base_string
|
||||
@deftp {@cind} ecl_string
|
||||
@deftpx {@cind} ecl_base_string
|
||||
If @code{x} is a lisp object of type string or a base-string, we can
|
||||
access the following fields:
|
||||
@table @code
|
||||
@item x->string.dim x->base_string.dim
|
||||
Actual number of characters in the string.
|
||||
@item x->string.fillp x->base_string.fillp
|
||||
Actual number of characters in the string.
|
||||
@item x->string.self x->base_string.self
|
||||
Pointer to the characters (appropriately integers and chars).
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@cppindex ECL_EXTENDED_STRING_P
|
||||
@cppindex ECL_BASE_STRING_P
|
||||
@deftypefun bool ECL_EXTENDED_STRING_P (cl_object object)
|
||||
@deftypefunx bool ECL_BASE_STRING_P (cl_object object)
|
||||
|
||||
Verifies if an objects is an extended or base string. If Unicode isn't
|
||||
supported, then @code{ECL_EXTENDED_STRING_P} always returns 0.
|
||||
@end deftypefun
|
||||
|
||||
@node Bit-vectors (dev)
|
||||
@subsection Bit-vectors (dev)
|
||||
|
||||
Bit-vector operations are implemented in file
|
||||
@code{src/c/array.d}. Bit-vector shares the structure with a vector,
|
||||
therefore, almost everything mentioned in the section of arrays remains
|
||||
valid here.
|
||||
|
||||
@node Streams (dev)
|
||||
@subsection Streams (dev)
|
||||
|
||||
Streams implementation is a broad topic. Most of the implementation is
|
||||
done in the file @code{src/c/file.d}. Stream handling may have different
|
||||
implementations referred by a member pointer @code{ops}.
|
||||
|
||||
Additionally on top of that we have implemented @emph{Gray Streams} (in
|
||||
portable Common Lisp) in file @code{src/clos/streams.lsp}, which may be
|
||||
somewhat slower (we need to benchmark it!). This implementation is in a
|
||||
separate package @var{GRAY}. We may redefine functions in the
|
||||
@var{COMMON-LISP} package with a function @code{redefine-cl-functions}
|
||||
at run-time.
|
||||
|
||||
@cppindex ecl_file_pos
|
||||
@deftp {@cind} ecl_file_ops write_* read_* unread_* peek_* listen clear_input clear_output finish_output force_output input_p output_p interactive_p element_type length get_position set_position column close
|
||||
@end deftp
|
||||
|
||||
@cppindex ecl_stream
|
||||
@deftp {@cind} ecl_stream
|
||||
@table @code
|
||||
@item ecl_smmode mode
|
||||
Stream mode (in example @code{ecl_smm_string_input}).
|
||||
@item int closed
|
||||
Whenever stream is closed or not.
|
||||
@item ecl_file_ops *ops
|
||||
Pointer to the structure containing operation implementations (dispatch
|
||||
table).
|
||||
@item union file
|
||||
Union of ANSI C streams (FILE *stream) and POSIX files interface
|
||||
(cl_fixnum descriptor).
|
||||
@item cl_object object0, object1
|
||||
Some objects (may be used for a specific implementation purposes).
|
||||
@item cl_object byte_stack
|
||||
Buffer for unread bytes.
|
||||
@item cl_index column
|
||||
File column.
|
||||
@item cl_fixnum last_char
|
||||
Last character read.
|
||||
@item cl_fixnum last_code[2]
|
||||
Actual composition of the last character.
|
||||
@item cl_fixnum int0 int1
|
||||
Some integers (may be used for a specific implementation purposes).
|
||||
@item cl_index byte_size
|
||||
Size of byte in binary streams.
|
||||
@item cl_fixnum last_op
|
||||
0: unknown, 1: reading, -1: writing
|
||||
@item char *buffer
|
||||
Buffer for FILE
|
||||
@item cl_object format
|
||||
external format
|
||||
@item cl_eformat_encoder encoder
|
||||
@item cl_eformat_encoder decoder
|
||||
@item cl_object format_table
|
||||
@item in flags
|
||||
Character table, flags, etc
|
||||
@item ecl_character eof_character
|
||||
@end table
|
||||
@end deftp
|
||||
|
||||
@cppindex ECL_ANSI_STREAM_P
|
||||
@deftypefun ECL_ANSI_STREAM_P (cl_object o)
|
||||
Predicate determining if @code{o} is a first-class stream
|
||||
object. Doesn't check type of it's argument.
|
||||
@end deftypefun
|
||||
|
||||
@cppindex ECL_ANSI_STREAM_TYPE_P
|
||||
@deftypefun ECL_ANSI_STREAM_TYPE_P (cl_object o, ecl_smmode m)
|
||||
Predicate determining if @code{o} is a first-class stream
|
||||
object of type @code{m}.
|
||||
@end deftypefun
|
||||
|
||||
@node Structures (dev)
|
||||
@subsection Structures (dev)
|
||||
|
||||
Structures and instances share the same datatype @code{t_instance} (
|
||||
with a few exceptions. Structure implementation details are the file
|
||||
@code{src/c/structure.d}.
|
||||
|
||||
@cppindex ECL_STRUCT_TYPE
|
||||
@cppindex ECL_STRUCT_SLOTS
|
||||
@cppindex ECL_STRUCT_LENGTH
|
||||
@cppindex ECL_STRUCT_SLOT
|
||||
@cppindex ECL_STRUCT_NAME
|
||||
@deftypefun cl_object ECL_STRUCT_TYPE (cl_object x)
|
||||
@deftypefunx cl_object ECL_STRUCT_SLOTS (cl_object x)
|
||||
@deftypefunx cl_object ECL_STRUCT_LENGTH (cl_object x)
|
||||
@deftypefunx cl_object ECL_STRUCT_SLOT (cl_object x, cl_index i)
|
||||
@deftypefunx cl_object ECL_STRUCT_NAME (cl_object x)
|
||||
Convenience functions for the structures.
|
||||
@end deftypefun
|
||||
|
||||
@node Instances (dev)
|
||||
@subsection Instances (dev)
|
||||
|
||||
@cppindex ECL_CLASS_OF
|
||||
@cppindex ECL_SPEC_FLAG
|
||||
@cppindex ECL_SPEC_OBJECT
|
||||
@cppindex ECL_CLASS_NAME
|
||||
@cppindex ECL_CLASS_SUPERIORS
|
||||
@cppindex ECL_CLASS_INFERIORS
|
||||
@cppindex ECL_CLASS_SLOTS
|
||||
@cppindex ECL_CLASS_CPL
|
||||
@cppindex ECL_INSTANCEP
|
||||
|
||||
@deftypefun cl_object ECL_CLASS_OF (cl_object x)
|
||||
@deftypefunx cl_object ECL_SPEC_FLAG (cl_object x)
|
||||
@deftypefunx cl_object ECL_SPEC_OBJECT (cl_object x)
|
||||
@deftypefunx cl_object ECL_CLASS_NAME (cl_object x)
|
||||
@deftypefunx cl_object ECL_CLASS_SUPERIORS (cl_object x)
|
||||
@deftypefunx cl_object ECL_CLASS_INFERIORS (cl_object x)
|
||||
@deftypefunx cl_object ECL_CLASS_SLOTS (cl_object x)
|
||||
@deftypefunx cl_object ECL_CLASS_CPL (cl_object x)
|
||||
@deftypefunx bool ECL_INSTANCEP (cl_object x)
|
||||
Convenience functions for the structures.
|
||||
@end deftypefun
|
||||
|
||||
@node Bytecodes (dev)
|
||||
@subsection Bytecodes (dev)
|
||||
|
||||
A bytecodes object is a lisp object with a piece of code that can be
|
||||
interpreted. The objects of type t_bytecode are implicitly constructed
|
||||
by a call to eval, but can also be explicitly constructed with the
|
||||
make_lambda function.
|
||||
|
||||
@cppindex si_safe_eval
|
||||
@cppindex cl_safe_eval
|
||||
@cppindex cl_eval
|
||||
@deftypefun cl_object si_safe_eval (cl_object form, cl_object env, ...)
|
||||
|
||||
@code{si_safe_eval} evaluates @code{form} in the lexical environment
|
||||
@code{env}, which can be @var{ECL_NIL}. Before evaluating it, the
|
||||
expression form must be bytecompiled.
|
||||
|
||||
@table @code
|
||||
@item @strong{DEPRECATED} cl_object cl_eval (cl_object form)
|
||||
@code{cl_eval} is the equivalent of @code{si_safe_eval} but without
|
||||
environment and with err_value set to nil. It exists only for
|
||||
compatibility with previous versions.
|
||||
@item @strong{DEPRECATED} cl_object cl_safe_eval (cl_object form)
|
||||
Equivalent of @code{si_safe_eval} (macro define).
|
||||
@end table
|
||||
|
||||
@subheading Exmaple
|
||||
@exindex @code{cl_safe_eval}
|
||||
@example
|
||||
si_object form = c_string_to_object("(print 1)");
|
||||
si_safe_eval(form, ECL_NIL);
|
||||
si_safe_eval(form, ECL_NIL, 3); /* on error function will return 3 */
|
||||
@end example
|
||||
@end deftypefun
|
||||
|
||||
@cppindex si_make_lambda
|
||||
@deftypefun cl_object si_make_lambda (cl_object name, cl_object def)
|
||||
Builds an interpreted lisp function with name given by the symbol name
|
||||
and body given by def.
|
||||
|
||||
@subheading Example
|
||||
@exindex @code{si_make_lambda} building functions
|
||||
|
||||
For instance, we would achieve the equivalent of
|
||||
|
||||
@lisp
|
||||
(funcall #'(lambda (x y)
|
||||
(block foo (+ x y)))
|
||||
1 2)
|
||||
@end lisp
|
||||
|
||||
with the following code
|
||||
|
||||
@example
|
||||
cl_object def = c_string_to_object("((x y) (+ x y))");
|
||||
cl_object name = _intern("foo")
|
||||
cl_object fun = si_make_lambda(name, def);
|
||||
return funcall(fun, MAKE_FIXNUM(1), MAKE_FIXNUM(2));
|
||||
@end example
|
||||
|
||||
Notice that @code{si_make_lambda} performs a bytecodes compilation of
|
||||
the definition and thus it may signal some errors. Such errors are not
|
||||
handled by the routine itself so you might consider using
|
||||
@code{si_safe_eval} instead.
|
||||
@end deftypefun
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
@c * In-house GC:: ECL's own GC
|
||||
@c * Green threads:: Lightweight processes
|
||||
@c * Compiler newcmp:: Experimental compiler architecture
|
||||
@c * In-house bignum implementation::
|
||||
@c * Possibility to build without bignums::
|
||||
@c @end menu
|
||||
|
||||
@c @node In-house DFFI
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue