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