wlang 0.10.2 → 2.0.0.beta

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