stupidedi 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (500) hide show
  1. data/README.md +215 -0
  2. data/Rakefile +108 -0
  3. data/bin/edi-ed +71 -0
  4. data/bin/edi-pp +81 -0
  5. data/doc/Defining.md +0 -0
  6. data/doc/Generating.md +321 -0
  7. data/doc/LICENSE.md +0 -0
  8. data/doc/Navigating.md +645 -0
  9. data/doc/Parsing.md +0 -0
  10. data/doc/Serializing.md +7 -0
  11. data/doc/Tokenizing.md +0 -0
  12. data/doc/Validating.md +0 -0
  13. data/doc/design/Parser.md +0 -0
  14. data/doc/design/Reader.md +0 -0
  15. data/lib/ruby/array.rb +164 -0
  16. data/lib/ruby/blank.rb +67 -0
  17. data/lib/ruby/enumerable.rb +35 -0
  18. data/lib/ruby/exception.rb +33 -0
  19. data/lib/ruby/hash.rb +4 -0
  20. data/lib/ruby/instance_exec.rb +26 -0
  21. data/lib/ruby/module.rb +79 -0
  22. data/lib/ruby/object.rb +63 -0
  23. data/lib/ruby/string.rb +73 -0
  24. data/lib/ruby/symbol.rb +24 -0
  25. data/lib/ruby/to_d.rb +81 -0
  26. data/lib/ruby/to_date.rb +33 -0
  27. data/lib/ruby/to_time.rb +24 -0
  28. data/lib/ruby/try.rb +43 -0
  29. data/lib/stupidedi/blank_slate.rb +11 -0
  30. data/lib/stupidedi/builder/builder_dsl.rb +281 -0
  31. data/lib/stupidedi/builder/constraint_table.rb +418 -0
  32. data/lib/stupidedi/builder/generation.rb +112 -0
  33. data/lib/stupidedi/builder/instruction.rb +102 -0
  34. data/lib/stupidedi/builder/instruction_table.rb +204 -0
  35. data/lib/stupidedi/builder/navigation.rb +655 -0
  36. data/lib/stupidedi/builder/state_machine.rb +55 -0
  37. data/lib/stupidedi/builder/states/abstract_state.rb +332 -0
  38. data/lib/stupidedi/builder/states/failure_state.rb +69 -0
  39. data/lib/stupidedi/builder/states/functional_group_state.rb +97 -0
  40. data/lib/stupidedi/builder/states/initial_state.rb +63 -0
  41. data/lib/stupidedi/builder/states/interchange_state.rb +94 -0
  42. data/lib/stupidedi/builder/states/loop_state.rb +79 -0
  43. data/lib/stupidedi/builder/states/table_state.rb +96 -0
  44. data/lib/stupidedi/builder/states/transaction_set_state.rb +112 -0
  45. data/lib/stupidedi/builder/states/transmission_state.rb +59 -0
  46. data/lib/stupidedi/builder/tokenization.rb +196 -0
  47. data/lib/stupidedi/builder.rb +23 -0
  48. data/lib/stupidedi/color.rb +93 -0
  49. data/lib/stupidedi/config/code_list_config.rb +42 -0
  50. data/lib/stupidedi/config/editor_config.rb +51 -0
  51. data/lib/stupidedi/config/functional_group_config.rb +62 -0
  52. data/lib/stupidedi/config/interchange_config.rb +79 -0
  53. data/lib/stupidedi/config/transaction_set_config.rb +91 -0
  54. data/lib/stupidedi/config.rb +101 -0
  55. data/lib/stupidedi/editor/00501.rb +341 -0
  56. data/lib/stupidedi/editor/005010/N2.rb +0 -0
  57. data/lib/stupidedi/editor/005010/N3.rb +0 -0
  58. data/lib/stupidedi/editor/005010/N4.rb +63 -0
  59. data/lib/stupidedi/editor/005010/NM1.rb +0 -0
  60. data/lib/stupidedi/editor/005010.rb +469 -0
  61. data/lib/stupidedi/editor/X222-HC837.rb +195 -0
  62. data/lib/stupidedi/editor/abstract_ed.rb +36 -0
  63. data/lib/stupidedi/editor/claim_ack.rb +9 -0
  64. data/lib/stupidedi/editor/implementation_ack.rb +213 -0
  65. data/lib/stupidedi/editor/interchange_ack.rb +9 -0
  66. data/lib/stupidedi/editor/result.rb +100 -0
  67. data/lib/stupidedi/editor/result_set.rb +69 -0
  68. data/lib/stupidedi/editor/transaction_set_ed.rb +275 -0
  69. data/lib/stupidedi/editor/transmission_ed.rb +90 -0
  70. data/lib/stupidedi/editor.rb +37 -0
  71. data/lib/stupidedi/either.rb +287 -0
  72. data/lib/stupidedi/exceptions/invalid_element_error.rb +8 -0
  73. data/lib/stupidedi/exceptions/invalid_schema_error.rb +8 -0
  74. data/lib/stupidedi/exceptions/output_error.rb +8 -0
  75. data/lib/stupidedi/exceptions/parse_error.rb +8 -0
  76. data/lib/stupidedi/exceptions/stupidedi_error.rb +8 -0
  77. data/lib/stupidedi/exceptions/tokenize_error.rb +8 -0
  78. data/lib/stupidedi/exceptions/zipper_error.rb +8 -0
  79. data/lib/stupidedi/exceptions.rb +11 -0
  80. data/lib/stupidedi/guides/005010/X214-HN277.rb +409 -0
  81. data/lib/stupidedi/guides/005010/X221-HP835.rb +613 -0
  82. data/lib/stupidedi/guides/005010/X221A1-HP835.rb +613 -0
  83. data/lib/stupidedi/guides/005010/X222-HC837P.rb +2291 -0
  84. data/lib/stupidedi/guides/005010/X222A1-HC837P.rb +2297 -0
  85. data/lib/stupidedi/guides/005010/X231-FA999.rb +123 -0
  86. data/lib/stupidedi/guides/005010/X231A1-FA999.rb +119 -0
  87. data/lib/stupidedi/guides/005010/element_reqs.rb +38 -0
  88. data/lib/stupidedi/guides/005010/guide_builder.rb +180 -0
  89. data/lib/stupidedi/guides/005010/segment_reqs.rb +32 -0
  90. data/lib/stupidedi/guides/005010.rb +64 -0
  91. data/lib/stupidedi/guides.rb +5 -0
  92. data/lib/stupidedi/inspect.rb +26 -0
  93. data/lib/stupidedi/reader/input/abstract_input.rb +133 -0
  94. data/lib/stupidedi/reader/input/delegated_input.rb +111 -0
  95. data/lib/stupidedi/reader/input/file_input.rb +155 -0
  96. data/lib/stupidedi/reader/input.rb +30 -0
  97. data/lib/stupidedi/reader/position.rb +69 -0
  98. data/lib/stupidedi/reader/result.rb +168 -0
  99. data/lib/stupidedi/reader/segment_dict.rb +175 -0
  100. data/lib/stupidedi/reader/separators.rb +85 -0
  101. data/lib/stupidedi/reader/stream_reader.rb +172 -0
  102. data/lib/stupidedi/reader/token_reader.rb +466 -0
  103. data/lib/stupidedi/reader/tokens/component_element_tok.rb +56 -0
  104. data/lib/stupidedi/reader/tokens/composite_element_tok.rb +64 -0
  105. data/lib/stupidedi/reader/tokens/repeated_element_tok.rb +64 -0
  106. data/lib/stupidedi/reader/tokens/segment_tok.rb +51 -0
  107. data/lib/stupidedi/reader/tokens/simple_element_tok.rb +63 -0
  108. data/lib/stupidedi/reader.rb +121 -0
  109. data/lib/stupidedi/schema/abstract_def.rb +74 -0
  110. data/lib/stupidedi/schema/abstract_use.rb +73 -0
  111. data/lib/stupidedi/schema/code_list.rb +94 -0
  112. data/lib/stupidedi/schema/element_def.rb +173 -0
  113. data/lib/stupidedi/schema/element_req.rb +56 -0
  114. data/lib/stupidedi/schema/element_use.rb +251 -0
  115. data/lib/stupidedi/schema/functional_group_def.rb +114 -0
  116. data/lib/stupidedi/schema/interchange_def.rb +93 -0
  117. data/lib/stupidedi/schema/loop_def.rb +152 -0
  118. data/lib/stupidedi/schema/repeat_count.rb +85 -0
  119. data/lib/stupidedi/schema/segment_def.rb +108 -0
  120. data/lib/stupidedi/schema/segment_req.rb +43 -0
  121. data/lib/stupidedi/schema/segment_use.rb +98 -0
  122. data/lib/stupidedi/schema/syntax_note.rb +63 -0
  123. data/lib/stupidedi/schema/table_def.rb +139 -0
  124. data/lib/stupidedi/schema/transaction_set_def.rb +88 -0
  125. data/lib/stupidedi/schema.rb +28 -0
  126. data/lib/stupidedi/sets/absolute_set.rb +297 -0
  127. data/lib/stupidedi/sets/abstract_set.rb +174 -0
  128. data/lib/stupidedi/sets/null_set.rb +125 -0
  129. data/lib/stupidedi/sets/relative_complement.rb +137 -0
  130. data/lib/stupidedi/sets/relative_set.rb +269 -0
  131. data/lib/stupidedi/sets/universal_set.rb +104 -0
  132. data/lib/stupidedi/sets.rb +57 -0
  133. data/lib/stupidedi/tail_call.rb +109 -0
  134. data/lib/stupidedi/thread_local.rb +174 -0
  135. data/lib/stupidedi/values/abstract_element_val.rb +19 -0
  136. data/lib/stupidedi/values/abstract_val.rb +130 -0
  137. data/lib/stupidedi/values/composite_element_val.rb +95 -0
  138. data/lib/stupidedi/values/functional_group_val.rb +102 -0
  139. data/lib/stupidedi/values/interchange_val.rb +86 -0
  140. data/lib/stupidedi/values/invalid_envelope_val.rb +61 -0
  141. data/lib/stupidedi/values/invalid_segment_val.rb +78 -0
  142. data/lib/stupidedi/values/loop_val.rb +70 -0
  143. data/lib/stupidedi/values/repeated_element_val.rb +105 -0
  144. data/lib/stupidedi/values/segment_val.rb +104 -0
  145. data/lib/stupidedi/values/segment_val_group.rb +20 -0
  146. data/lib/stupidedi/values/simple_element_val.rb +80 -0
  147. data/lib/stupidedi/values/table_val.rb +66 -0
  148. data/lib/stupidedi/values/transaction_set_val.rb +66 -0
  149. data/lib/stupidedi/values/transmission_val.rb +52 -0
  150. data/lib/stupidedi/values.rb +21 -0
  151. data/lib/stupidedi/version.rb +3 -0
  152. data/lib/stupidedi/versions/functional_groups/004010/element_defs.rb +54 -0
  153. data/lib/stupidedi/versions/functional_groups/004010/element_reqs.rb +18 -0
  154. data/lib/stupidedi/versions/functional_groups/004010/element_types/date_val.rb +527 -0
  155. data/lib/stupidedi/versions/functional_groups/004010/element_types/fixnum_val.rb +335 -0
  156. data/lib/stupidedi/versions/functional_groups/004010/element_types/float_val.rb +299 -0
  157. data/lib/stupidedi/versions/functional_groups/004010/element_types/identifier_val.rb +287 -0
  158. data/lib/stupidedi/versions/functional_groups/004010/element_types/string_val.rb +338 -0
  159. data/lib/stupidedi/versions/functional_groups/004010/element_types/time_val.rb +309 -0
  160. data/lib/stupidedi/versions/functional_groups/004010/element_types.rb +124 -0
  161. data/lib/stupidedi/versions/functional_groups/004010/functional_group_def.rb +30 -0
  162. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GE.rb +20 -0
  163. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/GS.rb +27 -0
  164. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/SE.rb +20 -0
  165. data/lib/stupidedi/versions/functional_groups/004010/segment_defs/ST.rb +20 -0
  166. data/lib/stupidedi/versions/functional_groups/004010/segment_defs.rb +23 -0
  167. data/lib/stupidedi/versions/functional_groups/004010/segment_reqs.rb +18 -0
  168. data/lib/stupidedi/versions/functional_groups/004010/syntax_notes.rb +174 -0
  169. data/lib/stupidedi/versions/functional_groups/004010.rb +38 -0
  170. data/lib/stupidedi/versions/functional_groups/005010/element_defs.rb +1405 -0
  171. data/lib/stupidedi/versions/functional_groups/005010/element_reqs.rb +18 -0
  172. data/lib/stupidedi/versions/functional_groups/005010/element_types/date_val.rb +577 -0
  173. data/lib/stupidedi/versions/functional_groups/005010/element_types/fixnum_val.rb +322 -0
  174. data/lib/stupidedi/versions/functional_groups/005010/element_types/float_val.rb +354 -0
  175. data/lib/stupidedi/versions/functional_groups/005010/element_types/identifier_val.rb +368 -0
  176. data/lib/stupidedi/versions/functional_groups/005010/element_types/operators.rb +117 -0
  177. data/lib/stupidedi/versions/functional_groups/005010/element_types/string_val.rb +398 -0
  178. data/lib/stupidedi/versions/functional_groups/005010/element_types/time_val.rb +327 -0
  179. data/lib/stupidedi/versions/functional_groups/005010/element_types.rb +132 -0
  180. data/lib/stupidedi/versions/functional_groups/005010/functional_group_def.rb +30 -0
  181. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK1.rb +21 -0
  182. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK2.rb +21 -0
  183. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AK9.rb +28 -0
  184. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/AMT.rb +21 -0
  185. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BHT.rb +24 -0
  186. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/BPR.rb +49 -0
  187. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CAS.rb +56 -0
  188. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CL1.rb +22 -0
  189. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLM.rb +41 -0
  190. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CLP.rb +34 -0
  191. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CN1.rb +24 -0
  192. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR1.rb +32 -0
  193. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR2.rb +35 -0
  194. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CR3.rb +25 -0
  195. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CRC.rb +26 -0
  196. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTP.rb +36 -0
  197. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CTX.rb +24 -0
  198. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/CUR.rb +57 -0
  199. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DMG.rb +34 -0
  200. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN1.rb +22 -0
  201. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DN2.rb +24 -0
  202. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTM.rb +24 -0
  203. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/DTP.rb +21 -0
  204. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/FRM.rb +25 -0
  205. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GE.rb +20 -0
  206. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/GS.rb +27 -0
  207. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HCP.rb +39 -0
  208. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HI.rb +31 -0
  209. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/HL.rb +22 -0
  210. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK3.rb +22 -0
  211. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK4.rb +22 -0
  212. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/IK5.rb +24 -0
  213. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/K3.rb +21 -0
  214. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LIN.rb +69 -0
  215. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LQ.rb +22 -0
  216. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/LX.rb +19 -0
  217. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MEA.rb +39 -0
  218. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MIA.rb +45 -0
  219. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/MOA.rb +28 -0
  220. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N1.rb +24 -0
  221. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N2.rb +20 -0
  222. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N3.rb +20 -0
  223. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/N4.rb +30 -0
  224. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NM1.rb +35 -0
  225. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/NTE.rb +20 -0
  226. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/OI.rb +24 -0
  227. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PAT.rb +31 -0
  228. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PER.rb +32 -0
  229. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PLB.rb +40 -0
  230. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PRV.rb +26 -0
  231. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PS1.rb +21 -0
  232. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/PWK.rb +30 -0
  233. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/QTY.rb +25 -0
  234. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/RDM.rb +23 -0
  235. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/REF.rb +23 -0
  236. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SBR.rb +28 -0
  237. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SE.rb +20 -0
  238. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/ST.rb +21 -0
  239. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/STC.rb +30 -0
  240. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV1.rb +44 -0
  241. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV2.rb +29 -0
  242. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV3.rb +30 -0
  243. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SV5.rb +29 -0
  244. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVC.rb +26 -0
  245. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/SVD.rb +24 -0
  246. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TOO.rb +21 -0
  247. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TRN.rb +22 -0
  248. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS2.rb +40 -0
  249. data/lib/stupidedi/versions/functional_groups/005010/segment_defs/TS3.rb +45 -0
  250. data/lib/stupidedi/versions/functional_groups/005010/segment_defs.rb +227 -0
  251. data/lib/stupidedi/versions/functional_groups/005010/segment_reqs.rb +18 -0
  252. data/lib/stupidedi/versions/functional_groups/005010/syntax_notes.rb +165 -0
  253. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/FA999.rb +38 -0
  254. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HB271.rb +85 -0
  255. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HC837.rb +163 -0
  256. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HI278.rb +64 -0
  257. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HN277.rb +74 -0
  258. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HP835.rb +68 -0
  259. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HR276.rb +57 -0
  260. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/HS270.rb +53 -0
  261. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs/RA820.rb +240 -0
  262. data/lib/stupidedi/versions/functional_groups/005010/transaction_set_defs.rb +68 -0
  263. data/lib/stupidedi/versions/functional_groups/005010.rb +38 -0
  264. data/lib/stupidedi/versions/functional_groups.rb +8 -0
  265. data/lib/stupidedi/versions/interchanges/00401/element_defs.rb +224 -0
  266. data/lib/stupidedi/versions/interchanges/00401/interchange_def.rb +45 -0
  267. data/lib/stupidedi/versions/interchanges/00401/segment_defs/IEA.rb +20 -0
  268. data/lib/stupidedi/versions/interchanges/00401/segment_defs/ISA.rb +34 -0
  269. data/lib/stupidedi/versions/interchanges/00401/segment_defs/TA1.rb +23 -0
  270. data/lib/stupidedi/versions/interchanges/00401/segment_defs.rb +28 -0
  271. data/lib/stupidedi/versions/interchanges/00401.rb +23 -0
  272. data/lib/stupidedi/versions/interchanges/00501/element_defs.rb +269 -0
  273. data/lib/stupidedi/versions/interchanges/00501/interchange_def.rb +47 -0
  274. data/lib/stupidedi/versions/interchanges/00501/segment_defs/IEA.rb +20 -0
  275. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISA.rb +34 -0
  276. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISB.rb +18 -0
  277. data/lib/stupidedi/versions/interchanges/00501/segment_defs/ISE.rb +18 -0
  278. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA1.rb +23 -0
  279. data/lib/stupidedi/versions/interchanges/00501/segment_defs/TA3.rb +18 -0
  280. data/lib/stupidedi/versions/interchanges/00501/segment_defs.rb +37 -0
  281. data/lib/stupidedi/versions/interchanges/00501.rb +23 -0
  282. data/lib/stupidedi/versions/interchanges.rb +8 -0
  283. data/lib/stupidedi/versions.rb +6 -0
  284. data/lib/stupidedi/writer/claredi.rb +142 -0
  285. data/lib/stupidedi/writer/default.rb +124 -0
  286. data/lib/stupidedi/writer.rb +6 -0
  287. data/lib/stupidedi/zipper/abstract_cursor.rb +351 -0
  288. data/lib/stupidedi/zipper/dangling_cursor.rb +103 -0
  289. data/lib/stupidedi/zipper/edited_cursor.rb +157 -0
  290. data/lib/stupidedi/zipper/memoized_cursor.rb +131 -0
  291. data/lib/stupidedi/zipper/path.rb +124 -0
  292. data/lib/stupidedi/zipper/root_cursor.rb +120 -0
  293. data/lib/stupidedi/zipper.rb +25 -0
  294. data/lib/stupidedi.rb +66 -0
  295. data/spec/examples/integration/generating.example +551 -0
  296. data/spec/examples/integration/navigating.example +214 -0
  297. data/spec/examples/integration/parsing.example +445 -0
  298. data/spec/examples/ruby/array.example +476 -0
  299. data/spec/examples/ruby/blank.example +62 -0
  300. data/spec/examples/ruby/count.example +68 -0
  301. data/spec/examples/ruby/object.example +99 -0
  302. data/spec/examples/ruby/string.example +111 -0
  303. data/spec/examples/ruby/symbol.example +117 -0
  304. data/spec/examples/ruby/to_d.example +90 -0
  305. data/spec/examples/ruby/try.example +50 -0
  306. data/spec/examples/stupidedi/either.example +375 -0
  307. data/spec/examples/stupidedi/reader/failure.example +68 -0
  308. data/spec/examples/stupidedi/reader/input/delegated_input.example +292 -0
  309. data/spec/examples/stupidedi/reader/separators.example +73 -0
  310. data/spec/examples/stupidedi/reader/stream_reader.example +48 -0
  311. data/spec/examples/stupidedi/reader/success.example +34 -0
  312. data/spec/examples/stupidedi/reader/token_reader.example +775 -0
  313. data/spec/examples/stupidedi/reader.example +168 -0
  314. data/spec/examples/stupidedi/sets/absolute_set.example +1577 -0
  315. data/spec/examples/stupidedi/sets/null_set.example +2 -0
  316. data/spec/examples/stupidedi/sets/relative_set.example +2 -0
  317. data/spec/examples/stupidedi/sets/universal_set.example +1 -0
  318. data/spec/examples/stupidedi/versions/005010/element_types/an.example +201 -0
  319. data/spec/examples/stupidedi/versions/005010/element_types/dt.example +258 -0
  320. data/spec/examples/stupidedi/versions/005010/element_types/id.example +192 -0
  321. data/spec/examples/stupidedi/versions/005010/element_types/nn.example +177 -0
  322. data/spec/examples/stupidedi/versions/005010/element_types/r.example +178 -0
  323. data/spec/examples/stupidedi/versions/005010/element_types/tm.example +2 -0
  324. data/spec/examples/stupidedi/zipper/abstract_cursor.example +417 -0
  325. data/spec/examples/stupidedi/zipper.example +9 -0
  326. data/spec/fixtures/X186-AG824/1-bad.txt +21 -0
  327. data/spec/fixtures/X186-AG824/1-good.txt +17 -0
  328. data/spec/fixtures/X186-AG824/2-bad.txt +26 -0
  329. data/spec/fixtures/X186-AG824/2-good.txt +21 -0
  330. data/spec/fixtures/X186-AG824/3-bad.txt +87 -0
  331. data/spec/fixtures/X186-AG824/3-good.txt +61 -0
  332. data/spec/fixtures/X212-HN277/1-bad.txt +54 -0
  333. data/spec/fixtures/X212-HN277/1-good.txt +46 -0
  334. data/spec/fixtures/X212-HN277/2-bad.txt +37 -0
  335. data/spec/fixtures/X212-HN277/2-good.txt +29 -0
  336. data/spec/fixtures/X212-HN277/3-bad.txt +22 -0
  337. data/spec/fixtures/X212-HN277/3-good.txt +17 -0
  338. data/spec/fixtures/X212-HN277/4-bad.txt +30 -0
  339. data/spec/fixtures/X212-HN277/4-good.txt +24 -0
  340. data/spec/fixtures/X212-HR276/1-bad.txt +53 -0
  341. data/spec/fixtures/X212-HR276/1-good.txt +46 -0
  342. data/spec/fixtures/X212-HR276/2-bad.txt +45 -0
  343. data/spec/fixtures/X212-HR276/2-good.txt +38 -0
  344. data/spec/fixtures/X212-HR276/3-bad.txt +32 -0
  345. data/spec/fixtures/X212-HR276/3-good.txt +26 -0
  346. data/spec/fixtures/X212-HR276/4-bad.txt +32 -0
  347. data/spec/fixtures/X212-HR276/4-good.txt +26 -0
  348. data/spec/fixtures/X214-HN277/1-bad.txt +58 -0
  349. data/spec/fixtures/X214-HN277/1-good.txt +47 -0
  350. data/spec/fixtures/X214-HN277/2-bad.txt +34 -0
  351. data/spec/fixtures/X214-HN277/2-good.txt +22 -0
  352. data/spec/fixtures/X214-HN277/3-bad.txt +64 -0
  353. data/spec/fixtures/X214-HN277/3-good.txt +54 -0
  354. data/spec/fixtures/X214-HN277/4-bad.txt +77 -0
  355. data/spec/fixtures/X214-HN277/4-good.txt +63 -0
  356. data/spec/fixtures/X216-HI278/1-bad.txt +42 -0
  357. data/spec/fixtures/X216-HI278/1-good.txt +27 -0
  358. data/spec/fixtures/X216-HI278/2-bad.txt +43 -0
  359. data/spec/fixtures/X216-HI278/2-good.txt +29 -0
  360. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1.txt +24 -0
  361. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-1_Clean.txt +20 -0
  362. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2.txt +46 -0
  363. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-2_Clean.txt +30 -0
  364. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3.txt +38 -0
  365. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-3_Clean.txt +24 -0
  366. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a.txt +39 -0
  367. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4a_Clean.txt +24 -0
  368. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b.txt +43 -0
  369. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-4b_Clean.txt +25 -0
  370. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5.txt +63 -0
  371. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-5_Clean.txt +41 -0
  372. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6.txt +36 -0
  373. data/spec/fixtures/X217-HI278/Sample_278_Request_5010X217-6_Clean.txt +20 -0
  374. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r.txt +34 -0
  375. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-1r_Clean.txt +23 -0
  376. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r.txt +46 -0
  377. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-2r_Clean.txt +31 -0
  378. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r.txt +44 -0
  379. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-3r_Clean.txt +26 -0
  380. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4ar_Clean.txt +28 -0
  381. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-4br_Clean.txt +35 -0
  382. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r.txt +60 -0
  383. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-5r_Clean.txt +42 -0
  384. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r.txt +40 -0
  385. data/spec/fixtures/X217-HI278/Sample_278_Response_5010X217-6r_Clean.txt +24 -0
  386. data/spec/fixtures/X218-RA820/1-bad.txt +31 -0
  387. data/spec/fixtures/X218-RA820/1-good.txt +25 -0
  388. data/spec/fixtures/X218-RA820/2-bad.txt +37 -0
  389. data/spec/fixtures/X218-RA820/2-good.txt +29 -0
  390. data/spec/fixtures/X218-RA820/3-bad.txt +29 -0
  391. data/spec/fixtures/X218-RA820/3-good.txt +23 -0
  392. data/spec/fixtures/X218-RA820/4-bad.txt +36 -0
  393. data/spec/fixtures/X218-RA820/4-good.txt +27 -0
  394. data/spec/fixtures/X220-BE834/1-bad.txt +35 -0
  395. data/spec/fixtures/X220-BE834/1-good.txt +29 -0
  396. data/spec/fixtures/X220-BE834/10-bad.txt +26 -0
  397. data/spec/fixtures/X220-BE834/10-good.txt +19 -0
  398. data/spec/fixtures/X220-BE834/2-bad.txt +31 -0
  399. data/spec/fixtures/X220-BE834/2-good.txt +23 -0
  400. data/spec/fixtures/X220-BE834/3-bad.txt +36 -0
  401. data/spec/fixtures/X220-BE834/3-good.txt +26 -0
  402. data/spec/fixtures/X220-BE834/4-bad.txt +27 -0
  403. data/spec/fixtures/X220-BE834/4-good.txt +21 -0
  404. data/spec/fixtures/X220-BE834/5-bad.txt +26 -0
  405. data/spec/fixtures/X220-BE834/5-good.txt +17 -0
  406. data/spec/fixtures/X220-BE834/6-bad.txt +25 -0
  407. data/spec/fixtures/X220-BE834/6-good.txt +20 -0
  408. data/spec/fixtures/X220-BE834/7-bad.txt +25 -0
  409. data/spec/fixtures/X220-BE834/7-good.txt +20 -0
  410. data/spec/fixtures/X220-BE834/8-bad.txt +25 -0
  411. data/spec/fixtures/X220-BE834/8-good.txt +20 -0
  412. data/spec/fixtures/X220-BE834/9-bad.txt +27 -0
  413. data/spec/fixtures/X220-BE834/9-good.txt +21 -0
  414. data/spec/fixtures/X221-HP835/1-bad.txt +58 -0
  415. data/spec/fixtures/X221-HP835/1-good.txt +40 -0
  416. data/spec/fixtures/X221-HP835/2-bad.txt +51 -0
  417. data/spec/fixtures/X221-HP835/2-good.txt +40 -0
  418. data/spec/fixtures/X221-HP835/3a-bad.txt +78 -0
  419. data/spec/fixtures/X221-HP835/3a-good.txt +49 -0
  420. data/spec/fixtures/X221-HP835/3b-bad.txt +60 -0
  421. data/spec/fixtures/X221-HP835/3b-good.txt +32 -0
  422. data/spec/fixtures/X221-HP835/3c-bad.txt +55 -0
  423. data/spec/fixtures/X221-HP835/3c-good.txt +34 -0
  424. data/spec/fixtures/X222-HC837/1-bad.txt +60 -0
  425. data/spec/fixtures/X222-HC837/1-good.txt +53 -0
  426. data/spec/fixtures/X222-HC837/10a-bad.txt +52 -0
  427. data/spec/fixtures/X222-HC837/10a-good.txt +40 -0
  428. data/spec/fixtures/X222-HC837/10b-bad.txt +99 -0
  429. data/spec/fixtures/X222-HC837/10b-good.txt +80 -0
  430. data/spec/fixtures/X222-HC837/10c-bad.txt +105 -0
  431. data/spec/fixtures/X222-HC837/10c-good.txt +80 -0
  432. data/spec/fixtures/X222-HC837/11-bad.txt +69 -0
  433. data/spec/fixtures/X222-HC837/11-good.txt +45 -0
  434. data/spec/fixtures/X222-HC837/12-bad.txt +73 -0
  435. data/spec/fixtures/X222-HC837/12-good.txt +51 -0
  436. data/spec/fixtures/X222-HC837/13-bad.txt +64 -0
  437. data/spec/fixtures/X222-HC837/13-good.txt +46 -0
  438. data/spec/fixtures/X222-HC837/3a-bad.txt +83 -0
  439. data/spec/fixtures/X222-HC837/3a-good.txt +59 -0
  440. data/spec/fixtures/X222-HC837/3b-bad.txt +97 -0
  441. data/spec/fixtures/X222-HC837/3b-good.txt +70 -0
  442. data/spec/fixtures/X222-HC837/3c-bad.txt +95 -0
  443. data/spec/fixtures/X222-HC837/3c-good.txt +74 -0
  444. data/spec/fixtures/X222-HC837/4-bad.txt +67 -0
  445. data/spec/fixtures/X222-HC837/4-good.txt +48 -0
  446. data/spec/fixtures/X222-HC837/5-bad.txt +73 -0
  447. data/spec/fixtures/X222-HC837/5-good.txt +60 -0
  448. data/spec/fixtures/X222-HC837/6-bad.txt +50 -0
  449. data/spec/fixtures/X222-HC837/6-good.txt +39 -0
  450. data/spec/fixtures/X222-HC837/7-bad.txt +93 -0
  451. data/spec/fixtures/X222-HC837/7-good.txt +78 -0
  452. data/spec/fixtures/X222-HC837/8-bad.txt +64 -0
  453. data/spec/fixtures/X222-HC837/8-good.txt +52 -0
  454. data/spec/fixtures/X222-HC837/9-bad.txt +56 -0
  455. data/spec/fixtures/X222-HC837/9-good.txt +38 -0
  456. data/spec/fixtures/X223-HC837/1-bad.txt +66 -0
  457. data/spec/fixtures/X223-HC837/1-good.txt +53 -0
  458. data/spec/fixtures/X223-HC837/2-bad.txt +69 -0
  459. data/spec/fixtures/X223-HC837/2-good.txt +60 -0
  460. data/spec/fixtures/X223-HC837/3-bad.txt +89 -0
  461. data/spec/fixtures/X223-HC837/3-good.txt +61 -0
  462. data/spec/fixtures/X223-HC837/4-bad.txt +60 -0
  463. data/spec/fixtures/X223-HC837/4-good.txt +40 -0
  464. data/spec/fixtures/X223-HC837/5-bad.txt +75 -0
  465. data/spec/fixtures/X223-HC837/5-good.txt +58 -0
  466. data/spec/fixtures/X224-HC837/1-bad.txt +54 -0
  467. data/spec/fixtures/X224-HC837/1-good.txt +44 -0
  468. data/spec/fixtures/X224-HC837/2a-bad.txt +52 -0
  469. data/spec/fixtures/X224-HC837/2a-good.txt +42 -0
  470. data/spec/fixtures/X224-HC837/2b-bad.txt +67 -0
  471. data/spec/fixtures/X224-HC837/2b-good.txt +52 -0
  472. data/spec/fixtures/X224-HC837/3-bad.txt +67 -0
  473. data/spec/fixtures/X224-HC837/3-good.txt +51 -0
  474. data/spec/fixtures/X224-HC837/4-bad.txt +49 -0
  475. data/spec/fixtures/X224-HC837/4-good.txt +40 -0
  476. data/spec/fixtures/X230-FA997/1-bad.txt +19 -0
  477. data/spec/fixtures/X230-FA997/1-good.txt +16 -0
  478. data/spec/fixtures/X231-FA999/1-bad.txt +20 -0
  479. data/spec/fixtures/X231-FA999/1-good.txt +20 -0
  480. data/spec/fixtures/X279-HB271/1-bad.txt +36 -0
  481. data/spec/fixtures/X279-HB271/1-good.txt +30 -0
  482. data/spec/fixtures/X279-HB271/2-bad.txt +22 -0
  483. data/spec/fixtures/X279-HB271/2-good.txt +16 -0
  484. data/spec/fixtures/X279-HB271/3-bad.txt +44 -0
  485. data/spec/fixtures/X279-HB271/3-good.txt +36 -0
  486. data/spec/fixtures/X279-HS270/1-bad.txt +29 -0
  487. data/spec/fixtures/X279-HS270/1-good.txt +23 -0
  488. data/spec/fixtures/X279-HS270/2-bad.txt +32 -0
  489. data/spec/fixtures/X279-HS270/2-good.txt +25 -0
  490. data/spec/spec_helper.rb +34 -0
  491. data/spec/support/fixtures.rb +26 -0
  492. data/spec/support/matchers/either_matchers.rb +26 -0
  493. data/spec/support/matchers/navigation_matchers.rb +247 -0
  494. data/spec/support/node.rb +41 -0
  495. data/spec/support/quickcheck/characters.rb +28 -0
  496. data/spec/support/quickcheck/property.rb +105 -0
  497. data/spec/support/quickcheck/serialized_edi.rb +399 -0
  498. data/spec/support/quickcheck.rb +302 -0
  499. data/spec/support/rcov.rb +34 -0
  500. metadata +577 -0
