Ich versuche in Racket eine Modul-Meta-Sprache mylang
zu schreiben, die eine zweite Sprache akzeptiert, an die der modifizierte Körper übergeben wird, so dass:
%Vor%
entspricht:
%Vor% wobei der typed/racket
-Teil natürlich durch jede andere Modulsprache ersetzt werden kann.
Ich habe eine einfache Version versucht, die den Körper unverändert lässt. Es funktioniert in der Befehlszeile gut , gibt jedoch den folgenden Fehler bei der Ausführung in DrRacket:
%Vor%Hier ist der ganze Code:
%Vor%Anforderungen (d. h. Lösungen, die ich lieber vermeiden möchte):
(require (only-in typed/racket))
im Modul mylang
funktioniert, aber ich bin an einer allgemeinen Lösung interessiert, bei der mylang
nicht über typed/racket
at al wissen muss (dh wenn jemand ein neues hinzufügt) language foo
, dann sollte mylang
mit dem out of the box funktionieren). Ich bin auch nicht an Tricks interessiert, die ein Submodul deklarieren und sofort require
und re provide
it, wie hier , weil dadurch der Pfad zum eigentlichen Modul geändert wird (zB main
und test
verlieren ihr spezielles Verhalten).
Es ist auch langsamer zur Kompilierzeit, da Submodule besucht (begin-for-syntax (displayln 'here))
und hat eine spürbare Auswirkung auf große typed/racket
-Programme.
Bonuspunkte, wenn die Pfeile in DrRacket für von der delegierten Sprache bereitgestellte Einfügungen funktionieren, z. Im obigen Beispiel haben Sie Pfeile von ann
, +
und Number
bis typed/racket/base
.
Eine Sache, die Sie tun können, was meiner Meinung nach Ihre Anforderungen nicht verletzt, ist es in ein Modul zu stecken, dieses Modul vollständig zu erweitern und dann auf #%plain-module-begin
anzupassen, um eine Anforderung einzufügen.
Und wenn du den Körper irgendwie transformieren willst, könntest du das entweder vor oder nach der Erweiterung machen.
Der Mustervergleich zum Einfügen der zusätzlichen (#%require lng)
ist erforderlich, da das Erweitern des Modulkörpers in einem Kontext, in dem lng
verfügbar ist, nicht ausreicht. Wenn Sie den Code mod-body
wieder aus dem Formular module
entfernen, bedeutet dies, dass sich die Bindungen auf lng
beziehen, aber lng
zur Laufzeit nicht verfügbar ist. Deshalb bekomme ich den require: namespace mismatch; reference to a module that is not available
-Fehler ohne ihn, und deshalb muss er nach der Erweiterung hinzugefügt werden.
lng
einen Bezeichner x
liefert und das Modul, in dem es verwendet wird, ein anderes x
importiert, wird ein Importkonflikt auftreten, wo dies nicht sein sollte. Require-Zeilen sollten sich in einem "verschachtelten Bereich" in Bezug auf die Modulsprache befinden, damit sie Kennungen wie x
hier schattieren können.
@ GeorgesDupéron hat in dieser E-Mail auf der Racketbenutzerliste (make-syntax-introducer)
mod-body
verwenden, um den verschachtelten Bereich zu erstellen.
Tags und Links require racket metalanguage