YkLib 0.1.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 (125) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +7 -0
  7. data/Gemfile.lock +34 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +44 -0
  10. data/Rakefile +6 -0
  11. data/YkLib.gemspec +29 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/lib/YkLib/Yk/__advance__.rb +151 -0
  15. data/lib/YkLib/Yk/__defun__.rb +44 -0
  16. data/lib/YkLib/Yk/__hook__.rb +244 -0
  17. data/lib/YkLib/Yk/__minmax__.rb +123 -0
  18. data/lib/YkLib/Yk/__stdlog.rb +329 -0
  19. data/lib/YkLib/Yk/adhocLiterals/email.rb +119 -0
  20. data/lib/YkLib/Yk/adhocLiterals/path.rb +402 -0
  21. data/lib/YkLib/Yk/adhocLiterals/tag.rb +19 -0
  22. data/lib/YkLib/Yk/adhocLiterals/url.rb +36 -0
  23. data/lib/YkLib/Yk/adhocLiterals.rb +199 -0
  24. data/lib/YkLib/Yk/auto_escseq.rb +5 -0
  25. data/lib/YkLib/Yk/auto_pstore.rb +179 -0
  26. data/lib/YkLib/Yk/bsearch.rb +120 -0
  27. data/lib/YkLib/Yk/clambda.rb +309 -0
  28. data/lib/YkLib/Yk/confLine.rb +423 -0
  29. data/lib/YkLib/Yk/create_tty_width_available.rb +24 -0
  30. data/lib/YkLib/Yk/crypt.rb +26 -0
  31. data/lib/YkLib/Yk/debug2 +1 -0
  32. data/lib/YkLib/Yk/debug2.rb +473 -0
  33. data/lib/YkLib/Yk/debugout.rb +139 -0
  34. data/lib/YkLib/Yk/email_tz.rb +533 -0
  35. data/lib/YkLib/Yk/enum_expect.rb +170 -0
  36. data/lib/YkLib/Yk/errlog.rb +5 -0
  37. data/lib/YkLib/Yk/escseq.rb +59 -0
  38. data/lib/YkLib/Yk/eval_alt.rb +281 -0
  39. data/lib/YkLib/Yk/expector.rb +93 -0
  40. data/lib/YkLib/Yk/fetch.rb +556 -0
  41. data/lib/YkLib/Yk/fetch_old.rb +290 -0
  42. data/lib/YkLib/Yk/fib.rb +158 -0
  43. data/lib/YkLib/Yk/file_aux.rb +843 -0
  44. data/lib/YkLib/Yk/file_aux2.rb +919 -0
  45. data/lib/YkLib/Yk/file_aux_old.rb +160 -0
  46. data/lib/YkLib/Yk/filemod.rb +19 -0
  47. data/lib/YkLib/Yk/force_escseq.rb +3 -0
  48. data/lib/YkLib/Yk/generator__.rb +144 -0
  49. data/lib/YkLib/Yk/generator__.rb.org +139 -0
  50. data/lib/YkLib/Yk/indenter/argless_case.rb +46 -0
  51. data/lib/YkLib/Yk/indenter/each_token.rb +671 -0
  52. data/lib/YkLib/Yk/indenter/free_case.rb +313 -0
  53. data/lib/YkLib/Yk/indenter/if_less.rb +53 -0
  54. data/lib/YkLib/Yk/indenter/independent_ensure.rb +23 -0
  55. data/lib/YkLib/Yk/indenter/independent_rescue.rb +23 -0
  56. data/lib/YkLib/Yk/indenter/operand_circumflex.rb +0 -0
  57. data/lib/YkLib/Yk/indenter/operand_period.rb +16 -0
  58. data/lib/YkLib/Yk/indenter/parenless_and.rb +37 -0
  59. data/lib/YkLib/Yk/indenter/post_test.rb +48 -0
  60. data/lib/YkLib/Yk/indenter/token.rb +1525 -0
  61. data/lib/YkLib/Yk/indenter.rb +1382 -0
  62. data/lib/YkLib/Yk/inot.rb +265 -0
  63. data/lib/YkLib/Yk/intf.rb +815 -0
  64. data/lib/YkLib/Yk/io_aux.rb +1332 -0
  65. data/lib/YkLib/Yk/ioctl.rb +60 -0
  66. data/lib/YkLib/Yk/ipcc.rb +87 -0
  67. data/lib/YkLib/Yk/ipcountry.rb +207 -0
  68. data/lib/YkLib/Yk/ipv4adr.rb +318 -0
  69. data/lib/YkLib/Yk/localmail.rb +276 -0
  70. data/lib/YkLib/Yk/method_chain.rb +359 -0
  71. data/lib/YkLib/Yk/misc_tz.rb +1716 -0
  72. data/lib/YkLib/Yk/missing_method.rb +50 -0
  73. data/lib/YkLib/Yk/mojiConv.rb +257 -0
  74. data/lib/YkLib/Yk/nostdlog.rb +4 -0
  75. data/lib/YkLib/Yk/on_marshal.rb +20 -0
  76. data/lib/YkLib/Yk/overrider.rb +47 -0
  77. data/lib/YkLib/Yk/path.rb +293 -0
  78. data/lib/YkLib/Yk/path_aux.rb +883 -0
  79. data/lib/YkLib/Yk/path_aux_alt.rb +0 -0
  80. data/lib/YkLib/Yk/path_rep.rb +1267 -0
  81. data/lib/YkLib/Yk/pg_setup.rb +917 -0
  82. data/lib/YkLib/Yk/procinfo.rb +314 -0
  83. data/lib/YkLib/Yk/proclist.rb +492 -0
  84. data/lib/YkLib/Yk/property.rb +863 -0
  85. data/lib/YkLib/Yk/ranger.rb +606 -0
  86. data/lib/YkLib/Yk/resolv_tz.rb +88 -0
  87. data/lib/YkLib/Yk/rlprompt.rb +73 -0
  88. data/lib/YkLib/Yk/rootexec.rb +48 -0
  89. data/lib/YkLib/Yk/rpm-packageproxy.rb +784 -0
  90. data/lib/YkLib/Yk/rpm-packageproxy2.rb +1430 -0
  91. data/lib/YkLib/Yk/rwhen.rb +21 -0
  92. data/lib/YkLib/Yk/selector.rb +124 -0
  93. data/lib/YkLib/Yk/set.rb +170 -0
  94. data/lib/YkLib/Yk/shellquote.rb +300 -0
  95. data/lib/YkLib/Yk/sio.rb +1001 -0
  96. data/lib/YkLib/Yk/sio0.rb +835 -0
  97. data/lib/YkLib/Yk/sio_aux.rb +1524 -0
  98. data/lib/YkLib/Yk/sio_inot.rb +86 -0
  99. data/lib/YkLib/Yk/sock_aux.rb +42 -0
  100. data/lib/YkLib/Yk/spipe.rb +843 -0
  101. data/lib/YkLib/Yk/sql_table.rb +565 -0
  102. data/lib/YkLib/Yk/stdlog.rb +4 -0
  103. data/lib/YkLib/Yk/syscommand.rb +173 -0
  104. data/lib/YkLib/Yk/sysinit.rb +75 -0
  105. data/lib/YkLib/Yk/ttyFontWidth.rb +46113 -0
  106. data/lib/YkLib/Yk/tty_char.dump +0 -0
  107. data/lib/YkLib/Yk/tty_char.rb +47 -0
  108. data/lib/YkLib/Yk/tty_char_create.rb +437031 -0
  109. data/lib/YkLib/Yk/tty_char_static.rb +437016 -0
  110. data/lib/YkLib/Yk/tty_rewrite.rb +142 -0
  111. data/lib/YkLib/Yk/tty_str.rb +461 -0
  112. data/lib/YkLib/Yk/tty_width.dat.rb +114 -0
  113. data/lib/YkLib/Yk/tty_width.rb +180 -0
  114. data/lib/YkLib/Yk/tty_width_available +569 -0
  115. data/lib/YkLib/Yk/tty_width_list +0 -0
  116. data/lib/YkLib/Yk/tty_width_list.linux +280 -0
  117. data/lib/YkLib/Yk/tty_width_list.windows +324 -0
  118. data/lib/YkLib/Yk/tz_tty +0 -0
  119. data/lib/YkLib/Yk/tz_tty.rb +0 -0
  120. data/lib/YkLib/Yk/uprepos.rb +94 -0
  121. data/lib/YkLib/Yk/userinfo.rb +91 -0
  122. data/lib/YkLib/Yk/with.rb +109 -0
  123. data/lib/YkLib/version.rb +3 -0
  124. data/lib/YkLib.rb +6 -0
  125. metadata +170 -0
