guard-mthaml 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (341) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +34 -0
  3. data/lib/guard/mthaml.rb +140 -0
  4. data/lib/guard/mthaml/compiler/MtHaml.php +255 -0
  5. data/lib/guard/mthaml/templates/Guardfile +12 -0
  6. data/lib/guard/mthaml/version.rb +5 -0
  7. data/vendor/autoload.php +7 -0
  8. data/vendor/coffeescript/coffeescript/LICENSE +22 -0
  9. data/vendor/coffeescript/coffeescript/README.md +96 -0
  10. data/vendor/coffeescript/coffeescript/composer.json +23 -0
  11. data/vendor/coffeescript/coffeescript/grammar.y +309 -0
  12. data/vendor/coffeescript/coffeescript/make.php +115 -0
  13. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Compiler.php +76 -0
  14. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Error.php +15 -0
  15. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Helpers.php +116 -0
  16. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Init.php +96 -0
  17. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Lexer.php +1356 -0
  18. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Nodes.php +105 -0
  19. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Parser.php +3326 -0
  20. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Rewriter.php +552 -0
  21. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Scope.php +196 -0
  22. data/vendor/coffeescript/coffeescript/src/CoffeeScript/SyntaxError.php +9 -0
  23. data/vendor/coffeescript/coffeescript/src/CoffeeScript/Value.php +20 -0
  24. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Access.php +31 -0
  25. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Arr.php +69 -0
  26. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Assign.php +353 -0
  27. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Base.php +288 -0
  28. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Block.php +294 -0
  29. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Call.php +283 -0
  30. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Class.php +282 -0
  31. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Closure.php +49 -0
  32. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Code.php +203 -0
  33. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Comment.php +39 -0
  34. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Existence.php +42 -0
  35. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Extends.php +26 -0
  36. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/For.php +250 -0
  37. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/If.php +161 -0
  38. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/In.php +99 -0
  39. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Index.php +27 -0
  40. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Literal.php +96 -0
  41. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Obj.php +126 -0
  42. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Op.php +292 -0
  43. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Param.php +119 -0
  44. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Parens.php +45 -0
  45. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Range.php +225 -0
  46. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Return.php +56 -0
  47. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Slice.php +47 -0
  48. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Splat.php +100 -0
  49. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Switch.php +121 -0
  50. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Throw.php +37 -0
  51. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Try.php +79 -0
  52. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/Value.php +210 -0
  53. data/vendor/coffeescript/coffeescript/src/CoffeeScript/yy/While.php +112 -0
  54. data/vendor/coffeescript/coffeescript/tests/cases/arrays.coffee +77 -0
  55. data/vendor/coffeescript/coffeescript/tests/cases/assignment.coffee +352 -0
  56. data/vendor/coffeescript/coffeescript/tests/cases/booleans.coffee +21 -0
  57. data/vendor/coffeescript/coffeescript/tests/cases/classes.coffee +681 -0
  58. data/vendor/coffeescript/coffeescript/tests/cases/comments.coffee +207 -0
  59. data/vendor/coffeescript/coffeescript/tests/cases/compilation.coffee +72 -0
  60. data/vendor/coffeescript/coffeescript/tests/cases/comprehensions.coffee +501 -0
  61. data/vendor/coffeescript/coffeescript/tests/cases/control_flow.coffee +430 -0
  62. data/vendor/coffeescript/coffeescript/tests/cases/eval.coffee +29 -0
  63. data/vendor/coffeescript/coffeescript/tests/cases/exception_handling.coffee +102 -0
  64. data/vendor/coffeescript/coffeescript/tests/cases/formatting.coffee +146 -0
  65. data/vendor/coffeescript/coffeescript/tests/cases/function_invocation.coffee +552 -0
  66. data/vendor/coffeescript/coffeescript/tests/cases/functions.coffee +188 -0
  67. data/vendor/coffeescript/coffeescript/tests/cases/helpers.coffee +96 -0
  68. data/vendor/coffeescript/coffeescript/tests/cases/importing.coffee +18 -0
  69. data/vendor/coffeescript/coffeescript/tests/cases/interpolation.coffee +138 -0
  70. data/vendor/coffeescript/coffeescript/tests/cases/javascript_literals.coffee +10 -0
  71. data/vendor/coffeescript/coffeescript/tests/cases/numbers.coffee +76 -0
  72. data/vendor/coffeescript/coffeescript/tests/cases/objects.coffee +271 -0
  73. data/vendor/coffeescript/coffeescript/tests/cases/operators.coffee +277 -0
  74. data/vendor/coffeescript/coffeescript/tests/cases/option_parser.coffee +43 -0
  75. data/vendor/coffeescript/coffeescript/tests/cases/ranges.coffee +88 -0
  76. data/vendor/coffeescript/coffeescript/tests/cases/regexps.coffee +63 -0
  77. data/vendor/coffeescript/coffeescript/tests/cases/scope.coffee +43 -0
  78. data/vendor/coffeescript/coffeescript/tests/cases/slicing_and_splicing.coffee +143 -0
  79. data/vendor/coffeescript/coffeescript/tests/cases/soaks.coffee +134 -0
  80. data/vendor/coffeescript/coffeescript/tests/cases/strict.coffee +155 -0
  81. data/vendor/coffeescript/coffeescript/tests/cases/strings.coffee +107 -0
  82. data/vendor/coffeescript/coffeescript/tests/css/style.css +43 -0
  83. data/vendor/coffeescript/coffeescript/tests/index.php +119 -0
  84. data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.1.1.js +8 -0
  85. data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.2.0.js +8 -0
  86. data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.3.0.js +8 -0
  87. data/vendor/coffeescript/coffeescript/tests/js/lib/coffeescript_1.3.1.js +8 -0
  88. data/vendor/coffeescript/coffeescript/tests/js/lib/diff.js +276 -0
  89. data/vendor/coffeescript/coffeescript/tests/js/main.js +123 -0
  90. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/LICENSE.txt +10 -0
  91. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/Lempar.php +948 -0
  92. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Action.php +257 -0
  93. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/ActionTable.php +299 -0
  94. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Config.php +574 -0
  95. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Data.php +1857 -0
  96. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Parser.php +851 -0
  97. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/PropagationLink.php +126 -0
  98. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Rule.php +144 -0
  99. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/State.php +283 -0
  100. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/Symbol.php +288 -0
  101. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/PHP/ParserGenerator/cli.php +5 -0
  102. data/vendor/coffeescript/coffeescript/vendor/ParserGenerator/ParserGenerator.php +811 -0
  103. data/vendor/composer/ClassLoader.php +383 -0
  104. data/vendor/composer/autoload_classmap.php +9 -0
  105. data/vendor/composer/autoload_namespaces.php +12 -0
  106. data/vendor/composer/autoload_psr4.php +10 -0
  107. data/vendor/composer/autoload_real.php +50 -0
  108. data/vendor/composer/installed.json +166 -0
  109. data/vendor/michelf/php-markdown/License.md +36 -0
  110. data/vendor/michelf/php-markdown/Michelf/Markdown.inc.php +10 -0
  111. data/vendor/michelf/php-markdown/Michelf/Markdown.php +3117 -0
  112. data/vendor/michelf/php-markdown/Michelf/MarkdownExtra.inc.php +11 -0
  113. data/vendor/michelf/php-markdown/Michelf/MarkdownExtra.php +38 -0
  114. data/vendor/michelf/php-markdown/Michelf/MarkdownInterface.inc.php +9 -0
  115. data/vendor/michelf/php-markdown/Michelf/MarkdownInterface.php +37 -0
  116. data/vendor/michelf/php-markdown/Readme.md +305 -0
  117. data/vendor/michelf/php-markdown/Readme.php +31 -0
  118. data/vendor/michelf/php-markdown/composer.json +31 -0
  119. data/vendor/mthaml/mthaml/CHANGELOG +48 -0
  120. data/vendor/mthaml/mthaml/LICENSE +44 -0
  121. data/vendor/mthaml/mthaml/README.markdown +262 -0
  122. data/vendor/mthaml/mthaml/composer.json +45 -0
  123. data/vendor/mthaml/mthaml/docs/Makefile +153 -0
  124. data/vendor/mthaml/mthaml/docs/_static/mthaml.css +30 -0
  125. data/vendor/mthaml/mthaml/docs/_theme/mthaml/theme.conf +4 -0
  126. data/vendor/mthaml/mthaml/docs/conf.py +242 -0
  127. data/vendor/mthaml/mthaml/docs/index.rst +18 -0
  128. data/vendor/mthaml/mthaml/docs/twig-syntax.rst +274 -0
  129. data/vendor/mthaml/mthaml/examples/README.md +5 -0
  130. data/vendor/mthaml/mthaml/examples/autoload.php +8 -0
  131. data/vendor/mthaml/mthaml/examples/example-php.haml +5 -0
  132. data/vendor/mthaml/mthaml/examples/example-php.php +37 -0
  133. data/vendor/mthaml/mthaml/examples/example-twig-noext.twig +11 -0
  134. data/vendor/mthaml/mthaml/examples/example-twig.haml +9 -0
  135. data/vendor/mthaml/mthaml/examples/example-twig.php +60 -0
  136. data/vendor/mthaml/mthaml/examples/example.twig.haml +8 -0
  137. data/vendor/mthaml/mthaml/lib/MtHaml/Autoloader.php +22 -0
  138. data/vendor/mthaml/mthaml/lib/MtHaml/Environment.php +178 -0
  139. data/vendor/mthaml/mthaml/lib/MtHaml/Escaping.php +33 -0
  140. data/vendor/mthaml/mthaml/lib/MtHaml/Exception.php +9 -0
  141. data/vendor/mthaml/mthaml/lib/MtHaml/Exception/SyntaxErrorException.php +9 -0
  142. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/AbstractFilter.php +43 -0
  143. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Cdata.php +16 -0
  144. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/CoffeeScript.php +33 -0
  145. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Css.php +26 -0
  146. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Escaped.php +22 -0
  147. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/FilterInterface.php +15 -0
  148. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Javascript.php +26 -0
  149. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Less.php +27 -0
  150. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Less/LeafoLess.php +20 -0
  151. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Less/OyejorgeLess.php +23 -0
  152. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown.php +58 -0
  153. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/CebeMarkdown.php +22 -0
  154. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/Ciconia.php +21 -0
  155. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/MichelfMarkdown.php +21 -0
  156. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Markdown/Parsedown.php +21 -0
  157. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Php.php +37 -0
  158. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Plain.php +24 -0
  159. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Preserve.php +19 -0
  160. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Scss.php +37 -0
  161. data/vendor/mthaml/mthaml/lib/MtHaml/Filter/Twig.php +47 -0
  162. data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/Indentation.php +96 -0
  163. data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/IndentationException.php +9 -0
  164. data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/IndentationInterface.php +50 -0
  165. data/vendor/mthaml/mthaml/lib/MtHaml/Indentation/Undefined.php +41 -0
  166. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Comment.php +71 -0
  167. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Doctype.php +96 -0
  168. data/vendor/mthaml/mthaml/lib/MtHaml/Node/EscapableAbstract.php +19 -0
  169. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Filter.php +51 -0
  170. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Insert.php +42 -0
  171. data/vendor/mthaml/mthaml/lib/MtHaml/Node/InterpolatedString.php +73 -0
  172. data/vendor/mthaml/mthaml/lib/MtHaml/Node/NestAbstract.php +117 -0
  173. data/vendor/mthaml/mthaml/lib/MtHaml/Node/NestInterface.php +10 -0
  174. data/vendor/mthaml/mthaml/lib/MtHaml/Node/NodeAbstract.php +77 -0
  175. data/vendor/mthaml/mthaml/lib/MtHaml/Node/ObjectRefClass.php +42 -0
  176. data/vendor/mthaml/mthaml/lib/MtHaml/Node/ObjectRefId.php +42 -0
  177. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Root.php +35 -0
  178. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Run.php +71 -0
  179. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Statement.php +45 -0
  180. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Tag.php +90 -0
  181. data/vendor/mthaml/mthaml/lib/MtHaml/Node/TagAttribute.php +62 -0
  182. data/vendor/mthaml/mthaml/lib/MtHaml/Node/TagAttributeInterpolation.php +24 -0
  183. data/vendor/mthaml/mthaml/lib/MtHaml/Node/TagAttributeList.php +24 -0
  184. data/vendor/mthaml/mthaml/lib/MtHaml/Node/Text.php +37 -0
  185. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Autoclose.php +25 -0
  186. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Escaping.php +105 -0
  187. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/MergeAttrs.php +110 -0
  188. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Midblock.php +37 -0
  189. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/NodeVisitorAbstract.php +226 -0
  190. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/NodeVisitorInterface.php +97 -0
  191. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/PhpRenderer.php +288 -0
  192. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/Printer.php +265 -0
  193. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/RendererAbstract.php +581 -0
  194. data/vendor/mthaml/mthaml/lib/MtHaml/NodeVisitor/TwigRenderer.php +252 -0
  195. data/vendor/mthaml/mthaml/lib/MtHaml/Parser.php +862 -0
  196. data/vendor/mthaml/mthaml/lib/MtHaml/Parser/Buffer.php +147 -0
  197. data/vendor/mthaml/mthaml/lib/MtHaml/Runtime.php +218 -0
  198. data/vendor/mthaml/mthaml/lib/MtHaml/Runtime/AttributeInterpolation.php +16 -0
  199. data/vendor/mthaml/mthaml/lib/MtHaml/Runtime/AttributeList.php +16 -0
  200. data/vendor/mthaml/mthaml/lib/MtHaml/Support/Php/Executor.php +157 -0
  201. data/vendor/mthaml/mthaml/lib/MtHaml/Support/Twig/Extension.php +47 -0
  202. data/vendor/mthaml/mthaml/lib/MtHaml/Support/Twig/Lexer.php +48 -0
  203. data/vendor/mthaml/mthaml/lib/MtHaml/Support/Twig/Loader.php +81 -0
  204. data/vendor/mthaml/mthaml/lib/MtHaml/Target/Php.php +23 -0
  205. data/vendor/mthaml/mthaml/lib/MtHaml/Target/TargetAbstract.php +87 -0
  206. data/vendor/mthaml/mthaml/lib/MtHaml/Target/TargetInterface.php +12 -0
  207. data/vendor/mthaml/mthaml/lib/MtHaml/Target/Twig.php +23 -0
  208. data/vendor/mthaml/mthaml/lib/MtHaml/TreeBuilder.php +100 -0
  209. data/vendor/mthaml/mthaml/lib/MtHaml/TreeBuilderException.php +9 -0
  210. data/vendor/mthaml/mthaml/phpunit.xml +25 -0
  211. data/vendor/mthaml/mthaml/test/MtHaml/Tests/EnvironmentTest.php +59 -0
  212. data/vendor/mthaml/mthaml/test/MtHaml/Tests/HamlSpecTest.php +83 -0
  213. data/vendor/mthaml/mthaml/test/MtHaml/Tests/IndentationTest.php +140 -0
  214. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Node/DoctypeTest.php +51 -0
  215. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Node/NodeTest.php +110 -0
  216. data/vendor/mthaml/mthaml/test/MtHaml/Tests/NodeVisitor/PhpRendererTest.php +113 -0
  217. data/vendor/mthaml/mthaml/test/MtHaml/Tests/NodeVisitor/TwigRendererTest.php +68 -0
  218. data/vendor/mthaml/mthaml/test/MtHaml/Tests/NodeVisitorsTest.php +44 -0
  219. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Parser/BufferTest.php +77 -0
  220. data/vendor/mthaml/mthaml/test/MtHaml/Tests/ParserTest.php +47 -0
  221. data/vendor/mthaml/mthaml/test/MtHaml/Tests/RuntimeTest.php +356 -0
  222. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Support/Php/ExecutorTest.php +83 -0
  223. data/vendor/mthaml/mthaml/test/MtHaml/Tests/Support/Twig/LoaderTest.php +65 -0
  224. data/vendor/mthaml/mthaml/test/MtHaml/Tests/TestCase.php +49 -0
  225. data/vendor/mthaml/mthaml/test/MtHaml/Tests/TestCaseTest.php +50 -0
  226. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/Support/Php/Executor.001.haml +1 -0
  227. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/attr_list_php.test +20 -0
  228. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/attr_list_twig.test +12 -0
  229. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/boolean_attr_php.test +16 -0
  230. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/boolean_attr_twig.test +16 -0
  231. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug28_php.test +15 -0
  232. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug28_twig.test +15 -0
  233. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug42.test +13 -0
  234. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/bug8_twig.test +10 -0
  235. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/coffeescript_filter.test +31 -0
  236. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/comments.test +26 -0
  237. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/cond_cmt.test +25 -0
  238. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype.test +18 -0
  239. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_html4.test +20 -0
  240. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_invalid.test +12 -0
  241. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_invalid_xhtml.test +12 -0
  242. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_php.test +18 -0
  243. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/doctype_xhtml.test +30 -0
  244. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/filters.test +51 -0
  245. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/insert_non_echo_php.test +11 -0
  246. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/insert_non_echo_twig.test +11 -0
  247. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/interpolation_in_html_attrs_php.test +31 -0
  248. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/interpolation_in_html_attrs_twig.test +31 -0
  249. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/less_filter_leafo.test +33 -0
  250. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/less_filter_oyejorge.test +49 -0
  251. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_cebemarkdown.test +35 -0
  252. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_ciconia.test +36 -0
  253. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_michelf.test +34 -0
  254. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_filter_parsedown.test +31 -0
  255. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/markdown_optimization_filter_michelf.test +23 -0
  256. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/mergeattrs.test +18 -0
  257. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/nuke_inner_whitespace.test +77 -0
  258. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/nuke_outer_whitespace.test +122 -0
  259. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/object_ref_php.test +14 -0
  260. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/object_ref_twig.test +14 -0
  261. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php.test +109 -0
  262. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_autoescaping.test +22 -0
  263. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_autoescaping_once.test +25 -0
  264. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_blocks.test +29 -0
  265. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/php_filters.test +42 -0
  266. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/scss_filter.test +32 -0
  267. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/strip_inline_comments_php.test +22 -0
  268. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/test.test +24 -0
  269. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/trailing_semicolon_php.test +14 -0
  270. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/try_catch_php.test +17 -0
  271. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig.test +112 -0
  272. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig_blocks.test +29 -0
  273. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig_filters.test +37 -0
  274. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/twig_whitespace.test +32 -0
  275. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/environment/whitespace.test +63 -0
  276. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/autoclose.test +30 -0
  277. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/escaping.test +52 -0
  278. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/escaping_attr_once.test +52 -0
  279. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/escaping_html_false.test +52 -0
  280. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/mergeattrs.test +26 -0
  281. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/midblock.test +54 -0
  282. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/nodevisitors/midblock_002.test +32 -0
  283. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attr_list.test +14 -0
  284. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs.test +42 -0
  285. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs_002.test +35 -0
  286. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs_003.test +30 -0
  287. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/attrs_html_linebreak.test +17 -0
  288. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/blocks.test +27 -0
  289. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/blocks_002.test +15 -0
  290. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/boolean_attr.test +19 -0
  291. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/bug28.test +15 -0
  292. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/bug8.test +11 -0
  293. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/cond_cmt.test +23 -0
  294. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/doctype.test +11 -0
  295. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/double_equal.test +7 -0
  296. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/empty_line_after_multiline.test +10 -0
  297. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_001.test +8 -0
  298. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_002.test +8 -0
  299. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_003.test +8 -0
  300. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_004.test +6 -0
  301. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_005.test +5 -0
  302. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_006.test +7 -0
  303. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_007.test +7 -0
  304. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_008.test +7 -0
  305. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_009.test +5 -0
  306. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_010.test +5 -0
  307. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_013.test +5 -0
  308. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_016.test +7 -0
  309. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_017.test +8 -0
  310. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_018.test +6 -0
  311. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_019.test +6 -0
  312. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/errors_020.test +5 -0
  313. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters.test +20 -0
  314. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_002.test +19 -0
  315. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_003.test +13 -0
  316. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_004.test +21 -0
  317. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_005.test +22 -0
  318. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/filters_006.test +23 -0
  319. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/insertflags.test +17 -0
  320. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/interpolation.test +36 -0
  321. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/interpolation_in_html_attrs.test +17 -0
  322. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/multiline.test +18 -0
  323. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/multiline_code.test +59 -0
  324. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/multiple_attr_kinds.test +47 -0
  325. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/non_rendered_comment.test +31 -0
  326. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ns.test +11 -0
  327. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/object_ref.test +22 -0
  328. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/object_ref_error1.test +5 -0
  329. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/object_ref_error2.test +5 -0
  330. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/quotes_in_haml.test +10 -0
  331. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby19_attrs.test +11 -0
  332. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma.test +23 -0
  333. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma_errors_001.test +5 -0
  334. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma_errors_002.test +5 -0
  335. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/ruby_attrs_comma_errors_003.test +5 -0
  336. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/standard.test +114 -0
  337. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/parser/tagflags.test +39 -0
  338. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/runtime/php_filters.test +28 -0
  339. data/vendor/mthaml/mthaml/test/MtHaml/Tests/fixtures/runtime/twig_filters.test +31 -0
  340. data/vendor/mthaml/mthaml/test/bootstrap.php +3 -0
  341. metadata +398 -0
