Library interface to Embeddable Common Lisp (ECL)¶
- class sage.libs.ecl.EclListIterator¶
Bases:
object
Iterator object for an ECL list
This class is used to implement the iterator protocol for EclObject. Do not instantiate this class directly but use the iterator method on an EclObject instead. It is an error if the EclObject is not a list.
EXAMPLES:
sage: from sage.libs.ecl import * sage: I=EclListIterator(EclObject("(1 2 3)")) sage: type(I) <type 'sage.libs.ecl.EclListIterator'> sage: [i for i in I] [<ECL: 1>, <ECL: 2>, <ECL: 3>] sage: [i for i in EclObject("(1 2 3)")] [<ECL: 1>, <ECL: 2>, <ECL: 3>] sage: EclListIterator(EclObject("1")) Traceback (most recent call last): ... TypeError: ECL object is not iterable
- class sage.libs.ecl.EclObject¶
Bases:
object
Python wrapper of ECL objects
The
EclObject
forms a wrapper around ECL objects. The wrapper ensures that the data structure pointed to is protected from garbage collection in ECL by installing a pointer to it from a global data structure within the scope of the ECL garbage collector. This pointer is destroyed upon destruction of the EclObject.EclObject() takes a Python object and tries to find a representation of it in Lisp.
EXAMPLES:
Python lists get mapped to LISP lists. None and Boolean values to appropriate values in LISP:
sage: from sage.libs.ecl import * sage: EclObject([None,true,false]) <ECL: (NIL T NIL)>
Numerical values are translated to the appropriate type in LISP:
sage: EclObject(1) <ECL: 1> sage: EclObject(10**40) <ECL: 10000000000000000000000000000000000000000>
Floats in Python are IEEE double, which LISP has as well. However, the printing of floating point types in LISP depends on settings:
sage: a = EclObject(float(10^40)) sage: ecl_eval("(setf *read-default-float-format* 'single-float)") <ECL: SINGLE-FLOAT> sage: a <ECL: 1.d40> sage: ecl_eval("(setf *read-default-float-format* 'double-float)") <ECL: DOUBLE-FLOAT> sage: a <ECL: 1.e40>
Tuples are translated to dotted lists:
sage: EclObject( (false, true)) <ECL: (NIL . T)> sage: EclObject( (1, 2, 3) ) <ECL: (1 2 . 3)>
Strings are fed to the reader, so a string normally results in a symbol:
sage: EclObject("Symbol") <ECL: SYMBOL>
But with proper quotation one can construct a lisp string object too:
sage: EclObject('"Symbol"') <ECL: "Symbol">
Or any other object that the Lisp reader can construct:
sage: EclObject('#("I" am "just" a "simple" vector)') <ECL: #("I" AM "just" A "simple" VECTOR)>
By means of Lisp reader macros, you can include arbitrary objects:
sage: EclObject([ 1, 2, '''#.(make-hash-table :test #'equal)''', 4]) <ECL: (1 2 #<hash-table ...> 4)>
Using an optional argument, you can control how strings are handled:
sage: EclObject("String", False) <ECL: "String"> sage: EclObject('#(I may look like a vector but I am a string)', False) <ECL: "#(I may look like a vector but I am a string)">
This also affects strings within nested lists and tuples
sage: EclObject([1, 2, "String", 4], False) <ECL: (1 2 "String" 4)>
EclObjects translate to themselves, so one can mix:
sage: EclObject([1,2,EclObject([3])]) <ECL: (1 2 (3))>
Calling an EclObject translates into the appropriate LISP
apply
, where the argument is transformed into an EclObject itself, so one can flexibly apply LISP functions:sage: car=EclObject("car") sage: cdr=EclObject("cdr") sage: car(cdr([1,2,3])) <ECL: 2>
and even construct and evaluate arbitrary S-expressions:
sage: eval=EclObject("eval") sage: quote=EclObject("quote") sage: eval([car, [cdr, [quote,[1,2,3]]]]) <ECL: 2>
- atomp()¶
Return True if self is atomic, False otherwise.
EXAMPLES:
sage: from sage.libs.ecl import * sage: EclObject([]).atomp() True sage: EclObject([[]]).atomp() False
- caar()¶
Return the caar of self
EXAMPLES:
sage: from sage.libs.ecl import * sage: L=EclObject([[1,2],[3,4]]) sage: L.car() <ECL: (1 2)> sage: L.cdr() <ECL: ((3 4))> sage: L.caar() <ECL: 1> sage: L.cadr() <ECL: (3 4)> sage: L.cdar() <ECL: (2)> sage: L.cddr() <ECL: NIL>
- cadr()¶
Return the cadr of self
EXAMPLES:
sage: from sage.libs.ecl import * sage: L=EclObject([[1,2],[3,4]]) sage: L.car() <ECL: (1 2)> sage: L.cdr() <ECL: ((3 4))> sage: L.caar() <ECL: 1> sage: L.cadr() <ECL: (3 4)> sage: L.cdar() <ECL: (2)> sage: L.cddr() <ECL: NIL>
- car()¶
Return the car of self
EXAMPLES:
sage: from sage.libs.ecl import * sage: L=EclObject([[1,2],[3,4]]) sage: L.car() <ECL: (1 2)> sage: L.cdr() <ECL: ((3 4))> sage: L.caar() <ECL: 1> sage: L.cadr() <ECL: (3 4)> sage: L.cdar() <ECL: (2)> sage: L.cddr() <ECL: NIL>
- cdar()¶
Return the cdar of self
EXAMPLES:
sage: from sage.libs.ecl import * sage: L=EclObject([[1,2],[3,4]]) sage: L.car() <ECL: (1 2)> sage: L.cdr() <ECL: ((3 4))> sage: L.caar() <ECL: 1> sage: L.cadr() <ECL: (3 4)> sage: L.cdar() <ECL: (2)> sage: L.cddr() <ECL: NIL>
- cddr()¶
Return the cddr of self
EXAMPLES:
sage: from sage.libs.ecl import * sage: L=EclObject([[1,2],[3,4]]) sage: L.car() <ECL: (1 2)> sage: L.cdr() <ECL: ((3 4))> sage: L.caar() <ECL: 1> sage: L.cadr() <ECL: (3 4)> sage: L.cdar() <ECL: (2)> sage: L.cddr() <ECL: NIL>
- cdr()¶
Return the cdr of self
EXAMPLES:
sage: from sage.libs.ecl import * sage: L=EclObject([[1,2],[3,4]]) sage: L.car() <ECL: (1 2)> sage: L.cdr() <ECL: ((3 4))> sage: L.caar() <ECL: 1> sage: L.cadr() <ECL: (3 4)> sage: L.cdar() <ECL: (2)> sage: L.cddr() <ECL: NIL>
- characterp()¶
Return True if self is a character, False otherwise
Strings are not characters
EXAMPLES:
sage: from sage.libs.ecl import * sage: EclObject('"a"').characterp() False
- cons(d)¶
apply cons to self and argument and return the result.
EXAMPLES:
sage: from sage.libs.ecl import * sage: a=EclObject(1) sage: b=EclObject(2) sage: a.cons(b) <ECL: (1 . 2)>
- consp()¶
Return True if self is a cons, False otherwise. NIL is not a cons.
EXAMPLES:
sage: from sage.libs.ecl import * sage: EclObject([]).consp() False sage: EclObject([[]]).consp() True
- eval()¶
Evaluate object as an S-Expression
EXAMPLES:
sage: from sage.libs.ecl import * sage: S=EclObject("(+ 1 2)") sage: S <ECL: (+ 1 2)> sage: S.eval() <ECL: 3>
- fixnump()¶
Return True if self is a fixnum, False otherwise
EXAMPLES:
sage: from sage.libs.ecl import * sage: EclObject(2**3).fixnump() True sage: EclObject(2**200).fixnump() False
- listp()¶
Return True if self is a list, False otherwise. NIL is a list.
EXAMPLES:
sage: from sage.libs.ecl import * sage: EclObject([]).listp() True sage: EclObject([[]]).listp() True
- nullp()¶
Return True if self is NIL, False otherwise
EXAMPLES:
sage: from sage.libs.ecl import * sage: EclObject([]).nullp() True sage: EclObject([[]]).nullp() False
- python()¶
Convert an EclObject to a python object.
EXAMPLES:
sage: from sage.libs.ecl import * sage: L=EclObject([1,2,("three",'"four"')]) sage: L.python() [1, 2, ('THREE', '"four"')]
- rplaca(d)¶
Destructively replace car(self) with d.
EXAMPLES:
sage: from sage.libs.ecl import * sage: L=EclObject((1,2)) sage: L <ECL: (1 . 2)> sage: a=EclObject(3) sage: L.rplaca(a) sage: L <ECL: (3 . 2)>
- rplacd(d)¶
Destructively replace cdr(self) with d.
EXAMPLES:
sage: from sage.libs.ecl import * sage: L=EclObject((1,2)) sage: L <ECL: (1 . 2)> sage: a=EclObject(3) sage: L.rplacd(a) sage: L <ECL: (1 . 3)>
- symbolp()¶
Return True if self is a symbol, False otherwise.
EXAMPLES:
sage: from sage.libs.ecl import * sage: EclObject([]).symbolp() True sage: EclObject([[]]).symbolp() False
- sage.libs.ecl.ecl_eval(s)¶
Read and evaluate string in Lisp and return the result
EXAMPLES:
sage: from sage.libs.ecl import * sage: ecl_eval("(defun fibo (n)(cond((= n 0) 0)((= n 1) 1)(T (+ (fibo (- n 1)) (fibo (- n 2))))))") <ECL: FIBO> sage: ecl_eval("(mapcar 'fibo '(1 2 3 4 5 6 7))") <ECL: (1 1 2 3 5 8 13)>
- sage.libs.ecl.init_ecl()¶
Internal function to initialize ecl. Do not call.
This function initializes the ECL library for use within Python. This routine should only be called once and importing the ecl library interface already does that, so do not call this yourself.
EXAMPLES:
sage: from sage.libs.ecl import *
At this point, init_ecl() has run. Explicitly executing it gives an error:
sage: init_ecl() Traceback (most recent call last): ... RuntimeError: ECL is already initialized
- sage.libs.ecl.print_objects()¶
Print GC-protection list
Diagnostic function. ECL objects that are bound to Python objects need to be protected from being garbage collected. We do this by including them in a doubly linked list bound to the global ECL symbol SAGE-LIST-OF-OBJECTS. Only non-immediate values get included, so small integers do not get linked in. This routine prints the values currently stored.
EXAMPLES:
sage: from sage.libs.ecl import * sage: a=EclObject("hello") sage: b=EclObject(10) sage: c=EclObject("world") sage: print_objects() #random because previous test runs can have left objects NIL WORLD HELLO
- sage.libs.ecl.shutdown_ecl()¶
Shut down ecl. Do not call.
Given the way that ECL is used from python, it is very difficult to ensure that no ECL objects exist at a particular time. Hence, destroying ECL is a risky proposition.
EXAMPLES:
sage: from sage.libs.ecl import * sage: shutdown_ecl()
- sage.libs.ecl.test_ecl_options()¶
Print an overview of the ECL options
- sage.libs.ecl.test_sigint_before_ecl_sig_on()¶