diff options
author | Joe Zhao <joe@joe-pc.(none)> | 2014-03-20 11:56:20 +0800 |
---|---|---|
committer | Joe Zhao <joe@joe-pc.(none)> | 2014-03-20 11:56:20 +0800 |
commit | b5dc5a923ff86163319424affd8cfa6bfc063841 (patch) | |
tree | 47d826be08214e69cea25b6747a6ad82e6cfcc72 /simple/simple.rb | |
download | computation-b5dc5a923ff86163319424affd8cfa6bfc063841.tar.gz computation-b5dc5a923ff86163319424affd8cfa6bfc063841.tar.bz2 computation-b5dc5a923ff86163319424affd8cfa6bfc063841.zip |
First commit
Diffstat (limited to 'simple/simple.rb')
-rw-r--r-- | simple/simple.rb | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/simple/simple.rb b/simple/simple.rb new file mode 100644 index 0000000..a31e001 --- /dev/null +++ b/simple/simple.rb @@ -0,0 +1,196 @@ +#!/usr/bin/ruby + +class Value < Struct.new(:value) + def to_s + value.to_s + end + def inspect + "<#{self}>" + end + def reducible? + false + end +end + +class Number < Value +end + +class Boolean < Value +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 BiOp < Struct.new(:left, :right) + def inspect + "<#{self}>" + end + def reducible? + true + end +end + +class Add < BiOp + def to_s + "#{left} + #{right}" + end + def reduce(environment) + if left.reducible? + Add.new(left.reduce(environment),right) + elsif right.reducible? + Add.new(left,right.reduce(environment)) + else + Number.new(left.value+right.value) + end + end +end + +class Multiply < BiOp + def to_s + "#{left} * #{right}" + end + def reduce(environment) + if left.reducible? + Add.new(left.reduce(environment),right) + elsif right.reducible? + Add.new(left,right.reduce(environment)) + else + Number.new(left.value*right.value) + end + end +end + +class LessThan < BiOp + def to_s + "#{left} < #{right}" + end + + def reduce(environment) + if left.reducible? + LessThan.new(left.reduce(environment), right) + elsif right.reducible? + LessThan.new(left, right.reduce(environment)) + else + Boolean.new(left.value < right.value) + end + 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 If < Struct.new(:condition, :consequence, :alternative) + def to_s + "if (#{condition}) { #{consequence} } else { #{alternative} }" + end + + def inspect + "<#{self}>" + end + + def reducible? + true + end + + def reduce(environment) + if condition.reducible? + [If.new(condition.reduce(environment), consequence, alternative), environment] + else + case condition + when Boolean.new(true) + [consequence, environment] + when Boolean.new(false) + [alternative, environment] + end + end + end +end + +class Sequence < Struct.new(:first, :second) + def to_s + "#{first}; #{second}" + end + + def inspect + "<#{self}>" + end + + def reducible? + true + end + + def reduce(environment) + case first + when DoNothing.new + [second,environment] + else + reduced_first, reduced_environment = first.reduce(environment) + [Sequence.new(reduced_first, second), reduced_environment] + 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 |