@@ -0,0 +1,115 @@
1
+ <?php
2
+
3
+ define('ROOT', realpath(dirname(__FILE__)).'/');
4
+
5
+ // Disable output.
6
+ ini_set('implicit_flush', false);
7
+
8
+ function init()
9
+ {
10
+ $arg = array_slice($_SERVER['argv'], 1);
11
+ $arg = $arg ? $arg[0] : '';
12
+
13
+ if (in_array($arg, array('?', 'help')))
14
+ {
15
+ exit("make.php\n");
16
+ }
17
+
18
+ make();
19
+ }
20
+
21
+ function make()
22
+ {
23
+ require 'vendor/ParserGenerator/ParserGenerator.php';
24
+
25
+ $source = 'grammar';
26
+ $target = 'src/CoffeeScript/Parser.php';
27
+
28
+ // Lemon takes arguments on the command line.
29
+ $_SERVER['argv'] = $argv = array('-s', ROOT.$source.'.y');
30
+
31
+ echo "Attempting to build \"{$target}\" from \"{$source}.y\".\n";
32
+ echo "This could take a few minutes...\n";
33
+
34
+ // The -q flag doesn't seem to work but we can catch the output in a
35
+ // buffer (only want to display the errors).
36
+ ob_start();
37
+
38
+ $lemon = new PHP_ParserGenerator;
39
+ $lemon->main();
40
+
41
+ $reply = explode("\n", ob_get_contents());
42
+
43
+ ob_end_clean();
44
+
45
+ $errors = array();
46
+ $conflicts = 0;
47
+
48
+ foreach ($reply as $i => $line)
49
+ {
50
+ // Errors are prefixed with the grammar file path.
51
+ if (strpos($line, $argv[1]) === 0)
52
+ {
53
+ $errors[] = str_replace($argv[1], basename($argv[1]), $line);
54
+ }
55
+
56
+ if ($i === count($reply) - 2)
57
+ {
58
+ if (preg_match('/^(\d+).+/', $line, $m))
59
+ {
60
+ $conflicts = intval($m[1]);
61
+ }
62
+ }
63
+ }
64
+
65
+ if ($errors)
66
+ {
67
+ exit(implode("\n", $errors));
68
+ }
69
+
70
+ // Build was a success!
71
+ if ( ! file_exists(ROOT.$target) || @unlink(ROOT.$target))
72
+ {
73
+ $content = file_get_contents(ROOT.$source.'.php');
74
+
75
+ // Add namespace declaration.
76
+ $content = strtr($content, array(
77
+ '<?php' =>
78
+ "<?php\n"
79
+ . "namespace CoffeeScript;\n"
80
+ . "use \ArrayAccess as ArrayAccess;\n"
81
+ . "Init::init();\n"
82
+ ));
83
+
84
+ // Write.
85
+ file_put_contents(ROOT.$target, $content);
86
+
87
+ echo "Success!\n";
88
+
89
+ // Clean up.
90
+ unlink(ROOT.$source.'.php');
91
+
92
+ if ($conflicts)
93
+ {
94
+ echo "{$conflicts} parsing conflicts occurred (see {$source}.out).\n";
95
+ }
96
+ else
97
+ {
98
+ unlink(ROOT.$source.'.out');
99
+ }
100
+
101
+ exit(0);
102
+ }
103
+ else
104
+ {
105
+ // Bad permissions.
106
+ echo "Failed!\n";
107
+ echo "Couldn't remove {$target}. Check your permissions.\n";
108
+
109
+ exit(1);
110
+ }
111
+ }
112
+
113
+ init();
114
+
115
+ ?>
@@ -0,0 +1,76 @@
1
+ <?php
2
+
3
+ namespace CoffeeScript;
4
+
5
+ Init::init();
6
+
7
+ /**
8
+ * @package CoffeeScript
9
+ * @author Alex Little
10
+ * @license MIT
11
+ * @homepage http://github.com/alxlit/coffeescript-php
12
+ */
13
+ class Compiler {
14
+
15
+ /**
16
+ * Compile some CoffeeScript.
17
+ *
18
+ * Available options:
19
+ *
20
+ * 'filename' => The source file, for debugging (formatted into error messages)
21
+ * 'header' => Add a header to the generated source (default: TRUE)
22
+ * 'rewrite' => Enable rewriting token stream (debugging)
23
+ * 'tokens' => Reference to token stream (debugging)
24
+ * 'trace' => File to write parser trace to (debugging)
25
+ *
26
+ * @param string The source CoffeeScript code
27
+ * @param array Options (see above)
28
+ *
29
+ * @return string The resulting JavaScript (if there were no errors)
30
+ */
31
+ static function compile($code, $options = array())
32
+ {
33
+ $lexer = new Lexer($code, $options);
34
+
35
+ if (isset($options['filename']))
36
+ {
37
+ Parser::$FILE = $options['filename'];
38
+ }
39
+
40
+ if (isset($options['tokens']))
41
+ {
42
+ $tokens = & $options['tokens'];
43
+ }
44
+
45
+ if (isset($options['trace']))
46
+ {
47
+ Parser::Trace(fopen($options['trace'], 'w', TRUE), '> ');
48
+ }
49
+
50
+ try
51
+ {
52
+ $parser = new Parser();
53
+
54
+ foreach (($tokens = $lexer->tokenize()) as $token)
55
+ {
56
+ $parser->parse($token);
57
+ }
58
+
59
+ $js = $parser->parse(NULL)->compile($options);
60
+ }
61
+ catch (\Exception $e)
62
+ {
63
+ throw new Error("In {$options['filename']}, ".$e->getMessage());
64
+ }
65
+
66
+ if ( ! isset($options['header']) || $options['header'])
67
+ {
68
+ $js = '// Generated by CoffeeScript PHP ' . COFFEESCRIPT_VERSION . "\n" . $js;
69
+ }
70
+
71
+ return $js;
72
+ }
73
+
74
+ }
75
+
76
+ ?>
@@ -0,0 +1,15 @@
1
+ <?php
2
+
3
+ namespace CoffeeScript;
4
+
5
+ Init::init();
6
+
7
+ class Error extends \Exception
8
+ {
9
+ function __construct($message)
10
+ {
11
+ $this->message = $message;
12
+ }
13
+ }
14
+
15
+ ?>
@@ -0,0 +1,116 @@
1
+ <?php
2
+
3
+ namespace CoffeeScript;
4
+
5
+ Init::init();
6
+
7
+ class Helpers {
8
+
9
+ /**
10
+ * In some cases it seems to be unavoidable that method parameters conflict
11
+ * with their parent class's. This workaround is used to silence E_STRICT
12
+ * errors.
13
+ *
14
+ * @param $args `func_get_args()`
15
+ * @param $required The number of required arguments.
16
+ * @param $optional An array of defaults for optional arguments.
17
+ */
18
+ static function args(array $args, $required, array $optional = NULL)
19
+ {
20
+ if (count($args) < $required)
21
+ {
22
+ throw new Error("Function requires at least $required arguments.");
23
+ }
24
+
25
+ return array_merge($args, (array) $optional);
26
+ }
27
+
28
+ static function compact(array $array)
29
+ {
30
+ $compacted = array();
31
+
32
+ foreach ($array as $k => $v)
33
+ {
34
+ if ($v)
35
+ {
36
+ $compacted[] = $v;
37
+ }
38
+ }
39
+
40
+ return $compacted;
41
+ }
42
+
43
+ static function del( & $obj, $key)
44
+ {
45
+ $val = NULL;
46
+
47
+ if (isset($obj[$key]))
48
+ {
49
+ $val = $obj[$key];
50
+ unset($obj[$key]);
51
+ }
52
+
53
+ return $val;
54
+ }
55
+
56
+ static function extend($obj, $properties)
57
+ {
58
+ foreach ($properties as $k => $v)
59
+ {
60
+ $obj->{$k} = $v;
61
+ }
62
+
63
+ return $obj;
64
+ }
65
+
66
+ static function flatten(array $array)
67
+ {
68
+ $flattened = array();
69
+
70
+ foreach ($array as $k => $v)
71
+ {
72
+ if (is_array($v))
73
+ {
74
+ $flattened = array_merge($flattened, flatten($v));
75
+ }
76
+ else
77
+ {
78
+ $flattened[] = $v;
79
+ }
80
+ }
81
+
82
+ return $flattened;
83
+ }
84
+
85
+ static function & last( & $array, $back = 0)
86
+ {
87
+ static $NULL;
88
+
89
+ $i = count($array) - $back - 1;
90
+
91
+ if (isset($array[$i]))
92
+ {
93
+ return $array[$i];
94
+ }
95
+ else
96
+ {
97
+ // Make sure $NULL is really NULL.
98
+ $NULL = NULL;
99
+
100
+ return $NULL;
101
+ }
102
+ }
103
+
104
+
105
+ /**
106
+ * Wrap a primitive with an object, so that properties can be attached to it
107
+ * like in JavaScript.
108
+ */
109
+ static function wrap($v)
110
+ {
111
+ return new Value($v);
112
+ }
113
+
114
+ }
115
+
116
+ ?>
@@ -0,0 +1,96 @@
1
+ <?php
2
+
3
+ namespace CoffeeScript;
4
+
5
+ define('COFFEESCRIPT_VERSION', '1.3.1');
6
+
7
+ class Init {
8
+
9
+ /**
10
+ * Dummy function that doesn't actually do anything, it's just used to make
11
+ * sure that this file gets loaded.
12
+ */
13
+ static function init() {}
14
+
15
+ /**
16
+ * This function may be used in lieu of an autoloader.
17
+ */
18
+ static function load($root = NULL)
19
+ {
20
+ if ($root === NULL)
21
+ {
22
+ $root = realpath(dirname(__FILE__));
23
+ }
24
+
25
+ $files = array(
26
+ 'Compiler',
27
+ 'Error',
28
+ 'Helpers',
29
+ 'Lexer',
30
+ 'Nodes',
31
+ 'Parser',
32
+ 'Rewriter',
33
+ 'Scope',
34
+ 'SyntaxError',
35
+ 'Value',
36
+
37
+ 'yy/Base', // load the base class first
38
+ 'yy/While', // For extends While
39
+
40
+ 'yy/Access',
41
+ 'yy/Arr',
42
+ 'yy/Assign',
43
+ 'yy/Block',
44
+ 'yy/Call',
45
+ 'yy/Class',
46
+ 'yy/Closure',
47
+ 'yy/Code',
48
+ 'yy/Comment',
49
+ 'yy/Existence',
50
+ 'yy/Extends',
51
+ 'yy/For',
52
+ 'yy/If',
53
+ 'yy/In',
54
+ 'yy/Index',
55
+ 'yy/Literal',
56
+ 'yy/Obj',
57
+ 'yy/Op',
58
+ 'yy/Param',
59
+ 'yy/Parens',
60
+ 'yy/Range',
61
+ 'yy/Return',
62
+ 'yy/Slice',
63
+ 'yy/Splat',
64
+ 'yy/Switch',
65
+ 'yy/Throw',
66
+ 'yy/Try',
67
+ 'yy/Value',
68
+ );
69
+
70
+ foreach ($files as $file)
71
+ {
72
+ require_once "$root/$file.php";
73
+ }
74
+ }
75
+
76
+ }
77
+
78
+ //
79
+ // Function shortcuts. These are all used internally.
80
+ //
81
+
82
+ function args(array $args, $required, array $optional = NULL) { return Helpers::args($args, $required, $optional); }
83
+ function compact(array $array) { return Helpers::compact($array); }
84
+ function del( & $obj, $key) { return Helpers::del($obj, $key); }
85
+ function extend($obj, $properties) { return Helpers::extend($obj, $properties); }
86
+ function flatten(array $array) { return Helpers::flatten($array); }
87
+ function & last( & $array, $back = 0) { return Helpers::last($array, $back); }
88
+ function wrap($v) { return Helpers::wrap($v); }
89
+ function t() { return call_user_func_array('CoffeeScript\Lexer::t', func_get_args()); }
90
+ function t_canonical() { return call_user_func_array('CoffeeScript\Lexer::t_canonical', func_get_args()); }
91
+ function multident($code, $tab) { return Nodes::multident($code, $tab); }
92
+ function unfold_soak($options, $parent, $name) { return Nodes::unfold_soak($options, $parent, $name); }
93
+ function utility($name) { return Nodes::utility($name); }
94
+ function yy() { return call_user_func_array('CoffeeScript\Nodes::yy', func_get_args()); }
95
+
96
+ ?>
@@ -0,0 +1,1356 @@
1
+ <?php
2
+
3
+ namespace CoffeeScript;
4
+
5
+ Init::init();
6
+
7
+ /**
8
+ * CoffeeScript lexer. For the most part it's directly from the original
9
+ * source code, though there are some relatively minor differences in how it
10
+ * works with the parser (since we're using Lemon).
11
+ */
12
+ class Lexer
13
+ {
14
+ static $COFFEE_ALIASES = array(
15
+ 'and' => '&&',
16
+ 'or' => '||',
17
+ 'is' => '==',
18
+ 'isnt' => '!=',
19
+ 'not' => '!',
20
+ 'yes' => 'true',
21
+ 'no' => 'false',
22
+ 'on' => 'true',
23
+ 'off' => 'false'
24
+ );
25
+
26
+ static $COFFEE_KEYWORDS = array(
27
+ 'by',
28
+ 'loop',
29
+ 'of',
30
+ 'then',
31
+ 'undefined',
32
+ 'unless',
33
+ 'until',
34
+ 'when'
35
+ );
36
+
37
+ // exports.RESERVED.
38
+ static $COFFEE_RESERVED = array();
39
+
40
+ static $JS_KEYWORDS = array(
41
+ 'break',
42
+ 'catch',
43
+ 'class',
44
+ 'continue',
45
+ 'debugger',
46
+ 'delete',
47
+ 'do',
48
+ 'else',
49
+ 'extends',
50
+ 'false',
51
+ 'finally',
52
+ 'for',
53
+ 'if',
54
+ 'in',
55
+ 'instanceof',
56
+ 'new',
57
+ 'null',
58
+ 'this',
59
+ 'throw',
60
+ 'typeof',
61
+ 'return',
62
+ 'switch',
63
+ 'super',
64
+ 'true',
65
+ 'try',
66
+ 'while',
67
+ );
68
+
69
+ // RESERVED.
70
+ static $JS_RESERVED = array(
71
+ '__bind',
72
+ '__extends',
73
+ '__hasProp',
74
+ '__indexOf',
75
+ '__slice',
76
+ 'case',
77
+ 'const',
78
+ 'default',
79
+ 'enum',
80
+ 'export',
81
+ 'function',
82
+ 'implements',
83
+ 'import',
84
+ 'interface',
85
+ 'let',
86
+ 'native',
87
+ 'package',
88
+ 'protected',
89
+ 'private',
90
+ 'public',
91
+ 'static',
92
+ 'var',
93
+ 'void',
94
+ 'with',
95
+ 'yield',
96
+ );
97
+
98
+ static $STRICT_PROSCRIBED = array('arguments', 'eval');
99
+
100
+ static $JS_FORBIDDEN = array();
101
+
102
+ static $CODE = '/^[-=]>/';
103
+ static $COMMENT = '/^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)?$)|^(?:\s*#(?!##[^#]).*)+/';
104
+ static $HEREDOC = '/^("""|\'\'\')([\s\S]*?)(?:\n[^\n\S]*)?\1/';
105
+ static $HEREDOC_INDENT = '/\n+([^\n\S]*)/';
106
+ static $HEREDOC_ILLEGAL = '%\*/%';
107
+ static $HEREGEX = '%^/{3}([\s\S]+?)/{3}([imgy]{0,4})(?!\w)%';
108
+ static $HEREGEX_OMIT = '/\s+(?:#.*)?/';
109
+ static $IDENTIFIER = '/^([$A-Za-z_\x7f-\x{ffff}][$\w\x7f-\x{ffff}]*)([^\n\S]*:(?!:))?/u';
110
+ static $JSTOKEN = '/^`[^\\\\`]*(?:\\\\.[^\\\\`]*)*`/';
111
+ static $LINE_CONTINUER = '/^\s*(?:,|\??\.(?![.\d])|::)/';
112
+ static $MULTI_DENT = '/^(?:\n[^\n\S]*)+/';
113
+ static $MULTILINER = '/\n/';
114
+ static $NUMBER = '/^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i';
115
+ static $OPERATOR = '#^(?:[-=]>|[-+*/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})#';
116
+ static $REGEX = '%^(/(?![\s=])[^[/\n\\\\]*(?:(?:\\\\[\s\S]|\[[^\]\n\\\\]*(?:\\\\[\s\S][^\]\n\\\\]*)*\])[^[/\n\\\\]*)*/)([imgy]{0,4})(?!\w)%';
117
+ static $SIMPLESTR = '/^\'[^\\\\\']*(?:\\\\.[^\\\\\']*)*\'/i';
118
+ static $TRAILING_SPACES = '/\s+$/';
119
+ static $WHITESPACE = '/^[^\n\S]+/';
120
+
121
+ static $BOOL = array('TRUE', 'FALSE', 'NULL', 'UNDEFINED');
122
+ static $CALLABLE = array('IDENTIFIER', 'STRING', 'REGEX', ')', ']', '}', '?', '::', '@', 'THIS', 'SUPER');
123
+ static $COMPARE = array('==', '!=', '<', '>', '<=', '>=');
124
+ static $COMPOUND_ASSIGN = array('-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=' );
125
+ static $INDEXABLE = array('NUMBER', 'BOOL');
126
+ static $LINE_BREAK = array('INDENT', 'OUTDENT', 'TERMINATOR');
127
+ static $LOGIC = array('&&', '||', '&', '|', '^');
128
+ static $MATH = array('*', '/', '%');
129
+ static $NOT_REGEX = array('NUMBER', 'REGEX', 'BOOL', '++', '--', ']');
130
+ static $NOT_SPACED_REGEX = array(')', '}', 'THIS', 'IDENTIFIER', 'STRING');
131
+ static $RELATION = array('IN', 'OF', 'INSTANCEOF');
132
+ static $SHIFT = array('<<', '>>', '>>>');
133
+ static $UNARY = array('!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO');
134
+
135
+ static $INVERSES = array();
136
+
137
+ static $initialized = FALSE;
138
+
139
+ /**
140
+ * Initialize some static variables (called at the end of this file).
141
+ */
142
+ static function init()
143
+ {
144
+ if (self::$initialized) return;
145
+
146
+ self::$initialized = TRUE;
147
+
148
+ self::$COFFEE_KEYWORDS = array_merge(self::$COFFEE_KEYWORDS, array_keys(self::$COFFEE_ALIASES));
149
+ self::$COFFEE_RESERVED = array_merge(self::$JS_RESERVED, self::$JS_KEYWORDS, self::$COFFEE_KEYWORDS, self::$STRICT_PROSCRIBED);
150
+ self::$JS_FORBIDDEN = array_merge(self::$JS_KEYWORDS, self::$JS_RESERVED, self::$STRICT_PROSCRIBED);
151
+ self::$INDEXABLE = array_merge(self::$CALLABLE, self::$INDEXABLE);
152
+ self::$NOT_SPACED_REGEX = array_merge(self::$NOT_REGEX, self::$NOT_SPACED_REGEX);
153
+
154
+ Rewriter::init();
155
+
156
+ self::$INVERSES = Rewriter::$INVERSES;
157
+ }
158
+
159
+ /**
160
+ * In Jison, token tags can be represented simply using strings, whereas with
161
+ * ParserGenerator (a port of Lemon) we're stuck using numeric constants for
162
+ * everything.
163
+ *
164
+ * This static function maps those string representations to their numeric constants,
165
+ * making it easier to port directly from the CoffeeScript source.
166
+ */
167
+ static function t($name)
168
+ {
169
+ static $map = array(
170
+ '.' => 'ACCESSOR',
171
+ '[' => 'ARRAY_START',
172
+ ']' => 'ARRAY_END',
173
+ '@' => 'AT_SIGN',
174
+ '=>' => 'BOUND_FUNC',
175
+ ':' => 'COLON',
176
+ ',' => 'COMMA',
177
+ '--' => 'DECREMENT',
178
+ '=' => 'EQUALS',
179
+ '?' => 'EXISTENTIAL',
180
+ '?.' => 'EXISTENTIAL_ACCESSOR',
181
+ '->' => 'FUNC',
182
+ '++' => 'INCREMENT',
183
+ '&' => 'LOGIC',
184
+ '&&' => 'LOGIC',
185
+ '||' => 'LOGIC',
186
+ '-' => 'MINUS',
187
+ '{' => 'OBJECT_START',
188
+ '}' => 'OBJECT_END',
189
+ '(' => 'PAREN_START',
190
+ ')' => 'PAREN_END',
191
+ '+' => 'PLUS',
192
+ '::' => 'PROTOTYPE',
193
+ '...' => 'RANGE_EXCLUSIVE',
194
+ '..' => 'RANGE_INCLUSIVE',
195
+ );
196
+
197
+ if (is_array($name) || (func_num_args() > 1 && $name = func_get_args()))
198
+ {
199
+ $tags = array();
200
+
201
+ foreach ($name as $v)
202
+ {
203
+ $tags[] = t($v);
204
+ }
205
+
206
+ return $tags;
207
+ }
208
+
209
+ $prefix = 'CoffeeScript\Parser::YY_';
210
+
211
+ // In cases where there's no matching constant (see below) $name may
212
+ // already be prefixed.
213
+ if (strpos($name, $prefix) !== 0)
214
+ {
215
+ $name = $prefix.(isset($map[$name]) ? $map[$name] : $name);
216
+ }
217
+
218
+ // Don't return the original name if there's no matching constant, in some
219
+ // cases intermediate token types are created and the value returned by this
220
+ // static function still needs to be unique.
221
+ return defined($name) ? constant($name) : $name;
222
+ }
223
+
224
+ /**
225
+ * Change a CoffeeScript PHP token tag to it's equivalent canonical form (the
226
+ * form used in the JavaScript version).
227
+ *
228
+ * This static function is used for testing purposes only.
229
+ */
230
+ static function t_canonical($token)
231
+ {
232
+ static $map = array(
233
+ 'ACCESSOR' => '.',
234
+
235
+ // These are separate from INDEX_START and INDEX_END.
236
+ 'ARRAY_START' => '[',
237
+ 'ARRAY_END' => ']',
238
+
239
+ 'AT_SIGN' => '@',
240
+ 'BOUND_FUNC' => '=>',
241
+ 'COLON' => ':',
242
+ 'COMMA' => ',',
243
+ 'DECREMENT' => '--',
244
+ 'EQUALS' => '=',
245
+ 'EXISTENTIAL' => '?',
246
+ 'EXISTENTIAL_ACCESSOR' => '?.',
247
+ 'FUNC' => '->',
248
+ 'INCREMENT' => '++',
249
+ 'MINUS' => '-',
250
+ 'OBJECT_START' => '{',
251
+ 'OBJECT_END' => '}',
252
+
253
+ // These are separate from CALL_START and CALL_END.
254
+ 'PAREN_START' => '(',
255
+ 'PAREN_END' => ')',
256
+
257
+ 'PLUS' => '+',
258
+ 'PROTOTYPE' => '::',
259
+ 'RANGE_EXCLUSIVE' => '...',
260
+ 'RANGE_INCLUSIVE' => '..'
261
+ );
262
+
263
+ if (is_array($token))
264
+ {
265
+ if (is_array($token[0]))
266
+ {
267
+ foreach ($token as & $t)
268
+ {
269
+ $t = t_canonical($t);
270
+ }
271
+ }
272
+ else
273
+ {
274
+ // Single token.
275
+ $token[0] = t_canonical($token[0]);
276
+
277
+ if (is_object($token[1]))
278
+ {
279
+ $str = "< {$token[1]} ";
280
+
281
+ foreach ($token[1] as $k => $v)
282
+ {
283
+ if ($k !== 'v' && $v)
284
+ {
285
+ $str.= $k.' ';
286
+ }
287
+ }
288
+
289
+ $token[1] = $str.'>';
290
+ }
291
+ }
292
+
293
+ return $token;
294
+ }
295
+ else if (is_numeric($token))
296
+ {
297
+ $token = substr(Parser::tokenName($token), 3);
298
+ }
299
+ else if (is_string($token))
300
+ {
301
+ // The token type isn't known to the parser, so t() returned a unique
302
+ // string to use instead.
303
+ $token = substr($token, strlen('CoffeeScript\Parser::YY_'));
304
+ }
305
+
306
+ return isset($map[$token]) ? $map[$token] : $token;
307
+ }
308
+
309
+
310
+ function __construct($code, $options)
311
+ {
312
+ self::init();
313
+
314
+ if (preg_match(self::$WHITESPACE, $code))
315
+ {
316
+ $code = "\n{$code}";
317
+ }
318
+
319
+ $code = preg_replace(self::$TRAILING_SPACES, '', str_replace("\r", '', $code));
320
+
321
+ $options = array_merge(array(
322
+ 'indent' => 0,
323
+ 'index' => 0,
324
+ 'line' => 0,
325
+ 'rewrite' => TRUE
326
+ ),
327
+ $options);
328
+
329
+ $this->code = $code;
330
+ $this->chunk = $code;
331
+ $this->ends = array();
332
+ $this->indent = 0;
333
+ $this->indents = array();
334
+ $this->indebt = 0;
335
+ $this->index = $options['index'];
336
+ $this->length = strlen($this->code);
337
+ $this->line = $options['line'];
338
+ $this->outdebt = 0;
339
+ $this->options = $options;
340
+ $this->tokens = array();
341
+ }
342
+
343
+ function balanced_string($str, $end)
344
+ {
345
+ $continue_count = 0;
346
+
347
+ $stack = array($end);
348
+ $prev = NULL;
349
+
350
+ $len = strlen($str);
351
+
352
+ for ($i = 1; $i < $len; $i++)
353
+ {
354
+ if ($continue_count)
355
+ {
356
+ --$continue_count;
357
+ continue;
358
+ }
359
+
360
+ switch ($letter = $str{$i})
361
+ {
362
+ case '\\':
363
+ ++$continue_count;
364
+ continue 2;
365
+
366
+ case $end:
367
+ array_pop($stack);
368
+
369
+ if (count($stack) === 0)
370
+ {
371
+ return substr($str, 0, $i + 1);
372
+ }
373
+
374
+ $end = $stack[count($stack) - 1];
375
+ continue 2;
376
+ }
377
+
378
+ if ($end === '}' && ($letter === '"' || $letter === "'"))
379
+ {
380
+ $stack[] = $end = $letter;
381
+ }
382
+ else if ($end === '}' && $letter === '/' && (preg_match(self::$HEREGEX, substr($str, $i), $match) || preg_match(self::$REGEX, substr($str, $i), $match)))
383
+ {
384
+ $continue_count += strlen($match[0]) - 1;
385
+ }
386
+ else if ($end === '}' && $letter === '{')
387
+ {
388
+ $stack[] = $end = '}';
389
+ }
390
+ else if ($end === '"' && $prev === '#' && $letter === '{')
391
+ {
392
+ $stack[] = $end = '}';
393
+ }
394
+
395
+ $prev = $letter;
396
+ }
397
+
398
+ $this->error('missing '.array_pop($stack).', starting');
399
+ }
400
+
401
+ function close_indentation()
402
+ {
403
+ $this->outdent_token($this->indent);
404
+ }
405
+
406
+ function comment_token()
407
+ {
408
+ if ( ! preg_match(self::$COMMENT, $this->chunk, $match))
409
+ {
410
+ return 0;
411
+ }
412
+
413
+ $comment = $match[0];
414
+
415
+ if (isset($match[1]) && ($here = $match[1]))
416
+ {
417
+ $this->token('HERECOMMENT', $this->sanitize_heredoc($here, array(
418
+ 'herecomment' => TRUE,
419
+ 'indent' => str_pad('', $this->indent)
420
+ )));
421
+ }
422
+
423
+ $this->line += substr_count($comment, "\n");
424
+
425
+ return strlen($comment);
426
+ }
427
+
428
+ function error($message)
429
+ {
430
+ throw new SyntaxError($message.' on line '.($this->line + 1));
431
+ }
432
+
433
+ function escape_lines($str, $heredoc = NULL)
434
+ {
435
+ return preg_replace(self::$MULTILINER, $heredoc ? '\\n' : '', $str);
436
+ }
437
+
438
+ function heredoc_token()
439
+ {
440
+ if ( ! preg_match(self::$HEREDOC, $this->chunk, $match))
441
+ {
442
+ return 0;
443
+ }
444
+
445
+ $heredoc = $match[0];
446
+ $quote = $heredoc{0};
447
+ $doc = $this->sanitize_heredoc($match[2], array('quote' => $quote, 'indent' => NULL));
448
+
449
+ if ($quote === '"' && strpos($doc, '#{') !== FALSE)
450
+ {
451
+ $this->interpolate_string($doc, array('heredoc' => TRUE));
452
+ }
453
+ else
454
+ {
455
+ $this->token('STRING', $this->make_string($doc, $quote, TRUE));
456
+ }
457
+
458
+ $this->line += substr_count($heredoc, "\n");
459
+
460
+ return strlen($heredoc);
461
+ }
462
+
463
+ function heregex_token($match)
464
+ {
465
+ list($heregex, $body, $flags) = $match;
466
+
467
+ if (strpos($body, '#{') === FALSE)
468
+ {
469
+ $re = preg_replace(self::$HEREGEX_OMIT, '', $body);
470
+ $re = preg_replace('/\//', '\\/', $re);
471
+
472
+ if (preg_match('/^\*/', $re))
473
+ {
474
+ $this->error('regular expressions cannot begin with `*`');
475
+ }
476
+
477
+ $this->token('REGEX', '/'.($re ? $re : '(?:)').'/'.$flags);
478
+
479
+ return strlen($heregex);
480
+ }
481
+
482
+ $this->token('IDENTIFIER', 'RegExp');
483
+ $this->tokens[] = array(t('CALL_START'), '(');
484
+
485
+ $tokens = array();
486
+
487
+ foreach ($this->interpolate_string($body, array('regex' => TRUE)) as $token)
488
+ {
489
+ list($tag, $value) = $token;
490
+
491
+ if ($tag === 'TOKENS')
492
+ {
493
+ $tokens = array_merge($tokens, (array) $value);
494
+ }
495
+ else
496
+ {
497
+ if ( ! ($value = preg_replace(self::$HEREGEX_OMIT, '', $value)))
498
+ {
499
+ continue;
500
+ }
501
+
502
+ $value = preg_replace('/\\\\/', '\\\\\\\\', $value);
503
+ $tokens[] = array(t('STRING'), $this->make_string($value, '"', TRUE));
504
+ }
505
+
506
+ $tokens[] = array(t('+'), '+');
507
+ }
508
+
509
+ array_pop($tokens);
510
+
511
+ if ( ! (isset($tokens[0]) && $tokens[0][0] === 'STRING'))
512
+ {
513
+ array_push($this->tokens, array(t('STRING'), '""'), array(t('+'), '+'));
514
+ }
515
+
516
+ $this->tokens = array_merge($this->tokens, $tokens);
517
+
518
+ if ($flags)
519
+ {
520
+ array_push($this->tokens, array(t(','), ','), array(t('STRING'), "\"{$flags}\""));
521
+ }
522
+
523
+ $this->token(')', ')');
524
+
525
+ return strlen($heregex);
526
+ }
527
+
528
+ function identifier_token()
529
+ {
530
+ if ( ! preg_match(self::$IDENTIFIER, $this->chunk, $match))
531
+ {
532
+ return 0;
533
+ }
534
+
535
+ list($input, $id) = $match;
536
+
537
+ $colon = isset($match[2]) ? $match[2] : NULL;
538
+
539
+ if ($id === 'own' && $this->tag() === t('FOR'))
540
+ {
541
+ $this->token('OWN', $id);
542
+
543
+ return strlen($id);
544
+ }
545
+
546
+ $forced_identifier = $colon || ($prev = last($this->tokens)) &&
547
+ (in_array($prev[0], t('.', '?.', '::')) ||
548
+ ( ! (isset($prev['spaced']) && $prev['spaced']) && $prev[0] === t('@')));
549
+
550
+ $tag = 'IDENTIFIER';
551
+
552
+ if ( ! $forced_identifier and (in_array($id, self::$JS_KEYWORDS) || in_array($id, self::$COFFEE_KEYWORDS)))
553
+ {
554
+ $tag = strtoupper($id);
555
+
556
+ if ($tag === 'WHEN' && in_array($this->tag(), t(self::$LINE_BREAK)))
557
+ {
558
+ $tag = 'LEADING_WHEN';
559
+ }
560
+ else if ($tag === 'FOR')
561
+ {
562
+ $this->seen_for = TRUE;
563
+ }
564
+ else if ($tag === 'UNLESS')
565
+ {
566
+ $tag = 'IF';
567
+ }
568
+ else if (in_array($tag, self::$UNARY))
569
+ {
570
+ $tag = 'UNARY';
571
+ }
572
+ else if (in_array($tag, self::$RELATION))
573
+ {
574
+ if ($tag !== 'INSTANCEOF' && (isset($this->seen_for) && $this->seen_for))
575
+ {
576
+ $tag = 'FOR'.$tag;
577
+ $this->seen_for = FALSE;
578
+ }
579
+ else
580
+ {
581
+ $tag = 'RELATION';
582
+
583
+ if ($this->value() === '!')
584
+ {
585
+ array_pop($this->tokens);
586
+ $id = '!'. $id;
587
+ }
588
+ }
589
+ }
590
+ }
591
+
592
+ if (in_array($id, self::$JS_FORBIDDEN, TRUE))
593
+ {
594
+ if ($forced_identifier)
595
+ {
596
+ $id = wrap($id);
597
+ $id->reserved = TRUE;
598
+
599
+ $tag = 'IDENTIFIER';
600
+ }
601
+ else if (in_array($id, self::$JS_RESERVED, TRUE))
602
+ {
603
+ $this->error("reserved word $id");
604
+ }
605
+ }
606
+
607
+ if ( ! $forced_identifier)
608
+ {
609
+ if (isset(self::$COFFEE_ALIASES[$id]))
610
+ {
611
+ $id = self::$COFFEE_ALIASES[$id];
612
+ }
613
+
614
+ $map = array(
615
+ 'UNARY' => array('!'),
616
+ 'COMPARE' => array('==', '!='),
617
+ 'LOGIC' => array('&&', '||'),
618
+ 'BOOL' => array('true', 'false', 'null', 'undefined'),
619
+ 'STATEMENT' => array('break', 'continue')
620
+ );
621
+
622
+ foreach ($map as $k => $v)
623
+ {
624
+ if (in_array($id, $v))
625
+ {
626
+ $tag = $k;
627
+ break;
628
+ }
629
+ }
630
+ }
631
+
632
+ $this->token($tag, $id);
633
+
634
+ if ($colon)
635
+ {
636
+ $this->token(':', ':');
637
+ }
638
+
639
+ return strlen($input);
640
+ }
641
+
642
+ function interpolate_string($str, array $options = array()) // #{0}
643
+ {
644
+ $options = array_merge(array(
645
+ 'heredoc' => '',
646
+ 'regex' => NULL
647
+ ),
648
+ $options);
649
+
650
+ $tokens = array();
651
+ $pi = 0;
652
+ $i = -1;
653
+
654
+ while ( isset($str{++$i}) )
655
+ {
656
+ $letter = $str{$i};
657
+
658
+ if ($letter === '\\')
659
+ {
660
+ $i++;
661
+ continue;
662
+ }
663
+
664
+ if ( ! ($letter === '#' && (substr($str, $i + 1, 1) === '{') &&
665
+ ($expr = $this->balanced_string(substr($str, $i + 1), '}'))) )
666
+ {
667
+ continue;
668
+ }
669
+
670
+ if ($pi < $i)
671
+ {
672
+ $tokens[] = array('NEOSTRING', substr($str, $pi, $i - $pi));
673
+ }
674
+
675
+ $inner = substr($expr, 1, -1);
676
+
677
+ if (strlen($inner))
678
+ {
679
+ $lexer = new Lexer($inner, array(
680
+ 'line' => $this->line,
681
+ 'rewrite' => FALSE,
682
+ ));
683
+
684
+ $nested = $lexer->tokenize();
685
+
686
+ array_pop($nested);
687
+
688
+ if (isset($nested[0]) && $nested[0][0] === t('TERMINATOR'))
689
+ {
690
+ array_shift($nested);
691
+ }
692
+
693
+ if ( ($length = count($nested)) )
694
+ {
695
+ if ($length > 1)
696
+ {
697
+ array_unshift($nested, array(t('('), '(', $this->line));
698
+ $nested[] = array(t(')'), ')', $this->line);
699
+ }
700
+
701
+ $tokens[] = array('TOKENS', $nested);
702
+ }
703
+ }
704
+
705
+ $i += strlen($expr);
706
+ $pi = $i + 1;
707
+ }
708
+
709
+ if ($i > $pi && $pi < strlen($str))
710
+ {
711
+ $tokens[] = array('NEOSTRING', substr($str, $pi));
712
+ }
713
+
714
+ if ($options['regex'])
715
+ {
716
+ return $tokens;
717
+ }
718
+
719
+ if ( ! count($tokens))
720
+ {
721
+ return $this->token('STRING', '""');
722
+ }
723
+
724
+ if ( ! ($tokens[0][0] === 'NEOSTRING'))
725
+ {
726
+ array_unshift($tokens, array('', ''));
727
+ }
728
+
729
+ if ( ($interpolated = count($tokens) > 1) )
730
+ {
731
+ $this->token('(', '(');
732
+ }
733
+
734
+ for ($i = 0; $i < count($tokens); $i++)
735
+ {
736
+ list($tag, $value) = $tokens[$i];
737
+
738
+ if ($i)
739
+ {
740
+ $this->token('+', '+');
741
+ }
742
+
743
+ if ($tag === 'TOKENS')
744
+ {
745
+ $this->tokens = array_merge($this->tokens, $value);
746
+ }
747
+ else
748
+ {
749
+ $this->token('STRING', $this->make_string($value, '"', $options['heredoc']));
750
+ }
751
+ }
752
+
753
+ if ($interpolated)
754
+ {
755
+ $this->token(')', ')');
756
+ }
757
+
758
+ return $tokens;
759
+ }
760
+
761
+ function js_token()
762
+ {
763
+ if ( ! ($this->chunk{0} === '`' && preg_match(self::$JSTOKEN, $this->chunk, $match)))
764
+ {
765
+ return 0;
766
+ }
767
+
768
+ $this->token('JS', substr($script = $match[0], 1, -1));
769
+
770
+ return strlen($script);
771
+ }
772
+
773
+ function line_token()
774
+ {
775
+ if ( ! preg_match(self::$MULTI_DENT, $this->chunk, $match))
776
+ {
777
+ return 0;
778
+ }
779
+
780
+ $indent = $match[0];
781
+ $this->line += substr_count($indent, "\n");
782
+ $this->seen_for = FALSE;
783
+
784
+ // $prev = & last($this->tokens, 1);
785
+ $size = strlen($indent) - 1 - strrpos($indent, "\n");
786
+
787
+ $no_newlines = $this->unfinished();
788
+
789
+ if (($size - $this->indebt) === $this->indent)
790
+ {
791
+ if ($no_newlines)
792
+ {
793
+ $this->suppress_newlines();
794
+ }
795
+ else
796
+ {
797
+ $this->newline_token();
798
+ }
799
+
800
+ return strlen($indent);
801
+ }
802
+
803
+ if ($size > $this->indent)
804
+ {
805
+ if ($no_newlines)
806
+ {
807
+ $this->indebt = $size - $this->indent;
808
+ $this->suppress_newlines();
809
+
810
+ return strlen($indent);
811
+ }
812
+
813
+ $diff = $size - $this->indent + $this->outdebt;
814
+
815
+ $this->token('INDENT', $diff);
816
+ $this->indents[] = $diff;
817
+ $this->ends[] = 'OUTDENT';
818
+ $this->outdebt = $this->indebt = 0;
819
+ }
820
+ else
821
+ {
822
+ $this->indebt = 0;
823
+ $this->outdent_token($this->indent - $size, $no_newlines);
824
+ }
825
+
826
+ $this->indent = $size;
827
+
828
+ return strlen($indent);
829
+ }
830
+
831
+ function literal_token()
832
+ {
833
+ if (preg_match(self::$OPERATOR, $this->chunk, $match))
834
+ {
835
+ list($value) = $match;
836
+
837
+ if (preg_match(self::$CODE, $value))
838
+ {
839
+ $this->tag_parameters();
840
+ }
841
+ }
842
+ else
843
+ {
844
+ $value = $this->chunk{0};
845
+ }
846
+
847
+ $tag = t($value);
848
+ $prev = & last($this->tokens);
849
+
850
+ if ($value === '=' && $prev)
851
+ {
852
+ if ( ! (isset($prev[1]->reserved) && $prev[1]->reserved) && in_array(''.$prev[1], self::$JS_FORBIDDEN))
853
+ {
854
+ $this->error('reserved word "'.$this->value().'" can\'t be assigned');
855
+ }
856
+
857
+ if (in_array($prev[1], array('||', '&&')))
858
+ {
859
+ $prev[0] = t('COMPOUND_ASSIGN');
860
+ $prev[1] .= '=';
861
+
862
+ return 1;
863
+ }
864
+ }
865
+
866
+ if ($value === ';')
867
+ {
868
+ $this->seen_for = FALSE;
869
+ $tag = t('TERMINATOR');
870
+ }
871
+ else if (in_array($value, self::$MATH))
872
+ {
873
+ $tag = t('MATH');
874
+ }
875
+ else if (in_array($value, self::$COMPARE))
876
+ {
877
+ $tag = t('COMPARE');
878
+ }
879
+ else if (in_array($value, self::$COMPOUND_ASSIGN))
880
+ {
881
+ $tag = t('COMPOUND_ASSIGN');
882
+ }
883
+ else if (in_array($value, self::$UNARY))
884
+ {
885
+ $tag = t('UNARY');
886
+ }
887
+ else if (in_array($value, self::$SHIFT))
888
+ {
889
+ $tag = t('SHIFT');
890
+ }
891
+ else if (in_array($value, self::$LOGIC) || $value === '?' && (isset($prev['spaced']) && $prev['spaced']))
892
+ {
893
+ $tag = t('LOGIC');
894
+ }
895
+ else if ($prev && ! (isset($prev['spaced']) && $prev['spaced']))
896
+ {
897
+ if ($value === '(' && in_array($prev[0], t(self::$CALLABLE)))
898
+ {
899
+ if ($prev[0] === t('?'))
900
+ {
901
+ $prev[0] = t('FUNC_EXIST');
902
+ }
903
+
904
+ $tag = t('CALL_START');
905
+ }
906
+ else if ($value === '[' && in_array($prev[0], t(self::$INDEXABLE)))
907
+ {
908
+ $tag = t('INDEX_START');
909
+
910
+ if ($prev[0] === t('?'))
911
+ {
912
+ $prev[0] = t('INDEX_SOAK');
913
+ }
914
+ }
915
+ }
916
+
917
+ if (in_array($value, array('(', '{', '[')))
918
+ {
919
+ $this->ends[] = self::$INVERSES[$value];
920
+ }
921
+ else if (in_array($value, array(')', '}', ']')))
922
+ {
923
+ $this->pair($value);
924
+ }
925
+
926
+ $this->token($tag, $value);
927
+
928
+ return strlen($value);
929
+ }
930
+
931
+ function make_string($body, $quote, $heredoc = NULL)
932
+ {
933
+ if (!strlen($body))
934
+ {
935
+ return $quote.$quote;
936
+ }
937
+
938
+ $body = preg_replace_callback('/\\\\([\s\S])/', function($match) use ($quote)
939
+ {
940
+ $contents = $match[1];
941
+
942
+ if (in_array($contents, array("\n", $quote)))
943
+ {
944
+ return $contents;
945
+ }
946
+
947
+ return $match[0];
948
+ },
949
+ $body);
950
+
951
+ $body = preg_replace('/'.$quote.'/', '\\\\$0', $body);
952
+
953
+ return $quote.$this->escape_lines($body, $heredoc).$quote;
954
+ }
955
+
956
+ function newline_token()
957
+ {
958
+ while ($this->value() === ';')
959
+ {
960
+ array_pop($this->tokens);
961
+ }
962
+
963
+ if ($this->tag() !== t('TERMINATOR'))
964
+ {
965
+ $this->token('TERMINATOR', "\n");
966
+ }
967
+ }
968
+
969
+ function number_token()
970
+ {
971
+ if ( ! preg_match(self::$NUMBER, $this->chunk, $match))
972
+ {
973
+ return 0;
974
+ }
975
+
976
+ $number = $match[0];
977
+
978
+ if (preg_match('/^0[BOX]/', $number))
979
+ {
980
+ $this->error("radix prefix '$number' must be lowercase");
981
+ }
982
+ else if (preg_match('/E/', $number) && ! preg_match('/^0x/', $number))
983
+ {
984
+ $this->error("exponential notation '$number' must be indicated with a lowercase 'e'");
985
+ }
986
+ else if (preg_match('/^0\d*[89]/', $number))
987
+ {
988
+ $this->error("decimal literal '$number' must not be prefixed with '0'");
989
+ }
990
+ else if (preg_match('/^0\d+/', $number))
991
+ {
992
+ $this->error("octal literal '$number' must be prefixed with 0o");
993
+ }
994
+
995
+ $lexed_length = strlen($number);
996
+
997
+ if (preg_match('/^0o([0-7]+)/', $number, $octal_literal))
998
+ {
999
+ $number = '0x'.base_convert($octal_literal[1], 8, 16);
1000
+ }
1001
+
1002
+ if (preg_match('/^0b([01]+)/', $number, $binary_literal))
1003
+ {
1004
+ $number = '0x'.base_convert($binary_literal[1], 2, 16);
1005
+ }
1006
+
1007
+ $this->token('NUMBER', $number);
1008
+
1009
+ return $lexed_length;
1010
+ }
1011
+
1012
+ function outdent_token($move_out, $no_newlines = FALSE)
1013
+ {
1014
+ while ($move_out > 0)
1015
+ {
1016
+ $len = count($this->indents) - 1;
1017
+
1018
+ if ( ! isset($this->indents[$len]))
1019
+ {
1020
+ $move_out = 0;
1021
+ }
1022
+ else if ($this->indents[$len] === $this->outdebt)
1023
+ {
1024
+ $move_out -= $this->outdebt;
1025
+ $this->outdebt = 0;
1026
+ }
1027
+ else if ($this->indents[$len] < $this->outdebt)
1028
+ {
1029
+ $this->outdebt -= $this->indents[$len];
1030
+ $move_out -= $this->indents[$len];
1031
+ }
1032
+ else
1033
+ {
1034
+ $dent = array_pop($this->indents) - $this->outdebt;
1035
+ $move_out -= $dent;
1036
+ $this->outdebt = 0;
1037
+ $this->pair('OUTDENT');
1038
+ $this->token('OUTDENT', $dent);
1039
+ }
1040
+ }
1041
+
1042
+ if (isset($dent) && $dent)
1043
+ {
1044
+ $this->outdebt -= $move_out;
1045
+ }
1046
+
1047
+ while ($this->value() == ';')
1048
+ {
1049
+ array_pop($this->tokens);
1050
+ }
1051
+
1052
+ if ( ! ($this->tag() === t('TERMINATOR') || $no_newlines))
1053
+ {
1054
+ $this->token('TERMINATOR', "\n");
1055
+ }
1056
+
1057
+ return $this;
1058
+ }
1059
+
1060
+ function pair($tag)
1061
+ {
1062
+ if ( ! ($tag === ($wanted = last($this->ends))))
1063
+ {
1064
+ if ($wanted !== 'OUTDENT')
1065
+ {
1066
+ $this->error("unmateched $tag");
1067
+ }
1068
+
1069
+ $this->indent -= $size = last($this->indents);
1070
+ $this->outdent_token($size, TRUE);
1071
+
1072
+ return $this->pair($tag);
1073
+ }
1074
+
1075
+ return array_pop($this->ends);
1076
+ }
1077
+
1078
+ function regex_token()
1079
+ {
1080
+ if ($this->chunk{0} !== '/')
1081
+ {
1082
+ return 0;
1083
+ }
1084
+
1085
+ if (preg_match(self::$HEREGEX, $this->chunk, $match))
1086
+ {
1087
+ $length = $this->heregex_token($match);
1088
+ $this->line += substr_count($match[0], "\n");
1089
+
1090
+ return $length;
1091
+ }
1092
+
1093
+ $prev = last($this->tokens);
1094
+
1095
+ if ($prev)
1096
+ {
1097
+ if (in_array($prev[0], t((isset($prev['spaced']) && $prev['spaced']) ?
1098
+ self::$NOT_REGEX : self::$NOT_SPACED_REGEX)))
1099
+ {
1100
+ return 0;
1101
+ }
1102
+ }
1103
+
1104
+ if ( ! preg_match(self::$REGEX, $this->chunk, $match))
1105
+ {
1106
+ return 0;
1107
+ }
1108
+
1109
+ list($match, $regex, $flags) = $match;
1110
+
1111
+ if (substr($regex, 0, -1) === '/*')
1112
+ {
1113
+ $this->error('regular expressions cannot begin with `*`');
1114
+ }
1115
+
1116
+ $regex = $regex === '//' ? '/(?:)/' : $regex;
1117
+
1118
+ $this->token('REGEX', "{$regex}{$flags}");
1119
+
1120
+ return strlen($match);
1121
+ }
1122
+
1123
+ function sanitize_heredoc($doc, array $options)
1124
+ {
1125
+ $herecomment = isset($options['herecomment']) ? $options['herecomment'] : NULL;
1126
+ $indent = isset($options['indent']) ? $options['indent'] : NULL;
1127
+
1128
+ if ($herecomment)
1129
+ {
1130
+ if (preg_match(self::$HEREDOC_ILLEGAL, $doc))
1131
+ {
1132
+ $this->error('block comment cannot contain "*/*, starting');
1133
+ }
1134
+
1135
+ if ( ! strpos($doc, "\n"))
1136
+ {
1137
+ return $doc;
1138
+ }
1139
+ }
1140
+ else
1141
+ {
1142
+ $offset = 0;
1143
+
1144
+ while (preg_match(self::$HEREDOC_INDENT, $doc, $match, PREG_OFFSET_CAPTURE, $offset))
1145
+ {
1146
+ $attempt = $match[1][0];
1147
+ $offset = strlen($match[0][0]) + $match[0][1];
1148
+
1149
+ if ( is_null($indent) || (strlen($indent) > strlen($attempt) && strlen($attempt) > 0))
1150
+ {
1151
+ $indent = $attempt;
1152
+ }
1153
+ }
1154
+ }
1155
+
1156
+ if ($indent)
1157
+ {
1158
+ $doc = preg_replace('/\n'.$indent.'/', "\n", $doc);
1159
+ }
1160
+
1161
+ if ( ! $herecomment)
1162
+ {
1163
+ $doc = preg_replace('/^\n/', '', $doc);
1164
+ }
1165
+
1166
+ return $doc;
1167
+ }
1168
+
1169
+ function string_token()
1170
+ {
1171
+ switch ($this->chunk{0})
1172
+ {
1173
+ case "'":
1174
+ if ( ! preg_match(self::$SIMPLESTR, $this->chunk, $match))
1175
+ {
1176
+ return 0;
1177
+ }
1178
+
1179
+ $this->token('STRING', preg_replace(self::$MULTILINER, "\\\n", $string = $match[0]));
1180
+ break;
1181
+
1182
+ case '"':
1183
+ if ( ! ($string = $this->balanced_string($this->chunk, '"')))
1184
+ {
1185
+ return 0;
1186
+ }
1187
+
1188
+ if (strpos($string, '#{', 1) > 0)
1189
+ {
1190
+ $this->interpolate_string(substr($string, 1, -1));
1191
+ }
1192
+ else
1193
+ {
1194
+ $this->token('STRING', $this->escape_lines($string));
1195
+ }
1196
+
1197
+ break;
1198
+
1199
+ default:
1200
+ return 0;
1201
+ }
1202
+
1203
+ if (preg_match('/^(?:\\\\.|[^\\\\])*\\\\[0-7]/', $string, $octal_esc))
1204
+ {
1205
+ $this->error("octal escape sequences $string are not allowed");
1206
+ }
1207
+
1208
+ $this->line += substr_count($string, "\n");
1209
+
1210
+ return strlen($string);
1211
+ }
1212
+
1213
+ function suppress_newlines()
1214
+ {
1215
+ if ($this->value() === '\\')
1216
+ {
1217
+ array_pop($this->tokens);
1218
+ }
1219
+ }
1220
+
1221
+ function tag($index = 0, $tag = NULL)
1222
+ {
1223
+ $token = & last($this->tokens, $index);
1224
+
1225
+ if ( ! is_null($tag))
1226
+ {
1227
+ $token[0] = $tag;
1228
+ }
1229
+
1230
+ return $token[0];
1231
+ }
1232
+
1233
+ function tag_parameters()
1234
+ {
1235
+ if ($this->tag() !== t(')'))
1236
+ {
1237
+ return $this;
1238
+ }
1239
+
1240
+ $stack = array();
1241
+ $tokens = &$this->tokens;
1242
+
1243
+ $i = count($tokens);
1244
+ $tokens[--$i][0] = t('PARAM_END');
1245
+
1246
+ while ( ($tok = &$tokens[--$i]) )
1247
+ {
1248
+ if ($tok[0] === t(')'))
1249
+ {
1250
+ $stack[] = $tok;
1251
+ }
1252
+ else if (in_array($tok[0], t('(', 'CALL_START')))
1253
+ {
1254
+ if (count($stack))
1255
+ {
1256
+ array_pop($stack);
1257
+ }
1258
+ else if ($tok[0] === t('('))
1259
+ {
1260
+ $tok[0] = t('PARAM_START');
1261
+ return $this;
1262
+ }
1263
+ else
1264
+ {
1265
+ return $this;
1266
+ }
1267
+ }
1268
+ }
1269
+
1270
+ return $this;
1271
+ }
1272
+
1273
+ function token($tag, $value = NULL)
1274
+ {
1275
+ if ( ! is_numeric($tag))
1276
+ {
1277
+ $tag = t($tag);
1278
+ }
1279
+
1280
+ $token = array($tag, $value, $this->line);
1281
+
1282
+ return ($this->tokens[] = $token);
1283
+ }
1284
+
1285
+ function tokenize()
1286
+ {
1287
+ while ( ($this->chunk = substr($this->code, $this->index)) !== FALSE )
1288
+ {
1289
+ $types = array('identifier', 'comment', 'whitespace', 'line', 'heredoc',
1290
+ 'string', 'number', 'regex', 'js', 'literal');
1291
+
1292
+ foreach ($types as $type)
1293
+ {
1294
+ if ( ($d = $this->{$type.'_token'}()) )
1295
+ {
1296
+ $this->index += $d;
1297
+ break;
1298
+ }
1299
+ }
1300
+ }
1301
+
1302
+ $this->close_indentation();
1303
+
1304
+ if (($tag = array_pop($this->ends)) !== NULL)
1305
+ {
1306
+ $this->error('missing '.t_canonical($tag));
1307
+ }
1308
+
1309
+ if ($this->options['rewrite'])
1310
+ {
1311
+ $rewriter = new Rewriter($this->tokens);
1312
+ $this->tokens = $rewriter->rewrite();
1313
+ }
1314
+
1315
+ return $this->tokens;
1316
+ }
1317
+
1318
+ function value($index = 0, $value = NULL)
1319
+ {
1320
+ $token = & last($this->tokens, $index);
1321
+
1322
+ if ( ! is_null($value))
1323
+ {
1324
+ $token[1] = $value;
1325
+ }
1326
+
1327
+ return $token[1];
1328
+ }
1329
+
1330
+ function unfinished()
1331
+ {
1332
+ return
1333
+ preg_match(self::$LINE_CONTINUER, $this->chunk) ||
1334
+ in_array($this->tag(), t('\\', '.', '?.', 'UNARY', 'MATH', '+', '-', 'SHIFT', 'RELATION',
1335
+ 'COMPARE', 'LOGIC', 'THROW', 'EXTENDS'));
1336
+ }
1337
+
1338
+ function whitespace_token()
1339
+ {
1340
+ if ( ! (preg_match(self::$WHITESPACE, $this->chunk, $match) || ($nline = ($this->chunk{0} === "\n"))))
1341
+ {
1342
+ return 0;
1343
+ }
1344
+
1345
+ $prev = & last($this->tokens);
1346
+
1347
+ if ($prev)
1348
+ {
1349
+ $prev[$match ? 'spaced' : 'newLine'] = TRUE;
1350
+ }
1351
+
1352
+ return $match ? strlen($match[0]) : 0;
1353
+ }
1354
+ }
1355
+
1356
+ ?>