2015年11月21日土曜日

開発環境

  • OS X El Capitan - Apple (OS)
  • Emacs(Text Editor)
  • Python 3.5 (プログラミング言語)

アンダースタンディング コンピュテーション (Tom Stuart (著)、 笹田 耕一(著)、笹井 崇司 (翻訳)、オライリージャパン)の第1部(プログラムと機械)、2章(プログラムの意味)、2.4(表示的意味論)、2.4.1(式)を Python (本書ではRuby) で取り組んでみる。

2.4.1(式)

コード(Emacs)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

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)

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)

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)

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)

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)
        
if __name__ == '__main__':
    print(Number(5).to_python())
    print(Boolean(False).to_python())
    func = eval(Number(5).to_python())
    print(func)
    print(func({}))
    func = eval(Boolean(False).to_python())
    print(func)
    print(func({}))
    print()

    expression = Variable('x')
    print(expression)
    print(expression.to_python())
    func = eval(expression.to_python())
    print(func)
    print(func({'x': 7}))
    print()
    
    environment = {'x':3}
    print(environment)
    func = eval(Add(Variable('x'), Number(1)).to_python())
    print(func)
    print(func(environment))
    func = eval(LessThan(Add(Variable('x'), Number(1)), Number(3)).to_python())
    print(func)
    print(func(environment))

入出力結果(Terminal, IPython)

$ ./sample4_1.py
lambda e: 5
lambda e: False
<function <lambda> at 0x1080620d0>
5
<function <lambda> at 0x108282378>
False

x
lambda e: e['x']
<function <lambda> at 0x1080620d0>
7

{'x': 3}
<function <lambda> at 0x108282378>
4
<function <lambda> at 0x108282400>
False
$

0 コメント:

コメントを投稿