rubylexer 0.7.6 → 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -37,11 +37,32 @@ class SymbolTable
37
37
  list or raise "unbalanced end block"
38
38
  list.each_key {|sym|
39
39
  @symbols[sym].pop
40
- @symbols[sym].empty? and @symbols[sym]=nil
40
+ @symbols[sym].empty? and @symbols.delete sym
41
41
  }
42
42
  assert @locals_lists.last
43
43
  end
44
44
 
45
+ def deep_copy
46
+ result=SymbolTable.allocate
47
+ new_symbols={}
48
+ @symbols.each_pair{|str,stack|
49
+ new_symbols[str.clone]=stack.map{|elem| elem.clone rescue elem }
50
+ }
51
+ new_locals_lists=[]
52
+ @locals_lists.each{|hash|
53
+ new_locals_lists.push({})
54
+ hash.each_pair{|str,bool|
55
+ new_locals_lists.last[str.dup]=bool
56
+ }
57
+ }
58
+ new_locals_lists.push({}) if new_locals_lists.empty?
59
+ result.instance_eval{
60
+ @symbols=new_symbols
61
+ @locals_lists=new_locals_lists
62
+ }
63
+ return result
64
+ end
65
+
45
66
  def names
46
67
  @symbols.keys
47
68
  end
@@ -3,6 +3,23 @@ def x; yield end #this must be first!!!!
3
3
  #modifying the list of known local variables. it may be omitted
4
4
  #in cases where it is known that no local vars are defined.
5
5
 
6
+ module A 55 end
7
+ module Array([Array]).first::E; end
8
+ module Array ([Array]).first::E; end
9
+ module Array([Array]).first::E include M; end
10
+ module Array ([Array]).first::E include M; end
11
+ module Array([Array]).first::E include M end
12
+ module Array ([Array]).first::E include M end
13
+ x{a=Array; module a::Foo; 55 end}
14
+ x{a=Array; module a::Foo include a; 55 end}
15
+ x{a=Array; module a::Foo include a; a end}
16
+ module a.b.c.d.e.f::Quux; YYY=534 end
17
+ module[Array][0]::Foo; Bazz=556 end
18
+
19
+ module(@a)::Foo; Bar=111 end
20
+
21
+ module@x::Foo; Bar=1 end
22
+
6
23
  module A::B; end
7
24
 
8
25
  p a rescue b
@@ -499,6 +516,9 @@ def ~@; :foo end
499
516
  undef ~@
500
517
  alias ~@ non
501
518
  alias non ~@
519
+ undef :~@
520
+ alias :~@ non
521
+ alias non :~@
502
522
  p :~@
503
523
  a.~@
504
524
  a::~@
