public
Description: various ordered hash syntax experiments for ruby 1.8
Homepage:
Clone URL: git://github.com/coderrr/ordered_hash_syntax.git
ordered_hash_syntax / parse_tree_oh.rb
100644 63 lines (52 sloc) 1.202 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
require 'rubygems'
require 'parse_tree'
require 'ruby2ruby'
 
class ParseTreeOrderedHash < Ruby2Ruby
  class K
  end
 
  class << self
    def H(&b)
      K.send :define_method, :x, &b
      sexp = ParseTree.translate(K, :x)
      sexp = Unifier.new.process(sexp)
      hash_sexp = sexp[3][1][1]
 
      raise "block doesn't contain hash!" if hash_sexp.first != :hash
 
      r2r = ParseTreeOrderedHash.new
      s = r2r.process(hash_sexp)
      # puts s
      eval s, b
    end
  end
 
  # stolen from ruby2ruby
  def process_hash(exp)
    result = []
    until exp.empty?
      lhs = process(exp.shift)
      rhs = exp.shift
      t = rhs.first
      rhs = process rhs
      rhs = "(#{rhs})" unless [:lit, :str].include? t # TODO: verify better!
 
      result << [lhs, rhs]
    end
 
    ordered_hash(result)
  end
 
  def ordered_hash(pairs)
    s = "OrderedHash.new"
    pairs.each do |key, value|
      s << ".merge!(#{key}=>#{value})"
    end
    s
  end
end
 
def H *a, &b
  ParseTreeOrderedHash.H *a, &b
end
 
if $0 == __FILE__
  OrderedHash = Hash
  require 'benchmark'
  p 100*Benchmark.realtime {
    10000.times do
      ordered_hash = H{{ :k1 => :v1, 'key2' => :val2, :k3 => 55 }}
    end
  }
end