irb 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +5 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +55 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +6 -0
  9. data/bin/setup +6 -0
  10. data/exe/irb +11 -0
  11. data/irb.gemspec +26 -0
  12. data/lib/irb.rb +798 -0
  13. data/lib/irb/cmd/chws.rb +34 -0
  14. data/lib/irb/cmd/fork.rb +39 -0
  15. data/lib/irb/cmd/help.rb +42 -0
  16. data/lib/irb/cmd/load.rb +67 -0
  17. data/lib/irb/cmd/nop.rb +39 -0
  18. data/lib/irb/cmd/pushws.rb +41 -0
  19. data/lib/irb/cmd/subirb.rb +43 -0
  20. data/lib/irb/completion.rb +244 -0
  21. data/lib/irb/context.rb +425 -0
  22. data/lib/irb/ext/change-ws.rb +46 -0
  23. data/lib/irb/ext/history.rb +119 -0
  24. data/lib/irb/ext/loader.rb +129 -0
  25. data/lib/irb/ext/multi-irb.rb +265 -0
  26. data/lib/irb/ext/save-history.rb +105 -0
  27. data/lib/irb/ext/tracer.rb +72 -0
  28. data/lib/irb/ext/use-loader.rb +74 -0
  29. data/lib/irb/ext/workspaces.rb +67 -0
  30. data/lib/irb/extend-command.rb +306 -0
  31. data/lib/irb/frame.rb +81 -0
  32. data/lib/irb/help.rb +37 -0
  33. data/lib/irb/init.rb +302 -0
  34. data/lib/irb/input-method.rb +192 -0
  35. data/lib/irb/inspector.rb +132 -0
  36. data/lib/irb/lc/.document +4 -0
  37. data/lib/irb/lc/error.rb +32 -0
  38. data/lib/irb/lc/help-message +49 -0
  39. data/lib/irb/lc/ja/encoding_aliases.rb +11 -0
  40. data/lib/irb/lc/ja/error.rb +31 -0
  41. data/lib/irb/lc/ja/help-message +52 -0
  42. data/lib/irb/locale.rb +182 -0
  43. data/lib/irb/magic-file.rb +38 -0
  44. data/lib/irb/notifier.rb +232 -0
  45. data/lib/irb/output-method.rb +92 -0
  46. data/lib/irb/ruby-lex.rb +1180 -0
  47. data/lib/irb/ruby-token.rb +267 -0
  48. data/lib/irb/slex.rb +282 -0
  49. data/lib/irb/src_encoding.rb +7 -0
  50. data/lib/irb/version.rb +17 -0
  51. data/lib/irb/workspace.rb +143 -0
  52. data/lib/irb/ws-for-case-2.rb +15 -0
  53. data/lib/irb/xmp.rb +170 -0
  54. metadata +125 -0