@@ -0,0 +1,146 @@
1
+ module Ruby1_9OneLiners
2
+ EXPECT_NO_METHODS=[ #no errors either
3
+ '->a; h do 123 end',
4
+ '->{}',
5
+ '-> {}',
6
+ '->;{}',
7
+ '->(;){}',
8
+ '->a{}',
9
+ '->a {}',
10
+ '->a;{}',
11
+ '->(a;){}',
12
+ '->a,b{}',
13
+ '->a,b;{}',
14
+ '->a,b;c{}',
15
+ '->(a,b;){}',
16
+ '->(a,b;c){}',
17
+ '$f.($x,$y)',
18
+ '$f::($x,$y)',
19
+ '__ENCODING__',
20
+ '__ENCODING__ +"foo"',
21
+ 'module __ENCODING__::A; end',
22
+ '/(?<foo>bar)/ =~ "baz"; foo +1',
23
+ "/(?'foo'bar)/ =~ 'baz'; foo +1",
24
+ '/\\\\(?<foo>bar)/ =~ "baz"; foo +1',
25
+ "/\\\\(?'foo'bar)/ =~ 'baz'; foo +1",
26
+ '/\\c\\(?<foo>bar)/ =~ "baz"; foo +1',
27
+ "/\\c\\(?'foo'bar)/ =~ 'baz'; foo +1",
28
+ '/\\\\c(?<foo>bar)/ =~ "baz"; foo +1',
29
+ "/\\\\c(?'foo'bar)/ =~ 'baz'; foo +1",
30
+ '/\\C-\\(?<foo>bar)/ =~ "baz"; foo +1',
31
+ "/\\C-\\(?'foo'bar)/ =~ 'baz'; foo +1",
32
+ '/\\\\C-(?<foo>bar)/ =~ "baz"; foo +1',
33
+ "/\\\\C-(?'foo'bar)/ =~ 'baz'; foo +1",
34
+ '/\\(?#(?<foo>bar))/ =~ "baz"; foo +1',
35
+ "/\\(?#(?'foo'bar))/ =~ 'baz'; foo +1",
36
+ '/\\[(?<foo>bar)]/ =~ "baz"; foo +1',
37
+ "/\\[(?'foo'bar)]/ =~ 'baz'; foo +1",
38
+
39
+ '/z(?<foo>bar)/ =~ "baz"; foo +1',
40
+ "/z(?'foo'bar)/ =~ 'baz'; foo +1",
41
+ '/z\\\\(?<foo>bar)/ =~ "baz"; foo +1',
42
+ "/z\\\\(?'foo'bar)/ =~ 'baz'; foo +1",
43
+ '/z\\c\\(?<foo>bar)/ =~ "baz"; foo +1',
44
+ "/z\\c\\(?'foo'bar)/ =~ 'baz'; foo +1",
45
+ '/z\\\\c(?<foo>bar)/ =~ "baz"; foo +1',
46
+ "/z\\\\c(?'foo'bar)/ =~ 'baz'; foo +1",
47
+ '/z\\C-\\(?<foo>bar)/ =~ "baz"; foo +1',
48
+ "/z\\C-\\(?'foo'bar)/ =~ 'baz'; foo +1",
49
+ '/z\\\\C-(?<foo>bar)/ =~ "baz"; foo +1',
50
+ "/z\\\\C-(?'foo'bar)/ =~ 'baz'; foo +1",
51
+ '/z\\(?#(?<foo>bar))/ =~ "baz"; foo +1',
52
+ "/z\\(?#(?'foo'bar))/ =~ 'baz'; foo +1",
53
+ '/z\\[(?<foo>bar)]/ =~ "baz"; foo +1',
54
+ "/z\\[(?'foo'bar)]/ =~ 'baz'; foo +1",
55
+ ]
56
+
57
+ EXPECT_1_METHOD=[
58
+ 'def self.foo; 1 end',
59
+ '->{ foo=1 }; foo',
60
+ '->do foo=1 end; foo',
61
+ 'def __FILE__.foo; 1 end',
62
+ 'def __LINE__.foo; 1 end',
63
+ 'def a(b,*c,d) 1 end',
64
+ 'def a(*c,d) 1 end',
65
+ 'def Z::a(b,*c,d) 1 end',
66
+ 'def Z::a(*c,d) 1 end',
67
+ 'a{|b,*c,d| 1 }',
68
+ 'a{|*c,d| 1 }',
69
+ 'def a(b,(x,y),d) 1 end',
70
+ 'def a((x,y),d) 1 end',
71
+ 'def Z::a(b,(x,y),d) 1 end',
72
+ 'def Z::a((x,y),d) 1 end',
73
+ 'a{|b,(x,y),d| 1 }',
74
+ 'a{|(x,y),d| 1 }',
75
+ 'def a(b,(x,*y),d) 1 end',
76
+ 'def a((x,*y),d) 1 end',
77
+ 'def Z::a(b,(x,*y),d) 1 end',
78
+ 'def Z::a((x,*y),d) 1 end',
79
+ 'a{|b,(x,*y),d| 1 }',
80
+ 'a{|(x,*y),d| 1 }',
81
+ 'def a(b,(x,(y,z)),d) 1 end',
82
+ 'def a((x,(y,z)),d) 1 end',
83
+ 'def Z::a(b,(x,(y,z)),d) 1 end',
84
+ 'def Z::a((x,(y,z)),d) 1 end',
85
+ 'a{|b,(x,(y,z)),d| 1 }',
86
+ 'a{|(x,(y,z)),d| 1 }',
87
+ 'module __ENCODING__::A include B; end',
88
+ 'def __ENCODING__; 342 end',
89
+ 'def __ENCODING__.foo; 1 end',
90
+ 'def Z::__ENCODING__; 342 end',
91
+ #'def Z::__ENCODING__.foo; 1 end', #oops, 2 methods here
92
+ '/\\(?<foo>bar)/ =~ "baz"; foo +1',
93
+ "/\\(?'foo'bar)/ =~ 'baz'; foo +1",
94
+ '/\\c(?<foo>bar)/ =~ "baz"; foo +1',
95
+ "/\\c(?'foo'bar)/ =~ 'baz'; foo +1",
96
+ '/\\C-(?<foo>bar)/ =~ "baz"; foo +1',
97
+ "/\\C-(?'foo'bar)/ =~ 'baz'; foo +1",
98
+ '/\\M-(?<foo>bar)/ =~ "baz"; foo +1',
99
+ "/\\M-(?'foo'bar)/ =~ 'baz'; foo +1",
100
+ '/\\\\\\(?<foo>bar)/ =~ "baz"; foo +1',
101
+ "/\\\\\\(?'foo'bar)/ =~ 'baz'; foo +1",
102
+ '/\\\\c\\(?<foo>bar)/ =~ "baz"; foo +1',
103
+ "/\\\\c\\(?'foo'bar)/ =~ 'baz'; foo +1",
104
+ '/(?#(?<foo>bar))/ =~ "baz"; foo +1',
105
+ "/(?#(?'foo'bar))/ =~ 'baz'; foo +1",
106
+ '/[(?<foo>bar)]/ =~ "baz"; foo +1',
107
+ "/[(?'foo'bar)]/ =~ 'baz'; foo +1",
108
+ '/[qwe&&[^ty](?<foo>bar)]/ =~ "baz"; foo +1',
109
+ "/[qwe&&[^ty](?'foo'bar)]/ =~ 'baz'; foo +1",
110
+ '/[qwe&&[^(?<foo>bar)]]/ =~ "baz"; foo +1',
111
+ "/[qwe&&[^(?'foo'bar)]]/ =~ 'baz'; foo +1",
112
+ '/[qwe&&[^ty&&[^uip]](?<foo>bar)]/ =~ "baz"; foo +1',
113
+ "/[qwe&&[^ty&&[^uip]](?'foo'bar)]/ =~ 'baz'; foo +1",
114
+ '/[qwe&&[^ty&&[^uip](?<foo>bar)]]/ =~ "baz"; foo +1',
115
+ "/[qwe&&[^ty&&[^uip](?'foo'bar)]]/ =~ 'baz'; foo +1",
116
+ '/[qwe&&[^ty&&[^uip(?<foo>bar)]]]/ =~ "baz"; foo +1',
117
+ "/[qwe&&[^ty&&[^uip(?'foo'bar)]]]/ =~ 'baz'; foo +1",
118
+
119
+ '/z\\(?<foo>bar)/ =~ "baz"; foo +1',
120
+ "/z\\(?'foo'bar)/ =~ 'baz'; foo +1",
121
+ '/z\\c(?<foo>bar)/ =~ "baz"; foo +1',
122
+ "/z\\c(?'foo'bar)/ =~ 'baz'; foo +1",
123
+ '/z\\C-(?<foo>bar)/ =~ "baz"; foo +1',
124
+ "/z\\C-(?'foo'bar)/ =~ 'baz'; foo +1",
125
+ '/z\\M-(?<foo>bar)/ =~ "baz"; foo +1',
126
+ "/z\\M-(?'foo'bar)/ =~ 'baz'; foo +1",
127
+ '/z\\\\\\(?<foo>bar)/ =~ "baz"; foo +1',
128
+ "/z\\\\\\(?'foo'bar)/ =~ 'baz'; foo +1",
129
+ '/z\\\\c\\(?<foo>bar)/ =~ "baz"; foo +1',
130
+ "/z\\\\c\\(?'foo'bar)/ =~ 'baz'; foo +1",
131
+ '/z(?#(?<foo>bar))/ =~ "baz"; foo +1',
132
+ "/z(?#(?'foo'bar))/ =~ 'baz'; foo +1",
133
+ '/z[(?<foo>bar)]/ =~ "baz"; foo +1',
134
+ "/z[(?'foo'bar)]/ =~ 'baz'; foo +1",
135
+ '/z[qwe&&[^ty](?<foo>bar)]/ =~ "baz"; foo +1',
136
+ "/z[qwe&&[^ty](?'foo'bar)]/ =~ 'baz'; foo +1",
137
+ '/z[qwe&&[^(?<foo>bar)]]/ =~ "baz"; foo +1',
138
+ "/z[qwe&&[^(?'foo'bar)]]/ =~ 'baz'; foo +1",
139
+ '/z[qwe&&[^ty&&[^uip]](?<foo>bar)]/ =~ "baz"; foo +1',
140
+ "/z[qwe&&[^ty&&[^uip]](?'foo'bar)]/ =~ 'baz'; foo +1",
141
+ '/z[qwe&&[^ty&&[^uip](?<foo>bar)]]/ =~ "baz"; foo +1',
142
+ "/z[qwe&&[^ty&&[^uip](?'foo'bar)]]/ =~ 'baz'; foo +1",
143
+ '/z[qwe&&[^ty&&[^uip(?<foo>bar)]]]/ =~ "baz"; foo +1',
144
+ "/z[qwe&&[^ty&&[^uip(?'foo'bar)]]]/ =~ 'baz'; foo +1",
145
+ ]
146
+ end
@@ -8,9 +8,13 @@ module TestCases
8
8
  ILLEGAL_STANZAS=IO.read(rldir+'/rubylexer/test/illegal_stanzas.rb').split("\n\n").grep(/./).reverse
