demotape 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (548) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/CHANGELOG.md +9 -0
  4. data/Makefile +4 -2
  5. data/README.md +101 -10
  6. data/demotape.gemspec +1 -1
  7. data/demotape.y +224 -505
  8. data/demotape_new.y.backup +160 -0
  9. data/demotape_simple_test.y +32 -0
  10. data/editors/sublime-text/DemoTape.sublime-completions +4 -0
  11. data/editors/sublime-text/DemoTape.sublime-syntax +24 -2
  12. data/editors/vim/syntax/demotape.vim +16 -2
  13. data/editors/vscode/demotape.tmLanguage.json +31 -3
  14. data/lib/demo_tape/cli.rb +36 -0
  15. data/lib/demo_tape/command.rb +63 -103
  16. data/lib/demo_tape/exporter.rb +3 -0
  17. data/lib/demo_tape/formatter.rb +142 -0
  18. data/lib/demo_tape/lexer.rb +118 -34
  19. data/lib/demo_tape/parser/helpers.rb +363 -0
  20. data/lib/demo_tape/parser/rules.rb +396 -0
  21. data/lib/demo_tape/parser.rb +381 -592
  22. data/lib/demo_tape/runner.rb +82 -27
  23. data/lib/demo_tape/token.rb +86 -0
  24. data/lib/demo_tape/version.rb +1 -1
  25. data/lib/demo_tape.rb +5 -2
  26. metadata +10 -527
  27. data/examples/alt.mp4 +0 -0
  28. data/examples/alt.png +0 -0
  29. data/examples/alt.tape +0 -9
  30. data/examples/arrow.mp4 +0 -0
  31. data/examples/arrow.png +0 -0
  32. data/examples/arrow.tape +0 -7
  33. data/examples/backspace.mp4 +0 -0
  34. data/examples/backspace.png +0 -0
  35. data/examples/backspace.tape +0 -4
  36. data/examples/bash.mp4 +0 -0
  37. data/examples/bash.png +0 -0
  38. data/examples/bash.tape +0 -4
  39. data/examples/bg.jpg +0 -0
  40. data/examples/clear.mp4 +0 -0
  41. data/examples/clear.png +0 -0
  42. data/examples/clear.tape +0 -6
  43. data/examples/cli_ui_interactive_prompt.mp4 +0 -0
  44. data/examples/cli_ui_interactive_prompt.png +0 -0
  45. data/examples/cli_ui_interactive_prompt.tape +0 -16
  46. data/examples/cli_ui_nested_frames.mp4 +0 -0
  47. data/examples/cli_ui_nested_frames.png +0 -0
  48. data/examples/cli_ui_nested_frames.tape +0 -15
  49. data/examples/cli_ui_progress.mp4 +0 -0
  50. data/examples/cli_ui_progress.png +0 -0
  51. data/examples/cli_ui_progress.tape +0 -6
  52. data/examples/cli_ui_spinner.mp4 +0 -0
  53. data/examples/cli_ui_spinner.png +0 -0
  54. data/examples/cli_ui_spinner.tape +0 -6
  55. data/examples/cli_ui_status_widget.mp4 +0 -0
  56. data/examples/cli_ui_status_widget.png +0 -0
  57. data/examples/cli_ui_status_widget.tape +0 -6
  58. data/examples/cli_ui_symbols.mp4 +0 -0
  59. data/examples/cli_ui_symbols.png +0 -0
  60. data/examples/cli_ui_symbols.tape +0 -6
  61. data/examples/cli_ui_text_prompt.mp4 +0 -0
  62. data/examples/cli_ui_text_prompt.png +0 -0
  63. data/examples/cli_ui_text_prompt.tape +0 -10
  64. data/examples/clipboard.mp4 +0 -0
  65. data/examples/clipboard.png +0 -0
  66. data/examples/clipboard.tape +0 -5
  67. data/examples/ctrl.mp4 +0 -0
  68. data/examples/ctrl.png +0 -0
  69. data/examples/ctrl.tape +0 -5
  70. data/examples/ctrl_arrows.mp4 +0 -0
  71. data/examples/ctrl_arrows.png +0 -0
  72. data/examples/ctrl_arrows.tape +0 -14
  73. data/examples/demotape.mp4 +0 -0
  74. data/examples/demotape.png +0 -0
  75. data/examples/demotape.tape +0 -6
  76. data/examples/demotape.txt +0 -13
  77. data/examples/enter.mp4 +0 -0
  78. data/examples/enter.png +0 -0
  79. data/examples/enter.tape +0 -3
  80. data/examples/errors/include_itself.tape +0 -1
  81. data/examples/fastfetch.gif +0 -0
  82. data/examples/fastfetch.mp4 +0 -0
  83. data/examples/fastfetch.png +0 -0
  84. data/examples/fastfetch.tape +0 -11
  85. data/examples/fish.mp4 +0 -0
  86. data/examples/fish.png +0 -0
  87. data/examples/fish.tape +0 -4
  88. data/examples/format.mp4 +0 -0
  89. data/examples/format.png +0 -0
  90. data/examples/format.tape +0 -15
  91. data/examples/gh-cli.mp4 +0 -0
  92. data/examples/gh-cli.png +0 -0
  93. data/examples/gh-cli.tape +0 -13
  94. data/examples/gif_loop.gif +0 -0
  95. data/examples/gif_loop.png +0 -0
  96. data/examples/gif_loop.tape +0 -5
  97. data/examples/include.mp4 +0 -0
  98. data/examples/include.png +0 -0
  99. data/examples/include.tape +0 -1
  100. data/examples/include_with_set.mp4 +0 -0
  101. data/examples/include_with_set.png +0 -0
  102. data/examples/include_with_set.tape +0 -2
  103. data/examples/meta/cli.tape +0 -10
  104. data/examples/nerdfonts.mp4 +0 -0
  105. data/examples/nerdfonts.png +0 -0
  106. data/examples/nerdfonts.tape +0 -9
  107. data/examples/output.avi +0 -0
  108. data/examples/output.gif +0 -0
  109. data/examples/output.mov +0 -0
  110. data/examples/output.mp4 +0 -0
  111. data/examples/output.png +0 -0
  112. data/examples/output.tape +0 -9
  113. data/examples/output.webm +0 -0
  114. data/examples/products.json +0 -1803
  115. data/examples/screenshot.mp4 +0 -0
  116. data/examples/screenshot.png +0 -0
  117. data/examples/screenshot.tape +0 -9
  118. data/examples/script.rb +0 -3
  119. data/examples/set_cursor_bar.mp4 +0 -0
  120. data/examples/set_cursor_bar.png +0 -0
  121. data/examples/set_cursor_bar.tape +0 -5
  122. data/examples/set_cursor_blink.mp4 +0 -0
  123. data/examples/set_cursor_blink.png +0 -0
  124. data/examples/set_cursor_blink.tape +0 -4
  125. data/examples/set_cursor_underline.mp4 +0 -0
  126. data/examples/set_cursor_underline.png +0 -0
  127. data/examples/set_cursor_underline.tape +0 -5
  128. data/examples/set_dimensions.mp4 +0 -0
  129. data/examples/set_dimensions.png +0 -0
  130. data/examples/set_dimensions.tape +0 -5
  131. data/examples/set_font_family.mp4 +0 -0
  132. data/examples/set_font_family.png +0 -0
  133. data/examples/set_font_family.tape +0 -4
  134. data/examples/set_font_size.mp4 +0 -0
  135. data/examples/set_font_size.png +0 -0
  136. data/examples/set_font_size.tape +0 -4
  137. data/examples/set_line_height.mp4 +0 -0
  138. data/examples/set_line_height.png +0 -0
  139. data/examples/set_line_height.tape +0 -8
  140. data/examples/set_margin.mp4 +0 -0
  141. data/examples/set_margin.png +0 -0
  142. data/examples/set_margin.tape +0 -7
  143. data/examples/set_margin_with_border_radius.mp4 +0 -0
  144. data/examples/set_margin_with_border_radius.png +0 -0
  145. data/examples/set_margin_with_border_radius.tape +0 -8
  146. data/examples/set_margin_with_image.mp4 +0 -0
  147. data/examples/set_margin_with_image.png +0 -0
  148. data/examples/set_margin_with_image.tape +0 -7
  149. data/examples/set_padding.mp4 +0 -0
  150. data/examples/set_padding.png +0 -0
  151. data/examples/set_padding.tape +0 -7
  152. data/examples/set_theme.mp4 +0 -0
  153. data/examples/set_theme.png +0 -0
  154. data/examples/set_theme.tape +0 -9
  155. data/examples/set_theme_property.mp4 +0 -0
  156. data/examples/set_theme_property.png +0 -0
  157. data/examples/set_theme_property.tape +0 -10
  158. data/examples/set_typing_speed.mp4 +0 -0
  159. data/examples/set_typing_speed.png +0 -0
  160. data/examples/set_typing_speed.tape +0 -6
  161. data/examples/slides.mp4 +0 -0
  162. data/examples/slides.png +0 -0
  163. data/examples/slides.tape +0 -14
  164. data/examples/space.mp4 +0 -0
  165. data/examples/space.png +0 -0
  166. data/examples/space.tape +0 -3
  167. data/examples/stdin.mp4 +0 -0
  168. data/examples/stdin.png +0 -0
  169. data/examples/stdin.tape +0 -7
  170. data/examples/tab.mp4 +0 -0
  171. data/examples/tab.png +0 -0
  172. data/examples/tab.tape +0 -5
  173. data/examples/themes/3024_day.png +0 -0
  174. data/examples/themes/3024_night.png +0 -0
  175. data/examples/themes/aardvark_blue.png +0 -0
  176. data/examples/themes/abernathy.png +0 -0
  177. data/examples/themes/adventure.png +0 -0
  178. data/examples/themes/adventure_time.png +0 -0
  179. data/examples/themes/afterglow.png +0 -0
  180. data/examples/themes/alabaster.png +0 -0
  181. data/examples/themes/alien_blood.png +0 -0
  182. data/examples/themes/andromeda.png +0 -0
  183. data/examples/themes/apple_classic.png +0 -0
  184. data/examples/themes/apple_system_colors.png +0 -0
  185. data/examples/themes/arcoiris.png +0 -0
  186. data/examples/themes/argonaut.png +0 -0
  187. data/examples/themes/arthur.png +0 -0
  188. data/examples/themes/atelier_sulphurpool.png +0 -0
  189. data/examples/themes/atom.png +0 -0
  190. data/examples/themes/atom_one_light.png +0 -0
  191. data/examples/themes/aurora.png +0 -0
  192. data/examples/themes/ayu.png +0 -0
  193. data/examples/themes/ayu_light.png +0 -0
  194. data/examples/themes/ayu_mirage.png +0 -0
  195. data/examples/themes/banana_blueberry.png +0 -0
  196. data/examples/themes/batman.png +0 -0
  197. data/examples/themes/belafonte_day.png +0 -0
  198. data/examples/themes/belafonte_night.png +0 -0
  199. data/examples/themes/birds_of_paradise.png +0 -0
  200. data/examples/themes/blazer.png +0 -0
  201. data/examples/themes/blue_berry_pie.png +0 -0
  202. data/examples/themes/blue_dolphin.png +0 -0
  203. data/examples/themes/blue_matrix.png +0 -0
  204. data/examples/themes/bluloco_dark.png +0 -0
  205. data/examples/themes/bluloco_light.png +0 -0
  206. data/examples/themes/borland.png +0 -0
  207. data/examples/themes/breeze.png +0 -0
  208. data/examples/themes/bright_lights.png +0 -0
  209. data/examples/themes/broadcast.png +0 -0
  210. data/examples/themes/brogrammer.png +0 -0
  211. data/examples/themes/bubbles.png +0 -0
  212. data/examples/themes/builtin_dark.png +0 -0
  213. data/examples/themes/builtin_light.png +0 -0
  214. data/examples/themes/builtin_pastel_dark.png +0 -0
  215. data/examples/themes/builtin_solarized_dark.png +0 -0
  216. data/examples/themes/builtin_solarized_light.png +0 -0
  217. data/examples/themes/builtin_tango_dark.png +0 -0
  218. data/examples/themes/builtin_tango_light.png +0 -0
  219. data/examples/themes/c64.png +0 -0
  220. data/examples/themes/calamity.png +0 -0
  221. data/examples/themes/catppuccin_frappe.png +0 -0
  222. data/examples/themes/catppuccin_latte.png +0 -0
  223. data/examples/themes/catppuccin_macchiato.png +0 -0
  224. data/examples/themes/catppuccin_mocha.png +0 -0
  225. data/examples/themes/cga.png +0 -0
  226. data/examples/themes/chalk.png +0 -0
  227. data/examples/themes/chalkboard.png +0 -0
  228. data/examples/themes/challenger_deep.png +0 -0
  229. data/examples/themes/chester.png +0 -0
  230. data/examples/themes/ciapre.png +0 -0
  231. data/examples/themes/clrs.png +0 -0
  232. data/examples/themes/cobalt2.png +0 -0
  233. data/examples/themes/cobalt_neon.png +0 -0
  234. data/examples/themes/coffee_theme.png +0 -0
  235. data/examples/themes/contrast_light.png +0 -0
  236. data/examples/themes/coolnight.png +0 -0
  237. data/examples/themes/crayon_pony_fish.png +0 -0
  238. data/examples/themes/crystal_violet.png +0 -0
  239. data/examples/themes/cutie_pro.png +0 -0
  240. data/examples/themes/cyber_cube.png +0 -0
  241. data/examples/themes/cyber_punk2077.png +0 -0
  242. data/examples/themes/cyberdyne.png +0 -0
  243. data/examples/themes/cyberpunk.png +0 -0
  244. data/examples/themes/dark_pastel.png +0 -0
  245. data/examples/themes/dark_plus.png +0 -0
  246. data/examples/themes/darkermatrix.png +0 -0
  247. data/examples/themes/darkmatrix.png +0 -0
  248. data/examples/themes/darkside.png +0 -0
  249. data/examples/themes/dayfox.png +0 -0
  250. data/examples/themes/deep.png +0 -0
  251. data/examples/themes/desert.png +0 -0
  252. data/examples/themes/dimmed_monokai.png +0 -0
  253. data/examples/themes/django.png +0 -0
  254. data/examples/themes/django_reborn_again.png +0 -0
  255. data/examples/themes/django_smooth.png +0 -0
  256. data/examples/themes/doom_one.png +0 -0
  257. data/examples/themes/doom_peacock.png +0 -0
  258. data/examples/themes/dot_gov.png +0 -0
  259. data/examples/themes/dracula.png +0 -0
  260. data/examples/themes/dracula_plus.png +0 -0
  261. data/examples/themes/duckbones.png +0 -0
  262. data/examples/themes/duotone_dark.png +0 -0
  263. data/examples/themes/earthsong.png +0 -0
  264. data/examples/themes/elemental.png +0 -0
  265. data/examples/themes/elementary.png +0 -0
  266. data/examples/themes/encom.png +0 -0
  267. data/examples/themes/espresso.png +0 -0
  268. data/examples/themes/espresso_libre.png +0 -0
  269. data/examples/themes/everblush.png +0 -0
  270. data/examples/themes/fahrenheit.png +0 -0
  271. data/examples/themes/fairyfloss.png +0 -0
  272. data/examples/themes/farmhouse_dark.png +0 -0
  273. data/examples/themes/farmhouse_light.png +0 -0
  274. data/examples/themes/fideloper.png +0 -0
  275. data/examples/themes/firefly_traditional.png +0 -0
  276. data/examples/themes/firefox_dev.png +0 -0
  277. data/examples/themes/firewatch.png +0 -0
  278. data/examples/themes/fish_tank.png +0 -0
  279. data/examples/themes/flat.png +0 -0
  280. data/examples/themes/flatland.png +0 -0
  281. data/examples/themes/flexoki_dark.png +0 -0
  282. data/examples/themes/flexoki_light.png +0 -0
  283. data/examples/themes/floraverse.png +0 -0
  284. data/examples/themes/forest_blue.png +0 -0
  285. data/examples/themes/framer.png +0 -0
  286. data/examples/themes/front_end_delight.png +0 -0
  287. data/examples/themes/fun_forrest.png +0 -0
  288. data/examples/themes/galaxy.png +0 -0
  289. data/examples/themes/galizur.png +0 -0
  290. data/examples/themes/ganyu.png +0 -0
  291. data/examples/themes/git_hub_dark.png +0 -0
  292. data/examples/themes/github.png +0 -0
  293. data/examples/themes/glacier.png +0 -0
  294. data/examples/themes/glorious.png +0 -0
  295. data/examples/themes/grape.png +0 -0
  296. data/examples/themes/grass.png +0 -0
  297. data/examples/themes/grey_green.png +0 -0
  298. data/examples/themes/gruvbox_dark.png +0 -0
  299. data/examples/themes/gruvbox_dark_hard.png +0 -0
  300. data/examples/themes/gruvbox_light.png +0 -0
  301. data/examples/themes/guezwhoz.png +0 -0
  302. data/examples/themes/h4rithd.png +0 -0
  303. data/examples/themes/h4rithd_com.png +0 -0
  304. data/examples/themes/ha_x0_r_blue.png +0 -0
  305. data/examples/themes/ha_x0_r_gr33_n.png +0 -0
  306. data/examples/themes/ha_x0_r_r3_d.png +0 -0
  307. data/examples/themes/hacktober.png +0 -0
  308. data/examples/themes/hardcore.png +0 -0
  309. data/examples/themes/harper.png +0 -0
  310. data/examples/themes/highway.png +0 -0
  311. data/examples/themes/hipster_green.png +0 -0
  312. data/examples/themes/hivacruz.png +0 -0
  313. data/examples/themes/homebrew.png +0 -0
  314. data/examples/themes/hopscotch.png +0 -0
  315. data/examples/themes/hopscotch_256.png +0 -0
  316. data/examples/themes/horizon.png +0 -0
  317. data/examples/themes/hurtado.png +0 -0
  318. data/examples/themes/hybrid.png +0 -0
  319. data/examples/themes/hyper.png +0 -0
  320. data/examples/themes/ic_green_ppl.png +0 -0
  321. data/examples/themes/ic_orange_ppl.png +0 -0
  322. data/examples/themes/iceberg_dark.png +0 -0
  323. data/examples/themes/iceberg_light.png +0 -0
  324. data/examples/themes/idea.png +0 -0
  325. data/examples/themes/idle_toes.png +0 -0
  326. data/examples/themes/ir_black.png +0 -0
  327. data/examples/themes/iterm2_dark_background.png +0 -0
  328. data/examples/themes/iterm2_default.png +0 -0
  329. data/examples/themes/iterm2_light_background.png +0 -0
  330. data/examples/themes/iterm2_pastel_dark_background.png +0 -0
  331. data/examples/themes/iterm2_smoooooth.png +0 -0
  332. data/examples/themes/iterm2_solarized_dark.png +0 -0
  333. data/examples/themes/iterm2_solarized_light.png +0 -0
  334. data/examples/themes/iterm2_tango_dark.png +0 -0
  335. data/examples/themes/iterm2_tango_light.png +0 -0
  336. data/examples/themes/jackie_brown.png +0 -0
  337. data/examples/themes/japanesque.png +0 -0
  338. data/examples/themes/jellybeans.png +0 -0
  339. data/examples/themes/jet_brains_darcula.png +0 -0
  340. data/examples/themes/jubi.png +0 -0
  341. data/examples/themes/juicy_colors.png +0 -0
  342. data/examples/themes/kanagawa.png +0 -0
  343. data/examples/themes/kanagawabones.png +0 -0
  344. data/examples/themes/kibble.png +0 -0
  345. data/examples/themes/kolorit.png +0 -0
  346. data/examples/themes/konsolas.png +0 -0
  347. data/examples/themes/lab_fox.png +0 -0
  348. data/examples/themes/laser.png +0 -0
  349. data/examples/themes/later_this_evening.png +0 -0
  350. data/examples/themes/lavandula.png +0 -0
  351. data/examples/themes/liquid_carbon.png +0 -0
  352. data/examples/themes/liquid_carbon_transparent.png +0 -0
  353. data/examples/themes/liquid_carbon_transparent_inverse.png +0 -0
  354. data/examples/themes/lovelace.png +0 -0
  355. data/examples/themes/man_page.png +0 -0
  356. data/examples/themes/mariana.png +0 -0
  357. data/examples/themes/material.png +0 -0
  358. data/examples/themes/material_dark.png +0 -0
  359. data/examples/themes/material_darker.png +0 -0
  360. data/examples/themes/material_design_colors.png +0 -0
  361. data/examples/themes/material_ocean.png +0 -0
  362. data/examples/themes/mathias.png +0 -0
  363. data/examples/themes/matrix.png +0 -0
  364. data/examples/themes/medallion.png +0 -0
  365. data/examples/themes/mellifluous.png +0 -0
  366. data/examples/themes/midnight_in_mojave.png +0 -0
  367. data/examples/themes/mirage.png +0 -0
  368. data/examples/themes/misterioso.png +0 -0
  369. data/examples/themes/molokai.png +0 -0
  370. data/examples/themes/mona_lisa.png +0 -0
  371. data/examples/themes/monokai_cmder.png +0 -0
  372. data/examples/themes/monokai_pro.png +0 -0
  373. data/examples/themes/monokai_pro_filter_octagon.png +0 -0
  374. data/examples/themes/monokai_pro_filter_ristretto.png +0 -0
  375. data/examples/themes/monokai_remastered.png +0 -0
  376. data/examples/themes/monokai_soda.png +0 -0
  377. data/examples/themes/monokai_vivid.png +0 -0
  378. data/examples/themes/moonlight_ii.png +0 -0
  379. data/examples/themes/n0tch2k.png +0 -0
  380. data/examples/themes/neobones_dark.png +0 -0
  381. data/examples/themes/neobones_light.png +0 -0
  382. data/examples/themes/neon.png +0 -0
  383. data/examples/themes/neopolitan.png +0 -0
  384. data/examples/themes/neutron.png +0 -0
  385. data/examples/themes/night_city.png +0 -0
  386. data/examples/themes/night_lion_v1.png +0 -0
  387. data/examples/themes/night_lion_v2.png +0 -0
  388. data/examples/themes/night_owlish_light.png +0 -0
  389. data/examples/themes/nightfox.png +0 -0
  390. data/examples/themes/niji.png +0 -0
  391. data/examples/themes/nocturnal_winter.png +0 -0
  392. data/examples/themes/nord.png +0 -0
  393. data/examples/themes/nord_light.png +0 -0
  394. data/examples/themes/novel.png +0 -0
  395. data/examples/themes/nvim_dark.png +0 -0
  396. data/examples/themes/nvim_light.png +0 -0
  397. data/examples/themes/obsidian.png +0 -0
  398. data/examples/themes/ocean.png +0 -0
  399. data/examples/themes/oceanic_material.png +0 -0
  400. data/examples/themes/oceanic_next.png +0 -0
  401. data/examples/themes/ollie.png +0 -0
  402. data/examples/themes/one_dark.png +0 -0
  403. data/examples/themes/one_half_dark.png +0 -0
  404. data/examples/themes/one_half_light.png +0 -0
  405. data/examples/themes/one_star.png +0 -0
  406. data/examples/themes/operator_mono_dark.png +0 -0
  407. data/examples/themes/overnight_slumber.png +0 -0
  408. data/examples/themes/pale_night_hc.png +0 -0
  409. data/examples/themes/pandora.png +0 -0
  410. data/examples/themes/paraiso_dark.png +0 -0
  411. data/examples/themes/paul_millr.png +0 -0
  412. data/examples/themes/pencil_dark.png +0 -0
  413. data/examples/themes/pencil_light.png +0 -0
  414. data/examples/themes/peppermint.png +0 -0
  415. data/examples/themes/piatto_light.png +0 -0
  416. data/examples/themes/pnevma.png +0 -0
  417. data/examples/themes/popping_and_locking.png +0 -0
  418. data/examples/themes/primary.png +0 -0
  419. data/examples/themes/primer.png +0 -0
  420. data/examples/themes/pro.png +0 -0
  421. data/examples/themes/pro_light.png +0 -0
  422. data/examples/themes/purple_rain.png +0 -0
  423. data/examples/themes/purplepeter.png +0 -0
  424. data/examples/themes/qb64_super_dark_blue.png +0 -0
  425. data/examples/themes/rapture.png +0 -0
  426. data/examples/themes/raycast_dark.png +0 -0
  427. data/examples/themes/raycast_light.png +0 -0
  428. data/examples/themes/rebecca.png +0 -0
  429. data/examples/themes/red_alert.png +0 -0
  430. data/examples/themes/red_planet.png +0 -0
  431. data/examples/themes/red_sands.png +0 -0
  432. data/examples/themes/relaxed.png +0 -0
  433. data/examples/themes/retro.png +0 -0
  434. data/examples/themes/retrowave.png +0 -0
  435. data/examples/themes/rippedcasts.png +0 -0
  436. data/examples/themes/rose_pine.png +0 -0
  437. data/examples/themes/rose_pine_dawn.png +0 -0
  438. data/examples/themes/rose_pine_moon.png +0 -0
  439. data/examples/themes/rouge_2.png +0 -0
  440. data/examples/themes/royal.png +0 -0
  441. data/examples/themes/ryuuko.png +0 -0
  442. data/examples/themes/sakura.png +0 -0
  443. data/examples/themes/scarlet_protocol.png +0 -0
  444. data/examples/themes/sea_shells.png +0 -0
  445. data/examples/themes/seafoam_pastel.png +0 -0
  446. data/examples/themes/seoulbones_dark.png +0 -0
  447. data/examples/themes/seoulbones_light.png +0 -0
  448. data/examples/themes/serendipity_midnight.png +0 -0
  449. data/examples/themes/serendipity_morning.png +0 -0
  450. data/examples/themes/serendipity_sunset.png +0 -0
  451. data/examples/themes/seti.png +0 -0
  452. data/examples/themes/shades_of_purple.png +0 -0
  453. data/examples/themes/shaman.png +0 -0
  454. data/examples/themes/slate.png +0 -0
  455. data/examples/themes/sleepy_hollow.png +0 -0
  456. data/examples/themes/smyck.png +0 -0
  457. data/examples/themes/snazzy.png +0 -0
  458. data/examples/themes/soft_server.png +0 -0
  459. data/examples/themes/solarized_darcula.png +0 -0
  460. data/examples/themes/solarized_dark_higher_contrast.png +0 -0
  461. data/examples/themes/solarized_dark_patched.png +0 -0
  462. data/examples/themes/sonoran_gothic.png +0 -0
  463. data/examples/themes/sonoran_sunrise.png +0 -0
  464. data/examples/themes/space_gray.png +0 -0
  465. data/examples/themes/space_gray_eighties.png +0 -0
  466. data/examples/themes/space_gray_eighties_dull.png +0 -0
  467. data/examples/themes/spacedust.png +0 -0
  468. data/examples/themes/spiderman.png +0 -0
  469. data/examples/themes/spring.png +0 -0
  470. data/examples/themes/square.png +0 -0
  471. data/examples/themes/sublette.png +0 -0
  472. data/examples/themes/subliminal.png +0 -0
  473. data/examples/themes/sundried.png +0 -0
  474. data/examples/themes/symfonic.png +0 -0
  475. data/examples/themes/synthwave.png +0 -0
  476. data/examples/themes/synthwave_alpha.png +0 -0
  477. data/examples/themes/synthwave_everything.png +0 -0
  478. data/examples/themes/tango_adapted.png +0 -0
  479. data/examples/themes/tango_half_adapted.png +0 -0
  480. data/examples/themes/teerb.png +0 -0
  481. data/examples/themes/terafox.png +0 -0
  482. data/examples/themes/terminal_basic.png +0 -0
  483. data/examples/themes/thayer_bright.png +0 -0
  484. data/examples/themes/the_hulk.png +0 -0
  485. data/examples/themes/theme.tape +0 -13
  486. data/examples/themes/tinacious_design_dark.png +0 -0
  487. data/examples/themes/tinacious_design_light.png +0 -0
  488. data/examples/themes/tokyo_night.png +0 -0
  489. data/examples/themes/tokyo_night_light.png +0 -0
  490. data/examples/themes/tokyo_night_storm.png +0 -0
  491. data/examples/themes/tokyonight.png +0 -0
  492. data/examples/themes/tokyonight_day.png +0 -0
  493. data/examples/themes/tokyonight_storm.png +0 -0
  494. data/examples/themes/tomorrow.png +0 -0
  495. data/examples/themes/tomorrow_night.png +0 -0
  496. data/examples/themes/tomorrow_night_blue.png +0 -0
  497. data/examples/themes/tomorrow_night_bright.png +0 -0
  498. data/examples/themes/tomorrow_night_burns.png +0 -0
  499. data/examples/themes/tomorrow_night_eighties.png +0 -0
  500. data/examples/themes/toy_chest.png +0 -0
  501. data/examples/themes/treehouse.png +0 -0
  502. data/examples/themes/twilight.png +0 -0
  503. data/examples/themes/ubuntu.png +0 -0
  504. data/examples/themes/ultra_dark.png +0 -0
  505. data/examples/themes/ultra_violent.png +0 -0
  506. data/examples/themes/under_the_sea.png +0 -0
  507. data/examples/themes/unholy.png +0 -0
  508. data/examples/themes/unikitty.png +0 -0
  509. data/examples/themes/urple.png +0 -0
  510. data/examples/themes/vaughn.png +0 -0
  511. data/examples/themes/vesper.png +0 -0
  512. data/examples/themes/vibrant_ink.png +0 -0
  513. data/examples/themes/vimbones.png +0 -0
  514. data/examples/themes/violet_dark.png +0 -0
  515. data/examples/themes/violet_light.png +0 -0
  516. data/examples/themes/warm_neon.png +0 -0
  517. data/examples/themes/wez.png +0 -0
  518. data/examples/themes/whimsy.png +0 -0
  519. data/examples/themes/wild_cherry.png +0 -0
  520. data/examples/themes/wilmersdorf.png +0 -0
  521. data/examples/themes/wombat.png +0 -0
  522. data/examples/themes/wryan.png +0 -0
  523. data/examples/themes/zenbones.png +0 -0
  524. data/examples/themes/zenbones_dark.png +0 -0
  525. data/examples/themes/zenbones_light.png +0 -0
  526. data/examples/themes/zenburn.png +0 -0
  527. data/examples/themes/zenburned.png +0 -0
  528. data/examples/themes/zenwritten_dark.png +0 -0
  529. data/examples/themes/zenwritten_light.png +0 -0
  530. data/examples/themes/zeonica.png +0 -0
  531. data/examples/tmux.mp4 +0 -0
  532. data/examples/tmux.png +0 -0
  533. data/examples/tmux.tape +0 -28
  534. data/examples/type.mp4 +0 -0
  535. data/examples/type.png +0 -0
  536. data/examples/type.tape +0 -11
  537. data/examples/type_file.mp4 +0 -0
  538. data/examples/type_file.png +0 -0
  539. data/examples/type_file.tape +0 -23
  540. data/examples/variable_typing.mp4 +0 -0
  541. data/examples/variable_typing.png +0 -0
  542. data/examples/variable_typing.tape +0 -41
  543. data/examples/wait_until.mp4 +0 -0
  544. data/examples/wait_until.png +0 -0
  545. data/examples/wait_until.tape +0 -8
  546. data/examples/zsh.mp4 +0 -0
  547. data/examples/zsh.png +0 -0
  548. data/examples/zsh.tape +0 -4
