码迷,mamicode.com
首页 > 其他好文 > 详细

[Lua]50行代码的解释器,用来演示lambda calculus

时间:2014-05-21 14:28:02      阅读:357      评论:0      收藏:0      [点我收藏+]

标签:style   blog   class   c   code   java   

嗯,来写写经过:

 

在知乎上看见用Belleve牛用javascript写了一个精简的lisp解释器  

  =>

我也想写一个,用lua写,能多简单呢?  

  =>

写了一个阉割的scheme解释器,包含lambda/if两个special form,以及+-=print几个过程,60行代码  

  =>

能再精简吗?比如把if给去掉?  

  =>

搜索,嗯,lambda calculus能帮我  

  =>

阅读wiki上lambda calculus的"Encoding datatypes"部分  

  =>

改写scheme脚本,用Y-combiantor帮助实现递归,用church numeral表示数字,以及实现church numeral之上的基本逻辑、算数、关系运算,最后用这些基本运算编写for-each和fib过程  

  =>

从解释器里移除关键字if,移除过程+-=,改写print过程使之能够打印church numeral,解释器得以进一步精简到45行  

  =>

虽然scheme脚本为了打印fibonacci数列需要做更多的事情,但解释器仅仅为这门阉割scheme提供了一个lambda关键字;就结果而言,它演示了如何在只支持“匿名过程”这个基本元素的语言中实现强大的计算能力;当然,完成这一切靠的是lambda calculus理论。过程和结果都非常有趣~

 

scheme代码,只支持lambda这个special form和基本过程print:

bubuko.com,布布扣
 1 ((lambda (zero one add mul pow sub1 true false and or)
 2    ((lambda (sub not zero? two Y)
 3       ((lambda (less-equal? equal? three four)
 4          ;------------------------------
 5          ((lambda (for-each fib)
 6             (for-each (lambda (i) (print (fib zero one zero i))) zero (mul four four))
 7             )
 8           (Y 
 9             (lambda (self)
10               (lambda (f i n)
11                 (f i)
12                 (((equal? i n)
13                   (lambda () i)
14                   (lambda () (self f (add i one) n))))
15                 )
16               ))
17           (Y 
18             (lambda (self)
19               (lambda (a b i n)
20                 (((equal? i n)
21                   (lambda () a)
22                   (lambda () (self b (add a b) (add i one) n))))
23                 )
24               ))
25           )
26          ;------------------------------
27          )
28        (lambda (m n) (zero? (sub m n)))
29        (lambda (m n) (and (zero? (sub m n)) (zero? (sub n m))))
30        (add two one)
31        (add two two)
32        ))
33     (lambda (m n) ((n sub1) m))
34     (lambda (a) (a false true))
35     (lambda (n) ((n (lambda (x) false)) true))
36     (add one one)
37     (lambda (f)
38       ((lambda (g) (g g))
39        (lambda (g) (f (lambda (a b c d e) ((g g) a b c d e))))))
40     ))
41  (lambda (f) (lambda (x) x))
42  (lambda (f) (lambda (x) (f x)))
43  (lambda (m n) (lambda (f) (lambda (x) ((m f) ((n f) x)))))
44  (lambda (m n) (lambda (f) (m (n f))))
45  (lambda (e b) (e b))
46  (lambda (n) (lambda (f) (lambda (x) 
47                            (((n 
48                                (lambda (g) (lambda (h) (h (g f))))) 
49                              (lambda (u) x)) 
50                             (lambda (u) u)))))
51  (lambda (a b) a)
52  (lambda (a b) b)
53  (lambda (a b) (a b a))
54  (lambda (a b) (a a b))
55  )
bubuko.com,布布扣

 

lua解释器代码:

bubuko.com,布布扣
 1 function S_parse(s)
 2     s = string.gsub(s, ;[^\n]+\n, ‘‘)
 3     s = string.gsub(s, %s+, ,)
 4     s = string.gsub(s, [%(%)], {[(]={,[)]=}})
 5     s = string.gsub(s, [^{},%d][^{},]*, "%1")
 6     return assert(loadstring(string.format("return {%s}", s)))()[1]
 7 end
 8 function S_lookupVar(vm, env, name)
 9     while env do
10         if env[name] then return env[name] end
11         env = env[vm]
12     end
13 end
14 function S_interpret(vm, env, exp)
15     if type(exp) == string then return S_lookupVar(vm, env, exp) 
16     elseif exp[1] == lambda then
17         return function(...)
18             local newEnv = {[vm]=env}
19             for i = 1, #exp[2] do
20                 newEnv[exp[2][i]] = arg[i]
21             end
22             for i = 3, #exp - 1 do
23                 S_interpret(vm, newEnv, exp[i])
24             end
25             return S_interpret(vm, newEnv, exp[#exp])
26         end
27     else 
28         local p = S_interpret(vm, env, exp[1])
29         local args = {}
30         for i = 2, #exp do args[i - 1] = S_interpret(vm, env, exp[i]) end
31         return p(unpack(args))
32     end
33 end
34 function S_createVM()
35     return {
36         G = {
37             [print] = function(n) print(n(function(i) return i + 1 end)(0)) end,
38         },
39     }
40 end
41 function S_eval(vm, s)
42     return S_interpret(vm, vm.G, S_parse(s))
43 end
44 
45 S_eval(S_createVM(), io.read(*a))
bubuko.com,布布扣

 

驱动:

1 #! /bin/bash
2 cat script.rkt | lua main.lua

 

结果:

bubuko.com,布布扣
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
bubuko.com,布布扣

 

源码放这儿:https://github.com/PublicScan/LambdaCalculus/tree/c4a64b162b7049a6d278c86aaaa4a7c0750d7fa7

[Lua]50行代码的解释器,用来演示lambda calculus,布布扣,bubuko.com

[Lua]50行代码的解释器,用来演示lambda calculus

标签:style   blog   class   c   code   java   

原文地址:http://www.cnblogs.com/cbscan/p/3740435.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!