Skip to content

Commit

Permalink
raise a namespaced error for parse failures
Browse files Browse the repository at this point in the history
Closes #68
  • Loading branch information
rubysolo committed Feb 16, 2016
1 parent 2f0744d commit 0ce7c4a
Show file tree
Hide file tree
Showing 11 changed files with 37 additions and 16 deletions.
6 changes: 4 additions & 2 deletions lib/dentaku/ast/arithmetic.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ module AST
class Arithmetic < Operation
def initialize(*)
super
fail "#{ self.class } requires numeric operands" unless valid_node?(left) && valid_node?(right)
unless valid_node?(left) && valid_node?(right)
fail ParseError, "#{ self.class } requires numeric operands"
end
end

def type
Expand All @@ -29,7 +31,7 @@ def cast(value, prefer_integer=true)
end

def valid_node?(node)
node.dependencies.any? || node.type == :numeric
node && (node.dependencies.any? || node.type == :numeric)
end
end

Expand Down
4 changes: 3 additions & 1 deletion lib/dentaku/ast/combinators.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ module AST
class Combinator < Operation
def initialize(*)
super
fail "#{ self.class } requires logical operands" unless valid_node?(left) && valid_node?(right)
unless valid_node?(left) && valid_node?(right)
fail ParseError, "#{ self.class } requires logical operands"
end
end

def type
Expand Down
4 changes: 3 additions & 1 deletion lib/dentaku/ast/function.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ def dependencies(context={})
end

def self.get(name)
registry.fetch(function_name(name)) { fail "Undefined function #{ name } "}
registry.fetch(function_name(name)) {
fail ParseError, "Undefined function #{ name }"
}
end

def self.register(name, type, implementation)
Expand Down
4 changes: 2 additions & 2 deletions lib/dentaku/ast/negation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module AST
class Negation < Operation
def initialize(node)
@node = node
fail "Negation requires numeric operand" unless valid_node?(node)
fail ParseError, "Negation requires numeric operand" unless valid_node?(node)
end

def value(context={})
Expand Down Expand Up @@ -33,7 +33,7 @@ def dependencies(context={})
private

def valid_node?(node)
node.dependencies.any? || node.type == :numeric
node && (node.dependencies.any? || node.type == :numeric)
end
end
end
Expand Down
3 changes: 3 additions & 0 deletions lib/dentaku/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ def initialize(unbound_variables)
super("no value provided for variables: #{ unbound_variables.join(', ') }")
end
end

class ParseError < StandardError
end
end
12 changes: 6 additions & 6 deletions lib/dentaku/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def parse
end

unless operations.count == 1 && operations.last == AST::Case
fail "Unprocessed token #{ token.value }"
fail ParseError, "Unprocessed token #{ token.value }"
end
consume(arities.pop.succ)
when :when
Expand Down Expand Up @@ -139,7 +139,7 @@ def parse

operations.push(AST::CaseElse)
else
fail "Unknown case token #{ token.value }"
fail ParseError, "Unknown case token #{ token.value }"
end

when :grouping
Expand All @@ -158,7 +158,7 @@ def parse
end

lparen = operations.pop
fail "Unbalanced parenthesis" unless lparen == AST::Grouping
fail ParseError, "Unbalanced parenthesis" unless lparen == AST::Grouping

if operations.last && operations.last < AST::Function
consume(arities.pop.succ)
Expand All @@ -171,11 +171,11 @@ def parse
end

else
fail "Unknown grouping token #{ token.value }"
fail ParseError, "Unknown grouping token #{ token.value }"
end

else
fail "Not implemented for tokens of category #{ token.category }"
fail ParseError, "Not implemented for tokens of category #{ token.category }"
end
end

Expand All @@ -184,7 +184,7 @@ def parse
end

unless output.count == 1
fail "Parse error"
fail ParseError, "Invalid statement"
end

output.first
Expand Down
2 changes: 1 addition & 1 deletion spec/ast/addition_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
it 'requires numeric operands' do
expect {
described_class.new(five, t)
}.to raise_error(RuntimeError, /requires numeric operands/)
}.to raise_error(Dentaku::ParseError, /requires numeric operands/)

expression = Dentaku::AST::Multiplication.new(five, five)
group = Dentaku::AST::Grouping.new(expression)
Expand Down
2 changes: 1 addition & 1 deletion spec/ast/and_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
it 'requires logical operands' do
expect {
described_class.new(t, five)
}.to raise_error(RuntimeError, /requires logical operands/)
}.to raise_error(Dentaku::ParseError, /requires logical operands/)

expression = Dentaku::AST::LessThanOrEqual.new(five, five)
expect {
Expand Down
2 changes: 1 addition & 1 deletion spec/ast/division_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
it 'requires numeric operands' do
expect {
described_class.new(five, t)
}.to raise_error(RuntimeError, /requires numeric operands/)
}.to raise_error(Dentaku::ParseError, /requires numeric operands/)

expression = Dentaku::AST::Multiplication.new(five, five)
group = Dentaku::AST::Grouping.new(expression)
Expand Down
4 changes: 3 additions & 1 deletion spec/ast/function_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
end

it 'raises an exception when trying to access an undefined function' do
expect { described_class.get("flarble") }.to raise_error(RuntimeError, /undefined function/i)
expect {
described_class.get("flarble")
}.to raise_error(Dentaku::ParseError, /undefined function/i)
end

it 'registers a custom function' do
Expand Down
10 changes: 10 additions & 0 deletions spec/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,14 @@
case_close]).parse
expect(node.value(x: 3)).to eq(4)
end

it 'raises an error on parse failure' do
five = Dentaku::Token.new(:numeric, 5)
times = Dentaku::Token.new(:operator, :multiply)
minus = Dentaku::Token.new(:operator, :subtract)

expect {
described_class.new([five, times, minus]).parse
}.to raise_error(Dentaku::ParseError)
end
end

0 comments on commit 0ce7c4a

Please sign in to comment.