@@ -10,199 +10,179 @@ require 'racc/parser.rb'
10
10
  module DemoTape
11
11
  class Parser < Racc::Parser
12
12
 
13
- module_eval(<<'...end demotape.y/module_eval...', 'demotape.y', 442)
13
+ module_eval(<<'...end demotape.y/module_eval...', 'demotape.y', 228)
14
+ include Helpers
15
+
14
16
  def parse(str, file: "<unknown>")
15
17
  @file = file
16
18
  @lexer = DemoTape::Lexer.new
17
19
  @tokens = @lexer.tokenize(str)
18
20
  @token_index = 0
19
- do_parse
20
- end
21
-
22
- def next_token
23
- token = @tokens.shift
24
- @current_token_index = @token_index
25
- @token_index += 1
26
- token
27
- end
28
-
29
- def make_token(type, value, index)
30
- line_info = @lexer.line_map[index] || {}
31
- token_class = case type
32
- when :identifier then Token::Identifier
33
- when :string then Token::String
34
- when :number then Token::Number
35
- when :duration then Token::Duration
36
- when :regex then Token::Regex
37
- when :time_unit then Token::TimeUnit
38
- when :operator then Token::Operator
39
- else Token::Base
40
- end
41
-
42
- token_class.new(
43
- value,
44
- line: line_info[:line],
45
- column: line_info[:column],
46
- raw: line_info[:raw]
47
- )
48
- end
49
-
50
- def attach_location(command, duration_index: nil, speed_index: nil, timeout_index: nil)
51
- line_info = @lexer.line_map[@command_start_index] || {}
52
- command.line = line_info[:line]
53
- command.column = line_info[:column]
54
- command.line_content = line_info[:content]
55
- command.file = @file
56
-
57
- # Attach duration/speed/timeout specific columns if provided
58
- if duration_index
59
- duration_info = @lexer.line_map[duration_index] || {}
60
- command.duration_column = duration_info[:column]
61
- end
62
-
63
- if speed_index
64
- speed_info = @lexer.line_map[speed_index] || {}
65
- command.speed_column = speed_info[:column]
66
- end
67
-
68
- if timeout_index
69
- timeout_info = @lexer.line_map[timeout_index] || {}
70
- command.timeout_column = timeout_info[:column]
71
- end
72
-
73
- command
74
- end
75
-
76
- def on_error(token_id, token_value, value_stack)
77
- # Get line metadata from the lexer's line map
78
- line_info = @lexer.line_map[@current_token_index] || {}
79
- line_num = line_info[:line] || "?"
80
- col_num = line_info[:column] || 1
81
- line_content = line_info[:content] || ""
82
-
83
- token_name = token_to_str(token_id) || token_id.to_s
84
-
85
- error_msg = "Unexpected token #{token_name.inspect} at #{@file}:#{line_num}:#{col_num}:\n"
86
- error_msg += " #{line_content}\n"
87
- error_msg += " #{' ' * (col_num - 1)}^"
88
-
89
- raise DemoTape::ParseError, error_msg
21
+ @token_indices = {} # Map token object_id to its index
22
+ validate_tree!(do_parse)
90
23
  end