9
9
 
10
10
  datadir=$:.find{|dir| File.exist? dir+'/../test/data/p.rb' }
11
- FILENAMES=Dir[datadir+'/../test/data/*'].reject{|fn| File.directory? fn}
11
+ FILENAMES=Dir[datadir+'/../test/data/*.rb'].reject{|fn| File.directory? fn}
12
12
  FILES=FILENAMES.map{|fn| File.read fn }
13
13
 
14
+ ILLEGAL_FILENAMES=(Dir[datadir+'/../test/data/*']-Dir[datadir+'/../test/data/*.rb'])
15
+ ILLEGAL_FILENAMES.reject!{|fn| File.directory? fn}
16
+ ILLEGAL_FILES=ILLEGAL_FILENAMES.map{|fn| File.read fn }
17
+
14
18
  TESTCASES=ONELINERS+STANZAS+FILES
15
- ILLEGAL_TESTCASES=ILLEGAL_ONELINERS+ILLEGAL_STANZAS
19
+ ILLEGAL_TESTCASES=ILLEGAL_ONELINERS+ILLEGAL_STANZAS+ILLEGAL_FILES
16
20
  end
@@ -63,17 +63,24 @@ class KeywordToken < WToken #also some operators
63
63
  @callsite if defined? @callsite
64
64
  end
