2015年11月19日木曜日

開発環境

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

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

2.3.2(ビッグステップ意味論)、2.3.2.1(式)、2.3.2.2(文)

コード(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 evaluate(self, environment):
        return self

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 evaluate(self, environment):
        return Number(self.left.evaluate(environment).value +
                      self.right.evaluate(environment).value)
    
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 evaluate(self, environment):
        return Number(self.left.evaluate(environment).value *
                      self.right.evaluate(environment).value)

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 evaluate(self, environment):
        return self
    
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 evaluate(self, environment):
        return Boolean(self.left.evaluate(environment).value <
                       self.right.evaluate(environment).value)
        
class Variable:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return str(self.name)

    def __repr__(self):
        return '<<{}>>'.format(self)

    def evaluate(self, environment):
        return environment[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 evaluate(self):
        return self.environment

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 evaluate(self, environment):
        environment.update({self.name: self.expression.evaluate(environment)})
        return environment    

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 evaluate(self, environment):
        b = self.condition.evaluate(environment)
        if b == Boolean(True):
            return self.consequence.evaluate(environment)
        if b == Boolean(False):
            return self.alternative.evaluate(environment)

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 evaluate(self, environment):
        return self.second.evaluate(self.first.evaluate(environment))

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 evaluate(self, environment):
        b = self.condition.evaluate(environment)
        if b == Boolean(True):
            return self.evaluate(self.body.evaluate(environment))
        if b == Boolean(False):
            return environment
        
if __name__ == '__main__':
    print(Number(23).evaluate({}))
    print(Variable('x').evaluate({'x': Number(23)}))
    print(LessThan(Add(Variable('x'), Number(2)), Variable('y')).evaluate(
        {'x':Number(2), 'y':Number(5)}))
    print()
    
    statement = Sequence(Assign('x', Add(Number(1), Number(1))),
                         Assign('y', Add(Variable('x'), Number(3))))
    print(statement)
    print(statement.evaluate({}))
    print()
    
    statement = While(LessThan(Variable('x'), Number(5)),
                      Assign('x', Multiply(Variable('x'), Number(3))))
    print(statement)
    print(statement.evaluate({'x': Number(1)}))

入出力結果(Terminal, IPython)

$ ./sample3_2.py 
23
23
True

x = 1 + 1; y = x + 3
{'x': <<2>>, 'y': <<5>>}

while (x < 5) { x = x * 3 }
{'x': <<9>>}
$

0 コメント:

コメントを投稿