@@ -0,0 +1,267 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # irb/ruby-token.rb - ruby tokens
4
+ # $Release Version: 0.9.6$
5
+ # $Revision$
6
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
7
+ #
8
+ # --
9
+ #
10
+ #
11
+ #
12
+ # :stopdoc:
13
+ module RubyToken
14
+ EXPR_BEG = :EXPR_BEG
15
+ EXPR_MID = :EXPR_MID
16
+ EXPR_END = :EXPR_END
17
+ EXPR_ARG = :EXPR_ARG
18
+ EXPR_FNAME = :EXPR_FNAME
19
+ EXPR_DOT = :EXPR_DOT
20
+ EXPR_CLASS = :EXPR_CLASS
21
+
22
+ class Token
23
+ def initialize(seek, line_no, char_no)
24
+ @seek = seek
25
+ @line_no = line_no
26
+ @char_no = char_no
27
+ end
28
+ attr_reader :seek, :line_no, :char_no
29
+ end
30
+
31
+ class TkNode < Token
32
+ def initialize(seek, line_no, char_no)
33
+ super
34
+ end
35
+ attr_reader :node
36
+ end
37
+
38
+ class TkId < Token
39
+ def initialize(seek, line_no, char_no, name)
40
+ super(seek, line_no, char_no)
41
+ @name = name
42
+ end
43
+ attr_reader :name
44
+ end
45
+
46
+ class TkVal < Token
47
+ def initialize(seek, line_no, char_no, value = nil)
48
+ super(seek, line_no, char_no)
49
+ @value = value
50
+ end
51
+ attr_reader :value
52
+ end
53
+
54
+ class TkOp < Token
55
+ attr_accessor :name
56
+ end
57
+
58
+ class TkOPASGN < TkOp
59
+ def initialize(seek, line_no, char_no, op)
60
+ super(seek, line_no, char_no)
61
+ op = TkReading2Token[op][0] unless op.kind_of?(Symbol)
62
+ @op = op
63
+ end
64
+ attr_reader :op
65
+ end
66
+
67
+ class TkUnknownChar < Token
68
+ def initialize(seek, line_no, char_no, id)
69
+ super(seek, line_no, char_no)
70
+ @name = name
71
+ end
72
+ attr_reader :name
73
+ end
74
+
75
+ class TkError < Token
76
+ end
77
+
78
+ def Token(token, value = nil)
79
+ case token
80
+ when String
81
+ if (tk = TkReading2Token[token]).nil?
82
+ IRB.fail TkReading2TokenNoKey, token
83
+ end
84
+ tk = Token(tk[0], value)
85
+ if tk.kind_of?(TkOp)
86
+ tk.name = token
87
+ end
88
+ return tk
89
+ when Symbol
90
+ if (tk = TkSymbol2Token[token]).nil?
91
+ IRB.fail TkSymbol2TokenNoKey, token
92
+ end
93
+ return Token(tk[0], value)
94
+ else
95
+ if (token.ancestors & [TkId, TkVal, TkOPASGN, TkUnknownChar]).empty?
96
+ token.new(@prev_seek, @prev_line_no, @prev_char_no)
97
+ else
98
+ token.new(@prev_seek, @prev_line_no, @prev_char_no, value)
99
+ end
100
+ end
101
+ end
102
+
103
+ TokenDefinitions = [
104
+ [:TkCLASS, TkId, "class", EXPR_CLASS],
105
+ [:TkMODULE, TkId, "module", EXPR_BEG],
106
+ [:TkDEF, TkId, "def", EXPR_FNAME],
107
+ [:TkUNDEF, TkId, "undef", EXPR_FNAME],
108
+ [:TkBEGIN, TkId, "begin", EXPR_BEG],
109
+ [:TkRESCUE, TkId, "rescue", EXPR_MID],
110
+ [:TkENSURE, TkId, "ensure", EXPR_BEG],
111
+ [:TkEND, TkId, "end", EXPR_END],
112
+ [:TkIF, TkId, "if", EXPR_BEG, :TkIF_MOD],
113
+ [:TkUNLESS, TkId, "unless", EXPR_BEG, :TkUNLESS_MOD],
114
+ [:TkTHEN, TkId, "then", EXPR_BEG],
115
+ [:TkELSIF, TkId, "elsif", EXPR_BEG],
116
+ [:TkELSE, TkId, "else", EXPR_BEG],
117
+ [:TkCASE, TkId, "case", EXPR_BEG],
118
+ [:TkWHEN, TkId, "when", EXPR_BEG],
119
+ [:TkWHILE, TkId, "while", EXPR_BEG, :TkWHILE_MOD],
120
+ [:TkUNTIL, TkId, "until", EXPR_BEG, :TkUNTIL_MOD],
121
+ [:TkFOR, TkId, "for", EXPR_BEG],
122
+ [:TkBREAK, TkId, "break", EXPR_END],
123
+ [:TkNEXT, TkId, "next", EXPR_END],
124
+ [:TkREDO, TkId, "redo", EXPR_END],
125
+ [:TkRETRY, TkId, "retry", EXPR_END],
126
+ [:TkIN, TkId, "in", EXPR_BEG],
127
+ [:TkDO, TkId, "do", EXPR_BEG],
128
+ [:TkRETURN, TkId, "return", EXPR_MID],
129
+ [:TkYIELD, TkId, "yield", EXPR_END],
130
+ [:TkSUPER, TkId, "super", EXPR_END],
131
+ [:TkSELF, TkId, "self", EXPR_END],
132
+ [:TkNIL, TkId, "nil", EXPR_END],
133
+ [:TkTRUE, TkId, "true", EXPR_END],
134
+ [:TkFALSE, TkId, "false", EXPR_END],
135
+ [:TkAND, TkId, "and", EXPR_BEG],
136
+ [:TkOR, TkId, "or", EXPR_BEG],
137
+ [:TkNOT, TkId, "not", EXPR_BEG],
138
+ [:TkIF_MOD, TkId],
139
+ [:TkUNLESS_MOD, TkId],
140
+ [:TkWHILE_MOD, TkId],
141
+ [:TkUNTIL_MOD, TkId],
142
+ [:TkALIAS, TkId, "alias", EXPR_FNAME],
143
+ [:TkDEFINED, TkId, "defined?", EXPR_END],
144
+ [:TklBEGIN, TkId, "BEGIN", EXPR_END],
145
+ [:TklEND, TkId, "END", EXPR_END],
146
+ [:Tk__LINE__, TkId, "__LINE__", EXPR_END],
147
+ [:Tk__FILE__, TkId, "__FILE__", EXPR_END],
148
+
149
+ [:TkIDENTIFIER, TkId],
150
+ [:TkFID, TkId],
151
+ [:TkGVAR, TkId],
152
+ [:TkCVAR, TkId],
153
+ [:TkIVAR, TkId],
154
+ [:TkCONSTANT, TkId],
155
+
156
+ [:TkINTEGER, TkVal],
157
+ [:TkFLOAT, TkVal],
158
+ [:TkSTRING, TkVal],
159
+ [:TkXSTRING, TkVal],
160
+ [:TkREGEXP, TkVal],
161
+ [:TkSYMBOL, TkVal],
162
+
163
+ [:TkDSTRING, TkNode],
164
+ [:TkDXSTRING, TkNode],
165
+ [:TkDREGEXP, TkNode],
166
+ [:TkNTH_REF, TkNode],
167
+ [:TkBACK_REF, TkNode],
168
+
169
+ [:TkUPLUS, TkOp, "+@"],
170
+ [:TkUMINUS, TkOp, "-@"],
171
+ [:TkPOW, TkOp, "**"],
172
+ [:TkCMP, TkOp, "<=>"],
173
+ [:TkEQ, TkOp, "=="],
174
+ [:TkEQQ, TkOp, "==="],
175
+ [:TkNEQ, TkOp, "!="],
176
+ [:TkGEQ, TkOp, ">="],
177
+ [:TkLEQ, TkOp, "<="],
178
+ [:TkANDOP, TkOp, "&&"],
179
+ [:TkOROP, TkOp, "||"],
180
+ [:TkMATCH, TkOp, "=~"],
181
+ [:TkNMATCH, TkOp, "!~"],
182
+ [:TkDOT2, TkOp, ".."],
183
+ [:TkDOT3, TkOp, "..."],
184
+ [:TkAREF, TkOp, "[]"],
185
+ [:TkASET, TkOp, "[]="],
186
+ [:TkLSHFT, TkOp, "<<"],
187
+ [:TkRSHFT, TkOp, ">>"],
188
+ [:TkCOLON2, TkOp],
189
+ [:TkCOLON3, TkOp],
190
+ [:TkASSOC, TkOp, "=>"],
191
+ [:TkQUESTION, TkOp, "?"], #?
192
+ [:TkCOLON, TkOp, ":"], #:
193
+
194
+ [:TkfLPAREN], # func( #
195
+ [:TkfLBRACK], # func[ #
196
+ [:TkfLBRACE], # func{ #
197
+ [:TkSTAR], # *arg
198
+ [:TkAMPER], # &arg #
199
+ [:TkSYMBEG], # :SYMBOL
200
+
201
+ [:TkGT, TkOp, ">"],
202
+ [:TkLT, TkOp, "<"],
203
+ [:TkPLUS, TkOp, "+"],
204
+ [:TkMINUS, TkOp, "-"],
205
+ [:TkMULT, TkOp, "*"],
206
+ [:TkDIV, TkOp, "/"],
207
+ [:TkMOD, TkOp, "%"],
208
+ [:TkBITOR, TkOp, "|"],
209
+ [:TkBITXOR, TkOp, "^"],
210
+ [:TkBITAND, TkOp, "&"],
211
+ [:TkBITNOT, TkOp, "~"],
212
+ [:TkNOTOP, TkOp, "!"],
213
+
214
+ [:TkBACKQUOTE, TkOp, "`"],
215
+
216
+ [:TkASSIGN, Token, "="],
217
+ [:TkDOT, Token, "."],
218
+ [:TkLPAREN, Token, "("], #(exp)
219
+ [:TkLBRACK, Token, "["], #[arry]
220
+ [:TkLBRACE, Token, "{"], #{hash}
221
+ [:TkRPAREN, Token, ")"],
222
+ [:TkRBRACK, Token, "]"],
223
+ [:TkRBRACE, Token, "}"],
224
+ [:TkCOMMA, Token, ","],
225
+ [:TkSEMICOLON, Token, ";"],
226
+
227
+ [:TkCOMMENT],
228
+ [:TkRD_COMMENT],
229
+ [:TkSPACE],
230
+ [:TkNL],
231
+ [:TkEND_OF_SCRIPT],
232
+
233
+ [:TkBACKSLASH, TkUnknownChar, "\\"],
234
+ [:TkAT, TkUnknownChar, "@"],
235
+ [:TkDOLLAR, TkUnknownChar, "$"],
236
+ ]
237
+
238
+ # {reading => token_class}
239
+ # {reading => [token_class, *opt]}
240
+ TkReading2Token = {}
241
+ TkSymbol2Token = {}
242
+
243
+ def RubyToken.def_token(token_n, super_token = Token, reading = nil, *opts)
244
+ token_n = token_n.id2name if token_n.kind_of?(Symbol)
245
+ if RubyToken.const_defined?(token_n)
246
+ IRB.fail AlreadyDefinedToken, token_n
247
+ end
248
+ token_c = eval("class #{token_n} < #{super_token}; end; #{token_n}")
249
+
250
+ if reading
251
+ if TkReading2Token[reading]
252
+ IRB.fail TkReading2TokenDuplicateError, token_n, reading
253
+ end
254
+ if opts.empty?
255
+ TkReading2Token[reading] = [token_c]
256
+ else
257
+ TkReading2Token[reading] = [token_c].concat(opts)
258
+ end
259
+ end
260
+ TkSymbol2Token[token_n.intern] = token_c
261
+ end
262
+
263
+ for defs in TokenDefinitions
264
+ def_token(*defs)
265
+ end
266
+ end
267
+ # :startdoc:
@@ -0,0 +1,282 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ # irb/slex.rb - simple lex analyzer
4
+ # $Release Version: 0.9.6$
5
+ # $Revision$
6
+ # by Keiju ISHITSUKA(keiju@ruby-lang.org)
7
+ #
8
+ # --
9
+ #
10
+ #
11
+ #
12
+
13
+ require "e2mmap"
14
+ require_relative "notifier"
15
+
16
+ # :stopdoc:
17
+ module IRB
18
+ class SLex
19
+
20
+ extend Exception2MessageMapper
21
+ def_exception :ErrNodeNothing, "node nothing"
22
+ def_exception :ErrNodeAlreadyExists, "node already exists"
23
+
24
+ DOUT = Notifier::def_notifier("SLex::")
25
+ D_WARN = DOUT::def_notifier(1, "Warn: ")
26
+ D_DEBUG = DOUT::def_notifier(2, "Debug: ")
27
+ D_DETAIL = DOUT::def_notifier(4, "Detail: ")
28
+
29
+ DOUT.level = Notifier::D_NOMSG
30
+
31
+ def initialize
32
+ @head = Node.new("")
33
+ end
34
+
35
+ def def_rule(token, preproc = nil, postproc = nil, &block)
36
+ D_DETAIL.pp token
37
+
38
+ postproc = block if block_given?
39
+ create(token, preproc, postproc)
40
+ end
41
+
42
+ def def_rules(*tokens, &block)
43
+ if block_given?
44
+ p = block
45
+ end
46
+ for token in tokens
47
+ def_rule(token, nil, p)
48
+ end
49
+ end
50
+
51
+ def preproc(token, proc)
52
+ node = search(token)
53
+ node.preproc=proc
54
+ end
55
+
56
+ # need a check?
57
+ def postproc(token)
58
+ node = search(token, proc)
59
+ node.postproc=proc
60
+ end
61
+
62
+ def search(token)
63
+ @head.search(token.split(//))
64
+ end
65
+
66
+ def create(token, preproc = nil, postproc = nil)
67
+ @head.create_subnode(token.split(//), preproc, postproc)
68
+ end
69
+
70
+ def match(token)
71
+ case token
72
+ when Array
73
+ when String
74
+ return match(token.split(//))
75
+ else
76
+ return @head.match_io(token)
77
+ end
78
+ ret = @head.match(token)
79
+ D_DETAIL.exec_if{D_DETAIL.printf "match end: %s:%s\n", ret, token.inspect}
80
+ ret
81
+ end
82
+
83
+ def inspect
84
+ format("<SLex: @head = %s>", @head.inspect)
85
+ end
86
+
87
+ #----------------------------------------------------------------------
88
+ #
89
+ # class Node -
90
+ #
91
+ #----------------------------------------------------------------------
92
+ class Node
93
+ # if postproc is nil, this node is an abstract node.
94
+ # if postproc is non-nil, this node is a real node.
95
+ def initialize(preproc = nil, postproc = nil)
96
+ @Tree = {}
97
+ @preproc = preproc
98
+ @postproc = postproc
99
+ end
100
+
101
+ attr_accessor :preproc
102
+ attr_accessor :postproc
103
+
104
+ def search(chrs, opt = nil)
105
+ return self if chrs.empty?
106
+ ch = chrs.shift
107
+ if node = @Tree[ch]
108
+ node.search(chrs, opt)
109
+ else
110
+ if opt
111
+ chrs.unshift ch
112
+ self.create_subnode(chrs)
113
+ else
114
+ SLex.fail ErrNodeNothing
115
+ end
116
+ end
117
+ end
118
+
119
+ def create_subnode(chrs, preproc = nil, postproc = nil)
120
+ if chrs.empty?
121
+ if @postproc
122
+ D_DETAIL.pp node
123
+ SLex.fail ErrNodeAlreadyExists
124
+ else
125
+ D_DEBUG.puts "change abstract node to real node."
126
+ @preproc = preproc
127
+ @postproc = postproc
128
+ end
129
+ return self
130
+ end
131
+
132
+ ch = chrs.shift
133
+ if node = @Tree[ch]
134
+ if chrs.empty?
135
+ if node.postproc
136
+ DebugLogger.pp node
137
+ DebugLogger.pp self
138
+ DebugLogger.pp ch
139
+ DebugLogger.pp chrs
140
+ SLex.fail ErrNodeAlreadyExists
141
+ else
142
+ D_WARN.puts "change abstract node to real node"
143
+ node.preproc = preproc
144
+ node.postproc = postproc
145
+ end
146
+ else
147
+ node.create_subnode(chrs, preproc, postproc)
148
+ end
149
+ else
150
+ if chrs.empty?
151
+ node = Node.new(preproc, postproc)
152
+ else
153
+ node = Node.new
154
+ node.create_subnode(chrs, preproc, postproc)
155
+ end
156
+ @Tree[ch] = node
157
+ end
158
+ node
159
+ end
160
+
161
+ #
162
+ # chrs: String
163
+ # character array
164
+ # io must have getc()/ungetc(); and ungetc() must be
165
+ # able to be called arbitrary number of times.
166
+ #
167
+ def match(chrs, op = "")
168
+ D_DETAIL.print "match>: ", chrs, "op:", op, "\n"
169
+ if chrs.empty?
170
+ if @preproc.nil? || @preproc.call(op, chrs)
171
+ DOUT.printf(D_DETAIL, "op1: %s\n", op)
172
+ @postproc.call(op, chrs)
173
+ else
174
+ nil
175
+ end
176
+ else
177
+ ch = chrs.shift
178
+ if node = @Tree[ch]
179
+ if ret = node.match(chrs, op+ch)
180
+ return ret
181
+ else
182
+ chrs.unshift ch
183
+ if @postproc and @preproc.nil? || @preproc.call(op, chrs)
184
+ DOUT.printf(D_DETAIL, "op2: %s\n", op.inspect)
185
+ ret = @postproc.call(op, chrs)
186
+ return ret
187
+ else
188
+ return nil
189
+ end
190
+ end
191
+ else
192
+ chrs.unshift ch
193
+ if @postproc and @preproc.nil? || @preproc.call(op, chrs)
194
+ DOUT.printf(D_DETAIL, "op3: %s\n", op)
195
+ @postproc.call(op, chrs)
196
+ return ""
197
+ else
198
+ return nil
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ def match_io(io, op = "")
205
+ if op == ""
206
+ ch = io.getc
207
+ if ch == nil
208
+ return nil
209
+ end
210
+ else
211
+ ch = io.getc_of_rests
212
+ end
213
+ if ch.nil?
214
+ if @preproc.nil? || @preproc.call(op, io)
215
+ D_DETAIL.printf("op1: %s\n", op)
216
+ @postproc.call(op, io)
217
+ else
218
+ nil
219
+ end
220
+ else
221
+ if node = @Tree[ch]
222
+ if ret = node.match_io(io, op+ch)
223
+ ret
224
+ else
225
+ io.ungetc ch
226
+ if @postproc and @preproc.nil? || @preproc.call(op, io)
227
+ DOUT.exec_if{D_DETAIL.printf "op2: %s\n", op.inspect}
228
+ @postproc.call(op, io)
229
+ else
230
+ nil
231
+ end
232
+ end
233
+ else
234
+ io.ungetc ch
235
+ if @postproc and @preproc.nil? || @preproc.call(op, io)
236
+ D_DETAIL.printf("op3: %s\n", op)
237
+ @postproc.call(op, io)
238
+ else
239
+ nil
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end
245
+ end
246
+ end
247
+ # :startdoc:
248
+
249
+ if $0 == __FILE__
250
+ case $1
251
+ when "1"
252
+ tr = SLex.new
253
+ print "0: ", tr.inspect, "\n"
254
+ tr.def_rule("=") {print "=\n"}
255
+ print "1: ", tr.inspect, "\n"
256
+ tr.def_rule("==") {print "==\n"}
257
+ print "2: ", tr.inspect, "\n"
258
+
259
+ print "case 1:\n"
260
+ print tr.match("="), "\n"
261
+ print "case 2:\n"
262
+ print tr.match("=="), "\n"
263
+ print "case 3:\n"
264
+ print tr.match("=>"), "\n"
265
+
266
+ when "2"
267
+ tr = SLex.new
268
+ print "0: ", tr.inspect, "\n"
269
+ tr.def_rule("=") {print "=\n"}
270
+ print "1: ", tr.inspect, "\n"
271
+ tr.def_rule("==", proc{false}) {print "==\n"}
272
+ print "2: ", tr.inspect, "\n"
273
+
274
+ print "case 1:\n"
275
+ print tr.match("="), "\n"
276
+ print "case 2:\n"
277
+ print tr.match("=="), "\n"
278
+ print "case 3:\n"
279
+ print tr.match("=>"), "\n"
280
+ end
281
+ exit
282
+ end