65
65
 
66
+ attr_accessor :value
66
67
 
67
68
  #-----------------------------------
68
69
  def set_infix!
69
70
  @infix=true
70
71
  end
71
72
 
73
+ #-----------------------------------
74
+ def unary= flag
75
+ @infix=!flag
76
+ end
77
+
72
78
  #-----------------------------------
73
79
  def infix?
74
80
  @infix ||= nil
75
81
  end
76
82
  def prefix?; !infix? end
83
+ alias unary prefix?
77
84
 
78
85
  #-----------------------------------
79
86
  def has_end!
@@ -103,9 +110,16 @@ end
103
110
  #-------------------------
104
111
  class OperatorToken < WToken
105
112
  attr_accessor :unary
113
+ attr_writer :as
106
114
  alias prefix? unary
107
115
  def infix?; !prefix? end
108
116
 
117
+ def as
118
+ return @as if defined? @as
119
+ if tag and ident[/^[,*&]$/]
120
+ tag.to_s+ident
121
+ end
122
+ end
109
123
  end
110
124
 
111
125
 
@@ -212,6 +226,8 @@ class StringToken < Token
212
226
 
213
227
  attr_accessor :open #exact sequence of chars used to start the str
214
228
  attr_accessor :close #exact seq of (1) char to stop the str
229
+
230
+ attr_accessor :lvars #names used in named backrefs if this is a regex
215
231
 
216
232
  def with_line(line)
217
233
  @line=line
@@ -255,16 +271,16 @@ class StringToken < Token
255
271
  ender=close
256
272
  elems.each{|e|
257
273
  case e
258
- when String: result<<e
274
+ when String; result<<e
259
275
  # strfrag=translate_escapes strfrag if RubyLexer::FASTER_STRING_ESCAPES
260
276
  # result << send(transname,strfrag,starter,ender)
261
- when VarNameToken:
277
+ when VarNameToken;
262
278
  if /^[$@]/===e.to_s
263
279
  result << '#' + e.to_s
264
280
  else
265
281
  result << "\#{#{e}}"
266
282
  end
267
- when RubyCode: result << '#' + e.to_s
283
+ when RubyCode; result << '#' + e.to_s
268
284
  else fail
269
285
  end
270
286
  }
