如何在球拍中创建一种新语言?

JRR*_*JRR 7 racket

我想创建一种与类型化球拍具有相同语法的新语言,但在执行时会做两件事:

  1. 运行给定的程序作为输入球拍
  2. 如果类型检查,则将输入翻译成另一种语言(比如python)。我计划编写一个从类型化球拍形式到 python 语法的翻译器。

关于如何开始或指向一些骨架代码的任何建议?我已经阅读了本教程,但它主要讨论创建我不需要的新语法。

我了解如何编写球拍代码以将一种语言翻译成另一种语言,但我不明白的是我如何才能做到以上两点,即首先将其作为另一种语言运行,然后使用相同的输入执行其他操作.

Lei*_*sen 6

听起来你想创造一种新#%module-begin形式的语言。这种形式要么由读者插入(当您#lang ....在文件顶部添加一行时,要么由语言插入(如果您手动编写模块)。无论哪种方式,它通常与您的语言定义相关联。该宏具有完全访问权限整个模块的未扩展语法。例如,像这样的宏:

(provide (rename-out [-module-begin #%module-begin]))
(define-simple-macro (-module-begin body ...)
  (#%module-begin
    (writeln '(body ...))
    body ...))
Run Code Online (Sandbox Code Playgroud)

将创建一种可以做两件事的语言:

  1. 打印出代码主体(作为 s 表达式),并且

  2. #%module-begin使用编写语言定义的来运行主体。

您可以看到如何使用此技术两次抓取程序主体,并用它执行两项不同的操作。那么让我们尝试运行这个示例。首先,让我们从上面获取示例,并将其放入文件“mylang.rkt”中:

#lang racket
(provide (rename-out [-module-begin #%module-begin])
         (except-out (all-from-out racket) #%module-begin))
(require syntax/parse/define)
(define-simple-macro (-module-begin body ...)
  (#%module-begin
    (writeln '(body ...))
    body ...))
Run Code Online (Sandbox Code Playgroud)

现在我们可以编写mylang这样的程序:

#lang s-exp "mylang.rkt"
(+ 1 2)
Run Code Online (Sandbox Code Playgroud)

当你运行它时,你会得到类似这样的信息:

((+ 1 2))
3
Run Code Online (Sandbox Code Playgroud)

首先打印出程序文本,然后运行它。

您可以在我撰写的讨论视频语言这一方面的论文中阅读有关此过程的更多信息。您可能还会发现《美丽的球拍》一书中有一些您可能会觉得有用的示例。