haml-more 0.4.0.a

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. data/README.md +79 -0
  2. data/lib/haml/more/coffee_script.rb +137 -0
  3. data/lib/haml/more/content_for.rb +25 -0
  4. data/lib/haml/more.rb +45 -0
  5. data/lib/haml-more.rb +1 -0
  6. data/lib/sass/more.rb +16 -0
  7. data/lib/sass-more.rb +1 -0
  8. data/spec/sass/more_spec.rb +21 -0
  9. data/vendor/coffee-script/Cakefile +57 -0
  10. data/vendor/coffee-script/LICENSE +22 -0
  11. data/vendor/coffee-script/README +41 -0
  12. data/vendor/coffee-script/Rakefile +20 -0
  13. data/vendor/coffee-script/bin/cake +7 -0
  14. data/vendor/coffee-script/bin/coffee +7 -0
  15. data/vendor/coffee-script/documentation/coffee/aliases.coffee +9 -0
  16. data/vendor/coffee-script/documentation/coffee/arguments.coffee +4 -0
  17. data/vendor/coffee-script/documentation/coffee/array_comprehensions.coffee +7 -0
  18. data/vendor/coffee-script/documentation/coffee/assignment.coffee +2 -0
  19. data/vendor/coffee-script/documentation/coffee/cake_tasks.coffee +5 -0
  20. data/vendor/coffee-script/documentation/coffee/comparisons.coffee +5 -0
  21. data/vendor/coffee-script/documentation/coffee/conditionals.coffee +9 -0
  22. data/vendor/coffee-script/documentation/coffee/embedded.coffee +5 -0
  23. data/vendor/coffee-script/documentation/coffee/existence.coffee +8 -0
  24. data/vendor/coffee-script/documentation/coffee/expressions.coffee +9 -0
  25. data/vendor/coffee-script/documentation/coffee/expressions_assignment.coffee +1 -0
  26. data/vendor/coffee-script/documentation/coffee/expressions_comprehension.coffee +3 -0
  27. data/vendor/coffee-script/documentation/coffee/expressions_try.coffee +6 -0
  28. data/vendor/coffee-script/documentation/coffee/fat_arrow.coffee +6 -0
  29. data/vendor/coffee-script/documentation/coffee/functions.coffee +2 -0
  30. data/vendor/coffee-script/documentation/coffee/heredocs.coffee +5 -0
  31. data/vendor/coffee-script/documentation/coffee/multiple_return_values.coffee +5 -0
  32. data/vendor/coffee-script/documentation/coffee/object_comprehensions.coffee +4 -0
  33. data/vendor/coffee-script/documentation/coffee/object_extraction.coffee +13 -0
  34. data/vendor/coffee-script/documentation/coffee/objects_and_arrays.coffee +13 -0
  35. data/vendor/coffee-script/documentation/coffee/overview.coffee +29 -0
  36. data/vendor/coffee-script/documentation/coffee/parallel_assignment.coffee +4 -0
  37. data/vendor/coffee-script/documentation/coffee/range_comprehensions.coffee +6 -0
  38. data/vendor/coffee-script/documentation/coffee/scope.coffee +5 -0
  39. data/vendor/coffee-script/documentation/coffee/slices.coffee +6 -0
  40. data/vendor/coffee-script/documentation/coffee/soaks.coffee +1 -0
  41. data/vendor/coffee-script/documentation/coffee/splats.coffee +25 -0
  42. data/vendor/coffee-script/documentation/coffee/splices.coffee +5 -0
  43. data/vendor/coffee-script/documentation/coffee/strings.coffee +8 -0
  44. data/vendor/coffee-script/documentation/coffee/super.coffee +34 -0
  45. data/vendor/coffee-script/documentation/coffee/switch.coffee +10 -0
  46. data/vendor/coffee-script/documentation/coffee/try.coffee +7 -0
  47. data/vendor/coffee-script/documentation/coffee/while.coffee +10 -0
  48. data/vendor/coffee-script/documentation/css/docs.css +213 -0
  49. data/vendor/coffee-script/documentation/css/idle.css +63 -0
  50. data/vendor/coffee-script/documentation/css/logo.png +0 -0
  51. data/vendor/coffee-script/documentation/index.html.erb +967 -0
  52. data/vendor/coffee-script/documentation/js/aliases.js +14 -0
  53. data/vendor/coffee-script/documentation/js/arguments.js +8 -0
  54. data/vendor/coffee-script/documentation/js/array_comprehensions.js +26 -0
  55. data/vendor/coffee-script/documentation/js/assignment.js +5 -0
  56. data/vendor/coffee-script/documentation/js/cake_tasks.js +14 -0
  57. data/vendor/coffee-script/documentation/js/comparisons.js +5 -0
  58. data/vendor/coffee-script/documentation/js/conditionals.js +12 -0
  59. data/vendor/coffee-script/documentation/js/embedded.js +6 -0
  60. data/vendor/coffee-script/documentation/js/existence.js +7 -0
  61. data/vendor/coffee-script/documentation/js/expressions.js +13 -0
  62. data/vendor/coffee-script/documentation/js/expressions_assignment.js +4 -0
  63. data/vendor/coffee-script/documentation/js/expressions_comprehension.js +12 -0
  64. data/vendor/coffee-script/documentation/js/expressions_try.js +9 -0
  65. data/vendor/coffee-script/documentation/js/fat_arrow.js +15 -0
  66. data/vendor/coffee-script/documentation/js/functions.js +9 -0
  67. data/vendor/coffee-script/documentation/js/heredocs.js +4 -0
  68. data/vendor/coffee-script/documentation/js/intro.js +7 -0
  69. data/vendor/coffee-script/documentation/js/multiple_return_values.js +11 -0
  70. data/vendor/coffee-script/documentation/js/object_comprehensions.js +17 -0
  71. data/vendor/coffee-script/documentation/js/object_extraction.js +17 -0
  72. data/vendor/coffee-script/documentation/js/objects_and_arrays.js +10 -0
  73. data/vendor/coffee-script/documentation/js/overview.js +43 -0
  74. data/vendor/coffee-script/documentation/js/parallel_assignment.js +8 -0
  75. data/vendor/coffee-script/documentation/js/punctuation.js +8 -0
  76. data/vendor/coffee-script/documentation/js/range_comprehensions.js +21 -0
  77. data/vendor/coffee-script/documentation/js/scope.js +10 -0
  78. data/vendor/coffee-script/documentation/js/slices.js +6 -0
  79. data/vendor/coffee-script/documentation/js/soaks.js +4 -0
  80. data/vendor/coffee-script/documentation/js/splats.js +16 -0
  81. data/vendor/coffee-script/documentation/js/splices.js +5 -0
  82. data/vendor/coffee-script/documentation/js/strings.js +9 -0
  83. data/vendor/coffee-script/documentation/js/super.js +37 -0
  84. data/vendor/coffee-script/documentation/js/switch.js +18 -0
  85. data/vendor/coffee-script/documentation/js/try.js +10 -0
  86. data/vendor/coffee-script/documentation/js/while.js +22 -0
  87. data/vendor/coffee-script/documentation/underscore.html +627 -0
  88. data/vendor/coffee-script/examples/beautiful_code/binary_search.coffee +16 -0
  89. data/vendor/coffee-script/examples/beautiful_code/quicksort_runtime.coffee +13 -0
  90. data/vendor/coffee-script/examples/beautiful_code/regular_expression_matcher.coffee +34 -0
  91. data/vendor/coffee-script/examples/blocks.coffee +57 -0
  92. data/vendor/coffee-script/examples/code.coffee +173 -0
  93. data/vendor/coffee-script/examples/computer_science/README +4 -0
  94. data/vendor/coffee-script/examples/computer_science/binary_search.coffee +25 -0
  95. data/vendor/coffee-script/examples/computer_science/bubble_sort.coffee +11 -0
  96. data/vendor/coffee-script/examples/computer_science/linked_list.coffee +106 -0
  97. data/vendor/coffee-script/examples/computer_science/luhn_algorithm.coffee +36 -0
  98. data/vendor/coffee-script/examples/computer_science/merge_sort.coffee +19 -0
  99. data/vendor/coffee-script/examples/computer_science/selection_sort.coffee +23 -0
  100. data/vendor/coffee-script/examples/poignant.coffee +186 -0
  101. data/vendor/coffee-script/examples/potion.coffee +205 -0
  102. data/vendor/coffee-script/examples/underscore.coffee +603 -0
  103. data/vendor/coffee-script/examples/web_server.coffee +12 -0
  104. data/vendor/coffee-script/extras/CoffeeScript.tmbundle/Preferences/CoffeeScript.tmPreferences +24 -0
  105. data/vendor/coffee-script/extras/CoffeeScript.tmbundle/Syntaxes/CoffeeScript.tmLanguage +361 -0
  106. data/vendor/coffee-script/extras/CoffeeScript.tmbundle/info.plist +10 -0
  107. data/vendor/coffee-script/extras/EXTRAS +20 -0
  108. data/vendor/coffee-script/extras/coffee.vim +117 -0
  109. data/vendor/coffee-script/index.html +1847 -0
  110. data/vendor/coffee-script/lib/bin/cake +7 -0
  111. data/vendor/coffee-script/lib/bin/coffee +7 -0
  112. data/vendor/coffee-script/lib/cake.js +80 -0
  113. data/vendor/coffee-script/lib/coffee-script.js +61 -0
  114. data/vendor/coffee-script/lib/command_line.js +201 -0
  115. data/vendor/coffee-script/lib/grammar.js +564 -0
  116. data/vendor/coffee-script/lib/lexer.js +405 -0
  117. data/vendor/coffee-script/lib/narwhal.js +44 -0
  118. data/vendor/coffee-script/lib/nodes.js +1328 -0
  119. data/vendor/coffee-script/lib/optparse.js +117 -0
  120. data/vendor/coffee-script/lib/parser.js +536 -0
  121. data/vendor/coffee-script/lib/repl.js +32 -0
  122. data/vendor/coffee-script/lib/rewriter.js +383 -0
  123. data/vendor/coffee-script/lib/scope.js +114 -0
  124. data/vendor/coffee-script/package.json +7 -0
  125. data/vendor/coffee-script/src/cake.coffee +45 -0
  126. data/vendor/coffee-script/src/coffee-script.coffee +45 -0
  127. data/vendor/coffee-script/src/command_line.coffee +130 -0
  128. data/vendor/coffee-script/src/grammar.coffee +456 -0
  129. data/vendor/coffee-script/src/lexer.coffee +327 -0
  130. data/vendor/coffee-script/src/narwhal.coffee +42 -0
  131. data/vendor/coffee-script/src/nodes.coffee +1045 -0
  132. data/vendor/coffee-script/src/optparse.coffee +79 -0
  133. data/vendor/coffee-script/src/repl.coffee +23 -0
  134. data/vendor/coffee-script/src/rewriter.coffee +253 -0
  135. data/vendor/coffee-script/src/scope.coffee +75 -0
  136. data/vendor/coffee-script/test/test_arguments.coffee +34 -0
  137. data/vendor/coffee-script/test/test_array_comprehension.coffee +42 -0
  138. data/vendor/coffee-script/test/test_assignment.coffee +26 -0
  139. data/vendor/coffee-script/test/test_blocks.coffee +4 -0
  140. data/vendor/coffee-script/test/test_calling_super.coffee +42 -0
  141. data/vendor/coffee-script/test/test_chained_calls.coffee +25 -0
  142. data/vendor/coffee-script/test/test_destructuring_assignment.coffee +62 -0
  143. data/vendor/coffee-script/test/test_everything.coffee +29 -0
  144. data/vendor/coffee-script/test/test_exceptions.coffee +2 -0
  145. data/vendor/coffee-script/test/test_existence.coffee +81 -0
  146. data/vendor/coffee-script/test/test_expressions.coffee +30 -0
  147. data/vendor/coffee-script/test/test_fancy_if_statement.coffee +26 -0
  148. data/vendor/coffee-script/test/test_functions.coffee +80 -0
  149. data/vendor/coffee-script/test/test_funky_comments.coffee +25 -0
  150. data/vendor/coffee-script/test/test_heredocs.coffee +46 -0
  151. data/vendor/coffee-script/test/test_lexical_scope.coffee +10 -0
  152. data/vendor/coffee-script/test/test_literals.coffee +56 -0
  153. data/vendor/coffee-script/test/test_nested_comprehensions.coffee +11 -0
  154. data/vendor/coffee-script/test/test_newline_escaping.coffee +6 -0
  155. data/vendor/coffee-script/test/test_operations.coffee +18 -0
  156. data/vendor/coffee-script/test/test_range_comprehension.coffee +20 -0
  157. data/vendor/coffee-script/test/test_ranges_and_slices.coffee +16 -0
  158. data/vendor/coffee-script/test/test_splats.coffee +47 -0
  159. data/vendor/coffee-script/test/test_splices.coffee +5 -0
  160. data/vendor/coffee-script/test/test_switch.coffee +64 -0
  161. data/vendor/coffee-script/test/test_while.coffee +30 -0
  162. data/vendor/coffee-script/vendor/jison/Jakefile +31 -0
  163. data/vendor/coffee-script/vendor/jison/README.md +347 -0
  164. data/vendor/coffee-script/vendor/jison/bin/jison +3 -0
  165. data/vendor/coffee-script/vendor/jison/bin/json2jison +3 -0
  166. data/vendor/coffee-script/vendor/jison/examples/ansic.jison +415 -0
  167. data/vendor/coffee-script/vendor/jison/examples/basic.json +8 -0
  168. data/vendor/coffee-script/vendor/jison/examples/basic2.json +9 -0
  169. data/vendor/coffee-script/vendor/jison/examples/basic2_lex.json +16 -0
  170. data/vendor/coffee-script/vendor/jison/examples/basic_lex.json +15 -0
  171. data/vendor/coffee-script/vendor/jison/examples/calculator.jison +38 -0
  172. data/vendor/coffee-script/vendor/jison/examples/calculator.jisonlex +14 -0
  173. data/vendor/coffee-script/vendor/jison/examples/calculator.json +42 -0
  174. data/vendor/coffee-script/vendor/jison/examples/classy.json +105 -0
  175. data/vendor/coffee-script/vendor/jison/examples/classy_ast.json +126 -0
  176. data/vendor/coffee-script/vendor/jison/examples/dism.json +25 -0
  177. data/vendor/coffee-script/vendor/jison/examples/dism_lr0.json +26 -0
  178. data/vendor/coffee-script/vendor/jison/examples/json.js +80 -0
  179. data/vendor/coffee-script/vendor/jison/examples/json_ast.js +83 -0
  180. data/vendor/coffee-script/vendor/jison/examples/precedence.json +26 -0
  181. data/vendor/coffee-script/vendor/jison/examples/reduce_conflict.json +13 -0
  182. data/vendor/coffee-script/vendor/jison/lib/jison/bnf.js +43 -0
  183. data/vendor/coffee-script/vendor/jison/lib/jison/jisonlex.js +18 -0
  184. data/vendor/coffee-script/vendor/jison/lib/jison/json2jison.js +146 -0
  185. data/vendor/coffee-script/vendor/jison/lib/jison/lexer.js +224 -0
  186. data/vendor/coffee-script/vendor/jison/lib/jison/util/bnf-parser.js +383 -0
  187. data/vendor/coffee-script/vendor/jison/lib/jison/util/lex-parser.js +407 -0
  188. data/vendor/coffee-script/vendor/jison/lib/jison/util/set.js +94 -0
  189. data/vendor/coffee-script/vendor/jison/lib/jison/util/typal.js +90 -0
  190. data/vendor/coffee-script/vendor/jison/lib/jison.js +1414 -0
  191. data/vendor/coffee-script/vendor/jison/package.json +14 -0
  192. data/vendor/coffee-script/vendor/jison/src/bnf.jison +110 -0
  193. data/vendor/coffee-script/vendor/jison/src/bnf.jisonlex +25 -0
  194. data/vendor/coffee-script/vendor/jison/src/bnf.lex.json +24 -0
  195. data/vendor/coffee-script/vendor/jison/src/jisonlex.jison +129 -0
  196. data/vendor/coffee-script/vendor/jison/src/jisonlex.jisonlex +31 -0
  197. data/vendor/coffee-script/vendor/jison/src/jisonlex.lex.json +30 -0
  198. data/vendor/coffee-script/vendor/jison/tests/all-tests.js +8 -0
  199. data/vendor/coffee-script/vendor/jison/tests/grammar/bnf.js +91 -0
  200. data/vendor/coffee-script/vendor/jison/tests/grammar/bnf_parse.js +65 -0
  201. data/vendor/coffee-script/vendor/jison/tests/grammar/grammar-tests.js +10 -0
  202. data/vendor/coffee-script/vendor/jison/tests/grammar/json2jison.js +24 -0
  203. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/ansic.jisonlex +115 -0
  204. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/bnf.jisonlex +25 -0
  205. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/bnf.lex.json +24 -0
  206. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/lex_grammar.jisonlex +31 -0
  207. data/vendor/coffee-script/vendor/jison/tests/grammar/lex/lex_grammar.lex.json +30 -0
  208. data/vendor/coffee-script/vendor/jison/tests/grammar/lex.jison +119 -0
  209. data/vendor/coffee-script/vendor/jison/tests/grammar/lex.js +58 -0
  210. data/vendor/coffee-script/vendor/jison/tests/grammar/lex_parse.js +117 -0
  211. data/vendor/coffee-script/vendor/jison/tests/lexer/lexer-tests.js +6 -0
  212. data/vendor/coffee-script/vendor/jison/tests/lexer/regexplexer.js +417 -0
  213. data/vendor/coffee-script/vendor/jison/tests/parser/actions.js +311 -0
  214. data/vendor/coffee-script/vendor/jison/tests/parser/api.js +236 -0
  215. data/vendor/coffee-script/vendor/jison/tests/parser/generator.js +196 -0
  216. data/vendor/coffee-script/vendor/jison/tests/parser/lalr.js +183 -0
  217. data/vendor/coffee-script/vendor/jison/tests/parser/lr0.js +72 -0
  218. data/vendor/coffee-script/vendor/jison/tests/parser/lr1.js +119 -0
  219. data/vendor/coffee-script/vendor/jison/tests/parser/parser-tests.js +14 -0
  220. data/vendor/coffee-script/vendor/jison/tests/parser/precedence.js +237 -0
  221. data/vendor/coffee-script/vendor/jison/tests/parser/slr.js +52 -0
  222. data/vendor/coffee-script/vendor/jison/tests/parser/tables.js +126 -0
  223. data/vendor/coffee-script/vendor/jison/tests/performance.js +110 -0
  224. data/vendor/coffee-script/vendor/jison/tests/setup.js +3 -0
  225. metadata +324 -0
