00001 # -*- mode: ruby; coding: us-ascii -*-
00002 firstline, predefined = __LINE__+1, %[\
00003 freeze
00004 inspect
00005 intern
00006 object_id
00007 const_missing
00008 method_missing MethodMissing
00009 method_added
00010 singleton_method_added
00011 method_removed
00012 singleton_method_removed
00013 method_undefined
00014 singleton_method_undefined
00015 length
00016 size
00017 gets
00018 succ
00019 each
00020 proc
00021 lambda
00022 send
00023 __send__
00024 __attached__
00025 initialize
00026 initialize_copy
00027 initialize_clone
00028 initialize_dup
00029 _ UScore
00030 "/*NULL*/" NULL
00031 empty?
00032 eql?
00033 respond_to? Respond_to
00034 respond_to_missing? Respond_to_missing
00035 <IFUNC>
00036 <CFUNC>
00037 core#set_method_alias
00038 core#set_variable_alias
00039 core#undef_method
00040 core#define_method
00041 core#define_singleton_method
00042 core#set_postexe
00043 core#hash_from_ary
00044 core#hash_merge_ary
00045 core#hash_merge_ptr
00046 core#hash_merge_kwd
00047 ]
00048
00049 class KeywordError < RuntimeError
00050 def self.raise(mesg, line)
00051 super(self, mesg, ["#{__FILE__}:#{line}", *caller])
00052 end
00053 end
00054
00055 predefined_ids = {}
00056 preserved_ids = []
00057 local_ids = []
00058 instance_ids = []
00059 global_ids = []
00060 const_ids = []
00061 class_ids = []
00062 names = {}
00063 predefined.split(/^/).each_with_index do |line, num|
00064 next if /^#/ =~ line
00065 line.sub!(/\s+#.*/, '')
00066 name, token = line.split
00067 next unless name
00068 token ||= name
00069 if /#/ =~ token
00070 token = "_#{token.gsub(/\W+/, '_')}"
00071 else
00072 token = token.sub(/\?/, 'P').sub(/\A[a-z]/) {$&.upcase}
00073 token.sub!(/\A\$/, "_G_")
00074 token.sub!(/\A@@/, "_C_")
00075 token.sub!(/\A@/, "_I_")
00076 token.gsub!(/\W+/, "")
00077 end
00078 if prev = names[name]
00079 KeywordError.raise("#{name} is already registered at line #{prev+firstline}", firstline+num)
00080 end
00081 if prev = predefined_ids[token]
00082 KeywordError.raise("#{token} is already used for #{prev} at line #{names[prev]+firstline}", firstline+num)
00083 end
00084 names[name] = num
00085 case name
00086 when /\A[A-Z]\w*\z/; const_ids
00087 when /\A(?!\d)\w+\z/; local_ids
00088 when /\A\$(?:\d+|(?!\d)\w+)\z/; global_ids
00089 when /\A@@(?!\d)\w+\z/; class_ids
00090 when /\A@(?!\d)\w+\z/; instance_ids
00091 when /\A((?!\d)\w+)=\z/
00092 KeywordError.raise("use ID2ATTRSET(#{$1}) instead of ATTRSET #{name}", firstline+num)
00093 else preserved_ids
00094 end << token
00095 predefined_ids[token] = name
00096 end
00097 {
00098 "LOCAL" => local_ids,
00099 "INSTANCE" => instance_ids,
00100 "GLOBAL" => global_ids,
00101 "CONST" => const_ids,
00102 "CLASS" => class_ids,
00103 :preserved => preserved_ids,
00104 :predefined => predefined_ids,
00105 }
00106