-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLExp.ruby
106 lines (76 loc) · 1.73 KB
/
LExp.ruby
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# ruby LExp.ruby | node -i
class LExp
end
class LExpVariable < LExp
# LExp -> Variable
attr_reader :variable
def initialize variable
@variable = variable
end
end
class LExpApplication < LExp
# LExp -> LExp LExp
attr_reader :left, :right
def initialize left, right
@left = left
@right = right
end
def to_s
"(#{@left} #{@right})"
end
def to_js
"(#{@left.to_js})(#{@right.to_js})"
end
end
class LExpBinding < LExp
# LExp -> λVariable.LExp
attr_reader :binding_variable, :body
def initialize binding_variable, body
@binding_variable = binding_variable
@body = body
end
def to_s
# (λx.(x x))
"(λ#{@binding_variable}.#{@body})"
end
def to_js
"function(#{@binding_variable.to_js}) { return #{@body.to_js} }"
end
end
class Variable
attr_reader :name
def initialize name
@name = name
end
def to_s
@name
end
def to_js
self.to_s
end
def collect_variables
end
end
# (\x.(x x))
x = Variable.new("x")
# puts "Variable: #{x}"
left_body = LExpApplication.new(x, x)
left_binding = LExpBinding.new(x, left_body)
# (\y.(y y))
y = Variable.new("y")
right_body = LExpApplication.new(y, y)
right_binding = LExpBinding.new(y, right_body)
# puts "Binding: #{right_binding}"
omega = LExpApplication.new(left_binding, right_binding)
# puts "Application: #{omega}"
#============================================
# (\x.(x x))(\x. (x x))
x = Variable.new("x")
left_body = LExpApplication.new(x, x)
left_binding = LExpBinding.new(x, left_body)
omega2 = LExpApplication.new(left_binding, left_binding)
puts "var #{x} = function(#{x}) {return #{x}};"
puts "#{LExpApplication.new(x, x).to_js}.toString()"
# lambda calculus interpreter:
#input: x x
#output: x x