2016-06-23 9 views
2

Ich muss eine Racket-Quelldatei lesen und sie durch Makroerweiterung ausführen. Ich habe eine einfache Test-Datei, die Schläger selbst glücklich akzeptiert:Lesen und Erweitern einer Racket-Quelldatei

C:\ayane>type factorial.rkt 
#lang racket 
(provide factorial) 

(define (factorial n) 
(if (<= n 1) 
    1 
    (* n (factorial (sub1 n))))) 

Jetzt versuche ich aus dem REPL:

C:\ayane>racket 
Welcome to Racket v6.5. 
> (read-accept-reader #t) 
> (expand (with-input-from-file "factorial.rkt" (lambda() (read-syntax "factorial.rkt")))) 
#<syntax::1 (module factorial racket (#%m...> 

So weit so gut. Nun ist die gleiche Sache aus einem Testprogramm:

C:\ayane>type test.rkt 
#lang racket 
(read-accept-reader #t) 
(expand (with-input-from-file "factorial.rkt" 
           (lambda() 
           (read-syntax "factorial.rkt")))) 

C:\ayane>racket test.rkt 
factorial.rkt::1: module: unbound identifier; 
also, no #%app syntax transformer is bound 
    at: module 
    in: (module factorial racket (#%module-begin (provide factorial) (define (factorial n) (if (<= n 1) 1 (* n (factorial (sub1 n))))))) 
    context...: 
    C:\ayane\test.rkt: [running body] 

So sieht es aus wie der gleiche Code interaktiv, aber nicht in einem Programm funktioniert. Was vermisse ich?

Antwort

4

Sie müssen angeben, welcher Namespace expand verwenden soll, um Variablen auf oberster Ebene (d. H. Variablen, die nicht im Programm gebunden sind) zu verwenden.

Zum Beispiel:

(parameterize ([current-namespace (make-base-namespace)]) 
    (expand ...)) 

Weitere Informationen finden Sie in den Kommentaren in der Datei unten, in dem ich versuche, die Beziehung zwischen Namespaces zu erklären und erweitern:

https://github.com/soegaard/meta/blob/master/runtime/racket-eval.rkt#L122

Verwandte Themen