91
24
 
92
25
  ...end demotape.y/module_eval...
93
26
  ##### State transition tables begin ###
94
27
 
95
28
  racc_action_table = [
96
- 37, 21, 18, 19, 40, 20, 38, 24, 25, 34,
97
- 24, 25, 43, 4, 44, 45, 24, 25, 6, 24,
98
- 25, 10, 4, 12, 47, 11, 49, 34, 13, 48,
99
- 14, 28, 31, 29, 32, 9, 15, 9, 17, 27,
100
- 30, 33, 34, 35, 36, 50, 51, 52, 53, 54,
101
- 55, 56, 57, 58, 59, 60 ]
29
+ 5, 4, 6, 22, 17, 10, 11, 12, 13, 14,
30
+ 15, 16, 18, 19, 20, 21, 5, 4, 6, 24,
31
+ 17, 10, 11, 12, 13, 14, 15, 16, 18, 19,
32
+ 20, 21, 44, 41, 42, 30, 17, 10, 11, 12,
33
+ 13, 14, 15, 16, 18, 19, 20, 21, 44, 41,
34
+ 42, 31, 17, 10, 11, 12, 13, 14, 15, 16,
35
+ 18, 19, 20, 21, 44, 41, 42, 45, 17, 10,
36
+ 11, 12, 13, 14, 15, 16, 18, 19, 20, 21,
37
+ 44, 41, 42, 47, 17, 10, 11, 12, 13, 14,
38
+ 15, 16, 18, 19, 20, 21, 44, 41, 42, 51,
39
+ 17, 10, 11, 12, 13, 14, 15, 16, 18, 19,
40
+ 20, 21, 25, 48, 49, 17, 10, 11, 12, 13,
41
+ 14, 15, 16, 18, 19, 20, 21, 54, 56, 57,
42
+ 17, 10, 11, 12, 13, 14, 15, 16, 18, 19,
43
+ 20, 21, 27, 28, 17, 10, 11, 12, 13, 14,
44
+ 15, 16, 18, 19, 20, 21, 32, 33, 17, 10,
45
+ 11, 12, 13, 14, 15, 16, 18, 19, 20, 21,
46
+ 52, 59, 17, 10, 11, 12, 13, 14, 15, 16,
47
+ 18, 19, 20, 21, 61, 60, 17, 10, 11, 12,
48
+ 13, 14, 15, 16, 18, 19, 20, 21, 34, 36,
49
+ 35, 37, 63, 64, 68, 67, 62, 65, 66, 69,
50
+ 70, 71, 72, 73, 74, 75, 76 ]
102
51
 