@@ -429,7 +445,7 @@ class HerePlaceholderToken < WToken
429
445
 
430
446
  #@termex=/^#{'[\s\v]*' if dash}#{Regexp.escape ender}$/
431
447
  @termex=Regexp.new \
432
- ["^", ('[\s\v]*' if dash), Regexp.escape(ender), "$"].to_s
448
+ ["^", ('[\s\v]*' if dash), Regexp.escape(ender), "$"].join
433
449
  @bodyclass=HereBodyToken
434
450
  end
435
451
 
@@ -442,7 +458,7 @@ class HerePlaceholderToken < WToken
442
458
  else
443
459
  @ender
444
460
  end
445
- return ["<<",@dash,@quote_real&&@quote,result,@quote_real&&@quote].to_s
461
+ return ["<<",@dash,@quote_real&&@quote,result,@quote_real&&@quote].join
446
462
  # else
447
463
  # assert !unsafe_to_use
448
464
  # return @string.to_s
@@ -557,7 +573,7 @@ EndDefHeaderToken=EndHeaderToken
557
573
 
558
574
  #-------------------------
559
575
  class EscNlToken < IgnoreToken
560
- def initialize(filename,linenum,ident="\\\n",offset=nil)
576
+ def initialize(ident,offset,filename=nil,linenum=nil)
561
577
  super(ident,offset)
562
578
  #@char='\\'
563
579
  @filename=filename
@@ -87,9 +87,9 @@ end
87
87
  end end
88
88
  class ZwToken; def ws_munge(tp)
89
89
  case tp.showzw
90
- when 2: explicit_form_all
91
- when 1: explicit_form
92
- when 0: nil
90
+ when 2; explicit_form_all
91
+ when 1; explicit_form
92
+ when 0; nil
93
93
  else raise 'unknown showzw'
94
94
  end
95
95
  end end
@@ -117,7 +117,7 @@ class KeepWsTokenPrinter
117
117
  def pprint(tok,output=$stdout)
118
118
  @accum<<aprint(tok).to_s
119
119
  if (@accum.size>ACCUMSIZE and NewlineToken===tok) or EoiToken===tok
120
- output.print(@accum)
120
+ output.print(@accum.join)
121
121
  @accum=[]
122
122
  end
123
123
  end
@@ -139,10 +139,10 @@ class KeepWsTokenPrinter
139
139
  result=
140
140
  case tok
141
141
  when ZwToken,EoiToken,NoWsToken, HereBodyToken, NewlineToken,
142
- ImplicitParamListStartToken,ImplicitParamListEndToken:
142
+ ImplicitParamListStartToken,ImplicitParamListEndToken;
143
143
  tok
144
144
  else
145
- [@sep.dup,tok]
145
+ @sep.dup<<tok.to_s
146
146
  end unless NoWsToken===lasttok
147
147
 
148
148
  if str_needs_escnls
@@ -1,3 +1,3 @@
1
1
  class RubyLexer
2
- VERSION='0.7.6'
2
+ VERSION='0.7.7'
3
3
  end
