summaryrefslogtreecommitdiff
path: root/ext/ripper/tools/generate-ripper_rb.rb
blob: 5c06ca40a4df5e8d19f9a8dfd1086fa05fcc88ad (plain)
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
# $Id$

def main
  template, ids1, ids2 = *ARGV
  print <<header
# This file is automatically generated from #{File.basename(template)} and parse.y.
# DO NOT MODIFY!!!!!!

header
  File.foreach(template) do |line|
    case line
    when /\A\#include ids1/
      print_items read_ids(ids1)
    when /\A\#include ids2/
      print_items read_ids(ids2)
    when /\A\#include handlers1/
      File.foreach(ids1) do |line|
        id, arity = line.split
        arity = arity.to_i
        puts
        puts "  def on_#{id}#{paramdecl(arity)}"
        puts "    #{arity == 0 ? 'nil' : 'a'}"
        puts "  end"
      end
    when /\A\#include handlers2/
      File.foreach(ids2) do |line|
        id, arity = line.split
        arity = arity.to_i
        puts
        puts "  def on_#{id}(token)"
        puts "    token"
        puts "  end"
      end
    when /\A\#include (.*)/
      raise "unknown operation: #include #{$1}"
    else
      print line
    end
  end
end

def print_items(ids)
  comma = ''
  ids.each do |id, arity|
    print comma; comma = ",\n"
    print "    #{id.intern.inspect} => #{arity}"
  end
  puts
end

def read_ids(path)
  File.readlines(path).map {|line| line.split }
end

def paramdecl(n)
  return '' if n == 0
  '(' + %w(a b c d e f g h i j k l m)[0, n].join(', ') + ')'
end

main