Skip to content

Instantly share code, notes, and snippets.

@justinko
Created May 26, 2011 22:22
Show Gist options
  • Save justinko/994238 to your computer and use it in GitHub Desktop.
Save justinko/994238 to your computer and use it in GitHub Desktop.
Reverse Polish Calculator
module RPN
def self.start
loop { stack.add(Line.new) }
end
def self.stack
@stack ||= Stack.new
end
class Stack
Error = Class.new(StandardError)
OperandOneIndex = -3
OperandTwoIndex = -2
def initialize
@lines, @aggregate = [], nil
end
def add(line)
if line.valid?
@lines << line
output
end
end
def output
validate
if can_calculate?
calculate
puts @aggregate
end
rescue Error => exception
puts exception.message
end
def calculate
@aggregate = 0 unless @aggregate
if operand_one_in_stack
@aggregate += calculated_result
else
@aggregate = calculated_result
end
clear_invoked
end
def can_calculate?
not current_line.operand?
end
def calculated_result
current_line.invoke(operand_one, operand_two)
end
def validate
if not operand_one or
not operand_two and
not current_line.operand? and
not full?
clear_current_line
raise Error.new('Sorry, need another operand.')
end
end
def full?
@lines.size > 2
end
def current_line
@lines.last
end
def operand_one
operand_one_in_stack || @aggregate
end
def operand_one_in_stack
@lines.at(OperandOneIndex)
end
def operand_two_in_stack
@lines.at(OperandTwoIndex)
end
alias :operand_two :operand_two_in_stack
def clear_invoked
@lines.delete_at(OperandOneIndex)
@lines.delete_at(OperandTwoIndex)
clear_current_line
end
def clear_current_line
@lines.pop
end
end
class Line
attr_reader :character
def initialize
@character = gets.chomp
__exit if exited?
validate
end
def __exit
puts 'goodbye'
exit
end
def exited?
character == 'q'
end
def validate
if character[/\s/]
puts 'One character at a time, please.'
else
@valid = true
end
end
def valid?
!!@valid
end
def operand?
!!character[/\d/]
end
def invoke(line1, line2)
line1.to_f.send(character, line2.to_f)
end
def to_f
character.to_f
end
end
end
RPN.start
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment