Racket 编程

4 部分 · 语言设计

创建 #lang

创建 #lang

从零开始创建一个完整的 #lang 语言实现。

#lang 的工作原理

当 Racket 看到 #lang mylang 时,它会:

  1. 找到 mylang 的 reader 模块
  2. 用 reader 将源码文本转换为 S-表达式
  3. 用 expander 展开宏

最简 #lang

;; 创建目录结构
mylang/
├── main.rkt      ; 语言实现
├── reader.rkt    ; 读取器
└── lang/
    └── reader.rkt
;; mylang/main.rkt
#lang racket

(provide (all-from-out racket)
         #%module-begin)

;; 可以在这里添加自定义的语法形式
;; mylang/lang/reader.rkt
#lang s-exp syntax/module-reader
mylang

自定义读取器

#lang 支持完全不同的语法:

;; mylang/lang/reader.rkt
#lang racket

(require syntax/module-reader)

(provide (rename-out [my-read-syntax read-syntax]))

(define (my-read-syntax src port)
  ;; 自定义解析逻辑
  ...)

注册 #lang

通过 info.rkt 注册:

;; mylang/info.rkt
#lang info

(define collection "mylang")
(define deps '("base"))

安装后即可使用:

raco pkg install ./mylang

小结

创建 #lang 让你完全控制语言的读写和展开。从简单的语法别名到全新的语言,Racket 都能支持。