@@ -0,0 +1,103 @@
1
+ module Stupidedi
2
+ module Zipper
3
+
4
+ class DanglingCursor < AbstractCursor
5
+
6
+ # @return [AbstractCursor]
7
+ attr_reader :parent
8
+
9
+ def initialize(parent)
10
+ @parent = parent
11
+ end
12
+
13
+ # (see AbstractCursor#node)
14
+ def node
15
+ raise Exceptions::ZipperError,
16
+ "DanglingCursor#node should not be called"
17
+ end
18
+
19
+ # (see AbstractCursor#path)
20
+ def path
21
+ Hole.new([], @parent.path.parent, [])
22
+ end
23
+
24
+ # @group Querying the Tree Location
25
+ #########################################################################
26
+
27
+ # (see AbstractCursor#leaf?)
28
+ def leaf?
29
+ true
30
+ end
31
+
32
+ # (see AbstractCursor#root?)
33
+ def root?
34
+ false
35
+ end
36
+
37
+ # (see AbstractCursor#depth)
38
+ def depth
39
+ @parent.depth + 1
40
+ end
41
+
42
+ # (see AbstractCursor#first?)
43
+ def first?
44
+ true
45
+ end
46
+
47
+ # (see AbstractCursor#last?)
48
+ def last?
49
+ true
50
+ end
51
+
52
+ # @group Traversing the Tree
53
+ #########################################################################
54
+
55
+ # @return [AbstractCursor]
56
+ def up
57
+ @parent
58
+ end
59
+
60
+ # (see AbstractCursor#next)
61
+ def next
62
+ raise Exceptions::ZipperError,
63
+ "cannot move to next after last node"
64
+ end
65
+
66
+ # (see AbstractCursor#prev)
67
+ def prev
68
+ raise Exceptions::ZipperError,
69
+ "cannot move to prev before first node"
70
+ end
71
+
72
+ # (see AbstractCursor#first)
73
+ def first
74
+ self
75
+ end
76
+
77
+ # (see AbstractCursor#last)
78
+ def last
79
+ self
80
+ end
81
+
82
+ # @group Editing the Tree
83
+ #########################################################################
84
+
85
+ # (see AbstractCursor#replace)
86
+ def replace(node)
87
+ @parent.append_child(node)
88
+ end
89
+
90
+ alias prepend replace
91
+ alias append replace
92
+
93
+ # (see AbstractCursor#delete)
94
+ def delete
95
+ self
96
+ end
97
+
98
+ # @endgroup
99
+ #########################################################################
100
+ end
101
+
102
+ end
103
+ end
@@ -0,0 +1,157 @@
1
+ module Stupidedi
2
+ module Zipper
3
+
4
+ class EditedCursor < AbstractCursor
5
+
6
+ # (see AbstractCursor#node)
7
+ attr_reader :node
8
+
9
+ # @return [Hole]
10
+ attr_reader :path
11
+
12
+ # @return [AbstractCursor]
13
+ attr_reader :parent
14
+
15
+ def initialize(node, path, parent)
16
+ @node, @path, @parent =
17
+ node, path, parent
18
+ end
19
+
20
+ # @group Querying the Tree Location
21
+ #########################################################################
22
+
23
+ # (see AbstractCursor#leaf?)
24
+ def leaf?
25
+ @node.leaf? or @node.children.empty?
26
+ end
27
+
28
+ # (see AbstractCursor#root?)
29
+ def root?
30
+ false
31
+ end
32
+
33
+ # @group Traversing the Tree
34
+ #########################################################################
35
+
36
+ # (see AbstractCursor#up)
37
+ # @return [AbstractCursor]
38
+ def up
39
+ node =
40
+ @parent.node.copy(:children =>
41
+ @path.left.reverse.concat(@node.cons(@path.right)))
42
+
43
+ if parent.root?
44
+ RootCursor.new(node)
45
+ else
46
+ EditedCursor.new(node, @path.parent, @parent.parent)
47
+ end
48
+ end
49
+
50
+ # (see AbstractCursor#next)
51
+ # @return [EditedCursor]
52
+ def next
53
+ if last?
54
+ raise Exceptions::ZipperError,
55
+ "cannot move to next after last node"
56
+ end
57
+
58
+ head, *tail = @path.right
59
+
60
+ EditedCursor.new(head,
61
+ Hole.new(@node.cons(@path.left), @path.parent, tail), @parent)
62
+ end
63
+
64
+ # (see AbstractCursor#prev)
65
+ # @return [EditedCursor]
66
+ def prev
67
+ if first?
68
+ raise Exceptions::ZipperError,
69
+ "cannot move to prev before first node"
70
+ end
71
+
72
+ head, *tail = @path.left
73
+
74
+ EditedCursor.new(head,
75
+ Hole.new(tail, @path.parent, @node.cons(@path.right)), @parent)
76
+ end
77
+
78
+ # (see AbstractCursor#first)
79
+ # @return [EditedCursor]
80
+ def first
81
+ if first?
82
+ return self
83
+ end
84
+
85
+ right = @path.left.init.reverse.concat(@node.cons(@path.right))
86
+
87
+ EditedCursor.new(@path.left.last,
88
+ Hole.new([], @path.parent, right), @parent)
89
+ end
90
+
91
+ # (see AbstractCursor#last)
92
+ # @return [EditedCursor]
93
+ def last
94
+ if last?
95
+ return self
96
+ end
97
+
98
+ left = @node.cons(@path.right.init.reverse).concat(@path.left)
99
+
100
+ EditedCursor.new(@path.right.last,
101
+ Hole.new(left, @path.parent, []), @parent)
102
+ end
103
+
104
+ # @group Editing the Tree
105
+ #########################################################################
106
+
107
+ # (see AbstractCursor#last)
108
+ # @return [EditedCursor]
109
+ def append(node)
110
+ EditedCursor.new(node,
111
+ Hole.new(@node.cons(@path.left), @path.parent, @path.right), @parent)
112
+ end
113
+
114
+ # (see AbstractCursor#last)
115
+ # @return [EditedCursor]
116
+ def prepend(node)
117
+ EditedCursor.new(node,
118
+ Hole.new(@path.left, @path.parent, @node.cons(@path.right)), @parent)
119
+ end
120
+
121
+ # (see AbstractCursor#last)
122
+ # @return [EditedCursor]
123
+ def replace(node)
124
+ EditedCursor.new(node, @path, @parent)
125
+ end
126
+
127
+ # (see AbstractCursor#last)
128
+ # @return [EditedCursor]
129
+ def delete
130
+ if not last?
131
+ # Move to `next`
132
+ head, *tail = @path.right
133
+
134
+ EditedCursor.new(head,
135
+ Hole.new(@path.left, @path.parent, tail), @parent)
136
+ elsif not first?
137
+ # Move to `prev`
138
+ head, *tail = @path.left
139
+
140
+ EditedCursor.new(head,
141
+ Hole.new(tail, @path.parent, @path.right), @parent)
142
+ else
143
+ # Deleting the only child
144
+ parent =
145
+ @parent.node.copy(:children =>
146
+ @path.left.reverse.concat(@path.right))
147
+
148
+ EditedCursor.new(parent, @path.parent, @parent.parent).dangle
149
+ end
150
+ end
151
+
152
+ # @endgroup
153
+ #########################################################################
154
+ end
155
+
156
+ end
157
+ end
@@ -0,0 +1,131 @@
1
+ module Stupidedi
2
+ module Zipper
3
+
4
+ class MemoizedCursor < AbstractCursor
5
+
6
+ # @return [#leaf?, #children, #copy]
7
+ attr_reader :node
8
+
9
+ # @return [Hole]
10
+ attr_reader :path
11
+
12
+ # @private
13
+ # @return [AbstractCursor]
14
+ attr_reader :parent
15
+
16
+ def initialize(node, path, parent)
17
+ @node, @path, @parent =
18
+ node, path, parent
19
+ end
20
+
21
+ # @group Querying the Tree Location
22
+ #########################################################################
23
+
24
+ def leaf?
25
+ @node.leaf? or @node.children.empty?
26
+ end
27
+
28
+ def root?
29
+ false
30
+ end
31
+
32
+ # @group Traversing the Tree
33
+ #########################################################################
34
+
35
+ # @return [AbstractCursor]
36
+ def up
37
+ @parent
38
+ end
39
+
40
+ # @return [MemoizedCursor]
41
+ def next
42
+ @__next ||= begin
43
+ if last?
44
+ raise Exceptions::ZipperError,
45
+ "cannot move to next after last node"
46
+ end
47
+
48
+ head, *tail = @path.right
49
+
50
+ MemoizedCursor.new(head,
51
+ Hole.new(@node.cons(@path.left), @path.parent, tail), @parent)
52
+ end
53
+ end
54
+
55
+ # @return [MemoizedCursor]
56
+ def prev
57
+ @__prev ||= begin
58
+ if first?
59
+ raise Exceptions::ZipperError,
60
+ "cannot move to prev before first node"
61
+ end
62
+
63
+ head, *tail = @path.left
64
+
65
+ MemoizedCursor.new(head,
66
+ Hole.new(tail, @path.parent, @node.cons(@path.right)), @parent)
67
+ end
68
+ end
69
+
70
+ # @return [MemoizedCursor]
71
+ def first
72
+ @parent.down
73
+ end
74
+
75
+ # @return [MemoizedCursor]
76
+ def last
77
+ current = self
78
+ current = current.next until current.last?
79
+ current
80
+ end
81
+
82
+ # @group Editing the Tree
83
+ #########################################################################
84
+
85
+ # @return [EditedCursor]
86
+ def append(node)
87
+ EditedCursor.new(node,
88
+ Hole.new(@node.cons(@path.left), @path.parent, @path.right), @parent)
89
+ end
90
+
91
+ # @return [EditedCursor]
92
+ def prepend
93
+ EditedCursor.new(node,
94
+ Hole.new(@path.left, @path.parent, @node.cons(@path.right)), @parent)
95
+ end
96
+
97
+ # @return [EditedCursor]
98
+ def replace(node)
99
+ EditedCursor.new(node, @path, @parent)
100
+ end
101
+
102
+ # @return [EditedCursor]
103
+ def delete
104
+ if not last?
105
+ # Move to `next`
106
+ head, *tail = @path.right
107
+
108
+ EditedCursor.new(head,
109
+ Hole.new(@path.left, @path.parent, tail), @parent)
110
+ elsif not first?
111
+ # Move to `prev`
112
+ head, *tail = @path.left
113
+
114
+ EditedCursor.new(head,
115
+ Hole.new(tail, @path.parent, @path.right), @parent)
116
+ else
117
+ # Deleting the only child
118
+ parent =
119
+ @parent.node.copy(:children =>
120
+ @path.left.reverse.concat(@path.right))
121
+
122
+ EditedCursor.new(parent, @path.parent, @parent.parent).dangle
123
+ end
124
+ end
125
+
126
+ # @endgroup
127
+ #########################################################################
128
+ end
129
+
130
+ end
131
+ end
@@ -0,0 +1,124 @@
1
+ module Stupidedi
2
+ module Zipper
3
+
4
+ class AbstractPath
5
+
6
+ # @return [AbstractPath]
7
+ abstract :parent
8
+
9
+ # Contains the node's leftward siblings, sorted nearest to furthest
10
+ #
11
+ # @return [Array<#leaf?, #children, #copy>]
12
+ abstract :left
13
+
14
+ # Contains the node's rightward siblings, sorted nearest to furthest
15
+ #
16
+ # @return [Array<#leaf?, #children, #copy>]
17
+ abstract :right
18
+
19
+ # True when the node has no rightward siblings
20
+ abstract :last?
21
+
22
+ # True when the node has no leftward siblings
23
+ abstract :first?
24
+
25
+ # Distance from the root node
26
+ #
27
+ # @return [Integer]
28
+ abstract :depth
29
+ end
30
+
31
+ # @private
32
+ Root = Class.new(AbstractPath) do
33
+
34
+ # @return self
35
+ def parent
36
+ self
37
+ end
38
+
39
+ # (see AbstractPath#left)
40
+ def left
41
+ []
42
+ end
43
+
44
+ # (see AbstractPath#right)
45
+ def right
46
+ []
47
+ end
48
+
49
+ # (see AbstractPath#last?)
50
+ # @return true
51
+ def last?
52
+ true
53
+ end
54
+
55
+ # (see AbstractPath#first?)
56
+ # @return true
57
+ def first?
58
+ true
59
+ end
60
+
61
+ # (see AbstractPath#depth)
62
+ def depth
63
+ 0
64
+ end
65
+
66
+ def position
67
+ nil
68
+ end
69
+
70
+ # @return [String]
71
+ def inspect
72
+ "root"
73
+ end
74
+ end.new
75
+
76
+ class Hole < AbstractPath
77
+
78
+ # (see AbstractPath#right)
79
+ attr_reader :left
80
+
81
+ # @return [AbstractPath]
82
+ attr_reader :parent
83
+
84
+ # (see AbstractPath#left)
85
+ attr_reader :right
86
+
87
+ def initialize(left, parent, right)
88
+ @left, @parent, @right =
89
+ left, parent, right
90
+ end
91
+
92
+ # (see AbstractPath#last?)
93
+ def last?
94
+ @right.empty?
95
+ end
96
+
97
+ # (see AbstractPath#first?)
98
+ def first?
99
+ @left.empty?
100
+ end
101
+
102
+ # (see AbstractPath#depth)
103
+ def depth
104
+ 1 + @parent.depth
105
+ end
106
+
107
+ def position
108
+ @left.length
109
+ end
110
+
111
+ # @return [String]
112
+ def inspect
113
+ "#{@parent.inspect}/#{@left.length}"
114
+ end
115
+
116
+ # @return [Boolean]
117
+ def ==(other)
118
+ depth == other.depth and
119
+ position == other.position
120
+ end
121
+ end
122
+
123
+ end
124
+ end
@@ -0,0 +1,120 @@
1
+ module Stupidedi
2
+ module Zipper
3
+
4
+ class RootCursor < AbstractCursor
5
+
6
+ # @return [AbstractNode]
7
+ attr_reader :node
8
+
9
+ # @return [AbstractPath]
10
+ attr_reader :path
11
+
12
+ def initialize(node)
13
+ @node, @path =
14
+ node, Root
15
+ end
16
+
17
+ # @group Query the Tree Location
18
+ #########################################################################
19
+
20
+ # (see AbstractCursor#depth)
21
+ def depth
22
+ 0
23
+ end
24
+
25
+ # (see AbstractCursor#first?)
26
+ def first?
27
+ true
28
+ end
29
+
30
+ # (see AbstractCursor#last?)
31
+ def last?
32
+ true
33
+ end
34
+
35
+ # (see AbstractCursor#leaf?)
36
+ def leaf?
37
+ @node.leaf? or @node.children.empty?
38
+ end
39
+
40
+ # (see AbstractCursor#root?)
41
+ def root?
42
+ true
43
+ end
44
+
45
+ # @group Traversing the Tree
46
+ #########################################################################
47
+
48
+ # (see AbstractCursor#first)
49
+ def first
50
+ self
51
+ end
52
+
53
+ # (see AbstractCursor#last)
54
+ def last
55
+ self
56
+ end
57
+
58
+ # (see AbstractCursor#next)
59
+ # @return [void]
60
+ def next
61
+ raise Exceptions::ZipperError,
62
+ "root node has no siblings"
63
+ end
64
+
65
+ # (see AbstractCursor#prev)
66
+ # @return [void]
67
+ def prev
68
+ raise Exceptions::ZipperError,
69
+ "root node has no siblings"
70
+ end
71
+
72
+ # (see AbstractCursor#root)
73
+ # @return [RootCursor]
74
+ def root
75
+ self
76
+ end
77
+
78
+ # (see AbstractCursor#up)
79
+ # @return [void]
80
+ def up
81
+ raise Exceptions::ZipperError,
82
+ "root node has no parent"
83
+ end
84
+
85
+ # @group Editing the Tree
86
+ #########################################################################
87
+
88
+ # (see AbstractCursor#append)
89
+ # @return [void]
90
+ def append(node)
91
+ raise Exceptions::ZipperError,
92
+ "root node has no siblings"
93
+ end
94
+
95
+ # (see AbstractCursor#prepend)
96
+ # @return [void]
97
+ def prepend(node)
98
+ raise Exceptions::ZipperError,
99
+ "root node has no siblings"
100
+ end
101
+
102
+ # (see AbstractCursor#replace)
103
+ # @return [RootCursor]
104
+ def replace(node)
105
+ RootCursor.new(node)
106
+ end
107
+
108
+ # (see AbstractCursor#delete)
109
+ # @return [void]
110
+ def delete
111
+ raise Exceptions::ZipperError,
112
+ "cannot delete root node"
113
+ end
114
+
115
+ # @endgroup
116
+ #########################################################################
117
+ end
118
+
119
+ end
120
+ end
@@ -0,0 +1,25 @@
1
+ module Stupidedi
2
+ module Zipper
3
+ autoload :AbstractCursor, "stupidedi/zipper/abstract_cursor"
4
+ autoload :DanglingCursor, "stupidedi/zipper/dangling_cursor"
5
+ autoload :EditedCursor, "stupidedi/zipper/edited_cursor"
6
+ autoload :MemoizedCursor, "stupidedi/zipper/memoized_cursor"
7
+ autoload :RootCursor, "stupidedi/zipper/root_cursor"
8
+
9
+ autoload :AbstractPath, "stupidedi/zipper/path"
10
+ autoload :Hole, "stupidedi/zipper/path"
11
+ autoload :Root, "stupidedi/zipper/path"
12
+ end
13
+
14
+ class << Zipper
15
+
16
+ # @group Constructors
17
+ ###########################################################################
18
+
19
+ # @return [AbstractCursor]
20
+ def build(node)
21
+ Zipper::RootCursor.new(node)
22
+ end
23
+ end
24
+
25
+ end