在REPL中使用#lang设置语言

时间:2014-01-08 23:16:13

标签: racket geiser

我想使用#lang动态设置REPL中的语言,而不是使用“-I”命令行参数。但这给了我错误“读取:#lang在当前上下文中未启用”。

我是否缺少命令行开关?或者也许我可以使用“,metacommand”?我需要这个的原因是因为我希望能够将一个Emacs缓冲区发送到Racket REPL,但如果该文件以#lang开头,则无效。

3 个答案:

答案 0 :(得分:9)

[编辑]

我无法让C-x C-b#lang合作。

但是包含#lang的缓冲区可以通过C-c C-a从Geiser发送到REPL。这是从Geiser下拉菜单切换到REPL并输入模块。如果我有bugsy.rkt的缓冲区:

;; bugsy.rkt
#lang racket
(define k 6)
(define j 7)
(define (f lhs rhs)
   (+ lhs rhs))

键入C-c C-a在REPL中给出了这个:

racket@> ,enter "<filepath>/bugsy.rkt"
racket@bugsy.rkt>

然后我可以访问REPL中的模块:

racket@bugsy.rkt> k
6
racket@bugsy.rkt> (f 3 4)
7

如果我想切换到另一个模块[或文件的缓冲区],我可以在REPL中使用,enter命令:

racket@bugsy.rkt> ,enter "clyde.rkt"
racket@clyde.rkt> ,enter "bonny.rkt"
racket@bonny.rkt>

文档中有一个,enter命令的示例。 Look above the Dinosaur

[原文]

根据Racket文档#lang has very simple syntax,读者基本上从#lang之后的空格字符后面的任何内容引导语言语法。这意味着在某种意义上#lang不在Racket [或任何其他语言]的语法中。相反,它是读者的一个实现功能,它构成了更大的“Racket”开发生态系统的一部分。

Geiser [并且可能是Quack和racket-mode]通过在将代码传递给Racket REPL之前解析elsip中的#lang来处理此问题。在Geiser中,工作在geiser-racket.el完成。

解析功能位于第132行:

(defun geiser-racket--language ()
  (or (cdr (geiser-racket--explicit-module))
      (save-excursion
        (goto-char (point-min))
        (if (re-search-forward "^#lang +\\([^ ]+\\)" nil t)
            (geiser-syntax--form-from-string (match-string-no-properties 1))))
      "#f"))

第166行由geiser-racket--geiser-procedure调用。

(defun geiser-racket--geiser-procedure (proc &rest args)
  (case proc
    ((eval compile)
     (format ",geiser-eval %s %s %s"
             (or (car args) "#f")
             (geiser-racket--language)
             (mapconcat 'identity (cdr args) " ")))
    ((load-file compile-file)
     (format ",geiser-load %S" (geiser-racket--find-module)))
    ((no-values) ",geiser-no-values")
    (t (format ",apply geiser:%s (%s)" proc (mapconcat 'identity args " ")))))

如果现有的Emacs模式之一无法满足您的需求,这可能会为您提供滚动自己代码的起点。

答案 1 :(得分:4)

; foo.rkt
#lang whatever
"hi"

基本相同
(module foo whatever
  "hi")

所以作为一个快速黑客,你可以切掉#lang行,抓住它的lang,然后将(module ...)形式的其余部分填充到comint-send-input形式之前,enter /path/to/file.rkt - 它。

更简单,如果您不介意将缓冲区保存到磁盘,首先:只需将(enter! "/path/to/file.rkt")发送到REPL缓冲区,或者如果您不使用XREPL,{{1}}。

此外,值得一提的是一些与球拍相关的模式:

其中一个可能已经做了你想做的事情,或者,你可以看看它们是如何工作的(每个都采用了一种不同的方法)。

答案 2 :(得分:0)

我很难用Racket&amp; amp;使用#lang sicp通过SICP的Geiser。终于想通了。基于上面所有的好答案,这些是评论,以提醒自己该做什么和为什么:

#lang sicp
;;C-c C-a loads #lang module into REPL (save before loading)
;;C-u C-c C-z is faster than C-c C-a
;;https://docs.racket-lang.org/sicp-manual/index.html
;;https://stackoverflow.com/questions/21008623/setting-language-with-lang-in-the-repl
(#%require sicp-pict)
(paint einstein)

Racket和Geiser是两款令人惊叹的软件,几乎放弃了,但值得努力才能实现这一目标。感谢所有人的出色工作并帮助我们学习。