@@ -0,0 +1,405 @@
1
+ (function(){
2
+ var ACCESSORS, ASSIGNMENT, BEFORE_WHEN, CALLABLE, CODE, COFFEE_KEYWORDS, COMMENT, COMMENT_CLEANER, HEREDOC, HEREDOC_INDENT, IDENTIFIER, JS, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, KEYWORDS, LAST_DENT, LAST_DENTS, MULTILINER, MULTI_DENT, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RESERVED, Rewriter, STRING, STRING_NEWLINES, WHITESPACE, lex;
3
+ if ((typeof process !== "undefined" && process !== null)) {
4
+ Rewriter = require('./rewriter').Rewriter;
5
+ } else {
6
+ this.exports = this;
7
+ Rewriter = this.Rewriter;
8
+ }
9
+ // The lexer reads a stream of CoffeeScript and divvys it up into tagged
10
+ // tokens. A minor bit of the ambiguity in the grammar has been avoided by
11
+ // pushing some extra smarts into the Lexer.
12
+ exports.Lexer = (lex = function lex() { });
13
+ // Constants ============================================================
14
+ // Keywords that CoffeScript shares in common with JS.
15
+ JS_KEYWORDS = ["if", "else", "true", "false", "new", "return", "try", "catch", "finally", "throw", "break", "continue", "for", "in", "while", "delete", "instanceof", "typeof", "switch", "super", "extends"];
16
+ // CoffeeScript-only keywords -- which we're more relaxed about allowing.
17
+ COFFEE_KEYWORDS = ["then", "unless", "yes", "no", "on", "off", "and", "or", "is", "isnt", "not", "of", "by", "where", "when"];
18
+ // The list of keywords passed verbatim to the parser.
19
+ KEYWORDS = JS_KEYWORDS.concat(COFFEE_KEYWORDS);
20
+ // The list of keywords that are reserved by JavaScript, but not used, and aren't
21
+ // used by CoffeeScript. Using these will throw an error at compile time.
22
+ RESERVED = ["case", "default", "do", "function", "var", "void", "with", "class", "const", "let", "debugger", "enum", "export", "import", "native"];
23
+ // JavaScript keywords and reserved words together, excluding CoffeeScript ones.
24
+ JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED);
25
+ // Token matching regexes. (keep the IDENTIFIER regex in sync with AssignNode.)
26
+ IDENTIFIER = /^([a-zA-Z$_](\w|\$)*)/;
27
+ NUMBER = /^(\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i;
28
+ STRING = /^(""|''|"([\s\S]*?)([^\\]|\\\\)"|'([\s\S]*?)([^\\]|\\\\)')/;
29
+ HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/;
30
+ JS = /^(``|`([\s\S]*?)([^\\]|\\\\)`)/;
31
+ OPERATOR = /^([+\*&|\/\-%=<>:!?]+)/;
32
+ WHITESPACE = /^([ \t]+)/;
33
+ COMMENT = /^(((\n?[ \t]*)?#[^\n]*)+)/;
34
+ CODE = /^((-|=)>)/;
35
+ REGEX = /^(\/(.*?)([^\\]|\\\\)\/[imgy]{0,4})/;
36
+ MULTI_DENT = /^((\n([ \t]*))+)(\.)?/;
37
+ LAST_DENTS = /\n([ \t]*)/g;
38
+ LAST_DENT = /\n([ \t]*)/;
39
+ ASSIGNMENT = /^(:|=)$/;
40
+ // Token cleaning regexes.
41
+ JS_CLEANER = /(^`|`$)/g;
42
+ MULTILINER = /\n/g;
43
+ STRING_NEWLINES = /\n[ \t]*/g;
44
+ COMMENT_CLEANER = /(^[ \t]*#|\n[ \t]*$)/mg;
45
+ NO_NEWLINE = /^([+\*&|\/\-%=<>:!.\\][<>=&|]*|and|or|is|isnt|not|delete|typeof|instanceof)$/;
46
+ HEREDOC_INDENT = /^[ \t]+/mg;
47
+ // Tokens which a regular expression will never immediately follow, but which
48
+ // a division operator might.
49
+ // See: http://www.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions
50
+ NOT_REGEX = ['IDENTIFIER', 'NUMBER', 'REGEX', 'STRING', ')', '++', '--', ']', '}', 'FALSE', 'NULL', 'TRUE'];
51
+ // Tokens which could legitimately be invoked or indexed.
52
+ CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@'];
53
+ // Tokens that indicate an access -- keywords immediately following will be
54
+ // treated as identifiers.
55
+ ACCESSORS = ['PROPERTY_ACCESS', 'PROTOTYPE_ACCESS', 'SOAK_ACCESS', '@'];
56
+ // Tokens that, when immediately preceding a 'WHEN', indicate that its leading.
57
+ BEFORE_WHEN = ['INDENT', 'OUTDENT', 'TERMINATOR'];
58
+ // Scan by attempting to match tokens one character at a time. Slow and steady.
59
+ lex.prototype.tokenize = function tokenize(code) {
60
+ this.code = code;
61
+ // Cleanup code by remove extra line breaks, TODO: chomp
62
+ this.i = 0;
63
+ // Current character position we're parsing
64
+ this.line = 1;
65
+ // The current line.
66
+ this.indent = 0;
67
+ // The current indent level.
68
+ this.indents = [];
69
+ // The stack of all indent levels we are currently within.
70
+ this.tokens = [];
71
+ // Collection of all parsed tokens in the form [:TOKEN_TYPE, value]
72
+ while (this.i < this.code.length) {
73
+ this.chunk = this.code.slice(this.i);
74
+ this.extract_next_token();
75
+ }
76
+ this.close_indentation();
77
+ return (new Rewriter()).rewrite(this.tokens);
78
+ };
79
+ // At every position, run through this list of attempted matches,
80
+ // short-circuiting if any of them succeed.
81
+ lex.prototype.extract_next_token = function extract_next_token() {
82
+ if (this.identifier_token()) {
83
+ return null;
84
+ }
85
+ if (this.number_token()) {
86
+ return null;
87
+ }
88
+ if (this.heredoc_token()) {
89
+ return null;
90
+ }
91
+ if (this.string_token()) {
92
+ return null;
93
+ }
94
+ if (this.js_token()) {
95
+ return null;
96
+ }
97
+ if (this.regex_token()) {
98
+ return null;
99
+ }
100
+ if (this.indent_token()) {
101
+ return null;
102
+ }
103
+ if (this.comment_token()) {
104
+ return null;
105
+ }
106
+ if (this.whitespace_token()) {
107
+ return null;
108
+ }
109
+ return this.literal_token();
110
+ };
111
+ // Tokenizers ==========================================================
112
+ // Matches identifying literals: variables, keywords, method names, etc.
113
+ lex.prototype.identifier_token = function identifier_token() {
114
+ var id, tag;
115
+ if (!((id = this.match(IDENTIFIER, 1)))) {
116
+ return false;
117
+ }
118
+ if (this.value() === '::') {
119
+ this.tag(1, 'PROTOTYPE_ACCESS');
120
+ }
121
+ if (this.value() === '.' && !(this.value(2) === '.')) {
122
+ if (this.tag(2) === '?') {
123
+ this.tag(1, 'SOAK_ACCESS');
124
+ this.tokens.splice(-2, 1);
125
+ } else {
126
+ this.tag(1, 'PROPERTY_ACCESS');
127
+ }
128
+ }
129
+ tag = 'IDENTIFIER';
130
+ if (KEYWORDS.indexOf(id) >= 0 && !((ACCESSORS.indexOf(this.tag()) >= 0) && !this.prev().spaced)) {
131
+ tag = id.toUpperCase();
132
+ }
133
+ if (RESERVED.indexOf(id) >= 0) {
134
+ throw new Error('SyntaxError: Reserved word "' + id + '" on line ' + this.line);
135
+ }
136
+ if (tag === 'WHEN' && BEFORE_WHEN.indexOf(this.tag()) >= 0) {
137
+ tag = 'LEADING_WHEN';
138
+ }
139
+ this.token(tag, id);
140
+ this.i += id.length;
141
+ return true;
142
+ };
143
+ // Matches numbers, including decimals, hex, and exponential notation.
144
+ lex.prototype.number_token = function number_token() {
145
+ var number;
146
+ if (!((number = this.match(NUMBER, 1)))) {
147
+ return false;
148
+ }
149
+ this.token('NUMBER', number);
150
+ this.i += number.length;
151
+ return true;
152
+ };
153
+ // Matches strings, including multi-line strings.
154
+ lex.prototype.string_token = function string_token() {
155
+ var escaped, string;
156
+ if (!((string = this.match(STRING, 1)))) {
157
+ return false;
158
+ }
159
+ escaped = string.replace(STRING_NEWLINES, " \\\n");
160
+ this.token('STRING', escaped);
161
+ this.line += this.count(string, "\n");
162
+ this.i += string.length;
163
+ return true;
164
+ };
165
+ // Matches heredocs, adjusting indentation to the correct level.
166
+ lex.prototype.heredoc_token = function heredoc_token() {
167
+ var doc, indent, match;
168
+ if (!((match = this.chunk.match(HEREDOC)))) {
169
+ return false;
170
+ }
171
+ doc = match[2] || match[4];
172
+ indent = (doc.match(HEREDOC_INDENT) || ['']).sort()[0];
173
+ doc = doc.replace(new RegExp("^" + indent, 'gm'), '').replace(MULTILINER, "\\n").replace('"', '\\"');
174
+ this.token('STRING', '"' + doc + '"');
175
+ this.line += this.count(match[1], "\n");
176
+ this.i += match[1].length;
177
+ return true;
178
+ };
179
+ // Matches interpolated JavaScript.
180
+ lex.prototype.js_token = function js_token() {
181
+ var script;
182
+ if (!((script = this.match(JS, 1)))) {
183
+ return false;
184
+ }
185
+ this.token('JS', script.replace(JS_CLEANER, ''));
186
+ this.i += script.length;
187
+ return true;
188
+ };
189
+ // Matches regular expression literals.
190
+ lex.prototype.regex_token = function regex_token() {
191
+ var regex;
192
+ if (!((regex = this.match(REGEX, 1)))) {
193
+ return false;
194
+ }
195
+ if (NOT_REGEX.indexOf(this.tag()) >= 0) {
196
+ return false;
197
+ }
198
+ this.token('REGEX', regex);
199
+ this.i += regex.length;
200
+ return true;
201
+ };
202
+ // Matches and conumes comments.
203
+ lex.prototype.comment_token = function comment_token() {
204
+ var comment;
205
+ if (!((comment = this.match(COMMENT, 1)))) {
206
+ return false;
207
+ }
208
+ this.line += (comment.match(MULTILINER) || []).length;
209
+ this.token('COMMENT', comment.replace(COMMENT_CLEANER, '').split(MULTILINER));
210
+ this.token('TERMINATOR', "\n");
211
+ this.i += comment.length;
212
+ return true;
213
+ };
214
+ // Record tokens for indentation differing from the previous line.
215
+ lex.prototype.indent_token = function indent_token() {
216
+ var diff, indent, next_character, no_newlines, prev, size;
217
+ if (!((indent = this.match(MULTI_DENT, 1)))) {
218
+ return false;
219
+ }
220
+ this.line += indent.match(MULTILINER).length;
221
+ this.i += indent.length;
222
+ next_character = this.chunk.match(MULTI_DENT)[4];
223
+ prev = this.prev(2);
224
+ no_newlines = next_character === '.' || (this.value() && this.value().match(NO_NEWLINE) && prev && (prev[0] !== '.') && !this.value().match(CODE));
225
+ if (no_newlines) {
226
+ return this.suppress_newlines(indent);
227
+ }
228
+ size = indent.match(LAST_DENTS).reverse()[0].match(LAST_DENT)[1].length;
229
+ if (size === this.indent) {
230
+ return this.newline_token(indent);
231
+ }
232
+ if (size > this.indent) {
233
+ diff = size - this.indent;
234
+ this.token('INDENT', diff);
235
+ this.indents.push(diff);
236
+ } else {
237
+ this.outdent_token(this.indent - size);
238
+ }
239
+ this.indent = size;
240
+ return true;
241
+ };
242
+ // Record an oudent token or tokens, if we're moving back inwards past
243
+ // multiple recorded indents.
244
+ lex.prototype.outdent_token = function outdent_token(move_out) {
245
+ var last_indent;
246
+ while (move_out > 0 && this.indents.length) {
247
+ last_indent = this.indents.pop();
248
+ this.token('OUTDENT', last_indent);
249
+ move_out -= last_indent;
250
+ }
251
+ if (!(this.tag() === 'TERMINATOR')) {
252
+ this.token('TERMINATOR', "\n");
253
+ }
254
+ return true;
255
+ };
256
+ // Matches and consumes non-meaningful whitespace.
257
+ lex.prototype.whitespace_token = function whitespace_token() {
258
+ var prev, space;
259
+ if (!((space = this.match(WHITESPACE, 1)))) {
260
+ return false;
261
+ }
262
+ prev = this.prev();
263
+ if (prev) {
264
+ prev.spaced = true;
265
+ }
266
+ this.i += space.length;
267
+ return true;
268
+ };
269
+ // Multiple newlines get merged together.
270
+ // Use a trailing \ to escape newlines.
271
+ lex.prototype.newline_token = function newline_token(newlines) {
272
+ if (!(this.tag() === 'TERMINATOR')) {
273
+ this.token('TERMINATOR', "\n");
274
+ }
275
+ return true;
276
+ };
277
+ // Tokens to explicitly escape newlines are removed once their job is done.
278
+ lex.prototype.suppress_newlines = function suppress_newlines(newlines) {
279
+ if (this.value() === "\\") {
280
+ this.tokens.pop();
281
+ }
282
+ return true;
283
+ };
284
+ // We treat all other single characters as a token. Eg.: ( ) , . !
285
+ // Multi-character operators are also literal tokens, so that Racc can assign
286
+ // the proper order of operations.
287
+ lex.prototype.literal_token = function literal_token() {
288
+ var match, not_spaced, tag, value;
289
+ match = this.chunk.match(OPERATOR);
290
+ value = match && match[1];
291
+ if (value && value.match(CODE)) {
292
+ this.tag_parameters();
293
+ }
294
+ value = value || this.chunk.substr(0, 1);
295
+ not_spaced = !this.prev() || !this.prev().spaced;
296
+ tag = value;
297
+ if (value.match(ASSIGNMENT)) {
298
+ tag = 'ASSIGN';
299
+ if (JS_FORBIDDEN.indexOf(this.value()) >= 0) {
300
+ throw new Error('SyntaxError: Reserved word "' + this.value() + '" on line ' + this.line + ' can\'t be assigned');
301
+ }
302
+ } else if (value === ';') {
303
+ tag = 'TERMINATOR';
304
+ } else if (value === '[' && this.tag() === '?' && not_spaced) {
305
+ tag = 'SOAKED_INDEX_START';
306
+ this.soaked_index = true;
307
+ this.tokens.pop();
308
+ } else if (value === ']' && this.soaked_index) {
309
+ tag = 'SOAKED_INDEX_END';
310
+ this.soaked_index = false;
311
+ } else if (CALLABLE.indexOf(this.tag()) >= 0 && not_spaced) {
312
+ if (value === '(') {
313
+ tag = 'CALL_START';
314
+ }
315
+ if (value === '[') {
316
+ tag = 'INDEX_START';
317
+ }
318
+ }
319
+ this.token(tag, value);
320
+ this.i += value.length;
321
+ return true;
322
+ };
323
+ // Helpers =============================================================
324
+ // Add a token to the results, taking note of the line number.
325
+ lex.prototype.token = function token(tag, value) {
326
+ return this.tokens.push([tag, value, this.line]);
327
+ };
328
+ // Look at a tag in the current token stream.
329
+ lex.prototype.tag = function tag(index, tag) {
330
+ var tok;
331
+ if (!((tok = this.prev(index)))) {
332
+ return null;
333
+ }
334
+ if ((typeof tag !== "undefined" && tag !== null)) {
335
+ return (tok[0] = tag);
336
+ }
337
+ return tok[0];
338
+ };
339
+ // Look at a value in the current token stream.
340
+ lex.prototype.value = function value(index, val) {
341
+ var tok;
342
+ if (!((tok = this.prev(index)))) {
343
+ return null;
344
+ }
345
+ if ((typeof val !== "undefined" && val !== null)) {
346
+ return (tok[1] = val);
347
+ }
348
+ return tok[1];
349
+ };
350
+ // Look at a previous token.
351
+ lex.prototype.prev = function prev(index) {
352
+ return this.tokens[this.tokens.length - (index || 1)];
353
+ };
354
+ // Count the occurences of a character in a string.
355
+ lex.prototype.count = function count(string, letter) {
356
+ var num, pos;
357
+ num = 0;
358
+ pos = string.indexOf(letter);
359
+ while (pos !== -1) {
360
+ num += 1;
361
+ pos = string.indexOf(letter, pos + 1);
362
+ }
363
+ return num;
364
+ };
365
+ // Attempt to match a string against the current chunk, returning the indexed
366
+ // match.
367
+ lex.prototype.match = function match(regex, index) {
368
+ var m;
369
+ if (!((m = this.chunk.match(regex)))) {
370
+ return false;
371
+ }
372
+ return m ? m[index] : false;
373
+ };
374
+ // A source of ambiguity in our grammar was parameter lists in function
375
+ // definitions (as opposed to argument lists in function calls). Tag
376
+ // parameter identifiers in order to avoid this. Also, parameter lists can
377
+ // make use of splats.
378
+ lex.prototype.tag_parameters = function tag_parameters() {
379
+ var _a, i, tok;
380
+ if (this.tag() !== ')') {
381
+ return null;
382
+ }
383
+ i = 0;
384
+ while (true) {
385
+ i += 1;
386
+ tok = this.prev(i);
387
+ if (!tok) {
388
+ return null;
389
+ }
390
+ if ((_a = tok[0]) === 'IDENTIFIER') {
391
+ tok[0] = 'PARAM';
392
+ } else if (_a === ')') {
393
+ tok[0] = 'PARAM_END';
394
+ } else if (_a === '(') {
395
+ return (tok[0] = 'PARAM_START');
396
+ }
397
+ }
398
+ return true;
399
+ };
400
+ // Close up all remaining open blocks. IF the first token is an indent,
401
+ // axe it.
402
+ lex.prototype.close_indentation = function close_indentation() {
403
+ return this.outdent_token(this.indent);
404
+ };
405
+ })();
@@ -0,0 +1,44 @@
1
+ (function(){
2
+ var coffee, factories, file, loader, os, puts;
3
+ // The Narwhal-compatibility wrapper for CoffeeScript.
4
+ // Require external dependencies.
5
+ os = require('os');
6
+ file = require('file');
7
+ coffee = require('./coffee-script');
8
+ // Alias print to "puts", for Node.js compatibility:
9
+ puts = print;
10
+ // Compile a string of CoffeeScript into JavaScript.
11
+ exports.compile = function compile(source) {
12
+ return coffee.compile(source);
13
+ };
14
+ // Compile a given CoffeeScript file into JavaScript.
15
+ exports.compileFile = function compileFile(path) {
16
+ return coffee.compile(file.read(path));
17
+ };
18
+ // Make a factory for the CoffeeScript environment.
19
+ exports.makeNarwhalFactory = function makeNarwhalFactory(path) {
20
+ var code, factoryText;
21
+ code = exports.compileFile(path);
22
+ factoryText = "function(require,exports,module,system,print){" + code + "/**/\n}";
23
+ if (system.engine === "rhino") {
24
+ return Packages.org.mozilla.javascript.Context.getCurrentContext().compileFunction(global, factoryText, path, 0, null);
25
+ } else {
26
+ // eval requires parentheses, but parentheses break compileFunction.
27
+ return eval("(" + factoryText + ")");
28
+ }
29
+ };
30
+ // The Narwhal loader for '.coffee' files.
31
+ factories = {};
32
+ loader = {};
33
+ // Reload the coffee-script environment from source.
34
+ loader.reload = function reload(topId, path) {
35
+ return factories[topId] = function() {
36
+ return exports.makeNarwhalFactory(path);
37
+ };
38
+ };
39
+ // Ensure that the coffee-script environment is loaded.
40
+ loader.load = function load(topId, path) {
41
+ return factories[topId] = factories[topId] || this.reload(topId, path);
42
+ };
43
+ require.loader.loaders.unshift([".coffee", loader]);
44
+ })();