103
52
  racc_action_check = [
104
- 27, 10, 10, 10, 35, 10, 35, 10, 10, 27,
105
- 35, 35, 36, 0, 36, 37, 36, 36, 1, 37,
106
- 37, 4, 2, 4, 38, 4, 47, 38, 5, 47,
107
- 5, 12, 14, 12, 14, 3, 6, 7, 8, 11,
108
- 13, 16, 19, 21, 26, 48, 49, 50, 51, 52,
109
- 53, 54, 55, 57, 58, 59 ]
53
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
54
+ 0, 0, 0, 0, 0, 0, 2, 2, 2, 4,
55
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
56
+ 2, 2, 34, 34, 34, 22, 34, 34, 34, 34,
57
+ 34, 34, 34, 34, 34, 34, 34, 34, 36, 36,
58
+ 36, 25, 36, 36, 36, 36, 36, 36, 36, 36,
59
+ 36, 36, 36, 36, 39, 39, 39, 35, 39, 39,
60
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
61
+ 45, 45, 45, 37, 45, 45, 45, 45, 45, 45,
62
+ 45, 45, 45, 45, 45, 45, 47, 47, 47, 41,
63
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
64
+ 47, 47, 5, 38, 38, 5, 5, 5, 5, 5,
65
+ 5, 5, 5, 5, 5, 5, 5, 44, 46, 46,
66
+ 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
67
+ 44, 44, 8, 8, 8, 8, 8, 8, 8, 8,
68
+ 8, 8, 8, 8, 8, 8, 26, 26, 26, 26,
69
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
70
+ 43, 48, 43, 43, 43, 43, 43, 43, 43, 43,
71
+ 43, 43, 43, 43, 53, 49, 53, 53, 53, 53,
72
+ 53, 53, 53, 53, 53, 53, 53, 53, 28, 33,
73
+ 28, 33, 55, 55, 58, 58, 54, 56, 57, 60,
74
+ 63, 64, 66, 67, 68, 71, 73 ]
110
75
 
111
76
  racc_action_pointer = [
112
- 9, 18, 18, 32, 18, 25, 36, 34, 36, nil,
113
- -3, 33, 27, 34, 28, nil, 39, nil, nil, 30,
114
- nil, 40, nil, nil, nil, nil, 41, -3, nil, nil,
115
- nil, nil, nil, nil, nil, 0, 6, 9, 15, nil,
116
- nil, nil, nil, nil, nil, nil, nil, 23, 36, 40,
117
- 41, 39, 40, 47, 45, 46, nil, 44, 51, 49,
118
- nil ]
77
+ -3, 3, 13, nil, 14, 108, nil, nil, 137, nil,
78
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
79
+ nil, nil, 35, nil, nil, 46, 151, nil, 193, nil,
80
+ nil, nil, nil, 194, 29, 62, 45, 78, 111, 61,
81
+ nil, 94, nil, 165, 123, 77, 126, 93, 166, 183,
82
+ nil, nil, nil, 179, 201, 200, 202, 206, 202, nil,
83
+ 204, nil, nil, 205, 209, nil, 207, 211, 209, nil,
84
+ nil, 210, nil, 211, nil, nil, nil ]
119
85
 
120
86
  racc_action_default = [
121
- -2, -39, -1, -6, -31, -9, -39, -6, -39, -5,
122
- -39, -39, -39, -39, -39, 61, -39, -3, -7, -10,
123
- -18, -39, -29, -30, -36, -37, -16, -15, -32, -33,
124
- -8, -34, -35, -4, -38, -39, -39, -39, -26, -25,
125
- -27, -28, -11, -12, -17, -13, -14, -39, -23, -39,
126
- -39, -24, -21, -39, -39, -39, -19, -22, -39, -39,
127
- -20 ]
87
+ -2, -42, -1, -3, -42, -42, -7, -8, -42, -28,
88
+ -30, -31, -32, -33, -34, -35, -36, -37, -38, -39,
89
+ -40, -41, -42, -4, -5, -42, -42, -9, -42, -29,
90
+ 77, -6, -10, -42, -19, -42, -19, -42, -42, -20,
91
+ -21, -42, -24, -42, -42, -19, -42, -19, -42, -42,
92
+ -22, -23, -25, -42, -42, -42, -42, -42, -42, -11,
93
+ -42, -26, -27, -42, -42, -13, -42, -42, -42, -12,
94
+ -15, -42, -14, -42, -18, -16, -17 ]
128
95
 
129
96
  racc_goto_table = [
130
- 22, 8, 1, 23, 26, 16, 3, 2, 7, nil,
97
+ 29, 38, 8, 46, 8, 1, 3, 26, 23, 2,
98
+ 50, nil, 55, nil, 58, nil, nil, nil, 29, nil,
131
99
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
132
- nil, nil, nil, nil, nil, 41, 42, 46, 39 ]
100
+ nil, nil, nil, nil, nil, 29, nil, nil, nil, nil,
101
+ nil, nil, nil, nil, nil, 29, 53 ]
133
102
 
134
103
  racc_goto_check = [
135
- 7, 4, 1, 6, 6, 4, 3, 2, 3, nil,
104
+ 9, 6, 5, 6, 5, 1, 3, 5, 3, 2,
105
+ 8, nil, 6, nil, 6, nil, nil, nil, 9, nil,
136
106
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
137
- nil, nil, nil, nil, nil, 7, 7, 7, 6 ]
107
+ nil, nil, nil, nil, nil, 9, nil, nil, nil, nil,
108
+ nil, nil, nil, nil, nil, 9, 5 ]
138
109
 
139
110
  racc_goto_pointer = [
140
- nil, 2, 7, 6, -2, nil, -7, -10 ]
111
+ nil, 5, 9, 6, nil, 2, -33, nil, -29, -8 ]
141
112
 
142
113
  racc_goto_default = [
143
- nil, nil, nil, nil, nil, 5, nil, nil ]
114
+ nil, nil, nil, nil, 7, 43, nil, 39, 40, 9 ]
144
115
 
