Skip to content

Instantly share code, notes, and snippets.

@kurinoku
Last active December 10, 2023 21:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kurinoku/a0a788a6e9226ce48942da8a2533a8f6 to your computer and use it in GitHub Desktop.
Save kurinoku/a0a788a6e9226ce48942da8a2533a8f6 to your computer and use it in GitHub Desktop.
[Racket] Dynamically evaluate your language using `make-module-evaluator`
#lang racket/base
(require racket/sandbox
racket/runtime-path
"parser.rkt"
"tokenizer.rkt"
"expander.rkt"
syntax/strip-context)
;; To pass to the module datum
(define-runtime-path expander "expander.rkt")
;; This way, it doesn't matter from what file you evaluate your
;; code, it expands correctly using our expander
(define module-datum `(module m ,expander))
;; I make it a procedure, because `sandbox-namespace-specs`
;; is a list of a thunk followed optionally by module paths
(define (my-sandbox-namespace)
(namespace-anchor->namespace EXPANDER-ANCHOR))
;; you might want to define more module paths with
;; define-runtime-path and add them here
(define allow-for-require (list expander ...))
(define my-mod-eval
(parameterize ([sandbox-namespace-specs (list my-sandbox-namespace)])
(make-module-evaluator module-datum
#:allow-for-require allow-for-require)))
(define (code-string->syntax str)
(strip-context
(parse
(make-tokenizer
(open-input-string str)))))
;; this should do
(define (my-eval str)
(define stx (code-string->syntax str))
(my-mod-eval stx))
(provide my-eval)
(module+ test
(require rackunit)
(check-pred thing? (my-eval "(thing)"))) ; #t
#lang racket/base
(require ...)
;; this will make possible to use structs gotten from our eval
;; to result in #t when called in struct predicates
(define-namespace-anchor EXPANDER-ANCHOR)
(struct thing ())
(provide (struct-out thing)
EXPANDER-ANCHOR
...)
@kurinoku
Copy link
Author

kurinoku commented Aug 30, 2020

Heads up, I thought I made a mistake and added a warning, but then deleted it. It was another part of the code that I made that was wrong. This code works well. Just in case someone saw the commits of this gist.

@ashpool37
Copy link

Thank you for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment