Permalink
Browse files

Delete old namespace

  • Loading branch information...
Josep M. Bach
Josep M. Bach committed Jan 9, 2011
1 parent cd8fae2 commit c8c48273f56cb888618076517dff82372c8c7067
View
@@ -1,14 +0,0 @@
module Rpncalc
class Calculator
attr_reader :parser, :stack
def initialize options = {}
arity, delimiter = options[:arity] || 2,
options[:delimiter] || ' '
@stack = Stack.new(arity)
@parser = Parser.new(delimiter)
end
def solve string
stack.solve parser.parse(string)
end
end
end
View
@@ -1,40 +0,0 @@
module Rpncalc
class Parser
class MalformedStringError < StandardError; end;
class InvalidDelimiterError < StandardError; end;
TOKENS = %w{. + - * / ^}
attr_reader :delimiter
def initialize delimiter
@delimiter = validate(delimiter)
end
def parse string
string.gsub(/#{delimiter}+/, delimiter)
.split(delimiter).map(&:strip).map do |element|
if element.to_i.zero? && element != '0'
if TOKENS.include?(element)
element.to_sym
else
raise MalformedStringError.new("Offending token: #{element}")
end
else
element =~ /\./ ? element.to_f
: element.to_i
end
end
end
private
def validate delimiter
if TOKENS.include?(delimiter.strip) ||
delimiter =~ /[0-9]+/
raise InvalidDelimiterError.new
end
delimiter
end
end
end
View
@@ -1,43 +0,0 @@
module Rpncalc
class Stack
class InsufficientValuesAvailable < StandardError; end;
class UnsolvableExpressionError < StandardError; end;
attr_reader :arity, :elements
def initialize arity
@arity = arity
@elements = []
end
def solve tokens
tokens.each do |token|
if Numeric === token
push token
next
end
raise InsufficientValuesAvailable
.new("Cannot apply #{token} to less than #{arity} values!") if size < arity
result = pop(arity).inject do |acc, e|
acc.send(token, e)
end
push result
end
raise UnsolvableExpressionError.new("The final stack contained more than one value: #{elements.inspect}") if size > 1
elements.first
end
def push token
elements.push token
end
def pop amount
elements.pop amount
end
def size
elements.size
end
end
end
View
@@ -1,3 +0,0 @@
module Rpncalc
VERSION = "0.0.1"
end
View
@@ -1,26 +0,0 @@
# -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "rpncalc/version"
Gem::Specification.new do |s|
s.name = "rpncalc"
s.version = Rpncalc::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Josep M. Bach"]
s.email = ["josep.m.bach@gmail.com"]
s.homepage = "http://github.com/txus/rpncalc"
s.summary = %q{A simple Reverse Polish Notation calculator in Ruby}
s.description = %q{A simple Reverse Polish Notation calculator in Ruby}
s.rubyforge_project = "rpncalc"
s.add_development_dependency 'bundler', '~> 1.0.7'
s.add_development_dependency 'rspec', '~> 2.4.0'
s.add_development_dependency 'guard'
s.add_development_dependency 'guard-rspec'
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
end
@@ -1,47 +0,0 @@
require 'spec_helper'
module Rpncalc
describe Calculator do
describe "#initialize" do
context "with no arguments" do
it 'sets default arity' do
Stack.should_receive(:new).with(2)
Calculator.new
end
it 'sets default delimiter' do
Parser.should_receive(:new).with(' ')
Calculator.new
end
end
it 'accepts a custom arity' do
Stack.should_receive(:new).with(3)
Calculator.new :arity => 3
end
it 'accepts a custom delimiter' do
Parser.should_receive(:new).with(',')
Calculator.new :delimiter => ','
end
it 'creates an accessible stack' do
calculator = Calculator.new
calculator.stack.should be_kind_of(Stack)
end
it 'creates an accessible parser' do
calculator = Calculator.new
calculator.parser.should be_kind_of(Parser)
end
end
describe "#solve" do
it 'passes the string to the parser' do
subject.stack.stub(:solve)
subject.parser.should_receive(:parse).with "3 4 +"
subject.solve "3 4 +"
end
it 'delegates solving to the stack' do
subject.parser.stub(:parse).and_return ["3", "4", "+"]
subject.stack.should_receive(:solve).with ["3", "4", "+"]
subject.solve "3 4 +"
end
end
end
end
@@ -1,60 +0,0 @@
require 'spec_helper'
module Rpncalc
describe Parser do
describe "#initialize" do
it 'sets the delimiter' do
parser = Parser.new ' '
parser.delimiter.should == ' '
end
describe "makes the parser raise an InvalidDelimiterError" do
%w{. + - * / ^ 19 425 0}.each do |invalid_delimiter|
it "when using #{invalid_delimiter} as a delimiter" do
expect {
Parser.new invalid_delimiter
}.to raise_error(Parser::InvalidDelimiterError)
end
end
end
end
describe "#parse" do
context "with a space delimiter" do
subject { Parser.new ' ' }
it 'returns a tokenized array' do
subject.parse("1 4 5 + -").should == [1, 4, 5, :+, :-]
subject.parse("1 2 3 4 5 6 7 8 + - * / ^").should == [1, 2, 3, 4, 5, 6, 7, 8, :+, :-, :*, :/, :^]
end
describe "edge cases" do
it 'strips any extra spaces' do
subject.parse("1 4 5 + -").should == [1, 4, 5, :+, :-]
end
end
end
context "with a comma delimiter" do
subject { Parser.new ',' }
it 'returns a tokenized array' do
subject.parse("1,4,5.3,+,-").should == [1, 4, 5.3, :+, :-]
subject.parse("1,2,3,4,5,6,7,8,+,-,*,/,^").should == [1,2,3,4,5,6,7,8,:+,:-,:*,:/,:^]
end
describe "edge cases" do
it 'strips any extra spaces and delimiter' do
subject.parse("1,, 4 , 5.3 ,,,+, -").should == [1, 4, 5.3, :+, :-]
end
end
end
context "with inconsistent or malformed strings" do
subject { Parser.new ',' }
it 'raises a MalformedStringError' do
expect {
subject.parse "1,4.5,&+,-"
}.to raise_error(Parser::MalformedStringError, "Offending token: &+")
end
end
end
end
end
View
@@ -1,80 +0,0 @@
require 'spec_helper'
module Rpncalc
describe Stack do
subject { Stack.new 2 }
describe "#initialize" do
it 'sets the delimiter' do
stack = Stack.new 3
stack.arity.should == 3
end
end
describe "#solve", "iterates the tokens" do
context 'when the token is a value' do
it 'pushes it to the stack' do
subject.should_receive(:push).with 3
subject.solve [3]
end
end
context 'when the token is an operator' do
context 'if the size of the stack is below the arity' do
it 'raises an error' do
subject.stub(:size).and_return 1
expect {
subject.solve [:+]
}.to raise_error(Stack::InsufficientValuesAvailable)
end
end
context 'otherwise' do
it 'pops n elements from the stack and pushes the result' do
subject.stub(:size).and_return 3, 1
elements = [1,2]
subject.should_receive(:pop).with(subject.arity).and_return elements
subject.should_receive(:push).with(3)
subject.solve [:+]
end
end
end
context 'when at the end there is more than one result' do
it 'raises an error' do
subject.stub(:size).and_return 2
expect {
subject.solve [:+]
}.to raise_error(Stack::UnsolvableExpressionError)
end
end
context 'when everything is fine' do
it 'returns the result' do
subject.stub(:size).and_return 3, 1
elements = [1,2]
subject.stub(:pop).with(subject.arity).and_return elements
subject.solve([:+]).should == 3
end
end
end
describe "#push" do
it 'pushes a token to the elements collection' do
subject.elements.should_receive(:push).with 3
subject.push 3
end
end
describe "#pop" do
it 'pushes a token to the elements collection' do
subject.elements.should_receive(:pop).with 2
subject.pop 2
end
end
describe "#size" do
it 'pushes a token to the elements collection' do
subject.elements.should_receive(:size)
subject.size
end
end
end
end

0 comments on commit c8c4827

Please sign in to comment.