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

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. Python 1 —— Start Up

    作为一种脚本语言,Python号称是万能的胶带语言,可以非常好的作为多种语言之间的粘合剂,因此从多种语言融合的角度看,学习Python是非常有必要的!下面对学习Python当中的一些重点进行记录! 一 ...

  2. 删除xcode中的描述文件的路径

    打开Finder  commend + shift +g 进入文件夹  : ~/Library/MobileDevice/Provisioning Profiles  删除即可

  3. 「2013-9-5」Configure WingIDE for better display of East Asian Glyphs

    很久没写软件配置相关的博客了.这次对于 WingIDE 在 Windows 下的字体配置,折腾了好一阵子,略曲折,也反映了「不清楚原理和背景的情况下,盲人摸象的效率低下是必然」这条放之四海而皆准的赤果 ...

  4. iPad应用开发者的建议

    原文摘自Smashing Magazine<A Dad’s Plea To Developers of iPad Apps For Children> 我花了很长时间为孩子购买和测试iPa ...

  5. C2第四次作业解题报告

    看过题解后如果觉得还算有用,请帮忙加点我所在团队博客访问量 http://www.cnblogs.com/newbe/ http://www.cnblogs.com/newbe/p/4069834.h ...

  6. GET和POST有什么区别?

    前几天有人问我这个问题.我说GET是用于获取数据的,POST,一般用于将数据发给服务器之用. 这个答案好像并不是他想要的.于是他继续追问有没有别的区别?我说这就是个名字而已,如果服务器支持,他完全可以 ...

  7. javascript中的call()和apply()方法的使用

    1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...

  8. Linux: shell常用通配符

    字符 含义 * 匹配 0 或多个字符 ? 匹配任意一个字符 [list] 匹配 list 中的任意单一字符 [!list] 匹配 除list 中的任意单一字符以外的字符 [c1-c2] 匹配 c1-c ...

  9. Minifying Angular应用时产生的问题

    一.产生的问题 如果你正在进行AngularJS的项目开发,生产时Minified JS文件有没有遇到下面问题: angular.module("myApp", []) .cont ...

  10. 移动开发下Xamarin VS PhoneGap

    跨平台开发 移动应用开发对很多开发人员来说是一种令人恐惧的事情.许多企业希望能够通过开发移动应用程序,来提升企业业务水平,开发原生App时往往又缺少专业的Objective C 或 Java 移动开发 ...