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