这个解释器可以用来跑前面两篇文章的例子,所以一并扔出来,三部曲哈哈。

Lisp内置的S-expression相当于解析好的语法树,而借助quasiquote和unquote又很容易进行语法树层面的变换,所以Lisp的自举和扩展都很容易。

相对而言,其他语言有入门教材就讲怎么实现语言自身的解释器的吗?至少命令式语言恐怕不容易,尤其是中缀表示法的语言,Parser这一关会卡死很多人。

这个解释器的典型特性包括currying、call/cc,所以可以用来跑前面的lambda calculus和yin-yang-puzzle例子:

 #lang racket

 (require racket/match)
;------------------------------
(define (eval env e k)
(match e
[(? symbol?) (k (cdr (assq e env)))]
[(list 'lambda arg-list exp-list ...)
(let ([arg-list (if (empty? arg-list) '(_) arg-list)])
(cond
[(> (length arg-list) 1)
(eval env `(lambda (,(car arg-list)) (lambda ,(cdr arg-list) ,@exp-list)) k)]
[(> (length exp-list) 1)
(eval env `(lambda ,arg-list ((lambda (_) ,@(cdr exp-list)) ,(car exp-list))) k)]
[else (k
(lambda (arg k2)
(eval (cons (cons (car arg-list) arg) env) (car exp-list) k2)))]))]
[(list p arg-list ...)
(let ([arg-list (if (empty? arg-list) '(print) arg-list)])
(if (= 1 (length arg-list))
(eval env p (lambda (p)
(eval env (car arg-list) (lambda (arg)
(p arg k)))))
(eval env `((,p ,(car arg-list)) ,@(cdr arg-list)) k)))]
)
)
;------------------------------
(define G (list
(cons 'print (lambda (n k)
(n (lambda (v k2)
(k2 (add1 v)))
(lambda (v)
(v 0 (lambda (v) (k (print v))))))))
(cons 'newline (lambda (_ k)
(k (newline))))
(cons 'call/cc (lambda (f k)
(f (lambda (v k2) (k v)) k)))
))
;------------------------------
(eval G (read) identity)

用到了racket/match,当然,自己弄一个简单的linear pattern matcher也很容易,不过我就不做让事情复杂化的尝试了。

这是前文lambda calculus的例子,一字不变:

 ((lambda (zero one add mul pow sub1 true false and or)
((lambda (sub not zero? two Y)
((lambda (less-equal? equal? three four)
;------------------------------
((lambda (for-each fib)
(for-each (lambda (i) (print (fib zero one zero i))(newline)) zero (mul four four))
)
(Y
(lambda (self)
(lambda (f i n)
(f i)
(((equal? i n)
(lambda () i)
(lambda () (self f (add i one) n))))
)
))
(Y
(lambda (self)
(lambda (a b i n)
(((equal? i n)
(lambda () a)
(lambda () (self b (add a b) (add i one) n))))
)
))
)
;------------------------------
)
(lambda (m n) (zero? (sub m n)))
(lambda (m n) (and (zero? (sub m n)) (zero? (sub n m))))
(add two one)
(add two two)
))
(lambda (m n) (n sub1 m))
(lambda (a) (a false true))
(lambda (n) (n (lambda (x) false) true))
(add one one)
(lambda (f)
((lambda (g) (g g))
(lambda (g) (f (lambda (a) ((g g) a))))))
))
(lambda (f x) x)
(lambda (f x) (f x))
(lambda (m n f x) (m f (n f x)))
(lambda (m n f) (m (n f)))
(lambda (e b) (e b))
(lambda (n f x)
(((n
(lambda (g h) (h (g f))))
(lambda (u) x))
(lambda (u) u)))
(lambda (a b) a)
(lambda (a b) b)
(lambda (a b) (a b a))
(lambda (a b) (a a b))
)

这是yin-yang-puzzle的例子,人肉展开了let*

 ((lambda (yin)
((lambda (yang)
(yin yang))
((lambda (c) (print (lambda (f x) x)) c)
(call/cc (lambda (k) k)))))
((lambda (c) (print (lambda (f x) (f x))) c)
(call/cc (lambda (k) k))))

[Scheme]一个Scheme的Metacircular evaluator的更多相关文章

  1. Scheme语言实例入门--怎样写一个“新型冠状病毒感染风险检测程序”

    小学生都能用的编程语言 2020的春季中小学受疫情影响,一直还没有开学,孩子宅在家说想做一个学校要求的研究项目,我就说你做一个怎么样通过编程来学习数学的小项目吧,用最简单的计算机语言来解决小学数学问题 ...

  2. 算法语言Scheme修订6报告 R6RS简体中文翻译

    算法语言Scheme修订6报告 R6RS简体中文翻译 来源 https://r6rs.mrliu.org/   MICHAEL SPERBERR. KENT DYBVIG, MATTHEW FLATT ...

  3. Android业务组件化之URL Scheme使用

    前言: 最近公司业务发展迅速,单一的项目工程不再适合公司发展需要,所以开始推进公司APP业务组件化,很荣幸自己能够牵头做这件事,经过研究实现组件化的通信方案通过URL Scheme,所以想着现在还是在 ...

  4. iOS - URL Scheme 操作

    推荐JLRoutes路由跳转 NSScanner 在寻找更加灵活的页面跳转和通知,我遇见了JLRoutes,从而学习使用URL Scheme来定义界面入口.以前从来没有使用过,不过很多大厂和流行的框架 ...

  5. 自定义 URL Scheme 完全指南

    本文由 Migrant 翻译自 The Complete Tutorial on iOS/iPhone Custom URL Schemes,转载请注明出处. 注意: 自从自定义 URL 的引入,本文 ...

  6. Project、Target、Workspace and Scheme

    前言 今天有人问我Target和Project是什么关系?额...学习iOS开发都知道Target和Project的关系.这里我就简单的做了一个总结,而且加入的Scheme和Workspace.如果不 ...

  7. 自定义 URL Scheme 完全指南(转载)

    iPhone / iOS SDK 最酷的特性之一就是应用将其自身”绑定”到一个自定义 URL scheme 上,该 scheme 用于从浏览器或其他应用中启动本应用. 注册自定义 URL Scheme ...

  8. URL Scheme APP跳转safari以及跳回APP

    上图 : 在plist文件里面设置. URL identifier 一般为反域名+项目名称 (尽可能保证少重复) URL Schemes是一个数组.一个APP可以添加多个.该参数为跳转时使用的标识. ...

  9. OpenCascade Tcl vs. ACIS Scheme

    OpenCascade Tcl vs. ACIS Scheme eryar@163.com 摘要Abstract:本文通过OpenCascade的Tcl/Tk和ACIS的Scheme的对比来说明脚本语 ...

随机推荐

  1. JBOSS通过Apache负载均衡方法一:使用mod_jk

    JBOSS通过Apache负载均衡方法一:使用mod_jk   本文第一.二节分别对Linux环境下前端使用Apache以及windows环境下前端使用IIS通过AJP协议和后端的JBOSS通信实现负 ...

  2. codeforces 425D

    题意:给定n<=100000个二维点,并且0<=x,y<=100000,求有多少个平行于坐标轴的正方形 思路:本来想hash的,但是感觉不好弄.. 后来感觉像是分块,最坏的情况就是那 ...

  3. 解析ASP.NET Mvc开发之查询数据实例

    目录: 1)从明源动力到创新工场这一路走来 2)解析ASP.NET WebForm和Mvc开发的区别 ------------------------------------------------- ...

  4. [ACM_几何] UVA 11300 Spreading the Wealth [分金币 左右给 最终相等 方程组 中位数]

    Problem A Communist regime is trying to redistribute wealth in a village. They have have decided to ...

  5. JavaScript:最烂与最火

    ============================================================================== 一.世无英雄,遂使竖子成名 1 Web客户 ...

  6. .NET通过RFC读取SAP数据

    本篇文章中我主要讲的是.NET如何通过RFC从SAP中读取数据.为了功能的可复用性,我将调用RFC的代码从业务层中分离出来单独建立在一个namespace中. 当然除了需要我们自己编写代码以外,还需要 ...

  7. CSS关于元素垂直居中的问题

    今天碰到了一个问题,给一个父容器和一个子元素,子元素不定高和不定宽,怎么让子元素居中在父容器中,比如下段代码 方法1: <div class="div1"> <d ...

  8. paip.mysql 全文索引查询空白解决

    paip.mysql 全文索引查询空白解决   或者  Incorrect key file for table: \'%s\'. Try to repair it    作者Attilax  艾龙, ...

  9. MVC 添加 httpHandlers 支持 .aspx 页面访问

    <?xml version="1.0"?> <!-- For more information on how to configure your ASP.NET ...

  10. FreeMarker模板语法

    四.FreeMarker模板语法 要编写复杂的模板需要熟悉FreeMarker语法规则,官网有详细说明,中文帮助也比较详细了,下面这些内容是从网上收罗来的,感谢网友的分享,经过整理与修改的内容如下.建 ...