From d8f8f6bca98b4b7da489733b2a5bb52ff253a83e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Fri, 4 Mar 2016 19:54:09 +0100 Subject: [PATCH] new-doc: objects: finish objects (dev) module --- src/doc/new-doc/developer-guide/objects.txi | 593 +++++++++++++++++++- src/doc/new-doc/developer-guide/removed.txi | 2 + 2 files changed, 592 insertions(+), 3 deletions(-) diff --git a/src/doc/new-doc/developer-guide/objects.txi b/src/doc/new-doc/developer-guide/objects.txi index 1ee9057c2..d7dcae215 100644 --- a/src/doc/new-doc/developer-guide/objects.txi +++ b/src/doc/new-doc/developer-guide/objects.txi @@ -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 diff --git a/src/doc/new-doc/developer-guide/removed.txi b/src/doc/new-doc/developer-guide/removed.txi index f7a09f8f4..ddfb2c2d3 100644 --- a/src/doc/new-doc/developer-guide/removed.txi +++ b/src/doc/new-doc/developer-guide/removed.txi @@ -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