I am trying define symbols a and b in following way
a + 1 1 b
2
I am trying to do this by using define-symbol-macro
(define-symbol-macro a '( )
(define-symbol-macro b ') )
but this way is not working.
Symbol macros are special macros with the *. ems file suffix. They are created when you select the desired elements in the schematic and then select the menu item Edit > Create window macro / symbol macro.
Common Lisp is an incredibly flexible language, in part because its source code can be easily represented using the same data structures that are used in the language. The most common form of macro expansion transforms the these structures into other structures. These are the kind of macros that you can define with define-symbol-macro
, define-compiler-macro
, defmacro
, and macrolet
. Before any of those kind of macroexpansions can be performed, however, the system first needs to read the source from an input stream (typically a file, or an interactive prompt). That's the reader's responsibility. The reader also is capable of executing some special actions when it encounters certain characters, such (
and '
. What you're trying to do probably needs to be happening down at the reader level, if you want to have, e.g., (read-from-string "a + 1 1 b")
return the list (+ 1 1)
, which is what you want if you want (eval (read-from-string "a + 1 1 b"))
to return 2
. That said, you could also define a special custom language (like loop
does) where a
and b
are treated specially.
set-macro-character
, not define-symbol-macro
This isn't something that you would do using symbol-macros, but rather with macro characters. You can set macro characters using the aptly named set-macro-character
. For instance, in the following, I set the macro character for %
to be a function that reads a list, using read-delimited-list
that should be terminated by ^
. (Using the characters a
and b
here will prove very difficult, because you won't be able to write things like (set-macro-character ...)
afterwards; it would be like writing (set-m(cro-ch(r(cter ...)
, which is not good.)
CL-USER> (set-macro-character #\% (lambda (stream ignore)
(declare (ignore ignore))
(read-delimited-list #\^ stream)))
T
CL-USER> % + 1 1 ^
2
set-syntax-from-char
There's a related function that almost does what you want here, set-syntax-from-char
. You can use it to make one character behave like another. For instance, you can make %
behave like (
CL-USER> (set-syntax-from-char #\% #\()
T
CL-USER> % + 1 1 )
2
However, since the macro character associated with (
isn't looking for a character that has the same syntax as )
, but an actual )
character, you can't simply replace )
with ^
in the same way:
CL-USER> (set-syntax-from-char #\^ #\))
T
CL-USER> % + 1 1 ^
; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR "unmatched close parenthesis" {1002C66031}>.
set-syntax-from-char
is more useful when there's an existing character that, by itself does something that you want to imitate. For instance, if you wanted to make !
an additional quotation character:
CL-USER> (set-syntax-from-char #\! #\')
T
CL-USER> (list !a !(1 2 3))
(A (1 2 3))
or make %
be a comment character, like it is in LaTeX:
CL-USER> (set-syntax-from-char #\% #\;)
T
CL-USER> (list 1 2 % 3 4
5 6)
(1 2 5 6)
Now, even though you can do all of this, it seems like something that would be utterly surprising to anyone who ran into it. (Perhaps you're entering an obfuscated coding competition? ;)) For the reasons shown above, doing this with commonly used characters such as a
and b
will also make it very difficult to write any more source code. It's probably a better bet to define an entirely new readtable that does what you want, or even write a new parser. even though (Common) Lisp lets you redefine the language, there are still things that it probably makes sense to leave alone.
A symbol-macro is a symbol that stands for another form. Seems like you want to look at reader macros.
I would second Rainer's comment though, what are you trying to make?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With