wlang 0.10.2 → 2.0.0.beta

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 (269) hide show
  1. data/CHANGELOG.md +3 -121
  2. data/Gemfile +23 -1
  3. data/Gemfile.lock +32 -28
  4. data/LICENCE.md +18 -21
  5. data/Manifest.txt +4 -5
  6. data/README.md +100 -174
  7. data/Rakefile +1 -13
  8. data/bin/wlang +3 -29
  9. data/lib/wlang.rb +21 -394
  10. data/lib/wlang/command.rb +94 -0
  11. data/lib/wlang/compiler.rb +78 -0
  12. data/lib/wlang/compiler/autospacing.rb +60 -0
  13. data/lib/wlang/compiler/dialect_enforcer.rb +91 -0
  14. data/lib/wlang/compiler/filter.rb +32 -0
  15. data/lib/wlang/compiler/grammar.citrus +67 -0
  16. data/lib/wlang/compiler/parser.rb +26 -0
  17. data/lib/wlang/compiler/proc_call_removal.rb +15 -0
  18. data/lib/wlang/compiler/static_merger.rb +28 -0
  19. data/lib/wlang/compiler/strconcat_flattener.rb +25 -0
  20. data/lib/wlang/compiler/to_ruby_abstraction.rb +22 -0
  21. data/lib/wlang/compiler/to_ruby_code.rb +55 -0
  22. data/lib/wlang/dialect.rb +40 -237
  23. data/lib/wlang/dialect/dispatching.rb +51 -0
  24. data/lib/wlang/dialect/evaluation.rb +30 -0
  25. data/lib/wlang/dialect/tags.rb +50 -0
  26. data/lib/wlang/dummy.rb +32 -0
  27. data/lib/wlang/html.rb +106 -0
  28. data/lib/wlang/loader.rb +6 -0
  29. data/lib/wlang/mustang.rb +90 -0
  30. data/lib/wlang/scope.rb +57 -0
  31. data/lib/wlang/scope/binding_scope.rb +18 -0
  32. data/lib/wlang/scope/object_scope.rb +25 -0
  33. data/lib/wlang/scope/proxy_scope.rb +18 -0
  34. data/lib/wlang/scope/root_scope.rb +24 -0
  35. data/lib/wlang/template.rb +16 -86
  36. data/lib/wlang/version.rb +9 -8
  37. data/spec/fixtures/dialect/foobar.rb +31 -0
  38. data/spec/fixtures/dialect/upcasing.rb +13 -0
  39. data/spec/fixtures/templates/hello.tpl +1 -0
  40. data/spec/integration/examples/1-basics.txt +65 -0
  41. data/spec/integration/examples/2-imperative.txt +51 -0
  42. data/spec/integration/examples/3-partials.txt +76 -0
  43. data/spec/integration/examples/4-recursion.txt +16 -0
  44. data/spec/integration/html/test_ampersand.rb +15 -0
  45. data/spec/integration/html/test_bang.rb +38 -0
  46. data/spec/integration/html/test_caret.rb +33 -0
  47. data/spec/integration/html/test_dollar.rb +16 -0
  48. data/spec/integration/html/test_greater.rb +23 -0
  49. data/spec/integration/html/test_modulo.rb +16 -0
  50. data/spec/integration/html/test_plus.rb +48 -0
  51. data/spec/integration/html/test_question.rb +33 -0
  52. data/spec/integration/html/test_sharp.rb +21 -0
  53. data/spec/integration/html/test_slash.rb +16 -0
  54. data/spec/integration/html/test_star.rb +37 -0
  55. data/spec/integration/test_dummy.rb +51 -0
  56. data/spec/integration/test_examples.rb +29 -0
  57. data/spec/integration/test_mustang.rb +120 -0
  58. data/spec/integration/test_readme.rb +56 -0
  59. data/spec/integration/test_upcasing.rb +22 -0
  60. data/spec/spec_helper.rb +62 -1
  61. data/spec/test_wlang.rb +101 -0
  62. data/spec/unit/compiler/autospacing/test_right_strip.rb +30 -0
  63. data/spec/unit/compiler/autospacing/test_unindent.rb +30 -0
  64. data/spec/unit/compiler/test_dialect_enforcer.rb +168 -0
  65. data/spec/unit/compiler/test_grammar.rb +207 -0
  66. data/spec/unit/compiler/test_parser.rb +69 -0
  67. data/spec/unit/compiler/test_proc_call_removal.rb +24 -0
  68. data/spec/unit/compiler/test_static_merger.rb +29 -0
  69. data/spec/unit/compiler/test_strconcat_flattener.rb +30 -0
  70. data/spec/unit/compiler/test_to_ruby_abstraction.rb +59 -0
  71. data/spec/unit/compiler/test_to_ruby_code.rb +24 -0
  72. data/spec/unit/dialect/test_compile.rb +52 -0
  73. data/spec/unit/dialect/test_dispatching.rb +19 -0
  74. data/spec/unit/dialect/test_evaluate.rb +41 -0
  75. data/spec/unit/dialect/test_render.rb +33 -0
  76. data/spec/unit/dialect/test_tags.rb +32 -0
  77. data/spec/unit/dialect/test_with_scope.rb +18 -0
  78. data/spec/unit/scope/test_binding_scope.rb +27 -0
  79. data/spec/unit/scope/test_coerce.rb +22 -0
  80. data/spec/unit/scope/test_object_scope.rb +38 -0
  81. data/spec/unit/scope/test_proxy_scope.rb +22 -0
  82. data/spec/unit/scope/test_root_scope.rb +22 -0
  83. data/spec/unit/test_assumptions.rb +29 -0
  84. data/spec/unit/test_scope.rb +57 -0
  85. data/tasks/debug_mail.rake +42 -45
  86. data/tasks/gem.rake +22 -17
  87. data/tasks/spec_test.rake +9 -17
  88. data/tasks/unit_test.rake +11 -12
  89. data/tasks/yard.rake +13 -13
  90. data/wlang.gemspec +36 -32
  91. data/wlang.noespec +27 -35
  92. metadata +268 -451
  93. data/doc/specification/about.rdoc +0 -61
  94. data/doc/specification/analytics.wtpl +0 -13
  95. data/doc/specification/dialect.wtpl +0 -14
  96. data/doc/specification/dialects.wtpl +0 -3
  97. data/doc/specification/examples.rb +0 -3
  98. data/doc/specification/glossary.wtpl +0 -14
  99. data/doc/specification/hosting.rdoc +0 -0
  100. data/doc/specification/overview.rdoc +0 -116
  101. data/doc/specification/rulesets.wtpl +0 -87
  102. data/doc/specification/specification.css +0 -53
  103. data/doc/specification/specification.html +0 -1690
  104. data/doc/specification/specification.js +0 -8
  105. data/doc/specification/specification.wtpl +0 -42
  106. data/doc/specification/specification.yml +0 -432
  107. data/doc/specification/symbols.wtpl +0 -16
  108. data/lib/wlang/dialect_dsl.rb +0 -141
  109. data/lib/wlang/dialect_loader.rb +0 -74
  110. data/lib/wlang/dialects/bluecloth_dialect.rb +0 -16
  111. data/lib/wlang/dialects/coderay_dialect.rb +0 -45
  112. data/lib/wlang/dialects/hosted_dialect.rb +0 -50
  113. data/lib/wlang/dialects/plain_text_dialect.rb +0 -69
  114. data/lib/wlang/dialects/rdoc_dialect.rb +0 -33
  115. data/lib/wlang/dialects/redcloth_dialect.rb +0 -16
  116. data/lib/wlang/dialects/ruby_dialect.rb +0 -118
  117. data/lib/wlang/dialects/sql_dialect.rb +0 -38
  118. data/lib/wlang/dialects/standard_dialects.rb +0 -181
  119. data/lib/wlang/dialects/xhtml_dialect.rb +0 -63
  120. data/lib/wlang/dialects/yaml_dialect.rb +0 -30
  121. data/lib/wlang/encoder.rb +0 -62
  122. data/lib/wlang/encoder_set.rb +0 -122
  123. data/lib/wlang/errors.rb +0 -80
  124. data/lib/wlang/ext/hash_methodize.rb +0 -13
  125. data/lib/wlang/ext/string.rb +0 -44
  126. data/lib/wlang/hash_scope.rb +0 -89
  127. data/lib/wlang/hosted_language.rb +0 -146
  128. data/lib/wlang/intelligent_buffer.rb +0 -94
  129. data/lib/wlang/parser.rb +0 -332
  130. data/lib/wlang/parser_state.rb +0 -94
  131. data/lib/wlang/rule.rb +0 -66
  132. data/lib/wlang/rule_set.rb +0 -106
  133. data/lib/wlang/rulesets/basic_ruleset.rb +0 -83
  134. data/lib/wlang/rulesets/buffering_ruleset.rb +0 -115
  135. data/lib/wlang/rulesets/context_ruleset.rb +0 -111
  136. data/lib/wlang/rulesets/encoding_ruleset.rb +0 -73
  137. data/lib/wlang/rulesets/imperative_ruleset.rb +0 -132
  138. data/lib/wlang/rulesets/ruleset_utils.rb +0 -317
  139. data/lib/wlang/wlang_command.rb +0 -51
  140. data/lib/wlang/wlang_command_options.rb +0 -163
  141. data/spec/basic_object.spec +0 -40
  142. data/spec/coderay_dialect.spec +0 -8
  143. data/spec/dialect/apply_post_transform.spec +0 -16
  144. data/spec/global_extensions.rb +0 -2
  145. data/spec/hash_scope.spec +0 -76
  146. data/spec/redcloth_dialect.spec +0 -24
  147. data/spec/test_all.rb +0 -8
  148. data/spec/wlang.spec +0 -53
  149. data/spec/wlang_spec.rb +0 -8
  150. data/spec/xhtml_dialect.spec +0 -22
  151. data/tasks/genspec.rake +0 -5
  152. data/test/blackbox/basic/execution_1.exp +0 -1
  153. data/test/blackbox/basic/execution_1.tpl +0 -1
  154. data/test/blackbox/basic/execution_2.exp +0 -1
  155. data/test/blackbox/basic/execution_2.tpl +0 -1
  156. data/test/blackbox/basic/execution_3.exp +0 -1
  157. data/test/blackbox/basic/execution_3.tpl +0 -1
  158. data/test/blackbox/basic/execution_4.exp +0 -1
  159. data/test/blackbox/basic/execution_4.tpl +0 -1
  160. data/test/blackbox/basic/inclusion_1.exp +0 -1
  161. data/test/blackbox/basic/inclusion_1.tpl +0 -1
  162. data/test/blackbox/basic/inclusion_2.exp +0 -1
  163. data/test/blackbox/basic/inclusion_2.tpl +0 -1
  164. data/test/blackbox/basic/injection_1.exp +0 -1
  165. data/test/blackbox/basic/injection_1.tpl +0 -1
  166. data/test/blackbox/basic/injection_2.exp +0 -1
  167. data/test/blackbox/basic/injection_2.tpl +0 -1
  168. data/test/blackbox/basic/modulation_1.exp +0 -1
  169. data/test/blackbox/basic/modulation_1.tpl +0 -1
  170. data/test/blackbox/basic/modulation_2.exp +0 -1
  171. data/test/blackbox/basic/modulation_2.tpl +0 -1
  172. data/test/blackbox/basic/recursive_app_1.exp +0 -1
  173. data/test/blackbox/basic/recursive_app_1.tpl +0 -1
  174. data/test/blackbox/basic/recursive_app_2.exp +0 -1
  175. data/test/blackbox/basic/recursive_app_2.tpl +0 -1
  176. data/test/blackbox/buffering/data_1.rb +0 -1
  177. data/test/blackbox/buffering/data_assignment_1.exp +0 -1
  178. data/test/blackbox/buffering/data_assignment_1.tpl +0 -1
  179. data/test/blackbox/buffering/data_assignment_2.exp +0 -1
  180. data/test/blackbox/buffering/data_assignment_2.tpl +0 -1
  181. data/test/blackbox/buffering/data_assignment_3.exp +0 -1
  182. data/test/blackbox/buffering/data_assignment_3.tpl +0 -1
  183. data/test/blackbox/buffering/data_assignment_4.exp +0 -1
  184. data/test/blackbox/buffering/data_assignment_4.tpl +0 -1
  185. data/test/blackbox/buffering/input_1.exp +0 -1
  186. data/test/blackbox/buffering/input_1.tpl +0 -1
  187. data/test/blackbox/buffering/input_2.exp +0 -1
  188. data/test/blackbox/buffering/input_2.tpl +0 -1
  189. data/test/blackbox/buffering/input_3.exp +0 -1
  190. data/test/blackbox/buffering/input_3.tpl +0 -1
  191. data/test/blackbox/buffering/input_inclusion.exp +0 -1
  192. data/test/blackbox/buffering/input_inclusion.tpl +0 -1
  193. data/test/blackbox/buffering/input_inclusion_1.exp +0 -0
  194. data/test/blackbox/buffering/input_inclusion_1.tpl +0 -1
  195. data/test/blackbox/buffering/input_inclusion_2.exp +0 -1
  196. data/test/blackbox/buffering/input_inclusion_2.tpl +0 -1
  197. data/test/blackbox/buffering/input_inclusion_3.exp +0 -1
  198. data/test/blackbox/buffering/input_inclusion_3.tpl +0 -1
  199. data/test/blackbox/buffering/input_inclusion_4.exp +0 -0
  200. data/test/blackbox/buffering/input_inclusion_4.tpl +0 -1
  201. data/test/blackbox/buffering/input_inclusion_5.exp +0 -1
  202. data/test/blackbox/buffering/input_inclusion_5.tpl +0 -1
  203. data/test/blackbox/buffering/input_inclusion_6.exp +0 -1
  204. data/test/blackbox/buffering/input_inclusion_6.tpl +0 -1
  205. data/test/blackbox/buffering/input_inclusion_7.exp +0 -0
  206. data/test/blackbox/buffering/input_inclusion_7.tpl +0 -1
  207. data/test/blackbox/buffering/text_1.txt +0 -1
  208. data/test/blackbox/buffering/wlang.txt +0 -1
  209. data/test/blackbox/context/assignment_1.exp +0 -1
  210. data/test/blackbox/context/assignment_1.tpl +0 -1
  211. data/test/blackbox/context/assignment_2.exp +0 -1
  212. data/test/blackbox/context/assignment_2.tpl +0 -1
  213. data/test/blackbox/context/assignment_3.exp +0 -2
  214. data/test/blackbox/context/assignment_3.tpl +0 -2
  215. data/test/blackbox/context/assignment_4.exp +0 -1
  216. data/test/blackbox/context/assignment_4.tpl +0 -1
  217. data/test/blackbox/context/block_assignment_1.exp +0 -1
  218. data/test/blackbox/context/block_assignment_1.tpl +0 -1
  219. data/test/blackbox/context/block_assignment_2.exp +0 -1
  220. data/test/blackbox/context/block_assignment_2.tpl +0 -1
  221. data/test/blackbox/context/modulo_assignment_1.exp +0 -1
  222. data/test/blackbox/context/modulo_assignment_1.tpl +0 -1
  223. data/test/blackbox/context/modulo_assignment_2.exp +0 -1
  224. data/test/blackbox/context/modulo_assignment_2.tpl +0 -1
  225. data/test/blackbox/data_1.rb +0 -1
  226. data/test/blackbox/postblock/hello.exp +0 -1
  227. data/test/blackbox/postblock/hello.pre +0 -1
  228. data/test/blackbox/postblock/hello.tpl +0 -1
  229. data/test/blackbox/postblock/hello_input_inclusion.exp +0 -1
  230. data/test/blackbox/postblock/hello_input_inclusion.tpl +0 -1
  231. data/test/blackbox/postblock/hello_to_authors.exp +0 -1
  232. data/test/blackbox/postblock/hello_to_authors.tpl +0 -1
  233. data/test/blackbox/poststring/hello.exp +0 -1
  234. data/test/blackbox/poststring/hello.tpl +0 -1
  235. data/test/blackbox/test_all.rb +0 -70
  236. data/test/standard_dialects/ruby/data.rb +0 -7
  237. data/test/standard_dialects/ruby/inclusion.exp +0 -6
  238. data/test/standard_dialects/ruby/inclusion.tpl +0 -6
  239. data/test/standard_dialects/test_all.rb +0 -29
  240. data/test/standard_dialects/yaml/assumptions_test.rb +0 -13
  241. data/test/standard_dialects/yaml/data.rb +0 -3
  242. data/test/standard_dialects/yaml/inclusion_1.exp +0 -7
  243. data/test/standard_dialects/yaml/inclusion_1.tpl +0 -2
  244. data/test/standard_dialects/yaml/inclusion_2.exp +0 -5
  245. data/test/standard_dialects/yaml/inclusion_2.tpl +0 -3
  246. data/test/unit/test_all.rb +0 -9
  247. data/test/unit/wlang/anagram_bugs_test.rb +0 -111
  248. data/test/unit/wlang/basic_ruleset_test.rb +0 -52
  249. data/test/unit/wlang/buffering_ruleset_test.rb +0 -102
  250. data/test/unit/wlang/buffering_template1.wtpl +0 -1
  251. data/test/unit/wlang/buffering_template2.wtpl +0 -1
  252. data/test/unit/wlang/buffering_template3.wtpl +0 -1
  253. data/test/unit/wlang/buffering_template4.wtpl +0 -1
  254. data/test/unit/wlang/buffering_template5.wtpl +0 -1
  255. data/test/unit/wlang/context_ruleset_test.rb +0 -32
  256. data/test/unit/wlang/data.rb +0 -3
  257. data/test/unit/wlang/encoder_set_test.rb +0 -42
  258. data/test/unit/wlang/imperative_ruleset_test.rb +0 -107
  259. data/test/unit/wlang/intelligent_buffer_test.rb +0 -194
  260. data/test/unit/wlang/othersymbols_test.rb +0 -16
  261. data/test/unit/wlang/parser_test.rb +0 -88
  262. data/test/unit/wlang/plain_text_dialect_test.rb +0 -21
  263. data/test/unit/wlang/ruby_dialect_test.rb +0 -100
  264. data/test/unit/wlang/ruby_expected.rb +0 -3
  265. data/test/unit/wlang/ruby_template.wrb +0 -3
  266. data/test/unit/wlang/ruleset_utils_test.rb +0 -245
  267. data/test/unit/wlang/specification_examples_test.rb +0 -54
  268. data/test/unit/wlang/test_utils.rb +0 -25
  269. data/test/unit/wlang/wlang_test.rb +0 -80
