Skip to content
Browse files

Dont rely on node type to determine if its an operator. Use the OPERA…

…TOR table instead.
  • Loading branch information...
1 parent 67ce83b commit de411e6e8faaf10a099ffd58092b7c24b6574578 @vic committed Aug 24, 2011
Showing with 19 additions and 14 deletions.
  1. +19 −14 lib/akin/shuffle.rb
View
33 lib/akin/shuffle.rb
@@ -33,22 +33,31 @@ def shuffle_chain(node)
def opers(ary)
ops = []
ary.each_with_index do |node, idx|
- if node.name == :oper
- ops.push Oper.new(idx, node, info(node.args.first))
- end
+ o = Oper.new(idx, node)
+ ops.push o if o.oper?
end
ops.sort
end
-
class Oper
include Comparable
- attr_reader :idx, :node, :info
- def initialize(idx, node, info)
- @idx, @node, @info = idx, node, info
+ attr_reader :idx, :node
+ def initialize(idx, node)
+ @idx, @node = idx, node
+ end
+
+ def info
+ @info ||= OPERATORS[node.args.first] || Info.new
+ end
+
+ def oper?(node = self.node)
+ node.args.size == 1 &&
+ node.name == :oper ||
+ (node.name == :name && OPERATORS[node.args.first])
end
+
def lhs?
info.assoc <= 0
end
@@ -75,7 +84,7 @@ def shuffle(ary)
lhs, rhs = nil, nil
pre, post = ary[0...ary.index(node)], ary[ary.index(node)+1..-1]
if lhs? && pre
- lhs = pre.reverse.take_while { |i| i.name != :oper }.reverse
+ lhs = pre.reverse.take_while { |i| !oper?(i) }.reverse
unless lhs.empty?
pre = ary[0...ary.index(lhs.first)]
if lhs.size == 1
@@ -86,7 +95,7 @@ def shuffle(ary)
end
end
if rhs? && post
- rhs = post.take_while { |i| i.name != :oper }
+ rhs = post.take_while { |i| !oper?(i) }
unless rhs.empty?
post = ary[ary.index(rhs.last)+1..-1]
if rhs.size == 1
@@ -113,7 +122,7 @@ def <=>(other)
prec <=> other.prec
end
end
- end
+ end
end
OPERATORS = {
@@ -123,9 +132,5 @@ def <=>(other)
"=" => Oper::Info.new(16, 0)
}
- def info(op)
- OPERATORS[op] || Oper::Info.new
- end
-
end
end

0 comments on commit de411e6

Please sign in to comment.
Something went wrong with that request. Please try again.