summaryrefslogtreecommitdiff
path: root/defs/id.def
blob: 24ca5d3f9f3a0b17b29df43ae14e1a640b54cd45 (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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# -*- mode: ruby; coding: us-ascii -*-
firstline, predefined = __LINE__+1, %[\
  max
  min
  freeze
  inspect
  intern
  object_id
  const_missing
  method_missing                                        MethodMissing
  method_added
  singleton_method_added
  method_removed
  singleton_method_removed
  method_undefined
  singleton_method_undefined
  length
  size
  gets
  succ
  each
  proc
  lambda
  send
  __send__
  __attached__
  initialize
  initialize_copy
  initialize_clone
  initialize_dup
  to_int
  to_ary
  to_str
  to_sym
  to_hash
  to_proc
  to_io
  to_a
  to_s
  to_i
  to_f
  to_r
  bt
  bt_locations
  call
  mesg
  exception
  not                                                   NOT
  and                                                   AND
  or                                                    OR

  _                                                     UScore
  "/*NULL*/"                                            NULL
  empty?
  eql?
  respond_to?                                           Respond_to
  respond_to_missing?                                   Respond_to_missing
  <IFUNC>
  <CFUNC>
  core#set_method_alias
  core#set_variable_alias
  core#undef_method
  core#define_method
  core#define_singleton_method
  core#set_postexe
  core#hash_merge_ptr
  core#hash_merge_kwd

  -                                                     debug#created_info

  $_                                                    LASTLINE
  $~                                                    BACKREF
  $!                                                    ERROR_INFO
]

# VM ID         OP      Parser Token
token_ops = %[\
  Dot2          ..      DOT2
  Dot3          ...     DOT3
  BDot2         ..      BDOT2
  BDot3         ...     BDOT3
  UPlus         +@      UPLUS
  UMinus        -@      UMINUS
  Pow           **      POW
  Cmp           <=>     CMP
  PLUS          +
  MINUS         -
  MULT          *
  DIV           /
  MOD           %
  LTLT          <<      LSHFT
  GTGT          >>      RSHFT
  LT            <
  LE            <=      LEQ
  GT            >
  GE            >=      GEQ
  Eq            ==      EQ
  Eqq           ===     EQQ
  Neq           !=      NEQ
  Not           !
  And           &
  Or            |
  Backquote     `
  EqTilde       =~      MATCH
  NeqTilde      !~      NMATCH
  AREF          []
  ASET          []=
  COLON2        ::
  ANDOP         &&
  OROP          ||
  ANDDOT        &.
  METHREF       .:
]

class KeywordError < RuntimeError
  def self.raise(mesg, line)
    super(self, mesg, ["#{__FILE__}:#{line}", *caller])
  end
end

predefined_ids = {}
preserved_ids = []
local_ids = []
instance_ids = []
global_ids = []
const_ids = []
class_ids = []
attrset_ids = []
token_op_ids = []
names = {}
predefined.split(/^/).each_with_index do |line, num|
  next if /^#/ =~ line
  line.sub!(/\s+#.*/, '')
  name, token = line.split
  next unless name
  token ||= name
  if /#/ =~ token
    token = "_#{token.gsub(/\W+/, '_')}"
  else
    token = token.sub(/\?/, 'P').sub(/\A[a-z]/) {$&.upcase}
    token.sub!(/\A\$/, "_G_")
    token.sub!(/\A@@/, "_C_")
    token.sub!(/\A@/, "_I_")
    token.gsub!(/\W+/, "")
  end
  if name == '-'
    preserved_ids << token
    next
  end
  if prev = names[name]
    KeywordError.raise("#{name} is already registered at line #{prev+firstline}", firstline+num)
  end
  if prev = predefined_ids[token]
    KeywordError.raise("#{token} is already used for #{prev} at line #{names[prev]+firstline}", firstline+num)
  end
  names[name] = num
  case name
  when /\A[A-Z]\w*\z/; const_ids
  when /\A(?!\d)\w+\z/; local_ids
  when /\A\$(?:\d+|(?!\d)\w+|\W)\z/; global_ids
  when /\A@@(?!\d)\w+\z/; class_ids
  when /\A@(?!\d)\w+\z/; instance_ids
  when /\A((?!\d)\w+)=\z/; attrset_ids
  else preserved_ids
  end << token
  predefined_ids[token] = name
end
token_ops.split(/^/).each do |line|
  next if /^#/ =~ line
  line.sub!(/\s+#.*/, '')
  id, op, token = line.split
  next unless id and op
  token ||= (id unless /\A\W\z/ =~ op)
  token_op_ids << [id, op, token]
end
{
  "LOCAL" => local_ids,
  "INSTANCE" => instance_ids,
  "GLOBAL" => global_ids,
  "CONST" => const_ids,
  "CLASS" => class_ids,
  "ATTRSET" => attrset_ids,
  :preserved => preserved_ids,
  :predefined => predefined_ids,
  :token_op => token_op_ids,
}