Skip to content

Commit

Permalink
Dont rely on node type to determine if its an operator. Use the OPERA…
Browse files Browse the repository at this point in the history
…TOR table instead.
  • Loading branch information
vic committed Aug 24, 2011
1 parent 67ce83b commit de411e6
Showing 1 changed file with 19 additions and 14 deletions.
33 changes: 19 additions & 14 deletions lib/akin/shuffle.rb
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -113,7 +122,7 @@ def <=>(other)
prec <=> other.prec
end
end
end
end
end

OPERATORS = {
Expand All @@ -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.