@@ -1,73 +0,0 @@
1
- module WLang
2
- class RuleSet
3
-
4
- #
5
- # Encoding RuleSet, commonly installed in any wlang dialect. Note that this
6
- # ruleset overrides <tt>${...}</tt> implemented in WLang::RuleSet::Basic.
7
- #
8
- # For an overview of this ruleset, see the wlang {specification file}[link://files/specification.html].
9
- #
10
- module Encoding
11
-
12
- # Default mapping between tag symbols and methods
13
- DEFAULT_RULESET = {'&' => :main_encoding, '&;' => :entities_encoding,
14
- "&'" => :single_quoting, '&"' => :double_quoting,
15
- "$" => :injection, "'" => :single_quoted,
16
- '"' => :double_quoted}
17
-
18
- # Main encoding as <tt>&{...}</tt>
19
- def self.main_encoding(parser, offset)
20
- parsed, reached = parser.parse(offset)
21
- result = parser.encode(parsed, "main-encoding")
22
- [result, reached]
23
- end
24
-
25
- # Entities-encoding as <tt>&;{...}</tt>
26
- def self.entities_encoding(parser, offset)
27
- parsed, reached = parser.parse(offset)
28
- result = parser.encode(parsed, "entities-encoding")
29
- [result, reached]
30
- end
31
-
32
- # Single-quoting as <tt>&'{...}</tt>
33
- def self.single_quoting(parser, offset)
34
- parsed, reached = parser.parse(offset)
35
- result = parser.encode(parsed, "single-quoting")
36
- [result, reached]
37
- end
38
-
39
- # Double-quoting as <tt>&"{...}</tt>
40
- def self.double_quoting(parser, offset)
41
- parsed, reached = parser.parse(offset)
42
- result = parser.encode(parsed, "double-quoting")
43
- [result, reached]
44
- end
45
-
46
- # Injection as <tt>${wlang/ruby}</tt>
47
- def self.injection(parser, offset)
48
- expression, reached = parser.parse(offset, "wlang/hosted")
49
- result = parser.evaluate(expression)
50
- encoded = parser.encode(result.to_s, "main-encoding")
51
- [encoded, reached]
52
- end
53
-
54
- # Single-quoted as <tt>'{wlang/ruby}</tt>
55
- def self.single_quoted(parser, offset)
56
- expression, reached = parser.parse(offset, "wlang/hosted")
57
- result = parser.evaluate(expression)
58
- encoded = parser.encode(result.to_s, "single-quoting")
59
- ["'" << encoded, reached]
60
- end
61
-
62
- # Double-quoted as <tt>"{wlang/ruby}</tt>
63
- def self.double_quoted(parser, offset)
64
- expression, reached = parser.parse(offset, "wlang/hosted")
65
- result = parser.evaluate(expression)
66
- encoded = parser.encode(result.to_s, "double-quoting")
67
- ['"' << encoded, reached]
68
- end
69
-
70
- end # module Encoding
71
-
72
- end
73
- end
@@ -1,132 +0,0 @@
1
- module WLang
2
- class RuleSet
3
-
4
- #
5
- # Imperative ruleset, providing special tags to iterate and instantiate
6
- # conditionaly.
7
- #
8
- # For an overview of this ruleset, see the wlang {specification file}[link://files/specification.html].
9
- #
10
- module Imperative
11
- U=WLang::RuleSet::Utils
12
-
13
- # Regular expression for #1 in <tt>*{wlang/hosted}{...}</tt>
14
- EACH_REGEXP = /^([^\s]+)((\s+(using\s+([_a-z]+)))?(\s+(as\s+([a-z]+(,\s+[a-z]+)*)))?)?$/
15
- # 1 23 4 5 6 7 8
16
- # 1 2 3 4 5
17
-
18
- # Default mapping between tag symbols and methods
19
- DEFAULT_RULESET = {'?' => :conditional, '*' => :enumeration}
20
-
21
- #
22
- # Conditional as <tt>?{wlang/hosted}{...}{...}</tt>
23
- #
24
- # (third block is optional) Instantiates #1, looking for an expression in the
25
- # hosting language. Evaluates it, looking for a boolean value (according to
26
- # boolean semantics of the hosting language). If true, instantiates #2,
27
- # otherwise instantiates #3 if present.
28
- #
29
- def self.conditional(parser, offset)
30
- expression, reached = parser.parse(offset, "wlang/hosted")
31
- value = parser.evaluate(expression)
32
- if value
33
- then_block, reached = parser.parse_block(reached)
34
- if parser.has_block?(reached)
35
- else_block, reached = parser.parse_block(reached, "wlang/dummy")
36
- end
37
- [then_block, reached]
38
- else
39
- then_block, reached = parser.parse_block(reached, "wlang/dummy")
40
- else_block = ""
41
- if parser.has_block?(reached)
42
- else_block, reached = parser.parse_block(reached)
43
- end
44
- [else_block, reached]
45
- end
46
- end
47
-
48
- # Install args on the parser
49
- def self.merge_each_args(names, args)
50
- hash = {}
51
- size = names.length>args.length ? args.length : names.length
52
- 0.upto(size-1) do |i|
53
- hash[names[i]] = args[i]
54
- end
55
- hash
56
- end
57
-
58
- #
59
- # Enumeration as <tt>*{wlang/hosted using each as x}{...}{...}</tt>
60
- #
61
- # (third block is optional) Instantiates #1, looking for an expression in the
62
- # hosting language. Evaluates it, looking for an enumerable. Iterates all its
63
- # elements, instanciating #2 for each of them (the iterated value is set under
64
- # name x in the scope). If #3 is present, it is instantiated between elements.
65
- #
66
- def self.enumeration(parser, offset)
67
- expression, reached = parser.parse(offset, "wlang/hosted")
68
-
69
- # decode 'wlang/hosted using each as x' expression
70
- hash = U.expr(:expr,
71
- ["using", :var, false],
72
- ["as", :multi_as, false]).decode(expression, parser)
73
- hash[:using] = "each" unless hash[:using]
74
- hash[:as] = [] unless hash[:as]
75
- parser.syntax_error(offset, "invalid loop expression '#{expression}'") if hash.nil?
76
-
77
- # evaluate 'wlang/hosted' sub-expression
78
- value = hash[:expr]
79
- if value.nil?
80
- expression, reached = parser.parse_block(reached, "wlang/dummy")
81
- expression, reached = parser.parse_block(reached, "wlang/dummy") if parser.has_block?(reached)
82
- ["",reached]
83
- else
84
- raise "Enumerated value #{value} does not respond to #{hash[:using]}"\
85
- unless value.respond_to?(hash[:using])
86
-
87
- # some variables
88
- iterator, names = hash[:using].to_sym, hash[:as]
89
- buffer = parser.factor_buffer
90
-
91
- # wlang start index of each block
92
- block2, block3, theend = reached, nil, nil # *{}{block2}{block3}theend
93
- first = true
94
-
95
- # iterate now
96
- value.send iterator do |*args|
97
- if not(first) and parser.has_block?(block3)
98
- # parse #3, positioned at reached after that
99
- parsed, theend = parser.parse_block(block3)
100
- parser.append_buffer(buffer, parsed, true)
101
- end
102
-
103
- # install arguments and parse block2, positioned at block3
104
- parser.branch_scope(merge_each_args(names, args)) {
105
- parsed, block3 = parser.parse_block(block2)
106
- parser.append_buffer(buffer, parsed, true)
107
- }
108
- first = false
109
- end
110
-
111
- # Empty array special case
112
- unless block3
113
- parsed, block3 = parser.parse_block(block2, "wlang/dummy")
114
- end
115
-
116
- # Singleton array special case
117
- unless theend
118
- if parser.has_block?(block3)
119
- parsed, theend = parser.parse_block(block3, "wlang/dummy")
120
- else
121
- theend = block3
122
- end
123
- end
124
- [buffer, theend]
125
- end
126
-
127
- end
128
-
129
- end # module Imperative
130
-
131
- end
132
- end
@@ -1,317 +0,0 @@
1
- module WLang
2
- class RuleSet
3
- module Utils
4
-
5
- # Regexp string for 'dialect'
6
- DIALECT = '[-a-z]+'
7
-
8
- # Regexp string for 'encoder'
9
- ENCODER = '[-a-z]+'
10
-
11
- # Regexp string for 'qualified/dialect'
12
- QDIALECT = DIALECT + '([\/]' + DIALECT + ')*'
13
-
14
- # Regexp string for 'qualified/encoder'
15
- QENCODER = ENCODER + '([\/]' + ENCODER + ')*'
16
-
17
- # Regexp string for 'user_variable'
18
- VAR = '[a-z][a-z0-9_]*'
19
-
20
- # Regexp string for expression in the hosting language
21
- EXPR = '.*?'
22
-
23
- # Regexp string for URI expresion
24
- URI = '[^\s]+'
25
-
26
- # Part of a with expression
27
- WITH_PART = '(' + VAR + ')' + '\s*:\s*(' + EXPR + ')'
28
-
29
- # Regexp string for with expression
30
- WITH = WITH_PART + '(\s*,\s*(' + WITH_PART + '))*'
31
-
32
- # Regexp string for as expression
33
- MULTI_AS = VAR + '(' + '\s*,\s*' + VAR + ')*'
34
-
35
- # USING string for as expression
36
- USING = VAR + '(' + '\s*,\s*' + VAR + ')*'
37
-
38
- # SHARE string for expression
39
- SHARE = '(all|root|none)'
40
-
41
- # Basic blocks for building expressions
42
- BASIC_BLOCKS = {
43
- :dialect => {:str => DIALECT, :groups => 0, :decoder => nil},
44
- :encoder => {:str => ENCODER, :groups => 0, :decoder => nil},
45
- :qdialect => {:str => QDIALECT, :groups => 1, :decoder => nil},
46
- :qencoder => {:str => QENCODER, :groups => 1, :decoder => nil},
47
- :var => {:str => VAR, :groups => 0, :decoder => nil},
48
- :expr => {:str => EXPR, :groups => 0, :decoder => :decode_expr},
49
- :uri => {:str => URI, :groups => 0, :decoder => nil},
50
- :with => {:str => WITH, :groups => 6, :decoder => :decode_with},
51
- :multi_as => {:str => MULTI_AS, :groups => 1, :decoder => :decode_multi_as},
52
- :using => {:str => USING, :groups => 1, :decoder => :decode_using},
53
- :share => {:str => SHARE, :groups => 1, :decoder => :decode_share}
54
- }
55
-
56
- # Regular expressions of built expressions
57
- REGEXPS = {}
58
-
59
- # Builds an expression.
60
- def self.expr(*args)
61
- expr = REGEXPS[args]
62
- if expr.nil?
63
- # 1) we simply create an equivalent regular expression in _str_
64
- str, hash, count = '^\s*', {}, 0
65
- args.each do |arg|
66
- case arg
67
- when Symbol
68
- raise ArgumentError, "No reusable RuleSet::Utils block called #{arg}"\
69
- unless BASIC_BLOCKS[arg]
70
- str << '(' << BASIC_BLOCKS[arg][:str] << ')'
71
- hash[arg] = [(count+=1), BASIC_BLOCKS[arg][:decoder]]
72
- count += BASIC_BLOCKS[arg][:groups]
73
- when Array
74
- keyword, what, mandatory = arg
75
- raise ArgumentError, "No reusable RuleSet::Utils block called #{what}"\
76
- unless BASIC_BLOCKS[what]
77
- mandatory = true if mandatory.nil?
78
- unless mandatory
79
- str << '('
80
- count += 1
81
- end
82
- str << '\s+' << keyword << '\s+'
83
- str << '(' << BASIC_BLOCKS[what][:str] << ')'
84
- str << ')?' unless mandatory
85
- hash[keyword.to_sym] = [(count+=1), BASIC_BLOCKS[what][:decoder]]
86
- count += BASIC_BLOCKS[what][:groups]
87
- else
88
- raise ArgumentError, "Symbol or Array expected"
89
- end
90
- end
91
- str << '\s*$'
92
-
93
- # here is the expression, on which we put a decode method
94
- expr = {:regexp => Regexp.new(str), :places => hash}
95
- def expr.decode(str, parser=nil)
96
- matchdata = self[:regexp].match(str)
97
- return nil if matchdata.nil?
98
- decoded = {}
99
- self[:places].each_pair do |k,v|
100
- value = matchdata[v[0]]
101
- value = Utils.send(v[1], value, parser)\
102
- if v[1] and not(value.nil?)
103
- decoded[k] = value
104
- end
105
- return decoded
106
- end
107
-
108
- # and we save it!
109
- REGEXPS[args] = expr
110
- end
111
- expr
112
- end
113
-
114
- # Decodes an expression using the parser
115
- def self.decode_expr(expr, parser)
116
- return expr if parser.nil?
117
- parser.evaluate(expr)
118
- end
119
-
120
- # Regular expression for WITH
121
- RG_WITH = Regexp.new('^' + WITH + '$')
122
-
123
- # Decodes a with expression
124
- def self.decode_with(expr, parser, hash={})
125
- matchdata = RG_WITH.match(expr)
126
- return hash if matchdata.nil?
127
- hash[matchdata[1]] = decode_expr(matchdata[2], parser)
128
- decode_with(matchdata[4], parser, hash)
129
- end
130
-
131
- # Decodes a multi as expression
132
- def self.decode_multi_as(expr, parser)
133
- expr.split(/\s*,\s*/)
134
- end
135
-
136
- # Decodes a multi as expression
137
- def self.decode_using(expr, parser)
138
- expr.split(/\s*,\s*/).collect{|s| decode_expr(s, parser)}
139
- end
140
-
141
- # Decodes a multi as expression
142
- def self.decode_share(expr, parser)
143
- expr.to_sym
144
- end
145
-
146
- # Converts something to a usable hash
147
- def self.to_hash(hash)
148
- case hash
149
- when Hash
150
- hash.dup
151
- when NilClass
152
- {}
153
- when Array
154
- hash.inject({}){|memo, n| memo.merge!(to_hash(n))}
155
- else
156
- raise ArgumentError, "Unable to convert #{hash} to an hash"
157
- end
158
- end
159
-
160
- # Builds a hash for 'using ... with ...' rules from a decoded expression
161
- def self.context_from_using_and_with(decoded, parser = nil)
162
- context = to_hash(decoded[:using])
163
- context.merge!(decoded[:with]) unless decoded[:with].nil?
164
- context
165
- end
166
-
167
-
168
- ### DEPRECATED API ####################################################
169
-
170
- # Regular expression for 'user_variable'
171
- RG_VAR = Regexp.new('^\s*(' + VAR + ')\s*$')
172
-
173
- # Regular expression for expression in the hosting language
174
- RG_EXPR = Regexp.new('^\s*(' + EXPR + ')\s*$')
175
-
176
- # Regular expression for expression in the hosting language
177
- RG_URI = Regexp.new('^\s*(' + URI + ')\s*$')
178
-
179
- # Part of a with expression
180
- RG_WITH_PART = Regexp.new('(' + VAR + ')' + '\s*:\s*([^,]+)')
181
-
182
- # Regular expression for 'dialect'
183
- RG_DIALECT = Regexp.new('^\s*(' + DIALECT + ')\s*$')
184
-
185
- # Regular expression for 'encoder'
186
- RG_ENCODER = Regexp.new('^\s*(' + ENCODER + ')\s*$')
187
-
188
- # Regular expression for 'qualified/dialect'
189
- RG_QDIALECT = Regexp.new('^\s*(' + QDIALECT + ')\s*$')
190
-
191
- # Regular expression for 'qualified/encoder'
192
- RG_QENCODER = Regexp.new('^\s*(' + QENCODER + ')\s*$')
193
-
194
- # Regexp string for 'qualified/dialect as var'
195
- QDIALECT_AS = '(' + QDIALECT + ')\s+as\s+(' + VAR + ')'
196
-
197
- # Regular expression for 'qualified/dialect as var'
198
- RG_QDIALECT_AS = Regexp.new('^\s*(' + QDIALECT_AS + ')\s*$')
199
-
200
- # Regexp string for 'qualified/dialect with ...'
201
- QDIALECT_WITH = '(' + QDIALECT + ')\s+as\s+(' + WITH + ')'
202
-
203
- # Regular expression for 'qualified/dialect with ...'
204
- RG_QDIALECT_WITH = Regexp.new('^\s*(' + QDIALECT_WITH + ')\s*$')
205
-
206
- # Regexp string for 'qualified/encoder as var'
207
- QENCODER_AS = '(' + QENCODER + ')\s+as\s+(' + VAR + ')'
208
-
209
- # Regular expression for 'qualified/encoder as var'
210
- RG_QENCODER_AS = Regexp.new('^\s*(' + QENCODER_AS + ')\s*$')
211
-
212
- # Regexp string for 'wlang/hosted as var'
213
- EXPR_AS = '(' + EXPR + ')\s+as\s+(' + VAR + ')'
214
-
215
- # Regular expression for 'wlang/hosted as var'
216
- RG_EXPR_AS = Regexp.new('^\s*(' + EXPR_AS + ')\s*$')
217
-
218
- # Regexp string for 'wlang/uri as var'
219
- URI_AS = '(' + URI + ')\s+as\s+(' + VAR + ')'
220
-
221
- # Regular expression for 'wlang/uri as var'
222
- RG_URI_AS = Regexp.new('^\s*(' + URI_AS + ')\s*$')
223
-
224
- # Regespc string for 'wlang/uri with ...'
225
- URI_WITH = '(' + URI + ')\s+with\s+(' + WITH + ')'
226
-
227
- # Regular expression for 'wlang/uri as var'
228
- RG_URI_WITH = Regexp.new('^\s*(' + URI_WITH + ')\s*$')
229
-
230
- # Decodes a simple var expression
231
- def self.decode_var(src)
232
- match = RG_VAR.match(src)
233
- return nil unless match
234
- {:variable => match[1]}
235
- end
236
-
237
- # Decodes a 'qualified/dialect as var'. Returns a hash
238
- # with :dialect and :variable keys, or nil if _str_ does
239
- # not match.
240
- def self.decode_qdialect_as(str)
241
- match = RG_QDIALECT_AS.match(str)
242
- return nil unless match
243
- {:dialect => match[2], :variable => match[4]}
244
- end
245
-
246
- # Decodes a 'qualified/encoder as var'. Returns a hash
247
- # with :encoder and :variable keys, or nil if _str_ does
248
- # not match.
249
- def self.decode_qencoder_as(str)
250
- match = RG_QENCODER_AS.match(str)
251
- return nil unless match
252
- {:encoder => match[2], :variable => match[4]}
253
- end
254
-
255
- # Decodes a 'wlang/hosted as var'. Returns a hash
256
- # with :expression and :variable keys, or nil if _str_ does
257
- # not match.
258
- def self.decode_expr_as(str)
259
- match = RG_EXPR_AS.match(str)
260
- return nil unless match
261
- {:expr => match[2], :variable => match[3]}
262
- end
263
-
264
- # Decodes a 'wlang/uri as var'. Returns a hash
265
- # with :uri and :variable keys, or nil if _str_ does
266
- # not match.
267
- def self.decode_uri_as(str)
268
- match = RG_URI_AS.match(str)
269
- return nil unless match
270
- {:uri => match[2], :variable => match[3]}
271
- end
272
-
273
- # Decodes a 'wlang/uri with ...'. Returns a hash
274
- # with :uri and :with keys (with being another hash), or nil if _str_ does
275
- # not match.
276
- def self.decode_uri_with(str, parser=nil, optional=false)
277
- match = RG_URI_WITH.match(str)
278
- if match.nil?
279
- return nil unless optional
280
- match = RG_URI.match(str)
281
- return nil if match.nil?
282
- return {:uri => match[1], :with => nil}
283
- else
284
- with_expr, with = match[3], {}
285
- exprs = with_expr.split(/\s*,\s*/)
286
- exprs.each do |expr|
287
- RG_WITH_PART =~ expr
288
- with[$1] = parser.nil? ? $2 : parser.evaluate($2)
289
- end
290
- {:uri => match[2], :with => with}
291
- end
292
- end
293
-
294
- # Decodes a 'wlang/dialect with ...'. Returns a hash
295
- # with :dialect and :with keys (with being another hash),
296
- # or nil if _str_ does not match.
297
- def self.decode_qdialect_with(str, parser=nil, optional=false)
298
- match = RG_QDIALECT_WITH.match(str)
299
- if match.nil?
300
- return nil unless optional
301
- match = RG_QDIALECT.match(str)
302
- return nil if match.nil?
303
- return {:dialect => match[1], :with => nil}
304
- else
305
- with_expr, with = match[3], {}
306
- exprs = with_expr.split(/\s*,\s*/)
307
- exprs.each do |expr|
308
- RG_WITH_PART =~ expr
309
- with[$1] = parser.nil? ? $2 : parser.evaluate($2)
310
- end
311
- {:dialect => match[2], :with => with}
312
- end
313
- end
314
-
315
- end
316
- end
317
- end