Skip to content

Instantly share code, notes, and snippets.

@track8
Created March 4, 2015 19:41
Show Gist options
  • Save track8/a00436cf83f0272c0896 to your computer and use it in GitHub Desktop.
Save track8/a00436cf83f0272c0896 to your computer and use it in GitHub Desktop.
toRuby 99まで
class Number < Struct.new(:value)
def to_s
value.to_s
end
def inspect
"<<#{self}>>"
end
def reducible?
false
end
end
class Add < Struct.new(:left, :right)
def to_s
"#{left} + #{right}"
end
def inspect
"<<#{self}>>"
end
def reducible?
true
end
def reduce(environment)
return Add.new(left.reduce(environment), right) if left.reducible?
return Add.new(left, right.reduce(environment)) if right.reducible?
Number.new(left.value + right.value)
end
end
class Multiply < Struct.new(:left, :right)
def to_s
"#{left} * #{right}"
end
def inspect
"<<#{self}>>"
end
def reducible?
true
end
def reduce(environment)
return Multiply.new(left.reduce(environment), right) if left.reducible?
return Multiply.new(left, right.reduce(environment)) if right.reducible?
Number.new(left.value * right.value)
end
end
class Boolean < Struct.new(:value)
def to_s
value.to_s
end
def inspect
"<<#{self}>>"
end
def reducible?
false
end
end
class LessThan < Struct.new(:left, :right)
def to_s
"#{left} < #{right}"
end
def inspect
"<<#{self}>>"
end
def reducible?
true
end
def reduce(environment)
return LessThan.new(left.reduce(environment), right) if left.reducible?
return LessThan.new(left, right.reduce(environment)) if right.reducible?
Boolean.new(left.value < right.value)
end
end
class Variable < Struct.new(:name)
def to_s
name.to_s
end
def inspect
"<<{self}>>"
end
def reduce(environment)
environment[name]
end
def reducible?
true
end
end
class DoNothing
def to_s
'do-nothing'
end
def inspect
"<<#{self}>>"
end
def == (other_statement)
other_statement.instance_of?(DoNothing)
end
def reducible?
false
end
end
class Assign < Struct.new(:name, :expression)
def to_s
"#{name} = #{expression}"
end
def inspect
"<<#{self}>>"
end
def reducible?
true
end
def reduce(environment)
if expression.reducible?
[Assign.new(name, expression.reduce(environment)), environment]
else
[DoNothing.new, environment.merge({ name => expression })]
end
end
end
class Machine < Struct.new(:statement, :environment)
def step
self.statement, self.environment = statement.reduce(environment)
end
def run
while statement.reducible?
puts "#{statement}, #{environment}"
step
end
puts "#{statement}, #{environment}"
end
end
if __FILE__ == $0
Machine.new(Assign.new(:x, Add.new(Variable.new(:x), Number.new(1))),
{ x: Number.new(2) }).run
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment