Reputation: 122052
I am trying to figure out how to create a racket macro that will simply convert to a string all contents except for s-expressions which it will leave alone.
I got as far as figuring out how to stringify everything
#+begin_src racket
(define-syntax (stringify-all stx)
(syntax-case stx ()
[(_ args ...)
#'(begin
(~s 'args)
...)]))
(stringify-all one 2 (add1 2))
#+end_src
#+RESULTS:
: "one"
: "2"
: "(add1 2)"
But have no clue how to test whether something is an s-expression or not.
How do I do that?
Upvotes: 1
Views: 117
Reputation: 6502
"s-expression" is syntax list/pair, so you can pattern match for ()
and (a . b)
, like this:
#lang racket
(require (for-syntax (only-in racket/format ~s)))
(define-for-syntax (compute stx)
(syntax-case stx ()
[() #'null]
[(a . b) #`(cons #,(compute #'a) #,(compute #'b))]
[_ (~s (syntax-e stx))]))
(define-syntax (stringify-all stx)
(syntax-case stx ()
[(_ args ...)
#`(begin #,@(map compute (syntax->list #'(args ...))))]))
(stringify-all one 2 (add1 2))
;; "one"
;; "2"
;; '("add1" "2")
Upvotes: 4
Reputation: 235994
If we use the usual definition of the atom?
procedure as reference:
(defne (atom? exp)
(and (not (null? exp))
(not (pair? exp))))
Then we could define an s-expression predicate as:
(define (s-exp? exp)
(or (null? exp)
(pair? exp)))
And of course, you'd need to apply this recursively to each of the elements of an s-expression.
Upvotes: 2