簡體   English   中英

在Racket腳本中調用`racket`

[英]Invoke `racket` in a Racket script

一般問題:

我可以在正在運行的Racket腳本中調用當前的racket可執行文件嗎?

基本上,在(find-executable-path "racket")沒有返回我正在使用的Racket可執行(find-executable-path "racket")的情況下,我想替換(system "racket ...")

語境:

我真正想要的是嘗試編譯一些表達式並斷言它們會引發編譯錯誤。 這是用於單元測試。

我不相信你需要在這里走出可執行文件。 嘗試這個:

#lang racket

(require syntax/modread)

;; define a namespace anchor to attach a namespace to:
(define-namespace-anchor anchor)
;; define a namespace for expansion:
(define target-namespace (namespace-anchor->namespace anchor))

(define program-to-compile
  "#lang racket
(+ 3 4)")

;; go ahead and expand
(with-module-reading-parameterization
 (λ()
   (parameterize ([current-namespace target-namespace])
   (expand
    (read-syntax
     "bogus-filename"
     (open-input-string program-to-compile))))))

當我說Racket在提供編譯器以規范方式運行程序的能力方面非常干凈時,我認為我是正確的。

如果您的目標只是編譯一些球拍表達式,那么您可以使用compile compile-syntaxcompile-syntax 示例文件將是:

#lang racket
(require rackunit)

(define tests
  (list #'(+ 1 "3")
        #'(void void)
        #'(string-append 4)))

(for/list ([t (in-list test)])
  (check-exn exn:fail?
     (lambda () (compile t))))

exn:fail? 無論你正在尋找什么異常。

此外,如果你有一些常見的語法上下文,你想運行你的測試,你可以使用#` #, #` 所以你的代碼最終會是這樣的:

#lang racket
(require rackunit)

(define tests
  (list #'(+ 1 "3")
        #'(void void)
        #'(string-append 4)))

(for/list ([t (in-list test)])
  (check-exn exn:fail?
     (lambda () (compile #`(module anonymous racket
                             #,t)))))

最后,如果您的代碼存儲在您的計算機上,您可以使用John的解決方案,同時使用file->string將文件轉換為字符串。

對於小測試,您還可以使用syntax/macro-testing庫中的convert-compile-time-error 它將一個表達式導致編譯時錯誤進入表達式,該表達式在計算時會引發運行時錯誤。 表達式使用模塊中出現的環境,包括本地綁定; 你不必操作命名空間和eval

(check-exn #rx"bad syntax"
            (lambda () (convert-compile-time-error (lambda))))

還有convert-syntax-error (在同一頁面上)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM