Racket 宏将除 s 表达式之外的所有内容字符串化
Racket macro to stringify all but s-expressions
我正在尝试弄清楚如何创建一个 racket 宏,它将简单地将所有内容转换为字符串,除了 s-expressions 之外,它将单独保留。
我已经弄清楚如何将所有内容字符串化
#+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)"
但是不知道如何测试某个东西是否是 s 表达式。
我该怎么做?
如果我们使用atom?
程序的通常定义作为参考:
(defne (atom? exp)
(and (not (null? exp))
(not (pair? exp))))
然后我们可以定义一个 s-expression 谓词:
(define (s-exp? exp)
(or (null? exp)
(pair? exp)))
当然,您需要将此递归地应用于 s 表达式的每个元素。
"s-expression" 是语法 list/pair,因此您可以对 ()
和 (a . b)
进行模式匹配,如下所示:
#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")
我正在尝试弄清楚如何创建一个 racket 宏,它将简单地将所有内容转换为字符串,除了 s-expressions 之外,它将单独保留。
我已经弄清楚如何将所有内容字符串化
#+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)"
但是不知道如何测试某个东西是否是 s 表达式。
我该怎么做?
如果我们使用atom?
程序的通常定义作为参考:
(defne (atom? exp)
(and (not (null? exp))
(not (pair? exp))))
然后我们可以定义一个 s-expression 谓词:
(define (s-exp? exp)
(or (null? exp)
(pair? exp)))
当然,您需要将此递归地应用于 s 表达式的每个元素。
"s-expression" 是语法 list/pair,因此您可以对 ()
和 (a . b)
进行模式匹配,如下所示:
#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")