1# -*- mode: ruby; coding: us-ascii -*-
2firstline, predefined = __LINE__+1, %[\
3  intern
4  method_missing                                        MethodMissing
5  length
6  size
7  gets
8  succ
9  each
10  proc
11  lambda
12  send
13  __send__
14  initialize
15  initialize_copy
16  initialize_clone
17  initialize_dup
18  _                                                     UScore
19  "/*NULL*/"                                            NULL
20  empty?
21  respond_to?                                           Respond_to
22  respond_to_missing?                                   Respond_to_missing
23  <IFUNC>
24  <CFUNC>
25  core#set_method_alias
26  core#set_variable_alias
27  core#undef_method
28  core#define_method
29  core#define_singleton_method
30  core#set_postexe
31  core#hash_from_ary
32  core#hash_merge_ary
33  core#hash_merge_ptr
34  core#hash_merge_kwd
35]
36
37class KeywordError < RuntimeError
38  def self.raise(mesg, line)
39    super(self, mesg, ["#{__FILE__}:#{line}", *caller])
40  end
41end
42
43predefined_ids = {}
44preserved_ids = []
45local_ids = []
46instance_ids = []
47global_ids = []
48const_ids = []
49class_ids = []
50names = {}
51predefined.split(/^/).each_with_index do |line, num|
52  next if /^#/ =~ line
53  line.sub!(/\s+#.*/, '')
54  name, token = line.split
55  next unless name
56  token ||= name
57  if /#/ =~ token
58    token = "_#{token.gsub(/\W+/, '_')}"
59  else
60    token = token.sub(/\?/, 'P').sub(/\A[a-z]/) {$&.upcase}
61    token.sub!(/\A\$/, "_G_")
62    token.sub!(/\A@@/, "_C_")
63    token.sub!(/\A@/, "_I_")
64    token.gsub!(/\W+/, "")
65  end
66  if prev = names[name]
67    KeywordError.raise("#{name} is already registered at line #{prev+firstline}", firstline+num)
68  end
69  if prev = predefined_ids[token]
70    KeywordError.raise("#{token} is already used for #{prev} at line #{names[prev]+firstline}", firstline+num)
71  end
72  names[name] = num
73  case name
74  when /\A[A-Z]\w*\z/; const_ids
75  when /\A(?!\d)\w+\z/; local_ids
76  when /\A\$(?:\d+|(?!\d)\w+)\z/; global_ids
77  when /\A@@(?!\d)\w+\z/; class_ids
78  when /\A@(?!\d)\w+\z/; instance_ids
79  when /\A((?!\d)\w+)=\z/
80    KeywordError.raise("use ID2ATTRSET(#{$1}) instead of ATTRSET #{name}", firstline+num)
81  else preserved_ids
82  end << token
83  predefined_ids[token] = name
84end
85{
86  "LOCAL" => local_ids,
87  "INSTANCE" => instance_ids,
88  "GLOBAL" => global_ids,
89  "CONST" => const_ids,
90  "CLASS" => class_ids,
91  :preserved => preserved_ids,
92  :predefined => predefined_ids,
93}
94