145
116
  racc_reduce_table = [
146
117
  0, 0, :racc_error,
147
- 1, 14, :_reduce_1,
148
- 0, 14, :_reduce_2,
149
- 3, 15, :_reduce_3,
150
- 4, 15, :_reduce_4,
151
- 1, 17, :_reduce_5,
152
- 0, 17, :_reduce_6,
153
- 3, 16, :_reduce_7,
154
- 3, 16, :_reduce_8,
155
- 1, 16, :_reduce_9,
156
- 3, 16, :_reduce_10,
157
- 5, 16, :_reduce_11,
158
- 5, 16, :_reduce_12,
159
- 5, 16, :_reduce_13,
160
- 5, 16, :_reduce_14,
161
- 3, 16, :_reduce_15,
162
- 3, 16, :_reduce_16,
163
- 5, 16, :_reduce_17,
164
- 3, 16, :_reduce_18,
165
- 11, 16, :_reduce_19,
166
- 14, 16, :_reduce_20,
167
- 9, 16, :_reduce_21,
168
- 11, 16, :_reduce_22,
169
- 7, 16, :_reduce_23,
170
- 8, 16, :_reduce_24,
171
- 5, 16, :_reduce_25,
172
- 5, 16, :_reduce_26,
173
- 5, 16, :_reduce_27,
174
- 5, 16, :_reduce_28,
175
- 3, 16, :_reduce_29,
176
- 3, 16, :_reduce_30,
177
- 1, 16, :_reduce_31,
178
- 3, 18, :_reduce_32,
179
- 3, 18, :_reduce_33,
180
- 3, 18, :_reduce_34,
181
- 3, 18, :_reduce_35,
182
- 1, 20, :_reduce_36,
183
- 1, 20, :_reduce_37,
184
- 2, 19, :_reduce_38 ]
185
-
186
- racc_reduce_n = 39
187
-
188
- racc_shift_n = 61
118
+ 1, 20, :_reduce_1,
119
+ 0, 20, :_reduce_2,
120
+ 1, 21, :_reduce_3,
121
+ 2, 21, :_reduce_4,
122
+ 2, 22, :_reduce_5,
123
+ 3, 22, :_reduce_6,
124
+ 1, 22, :_reduce_7,
125
+ 1, 22, :_reduce_8,
126
+ 2, 22, :_reduce_9,
127
+ 3, 22, :_reduce_10,
128
+ 6, 23, :_reduce_11,
129
+ 7, 23, :_reduce_12,
130
+ 7, 23, :_reduce_13,
131
+ 8, 23, :_reduce_14,
132
+ 7, 23, :_reduce_15,
133
+ 8, 23, :_reduce_16,
134
+ 9, 23, :_reduce_17,
135
+ 8, 23, :_reduce_18,
136
+ 0, 25, :_reduce_19,
137
+ 1, 25, :_reduce_20,
138
+ 1, 26, :_reduce_21,
139
+ 2, 26, :_reduce_22,
140
+ 2, 27, :_reduce_23,
141
+ 1, 27, :_reduce_24,
142
+ 2, 27, :_reduce_25,
143
+ 3, 27, :_reduce_26,
144
+ 3, 27, :_reduce_27,
145
+ 1, 24, :_reduce_28,
146
+ 2, 24, :_reduce_29,
147
+ 1, 28, :_reduce_30,
148
+ 1, 28, :_reduce_31,
149
+ 1, 28, :_reduce_32,
150
+ 1, 28, :_reduce_33,
151
+ 1, 28, :_reduce_34,
152
+ 1, 28, :_reduce_35,
153
+ 1, 28, :_reduce_36,
154
+ 1, 28, :_reduce_37,
155
+ 1, 28, :_reduce_38,
156
+ 1, 28, :_reduce_39,
157
+ 1, 28, :_reduce_40,
158
+ 1, 28, :_reduce_41 ]
159
+
160
+ racc_reduce_n = 42
161
+
162
+ racc_shift_n = 77
189
163
 
190
164
  racc_token_table = {
191
165
  false => 0,
192
166
  :error => 1,
193
- :NEWLINE => 2,
194
- :SPACE => 3,
195
- :IDENTIFIER => 4,
196
- :PLUS => 5,
197
- :NUMBER => 6,
198
- :AT => 7,
199
- :REGEX => 8,
200
- :COMMA => 9,
201
- :STRING => 10,
202
- :WORD => 11,
203
- :TIME_UNIT => 12 }
204
-
205
- racc_nt_base = 13
167
+ :END => 2,
168
+ :LEADING_SPACE => 3,
169
+ :COMMENT => 4,
170
+ :NEWLINE => 5,
171
+ :DO => 6,
172
+ :TRAILING_SPACE => 7,
173
+ :IDENTIFIER => 8,
174
+ :STRING => 9,
175
+ :MULTILINE_STRING => 10,
176
+ :NUMBER => 11,
177
+ :DURATION => 12,
178
+ :REGEX => 13,
179
+ :SPACE => 14,
180
+ :COMMA => 15,
181
+ :PLUS => 16,
182
+ :AT => 17,
183
+ :TIME_UNIT => 18 }
184
+
185
+ racc_nt_base = 19
206
186
 
207
187
  racc_use_result_var = true
208
188
 
@@ -226,25 +206,33 @@ Ractor.make_shareable(Racc_arg) if defined?(Ractor)
226
206
  Racc_token_to_s_table = [
227
207
  "$end",
228
208
  "error",
209
+ "END",
210
+ "LEADING_SPACE",
211
+ "COMMENT",
229
212
  "NEWLINE",
230
- "SPACE",
213
+ "DO",
214
+ "TRAILING_SPACE",
231
215
  "IDENTIFIER",
232
- "PLUS",
216
+ "STRING",
217
+ "MULTILINE_STRING",
233
218
  "NUMBER",
234
- "AT",
219
+ "DURATION",
235
220
  "REGEX",
221
+ "SPACE",
236
222
  "COMMA",
237
- "STRING",
238
- "WORD",
223
+ "PLUS",
224
+ "AT",
239
225
  "TIME_UNIT",
240
226
  "$start",
241
- "tape",
242
- "commands",
243
- "command",
244
- "trailing_space",
245
- "key_combo",
246
- "duration",
247
- "string" ]
227
+ "document",
228
+ "lines",
229
+ "line",
230
+ "group",
231
+ "line_tokens",
232
+ "group_body",
233
+ "group_lines",
234
+ "group_line",
235
+ "line_token" ]
248
236
  Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor)
249
237
 
250
238
  Racc_debug_parser = false
@@ -253,628 +241,429 @@ Racc_debug_parser = false
253
241
 
254
242
  # reduce 0 omitted
255
243
 
256
- module_eval(<<'.,.,', 'demotape.y', 2)
244
+ module_eval(<<'.,.,', 'demotape.y', 11)
257
245
  def _reduce_1(val, _values, result)
258
- result = val[0]
246
+ result = val[0].flatten.compact
259
247
  result
260
248
  end
261
249
  .,.,
262
250
 
263
- module_eval(<<'.,.,', 'demotape.y', 3)
251
+ module_eval(<<'.,.,', 'demotape.y', 12)
264
252
  def _reduce_2(val, _values, result)
265
253
  result = []
266
254
  result
267
255
  end
268
256
  .,.,
269
257
 
270
- module_eval(<<'.,.,', 'demotape.y', 5)
258
+ module_eval(<<'.,.,', 'demotape.y', 14)
271
259
  def _reduce_3(val, _values, result)
272
- result = [val[0]]
260
+ result = val[0]
273
261
  result
274
262
  end
275
263
  .,.,
276
264
 
277
- module_eval(<<'.,.,', 'demotape.y', 6)
265
+ module_eval(<<'.,.,', 'demotape.y', 15)
278
266
  def _reduce_4(val, _values, result)
279
- result = val[0] << val[1]
267
+ result = val[0] + val[1]
280
268
  result
281
269
  end
282
270
  .,.,
283
271
 
284
- module_eval(<<'.,.,', 'demotape.y', 8)
272
+ module_eval(<<'.,.,', 'demotape.y', 19)
285
273
  def _reduce_5(val, _values, result)
286
- result = nil
274
+ result = [
275
+ make_token(:comment, val[0], index_for_value(val[0])),
276
+ make_token(:newline, val[1], index_for_value(val[1]))
277
+ ]
278
+
287
279
  result
288
280
  end
289
281
  .,.,
290
282
 
291
- module_eval(<<'.,.,', 'demotape.y', 9)
283
+ module_eval(<<'.,.,', 'demotape.y', 25)
292
284
  def _reduce_6(val, _values, result)
293
- result = nil
285
+ result = [
286
+ make_token(:leading_space, val[0], index_for_value(val[0])),
287
+ make_token(:comment, val[1], index_for_value(val[1])),
288
+ make_token(:newline, val[2], index_for_value(val[2]))
289
+ ]
290
+
294
291
  result
295
292
  end
296
293
  .,.,
297
294
 
298
- module_eval(<<'.,.,', 'demotape.y', 12)
295
+ module_eval(<<'.,.,', 'demotape.y', 31)
299
296
  def _reduce_7(val, _values, result)
300
- space_index = @token_index - 2
301
- line_info = @lexer.line_map[space_index] || {}
302
- error_msg = "Unexpected token \"SPACE\" at #{@file}:#{line_info[:line]}:#{line_info[:column]}:\n"
303
- error_msg += " #{line_info[:content]}\n"
304
- error_msg += " #{' ' * (line_info[:column] - 1)}^"
305
- raise DemoTape::ParseError, error_msg
306
-
297
+ result = [make_token(:newline, val[0], index_for_value(val[0]))]
307
298
  result
308
299
  end
309
300
  .,.,
310
301
 
311
- module_eval(<<'.,.,', 'demotape.y', 20)
302
+ module_eval(<<'.,.,', 'demotape.y', 32)
312
303
  def _reduce_8(val, _values, result)
313
- @command_start_index = @last_key_index
314
- keys = val[0][:keys]
315
- key_tokens = val[0][:tokens]
316
- command_name = keys.shift
317
-
318
- tokens = key_tokens + [make_token(:number, val[2], @token_index - 1)]
319
-
320
- cmd = DemoTape::Command.new(command_name, "", keys:, count: val[2])
321
- cmd.tokens = tokens
322
- result = attach_location(cmd).prepare!
323
-
304
+ result = [val[0]]
324
305
  result
325
306
  end
326
307
  .,.,
327
308
 
328
- module_eval(<<'.,.,', 'demotape.y', 32)
309
+ module_eval(<<'.,.,', 'demotape.y', 34)
329
310
  def _reduce_9(val, _values, result)
