Skip to content

Instantly share code, notes, and snippets.

@shhyou
Last active February 18, 2021 13:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shhyou/75bcfe17f71e452384fcdc068d75f7af to your computer and use it in GitHub Desktop.
Save shhyou/75bcfe17f71e452384fcdc068d75f7af to your computer and use it in GitHub Desktop.
Compilation-time Environment
;; Exporting free identifier table operations that close over a global map
#lang racket/base
(require racket/list
syntax/id-table)
(provide env-ref env-has-id? env-add!)
(define id-table (make-free-id-table))
(define (env-ref id)
(debug-print-binding-info 'env-ref id)
(free-id-table-ref id-table id))
(define (env-has-id? id)
(debug-print-binding-info 'env-has-id? id)
(with-handlers ([exn:fail? (λ (e) #f)])
(free-id-table-ref id-table id)
#t))
(define (env-add! id value)
(debug-print-binding-info 'env-add! id)
(free-id-table-set! id-table id value))
(define (debug-print-binding-info who id)
(define binding
(identifier-binding id))
(printf "env.rkt: ~a:\n id: ~s\n binding: ~s\n"
who
id
(and (list? binding) (take binding 2))))
#lang racket/base
(require (for-syntax racket/base
"0-env.rkt"))
(provide my-fun
your-fun)
(begin-for-syntax
(env-add! #'my-fun "my-fun from add.rkt"))
(define (my-fun a b)
(+ a b))
(begin-for-syntax
(env-add! #'your-fun "your-fun from add.rkt"))
(define (your-fun c)
(- c))
;; See https://docs.racket-lang.org/syntax/syntax-helpers.html#%28part._.Dictionaries_for_free-identifier~3d_%29
;; for the caveat of macro-generated definitions
#lang racket/base
(require (for-syntax racket/base
"0-env.rkt")
"1-add.rkt")
(provide my-fun)
(begin-for-syntax
(env-add! #'my-fun "my-fun from mul.rkt")
(printf "mul.rkt: your-fun is: ~s\n" (env-ref #'your-fun)))
(define (my-fun a b)
(* a (your-fun b)))
;; Dependency:
;; add depends on {env}
;; mul depends on {add,env}
;; use depends on {mul,add,env}
#lang racket/base
(require (for-syntax racket/base
"0-env.rkt")
"2-mul.rkt")
(begin-for-syntax
(printf "use.rkt: my-fun = ~s\n" (env-ref #'my-fun))
(printf "use.rkt: has-key?(your-fun) = ~s\n" (env-has-id? #'your-fun))
)
(my-fun 8 3)
#;
(begin
(require (only-in "1-add.rkt" [my-fun add:my-fun]))
(begin-for-syntax
(printf "use.rkt: add:my-fun = ~s\n" (env-ref #'add:my-fun))
)
(add:my-fun 7 (my-fun 8 3))
)
#lang racket/base
(require (for-syntax racket/base))
(begin-for-syntax
(struct extrainfo (target data)
#:property prop:rename-transformer (struct-field-index target))
(provide extrainfo-data))
(provide (rename-out [my-extra-surface my-extra]))
(define-syntax my-extra-surface
(extrainfo (syntax-property #'my-extra 'not-free-identifier=? #t)
"mul.rkt: my-extra info"))
(define (my-extra a b)
(+ a b))
#lang racket/base
(require "a-extra.rkt")
my-extra
(my-extra 2 3)
(require (for-syntax racket/base
syntax/parse))
(define-syntax (expand-to-extra-info stx)
(syntax-parse stx
[(_ id)
(define-values (info target)
(syntax-local-value/immediate #'id))
#`(quote #,(extrainfo-data info))]))
(expand-to-extra-info my-extra)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment