@@ -424,12 +424,13 @@ def print_objects():
424
424
if c == Cnil:
425
425
break
426
426
427
- cdef cl_object python_to_ecl(pyobj) except NULL :
427
+ cdef cl_object python_to_ecl(pyobj, bint read_strings ) except NULL :
428
428
# conversion of a python object into an ecl object
429
429
# most conversions are straightforward. Noteworthy are:
430
430
# python lists -> lisp (NIL terminated) lists
431
431
# tuples -> dotted lists
432
- # strings ->parsed by lisp reader
432
+ # strings -> if read_strings is true, parsed by lisp reader
433
+ # otherwise creates a simple-string
433
434
434
435
cdef bytes s
435
436
cdef cl_object L, ptr, o
@@ -445,7 +446,7 @@ cdef cl_object python_to_ecl(pyobj) except NULL:
445
446
if pyobj >= MOST_NEGATIVE_FIXNUM and pyobj <= MOST_POSITIVE_FIXNUM:
446
447
return ecl_make_integer(pyobj)
447
448
else :
448
- return python_to_ecl(Integer(pyobj))
449
+ return python_to_ecl(Integer(pyobj), read_strings )
449
450
elif isinstance (pyobj,int ):
450
451
return ecl_make_integer(pyobj)
451
452
elif isinstance (pyobj,float ):
@@ -455,46 +456,53 @@ cdef cl_object python_to_ecl(pyobj) except NULL:
455
456
s = str_to_bytes(pyobj, ' ascii' )
456
457
except UnicodeEncodeError :
457
458
o = cl_funcall(2 , make_unicode_string_clobj,
458
- python_to_ecl([ord (c) for c in pyobj]))
459
+ python_to_ecl([ord (c) for c in pyobj], read_strings ))
459
460
else :
460
461
o = ecl_cstring_to_base_string_or_nil(s)
461
- return ecl_safe_funcall(read_from_string_clobj, o)
462
+
463
+ if read_strings:
464
+ return ecl_safe_funcall(read_from_string_clobj, o)
465
+ else :
466
+ return o
462
467
elif isinstance (pyobj,bytes):
463
468
s= < bytes> pyobj
464
- return ecl_safe_read_string(s)
469
+ if read_strings:
470
+ return ecl_safe_read_string(s)
471
+ else :
472
+ return ecl_cstring_to_base_string_or_nil(s)
465
473
elif isinstance (pyobj,Integer):
466
474
if pyobj >= MOST_NEGATIVE_FIXNUM and pyobj <= MOST_POSITIVE_FIXNUM:
467
475
return ecl_make_integer(pyobj)
468
476
else :
469
477
return ecl_bignum_from_mpz( (< Integer> pyobj).value )
470
478
elif isinstance (pyobj,Rational):
471
479
return ecl_make_ratio(
472
- python_to_ecl( (< Rational> pyobj).numerator() ),
473
- python_to_ecl( (< Rational> pyobj).denominator()))
480
+ python_to_ecl( (< Rational> pyobj).numerator(), read_strings ),
481
+ python_to_ecl( (< Rational> pyobj).denominator(), read_strings ))
474
482
elif isinstance (pyobj,EclObject):
475
483
return (< EclObject> pyobj).obj
476
484
elif isinstance (pyobj, list ):
477
485
if not pyobj:
478
486
return Cnil
479
487
else :
480
- L= cl_cons(python_to_ecl(pyobj[0 ]),Cnil)
481
- ptr= L
488
+ L = cl_cons(python_to_ecl(pyobj[0 ], read_strings ),Cnil)
489
+ ptr = L
482
490
for a in pyobj[1 :]:
483
- cl_rplacd(ptr,cl_cons(python_to_ecl(a), Cnil))
484
- ptr= cl_cdr(ptr)
491
+ cl_rplacd(ptr, cl_cons(python_to_ecl(a, read_strings), Cnil))
492
+ ptr = cl_cdr(ptr)
485
493
return L
486
494
elif isinstance (pyobj, tuple ):
487
495
if not pyobj:
488
496
return Cnil
489
497
elif len (pyobj) == 1 :
490
- return python_to_ecl(pyobj[0 ])
498
+ return python_to_ecl(pyobj[0 ], read_strings )
491
499
else :
492
- L= cl_cons(python_to_ecl(pyobj[0 ]), Cnil)
493
- ptr= L
500
+ L = cl_cons(python_to_ecl(pyobj[0 ], read_strings), Cnil)
501
+ ptr = L
494
502
for a in pyobj[1 :- 1 ]:
495
- cl_rplacd(ptr,cl_cons(python_to_ecl(a), Cnil))
496
- ptr= cl_cdr(ptr)
497
- cl_rplacd(ptr,python_to_ecl(pyobj[- 1 ]))
503
+ cl_rplacd(ptr, cl_cons(python_to_ecl(a, read_strings), Cnil))
504
+ ptr = cl_cdr(ptr)
505
+ cl_rplacd(ptr, python_to_ecl(pyobj[- 1 ], read_strings ))
498
506
return L
499
507
else :
500
508
raise TypeError (" Unimplemented type for python_to_ecl" )
@@ -591,6 +599,8 @@ cdef class EclObject:
591
599
592
600
sage: EclObject( ( false, true))
593
601
<ECL: ( NIL . T) >
602
+ sage: EclObject( ( 1, 2, 3) )
603
+ <ECL: ( 1 2 . 3) >
594
604
595
605
Strings are fed to the reader, so a string normally results in a symbol::
596
606
@@ -602,6 +612,28 @@ cdef class EclObject:
602
612
sage: EclObject( '"Symbol"')
603
613
<ECL: "Symbol">
604
614
615
+ Or any other object that the Lisp reader can construct::
616
+
617
+ sage: EclObject( '#( "I" am "just" a "simple" vector) ')
618
+ <ECL: #( "I" AM "just" A "simple" VECTOR) >
619
+
620
+ By means of Lisp reader macros, you can include arbitrary objects::
621
+
622
+ sage: EclObject( [ 1, 2, '''#.(make-hash-table :test #'equal)''', 4 ])
623
+ <ECL: ( 1 2 #<hash-table ... > 4) >
624
+
625
+ Using an optional argument, you can control how strings are handled::
626
+
627
+ sage: EclObject( "String", False)
628
+ <ECL: "String">
629
+ sage: EclObject( '#( I may look like a vector but I am a string) ', False)
630
+ <ECL: "#( I may look like a vector but I am a string) ">
631
+
632
+ This also affects strings within nested lists and tuples ::
633
+
634
+ sage: EclObject( [1, 2, "String", 4 ], False)
635
+ <ECL: ( 1 2 "String" 4) >
636
+
605
637
EclObjects translate to themselves, so one can mix::
606
638
607
639
sage: EclObject( [1,2,EclObject([3 ]) ])
@@ -661,7 +693,7 @@ cdef class EclObject:
661
693
if not (bint_fixnump(o) or bint_characterp(o) or bint_nullp(o)):
662
694
self .node= insert_node_after(list_of_objects,o)
663
695
664
- def __init__ (self ,*args ):
696
+ def __init__ (self , *args ):
665
697
r """
666
698
Create an EclObject
667
699
@@ -674,8 +706,14 @@ cdef class EclObject:
674
706
<ECL: ( NIL T NIL) >
675
707
676
708
"""
677
- if len (args) != 0 :
678
- self .set_obj(python_to_ecl(args[0 ]))
709
+ if not args:
710
+ return
711
+ elif len (args) == 1 :
712
+ self .set_obj(python_to_ecl(args[0 ], True ))
713
+ elif len (args) == 2 :
714
+ self .set_obj(python_to_ecl(args[0 ], args[1 ]))
715
+ else :
716
+ raise TypeError (' EclObject.__init__ received a wrong number of arguments' )
679
717
680
718
def __reduce__ (self ):
681
719
r """
@@ -1354,7 +1392,7 @@ cpdef EclObject ecl_eval(str s):
1354
1392
1355
1393
"""
1356
1394
cdef cl_object o
1357
- o= ecl_safe_eval(python_to_ecl(s))
1395
+ o= ecl_safe_eval(python_to_ecl(s, True ))
1358
1396
return ecl_wrap(o)
1359
1397
1360
1398
init_ecl()
0 commit comments