330
- @command_start_index = @last_key_index
331
- keys = val[0][:keys]
332
- key_tokens = val[0][:tokens]
333
- command_name = keys.shift
334
-
335
- cmd = DemoTape::Command.new(command_name, "", keys:)
336
- cmd.tokens = key_tokens
337
- result = attach_location(cmd).prepare!
311
+ tokens, start_idx = val[0]
312
+ result = [
313
+ { type: :command, tokens: tokens, line: line_for_token_at(start_idx), column: column_for_token_at(start_idx) },
314
+ make_token(:newline, val[1], index_for_value(val[1]))
315
+ ]
338
316
 
339
317
  result
340
318
  end
341
319
  .,.,
342
320
 
343
- module_eval(<<'.,.,', 'demotape.y', 42)
321
+ module_eval(<<'.,.,', 'demotape.y', 41)
344
322
  def _reduce_10(val, _values, result)
345
- @command_start_index = @token_index - 4
346
- duration_index = @token_index - 2
347
-
348
- tokens = [
349
- make_token(:identifier, val[0], @token_index - 4),
350
- make_token(:number, val[2], @token_index - 2)
351
- ]
352
-
353
- # Duration commands (Sleep, Wait) treat bare numbers as seconds
354
- # Key commands treat numbers as repeat counts
355
- if ["Sleep", "Wait"].include?(val[0])
356
- cmd = DemoTape::Command.new(val[0], "#{val[2]}s")
357
- cmd.tokens = tokens
358
- result = attach_location(cmd, duration_index: duration_index).prepare!
359
- else
360
- cmd = DemoTape::Command.new(val[0], "", count: val[2])
361
- cmd.tokens = tokens
362
- result = attach_location(cmd).prepare!
363
- end
323
+ idx_lead = index_for_value(val[0])
324
+ tokens, _ = val[1]
325
+ result = [
326
+ { type: :command, tokens: [make_token(:leading_space, val[0], idx_lead)] + tokens, line: line_for_token_at(idx_lead), column: column_for_token_at(idx_lead) },
327
+ make_token(:newline, val[2], index_for_value(val[2]))
328
+ ]
364
329
 
365
330
  result
366
331
  end
367
332
  .,.,
368
333
 
369
- module_eval(<<'.,.,', 'demotape.y', 63)
334
+ module_eval(<<'.,.,', 'demotape.y', 51)
370
335
  def _reduce_11(val, _values, result)
371
- @command_start_index = @token_index - 6
372
- speed_index = @token_index - 3 # TIME_UNIT position
373
-
374
- tokens = [
375
- make_token(:identifier, val[0], @token_index - 6),
376
- make_token(:operator, "@", @token_index - 5),
377
- make_token(:duration, val[2], @token_index - 4),
378
- make_token(:string, val[4], @token_index - 1)
379
- ]
380
-
381
- cmd = DemoTape::Command.new(val[0], val[4], speed: val[2])
382
- cmd.tokens = tokens
383
- result = attach_location(cmd, speed_index: speed_index).prepare!
336
+ tokens, start_idx = val[0]
337
+ idx_do = index_for_value(val[1])
338
+ idx_nl = index_for_value(val[2])
339
+ idx_end = index_for_value(val[4])
340
+ result = {
341
+ type: :group,
342
+ tokens: tokens + [make_token(:keyword, val[1], idx_do), make_token(:keyword, val[4], idx_end)],
343
+ children: [make_token(:newline, val[2], idx_nl)] + val[3],
344
+ line: line_for_token_at(start_idx),
345
+ column: column_for_token_at(start_idx)
346
+ }
384
347
 
385
348
  result
386
349
  end
387
350
  .,.,
388
351
 
389
- module_eval(<<'.,.,', 'demotape.y', 78)
352
+ module_eval(<<'.,.,', 'demotape.y', 64)
390
353
  def _reduce_12(val, _values, result)
391
- @command_start_index = @token_index - 6
392
- speed_index = @token_index - 3 # TIME_UNIT position
393
-
394
- tokens = [
395
- make_token(:identifier, val[0], @token_index - 6),
396
- make_token(:operator, "@", @token_index - 5),
397
- make_token(:duration, val[2], @token_index - 4),
398
- make_token(:number, val[4], @token_index - 1)
399
- ]
400
-
401
- cmd = DemoTape::Command.new(val[0], "", speed: val[2], count: val[4])
402
- cmd.tokens = tokens
403
- result = attach_location(cmd, speed_index: speed_index).prepare!
354
+ tokens, start_idx = val[0]
355
+ idx_do = index_for_value(val[1])
356
+ idx_nl = index_for_value(val[2])
357
+ idx_end = index_for_value(val[5])
358
+ # Discard the LEADING_SPACE before END (val[4])
359
+ result = {
360
+ type: :group,
361
+ tokens: tokens + [make_token(:keyword, val[1], idx_do), make_token(:keyword, val[5], idx_end)],
362
+ children: [make_token(:newline, val[2], idx_nl)] + val[3],
363
+ line: line_for_token_at(start_idx),
364
+ column: column_for_token_at(start_idx)
365
+ }
404
366
 
405
367
  result
406
368
  end
407
369
  .,.,
408
370
 
409
- module_eval(<<'.,.,', 'demotape.y', 93)
371
+ module_eval(<<'.,.,', 'demotape.y', 78)
410
372
  def _reduce_13(val, _values, result)
411
- @command_start_index = @token_index - 5
412
- speed_index = @token_index - 3
413
-
414
- tokens = [
415
- make_token(:identifier, val[0], @token_index - 5),
416
- make_token(:operator, "@", @token_index - 4),
417
- make_token(:number, val[2], @token_index - 3),
418
- make_token(:number, val[4], @token_index - 1)
419
- ]
420
-
421
- cmd = DemoTape::Command.new(val[0], "", speed: "#{val[2]}s", count: val[4])
422
- cmd.tokens = tokens
423
- result = attach_location(cmd, speed_index: speed_index).prepare!
373
+ idx_lead = index_for_value(val[0])
374
+ tokens, _ = val[1]
375
+ idx_do = index_for_value(val[2])
376
+ idx_nl = index_for_value(val[3])
377
+ idx_end = index_for_value(val[5])
378
+ result = {
379
+ type: :group,
380
+ tokens: [make_token(:leading_space, val[0], idx_lead)] + tokens + [make_token(:keyword, val[2], idx_do), make_token(:keyword, val[5], idx_end)],
381
+ children: [make_token(:newline, val[3], idx_nl)] + val[4],
382
+ line: line_for_token_at(idx_lead),
383
+ column: column_for_token_at(idx_lead)
384
+ }
424
385
 
425
386
  result
426
387
  end
427
388
  .,.,
428
389
 
429
- module_eval(<<'.,.,', 'demotape.y', 108)
390
+ module_eval(<<'.,.,', 'demotape.y', 92)
430
391
  def _reduce_14(val, _values, result)
431
- @command_start_index = @token_index - 5
432
- speed_index = @token_index - 3
433
-
434
- tokens = [
435
- make_token(:identifier, val[0], @token_index - 5),
436
- make_token(:operator, "@", @token_index - 4),
437
- make_token(:number, val[2], @token_index - 3),
438
- make_token(:string, val[4], @token_index - 1)
439
- ]
440
-
441
- cmd = DemoTape::Command.new(val[0], val[4], speed: "#{val[2]}s")
442
- cmd.tokens = tokens
443
- result = attach_location(cmd, speed_index: speed_index).prepare!
392
+ idx_lead = index_for_value(val[0])
393
+ tokens, _ = val[1]
394
+ idx_do = index_for_value(val[2])
395
+ idx_nl = index_for_value(val[3])
396
+ idx_end = index_for_value(val[6])
397
+ # Discard the LEADING_SPACE before END (val[5])
398
+ result = {
399
+ type: :group,
400
+ tokens: [make_token(:leading_space, val[0], idx_lead)] + tokens + [make_token(:keyword, val[2], idx_do), make_token(:keyword, val[6], idx_end)],
401
+ children: [make_token(:newline, val[3], idx_nl)] + val[4],
402
+ line: line_for_token_at(idx_lead),
403
+ column: column_for_token_at(idx_lead)
404
+ }
444
405
 
445
406
  result
446
407
  end
447
408
  .,.,
448
409
 
449
- module_eval(<<'.,.,', 'demotape.y', 123)
410
+ module_eval(<<'.,.,', 'demotape.y', 107)
450
411
  def _reduce_15(val, _values, result)
451
- @command_start_index = @token_index - 3
452
- speed_index = @token_index - 1
453
-
454
- tokens = [
455
- make_token(:identifier, val[0], @token_index - 3),
456
- make_token(:operator, "@", @token_index - 2),
457
- make_token(:number, val[2], @token_index - 1)
458
- ]
459
-
460
- cmd = DemoTape::Command.new(val[0], "", speed: "#{val[2]}s")
461
- cmd.tokens = tokens
462
- result = attach_location(cmd, speed_index: speed_index).prepare!
412
+ tokens, start_idx = val[0]
413
+ idx_do = index_for_value(val[1])
414
+ idx_trail = index_for_value(val[2])
415
+ idx_nl = index_for_value(val[3])
416
+ idx_end = index_for_value(val[5])
417
+ result = {
418
+ type: :group,
419
+ tokens: tokens + [make_token(:keyword, val[1], idx_do), make_token(:trailing_space, val[2], idx_trail), make_token(:keyword, val[5], idx_end)],
420
+ children: [make_token(:newline, val[3], idx_nl)] + val[4],
421
+ line: line_for_token_at(start_idx),
422
+ column: column_for_token_at(start_idx)
423
+ }
463
424
 
464
425
  result
465
426
  end
466
427
  .,.,
467
428
 
468
- module_eval(<<'.,.,', 'demotape.y', 137)
429
+ module_eval(<<'.,.,', 'demotape.y', 121)
469
430
  def _reduce_16(val, _values, result)
470
- @command_start_index = @token_index - 4
471
- speed_index = @token_index - 1 # TIME_UNIT position
472
-
473
- tokens = [
474
- make_token(:identifier, val[0], @token_index - 4),
475
- make_token(:operator, "@", @token_index - 3),
476
- make_token(:duration, val[2], @token_index - 2)
477
- ]
478
-
479
- cmd = DemoTape::Command.new(val[0], "", speed: val[2])
480
- cmd.tokens = tokens
481
- result = attach_location(cmd, speed_index: speed_index).prepare!
431
+ tokens, start_idx = val[0]
432
+ idx_do = index_for_value(val[1])
433
+ idx_trail = index_for_value(val[2])
434
+ idx_nl = index_for_value(val[3])
435
+ idx_end = index_for_value(val[6])
436
+ # Discard the LEADING_SPACE before END (val[5])
437
+ result = {
438
+ type: :group,
439
+ tokens: tokens + [make_token(:keyword, val[1], idx_do), make_token(:trailing_space, val[2], idx_trail), make_token(:keyword, val[6], idx_end)],
440
+ children: [make_token(:newline, val[3], idx_nl)] + val[4],
441
+ line: line_for_token_at(start_idx),
442
+ column: column_for_token_at(start_idx)
443
+ }
482
444
 