@@ -0,0 +1,1382 @@
1
+
2
+ require 'binding_of_caller'
3
+
4
+ require 'Yk/indenter/token'
5
+
6
+ require 'Yk/eval_alt'
7
+ require 'Yk/adhocLiterals'
8
+
9
+
10
+ class << self
11
+ alias __org_using__ using
12
+ def using *args
13
+ GrammerExt::using *args
14
+ end
15
+ end
16
+
17
+ module Kernel
18
+ p 123123
19
+ alias __org_require__ require
20
+ module_function
21
+ def require *args #second load
22
+ begin
23
+ p :require, args
24
+ ret = __org_require__ *args
25
+ p :require_finish, args
26
+ ret
27
+ rescue GrammerExt::RequireFinished
28
+ p "finish", args
29
+ end
30
+ end
31
+ def __get_args__ *args, **opts
32
+ args, opts
33
+ end
34
+ end
35
+
36
+ class BasicObject
37
+ def __translate__ expr, f, lno, bl = nil, :mode = :eval, this = nil
38
+ ....
39
+ expr
40
+ end
41
+ end
42
+
43
+ class GrammerExt
44
+ class RequireFinished < Exception
45
+ end
46
+ UsedFrom = {}
47
+ def self.usedFrom grammers, f, lno, b
48
+ lns = IO.readlines f
49
+ p [:exec, f, lno + 1]
50
+ p lns[lno + 1 .. lno + 10].join
51
+ mod.doEval(lns[lno + 1 .. -1].join, f, lno + 2)
52
+ p [:exec_finish, f, lno + 1]
53
+ if !(binding.of_caller(2) rescue nil)
54
+ p :exitting
55
+ exit 0
56
+ else
57
+ raise RequireFinished.new("finished")
58
+ end
59
+ end
60
+ def self.using *args, **opts
61
+ args.flatten!
62
+ p :bbbbbbbbbbbb
63
+ b = binding.of_caller(2)
64
+ mods = []
65
+ if !UsedFrom.key? f
66
+ grammers = []
67
+ f, lno = b.source_location
68
+ p [f, lno, :require]
69
+ f = File.expand_path(f)
70
+ lno = lno.to_i - 1
71
+ hasGram = false
72
+ args.each do |arg|
73
+ if arg.is_a?(GrammerExt)
74
+ if !(UsedFrom[f] ||= {}).key? arg
75
+ UsedFrom[f][arg] ||= true
76
+ grammers.push arg
77
+ end
78
+ else
79
+ mods.push arg
80
+ end
81
+ end
82
+ if !grammers.empty?
83
+ lns = IO.readlines f
84
+ p [:exec, f, lno + 1]
85
+ p lns[lno + 1 .. lno + 10].join
86
+ doEval(mods, grammers, opts, lns[lno + 1, -1], f, lno, b)
87
+ if !(binding.of_caller(3) rescue nil)
88
+ p :exitting
89
+ exit 0
90
+ else
91
+ raise RequireFinished.new("finished")
92
+ end
93
+ end
94
+ else
95
+ args.each do |arg|
96
+ if arg.is_a?(GrammerExt)
97
+ if !(UsedFrom[f] ||= {}).key? arg
98
+ raise ArgumentError.new("already used grammer, #{arg.inspect}")
99
+ end
100
+ else
101
+ mods.push arg
102
+ end
103
+ end
104
+ end
105
+ mods.each do |m|
106
+ b.eval("__org_using__ ::ObjectSpace.__id2ref(#{m.__id__})")
107
+ end
108
+ end
109
+ def self.doEval modules, grammers, opts, toEval, f, lno, b
110
+ start = 0
111
+ lns = toEval.lines
112
+ firstLine = lns.shift
113
+ if firstLine !~ /^\s*using\b([^<"'%]*)(#|$)/
114
+ raise ArgumentError.new("using a grammer, cannot contain any literal expressions")
115
+ end
116
+ lns.each_line do |ln|
117
+ #process first using for each GrammerExt
118
+ case ln
119
+ when /^\s*using\b([^<"'%/`]*)(#|$)/
120
+ begin
121
+ args, nopts = TOPLEVEL_BINDING.eval("__get_args__(" + $1 + ")").flatten
122
+ opts.merge nopts
123
+ args.each do |e|
124
+ if e.is_a? GrammerExt
125
+ if !grammers.include? e
126
+ grammers.push e
127
+ end
128
+ else
129
+ if !modules.include? e
130
+ modules.push e
131
+ end
132
+ end
133
+ end
134
+ rescue
135
+ break
136
+ end
137
+ when /^\s*(#|$)/
138
+ else
139
+ break
140
+ end
141
+ start += 1
142
+ end
143
+ toEval = lns[start .. -1].join
144
+ modules.each do |m|
145
+ b.eval("__org_using__ ::ObjectSpace.__id2ref(#{m.__id__})")
146
+ end
147
+ grammers.each do |g|
148
+ toEval = g.translate(opts, toEval, f, lno + start)
149
+ end
150
+ TOPLEVEL_BINDING.eval(toEval, f, lno + start)
151
+ end
152
+ def initialize name
153
+ @name = name
154
+ end
155
+ def inspect
156
+ @name
157
+ end
158
+ def to_s
159
+ @name
160
+ end
161
+ end
162
+
163
+ class Indenter < GrammerExt
164
+ def getTranslateOptions opts
165
+ ::AdhocLiterals.resolveRequirement opts
166
+ end
167
+ class CaseCondList
168
+ def initialize vn, cn
169
+ @vn = vn
170
+ @cn = cn
171
+ @list = []
172
+ end
173
+ def add c
174
+ @list.push c
175
+ end
176
+ def head
177
+ <<~Out
178
+ #{@vn}.pushCondProxy
179
+ begin
180
+ begin
181
+ #{getSubHead}
182
+ rescue #{@vn}.FinishCond
183
+ end
184
+ if #{@vn}.hasTrue?
185
+ Out
186
+ end
187
+ def getSubHead
188
+ emb = ""
189
+ @list.each do |e|
190
+ if e.is_a? CaseCondList
191
+ emb += e.getSubHead
192
+ else
193
+ case e
194
+ when /\A(when|in)\b/
195
+ emb += <<~Out
196
+ if case #{@vn}.case #{e}; true; else false end
197
+ #{@vn}.pushCond true
198
+ #{@vn}.finishCond
199
+ else
200
+ #{@vn}.pushCond false
201
+ end
202
+ Out
203
+ when /\Afor\b/
204
+ emb += <<~Out
205
+ if case #{@vn}.case when #{$'}; true; else false end
206
+ #{@vn}.pushCond true
207
+ else
208
+ #{@vn}.pushCond false
209
+ end
210
+ Out
211
+ end
212
+ end
213
+ end
214
+ emb
215
+ end
216
+ def tail
217
+ emb += <<~Out
218
+ #{
219
+ if ["when", "in"].include? @cn
220
+ #{@vn}.finish
221
+ end
222
+ }
223
+ end # if #{@vn}.hasTrue?
224
+ ensure
225
+ #{@vn}.popCondProxy
226
+ end
227
+ Out
228
+ end
229
+ end
230
+ class TranslationError << Exception
231
+ end
232
+ class Restart << Exception
233
+ end
234
+ RBRACE_MODE = StrBegin + [:bare, :path]
235
+ def getOpponent c
236
+ case c
237
+ when ?{
238
+ ?}
239
+ when ?[
240
+ ?]
241
+ when ?(
242
+ ?)
243
+ when ?}
244
+ ?{
245
+ when ?]
246
+ ?[
247
+ when ?)
248
+ ?(
249
+ when ?<
250
+ ?>
251
+ when ?>
252
+ ?<
253
+ end
254
+ end
255
+ def getLno pos
256
+ @lnoBase + @expr.count_until("\n", pos)
257
+ end
258
+ def getStringEndExceptSlash pos
259
+ lnoBase = getLno(pos)
260
+ self.class.new @expr[pos .. - 1], @@opts, @@fName, lnoBase, :path_quote do |qed|
261
+ if qed
262
+ return pos + qed
263
+ else
264
+ return nil
265
+ end
266
+ end
267
+ end
268
+ def getClosing pos
269
+ open = @expr[pos]
270
+ close = getOpponent open
271
+ s = 0
272
+ while o = @expr[i]
273
+ case o
274
+ when open #orphan
275
+ s += 1
276
+ break
277
+ when close
278
+ s -= 1
279
+ if s == 0
280
+ return i
281
+ end
282
+ when "#" #embeded expression do not allow first ".", "/", "?", "*", "{}", "[]", otherwise use #wpd{...}, w:wild([],{}.?,*), p:period(.), d:directory(/)
283
+ k = checkExtendedEmbExpr(@@expr, i, :path)
284
+ end
285
+ if !k
286
+ i += 1
287
+ else
288
+ i = k + 1
289
+ k = nil
290
+ end
291
+ end
292
+ return nil
293
+ end
294
+ def getOpening pos
295
+ cl = @expr[pos]
296
+ op = getOpponent cl
297
+ pos -= 1
298
+ cnt = 1
299
+ while pos > 0
300
+ case @expr[pos]
301
+ when cl
302
+ cnt += 1
303
+ when op
304
+ cnt -= 1
305
+ if cnt == 0
306
+ return pos
307
+ end
308
+ when "\n"
309
+ if @expr[0..pos - 1] =~ /#.*$/
310
+ end
311
+ end
312
+ pos -= 1
313
+ end
314
+ nil
315
+ end
316
+ def setRegexp start
317
+ [:f_regexp, :regexp].each do |m|
318
+ testExpr = @expr[start .. - 1]
319
+ self.class.new testExpr, @opts, @fName, getLno(start), m do |red|
320
+ if red
321
+ red += start - 1
322
+ @expr[start .. -1] = REGEXP_HEAD + testExpr[0 .. red] + ")" + testExpr[red + 1 .. -1]
323
+ raise Restart.new
324
+ else
325
+ next
326
+ end
327
+ end
328
+ raise Error.new("#{getLno(start)}: cannot find end of regular expression")
329
+ end
330
+ end
331
+ def checkExtendedEmbExpr start, kind = :bare, til = nil
332
+ sr = til ? @expr[start...til] : @expr
333
+ start = sr.index(/#(([^{\s\\]|\\.)*)\{/)&.+(til ? start : 0)
334
+ if start && checkEmbedPrefix(prefix = $1) && $`[/\\*$/].size % 2 == 0
335
+ lbrace_pos = start + prefix.size + 1
336
+ if @expr[lbrace_pos + 1, EMBED_START.size] != EMBED_START
337
+ altExpr = @expr[lbrace_pos .. -1]
338
+ lnoBase = getLno lbrace_pos
339
+ self.class.new altExpr, @opts, @fName, lnoBase, kind do |ed, mode, led, pstack|
340
+ if ed
341
+ pre = "#{EMBED_START}#{' ' * 6}, '#{prefix}', #{mode.inspect}, ("
342
+ post = "))"
343
+ emb = "\#{" + pre + altExpr[1 .. ed - 1] + post + "}"
344
+ emb[EMBED_START.size + 2, 6] = sprintf('%6d', emb.size)
345
+ @expr[start .. -1] = emb + altExpr[ed + 1 .. -1]
346
+ diff = emb.size - ed + start
347
+ case mode
348
+ when :email
349
+ when :path
350
+ pstack.map!{|e| e + diff}
351
+ checkPrevIsPath nil, start, diff + led, pstack
352
+ when :url
353
+ end
354
+ raise Restart.new
355
+ else
356
+ raise Error.new("#{getLno(start)}: cannot find end of embedded expression")
357
+ end
358
+ end
359
+ else
360
+ if @expr.index /\d+/, lbrace_pos + 1 + EMBED_START.size
361
+ return $&.to_i + start
362
+ else
363
+ raise Error.new("#{getLno(start)}: cannot find length of embedded expression")
364
+ end
365
+ end
366
+ else
367
+ nil
368
+ end
369
+ end
370
+ def removeCComment dprev
371
+ tab_stop = @opts[:tab_stop]
372
+ if @expr.index("*/", dprev.first + 2)
373
+ toReplace = @expr[dprev.first .. til + 1]
374
+ rln_pos = toReplace.rindex("\n")
375
+ begin
376
+ if rln_pos
377
+ @expr[dprev.first .. til + 1] = toReplace.count("\n") * (Token.stuffer(:hidden_nl) + "\\\n") + " " * TTYWidth.width toReplace[rln_pos + 1 .. -1], tab_stop, 0
378
+ else
379
+ @expr[dprev.first .. til + 1] = " " * (TTYWidth.width(toReplace[dprev.first .. til + 1], tab_stop, dprev.tty_pos) - dprev.tty_pos)
380
+ end
381
+ rescue ArgumentError
382
+ if t.prevNL || rln_pos
383
+ raise $!
384
+ else
385
+ @expr[dprev.first .. til + 1] = " "
386
+ end
387
+ end
388
+ raise Restart.new
389
+ else
390
+ raise TranslationError.new("unclosed C-style comment : #{t.str} in #{t.lno}:#{t.cno}")
391
+ end
392
+ end
393
+ EMBED_START = "GrammerExt::__embed__("
394
+ REGEXP_HEAD = "GrammerExt::__regexp__("
395
+ def checkEmbedPrefix pfx
396
+ if pfx == "" || pfx =~ /^\w+$/
397
+ true
398
+ elsif pfx =~ /^\W+$/
399
+ pfin = ""
400
+ pfx.each_char do |c|
401
+ if pfin.index c
402
+ return false
403
+ end
404
+ pfin += c
405
+ end
406
+ else
407
+ false
408
+ end
409
+ end
410
+ def themeExpr tk
411
+ case tk
412
+ when :"&."
413
+ "___theme_period"
414
+ when :"::"
415
+ "___theme_double_colon"
416
+ when :on_period
417
+ "___theme_period"
418
+ end
419
+ end
420
+ def initialize expr, opts, f, lnoBase = 0, ebmode = nil
421
+ @lnoBase = lnoBase
422
+ @expr = expr
423
+ @opts = opts
424
+ @fName = f
425
+ case ebmode
426
+ when :f_regexp
427
+ i = 1
428
+ while i = @expr.index(/\/|\#/, i)
429
+ next if $` =~ /\\+$/ && $&.size % 2 == 1
430
+ case @expr[i..-1]
431
+ when /^#(([^{\s\\]|\\.)*)\{/
432
+ begin
433
+ ed = checkExtendedEmbExpr i + $&.size - 1, :on_regexp_beg
434
+ if ed
435
+ i = ed
436
+ end
437
+ rescue Restart
438
+ end
439
+ when /^#.*\n/
440
+ @expr[i] = "\n"
441
+ i = 1
442
+ when /^\/\*.*\*\//m
443
+ @expr[i, $&.size] = " " + "\n" * $&.count("\n")
444
+ i = 1
445
+ when /^\/(\w*)/
446
+ if !$1.include? "x"
447
+ yield nil
448
+ else
449
+ yield i + $&.size - 1
450
+ end
451
+ end
452
+ i += 1
453
+ end
454
+ yield nil #do not return
455
+ when :regexp
456
+ i = 1
457
+ while i = @expr.index(/\/|\#/, i)
458
+ next if $` =~ /\\+$/ && $&.size % 2 == 1
459
+ case @expr[i..-1]
460
+ when /^#(([^{\s\\]|\\.)*)\{/
461
+ begin
462
+ ed = checkExtendedEmbExpr i + $&.size - 1, :on_regexp_beg
463
+ if ed
464
+ i = ed
465
+ end
466
+ rescue Restart
467
+ end
468
+ when /^\/(\w*)/
469
+ yield i + $&.size - 1
470
+ end
471
+ i += 1
472
+ end
473
+ yield nil #do not return
474
+ end
475
+ # tab_stop : 1
476
+ # cjk_width : :mintty, :ms, :xterm
477
+ allTokens = []
478
+ begin
479
+ while true
480
+ t = Token.next expr, opts, f, lnoBase, ebmode
481
+ if t.kind == :/ || (t.kind == :on_regexp_beg && t.str == "/" && (@expr[t.first - REGEXP_HEAD.size, REGEXP_HEAD.size] != REGEXP_HEAD))
482
+ checkPrevIsPath tenum if AdhocLiterals[:path]
483
+ if @expr[t.first + 1] == "*"
484
+ removeCComment dprev if defined?(CComment)
485
+ else
486
+ # regexp
487
+ checkPath t.first if AdhocLiterals[:path]
488
+ # check regexp
489
+ if t.kind == :on_regexp_beg
490
+ setRegexp dprev.first
491
+ end
492
+ end
493
+ end
494
+
495
+ #if (t.dprev&.dprev&.kind == :on_ident && t.dprev.dprev.maybeItertor? || [:while, :do, :until].include?(t.dprev&.dprev&.kind)) \
496
+ #&& [t.dprev&.kind, t.kind] == [:on_symbeg, :on_ident]
497
+ if AdhocLiterals[:url] || AdhocLiterals[:path]
498
+ if [:on_ident, :on_const].include?(t.dprev&.dprev&.kind) && t.dprev.kind == :on_symbeg && t.realToken?
499
+ checkURL t.dprev.dprev.first if AdhocLiterals[:url] || AdhocLiterals[:path]
500
+ end
501
+ if (t.dprev&.kind == :on_label) && t.realToken?
502
+ checkURL t.dprev.first
503
+ end
504
+ end
505
+ if AdhocLiterals[:email] && t.dprev&.kind == :on_ivar && t.dprev.dprev&.str !~ /\s/ && (t.dprev.str.size != 1 || @expr[t.dprev&.first + 1] == "[")
506
+ checkEmail t.dprev&.first
507
+ end
508
+ if AdhocLiterals[:tag] && t&.kind == :< && \
509
+ (c = @expr[t.first + 1];
510
+ c == ?_ \
511
+ || c == ?: \
512
+ || c == ?? \
513
+ || c == ?! \
514
+ || ?a.ord <= c.ord && c.ord <= ?z.ord \
515
+ || ?A.ord <= c.ord && c.ord <= ?Z.ord \
516
+ || 0x70 < c.ord)
517
+ checkTag(t.first)
518
+ end
519
+ if t.kind == :on_tstring_content
520
+ if mode == :path_quote && t.cur.parStack.size == 1 && t.parent.kind == :on_tstring_beg
521
+ if t.str.include "/"
522
+ raise Error.new("path element cannot contain '/'")
523
+ end
524
+ end
525
+ if t.parent.kind == :on_heredoc_beg && t.parent.str !~ /^\<\<(\~|\-|)'(.+)'$/
526
+ k = t.parent.str =~ /\`/ ? :on_backtick : :on_tstring_beg
527
+ elsif StrBegin.include?(t.parent.kind) && !["'", ":'", "%q", "%w", "%i", "%s"].include?(t.parent.str[0, 2])
528
+ k = t.parent.kind
529
+ end
530
+ ep = t.first
531
+ checkExtendedEmbExpr ep, k, ep + t.str.size
532
+ end
533
+ # concatenate path
534
+ mayConcatenatePath t if AdhocLiterals[:path] || AdhocLiterals[:url]
535
+ # insert embedding information although non-extended embed expression
536
+ if t.kind == :on_embexpr_beg
537
+ checkExtendedEmbExpr t.first, t.parent.kind
538
+ end
539
+ case t.kind
540
+ when :on_heredoc_beg
541
+ t.addModAfter SET_LINE
542
+ end
543
+
544
+
545
+ # ./file&{.r?}.open
546
+ # _1.gets
547
+ # braces for hash
548
+
549
+ # foo \n \n : pi
550
+ # goo goo : t
551
+ if defined?(Endless) && (pi = t&.prev) == :on_nl && t.realToken?
552
+ ti = t.cur.idtStack.last
553
+ if !ti
554
+ res = 0 <=> t.tty_pos
555
+ else
556
+ if ti.tty_pos < t.tty_pos
557
+ res = -1 # indent-in
558
+ elsif ti.unindent_pos > t.tty_pos
559
+ res = 1
560
+ else
561
+ res = 0 # same
562
+ end
563
+ end
564
+ if res < 0 # check iterator : indent-in
565
+ s = ti.parStackI&.last&.entity
566
+ case t.prev_non_sp.kind
567
+ when :on_lparen, :on_lbrace, :on_lbracket # t.prev_non_sp == s
568
+ when :"&.", :"::", :on_period #should not be operand, "foo.\n"
569
+ toPush = t.prev_non_sp
570
+ else
571
+ if s&.isStarterAll?
572
+ if s.requireArg? # while if ....
573
+ s.closeSentence pi
574
+ else # if ...;
575
+ # no need
576
+ end
577
+ elsif %i{argless_case_lower argless_case}.include? s&.kind
578
+ s.addArglessCaseLower pi
579
+ else #!s.isStarterAll? # iterator
580
+ if (pi.iteratorMethod = t.parent.iteratorCand)&.setupIteratorLabel
581
+ s.iteratorCand = nil
582
+ else
583
+ raise Error.new("cannot find iterator method for indentation-in")
584
+ end
585
+ end
586
+ toPush = pi # :on_nl, previous line end interpreted as iterator
587
+ end
588
+ if toPush
589
+ toPush.implementStarterMayBrace
590
+ toPush.spush
591
+ t.parent = toPush
592
+ end # toPush is nil : previous line ending with '(\n', '{\n', '[\n'
593
+ t.ipush #setup indent-in
594
+ else # indent-out or same-level
595
+ toInsert = ""
596
+ seach = proc do |sList, isCurrent|
597
+ sList.each_with_index do |s, i|
598
+ toInsert = s.closeBeginner(pi) + toInsert
599
+ # remove below
600
+ if s.isStarterAll?
601
+ case s.kind
602
+ when :on_nl
603
+ c = s.iteratorMethod
604
+ s.addModPrev, "do"
605
+ if !(ins = c.trySetupIterator(:preset, s))
606
+ ins = "end"
607
+ end
608
+ when :"\\"
609
+ c = s.iteratorMethod
610
+ barg_op = s.argRange ? "|" : ""
611
+ s.addModReplace "do #{barg_op}"
612
+ s.argEnd.addModPrev barg_op
613
+ if c
614
+ if !(ins = c.trySetupIterator(:preset, s))
615
+ ins = "end"
616
+ end
617
+ else
618
+ s.addModReplace " ::Kernel::proc do #{barg_op}\n"
619
+ s.argEnd.addModPrev barg_op
620
+ ins = "end"
621
+ if s.isSentenceHead?
622
+ if !s.argRange
623
+ ins += ".call"
624
+ else
625
+ raise Error.new("orphan proc with argumnents")
626
+ end
627
+ end
628
+ end
629
+ when :"&.", :on_period, :"::"
630
+ if (tmp = s.prev).kind == :on_rparen && tmp.beginner.isOperand?
631
+ if s.kind == :"&." && tmp.beginner.multiArgument?
632
+ raise Error.new("multiple theme for &. is not allowed")
633
+ end
634
+ # (Table1, Table2)::\n ... -> ____theme_double_colon___(Table1, Table2){ ... }
635
+ tmp.beginner.addModPrev themeExpr.(s.kind)
636
+ s.addModReplace "{"
637
+ else # a::\n ... -> a::____theme_double_colon___{ ... }
638
+ s.addModAfter themeExpr.(s.kind) + "{"
639
+ end
640
+ ############ implement ".", "@foo", "&&"
641
+ ins = "}"
642
+ when :on_tlambda
643
+ case s.body
644
+ when :on_lambeg
645
+ when :do
646
+ when nil
647
+ if s.argEnd != :on_nl
648
+ raise Error.new("descrepant -> args")
649
+ end
650
+ s.argEnd.addModReplace s.argEnd.str + "{"
651
+ ins = "}"
652
+ end
653
+ when :do
654
+ if c = s.iteratorMethod
655
+ if s.parent.iteratorCand == c
656
+ s.parent.iteratorCand = nil
657
+ end
658
+ c.setupIteratorLabel
659
+ if !(ins = c.trySetupIterator(:preset, s))
660
+ ins = "end"
661
+ end
662
+ else
663
+ s.addModPrev " ::Kernel::proc "
664
+ ins = "end"
665
+ end
666
+ when :case, :free_case # free case
667
+ ins = finalizeCase(s, pi) + "end"
668
+ else
669
+ if s.isIflessStarter?
670
+ finalizeIfless(s)
671
+ ins = "end"
672
+ elsif ![:until, :while].include?(s.kind) || !(ins = s.trySetupIterator(:forward, s))
673
+ ins = (s.requireArg? ?
674
+ (s.closeSentence(t.prev); s.argEnd = t.prev; ?;)
675
+ : ' ') + "end"
676
+ end
677
+ end
678
+ #toInsert = ins + Token.stuffer(:for_indent_out) + toInsert
679
+ toInsert = ins + toInsert
680
+ if isCurrent == :continue_clause
681
+ if !sList[i + 1] || !sList[i + 1].isStarter? || !sList[i + 1].requireArg?
682
+ raise Error.new("cannot continue '#{sList[i + 1].str}'")
683
+ end
684
+ break
685
+ end
686
+ elsif s.arglessCaseUpper
687
+ if !s.lines
688
+ raise Error.new("empty line under argless case")
689
+ end
690
+ s.lines.each_with_index do |item, i|
691
+ item.first.addModPrev "#{i == 0 ? "#{')&&(' if s.kind == :on_nl}(" : ') ||'}("
692
+ end
693
+ # case
694
+ # x ( x
695
+ # a ) ||( a
696
+ # b )&&( ( b
697
+ # c ) ||( c
698
+ # d ) ||( d )
699
+ # e ) ||( e
700
+ # f ) ||( f )
701
+ if s.kind == :argless_case
702
+ s.addModReplace ""
703
+ end
704
+ toInsert = ")" + toInsert
705
+ else
706
+ #if %i{post_test_while post_test_until}.include? (sc = s.currentClause).kind # should be argument is not closed
707
+ # if !sc.requireArg?
708
+ # raise Error.new("descrepant post test clause")
709
+ # end
710
+ # sc.argEnd = pi
711
+ # sc.closeSentence
712
+ # toInsert = postTestFinalize(pi) + toInsert
713
+ #els
714
+ if !isCurrent || isCurrent == :continue_clause
715
+ # if ( { [ left raise error
716
+ raise Error.new("unclosed '#{s.str}' before unindentation")
717
+ else
718
+ break
719
+ end
720
+ end
721
+ pi.spop
722
+ end
723
+ end
724
+ ri = t.cur.idtStack.rindex do |e|
725
+ e.unindent_pos <= t.first
726
+ end
727
+ if !ri
728
+ raise Error.new("unknown error")
729
+ end
730
+ # get indent-in parStack
731
+ chkList = []
732
+ (t.cur.idtStack.size - 1).downto ri - 1 do |i|
733
+ t.cur.idtStack[i].parStackI.reverse_each do |w|
734
+ chkList.unshift w.orgEntity
735
+ end
736
+ t.cur.idtStack.pop
737
+ end
738
+
739
+ # get same level parStack
740
+ t.cur.idtStack[ri].unindent_pos = t.first
741
+ t.cur.idtStack[ri].parStackI.reverse_each do |w|
742
+ lastList.unshift w.orgEntity
743
+ end
744
+
745
+ seach[chkList, toInsert, false]
746
+
747
+ if t.kind == :continue_clause
748
+ seach[lastList, toInsert, :continue_clause]
749
+ else
750
+ case t.cur.idtStack[ri].parStackI.last&.entity
751
+ when ->{_1.nativeContinue?(t.kind)},
752
+ ->{ defined?(PostTestWhile) && _1.kind == :do &&
753
+ !_1.parent.iteratorCand &&
754
+ %i{while until}.include?(t.kind) &&
755
+ (_1.setPostTest(t) ; true) }
756
+ seach[lastList, toInsert, true]
757
+ if t.parent.kind == :on_lbrace && t.kind != :on_rbrace && t.prev_non_sp != t.parent
758
+ t.parent.kind = :lbrace_clause # determine clause, not hash
759
+ end
760
+
761
+ end
762
+ end
763
+ if !toInsert.empty?
764
+ pi.addModReplace toInsert + pi.str
765
+ end
766
+ end
767
+ s = t.cur.idtStack.last.parStackI.last.entity #maybe newly pushed
768
+ end
769
+ # free case, free ensure, free rescue, ::{}, .{}
770
+ if [t.prev, t.prev_non_sp].find{[t.parent, t.parent.sentences&.last&.last].include?(_1)} && t.realToken?
771
+ t.parent.openSentence t
772
+ end
773
+ # argless_case
774
+ if %i{on_semicolon on_nl}.include? t.kind # already disposed
775
+ t.parent.closeSentence t
776
+ t.parent.iteratorCand = nil
777
+ if t.parent.kind == :case
778
+ if !t.parent.argStart
779
+ t.parent.kind = :argless_case
780
+ end
781
+ end
782
+ end
783
+ #seup iterator candidate
784
+ if [:on_ident, :on_const].include?(t.kind) || t.maybeIteratorLabel?
785
+ t.parent.iteratorCand ||= t
786
+ elsif [:"'", :'"'].include?(t.kind)
787
+ if t.parent.iteratorCand == t.dprev
788
+ t.parent.iteratorCand = t
789
+ else
790
+ t.parent.iteratorCand ||= t
791
+ end
792
+ elsif t.kind == :on_rparen && t.beginner.prev.kind == :'."' # ."(method_unbound)
793
+ t.parent.iteratorCand ||= t
794
+ elsif [:on_semicolon, :on_nl, :and, :or, :not].include?(t.kind)
795
+ t.parent.iteratorCand = nil
796
+ elsif t.dprev == t.parent.iteratorCand && t.continues? && !t.nonBinary?
797
+ if t.parent.kind == :on_lbrace && t.kind == :on_comma && t.parent.iteratorCand == nil &&
798
+ (t.parent.next == :on_label || t.parent.next_non_sp == :on_label)
799
+ t.parent.kind = :hash_beg
800
+ end
801
+ if t.parent.kind == :on_lbrace && t.kind == :"=>" && t.parent.iteratorCand == nil
802
+ if t.parent.firstRightAssign
803
+ t.parent.kind = :hash_beg
804
+ else
805
+ t.parent.firstRightAssign = t
806
+ end
807
+ t.parent.kind = :hash_beg
808
+ end
809
+ t.parent.iteratorCand = nil
810
+ elsif t.prev == t.parent.iteratorCand && t.dprev == :on_sp && t.realToken?
811
+ if t.kind == :on_period && !t.isOperand? || # method call operand start 'iterator.foo'
812
+ t.continues? && # include :&., :. (non operand) 'iterator +'
813
+ #(![:"::", :~, :"!", :"<:", :"@+", :"@-", :"@!", :"@~", # unary operator 'iterator ::foo', 'iterator ~foo'
814
+ # :on_lbrace, :on_lbracket, :on_lparen, :"..", :"..."].include?(t.kind) && #'iterator [...]'
815
+ #!([:*, :**, :+, :-, :&].include?(t.kind) && t.dnext != :on_sp) && # another unary operator with post-non-space
816
+ #(!defined?(PinClassOp) || (t.kind == :^ && t.dnext != :on_sp))
817
+ #)
818
+ !unary? && !callArgOp? && !t.themeLParen?
819
+ t.parent.iteratorCand = nil # 'iterator + ...' 'iterator , ...'
820
+ end
821
+ end
822
+ # setup hash
823
+ if t.parent.kind == :on_lbrace && t.kind == :on_comma && t.parent.iteratorCand == nil
824
+ && (t.parent.next == :on_label || t.parent.next_non_sp == :on_label)
825
+ t.parent.kind = :hash_beg
826
+ end
827
+ if t.parent.kind == :on_lbrace && t.kind == :"=>" && t.parent.iteratorCand == nil
828
+ if t.parent.firstRightAssign
829
+ t.parent.kind = :hash_beg
830
+ else
831
+ t.parent.firstRightAssign = t
832
+ end
833
+ t.parent.kind = :hash_beg
834
+ end
835
+
836
+ # instant variable by '>'
837
+ if t.var_able? && (tp = t.dprev).kind == :>
838
+ if tp.dprev.terminal?
839
+ tp.addModReplace "._____insert_var"
840
+ t.addModReplace "(#{t.str} = :#{t.str})"
841
+ elsif [:if, :unless].include? tp.dprev.kind
842
+ tp.addModReplace ""
843
+ t.addModAfter(" = ")
844
+ end
845
+ end
846
+ # instant variable by '>' for when, for
847
+ if %i{when free_when for}.include?((wh = t.parent).kind) && t == wh.argEnd
848
+ if wh.dnext.kind == :> && (whv = wh.dnext.dnext).var_able?
849
+ cs = wh.case
850
+ cs.requireIfConversion = true
851
+ wh.ifConverted = true
852
+ cmp = -> r, ord, head do
853
+ Token.addMod r, head + " _____case_comp_insert_var(#{whv.str} = :#{whv.str}, #{ord}, "
854
+ end
855
+ cmp.(wh.first ... whv.last, 0, "")
856
+ (cms = wh.argCommas).each_with_index do |cm, ord|
857
+ cmp.(cm.range, ord + 1, "), ")
858
+ end
859
+ Token.addMod wh.argEnd.first, ")"
860
+ end
861
+ wh.eachArgs do |a|
862
+ if a.kind == :lbrace_clause || (a.kind == :on_lbrace && a.next.kind != :on_label && a.maybeRightMatch? && a.kind = :lbrace_clause)
863
+ Token.addMod a.first, "->#{a.spVarName}" # dummy argument for lambda
864
+ end
865
+ end
866
+ end
867
+ case t.kind
868
+ when :on_semicolon
869
+ if t.parent.kind == :on_lbrace
870
+ t.parent.kind = :lbrace_clause
871
+ end
872
+ when :and, :or, :not
873
+ if [:on_lbracket, :on_lparen].include?(t.parent)
874
+ t.parent.hasAndOp = true
875
+ end
876
+ when :on_ivar
877
+ if t.str == "@"
878
+ t.eachParent do |par|
879
+ case par.kind
880
+ when :on_lbrace
881
+ if %{for free_when when}.include? par.parent.kind
882
+ if %i{on_comma for free_for free_when when}.include? :on_comma
883
+
884
+ end
885
+ end
886
+ when
887
+ if %{case free_case}.include? par.kind
888
+
889
+ par.spVarName
890
+ end
891
+ end
892
+ end
893
+ when :on_comma
894
+ case t.parent
895
+ when :on_lparen, :on_lbrace
896
+ if !t.parent.iteratorCand
897
+ t.parent.setComma t
898
+ end
899
+ when :on_lbrace
900
+ if !t.parent.iteratorCand
901
+ t.parent.setComma t
902
+ if t.parent.firstRightAssign
903
+ t.parent.maybeRightMatch = true
904
+ end
905
+ end
906
+ end
907
+ when :on_period
908
+ if t.isOperand? # should not be parent
909
+ if [:on_ident, :on_const].include?(t.next_meaningful.kind)
910
+ Token.addMod(t.first, "___theme_by_period")
911
+ elsif ambiguousPeriodTheme?
912
+ raise Error.new("Nested theme is referenced by single '.'")
913
+ else
914
+ Token.addMod(t.range, "___theme_by_period")
915
+ end
916
+ end
917
+ when :|
918
+ if [:do, :on_lbrace].include?(t.prev_non_sp) && t.parent == t.prev_non_sp
919
+ if t.parent == :on_lbrace
920
+ t.parent = :lbrace_clause
921
+ end
922
+ t.implementOpener
923
+ t.spush
924
+ elsif t.parent.kind == :|
925
+ t.spop
926
+ else
927
+ raise Error.new("unclosed iterator arg")
928
+ end
929
+ when :on_lambeg
930
+ if t.parent.kind == :on_tlambda && !t.parent.body
931
+ t.parent.setBody t
932
+ end
933
+ when :on_lparen, :on_lbracket,
934
+ :on_regexp_beg, :on_backtick, :on_embexpr_beg,
935
+ :on_tstring_beg, :on_qwords_beg,:on_words_beg, :on_symbeg, :on_qsymbols_beg, :on_symbols_beg
936
+ t.spush
937
+ when :on_rparen, :on_rbracket, :on_rbrace, :on_embexpr_end
938
+ first = true
939
+ if !t.parent.opponent?(t)
940
+ toInsert = ""
941
+ while t.parent.isStarter?
942
+ toInsert = (!t.parent.requireArg? ? ' ' : ?;) + "end" + toInsert
943
+ t.spop
944
+ end
945
+ if !t.parent.opponent?(t)
946
+ raise Error.new("#{t.parent.str()} is not closed")
947
+ end
948
+ if !toInsert.empty?
949
+ @expr[t.range] = toInsert + @expr[t.range]
950
+ raise Restart.new
951
+ end
952
+ end
953
+ t.spop
954
+ case t.kind
955
+ when :on_rparen, :on_rbracket
956
+ t.beginner.checkAndOp
957
+ when :on_rbrace
958
+ if t.beginner.kind == :hash_beg
959
+ Token.addMod t.beginner.first, " ("
960
+ Token.addMod t.last, ")"
961
+ end
962
+ if t.cur.parStack.size == 0 && RBRACE_MODE.include?(ebmode)
963
+ if ebmode == :bare
964
+ if AdhocLiterals[:url]
965
+ checkUrl t.first do |led|
966
+ yield t.first, :url #back track
967
+ end
968
+ end
969
+ if AdhocLiterals[:email]
970
+ checkEmail t.first do |led|
971
+ yield t.first, :email #back track
972
+ end
973
+ end
974
+ if AdhocLiterals[:path]
975
+ checkPath t.first do |led, pstack|
976
+ yield t.first, :path, led, pstack #back track
977
+ end
978
+ end
979
+ else
980
+ yield t.first, emode
981
+ end
982
+ # do not return : raise Restart.new
983
+ elsif [:on_lbrace, :lbrace_clause].include? t.beginner.kind # check iterator
984
+ if [:"&.", :on_period, :"::"].include?((tbp = t.beginner.prev).kind)
985
+ tbp.closeBeginner t
986
+ #if (tbpp = tbp.prev).kind == :on_rparen && (tbppb = tbpp.beginner).isOperand?
987
+ # # foo (a,b,c)::{...} -> foo ___theme(a,b,c){...}
988
+ # if tbp.kind == :"&." && tbpp.beginner.multiArgument?
989
+ # raise Error.new("multiple theme for '&.' operator is not allowed")
990
+ # end
991
+ # Token.addMod tbppb.first, themeExpr.(tbp)
992
+ # Token.addMod tbp.range, ""
993
+ #else
994
+ # # foo(a,b,c)::{...} -> foo(a,b,c)::___theme{...}
995
+ # Token.addMod t.beginner.first, themeExpr.(tbp)
996
+ # # lexical tree analysis with [], ||, &&, ?:, override output
997
+ #end
998
+ else
999
+ case (tt = t.beginner.prev).kind
1000
+ when :on_rparen
1001
+ case (ttt = tt.beginner.prev).kind
1002
+ when :"&.", :on_period # foo&.(...){...}, foo.(...){...}
1003
+ ######## (Table1, Table2)::{....}
1004
+ t.beginner.iterator_method = ttt
1005
+ # &.(...){...} -> NG
1006
+ # .(...){...} -> OK
1007
+ when :"::" #foo::(...){...}
1008
+ raise Error.new("foo::(...){...} is not implemented")
1009
+ else
1010
+ unless t.beginner.iterator_method = ttt.trySetupIterator(:back, t.beginner.argEnd, t) # foo:label(...){...}
1011
+ raise Error.new("cannot find iterator method like 'foo' in 'foo(...){...}'") # foo(...){...}
1012
+ end
1013
+ end
1014
+ # foo'(...){...}
1015
+ # foo"(...){...}
1016
+ # foo."(...)(...){...}
1017
+ # .(...){...}
1018
+ when :on_rbracket
1019
+ t.beginner.iterator_method = tt.beginner # a[...]{...} ':[]' is iterator method
1020
+ else
1021
+ t.beginner.iterator_method = tt.trySetupIterator(:back, t.beginner.argEnd, t) # foo:label{...}
1022
+ raise Error.new("cannot find iterator method like 'foo' in 'foo{...}'") # foo {...}
1023
+ end
1024
+ end
1025
+ end
1026
+ end
1027
+ end
1028
+ when :on_heredoc_end
1029
+ t.spop
1030
+ when :on_tstring_end
1031
+ case t.parent.kind
1032
+ when :on_tstring_beg
1033
+ Token.addmod t.range, SET_LINE
1034
+ t.spop
1035
+ when :on_qwords_beg,:on_words_beg, :on_symbeg, :on_qsymbols_beg, :on_symbols_beg, :on_backtick
1036
+ t.spop
1037
+ else
1038
+ raise Error.new("ERROR: String content closing at #{t.pos} is missing beginning\n")
1039
+ end
1040
+ if t.cur.parStack.size == 0 && mode.to_s =~ /_quote$/
1041
+ yield t.first # do not return : raise Retart.new
1042
+ end
1043
+ when :on_label_end
1044
+ if t.parent.kind == :on_tstring_beg
1045
+ t.spop
1046
+ else
1047
+ raise Error.new("ERROR: String content closing at #{t.pos} is missing beginning\n")
1048
+ end
1049
+ when :on_regexp_end
1050
+ if t.parent.kind == :on_regexp_beg
1051
+ t.spop
1052
+ else
1053
+ raise Error.new("ERROR: Reglar expression closing at #{t.pos} is missing beginning\n")
1054
+ end
1055
+ end
1056
+ # check Starters status
1057
+ h = t.parent
1058
+ if h.requireArg?
1059
+ if !h.argStart
1060
+ case t.kind
1061
+ when :on_semicolon, :on_nl
1062
+ if defined?(Endless) || t.kind == :on_semicolon
1063
+ if h.in
1064
+ raise Error.new("missing argument for 'in'")
1065
+ else
1066
+ case h.kind
1067
+ when *%i{if elsif unless while until on_tlambda post_test_while post_test_until \\ =}
1068
+ raise Error.new("missing argument for '#{h.str}'")
1069
+ when :case
1070
+ if !defined?(ArglessCase)
1071
+ raise Error.new("missing argument for '#{h.str}'")
1072
+ end
1073
+ when :for
1074
+ if !h.trySetUnderCase
1075
+ raise Error.new("new line or semicolon is not allowed after 'for' arguments")
1076
+ end
1077
+ else
1078
+ case h.parent.wrapped.orgEntity.kind
1079
+ when :case #traditional case, when, in
1080
+ raise Error.new("missing argument for '#{h.str}' of traditional style 'case'")
1081
+ when :in, :for, :when # free case when, in, for without argument
1082
+ end
1083
+ end
1084
+ end
1085
+ end
1086
+ h.argEnd = t # :rescue is unconditionally close argument
1087
+ when :in
1088
+ if h.kind == :for
1089
+ raise Error.new("missing argument for '#{h.str}' before 'in'")
1090
+ else # in without for
1091
+ h.argEnd = t
1092
+ end
1093
+ when :on_lambeg, :do
1094
+ if h.kind == :on_tlambda
1095
+ h.argEnd = t
1096
+ end
1097
+ when :"=" # one line method # def a(x,y) = x * y
1098
+ if defined?(Endless)
1099
+ if t.prev.kind == :on_lparen && t.prev.beginner.prev == :def
1100
+ h.changeEntity t
1101
+ end
1102
+ else
1103
+ if t.prev_non_sp.kind == :on_lparen && t.prev_non_sp.beginner.prev_non_sp.kind == :def
1104
+ h.changeEntity t
1105
+ end
1106
+ end
1107
+ else
1108
+ if t.realToken?
1109
+ h.argStart ||= t
1110
+ end
1111
+ end
1112
+ else
1113
+ if t.kind == :in && h.kind == :for
1114
+ h.setIn t #argEnd is also set with this method
1115
+ elsif t.kind == :on_semicolon || t.kind == :on_nl
1116
+ case h.kind
1117
+ when :for
1118
+ if !t.in?
1119
+ if t.trySetUnderCase
1120
+ t.kind = :free_for
1121
+ else
1122
+ raise Error.new("new line or semicolon is not allowed after 'for' arguments")
1123
+ end
1124
+ end
1125
+ when :on_tlambda
1126
+ if !defined?(Endless) || t.kind == :on_semicolon
1127
+ raise Error.new("new line or semicolon is not allowed after '->' arguments")
1128
+ end
1129
+ when :"="
1130
+ t.spop
1131
+ when :post_test_while, :post_test_until
1132
+ postTestFinalize t
1133
+ end
1134
+ h.argEnd = t
1135
+ elsif [:when, :in].include?(t.kind) && h.wrapped.orgEntity.kind == :case \ # case foo in goo (same line)
1136
+ || t.kind == :then && [:if, :elsif, :unless, :in, :when, :rescue].include?(h.kind) \
1137
+ || t.kind == :do && \
1138
+ ( (h.kind == :for && h.in) \
1139
+ || [:until, :while].include?(h.kind) \
1140
+ || h.kind == :on_tlambda
1141
+ )
1142
+ h.argEnd = t
1143
+ elsif t.kind == :on_lbrace && h.kind == :on_tlambda
1144
+ h.argEnd = t
1145
+ end
1146
+ end
1147
+ end
1148
+ #check starters
1149
+ case t.kind
1150
+ when :"\\" #onSetKind
1151
+ if t.prev_non_sp.continues? || t.isSentenceHead?
1152
+ t.spush # without method
1153
+ else
1154
+ if (t.iteratorMethod = t.parent&.iteratorCand)&.setupIteratorLabel
1155
+ t.parent.iteratorCand = nil
1156
+ t.spush
1157
+ else
1158
+ raise Error.new("cannot find iterator method")
1159
+ end
1160
+ end
1161
+ when :then #checkStarter
1162
+ if t.parent&.thenRelated?(t.prev_non_sp)
1163
+ t.parent.setThen t
1164
+ elsif defined?(Ifless) && defined?(Endless) && t.prev_nl?
1165
+ t.spush
1166
+ t.kind = :ifless_then
1167
+ else
1168
+ raise Error.new("orphan then")
1169
+ end
1170
+ when :on_tlambda #onSetKind
1171
+ t.spush
1172
+ when :do #onSetKind
1173
+ if !t.prev_non_sp.continues? && t.parent&.doRelated?
1174
+ t.parent.setDo t
1175
+ elsif !t.prev_non_sp.continues? && t.parent.kind = :on_tlambda && !t.parent.body
1176
+ t.parent.setBody t
1177
+ else
1178
+ if !t.prev_non_sp.continues? && !t.isSentenceHead?
1179
+ if t.iteratorMethod = t.parent&.iteratorCand
1180
+ # omit "t.parent.iteratorCand = nil" 'cause maybe :post_test_while, not iterator
1181
+ else
1182
+ raise Error.new("cannot find iterator method")
1183
+ end
1184
+ end
1185
+ t.spush
1186
+ end
1187
+ when :else
1188
+ if t.continuedClause?
1189
+ t.parent.clauseElse t
1190
+ elsif defined?(Ifless) && defined?(Endless) && t.prev_nl?
1191
+ t.spush
1192
+ t.kind = :ifless_else
1193
+ else
1194
+ raise Error.new("orphan else")
1195
+ end
1196
+ when :elsif
1197
+ if t.continuedClause?
1198
+ t.clauseElsif t
1199
+ elsif defined?(Ifless) && defined?(Endless) && t.prev_nl?
1200
+ t.spush
1201
+ t.kind = :ifless_elsif
1202
+ else
1203
+ raise Error.new("orphan elsif")
1204
+ end
1205
+ when :if, :unless, :case, :module, :begin, :for, :def
1206
+ t.spush
1207
+ when :class
1208
+ mth = t.findParent{%i{module class def origin}.include? _1.kind}
1209
+ if defined?(Endless)
1210
+ n = t.next
1211
+ else
1212
+ n = t.next_non_sp
1213
+ end
1214
+ if (if mth.kind == :def
1215
+ n.kind == :<<
1216
+ else
1217
+ %i{<< on_const ::}.include? n.kind
1218
+ end)
1219
+ then
1220
+ t.spush # singleton class
1221
+ else
1222
+ t.kind = :on_ident
1223
+ Token.addMod t.pos, "self."
1224
+ end
1225
+ when :in
1226
+ if t.continuedClause?
1227
+ if t.parent.kind == :case
1228
+ t.parent.clauseIn t
1229
+ elsif t.parent.kind == :in
1230
+ if t.parent.argEnd
1231
+ t.parent.clauseIn t
1232
+ else
1233
+ # right assignment 'in'
1234
+ end
1235
+ end
1236
+ elsif t.parent&.kind == :for && t.cur.idtStack.last == t.parent
1237
+ t.parent.setIn t
1238
+ else
1239
+ if t.isSentenceHead?
1240
+ if defined?(FreeCase) && t.trySetUnderCase
1241
+ t.kind = :free_in
1242
+ t.spush
1243
+ else
1244
+ raise Error.new("orphan in")
1245
+ end
1246
+ else
1247
+ # right assignment 'in'
1248
+ end
1249
+ end
1250
+ when :when
1251
+ if t.continuedClause?
1252
+ t.parent.clauseWhen t
1253
+ else
1254
+ if defined?(FreeCase) && t.trySetUnderCase
1255
+ t.kind = :free_when
1256
+ t.spush
1257
+ else
1258
+ raise Error.new("orphan when")
1259
+ end
1260
+ end
1261
+ when :rescue
1262
+ if t.continuedClause?
1263
+ t.parent.clauseRescue t
1264
+ else #independent rescue
1265
+ if defined?(IndependentRescue)
1266
+ t.spush
1267
+ else
1268
+ raise Error.new("found orphan 'rescue'")
1269
+ end
1270
+ end
1271
+ when :ensure
1272
+ if t.continuedClause?
1273
+ t.parent.clauseEnsure t
1274
+ else #independent ensure
1275
+ if defined?(IndependentEnsure)
1276
+ t.spush
1277
+ else
1278
+ raise Error.new("found orphan 'ensure'")
1279
+ end
1280
+ end
1281
+ when :end
1282
+ if t.continuedClause?
1283
+ Token.addMod t.range, t.parent.wrapped.orgEntity.closeBeginner(t)
1284
+ t.spop
1285
+ else
1286
+ raise Error.new("found extra end")
1287
+ end
1288
+ ############ remove below #############
1289
+ case t.parent.kind
1290
+ when :case, :free_case
1291
+ finalizeCase(t.parent, t)
1292
+ when :ensure
1293
+ finalizeFreeEnsure.(t.parent)
1294
+ when :rescue
1295
+ finalizeFreeRescue.(t.parent)
1296
+ else
1297
+ if t.parent.isIflessStarter?
1298
+ finalizeIfless(t.parent)
1299
+ elsif t.continuedClause?
1300
+ # protect over pop indentation
1301
+ case (lo = t.parent.wrapped.orgEntity).kind # without iterator method information 'cause may start post test while or until
1302
+ when :do ########### do"
1303
+ if c = lo.parent.iteratorCand
1304
+ if lo.iteratorMethod = c.trySetupIterator :preset, lo, t
1305
+ lo.parent.iteratorCand = nil
1306
+ end
1307
+ else
1308
+ case lop = lo.prev
1309
+ when :on_rbracket
1310
+ lo.iteratorMethod = lop.beginner
1311
+ when :on_rparen
1312
+ tt = lop.beginner.prev
1313
+ lo.iteratorMethod = tt.trySetupIterator :back, lo, t
1314
+ end
1315
+ end
1316
+ if !lo.iteratorMethod
1317
+ raise Error.new("cannot find iterator method identifier for 'do'")
1318
+ end
1319
+ when :until, :while
1320
+ lo.trySetupIterator :forward, lo, t
1321
+ when :then, :else, :elsif # ifless
1322
+ finalizeIfless t
1323
+ end
1324
+ t.spop
1325
+ else
1326
+ raise Error.new("found extra end")
1327
+ end
1328
+ end
1329
+ when :while, :until
1330
+ if t.parent.kind == :do && !t.parent.iteratorCand && defined?(PostTestDo)
1331
+ t.parent.setPostTest t
1332
+ else
1333
+ t.spush
1334
+ end
1335
+ end
1336
+ #check label
1337
+ if t.kind == :on_label &&
1338
+ if (t.str == "do:") ||
1339
+ (["while:", "until:"].include?(t.str) && ([:on_nl, :on_semicolon].include?(t.dprev.prev.kind) || t.dprev.prev.continues?))
1340
+
1341
+ if t.maybeIteratorLabel? true
1342
+ # NG do:label [,):};\n]
1343
+ # NG do:label ^ foo # cannot be interpreted as unary operator
1344
+ # OK do:label ! foo # unary operator
1345
+ # OK do:label + 1 # interpreted as unary operator
1346
+ # do not need check :post_test_do because 'do ... while:label cond' is not allowed
1347
+ t.setupIteratorLabel
1348
+ t.spush
1349
+ end
1350
+ end
1351
+ end
1352
+ allTokens.push t
1353
+ end
1354
+ rescue Restart
1355
+ allTokens.clear
1356
+ @restarted = true
1357
+ retry
1358
+ rescue StopIteration
1359
+ end
1360
+ if mode
1361
+ if mode.to_s =~ /_quote$/
1362
+ raise Error.new("cannot find closing end of quotation")
1363
+ else
1364
+ raise Error.new("cannot find closing end of brace")
1365
+ end
1366
+ end
1367
+ end
1368
+ attr_reader :pos, :kind, :str, :stat, :restarted
1369
+ def self.translate opts, expr, f, lno
1370
+ new expr, opts, f, lno
1371
+ end
1372
+ end
1373
+
1374
+
1375
+
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+