haml-more 0.4.0.a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,130 @@
1
+ fs: require 'fs'
2
+ path: require 'path'
3
+ coffee: require 'coffee-script'
4
+ optparse: require('optparse')
5
+
6
+ BANNER: '''
7
+ coffee compiles CoffeeScript source files into JavaScript.
8
+
9
+ Usage:
10
+ coffee path/to/script.coffee
11
+ '''
12
+
13
+ SWITCHES: [
14
+ ['-i', '--interactive', 'run an interactive CoffeeScript REPL']
15
+ ['-r', '--run', 'compile and run a CoffeeScript']
16
+ ['-o', '--output [DIR]', 'set the directory for compiled JavaScript']
17
+ ['-w', '--watch', 'watch scripts for changes, and recompile']
18
+ ['-p', '--print', 'print the compiled JavaScript to stdout']
19
+ ['-l', '--lint', 'pipe the compiled JavaScript through JSLint']
20
+ ['-e', '--eval', 'compile a string from the command line']
21
+ ['-t', '--tokens', 'print the tokens that the lexer produces']
22
+ ['-tr','--tree', 'print the parse tree that Jison produces']
23
+ ['-n', '--no-wrap', 'compile without the top-level function wrapper']
24
+ ['-v', '--version', 'display CoffeeScript version']
25
+ ['-h', '--help', 'display this help message']
26
+ ]
27
+
28
+ options: {}
29
+ sources: []
30
+ option_parser: null
31
+
32
+ # The CommandLine handles all of the functionality of the `coffee` utility.
33
+ exports.run: ->
34
+ parse_options()
35
+ return require 'repl' if options.interactive
36
+ return compile_script 'terminal', sources[0] if options.eval
37
+ usage() unless sources.length
38
+ separator: sources.indexOf '--'
39
+ flags: []
40
+ if separator >= 0
41
+ flags: sources[(separator + 1)...sources.length]
42
+ sources: sources[0...separator]
43
+ process.ARGV = flags
44
+ watch_scripts() if options.watch
45
+ compile_scripts()
46
+ this
47
+
48
+ # The "--help" usage message.
49
+ usage: ->
50
+ puts '\n' + option_parser.help() + '\n'
51
+ process.exit 0
52
+
53
+ # The "--version" message.
54
+ version: ->
55
+ puts "CoffeeScript version " + coffee.VERSION
56
+ process.exit 0
57
+
58
+ # Compiles the source CoffeeScript, returning the desired JavaScript, tokens,
59
+ # or JSLint results.
60
+ compile_scripts: ->
61
+ compile: (source) ->
62
+ fs.readFile source, (err, code) -> compile_script(source, code)
63
+ compile(source) for source in sources
64
+
65
+
66
+ # Compile a single source script, containing the given code, according to the
67
+ # requested options. Both compile_scripts and watch_scripts share this method.
68
+ compile_script: (source, code) ->
69
+ opts: options
70
+ o: if opts.no_wrap then {no_wrap: true} else {}
71
+ try
72
+ if opts.tokens then coffee.print_tokens coffee.tokenize code
73
+ else if opts.tree then puts coffee.tree(code).toString()
74
+ else
75
+ js: coffee.compile code, o
76
+ if opts.run then eval js
77
+ else if opts.lint then lint js
78
+ else if opts.print or opts.eval then puts js
79
+ else write_js source, js
80
+ catch err
81
+ if opts.watch then puts err.message else throw err
82
+
83
+ # Watch a list of source CoffeeScript files, recompiling them every time the
84
+ # files are updated.
85
+ watch_scripts: ->
86
+ watch: (source) ->
87
+ process.watchFile source, {persistent: true, interval: 500}, (curr, prev) ->
88
+ return if curr.mtime.getTime() is prev.mtime.getTime()
89
+ fs.readFile source, (err, code) -> compile_script(source, code)
90
+ watch(source) for source in sources
91
+
92
+ # Write out a JavaScript source file with the compiled code.
93
+ write_js: (source, js) ->
94
+ filename: path.basename(source, path.extname(source)) + '.js'
95
+ dir: options.output or path.dirname(source)
96
+ js_path: path.join dir, filename
97
+ fs.writeFile js_path, js
98
+
99
+ # Pipe compiled JS through JSLint (requires a working 'jsl' command).
100
+ lint: (js) ->
101
+ jsl: process.createChildProcess('jsl', ['-nologo', '-stdin'])
102
+ jsl.addListener 'output', (result) ->
103
+ puts result.replace(/\n/g, '') if result
104
+ jsl.addListener 'error', (result) ->
105
+ puts result if result
106
+ jsl.write js
107
+ jsl.close()
108
+
109
+ # Use OptionParser for all the options.
110
+ parse_options: ->
111
+ opts: options: {}
112
+ oparser: option_parser: new optparse.OptionParser SWITCHES
113
+ oparser.banner: BANNER
114
+
115
+ oparser.add 'interactive', -> opts.interactive: true
116
+ oparser.add 'run', -> opts.run: true
117
+ oparser.add 'output', (dir) -> opts.output: dir
118
+ oparser.add 'watch', -> opts.watch: true
119
+ oparser.add 'print', -> opts.print: true
120
+ oparser.add 'lint', -> opts.lint: true
121
+ oparser.add 'eval', -> opts.eval: true
122
+ oparser.add 'tokens', -> opts.tokens: true
123
+ oparser.add 'tree', -> opts.tree: true
124
+ oparser.add 'no-wrap', -> opts.no_wrap: true
125
+ oparser.add 'help', => usage()
126
+ oparser.add 'version', => version()
127
+
128
+ paths: oparser.parse(process.ARGV)
129
+ sources: paths[2...paths.length]
130
+
@@ -0,0 +1,456 @@
1
+ Parser: require('jison').Parser
2
+
3
+ # DSL ===================================================================
4
+
5
+ # Detect functions: [
6
+ unwrap: /function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/
7
+
8
+ # Quickie DSL for Jison access.
9
+ o: (pattern_string, func, options) ->
10
+ if func
11
+ func: if match: (func + "").match(unwrap) then match[1] else '(' + func + '())'
12
+ [pattern_string, '$$ = ' + func + ';', options]
13
+ else
14
+ [pattern_string, '$$ = $1;', options]
15
+
16
+ # Precedence ===========================================================
17
+
18
+ operators: [
19
+ ["left", '?']
20
+ ["nonassoc", 'UMINUS', 'UPLUS', 'NOT', '!', '!!', '~', '++', '--']
21
+ ["left", '*', '/', '%']
22
+ ["left", '+', '-']
23
+ ["left", '<<', '>>', '>>>']
24
+ ["left", '&', '|', '^']
25
+ ["left", '<=', '<', '>', '>=']
26
+ ["right", 'DELETE', 'INSTANCEOF', 'TYPEOF']
27
+ ["right", '==', '!=', 'IS', 'ISNT']
28
+ ["left", '&&', '||', 'AND', 'OR']
29
+ ["right", '-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=']
30
+ ["left", '.']
31
+ ["right", 'INDENT']
32
+ ["left", 'OUTDENT']
33
+ ["right", 'WHEN', 'LEADING_WHEN', 'IN', 'OF', 'BY', 'THROW']
34
+ ["right", 'FOR', 'NEW', 'SUPER']
35
+ ["left", 'EXTENDS']
36
+ ["right", 'ASSIGN', 'RETURN']
37
+ ["right", '->', '=>', 'UNLESS', 'IF', 'ELSE', 'WHILE']
38
+ ]
39
+
40
+ # Grammar ==============================================================
41
+
42
+ grammar: {
43
+
44
+ # All parsing will end in this rule, being the trunk of the AST.
45
+ Root: [
46
+ o "", -> new Expressions()
47
+ o "TERMINATOR", -> new Expressions()
48
+ o "Expressions", -> $1
49
+ o "Block TERMINATOR", -> $1
50
+ ]
51
+
52
+ # Any list of expressions or method body, seperated by line breaks or semis.
53
+ Expressions: [
54
+ o "Expression", -> Expressions.wrap([$1])
55
+ o "Expressions TERMINATOR Expression", -> $1.push($3)
56
+ o "Expressions TERMINATOR", -> $1
57
+ ]
58
+
59
+ # All types of expressions in our language. The basic unit of CoffeeScript
60
+ # is the expression.
61
+ Expression: [
62
+ o "Value"
63
+ o "Call"
64
+ o "Code"
65
+ o "Operation"
66
+ o "Assign"
67
+ o "If"
68
+ o "Try"
69
+ o "Throw"
70
+ o "Return"
71
+ o "While"
72
+ o "For"
73
+ o "Switch"
74
+ o "Extends"
75
+ o "Splat"
76
+ o "Existence"
77
+ o "Comment"
78
+ ]
79
+
80
+ # A block of expressions. Note that the Rewriter will convert some postfix
81
+ # forms into blocks for us, by altering the token stream.
82
+ Block: [
83
+ o "INDENT Expressions OUTDENT", -> $2
84
+ o "INDENT OUTDENT", -> new Expressions()
85
+ ]
86
+
87
+ Identifier: [
88
+ o "IDENTIFIER", -> new LiteralNode(yytext)
89
+ ]
90
+
91
+ AlphaNumeric: [
92
+ o "NUMBER", -> new LiteralNode(yytext)
93
+ o "STRING", -> new LiteralNode(yytext)
94
+ ]
95
+
96
+ # All hard-coded values. These can be printed straight to JavaScript.
97
+ Literal: [
98
+ o "AlphaNumeric", -> $1
99
+ o "JS", -> new LiteralNode(yytext)
100
+ o "REGEX", -> new LiteralNode(yytext)
101
+ o "BREAK", -> new LiteralNode(yytext)
102
+ o "CONTINUE", -> new LiteralNode(yytext)
103
+ o "TRUE", -> new LiteralNode(true)
104
+ o "FALSE", -> new LiteralNode(false)
105
+ o "YES", -> new LiteralNode(true)
106
+ o "NO", -> new LiteralNode(false)
107
+ o "ON", -> new LiteralNode(true)
108
+ o "OFF", -> new LiteralNode(false)
109
+ ]
110
+
111
+ # Assignment to a variable (or index).
112
+ Assign: [
113
+ o "Value ASSIGN Expression", -> new AssignNode($1, $3)
114
+ ]
115
+
116
+ # Assignment within an object literal (can be quoted).
117
+ AssignObj: [
118
+ o "Identifier ASSIGN Expression", -> new AssignNode(new ValueNode($1), $3, 'object')
119
+ o "AlphaNumeric ASSIGN Expression", -> new AssignNode(new ValueNode($1), $3, 'object')
120
+ o "Comment"
121
+ ]
122
+
123
+ # A return statement.
124
+ Return: [
125
+ o "RETURN Expression", -> new ReturnNode($2)
126
+ o "RETURN", -> new ReturnNode(new ValueNode(new LiteralNode('null')))
127
+ ]
128
+
129
+ # A comment.
130
+ Comment: [
131
+ o "COMMENT", -> new CommentNode(yytext)
132
+ ]
133
+
134
+ # Arithmetic and logical operators
135
+ # For Ruby's Operator precedence, see: [
136
+ # https://www.cs.auckland.ac.nz/references/ruby/ProgrammingRuby/language.html
137
+ Operation: [
138
+ o "! Expression", -> new OpNode('!', $2)
139
+ o "!! Expression", -> new OpNode('!!', $2)
140
+ o("- Expression", (-> new OpNode('-', $2)), {prec: 'UMINUS'})
141
+ o("+ Expression", (-> new OpNode('+', $2)), {prec: 'UPLUS'})
142
+ o "NOT Expression", -> new OpNode('not', $2)
143
+ o "~ Expression", -> new OpNode('~', $2)
144
+ o "-- Expression", -> new OpNode('--', $2)
145
+ o "++ Expression", -> new OpNode('++', $2)
146
+ o "DELETE Expression", -> new OpNode('delete', $2)
147
+ o "TYPEOF Expression", -> new OpNode('typeof', $2)
148
+ o "Expression --", -> new OpNode('--', $1, null, true)
149
+ o "Expression ++", -> new OpNode('++', $1, null, true)
150
+
151
+ o "Expression * Expression", -> new OpNode('*', $1, $3)
152
+ o "Expression / Expression", -> new OpNode('/', $1, $3)
153
+ o "Expression % Expression", -> new OpNode('%', $1, $3)
154
+
155
+ o "Expression + Expression", -> new OpNode('+', $1, $3)
156
+ o "Expression - Expression", -> new OpNode('-', $1, $3)
157
+
158
+ o "Expression << Expression", -> new OpNode('<<', $1, $3)
159
+ o "Expression >> Expression", -> new OpNode('>>', $1, $3)
160
+ o "Expression >>> Expression", -> new OpNode('>>>', $1, $3)
161
+ o "Expression & Expression", -> new OpNode('&', $1, $3)
162
+ o "Expression | Expression", -> new OpNode('|', $1, $3)
163
+ o "Expression ^ Expression", -> new OpNode('^', $1, $3)
164
+
165
+ o "Expression <= Expression", -> new OpNode('<=', $1, $3)
166
+ o "Expression < Expression", -> new OpNode('<', $1, $3)
167
+ o "Expression > Expression", -> new OpNode('>', $1, $3)
168
+ o "Expression >= Expression", -> new OpNode('>=', $1, $3)
169
+
170
+ o "Expression == Expression", -> new OpNode('==', $1, $3)
171
+ o "Expression != Expression", -> new OpNode('!=', $1, $3)
172
+ o "Expression IS Expression", -> new OpNode('is', $1, $3)
173
+ o "Expression ISNT Expression", -> new OpNode('isnt', $1, $3)
174
+
175
+ o "Expression && Expression", -> new OpNode('&&', $1, $3)
176
+ o "Expression || Expression", -> new OpNode('||', $1, $3)
177
+ o "Expression AND Expression", -> new OpNode('and', $1, $3)
178
+ o "Expression OR Expression", -> new OpNode('or', $1, $3)
179
+ o "Expression ? Expression", -> new OpNode('?', $1, $3)
180
+
181
+ o "Expression -= Expression", -> new OpNode('-=', $1, $3)
182
+ o "Expression += Expression", -> new OpNode('+=', $1, $3)
183
+ o "Expression /= Expression", -> new OpNode('/=', $1, $3)
184
+ o "Expression *= Expression", -> new OpNode('*=', $1, $3)
185
+ o "Expression %= Expression", -> new OpNode('%=', $1, $3)
186
+ o "Expression ||= Expression", -> new OpNode('||=', $1, $3)
187
+ o "Expression &&= Expression", -> new OpNode('&&=', $1, $3)
188
+ o "Expression ?= Expression", -> new OpNode('?=', $1, $3)
189
+
190
+ o "Expression INSTANCEOF Expression", -> new OpNode('instanceof', $1, $3)
191
+ o "Expression IN Expression", -> new OpNode('in', $1, $3)
192
+ ]
193
+
194
+ # The existence operator.
195
+ Existence: [
196
+ o "Expression ?", -> new ExistenceNode($1)
197
+ ]
198
+
199
+ # Function definition.
200
+ Code: [
201
+ o "PARAM_START ParamList PARAM_END FuncGlyph Block", -> new CodeNode($2, $5, $4)
202
+ o "FuncGlyph Block", -> new CodeNode([], $2, $1)
203
+ ]
204
+
205
+ # The symbols to signify functions, and bound functions.
206
+ FuncGlyph: [
207
+ o "->", -> 'func'
208
+ o "=>", -> 'boundfunc'
209
+ ]
210
+
211
+ # The parameters to a function definition.
212
+ ParamList: [
213
+ o "", -> []
214
+ o "Param", -> [$1]
215
+ o "ParamList , Param", -> $1.concat [$3]
216
+ ]
217
+
218
+ # A Parameter (or ParamSplat) in a function definition.
219
+ Param: [
220
+ o "PARAM", -> new LiteralNode(yytext)
221
+ o "Param . . .", -> new SplatNode($1)
222
+ ]
223
+
224
+ # A regular splat.
225
+ Splat: [
226
+ o "Expression . . .", -> new SplatNode($1)
227
+ ]
228
+
229
+ # Expressions that can be treated as values.
230
+ Value: [
231
+ o "Identifier", -> new ValueNode($1)
232
+ o "Literal", -> new ValueNode($1)
233
+ o "Array", -> new ValueNode($1)
234
+ o "Object", -> new ValueNode($1)
235
+ o "Parenthetical", -> new ValueNode($1)
236
+ o "Range", -> new ValueNode($1)
237
+ o "This", -> $1
238
+ o "Value Accessor", -> $1.push($2)
239
+ o "Invocation Accessor", -> new ValueNode($1, [$2])
240
+ ]
241
+
242
+ # Accessing into an object or array, through dot or index notation.
243
+ Accessor: [
244
+ o "PROPERTY_ACCESS Identifier", -> new AccessorNode($2)
245
+ o "PROTOTYPE_ACCESS Identifier", -> new AccessorNode($2, 'prototype')
246
+ o "SOAK_ACCESS Identifier", -> new AccessorNode($2, 'soak')
247
+ o "Index"
248
+ o "Slice", -> new SliceNode($1)
249
+ ]
250
+
251
+ # Indexing into an object or array.
252
+ Index: [
253
+ o "INDEX_START Expression INDEX_END", -> new IndexNode($2)
254
+ o "SOAKED_INDEX_START Expression SOAKED_INDEX_END", -> new IndexNode($2, 'soak')
255
+ ]
256
+
257
+ # An object literal.
258
+ Object: [
259
+ o "{ AssignList }", -> new ObjectNode($2)
260
+ ]
261
+
262
+ # Assignment within an object literal (comma or newline separated).
263
+ AssignList: [
264
+ o "", -> []
265
+ o "AssignObj", -> [$1]
266
+ o "AssignList , AssignObj", -> $1.concat [$3]
267
+ o "AssignList TERMINATOR AssignObj", -> $1.concat [$3]
268
+ o "AssignList , TERMINATOR AssignObj", -> $1.concat [$4]
269
+ o "INDENT AssignList OUTDENT", -> $2
270
+ ]
271
+
272
+ # All flavors of function call (instantiation, super, and regular).
273
+ Call: [
274
+ o "Invocation", -> $1
275
+ o "NEW Invocation", -> $2.new_instance()
276
+ o "Super", -> $1
277
+ ]
278
+
279
+ # Extending an object's prototype.
280
+ Extends: [
281
+ o "Value EXTENDS Value", -> new ExtendsNode($1, $3)
282
+ ]
283
+
284
+ # A generic function invocation.
285
+ Invocation: [
286
+ o "Value Arguments", -> new CallNode($1, $2)
287
+ o "Invocation Arguments", -> new CallNode($1, $2)
288
+ ]
289
+
290
+ # The list of arguments to a function invocation.
291
+ Arguments: [
292
+ o "CALL_START ArgList CALL_END", -> $2
293
+ ]
294
+
295
+ # Calling super.
296
+ Super: [
297
+ o "SUPER CALL_START ArgList CALL_END", -> new CallNode('super', $3)
298
+ ]
299
+
300
+ # This references, either naked or to a property.
301
+ This: [
302
+ o "@", -> new ValueNode(new LiteralNode('this'))
303
+ o "@ Identifier", -> new ValueNode(new LiteralNode('this'), [new AccessorNode($2)])
304
+ ]
305
+
306
+ # The range literal.
307
+ Range: [
308
+ o "[ Expression . . Expression ]", -> new RangeNode($2, $5)
309
+ o "[ Expression . . . Expression ]", -> new RangeNode($2, $6, true)
310
+ ]
311
+
312
+ # The slice literal.
313
+ Slice: [
314
+ o "INDEX_START Expression . . Expression INDEX_END", -> new RangeNode($2, $5)
315
+ o "INDEX_START Expression . . . Expression INDEX_END", -> new RangeNode($2, $6, true)
316
+ ]
317
+
318
+ # The array literal.
319
+ Array: [
320
+ o "[ ArgList ]", -> new ArrayNode($2)
321
+ ]
322
+
323
+ # A list of arguments to a method call, or as the contents of an array.
324
+ ArgList: [
325
+ o "", -> []
326
+ o "Expression", -> [$1]
327
+ o "INDENT Expression", -> [$2]
328
+ o "ArgList , Expression", -> $1.concat [$3]
329
+ o "ArgList TERMINATOR Expression", -> $1.concat [$3]
330
+ o "ArgList , TERMINATOR Expression", -> $1.concat [$4]
331
+ o "ArgList , INDENT Expression", -> $1.concat [$4]
332
+ o "ArgList OUTDENT", -> $1
333
+ ]
334
+
335
+ # Just simple, comma-separated, required arguments (no fancy syntax).
336
+ SimpleArgs: [
337
+ o "Expression", -> $1
338
+ o "SimpleArgs , Expression", ->
339
+ if $1 instanceof Array then $1.concat([$3]) else [$1].concat([$3])
340
+ ]
341
+
342
+ # Try/catch/finally exception handling blocks.
343
+ Try: [
344
+ o "TRY Block Catch", -> new TryNode($2, $3[0], $3[1])
345
+ o "TRY Block FINALLY Block", -> new TryNode($2, null, null, $4)
346
+ o "TRY Block Catch FINALLY Block", -> new TryNode($2, $3[0], $3[1], $5)
347
+ ]
348
+
349
+ # A catch clause.
350
+ Catch: [
351
+ o "CATCH Identifier Block", -> [$2, $3]
352
+ ]
353
+
354
+ # Throw an exception.
355
+ Throw: [
356
+ o "THROW Expression", -> new ThrowNode($2)
357
+ ]
358
+
359
+ # Parenthetical expressions.
360
+ Parenthetical: [
361
+ o "( Expression )", -> new ParentheticalNode($2)
362
+ ]
363
+
364
+ # The condition for a while loop.
365
+ WhileSource: [
366
+ o "WHILE Expression", -> new WhileNode($2)
367
+ o "WHILE Expression WHEN Expression", -> new WhileNode($2, {filter : $4})
368
+ ]
369
+
370
+ # The while loop. (there is no do..while).
371
+ While: [
372
+ o "WhileSource Block", -> $1.add_body $2
373
+ o "Expression WhileSource", -> $2.add_body $1
374
+ ]
375
+
376
+ # Array comprehensions, including guard and current index.
377
+ # Looks a little confusing, check nodes.rb for the arguments to ForNode.
378
+ For: [
379
+ o "Expression FOR ForVariables ForSource", -> new ForNode($1, $4, $3[0], $3[1])
380
+ o "FOR ForVariables ForSource Block", -> new ForNode($4, $3, $2[0], $2[1])
381
+ ]
382
+
383
+ # An array comprehension has variables for the current element and index.
384
+ ForVariables: [
385
+ o "Identifier", -> [$1]
386
+ o "Identifier , Identifier", -> [$1, $3]
387
+ ]
388
+
389
+ # The source of the array comprehension can optionally be filtered.
390
+ ForSource: [
391
+ o "IN Expression", -> {source: $2}
392
+ o "OF Expression", -> {source: $2, object: true}
393
+ o "ForSource WHEN Expression", -> $1.filter: $3; $1
394
+ o "ForSource BY Expression", -> $1.step: $3; $1
395
+ ]
396
+
397
+ # Switch/When blocks.
398
+ Switch: [
399
+ o "SWITCH Expression INDENT Whens OUTDENT", -> $4.rewrite_condition($2)
400
+ o "SWITCH Expression INDENT Whens ELSE Block OUTDENT", -> $4.rewrite_condition($2).add_else($6, true)
401
+ ]
402
+
403
+ # The inner list of whens.
404
+ Whens: [
405
+ o "When", -> $1
406
+ o "Whens When", -> $1.push $2
407
+ ]
408
+
409
+ # An individual when.
410
+ When: [
411
+ o "LEADING_WHEN SimpleArgs Block", -> new IfNode($2, $3, null, {statement: true})
412
+ o "LEADING_WHEN SimpleArgs Block TERMINATOR", -> new IfNode($2, $3, null, {statement: true})
413
+ o "Comment TERMINATOR When", -> $3.comment: $1; $3
414
+ ]
415
+
416
+ # The most basic form of "if".
417
+ IfStart: [
418
+ o "IF Expression Block", -> new IfNode($2, $3)
419
+ o "IfStart ElsIfs", -> $1.add_else($2)
420
+ ]
421
+
422
+ IfBlock: [
423
+ o "IfStart", -> $1
424
+ o "IfStart ELSE Block", -> $1.add_else($3)
425
+ ]
426
+
427
+ # Multiple elsifs can be chained together.
428
+ ElsIfs: [
429
+ o "ELSE IF Expression Block", -> (new IfNode($3, $4)).force_statement()
430
+ o "ElsIfs ElsIf", -> $1.add_else($2)
431
+ ]
432
+
433
+ # The full complement of if blocks, including postfix one-liner ifs and unlesses.
434
+ If: [
435
+ o "IfBlock", -> $1
436
+ o "Expression IF Expression", -> new IfNode($3, Expressions.wrap([$1]), null, {statement: true})
437
+ o "Expression UNLESS Expression", -> new IfNode($3, Expressions.wrap([$1]), null, {statement: true, invert: true})
438
+ ]
439
+
440
+ }
441
+
442
+ # Helpers ==============================================================
443
+
444
+ # Make the Jison parser.
445
+ bnf: {}
446
+ tokens: []
447
+ for name, non_terminal of grammar
448
+ bnf[name]: for option in non_terminal
449
+ for part in option[0].split(" ")
450
+ if !grammar[part]
451
+ tokens.push(part)
452
+ if name == "Root"
453
+ option[1] = "return " + option[1]
454
+ option
455
+ tokens: tokens.join(" ")
456
+ exports.parser: new Parser({tokens: tokens, bnf: bnf, operators: operators.reverse(), startSymbol: 'Root'}, {debug: false})