Last active
December 10, 2023 21:28
-
-
Save kurinoku/a0a788a6e9226ce48942da8a2533a8f6 to your computer and use it in GitHub Desktop.
[Racket] Dynamically evaluate your language using `make-module-evaluator`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 | |
...) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.