原来lambda循环如此简单..

1
In [47]: b = lambda x: x < 5 and  x * 3                                                                                                                       
2
In [48]: b(3)                                                                   Out[48]: 9

最近在做解释器相关的东西, 原书是用ruby的lambda 表达式实现的while循环

但是在Python中,没有直接用while关键字实现的while循环

故而只能用上面的形式实现

由于Python的特性(变量x 必须在while循环外赋值),所以这里不要再进行二次赋值

关于Assign方法的思考

Python和ruby不同, Python原生的dict.update 方法没有返回值,所以这个地方声明的时候会有问题

下面是指称语义Python代码

1
class Number:
2
3
    def __init__(self, value):
4
        self.value = value
5
6
    def __str__(self):
7
        return str(self.value)
8
9
    def to_py(self):
10
        return "lambda e: %s" % self.value
11
12
13
class Boolean:
14
15
    def __init__(self, value):
16
        self.value = value
17
18
    def __str__(self):
19
        return str(self.value)
20
21
    def to_py(self):
22
        return "lambda e: %s" % self.value
23
24
25
class Variable:
26
27
    def __init__(self, name):
28
        self.name = name
29
30
    def __str__(self):
31
        return self.name
32
33
    def to_py(self):
34
        return "lambda e: e['%s']" % self.name
35
36
37
class Add:
38
39
    def __init__(self, left, right):
40
        self.left = left
41
        self.right = right
42
43
    def __str__(self):
44
        return "{} + {}".format(str(self.left), str(self.right))
45
46
    def to_py(self):
47
        return "lambda e: ({})(e) + ({})(e)".format(self.left.to_py(),
48
                                                    self.right.to_py())
49
50
51
class Multiply:
52
53
    def __init__(self, left, right):
54
        self.left = left
55
        self.right = right
56
57
    def __str__(self):
58
        return "{} * {}".format(str(self.left), str(self.right))
59
60
    def to_py(self):
61
        return "lambda e: ({})(e) * ({})(e)".format(self.left.to_py(),
62
                                                    self.right.to_py())
63
64
65
class LessThan:
66
67
    def __init__(self, left, right):
68
        self.left = left
69
        self.right = right
70
71
    def __str__(self):
72
        return "{} < {}".format(self.left, self.right)
73
74
    def to_py(self):
75
        return "lambda e: ({})(e) < ({})(e)".format(self.left.to_py(),
76
                                                    self.right.to_py())
77
78
79
class DoNothing:
80
81
    def __str__(self):
82
        return "do-nothing"
83
84
    def eq(self, other_statement):
85
        return isinstance(other_statement, DoNothing)
86
87
    def to_py(self):
88
        return "lambda e: e"
89
90
91
class Assign:
92
93
    def __init__(self, name, expression):
94
        self.name = name
95
        self.expression = expression
96
97
    def __str__(self):
98
        return "{} = {}".format(self.name, self.expression)
99
100
    def to_py(self):
101
        return "lambda e: e.update({}=({})(e))".format(self.name,
102
                                                       self.expression.to_py())
103
104
105
class If(object):
106
107
    def __init__(self, condition, consequence, alternative):
108
        self.condition = condition
109
        self.consequence = consequence
110
        self.alternative = alternative
111
112
    def __str__(self):
113
        return "if ({}) ({}) else ({})".format(
114
            self.condition, self.consequence, self.alternative)
115
116
    def to_py(self):
117
        return "lambda e: ({})(e) if ({})(e) else ({})(e)".format(
118
            self.consequence.to_py(), 
119
            self.condition.to_py(),
120
            self.alternative.to_py())
121
122
123
class Sequence(object):
124
125
    def __init__(self, first, second):
126
        self.first = first
127
        self.second = second
128
129
    def __str__(self):
130
        return "{}; {}".format(self.first, self.second)
131
132
    
133
    def to_py(self):
134
        return "lambda e: ({})(({})(e))".format(
135
            self.second.to_py(),
136
            self.first.to_py())
137
    
138
139
class While(object):
140
141
    def __init__(self, condition, body):
142
        self.condition = condition
143
        self.body = body
144
145
    def __str__(self):
146
        return "while %s: %s" % (self.condition, self.body)
147
148
    def to_py(self):
149
        return "lambda e: ({})(e) and ({})(e)".format(self.condition.to_py(),
150
                                                      self.body.to_py())
151
152
if __name__ == "__main__":
153
    print(Number(5).to_py())
154
    expression = eval(Number(5).to_py())
155
    print(expression)
156
    print(expression({}))
157
    print(Boolean(True).to_py())
158
159
    print("-" * 100)
160
    expression = Variable("x")
161
    print("expression", expression)
162
    print('expression.to_py', eval(expression.to_py()))
163
    proc = eval(expression.to_py())
164
    print(proc({"x": 1}))
165
166
    print("-" * 100)
167
    print(Add(Number(3), Number(4)).to_py())
168
    statement = eval(Add(Number(3), Number(4)).to_py())
169
    print(statement({}))
170
171
    print("-" * 100)
172
    print(LessThan(Add(Variable("x"), Number(1)), Number(2)).to_py())
173
    statement = eval(LessThan(Add(Variable("x"), Number(1)),
174
                              Number(2)).to_py())
175
    print(statement({"x": 2}))
176
177
    print("-" * 100)
178
    statement = Assign("y", Add(Variable("x"), Number(3)))
179
    print("statement: ", statement)
180
    print("statement: ", statement.to_py())
181
    exp = eval(statement.to_py())
182
    environment = {"x": 1}
183
    print(exp(environment))
184
    print(environment)
185
    print("-" * 100)
186
    statement = While(
187
        LessThan(Variable("x"), Number(5)),
188
        Multiply(Variable("x"), Number(3))
189
    )
190
    print(statement)
191
    print(statement.to_py())
192
    proc = eval(statement.to_py())
193
    print(proc)
194
    print(proc({"x": 3}))