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,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})