483
445
  result
484
446
  end
485
447
  .,.,
486
448
 
487
- module_eval(<<'.,.,', 'demotape.y', 151)
449
+ module_eval(<<'.,.,', 'demotape.y', 136)
488
450
  def _reduce_17(val, _values, result)
489
- @command_start_index = @token_index - 6
490
- timeout_index = @token_index - 3 # TIME_UNIT position
491
- regex_index = @token_index - 1
492
-
493
- begin
494
- Regexp.new(val[4])
495
- rescue RegexpError => e
496
- line_info = @lexer.line_map[regex_index] || {}
497
- error_msg = "Invalid regex: #{e.message} at #{@file}:#{line_info[:line]}:#{line_info[:column]}:\n"
498
- error_msg += " #{line_info[:content]}\n"
499
- error_msg += " #{' ' * (line_info[:column] - 1)}^"
500
- raise DemoTape::ParseError, error_msg
501
- end
502
-
503
- tokens = [
504
- make_token(:identifier, val[0], @token_index - 6),
505
- make_token(:operator, "@", @token_index - 5),
506
- make_token(:duration, val[2], @token_index - 4),
507
- make_token(:regex, val[4], regex_index)
508
- ]
509
-
510
- cmd = DemoTape::Command.new(val[0], val[4], timeout: val[2])
511
- cmd.tokens = tokens
512
- result = attach_location(cmd, timeout_index: timeout_index).prepare!
451
+ idx_lead = index_for_value(val[0])
452
+ tokens, _ = val[1]
453
+ idx_do = index_for_value(val[2])
454
+ idx_trail = index_for_value(val[3])
455
+ idx_nl = index_for_value(val[4])
456
+ idx_end = index_for_value(val[7])
457
+ # Discard the LEADING_SPACE before END (val[6])
458
+ result = {
459
+ type: :group,
460
+ tokens: [make_token(:leading_space, val[0], idx_lead)] + tokens + [make_token(:keyword, val[2], idx_do), make_token(:trailing_space, val[3], idx_trail), make_token(:keyword, val[7], idx_end)],
461
+ children: [make_token(:newline, val[4], idx_nl)] + val[5],
462
+ line: line_for_token_at(idx_lead),
463
+ column: column_for_token_at(idx_lead)
464
+ }
513
465
 
514
466
  result
515
467
  end
516
468
  .,.,
517
469
 
518
- module_eval(<<'.,.,', 'demotape.y', 177)
470
+ module_eval(<<'.,.,', 'demotape.y', 152)
519
471
  def _reduce_18(val, _values, result)
520
- @command_start_index = @token_index - 3
521
- regex_index = @token_index - 1
522
-
523
- begin
524
- Regexp.new(val[2])
525
- rescue RegexpError => e
526
- line_info = @lexer.line_map[regex_index] || {}
527
- error_msg = "Invalid regex: #{e.message} at #{@file}:#{line_info[:line]}:#{line_info[:column]}:\n"
528
- error_msg += " #{line_info[:content]}\n"
529
- error_msg += " #{' ' * (line_info[:column] - 1)}^"
530
- raise DemoTape::ParseError, error_msg
531
- end
532
-
533
- tokens = [
534
- make_token(:identifier, val[0], @token_index - 3),
535
- make_token(:regex, val[2], regex_index)
536
- ]
537
-
538
- cmd = DemoTape::Command.new(val[0], val[2])
539
- cmd.tokens = tokens
540
- result = attach_location(cmd).prepare!
472
+ idx_lead = index_for_value(val[0])
473
+ tokens, _ = val[1]
474
+ idx_do = index_for_value(val[2])
475
+ idx_trail = index_for_value(val[3])
476
+ idx_nl = index_for_value(val[4])
477
+ idx_end = index_for_value(val[6])
478
+ result = {
479
+ type: :group,
480
+ tokens: [make_token(:leading_space, val[0], idx_lead)] + tokens + [make_token(:keyword, val[2], idx_do), make_token(:trailing_space, val[3], idx_trail), make_token(:keyword, val[6], idx_end)],
481
+ children: [make_token(:newline, val[4], idx_nl)] + val[5],
482
+ line: line_for_token_at(idx_lead),
483
+ column: column_for_token_at(idx_lead)
484
+ }
541
485
 
542
486
  result
543
487
  end
544
488
  .,.,
545
489
 
546
- module_eval(<<'.,.,', 'demotape.y', 200)
490
+ module_eval(<<'.,.,', 'demotape.y', 169)
547
491
  def _reduce_19(val, _values, result)
548
- @command_start_index = @token_index - 9
549
-
550
- tokens = [
551
- make_token(:identifier, val[0], @token_index - 9),
552
- make_token(:identifier, val[2], @token_index - 7),
553
- make_token(:number, val[4], @token_index - 5),
554
- make_token(:operator, ",", @token_index - 4),
555
- make_token(:number, val[6], @token_index - 3),
556
- make_token(:operator, ",", @token_index - 2),
557
- make_token(:number, val[8], @token_index - 1),
558
- make_token(:operator, ",", @token_index - 1),
559
- make_token(:number, val[10], @token_index - 1)
560
- ]
561
-
562
- cmd = DemoTape::Command.new(val[0], [val[4], val[6], val[8], val[10]], option: val[2])
563
- cmd.tokens = tokens
564
- result = attach_location(cmd).prepare!
565
-
492
+ result = []
566
493
  result
567
494
  end
568
495
  .,.,
569
496
 
570
- module_eval(<<'.,.,', 'demotape.y', 219)
497
+ module_eval(<<'.,.,', 'demotape.y', 170)
571
498
  def _reduce_20(val, _values, result)
572
- @command_start_index = @token_index - 13
573
-
574
- tokens = [
575
- make_token(:identifier, val[0], @token_index - 13),
576
- make_token(:identifier, val[2], @token_index - 11),
577
- make_token(:number, val[4], @token_index - 9),
578
- make_token(:operator, ",", @token_index - 8),
579
- make_token(:number, val[7], @token_index - 6),
580
- make_token(:operator, ",", @token_index - 5),
581
- make_token(:number, val[10], @token_index - 3),
582
- make_token(:operator, ",", @token_index - 2),
583
- make_token(:number, val[13], @token_index - 1)
584
- ]
585
-
586
- cmd = DemoTape::Command.new(val[0], [val[4], val[7], val[10], val[13]], option: val[2])
587
- cmd.tokens = tokens
588
- result = attach_location(cmd).prepare!
589
-
499
+ result = val[0].flatten.compact
590
500
  result
591
501
  end
592
502
  .,.,
593
503
 
594
- module_eval(<<'.,.,', 'demotape.y', 238)
504
+ module_eval(<<'.,.,', 'demotape.y', 172)
595
505
  def _reduce_21(val, _values, result)
596
- @command_start_index = @token_index - 7
597
-
598
- tokens = [
599
- make_token(:identifier, val[0], @token_index - 7),
600
- make_token(:identifier, val[2], @token_index - 5),
601
- make_token(:number, val[4], @token_index - 3),
602
- make_token(:operator, ",", @token_index - 2),
603
- make_token(:number, val[6], @token_index - 1),
604
- make_token(:operator, ",", @token_index - 1),
605
- make_token(:number, val[8], @token_index - 1)
606
- ]
607
-
608
- cmd = DemoTape::Command.new(val[0], [val[4], val[6], val[8]], option: val[2])
609
- cmd.tokens = tokens
610
- result = attach_location(cmd).prepare!
611
-
506
+ result = val[0]
612
507
  result
613
508
  end
614
509
  .,.,
615
510
 
616
- module_eval(<<'.,.,', 'demotape.y', 255)
511
+ module_eval(<<'.,.,', 'demotape.y', 173)
617
512
  def _reduce_22(val, _values, result)
618
- @command_start_index = @token_index - 11
619
-
620
- tokens = [
621
- make_token(:identifier, val[0], @token_index - 11),
622
- make_token(:identifier, val[2], @token_index - 9),
623
- make_token(:number, val[4], @token_index - 7),
624
- make_token(:operator, ",", @token_index - 6),
625
- make_token(:number, val[7], @token_index - 4),
626
- make_token(:operator, ",", @token_index - 3),
627
- make_token(:number, val[10], @token_index - 1)
628
- ]
629
-
630
- cmd = DemoTape::Command.new(val[0], [val[4], val[7], val[10]], option: val[2])
631
- cmd.tokens = tokens
632
- result = attach_location(cmd).prepare!
633
-
513
+ result = val[0] + val[1]
634
514
  result
635
515
  end
636
516
  .,.,
637
517
 
638
- module_eval(<<'.,.,', 'demotape.y', 272)
518
+ module_eval(<<'.,.,', 'demotape.y', 177)
639
519
  def _reduce_23(val, _values, result)
640
- @command_start_index = @token_index - 5
641
-
642
- tokens = [
643
- make_token(:identifier, val[0], @token_index - 5),
644
- make_token(:identifier, val[2], @token_index - 3),
645
- make_token(:number, val[4], @token_index - 1),
646
- make_token(:operator, ",", @token_index - 1),
647
- make_token(:number, val[6], @token_index - 1)
648
- ]
649
-
650
- cmd = DemoTape::Command.new(val[0], [val[4], val[6]], option: val[2])
651
- cmd.tokens = tokens
652
- result = attach_location(cmd).prepare!
520
+ result = [
521
+ make_token(:comment, val[0], index_for_value(val[0])),
522
+ make_token(:newline, val[1], index_for_value(val[1]))
523
+ ]
653
524
 
654
525
  result
655
526
  end
656
527
  .,.,
657
528
 
658
- module_eval(<<'.,.,', 'demotape.y', 287)
529
+ module_eval(<<'.,.,', 'demotape.y', 182)
659
530
  def _reduce_24(val, _values, result)
660
- @command_start_index = @token_index - 8
661
-
662
- tokens = [
663
- make_token(:identifier, val[0], @token_index - 8),
664
- make_token(:identifier, val[2], @token_index - 6),
665
- make_token(:number, val[4], @token_index - 4),
666
- make_token(:operator, ",", @token_index - 3),
667
- make_token(:number, val[7], @token_index - 1)
668
- ]
669
-
670
- cmd = DemoTape::Command.new(val[0], [val[4], val[7]], option: val[2])
671
- cmd.tokens = tokens
672
- result = attach_location(cmd).prepare!
673
-
531
+ result = [make_token(:newline, val[0], index_for_value(val[0]))]
674
532
  result
675
533
  end
676
534
  .,.,
677
535
 
678
- module_eval(<<'.,.,', 'demotape.y', 302)
536
+ module_eval(<<'.,.,', 'demotape.y', 184)
679
537
  def _reduce_25(val, _values, result)
