How to force Common Lisp to treat numerals as symbol names?

270 views Asked by At

I hope these codes

(12 3.5 1e4)

could be treated as three symbols

(|12| |3.5| |1e4|)

rather than three numbers.

Can I fulfill this by setting the reader?


Update:

I have a collection of data which is organized as nested lists:

(abc,d/e-f    12ab, 21e4, %rqa, (foo bar), ....)

Different items are separated by commas or spaces (tab and newline included). I want to read them in w.r.t. the nested structure, and without changing any character. The commas can be set as spaces by this:

(set-syntax-from-char #\, #\Space)

Finally the problem remains at the numbers. 21e4 is transferred to 210000.0 by the reader. I don't want to write a parser all from scratch, and try to utilize the reader of common-lisp as much as possible.

2

There are 2 answers

2
Vatine On

You could, I guess. But that would probably end in tears, as you would lose the ability to read numbers.

What are you trying to accomplish, with this, that isn't solvable by iterating over a list of numbers, creating symbols with make-symbol and string?

4
Rainer Joswig On

Example for 1, works in LispWorks:

CL-USER 1 > (setf rt0 *readtable*)
#<READTABLE 40F0038923>

CL-USER 2 > (setf rt1 (copy-readtable nil))
#<READTABLE 4020008C23>

CL-USER 3 > (defun read-digit-symbol (stream char)
              (let ((*readtable* rt0))
                (unread-char char stream)
                (intern
                  (princ-to-string
                    (read stream t nil t)))))
READ-DIGIT-SYMBOL

CL-USER 4 > (set-macro-character #\1 #'read-digit-symbol t rt1)
T

CL-USER 5 > (defun test ()
              (let ((*readtable* rt1))
                (read-from-string "(1 11 111)")))
TEST

CL-USER 6 > (test)
(\1 |11| |111|)
10

CL-USER 7 >