Permalink
Browse files

Separated operator table from suffle implementation.

  • Loading branch information...
vic committed Aug 25, 2011
1 parent 1e4f904 commit 3377700beb87a48489f96fb6cd4074a6e8c679c7
Showing with 247 additions and 224 deletions.
  1. +1 −0 lib/akin.rb
  2. +195 −0 lib/akin/operator.rb
  3. +4 −186 lib/akin/shuffle.rb
  4. +44 −0 spec/operator_spec.rb
  5. +2 −37 spec/shuffle_spec.rb
  6. +1 −1 spec/spec_helper.rb
View
@@ -2,6 +2,7 @@
parser
grammar
+ operator
shuffle
}.each { |f| require File.expand_path("../akin/#{f}", __FILE__) }
View
@@ -0,0 +1,195 @@
+# -*- coding: utf-8 -*-
+module Akin
+ class Operator < Struct.new(:name,
+ :precedence, :assoc,
+ :arity_l, :arity_r,
+ :node, :idx,
+ :inverted)
+
+ def <=>(o)
+ prec = precedence <=> o.precedence
+ if prec.zero? && idx && assoc > 0
+ o.idx <=> idx
+ else
+ prec
+ end
+ end
+
+ def at(node, idx)
+ self.class.new name, precedence, assoc, arity_l, arity_r, node, idx, inverted
+ end
+
+ def self.build(ary)
+ ops = Hash.new
+ ary.each_slice(2) do |n, p|
+ ops[n] = Operator.new n, p.to_i, *DEFAULT[1..-1]
+ end
+ ops
+ end
+
+ class Table
+ def initialize(operators = OPERATORS, prefix = PREFIX, default = DEFAULT)
+ @operators, @prefix, @default = operators, prefix, default
+ end
+
+ def operator?(node)
+ !operator(node,0).nil?
+ end
+
+ def operator(node, idx)
+ if [:oper, :name].include?(node.name) && @operators.key?(node.args.first)
+ @operators[node.args.first].at(node, idx)
+ elsif :oper == node.name && @prefix.key?(node.args.first[0,1])
+ op = @prefix[node.args.first[0,1]].at(node, idx)
+ op.name = node.args.first
+ op
+ elsif :oper == node.name
+ Operator.new(node.args.first, *@default).at(node, idx)
+ end
+ end
+ end
+
+ # OPER PRECED ASOC ARY_L ARY_R
+ DEFAULT = [10, 0, 0.0, 0.1]
+ OPERATORS = Operator.build %w'
+ ! 0
+ ? 0
+ $ 0
+ ~ 0
+ # 0
+ -- 0
+ ++ 0
+ ** 1
+ * 2
+ / 2
+ % 2
+ + 3
+ - 3
+ ∩ 3
+ ∪ 3
+ << 4
+ >> 4
+ < 5
+ > 5
+ < 5
+ <= 5
+ ≤ 5
+ >= 5
+ ≥ 5
+ <> 5
+ <>> 5
+ <<>> 5
+ ⊂ 5
+ ⊃ 5
+ ⊆ 5
+ ⊇ 5
+ == 6
+ != 6
+ ≠ 6
+ === 6
+ =~ 6
+ !~ 6
+ & 7
+ ^ 8
+ | 9
+ && 10
+ ?& 10
+ || 11
+ ?| 11
+ .. 12
+ ... 12
+ ∈ 12
+ ∉ 12
+ ::: 12
+ => 12
+ <-> 12
+ -> 12
+ ∘ 12
+ +> 12
+ !> 12
+ &> 12
+ %> 12
+ #> 12
+ @> 12
+ /> 12
+ *> 12
+ ?> 12
+ |> 12
+ ^> 12
+ ~> 12
+ ->> 12
+ +>> 12
+ !>> 12
+ &>> 12
+ %>> 12
+ #>> 12
+ @>> 12
+ />> 12
+ *>> 12
+ ?>> 12
+ |>> 12
+ ^>> 12
+ ~>> 12
+ =>> 12
+ **> 12
+ **>> 12
+ &&> 12
+ &&>> 12
+ ||> 12
+ ||>> 12
+ $> 12
+ $>> 12
+ += 13
+ -= 13
+ **= 13
+ *= 13
+ /= 13
+ %= 13
+ and 13
+ nand 13
+ &= 13
+ &&= 13
+ ^= 13
+ or 13
+ xor 13
+ nor 13
+ |= 13
+ ||= 13
+ <<= 13
+ >>= 13
+ <- 14
+ return 14
+ ret 14
+ use 14
+ '
+ PREFIX = Operator.build %w'
+ / 2
+ * 2
+ % 2
+ + 3
+ - 3
+ $ 6
+ ~ 6
+ ? 6
+ ! 6
+ = 6
+ > 6
+ < 6
+ & 7
+ ^ 8
+ | 9
+ '
+
+ %w[ * / % = ].each { |i| PREFIX[i].assoc = 1 }
+ %w[ * / % ** ].each { |i| OPERATORS[i].assoc = 1 }
+
+ %w[ ++ -- ].each { |i| o = OPERATORS[i]; o.arity_l, o.arity_r = 1, 0 }
+
+ %w[ = ].each { |i| o = PREFIX[i]; o.arity_l, o.arity_r = 0.1, 0.1 }
+ %w[ ? ].each { |i| o = OPERATORS[i]; o.arity_l, o.arity_r = 1, -1 }
+ %w[ $ ].each { |i| o = OPERATORS[i]; o.arity_l, o.arity_r = 0, -1 }
+
+ %w[ ∈ ∉ ::: ].each { |i| o = OPERATORS[i]; o.inverted = o.assoc = 1 }
+
+ end
+end
Oops, something went wrong.

0 comments on commit 3377700

Please sign in to comment.