YkLib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+