680
- @command_start_index = @token_index - 6
681
-
682
- tokens = [
683
- make_token(:identifier, val[0], @token_index - 6),
684
- make_token(:identifier, val[2], @token_index - 4),
685
- make_token(:duration, val[4], @token_index - 2)
686
- ]
687
-
688
- cmd = DemoTape::Command.new(val[0], val[4], option: val[2])
689
- cmd.tokens = tokens
690
- result = attach_location(cmd).prepare!
538
+ tokens, start_idx = val[0]
539
+ result = [
540
+ { type: :command, tokens: tokens, line: line_for_token_at(start_idx), column: column_for_token_at(start_idx) },
541
+ make_token(:newline, val[1], index_for_value(val[1]))
542
+ ]
691
543
 
692
544
  result
693
545
  end
694
546
  .,.,
695
547
 
696
- module_eval(<<'.,.,', 'demotape.y', 315)
548
+ module_eval(<<'.,.,', 'demotape.y', 191)
697
549
  def _reduce_26(val, _values, result)
698
- @command_start_index = @token_index - 5
699
-
700
- tokens = [
701
- make_token(:identifier, val[0], @token_index - 5),
702
- make_token(:identifier, val[2], @token_index - 3),
703
- make_token(:number, val[4], @token_index - 1)
704
- ]
705
-
706
- cmd = DemoTape::Command.new(val[0], val[4].to_s, option: val[2])
707
- cmd.tokens = tokens
708
- result = attach_location(cmd).prepare!
550
+ idx_lead = index_for_value(val[0])
551
+ tokens, _ = val[1]
552
+ result = [
553
+ { type: :command, tokens: [make_token(:leading_space, val[0], idx_lead)] + tokens, line: line_for_token_at(idx_lead), column: column_for_token_at(idx_lead) },
554
+ make_token(:newline, val[2], index_for_value(val[2]))
555
+ ]
709
556
 
710
557
  result
711
558
  end
712
559
  .,.,
713
560
 
714
- module_eval(<<'.,.,', 'demotape.y', 328)
561
+ module_eval(<<'.,.,', 'demotape.y', 199)
715
562
  def _reduce_27(val, _values, result)
716
- @command_start_index = @token_index - 5
717
-
718
- tokens = [
719
- make_token(:identifier, val[0], @token_index - 5),
720
- make_token(:identifier, val[2], @token_index - 3),
721
- make_token(:identifier, val[4], @token_index - 1)
722
- ]
723
-
724
- cmd = DemoTape::Command.new(val[0], val[4], option: val[2])
725
- cmd.tokens = tokens
726
- result = attach_location(cmd).prepare!
563
+ result = [
564
+ make_token(:leading_space, val[0], index_for_value(val[0])),
565
+ make_token(:comment, val[1], index_for_value(val[1])),
566
+ make_token(:newline, val[2], index_for_value(val[2]))
567
+ ]
727
568
 
728
569
  result
729
570
  end
730
571
  .,.,
731
572
 
732
- module_eval(<<'.,.,', 'demotape.y', 341)
573
+ module_eval(<<'.,.,', 'demotape.y', 208)
733
574
  def _reduce_28(val, _values, result)
734
- @command_start_index = @token_index - 5
735
-
736
- tokens = [
737
- make_token(:identifier, val[0], @token_index - 5),
738
- make_token(:identifier, val[2], @token_index - 3),
739
- make_token(:string, val[4], @token_index - 1)
740
- ]
741
-
742
- cmd = DemoTape::Command.new(val[0], val[4], option: val[2])
743
- cmd.tokens = tokens
744
- result = attach_location(cmd).prepare!
745
-
575
+ result = [[val[0][:token]], val[0][:index]]
746
576
  result
747
577
  end
748
578
  .,.,
749
579
 
750
- module_eval(<<'.,.,', 'demotape.y', 354)
580
+ module_eval(<<'.,.,', 'demotape.y', 209)
751
581
  def _reduce_29(val, _values, result)
752
- @command_start_index = @token_index - 3
753
-
754
- tokens = [
755
- make_token(:identifier, val[0], @token_index - 3),
756
- make_token(:string, val[2], @token_index - 1)
757
- ]
758
-
759
- cmd = DemoTape::Command.new(val[0], val[2])
760
- cmd.tokens = tokens
761
- result = attach_location(cmd).prepare!
762
-
582
+ result = [val[0][0] << val[1][:token], val[0][1]]
763
583
  result
764
584
  end
765
585
  .,.,
766
586
 
767
- module_eval(<<'.,.,', 'demotape.y', 366)
587
+ module_eval(<<'.,.,', 'demotape.y', 211)
768
588
  def _reduce_30(val, _values, result)
769
- @command_start_index = @token_index - 4
770
- duration_index = @token_index - 1 # TIME_UNIT position
771
-
772
- tokens = [
773
- make_token(:identifier, val[0], @token_index - 4),
774
- make_token(:duration, val[2], @token_index - 2)
775
- ]
776
-
777
- cmd = DemoTape::Command.new(val[0], val[2])
778
- cmd.tokens = tokens
779
- result = attach_location(cmd, duration_index: duration_index).prepare!
780
-
589
+ idx = index_for_value(val[0]); result = { token: make_token(:identifier, val[0], idx), index: idx }
781
590
  result
782
591
  end
783
592
  .,.,
784
593
 
785
- module_eval(<<'.,.,', 'demotape.y', 379)
594
+ module_eval(<<'.,.,', 'demotape.y', 212)
786
595
  def _reduce_31(val, _values, result)
787
- @command_start_index = @token_index - 2
788
-
789
- tokens = [make_token(:identifier, val[0], @token_index - 2)]
790
-
791
- cmd = DemoTape::Command.new(val[0], "")
792
- cmd.tokens = tokens
793
- result = attach_location(cmd).prepare!
794
-
596
+ idx = index_for_value(val[0]); result = { token: make_token(:string, val[0], idx), index: idx }
795
597
  result
796
598
  end
797
599
  .,.,
798
600
 
799
- module_eval(<<'.,.,', 'demotape.y', 389)
601
+ module_eval(<<'.,.,', 'demotape.y', 213)
800
602
  def _reduce_32(val, _values, result)
801
- @last_key_index = @token_index - 1
802
-
803
- tokens = [
804
- make_token(:identifier, val[0], @token_index - 3),
805
- make_token(:operator, "+", @token_index - 2),
806
- make_token(:identifier, val[2], @token_index - 1)
807
- ]
808
-
809
- result = { keys: [val[0], val[2]], tokens: tokens }
810
-
603
+ idx = index_for_value(val[0]); result = { token: make_token(:multiline_string, val[0], idx), index: idx }
811
604
  result
812
605
  end
813
606
  .,.,
814
607
 
815
- module_eval(<<'.,.,', 'demotape.y', 400)
608
+ module_eval(<<'.,.,', 'demotape.y', 214)
816
609
  def _reduce_33(val, _values, result)
817
- @last_key_index = @token_index - 1
818
-
819
- tokens = [
820
- make_token(:identifier, val[0], @token_index - 3),
821
- make_token(:operator, "+", @token_index - 2),
822
- make_token(:number, val[2], @token_index - 1)
823
- ]
824
-
825
- result = { keys: [val[0], val[2].to_s], tokens: tokens }
826
-
610
+ idx = index_for_value(val[0]); result = { token: make_token(:number, val[0], idx), index: idx }
827
611
  result
828
612
  end
829
613
  .,.,
830
614
 
831
- module_eval(<<'.,.,', 'demotape.y', 411)
615
+ module_eval(<<'.,.,', 'demotape.y', 215)
832
616
  def _reduce_34(val, _values, result)
833
- @last_key_index = @token_index - 1
834
-
835
- tokens = val[0][:tokens] + [
836
- make_token(:operator, "+", @token_index - 2),
837
- make_token(:identifier, val[2], @token_index - 1)
838
- ]
839
-
840
- result = { keys: val[0][:keys] << val[2], tokens: tokens }
841
-
617
+ idx = index_for_value(val[0]); result = { token: make_token(:duration, val[0], idx), index: idx }
842
618
  result
843
619
  end
844
620
  .,.,
845
621
 
846
- module_eval(<<'.,.,', 'demotape.y', 421)
622
+ module_eval(<<'.,.,', 'demotape.y', 216)
847
623
  def _reduce_35(val, _values, result)
848
- @last_key_index = @token_index - 1
849
-
850
- tokens = val[0][:tokens] + [
851
- make_token(:operator, "+", @token_index - 2),
852
- make_token(:number, val[2], @token_index - 1)
853
- ]
854
-
855
- result = { keys: val[0][:keys] << val[2].to_s, tokens: tokens }
856
-
624
+ idx = index_for_value(val[0]); result = { token: make_token(:regex, val[0], idx), index: idx }
857
625
  result
858
626
  end
859
627
  .,.,
860
628
 
861
- module_eval(<<'.,.,', 'demotape.y', 431)
629
+ module_eval(<<'.,.,', 'demotape.y', 217)
862
630
  def _reduce_36(val, _values, result)
863
- result = val[0]
631
+ idx = index_for_value(val[0]); result = { token: make_token(:space, val[0], idx), index: idx }
864
632
  result
865
633
  end
866
634
  .,.,
867
635
 
868
- module_eval(<<'.,.,', 'demotape.y', 432)
636
+ module_eval(<<'.,.,', 'demotape.y', 218)
869
637
  def _reduce_37(val, _values, result)
870
- result = val[0]
638
+ idx = index_for_value(val[0]); result = { token: make_token(:trailing_space, val[0], idx), index: idx }
871
639
  result
872
640
  end
873
641
  .,.,
874
642
 
875
- module_eval(<<'.,.,', 'demotape.y', 434)
643
+ module_eval(<<'.,.,', 'demotape.y', 219)
876
644
  def _reduce_38(val, _values, result)
877
- result = "#{val[0]}#{val[1]}"
645
+ idx = index_for_value(val[0]); result = { token: make_token(:operator, ",", idx), index: idx }
646
+ result
647
+ end
648
+ .,.,
649
+
650
+ module_eval(<<'.,.,', 'demotape.y', 220)
651
+ def _reduce_39(val, _values, result)
652
+ idx = index_for_value(val[0]); result = { token: make_token(:operator, "+", idx), index: idx }
653
+ result
654
+ end
655
+ .,.,
656
+
657
+ module_eval(<<'.,.,', 'demotape.y', 221)
658
+ def _reduce_40(val, _values, result)
659
+ idx = index_for_value(val[0]); result = { token: make_token(:operator, "@", idx), index: idx }
660
+ result
661
+ end
662
+ .,.,
663
+
664
+ module_eval(<<'.,.,', 'demotape.y', 222)
665
+ def _reduce_41(val, _values, result)
666
+ idx = index_for_value(val[0]); result = { token: make_token(:time_unit, val[0], idx), index: idx }
878
667
  result
879
668
  end
880
669
  .,.,