请参见阶段0中阶段1计算的结果

时间:2016-08-20 02:56:16

标签: racket metaprogramming

假设我有一些非平凡的模块define"覆盖"在球拍中。那"覆盖"收集有关过程体的信息并将其存储到地图中(在编译阶段)。现在我需要在运行时阶段使用收集的信息。直截了当的方法似乎不起作用:

#lang racket

(require (for-syntax racket))

(define-for-syntax map-that-should-be-used-in-phase-0 (make-hash))
(define-for-syntax (fill-in-useful-information n) (hash-set! map-that-should-be-used-in-phase-0 n n))

; Suppose that some useful information is collected here and stored into a map
(define-syntax (fill-in-map stx)
  (begin
    (fill-in-useful-information 1)
    (fill-in-useful-information 2)
    (syntax/loc stx (displayln "OK, the map is filled, but I cannot see it here"))))

(define-syntax (print-that-map stx)
  (syntax/loc stx (displayln map-that-should-be-used-in-phase-0))) ; <-- This can not be compiled

(fill-in-map)
(print-that-map)

我可以在Racket中进行吗?如果是,那怎么样?任何提示都会非常感激!

1 个答案:

答案 0 :(得分:2)

引用变量的标识符无法编译,但它所引用的值可以,只要它是Racket提供的内置数据结构之一,只要它是不可变的。

您可以使用quasisyntaxunsyntax将哈希表值粘贴到语法对象中。

> (quasisyntax (foo #,(hash 'a 4 'b 16)))
#<syntax:5:15 (foo #hash((a . 4) (b . 16)))>

你可以做同样的事情,从编译时到运行时单向通信。

(define-for-syntax (hash->immutable-hash hsh)
  (make-immutable-hash (hash->list hsh)))

(define-syntax (print-that-map stx)
  (quasisyntax/loc stx (displayln #,(hash->immutable-hash map-that-should-be-used-in-phase-0))))