@@ -0,0 +1,40 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require "#{File.dirname(__FILE__)}/lib/rubylexer/version"
4
+ RubyLexer::Description=open("README.txt"){|f| f.read[/^==+ ?description[^\n]*?\n *\n?(.*?\n *\n.*?)\n *\n/im,1] }
5
+ RubyLexer::Latest_changes="###"+open("History.txt"){|f| f.read[/\A===(.*?)(?====)/m,1] }
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "rubylexer"
9
+ s.version = RubyLexer::VERSION
10
+ s.date = Time.now.strftime("%Y-%m-%d")
11
+ s.authors = ["Caleb Clausen"]
12
+ s.email = %q{caleb (at) inforadical (dot) net}
13
+ s.summary = "RubyLexer is a lexer library for Ruby, written in Ruby."
14
+ s.description = RubyLexer::Description
15
+ s.homepage = %{http://github.com/coatl/rubylexer}
16
+ s.rubyforge_project = %q{rubylexer}
17
+
18
+ s.files = `git ls-files`.split
19
+ s.test_files = %w[test/test_all.rb]
20
+ s.require_paths = ["lib"]
21
+ s.extra_rdoc_files = ["README.txt", "COPYING"]
22
+ s.has_rdoc = true
23
+ s.rdoc_options = %w[--main README.txt]
24
+
25
+ s.rubygems_version = %q{1.3.0}
26
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
27
+
28
+ if s.respond_to? :specification_version then
29
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
30
+ s.specification_version = 2
31
+
32
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
33
+ s.add_runtime_dependency("sequence", [">= 0.2.3"])
34
+ else
35
+ s.add_dependency("sequence", [">= 0.2.3"])
36
+ end
37
+ else
38
+ s.add_dependency("sequence", [">= 0.2.3"])
39
+ end
40
+ end
@@ -0,0 +1,154 @@
1
+ require 'rubygems'
2
+ require 'rubylexer'
3
+ require 'term/ansicolor'
4
+
5
+
6
+ def coloruby file,fd=open(file)
7
+ lexer=RubyLexer.new(file,fd)
8
+ begin
9
+ token=lexer.get1token
10
+ print token.colorize
11
+ end until RubyLexer::EoiToken===token
12
+ ensure
13
+ print Term::ANSIColor.reset
14
+ end
15
+
16
+ class RubyLexer
17
+ class Token
18
+ include Term::ANSIColor
19
+
20
+ def colorize
21
+ color+ident.to_s
22
+ end
23
+ end
24
+
25
+ class VarNameToken
26
+ alias color blue
27
+ end
28
+
29
+ class MethNameToken
30
+ alias color green
31
+ end
32
+
33
+ class OperatorToken
34
+ alias color cyan
35
+ end
36
+
37
+ class KeywordToken
38
+ def colorize
39
+ if /[^a-z]/i===ident
40
+ yellow+ident
41
+ else
42
+ red+ident
43
+ end
44
+ end
45
+ end
46
+
47
+ class WsToken
48
+ def colorize
49
+ black+ident
50
+ end
51
+ end
52
+
53
+ class NewlineToken
54
+ alias color black
55
+ end
56
+
57
+ class ZwToken
58
+ def colorize; '' end
59
+ end
60
+
61
+ class FileAndLineToken
62
+ def colorize; '' end
63
+ end
64
+
65
+ class ImplicitParamListStartToken
66
+ def colorize; '' end
67
+ end
68
+
69
+ class ImplicitParamListEndToken
70
+ def colorize; '' end
71
+ end
72
+
73
+ class IgnoreToken
74
+ def colorize
75
+ dark+green+ident+reset
76
+ end
77
+ end
78
+
79
+ class EscNlToken
80
+ def colorize
81
+ yellow+ident
82
+ end
83
+ end
84
+
85
+ class NumberToken
86
+ def colorize
87
+ dark+blue+ident+reset
88
+ end
89
+ end
90
+
91
+ class SymbolToken
92
+ def colorize
93
+ if StringToken===ident
94
+ dark+blue+':'+ident.colorize+reset
95
+ else
96
+ dark+blue+ident+reset
97
+ end
98
+ end
99
+ end
100
+
101
+ class StringToken
102
+ def colorize
103
+ magenta+open+
104
+ elems.map{|elem|
105
+ if String===elem
106
+ magenta+elem
107
+ else
108
+ yellow+'#'+elem.colorize
109
+ end
110
+ }.join+
111
+ magenta+close
112
+ end
113
+ end
114
+
115
+ class RubyCode
116
+ def colorize
117
+ ident.map{|tok| tok.colorize }.join
118
+ end
119
+ end
120
+
121
+ class HerePlaceholderToken
122
+ def colorize
123
+ "#{blue}<<#{'-' if @dash}#{ender}"
124
+ end
125
+ end
126
+
127
+ class HereBodyToken
128
+ def colorize
129
+ headtok.string.colorize
130
+ end
131
+ end
132
+
133
+ class EoiToken
134
+ def colorize
135
+ return '' #gyaah, @offset has off by one errors
136
+ data=begin
137
+ @file.pos=@offset-1
138
+ @file.read
139
+ rescue
140
+ @file[@offset-1..-1]
141
+ end
142
+ dark+green+data+reset
143
+ end
144
+ end
145
+ end
146
+
147
+ if __FILE__==$0
148
+ if ARGV.first=='-e'
149
+ coloruby ARGV[1],ARGV[1]
150
+ else
151
+ coloruby ARGV.first
152
+ end
153
+ end
154
+