irb 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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