開発環境
- OS X El Capitan - Apple (OS)
- Emacs(Text Editor)
- Python 3.5 (プログラミング言語)
アンダースタンディング コンピュテーション (Tom Stuart (著)、 笹田 耕一(著)、笹井 崇司 (翻訳)、オライリージャパン)の第1部(プログラムと機械)、2章(プログラムの意味)、2.4(表示的意味論)、2.4.2(文)を Python (本書ではRuby) で取り組んでみる。
2.4.2(文)
コード(Emacs)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def merge(d1, d2):
d = d1.copy()
d.update(d2)
return d
class Number:
def __init__(self, value):
self.value = value
def __str__(self):
return str(self.value)
def __repr__(self):
return '<<{0}>>'.format(self)
def to_python(self):
return 'lambda e: {0}'.format(self.value)
class Add:
def __init__(self, left, right):
self.left = left
self.right = right
def __str__(self):
return '{0} + {1}'.format(self.left, self.right)
def __repr__(self):
return '<<{0}>>'.format(self)
def to_python(self):
return 'lambda e: ({0})(e) + ({1})(e)'.format(self.left.to_python(),
self.right.to_python())
class Multiply:
def __init__(self, left, right):
self.left = left
self.right = right
def __str__(self):
return '{0} * {1}'.format(self.left, self.right)
def __repr__(self):
return '<<{0}>>'.format(self)
def to_python(self):
return 'lambda e: ({0})(e) * ({1})(e)'.format(self.left.to_python(),
self.right.to_python())
class Boolean:
def __init__(self, value):
self.value = value
def __str__(self):
return str(self.value)
def __repr__(self):
return '<<{}>>'.format(self)
def __eq__(self, other):
return type(self) == type(other) and self.value == other.value
def to_python(self):
return 'lambda e: False'
class LessThan:
def __init__(self, left, right):
self.left = left
self.right = right
def __str__(self):
return '{0} < {1}'.format(self.left, self.right)
def __repr__(self):
return '<<{0}>>'.format(self)
def to_python(self):
return 'lambda e: ({0})(e) < ({1})(e)'.format(self.left.to_python(),
self.right.to_python())
class Variable:
def __init__(self, name):
self.name = name
def __str__(self):
return str(self.name)
def __repr__(self):
return '<<{}>>'.format(self)
def to_python(self):
return 'lambda e: e[\'{0}\']'.format(self.name)
class DoNothing:
def __str__(self):
return 'do-nothing'
def __repr__(self):
return '<<{}>>'.format(self)
def __eq__(self, other):
return type(other) == type(self)
def to_python(self):
return 'lambda e: e'
class Assign:
def __init__(self, name, expression):
self.name = name
self.expression = expression
def __str__(self):
return '{0} = {1}'.format(self.name, self.expression)
def __repr__(self):
return '<<{}>>'.format(self)
def to_python(self):
return 'lambda e: merge(e, {{\'{0}\': ({1})(e)}})'.format(
self.name, self.expression.to_python())
class If:
def __init__(self, condition, consequence, alternative):
self.condition = condition
self.consequence = consequence
self.alternative = alternative
def __str__(self):
return 'if ({0}) {{ {1} }} else {{ {2} }}'.format(
self.condition, self.consequence, self.alternative)
def __repr__(self):
return '<<{0}>>'.format(self)
def to_python(self):
return 'lambda e: ({0})(e) if ({1})(e) else ({2})(e)'.format(
self.consequence.to_python(),
self.consequence.to_python(),
self.alternative.to_python())
class Sequence:
def __init__(self, first, second):
self.first = first
self.second = second
def __str__(self):
return '{0}; {1}'.format(self.first, self.second)
def __repr__(self):
return '<<{}>>'.format(self)
def to_python(self):
return 'lambda e: ({0})(({1})(e))'.format(
self.second.to_python(), self.first.to_python())
def while1(e, condition, bocy):
while condition(e):
e = bocy(e)
return e
class While:
def __init__(self, condition, body):
self.condition = condition
self.body = body
def __str__(self):
return 'while ({0}) {{ {1} }}'.format(self.condition, self.body)
def __repr__(self):
return '<<{}>>'.format(self)
def to_python(self):
return 'lambda e: while1(e, {0}, {1})'.format(
self.condition.to_python(), self.body.to_python())
if __name__ == '__main__':
statement = Assign('y', Add(Variable('x'), Number(1)))
print(statement)
print(statement.to_python())
func = eval(statement.to_python())
print(func({'x': 3}))
print()
statement = If(Boolean(True), Number(1), Number(0))
print(statement)
print(statement.to_python())
func = eval(statement.to_python())
print(func({}))
print()
statement = Sequence(Assign('x', Add(Number(1), Number(1))),
Assign('y', Add(Variable('x'), Number(3))))
print(statement)
print(statement.to_python())
func = eval(statement.to_python())
print(func({}))
print()
statement = While(LessThan(Variable('x'), Number(5)),
Assign('x', Multiply(Variable('x'), Number(3))))
print(statement)
print(statement.to_python())
func = eval(statement.to_python())
print(func)
print(func({'x': 1}))
入出力結果(Terminal, IPython)
$ ./sample4_2.py y = x + 1 lambda e: merge(e, {'y': (lambda e: (lambda e: e['x'])(e) + (lambda e: 1)(e))(e)}) {'y': 4, 'x': 3} if (True) { 1 } else { 0 } lambda e: (lambda e: 1)(e) if (lambda e: 1)(e) else (lambda e: 0)(e) 1 x = 1 + 1; y = x + 3 lambda e: (lambda e: merge(e, {'y': (lambda e: (lambda e: e['x'])(e) + (lambda e: 3)(e))(e)}))((lambda e: merge(e, {'x': (lambda e: (lambda e: 1)(e) + (lambda e: 1)(e))(e)}))(e)) {'y': 5, 'x': 2} while (x < 5) { x = x * 3 } lambda e: while1(e, lambda e: (lambda e: e['x'])(e) < (lambda e: 5)(e), lambda e: merge(e, {'x': (lambda e: (lambda e: e['x'])(e) * (lambda e: 3)(e))(e)})) <function <lambda> at 0x108ce6488> {'x': 9} $
0 コメント:
コメントを投稿