rubysl-irb 1.0.2 → 2.0.3
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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/lib/irb/cmd/chws.rb +6 -6
- data/lib/irb/cmd/fork.rb +10 -10
- data/lib/irb/cmd/help.rb +24 -14
- data/lib/irb/cmd/load.rb +8 -7
- data/lib/irb/cmd/nop.rb +8 -8
- data/lib/irb/cmd/pushws.rb +6 -5
- data/lib/irb/cmd/subirb.rb +6 -7
- data/lib/irb/completion.rb +90 -58
- data/lib/irb/context.rb +197 -30
- data/lib/irb/ext/change-ws.rb +17 -10
- data/lib/irb/ext/history.rb +20 -10
- data/lib/irb/ext/loader.rb +22 -12
- data/lib/irb/ext/math-mode.rb +16 -6
- data/lib/irb/ext/multi-irb.rb +69 -24
- data/lib/irb/ext/save-history.rb +87 -37
- data/lib/irb/ext/tracer.rb +17 -7
- data/lib/irb/ext/use-loader.rb +14 -6
- data/lib/irb/ext/workspaces.rb +16 -6
- data/lib/irb/extend-command.rb +92 -34
- data/lib/irb/frame.rb +18 -5
- data/lib/irb/help.rb +20 -19
- data/lib/irb/init.rb +156 -104
- data/lib/irb/input-method.rb +96 -23
- data/lib/irb/inspector.rb +145 -0
- data/lib/irb/lc/.document +4 -0
- data/lib/irb/lc/error.rb +8 -7
- data/lib/irb/lc/{help-message.rb → help-message} +14 -11
- data/lib/irb/lc/ja/encoding_aliases.rb +10 -0
- data/lib/irb/lc/ja/error.rb +19 -16
- data/lib/irb/lc/ja/help-message +33 -28
- data/lib/irb/locale.rb +83 -85
- data/lib/irb/magic-file.rb +37 -0
- data/lib/irb/notifier.rb +101 -15
- data/lib/irb/output-method.rb +38 -32
- data/lib/irb/ruby-lex.rb +143 -81
- data/lib/irb/ruby-token.rb +13 -19
- data/lib/irb/slex.rb +26 -27
- data/lib/irb/src_encoding.rb +4 -0
- data/lib/irb/version.rb +6 -7
- data/lib/irb/workspace.rb +22 -15
- data/lib/irb/ws-for-case-2.rb +5 -6
- data/lib/irb/xmp.rb +91 -4
- data/lib/rubysl/irb/irb.rb +523 -175
- data/lib/rubysl/irb/version.rb +1 -1
- data/rubysl-irb.gemspec +7 -6
- metadata +35 -15
@@ -0,0 +1,37 @@
|
|
1
|
+
module IRB
|
2
|
+
class << (MagicFile = Object.new)
|
3
|
+
# see parser_magic_comment in parse.y
|
4
|
+
ENCODING_SPEC_RE = %r"coding\s*[=:]\s*([[:alnum:]\-_]+)"
|
5
|
+
|
6
|
+
def open(path)
|
7
|
+
io = File.open(path, 'rb')
|
8
|
+
line = io.gets
|
9
|
+
line = io.gets if line[0,2] == "#!"
|
10
|
+
encoding = detect_encoding(line)
|
11
|
+
internal_encoding = encoding
|
12
|
+
encoding ||= default_src_encoding
|
13
|
+
io.rewind
|
14
|
+
io.set_encoding(encoding, internal_encoding)
|
15
|
+
|
16
|
+
if block_given?
|
17
|
+
begin
|
18
|
+
return (yield io)
|
19
|
+
ensure
|
20
|
+
io.close
|
21
|
+
end
|
22
|
+
else
|
23
|
+
return io
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def detect_encoding(line)
|
29
|
+
return unless line[0] == ?#
|
30
|
+
line = line[1..-1]
|
31
|
+
line = $1 if line[/-\*-\s*(.*?)\s*-*-$/]
|
32
|
+
return nil unless ENCODING_SPEC_RE =~ line
|
33
|
+
encoding = $1
|
34
|
+
return encoding.sub(/-(?:mac|dos|unix)/i, '')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/irb/notifier.rb
CHANGED
@@ -1,79 +1,120 @@
|
|
1
1
|
#
|
2
|
-
# notifier.rb -
|
3
|
-
# $Release Version: 0.9.
|
4
|
-
# $Revision
|
5
|
-
# $Date: 2007-02-12 15:01:19 -0800 (Mon, 12 Feb 2007) $
|
2
|
+
# notifier.rb - output methods used by irb
|
3
|
+
# $Release Version: 0.9.6$
|
4
|
+
# $Revision$
|
6
5
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
6
|
#
|
8
7
|
# --
|
9
8
|
#
|
10
|
-
#
|
9
|
+
#
|
11
10
|
#
|
12
11
|
|
13
12
|
require "e2mmap"
|
14
13
|
require "irb/output-method"
|
15
14
|
|
16
15
|
module IRB
|
16
|
+
# An output formatter used internally by the lexer.
|
17
17
|
module Notifier
|
18
18
|
extend Exception2MessageMapper
|
19
|
-
def_exception :ErrUndefinedNotifier,
|
19
|
+
def_exception :ErrUndefinedNotifier,
|
20
20
|
"undefined notifier level: %d is specified"
|
21
|
-
def_exception :ErrUnrecognizedLevel,
|
21
|
+
def_exception :ErrUnrecognizedLevel,
|
22
22
|
"unrecognized notifier level: %s is specified"
|
23
23
|
|
24
|
+
# Define a new Notifier output source, returning a new CompositeNotifier
|
25
|
+
# with the given +prefix+ and +output_method+.
|
26
|
+
#
|
27
|
+
# The optional +prefix+ will be appended to all objects being inspected
|
28
|
+
# during output, using the given +output_method+ as the output source. If
|
29
|
+
# no +output_method+ is given, StdioOuputMethod will be used, and all
|
30
|
+
# expressions will be sent directly to STDOUT without any additional
|
31
|
+
# formatting.
|
24
32
|
def def_notifier(prefix = "", output_method = StdioOutputMethod.new)
|
25
33
|
CompositeNotifier.new(prefix, output_method)
|
26
34
|
end
|
27
35
|
module_function :def_notifier
|
28
|
-
|
29
|
-
class
|
36
|
+
|
37
|
+
# An abstract class, or superclass, for CompositeNotifier and
|
38
|
+
# LeveledNotifier to inherit. It provides several wrapper methods for the
|
39
|
+
# OutputMethod object used by the Notifier.
|
40
|
+
class AbstractNotifier
|
41
|
+
# Creates a new Notifier object
|
30
42
|
def initialize(prefix, base_notifier)
|
31
43
|
@prefix = prefix
|
32
44
|
@base_notifier = base_notifier
|
33
45
|
end
|
34
46
|
|
47
|
+
# The +prefix+ for this Notifier, which is appended to all objects being
|
48
|
+
# inspected during output.
|
35
49
|
attr_reader :prefix
|
36
50
|
|
51
|
+
# A wrapper method used to determine whether notifications are enabled.
|
52
|
+
#
|
53
|
+
# Defaults to +true+.
|
37
54
|
def notify?
|
38
55
|
true
|
39
56
|
end
|
40
57
|
|
58
|
+
# See OutputMethod#print for more detail.
|
41
59
|
def print(*opts)
|
42
60
|
@base_notifier.print prefix, *opts if notify?
|
43
61
|
end
|
44
62
|
|
63
|
+
# See OutputMethod#printn for more detail.
|
45
64
|
def printn(*opts)
|
46
65
|
@base_notifier.printn prefix, *opts if notify?
|
47
66
|
end
|
48
67
|
|
68
|
+
# See OutputMethod#printf for more detail.
|
49
69
|
def printf(format, *opts)
|
50
70
|
@base_notifier.printf(prefix + format, *opts) if notify?
|
51
71
|
end
|
52
72
|
|
73
|
+
# See OutputMethod#puts for more detail.
|
53
74
|
def puts(*objs)
|
54
75
|
if notify?
|
55
76
|
@base_notifier.puts(*objs.collect{|obj| prefix + obj.to_s})
|
56
77
|
end
|
57
78
|
end
|
58
79
|
|
80
|
+
# Same as #ppx, except it uses the #prefix given during object
|
81
|
+
# initialization.
|
82
|
+
# See OutputMethod#ppx for more detail.
|
59
83
|
def pp(*objs)
|
60
84
|
if notify?
|
61
85
|
@base_notifier.ppx @prefix, *objs
|
62
86
|
end
|
63
87
|
end
|
64
88
|
|
89
|
+
# Same as #pp, except it concatenates the given +prefix+ with the #prefix
|
90
|
+
# given during object initialization.
|
91
|
+
#
|
92
|
+
# See OutputMethod#ppx for more detail.
|
65
93
|
def ppx(prefix, *objs)
|
66
94
|
if notify?
|
67
95
|
@base_notifier.ppx @prefix+prefix, *objs
|
68
96
|
end
|
69
97
|
end
|
70
98
|
|
99
|
+
# Execute the given block if notifications are enabled.
|
71
100
|
def exec_if
|
72
101
|
yield(@base_notifier) if notify?
|
73
102
|
end
|
74
103
|
end
|
75
104
|
|
76
|
-
class
|
105
|
+
# A class that can be used to create a group of notifier objects with the
|
106
|
+
# intent of representing a leveled notification system for irb.
|
107
|
+
#
|
108
|
+
# This class will allow you to generate other notifiers, and assign them
|
109
|
+
# the appropriate level for output.
|
110
|
+
#
|
111
|
+
# The Notifier class provides a class-method Notifier.def_notifier to
|
112
|
+
# create a new composite notifier. Using the first composite notifier
|
113
|
+
# object you create, sibling notifiers can be initialized with
|
114
|
+
# #def_notifier.
|
115
|
+
class CompositeNotifier<AbstractNotifier
|
116
|
+
# Create a new composite notifier object with the given +prefix+, and
|
117
|
+
# +base_notifier+ to use for output.
|
77
118
|
def initialize(prefix, base_notifier)
|
78
119
|
super
|
79
120
|
|
@@ -81,20 +122,42 @@ module IRB
|
|
81
122
|
@level_notifier = D_NOMSG
|
82
123
|
end
|
83
124
|
|
125
|
+
# List of notifiers in the group
|
84
126
|
attr_reader :notifiers
|
85
127
|
|
128
|
+
# Creates a new LeveledNotifier in the composite #notifiers group.
|
129
|
+
#
|
130
|
+
# The given +prefix+ will be assigned to the notifier, and +level+ will
|
131
|
+
# be used as the index of the #notifiers Array.
|
132
|
+
#
|
133
|
+
# This method returns the newly created instance.
|
86
134
|
def def_notifier(level, prefix = "")
|
87
135
|
notifier = LeveledNotifier.new(self, level, prefix)
|
88
136
|
@notifiers[level] = notifier
|
89
137
|
notifier
|
90
138
|
end
|
91
139
|
|
140
|
+
# Returns the leveled notifier for this object
|
92
141
|
attr_reader :level_notifier
|
93
142
|
alias level level_notifier
|
94
143
|
|
144
|
+
# Sets the leveled notifier for this object.
|
145
|
+
#
|
146
|
+
# When the given +value+ is an instance of AbstractNotifier,
|
147
|
+
# #level_notifier is set to the given object.
|
148
|
+
#
|
149
|
+
# When an Integer is given, #level_notifier is set to the notifier at the
|
150
|
+
# index +value+ in the #notifiers Array.
|
151
|
+
#
|
152
|
+
# If no notifier exists at the index +value+ in the #notifiers Array, an
|
153
|
+
# ErrUndefinedNotifier exception is raised.
|
154
|
+
#
|
155
|
+
# An ErrUnrecognizedLevel exception is raised if the given +value+ is not
|
156
|
+
# found in the existing #notifiers Array, or an instance of
|
157
|
+
# AbstractNotifier
|
95
158
|
def level_notifier=(value)
|
96
159
|
case value
|
97
|
-
when
|
160
|
+
when AbstractNotifier
|
98
161
|
@level_notifier = value
|
99
162
|
when Integer
|
100
163
|
l = @notifiers[value]
|
@@ -108,38 +171,61 @@ module IRB
|
|
108
171
|
alias level= level_notifier=
|
109
172
|
end
|
110
173
|
|
111
|
-
|
174
|
+
# A leveled notifier is comparable to the composite group from
|
175
|
+
# CompositeNotifier#notifiers.
|
176
|
+
class LeveledNotifier<AbstractNotifier
|
112
177
|
include Comparable
|
113
178
|
|
179
|
+
# Create a new leveled notifier with the given +base+, and +prefix+ to
|
180
|
+
# send to AbstractNotifier.new
|
181
|
+
#
|
182
|
+
# The given +level+ is used to compare other leveled notifiers in the
|
183
|
+
# CompositeNotifier group to determine whether or not to output
|
184
|
+
# notifications.
|
114
185
|
def initialize(base, level, prefix)
|
115
186
|
super(prefix, base)
|
116
|
-
|
187
|
+
|
117
188
|
@level = level
|
118
189
|
end
|
119
190
|
|
191
|
+
# The current level of this notifier object
|
120
192
|
attr_reader :level
|
121
193
|
|
194
|
+
# Compares the level of this notifier object with the given +other+
|
195
|
+
# notifier.
|
196
|
+
#
|
197
|
+
# See the Comparable module for more information.
|
122
198
|
def <=>(other)
|
123
199
|
@level <=> other.level
|
124
200
|
end
|
125
|
-
|
201
|
+
|
202
|
+
# Whether to output messages to the output method, depending on the level
|
203
|
+
# of this notifier object.
|
126
204
|
def notify?
|
127
205
|
@base_notifier.level >= self
|
128
206
|
end
|
129
207
|
end
|
130
208
|
|
209
|
+
# NoMsgNotifier is a LeveledNotifier that's used as the default notifier
|
210
|
+
# when creating a new CompositeNotifier.
|
211
|
+
#
|
212
|
+
# This notifier is used as the +zero+ index, or level +0+, for
|
213
|
+
# CompositeNotifier#notifiers, and will not output messages of any sort.
|
131
214
|
class NoMsgNotifier<LeveledNotifier
|
215
|
+
# Creates a new notifier that should not be used to output messages.
|
132
216
|
def initialize
|
133
217
|
@base_notifier = nil
|
134
218
|
@level = 0
|
135
219
|
@prefix = ""
|
136
220
|
end
|
137
221
|
|
222
|
+
# Ensures notifications are ignored, see AbstractNotifier#notify? for
|
223
|
+
# more information.
|
138
224
|
def notify?
|
139
225
|
false
|
140
226
|
end
|
141
227
|
end
|
142
228
|
|
143
|
-
D_NOMSG = NoMsgNotifier.new
|
229
|
+
D_NOMSG = NoMsgNotifier.new # :nodoc:
|
144
230
|
end
|
145
231
|
end
|
data/lib/irb/output-method.rb
CHANGED
@@ -1,33 +1,38 @@
|
|
1
1
|
#
|
2
|
-
# output-method.rb -
|
3
|
-
# $Release Version: 0.9.
|
4
|
-
# $Revision
|
5
|
-
# $Date: 2007-02-12 15:01:19 -0800 (Mon, 12 Feb 2007) $
|
2
|
+
# output-method.rb - output methods used by irb
|
3
|
+
# $Release Version: 0.9.6$
|
4
|
+
# $Revision$
|
6
5
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
6
|
#
|
8
7
|
# --
|
9
8
|
#
|
10
|
-
#
|
9
|
+
#
|
11
10
|
#
|
12
11
|
|
13
12
|
require "e2mmap"
|
14
13
|
|
15
14
|
module IRB
|
16
|
-
#
|
17
|
-
#
|
18
|
-
|
15
|
+
# An abstract output class for IO in irb. This is mainly used internally by
|
16
|
+
# IRB::Notifier. You can define your own output method to use with Irb.new,
|
17
|
+
# or Context.new
|
19
18
|
class OutputMethod
|
20
|
-
|
19
|
+
extend Exception2MessageMapper
|
20
|
+
def_exception :NotImplementedError, "Need to define `%s'"
|
21
|
+
|
21
22
|
|
23
|
+
# Open this method to implement your own output method, raises a
|
24
|
+
# NotImplementedError if you don't define #print in your own class.
|
22
25
|
def print(*opts)
|
23
|
-
|
26
|
+
OutputMethod.Raise NotImplementedError, "print"
|
24
27
|
end
|
25
28
|
|
29
|
+
# Prints the given +opts+, with a newline delimiter.
|
26
30
|
def printn(*opts)
|
27
31
|
print opts.join(" "), "\n"
|
28
32
|
end
|
29
33
|
|
30
|
-
#
|
34
|
+
# Extends IO#printf to format the given +opts+ for Kernel#sprintf using
|
35
|
+
# #parse_printf_format
|
31
36
|
def printf(format, *opts)
|
32
37
|
if /(%*)%I/ =~ format
|
33
38
|
format, opts = parse_printf_format(format, opts)
|
@@ -35,31 +40,22 @@ module IRB
|
|
35
40
|
print sprintf(format, *opts)
|
36
41
|
end
|
37
42
|
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
43
|
+
# Returns an array of the given +format+ and +opts+ to be used by
|
44
|
+
# Kernel#sprintf, if there was a successful Regexp match in the given
|
45
|
+
# +format+ from #printf
|
46
|
+
#
|
47
|
+
# %
|
48
|
+
# <flag> [#0- +]
|
49
|
+
# <minimum field width> (\*|\*[1-9][0-9]*\$|[1-9][0-9]*)
|
50
|
+
# <precision>.(\*|\*[1-9][0-9]*\$|[1-9][0-9]*|)?
|
51
|
+
# #<length modifier>(hh|h|l|ll|L|q|j|z|t)
|
52
|
+
# <conversion specifier>[diouxXeEfgGcsb%]
|
44
53
|
def parse_printf_format(format, opts)
|
45
54
|
return format, opts if $1.size % 2 == 1
|
46
55
|
end
|
47
56
|
|
48
|
-
|
49
|
-
|
50
|
-
inspects = []
|
51
|
-
format.scan(/%[#0\-+ ]?(\*(?=[^0-9])|\*[1-9][0-9]*\$|[1-9][0-9]*(?=[^0-9]))?(\.(\*(?=[^0-9])|\*[1-9][0-9]*\$|[1-9][0-9]*(?=[^0-9])))?(([1-9][0-9]*\$)*)([diouxXeEfgGcsb%])/) {|f, p, pp, pos, new_pos, c|
|
52
|
-
puts [f, p, pp, pos, new_pos, c].join("!")
|
53
|
-
pos = new_pos if new_pos
|
54
|
-
if c == "I"
|
55
|
-
inspects.push pos.to_i
|
56
|
-
(f||"")+(p||"")+(pp||"")+(pos||"")+"s"
|
57
|
-
else
|
58
|
-
$&
|
59
|
-
end
|
60
|
-
}
|
61
|
-
end
|
62
|
-
|
57
|
+
# Calls #print on each element in the given +objs+, followed by a newline
|
58
|
+
# character.
|
63
59
|
def puts(*objs)
|
64
60
|
for obj in objs
|
65
61
|
print(*obj)
|
@@ -67,17 +63,27 @@ module IRB
|
|
67
63
|
end
|
68
64
|
end
|
69
65
|
|
66
|
+
# Prints the given +objs+ calling Object#inspect on each.
|
67
|
+
#
|
68
|
+
# See #puts for more detail.
|
70
69
|
def pp(*objs)
|
71
70
|
puts(*objs.collect{|obj| obj.inspect})
|
72
71
|
end
|
73
72
|
|
73
|
+
# Prints the given +objs+ calling Object#inspect on each and appending the
|
74
|
+
# given +prefix+.
|
75
|
+
#
|
76
|
+
# See #puts for more detail.
|
74
77
|
def ppx(prefix, *objs)
|
75
78
|
puts(*objs.collect{|obj| prefix+obj.inspect})
|
76
79
|
end
|
77
80
|
|
78
81
|
end
|
79
82
|
|
83
|
+
# A standard output printer
|
80
84
|
class StdioOutputMethod<OutputMethod
|
85
|
+
# Prints the given +opts+ to standard output, see IO#print for more
|
86
|
+
# information.
|
81
87
|
def print(*opts)
|
82
88
|
STDOUT.print(*opts)
|
83
89
|
end
|
data/lib/irb/ruby-lex.rb
CHANGED
@@ -1,32 +1,32 @@
|
|
1
1
|
#
|
2
|
-
# irb/ruby-lex.rb - ruby lexcal
|
3
|
-
# $Release Version: 0.9.
|
4
|
-
# $Revision
|
5
|
-
# $Date: 2007-02-12 15:01:19 -0800 (Mon, 12 Feb 2007) $
|
2
|
+
# irb/ruby-lex.rb - ruby lexcal analyzer
|
3
|
+
# $Release Version: 0.9.6$
|
4
|
+
# $Revision$
|
6
5
|
# by Keiju ISHITSUKA(keiju@ruby-lang.org)
|
7
6
|
#
|
8
7
|
# --
|
9
8
|
#
|
10
|
-
#
|
9
|
+
#
|
11
10
|
#
|
12
11
|
|
13
12
|
require "e2mmap"
|
14
13
|
require "irb/slex"
|
15
14
|
require "irb/ruby-token"
|
16
15
|
|
16
|
+
# :stopdoc:
|
17
17
|
class RubyLex
|
18
|
-
@RCS_ID='-$Id
|
18
|
+
@RCS_ID='-$Id$-'
|
19
19
|
|
20
20
|
extend Exception2MessageMapper
|
21
21
|
def_exception(:AlreadyDefinedToken, "Already defined token(%s)")
|
22
22
|
def_exception(:TkReading2TokenNoKey, "key nothing(key='%s')")
|
23
23
|
def_exception(:TkSymbol2TokenNoKey, "key nothing(key='%s')")
|
24
|
-
def_exception(:TkReading2TokenDuplicateError,
|
24
|
+
def_exception(:TkReading2TokenDuplicateError,
|
25
25
|
"key duplicate(token_n='%s', key='%s')")
|
26
26
|
def_exception(:SyntaxError, "%s")
|
27
27
|
|
28
28
|
def_exception(:TerminateLineInput, "Terminate Line Input")
|
29
|
-
|
29
|
+
|
30
30
|
include RubyToken
|
31
31
|
|
32
32
|
class << self
|
@@ -54,7 +54,8 @@ class RubyLex
|
|
54
54
|
@lex_state = EXPR_BEG
|
55
55
|
@space_seen = false
|
56
56
|
@here_header = false
|
57
|
-
|
57
|
+
@post_symbeg = false
|
58
|
+
|
58
59
|
@continue = false
|
59
60
|
@line = ""
|
60
61
|
|
@@ -77,7 +78,7 @@ class RubyLex
|
|
77
78
|
# io functions
|
78
79
|
def set_input(io, p = nil, &block)
|
79
80
|
@io = io
|
80
|
-
if p
|
81
|
+
if p.respond_to?(:call)
|
81
82
|
@input = p
|
82
83
|
elsif block_given?
|
83
84
|
@input = block
|
@@ -87,12 +88,12 @@ class RubyLex
|
|
87
88
|
end
|
88
89
|
|
89
90
|
def get_readed
|
90
|
-
if idx = @readed.
|
91
|
-
@base_char_no = idx
|
91
|
+
if idx = @readed.rindex("\n")
|
92
|
+
@base_char_no = @readed.size - (idx + 1)
|
92
93
|
else
|
93
94
|
@base_char_no += @readed.size
|
94
95
|
end
|
95
|
-
|
96
|
+
|
96
97
|
readed = @readed.join("")
|
97
98
|
@readed = []
|
98
99
|
readed
|
@@ -111,7 +112,7 @@ class RubyLex
|
|
111
112
|
end
|
112
113
|
@seek += 1
|
113
114
|
if c == "\n"
|
114
|
-
@line_no += 1
|
115
|
+
@line_no += 1
|
115
116
|
@char_no = 0
|
116
117
|
else
|
117
118
|
@char_no += 1
|
@@ -148,12 +149,12 @@ class RubyLex
|
|
148
149
|
c2 = @here_readed.pop
|
149
150
|
end
|
150
151
|
c = c2 unless c
|
151
|
-
@rests.unshift c #c =
|
152
|
-
|
152
|
+
@rests.unshift c #c =
|
153
|
+
@seek -= 1
|
153
154
|
if c == "\n"
|
154
|
-
@line_no -= 1
|
155
|
-
if idx = @readed.
|
156
|
-
@char_no =
|
155
|
+
@line_no -= 1
|
156
|
+
if idx = @readed.rindex("\n")
|
157
|
+
@char_no = idx + 1
|
157
158
|
else
|
158
159
|
@char_no = @base_char_no + @readed.size
|
159
160
|
end
|
@@ -188,7 +189,7 @@ class RubyLex
|
|
188
189
|
prompt
|
189
190
|
line = @input.call
|
190
191
|
return nil unless line
|
191
|
-
@rests.concat line.
|
192
|
+
@rests.concat line.chars.to_a
|
192
193
|
true
|
193
194
|
end
|
194
195
|
private :buf_input
|
@@ -216,14 +217,16 @@ class RubyLex
|
|
216
217
|
@lex_state = EXPR_BEG
|
217
218
|
@space_seen = false
|
218
219
|
@here_header = false
|
219
|
-
|
220
|
+
|
220
221
|
@continue = false
|
222
|
+
@post_symbeg = false
|
223
|
+
|
221
224
|
prompt
|
222
225
|
|
223
226
|
@line = ""
|
224
227
|
@exp_line_no = @line_no
|
225
228
|
end
|
226
|
-
|
229
|
+
|
227
230
|
def each_top_level_statement
|
228
231
|
initialize_input
|
229
232
|
catch(:TERM_INPUT) do
|
@@ -234,13 +237,13 @@ class RubyLex
|
|
234
237
|
unless l = lex
|
235
238
|
throw :TERM_INPUT if @line == ''
|
236
239
|
else
|
237
|
-
#p l
|
238
240
|
@line.concat l
|
239
241
|
if @ltype or @continue or @indent > 0
|
240
242
|
next
|
241
243
|
end
|
242
244
|
end
|
243
245
|
if @line != "\n"
|
246
|
+
@line.force_encoding(@io.encoding)
|
244
247
|
yield @line, @exp_line_no
|
245
248
|
end
|
246
249
|
break unless l
|
@@ -286,6 +289,8 @@ class RubyLex
|
|
286
289
|
begin
|
287
290
|
tk = @OP.match(self)
|
288
291
|
@space_seen = tk.kind_of?(TkSPACE)
|
292
|
+
@lex_state = EXPR_END if @post_symbeg && tk.kind_of?(TkOp)
|
293
|
+
@post_symbeg = tk.kind_of?(TkSYMBEG)
|
289
294
|
rescue SyntaxError
|
290
295
|
raise if @exception_on_syntax_error
|
291
296
|
tk = TkError.new(@seek, @line_no, @char_no)
|
@@ -297,7 +302,7 @@ class RubyLex
|
|
297
302
|
# Tracer.off
|
298
303
|
tk
|
299
304
|
end
|
300
|
-
|
305
|
+
|
301
306
|
ENINDENT_CLAUSE = [
|
302
307
|
"case", "class", "def", "do", "for", "if",
|
303
308
|
"module", "unless", "until", "while", "begin" #, "when"
|
@@ -312,9 +317,11 @@ class RubyLex
|
|
312
317
|
"r" => "/",
|
313
318
|
"w" => "]",
|
314
319
|
"W" => "]",
|
320
|
+
"i" => "]",
|
321
|
+
"I" => "]",
|
315
322
|
"s" => ":"
|
316
323
|
}
|
317
|
-
|
324
|
+
|
318
325
|
PERCENT_PAREN = {
|
319
326
|
"{" => "}",
|
320
327
|
"[" => "]",
|
@@ -354,7 +361,7 @@ class RubyLex
|
|
354
361
|
end
|
355
362
|
|
356
363
|
@OP.def_rule("=begin",
|
357
|
-
proc{|op, io| @prev_char_no == 0 && peek(0) =~ /\s/}) do
|
364
|
+
proc{|op, io| @prev_char_no == 0 && peek(0) =~ /\s/}) do
|
358
365
|
|op, io|
|
359
366
|
@ltype = "="
|
360
367
|
until getc == "\n"; end
|
@@ -374,8 +381,8 @@ class RubyLex
|
|
374
381
|
else
|
375
382
|
@continue = false
|
376
383
|
@lex_state = EXPR_BEG
|
377
|
-
until (@indent_stack.empty? ||
|
378
|
-
[TkLPAREN, TkLBRACK, TkLBRACE,
|
384
|
+
until (@indent_stack.empty? ||
|
385
|
+
[TkLPAREN, TkLBRACK, TkLBRACE,
|
379
386
|
TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))
|
380
387
|
@indent_stack.pop
|
381
388
|
end
|
@@ -385,11 +392,12 @@ class RubyLex
|
|
385
392
|
Token(TkNL)
|
386
393
|
end
|
387
394
|
|
388
|
-
@OP.def_rules("*", "**",
|
389
|
-
"=", "==", "===",
|
390
|
-
"=~", "<=>",
|
395
|
+
@OP.def_rules("*", "**",
|
396
|
+
"=", "==", "===",
|
397
|
+
"=~", "<=>",
|
391
398
|
"<", "<=",
|
392
|
-
">", ">=", ">>"
|
399
|
+
">", ">=", ">>",
|
400
|
+
"!", "!=", "!~") do
|
393
401
|
|op, io|
|
394
402
|
case @lex_state
|
395
403
|
when EXPR_FNAME, EXPR_DOT
|
@@ -400,19 +408,13 @@ class RubyLex
|
|
400
408
|
Token(op)
|
401
409
|
end
|
402
410
|
|
403
|
-
@OP.def_rules("!", "!=", "!~") do
|
404
|
-
|op, io|
|
405
|
-
@lex_state = EXPR_BEG
|
406
|
-
Token(op)
|
407
|
-
end
|
408
|
-
|
409
411
|
@OP.def_rules("<<") do
|
410
412
|
|op, io|
|
411
413
|
tk = nil
|
412
414
|
if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&
|
413
415
|
(@lex_state != EXPR_ARG || @space_seen)
|
414
416
|
c = peek(0)
|
415
|
-
if /\S/ =~ c && (/["'`]/ =~ c || /
|
417
|
+
if /\S/ =~ c && (/["'`]/ =~ c || /\w/ =~ c || c == "-")
|
416
418
|
tk = identify_here_document
|
417
419
|
end
|
418
420
|
end
|
@@ -455,7 +457,7 @@ class RubyLex
|
|
455
457
|
@lex_state = EXPR_BEG;
|
456
458
|
Token(TkQUESTION)
|
457
459
|
else
|
458
|
-
if (ch == '\\')
|
460
|
+
if (ch == '\\')
|
459
461
|
read_escape
|
460
462
|
end
|
461
463
|
@lex_state = EXPR_END
|
@@ -469,8 +471,8 @@ class RubyLex
|
|
469
471
|
@lex_state = EXPR_BEG
|
470
472
|
Token(op)
|
471
473
|
end
|
472
|
-
|
473
|
-
@OP.def_rules("+=", "-=", "*=", "**=",
|
474
|
+
|
475
|
+
@OP.def_rules("+=", "-=", "*=", "**=",
|
474
476
|
"&=", "|=", "^=", "<<=", ">>=", "||=", "&&=") do
|
475
477
|
|op, io|
|
476
478
|
@lex_state = EXPR_BEG
|
@@ -529,7 +531,7 @@ class RubyLex
|
|
529
531
|
|
530
532
|
lex_int2
|
531
533
|
end
|
532
|
-
|
534
|
+
|
533
535
|
def lex_int2
|
534
536
|
@OP.def_rules("]", "}", ")") do
|
535
537
|
|op, io|
|
@@ -545,7 +547,7 @@ class RubyLex
|
|
545
547
|
@lex_state = EXPR_BEG
|
546
548
|
Token(TkCOLON)
|
547
549
|
else
|
548
|
-
@lex_state = EXPR_FNAME
|
550
|
+
@lex_state = EXPR_FNAME
|
549
551
|
Token(TkSYMBEG)
|
550
552
|
end
|
551
553
|
end
|
@@ -572,7 +574,7 @@ class RubyLex
|
|
572
574
|
Token(TkOPASGN, "/") #/)
|
573
575
|
elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
|
574
576
|
identify_string(op)
|
575
|
-
else
|
577
|
+
else
|
576
578
|
@lex_state = EXPR_BEG
|
577
579
|
Token("/") #/)
|
578
580
|
end
|
@@ -588,7 +590,7 @@ class RubyLex
|
|
588
590
|
# @lex_state = EXPR_BEG
|
589
591
|
# Token(OP_ASGN, :^)
|
590
592
|
# end
|
591
|
-
|
593
|
+
|
592
594
|
@OP.def_rules(",") do
|
593
595
|
|op, io|
|
594
596
|
@lex_state = EXPR_BEG
|
@@ -598,8 +600,8 @@ class RubyLex
|
|
598
600
|
@OP.def_rules(";") do
|
599
601
|
|op, io|
|
600
602
|
@lex_state = EXPR_BEG
|
601
|
-
until (@indent_stack.empty? ||
|
602
|
-
[TkLPAREN, TkLBRACK, TkLBRACE,
|
603
|
+
until (@indent_stack.empty? ||
|
604
|
+
[TkLPAREN, TkLBRACK, TkLBRACE,
|
603
605
|
TkfLPAREN, TkfLBRACK, TkfLBRACE].include?(@indent_stack.last))
|
604
606
|
@indent_stack.pop
|
605
607
|
end
|
@@ -617,7 +619,7 @@ class RubyLex
|
|
617
619
|
@lex_state = EXPR_BEG
|
618
620
|
Token("~")
|
619
621
|
end
|
620
|
-
|
622
|
+
|
621
623
|
@OP.def_rule("(") do
|
622
624
|
|op, io|
|
623
625
|
@indent += 1
|
@@ -629,7 +631,7 @@ class RubyLex
|
|
629
631
|
tk_c = TkLPAREN
|
630
632
|
end
|
631
633
|
@indent_stack.push tk_c
|
632
|
-
|
634
|
+
Token(tk_c)
|
633
635
|
end
|
634
636
|
|
635
637
|
@OP.def_rule("[]", proc{|op, io| @lex_state == EXPR_FNAME}) do
|
@@ -683,7 +685,7 @@ class RubyLex
|
|
683
685
|
@continue = true
|
684
686
|
Token(TkSPACE)
|
685
687
|
else
|
686
|
-
|
688
|
+
read_escape
|
687
689
|
Token("\\")
|
688
690
|
end
|
689
691
|
end
|
@@ -710,7 +712,7 @@ class RubyLex
|
|
710
712
|
|
711
713
|
@OP.def_rule('@') do
|
712
714
|
|op, io|
|
713
|
-
if peek(0) =~ /[\
|
715
|
+
if peek(0) =~ /[\w@]/
|
714
716
|
ungetc
|
715
717
|
identify_identifier
|
716
718
|
else
|
@@ -718,7 +720,7 @@ class RubyLex
|
|
718
720
|
end
|
719
721
|
end
|
720
722
|
|
721
|
-
# @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do
|
723
|
+
# @OP.def_rule("def", proc{|op, io| /\s/ =~ io.peek(0)}) do
|
722
724
|
# |op, io|
|
723
725
|
# @indent += 1
|
724
726
|
# @lex_state = EXPR_FNAME
|
@@ -733,19 +735,19 @@ class RubyLex
|
|
733
735
|
printf "MATCH: start %s: %s\n", op, io.inspect if RubyLex.debug?
|
734
736
|
if peek(0) =~ /[0-9]/
|
735
737
|
t = identify_number
|
736
|
-
elsif peek(0) =~ /[
|
738
|
+
elsif peek(0) =~ /[^\x00-\/:-@\[-^`{-\x7F]/
|
737
739
|
t = identify_identifier
|
738
740
|
end
|
739
741
|
printf "MATCH: end %s: %s\n", op, io.inspect if RubyLex.debug?
|
740
742
|
t
|
741
743
|
end
|
742
|
-
|
744
|
+
|
743
745
|
p @OP if RubyLex.debug?
|
744
746
|
end
|
745
|
-
|
747
|
+
|
746
748
|
def identify_gvar
|
747
749
|
@lex_state = EXPR_END
|
748
|
-
|
750
|
+
|
749
751
|
case ch = getc
|
750
752
|
when /[~_*$?!@\/\\;,=:<>".]/ #"
|
751
753
|
Token(TkGVAR, "$" + ch)
|
@@ -761,12 +763,12 @@ class RubyLex
|
|
761
763
|
ungetc
|
762
764
|
ungetc
|
763
765
|
identify_identifier
|
764
|
-
else
|
766
|
+
else
|
765
767
|
ungetc
|
766
768
|
Token("$")
|
767
769
|
end
|
768
770
|
end
|
769
|
-
|
771
|
+
|
770
772
|
def identify_identifier
|
771
773
|
token = ""
|
772
774
|
if peek(0) =~ /[$@]/
|
@@ -776,12 +778,12 @@ class RubyLex
|
|
776
778
|
end
|
777
779
|
end
|
778
780
|
|
779
|
-
while (ch = getc) =~
|
781
|
+
while (ch = getc) =~ /[^\x00-\/:-@\[-^`{-\x7F]/
|
780
782
|
print ":", ch, ":" if RubyLex.debug?
|
781
783
|
token.concat ch
|
782
784
|
end
|
783
785
|
ungetc
|
784
|
-
|
786
|
+
|
785
787
|
if (ch == "!" || ch == "?") && token[0,1] =~ /\w/ && peek(0) != "="
|
786
788
|
token.concat getc
|
787
789
|
end
|
@@ -799,7 +801,7 @@ class RubyLex
|
|
799
801
|
@lex_state = EXPR_END
|
800
802
|
return Token(TkIVAR, token)
|
801
803
|
end
|
802
|
-
|
804
|
+
|
803
805
|
if @lex_state != EXPR_DOT
|
804
806
|
print token, "\n" if RubyLex.debug?
|
805
807
|
|
@@ -822,11 +824,11 @@ class RubyLex
|
|
822
824
|
when "class"
|
823
825
|
valid = false unless peek_match?(/^\s*(<<|\w|::)/)
|
824
826
|
when "def"
|
825
|
-
valid = false if peek_match?(/^\s*(([
|
827
|
+
valid = false if peek_match?(/^\s*(([+\-\/*&\|^]|<<|>>|\|\||\&\&)=|\&\&|\|\|)/)
|
826
828
|
when "do"
|
827
|
-
valid = false if peek_match?(/^\s*([
|
829
|
+
valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&)/)
|
828
830
|
when *ENINDENT_CLAUSE
|
829
|
-
valid = false if peek_match?(/^\s*([
|
831
|
+
valid = false if peek_match?(/^\s*([+\-\/*]?=|\*|<|>|\&|\|)/)
|
830
832
|
else
|
831
833
|
# no nothing
|
832
834
|
end
|
@@ -910,10 +912,25 @@ class RubyLex
|
|
910
912
|
end
|
911
913
|
|
912
914
|
@here_header = false
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
915
|
+
# while l = gets
|
916
|
+
# l = l.sub(/(:?\r)?\n\z/, '')
|
917
|
+
# if (indent ? l.strip : l) == quoted
|
918
|
+
# break
|
919
|
+
# end
|
920
|
+
# end
|
921
|
+
|
922
|
+
line = ""
|
923
|
+
while ch = getc
|
924
|
+
if ch == "\n"
|
925
|
+
if line == quoted
|
926
|
+
break
|
927
|
+
end
|
928
|
+
line = ""
|
929
|
+
else
|
930
|
+
line.concat ch unless indent && line == "" && /\s/ =~ ch
|
931
|
+
if @ltype != "'" && ch == "#" && peek(0) == "{"
|
932
|
+
identify_string_dvar
|
933
|
+
end
|
917
934
|
end
|
918
935
|
end
|
919
936
|
|
@@ -927,7 +944,7 @@ class RubyLex
|
|
927
944
|
@lex_state = EXPR_END
|
928
945
|
Token(Ltype2Token[lt])
|
929
946
|
end
|
930
|
-
|
947
|
+
|
931
948
|
def identify_quotation
|
932
949
|
ch = getc
|
933
950
|
if lt = PERCENT_LTYPE[ch]
|
@@ -967,11 +984,11 @@ class RubyLex
|
|
967
984
|
when /[0-7]/
|
968
985
|
match = /[0-7_]/
|
969
986
|
when /[89]/
|
970
|
-
RubyLex.fail SyntaxError, "
|
971
|
-
else
|
987
|
+
RubyLex.fail SyntaxError, "Invalid octal digit"
|
988
|
+
else
|
972
989
|
return Token(TkINTEGER)
|
973
990
|
end
|
974
|
-
|
991
|
+
|
975
992
|
len0 = true
|
976
993
|
non_digit = false
|
977
994
|
while ch = getc
|
@@ -999,7 +1016,7 @@ class RubyLex
|
|
999
1016
|
end
|
1000
1017
|
return Token(TkINTEGER)
|
1001
1018
|
end
|
1002
|
-
|
1019
|
+
|
1003
1020
|
type = TkINTEGER
|
1004
1021
|
allow_point = true
|
1005
1022
|
allow_e = true
|
@@ -1042,7 +1059,7 @@ class RubyLex
|
|
1042
1059
|
end
|
1043
1060
|
Token(type)
|
1044
1061
|
end
|
1045
|
-
|
1062
|
+
|
1046
1063
|
def identify_string(ltype, quoted = ltype)
|
1047
1064
|
@ltype = ltype
|
1048
1065
|
@quoted = quoted
|
@@ -1052,12 +1069,20 @@ class RubyLex
|
|
1052
1069
|
while ch = getc
|
1053
1070
|
if @quoted == ch and nest == 0
|
1054
1071
|
break
|
1072
|
+
elsif @ltype != "'" && ch == "#" && peek(0) == "{"
|
1073
|
+
identify_string_dvar
|
1055
1074
|
elsif @ltype != "'" && @ltype != "]" && @ltype != ":" and ch == "#"
|
1056
1075
|
subtype = true
|
1076
|
+
elsif ch == '\\' and @ltype == "'" #'
|
1077
|
+
case ch = getc
|
1078
|
+
when "\\", "\n", "'"
|
1079
|
+
else
|
1080
|
+
ungetc
|
1081
|
+
end
|
1057
1082
|
elsif ch == '\\' #'
|
1058
1083
|
read_escape
|
1059
1084
|
end
|
1060
|
-
if PERCENT_PAREN.values.include?(@quoted)
|
1085
|
+
if PERCENT_PAREN.values.include?(@quoted)
|
1061
1086
|
if PERCENT_PAREN[ch] == @quoted
|
1062
1087
|
nest += 1
|
1063
1088
|
elsif ch == @quoted
|
@@ -1066,7 +1091,7 @@ class RubyLex
|
|
1066
1091
|
end
|
1067
1092
|
end
|
1068
1093
|
if @ltype == "/"
|
1069
|
-
|
1094
|
+
while /[imxoesun]/ =~ peek(0)
|
1070
1095
|
getc
|
1071
1096
|
end
|
1072
1097
|
end
|
@@ -1081,7 +1106,43 @@ class RubyLex
|
|
1081
1106
|
@lex_state = EXPR_END
|
1082
1107
|
end
|
1083
1108
|
end
|
1084
|
-
|
1109
|
+
|
1110
|
+
def identify_string_dvar
|
1111
|
+
begin
|
1112
|
+
getc
|
1113
|
+
|
1114
|
+
reserve_continue = @continue
|
1115
|
+
reserve_ltype = @ltype
|
1116
|
+
reserve_indent = @indent
|
1117
|
+
reserve_indent_stack = @indent_stack
|
1118
|
+
reserve_state = @lex_state
|
1119
|
+
reserve_quoted = @quoted
|
1120
|
+
|
1121
|
+
@ltype = nil
|
1122
|
+
@quoted = nil
|
1123
|
+
@indent = 0
|
1124
|
+
@indent_stack = []
|
1125
|
+
@lex_state = EXPR_BEG
|
1126
|
+
|
1127
|
+
loop do
|
1128
|
+
@continue = false
|
1129
|
+
prompt
|
1130
|
+
tk = token
|
1131
|
+
if @ltype or @continue or @indent > 0
|
1132
|
+
next
|
1133
|
+
end
|
1134
|
+
break if tk.kind_of?(TkRBRACE)
|
1135
|
+
end
|
1136
|
+
ensure
|
1137
|
+
@continue = reserve_continue
|
1138
|
+
@ltype = reserve_ltype
|
1139
|
+
@indent = reserve_indent
|
1140
|
+
@indent_stack = reserve_indent_stack
|
1141
|
+
@lex_state = reserve_state
|
1142
|
+
@quoted = reserve_quoted
|
1143
|
+
end
|
1144
|
+
end
|
1145
|
+
|
1085
1146
|
def identify_comment
|
1086
1147
|
@ltype = "#"
|
1087
1148
|
|
@@ -1097,7 +1158,7 @@ class RubyLex
|
|
1097
1158
|
end
|
1098
1159
|
return Token(TkCOMMENT)
|
1099
1160
|
end
|
1100
|
-
|
1161
|
+
|
1101
1162
|
def read_escape
|
1102
1163
|
case ch = getc
|
1103
1164
|
when "\n", "\r", "\f"
|
@@ -1114,7 +1175,7 @@ class RubyLex
|
|
1114
1175
|
break
|
1115
1176
|
end
|
1116
1177
|
end
|
1117
|
-
|
1178
|
+
|
1118
1179
|
when "x"
|
1119
1180
|
2.times do
|
1120
1181
|
case ch = getc
|
@@ -1143,7 +1204,8 @@ class RubyLex
|
|
1143
1204
|
read_escape
|
1144
1205
|
end
|
1145
1206
|
else
|
1146
|
-
# other characters
|
1207
|
+
# other characters
|
1147
1208
|
end
|
1148
1209
|
end
|
1149
1210
|
end
|
1211
|
+
# :startdoc:
|