diff options
Diffstat (limited to 'imports')
-rw-r--r-- | imports/codemirror/mode/scheme/scheme.js | 402 |
1 files changed, 201 insertions, 201 deletions
diff --git a/imports/codemirror/mode/scheme/scheme.js b/imports/codemirror/mode/scheme/scheme.js index caf78db0..45ae1822 100644 --- a/imports/codemirror/mode/scheme/scheme.js +++ b/imports/codemirror/mode/scheme/scheme.js | |||
@@ -1,202 +1,202 @@ | |||
1 | /** | 1 | /** |
2 | * Author: Koh Zi Han, based on implementation by Koh Zi Chun | 2 | * Author: Koh Zi Han, based on implementation by Koh Zi Chun |
3 | */ | 3 | */ |
4 | CodeMirror.defineMode("scheme", function (config, mode) { | 4 | CodeMirror.defineMode("scheme", function (config, mode) { |
5 | var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", | 5 | var BUILTIN = "builtin", COMMENT = "comment", STRING = "string", |
6 | ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD="keyword"; | 6 | ATOM = "atom", NUMBER = "number", BRACKET = "bracket", KEYWORD="keyword"; |
7 | var INDENT_WORD_SKIP = 2, KEYWORDS_SKIP = 1; | 7 | var INDENT_WORD_SKIP = 2, KEYWORDS_SKIP = 1; |
8 | 8 | ||
9 | function makeKeywords(str) { | 9 | function makeKeywords(str) { |
10 | var obj = {}, words = str.split(" "); | 10 | var obj = {}, words = str.split(" "); |
11 | for (var i = 0; i < words.length; ++i) obj[words[i]] = true; | 11 | for (var i = 0; i < words.length; ++i) obj[words[i]] = true; |
12 | return obj; | 12 | return obj; |
13 | } | 13 | } |
14 | 14 | ||
15 | var keywords = makeKeywords("λ case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string<? string=? string>=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"); | 15 | var keywords = makeKeywords("λ case-lambda call/cc class define-class exit-handler field import inherit init-field interface let*-values let-values let/ec mixin opt-lambda override protect provide public rename require require-for-syntax syntax syntax-case syntax-error unit/sig unless when with-syntax and begin call-with-current-continuation call-with-input-file call-with-output-file case cond define define-syntax delay do dynamic-wind else for-each if lambda let let* let-syntax letrec letrec-syntax map or syntax-rules abs acos angle append apply asin assoc assq assv atan boolean? caar cadr call-with-input-file call-with-output-file call-with-values car cdddar cddddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? char? close-input-port close-output-port complex? cons cos current-input-port current-output-port denominator display eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt #f floor force gcd imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lcm length list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file output-port? pair? peek-char port? positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string<? string=? string>=? string>? string? substring symbol->string symbol? #t tan transcript-off transcript-on truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! with-input-from-file with-output-to-file write write-char zero?"); |
16 | var indentKeys = makeKeywords("define let letrec let* lambda"); | 16 | var indentKeys = makeKeywords("define let letrec let* lambda"); |
17 | 17 | ||
18 | 18 | ||
19 | function stateStack(indent, type, prev) { // represents a state stack object | 19 | function stateStack(indent, type, prev) { // represents a state stack object |
20 | this.indent = indent; | 20 | this.indent = indent; |
21 | this.type = type; | 21 | this.type = type; |
22 | this.prev = prev; | 22 | this.prev = prev; |
23 | } | 23 | } |
24 | 24 | ||
25 | function pushStack(state, indent, type) { | 25 | function pushStack(state, indent, type) { |
26 | state.indentStack = new stateStack(indent, type, state.indentStack); | 26 | state.indentStack = new stateStack(indent, type, state.indentStack); |
27 | } | 27 | } |
28 | 28 | ||
29 | function popStack(state) { | 29 | function popStack(state) { |
30 | state.indentStack = state.indentStack.prev; | 30 | state.indentStack = state.indentStack.prev; |
31 | } | 31 | } |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * Scheme numbers are complicated unfortunately. | 34 | * Scheme numbers are complicated unfortunately. |
35 | * Checks if we're looking at a number, which might be possibly a fraction. | 35 | * Checks if we're looking at a number, which might be possibly a fraction. |
36 | * Also checks that it is not part of a longer identifier. Returns true/false accordingly. | 36 | * Also checks that it is not part of a longer identifier. Returns true/false accordingly. |
37 | */ | 37 | */ |
38 | function isNumber(ch, stream){ | 38 | function isNumber(ch, stream){ |
39 | if(/[0-9]/.exec(ch) != null){ | 39 | if(/[0-9]/.exec(ch) != null){ |
40 | stream.eatWhile(/[0-9]/); | 40 | stream.eatWhile(/[0-9]/); |
41 | stream.eat(/\//); | 41 | stream.eat(/\//); |
42 | stream.eatWhile(/[0-9]/); | 42 | stream.eatWhile(/[0-9]/); |
43 | if (stream.eol() || !(/[a-zA-Z\-\_\/]/.exec(stream.peek()))) return true; | 43 | if (stream.eol() || !(/[a-zA-Z\-\_\/]/.exec(stream.peek()))) return true; |
44 | stream.backUp(stream.current().length - 1); // undo all the eating | 44 | stream.backUp(stream.current().length - 1); // undo all the eating |
45 | } | 45 | } |
46 | return false; | 46 | return false; |
47 | } | 47 | } |
48 | 48 | ||
49 | return { | 49 | return { |
50 | startState: function () { | 50 | startState: function () { |
51 | return { | 51 | return { |
52 | indentStack: null, | 52 | indentStack: null, |
53 | indentation: 0, | 53 | indentation: 0, |
54 | mode: false, | 54 | mode: false, |
55 | sExprComment: false | 55 | sExprComment: false |
56 | }; | 56 | }; |
57 | }, | 57 | }, |
58 | 58 | ||
59 | token: function (stream, state) { | 59 | token: function (stream, state) { |
60 | if (state.indentStack == null && stream.sol()) { | 60 | if (state.indentStack == null && stream.sol()) { |
61 | // update indentation, but only if indentStack is empty | 61 | // update indentation, but only if indentStack is empty |
62 | state.indentation = stream.indentation(); | 62 | state.indentation = stream.indentation(); |
63 | } | 63 | } |
64 | 64 | ||
65 | // skip spaces | 65 | // skip spaces |
66 | if (stream.eatSpace()) { | 66 | if (stream.eatSpace()) { |
67 | return null; | 67 | return null; |
68 | } | 68 | } |
69 | var returnType = null; | 69 | var returnType = null; |
70 | 70 | ||
71 | switch(state.mode){ | 71 | switch(state.mode){ |
72 | case "string": // multi-line string parsing mode | 72 | case "string": // multi-line string parsing mode |
73 | var next, escaped = false; | 73 | var next, escaped = false; |
74 | while ((next = stream.next()) != null) { | 74 | while ((next = stream.next()) != null) { |
75 | if (next == "\"" && !escaped) { | 75 | if (next == "\"" && !escaped) { |
76 | 76 | ||
77 | state.mode = false; | 77 | state.mode = false; |
78 | break; | 78 | break; |
79 | } | 79 | } |
80 | escaped = !escaped && next == "\\"; | 80 | escaped = !escaped && next == "\\"; |
81 | } | 81 | } |
82 | returnType = STRING; // continue on in scheme-string mode | 82 | returnType = STRING; // continue on in scheme-string mode |
83 | break; | 83 | break; |
84 | case "comment": // comment parsing mode | 84 | case "comment": // comment parsing mode |
85 | var next, maybeEnd = false; | 85 | var next, maybeEnd = false; |
86 | while ((next = stream.next()) != null) { | 86 | while ((next = stream.next()) != null) { |
87 | if (next == "#" && maybeEnd) { | 87 | if (next == "#" && maybeEnd) { |
88 | 88 | ||
89 | state.mode = false; | 89 | state.mode = false; |
90 | break; | 90 | break; |
91 | } | 91 | } |
92 | maybeEnd = (next == "|"); | 92 | maybeEnd = (next == "|"); |
93 | } | 93 | } |
94 | returnType = COMMENT; | 94 | returnType = COMMENT; |
95 | break; | 95 | break; |
96 | case "s-expr-comment": // s-expr commenting mode | 96 | case "s-expr-comment": // s-expr commenting mode |
97 | state.mode = false; | 97 | state.mode = false; |
98 | if(stream.peek() == "(" || stream.peek() == "["){ | 98 | if(stream.peek() == "(" || stream.peek() == "["){ |
99 | // actually start scheme s-expr commenting mode | 99 | // actually start scheme s-expr commenting mode |
100 | state.sExprComment = 0; | 100 | state.sExprComment = 0; |
101 | }else{ | 101 | }else{ |
102 | // if not we just comment the entire of the next token | 102 | // if not we just comment the entire of the next token |
103 | stream.eatWhile(/[^/s]/); // eat non spaces | 103 | stream.eatWhile(/[^/s]/); // eat non spaces |
104 | returnType = COMMENT; | 104 | returnType = COMMENT; |
105 | break; | 105 | break; |
106 | } | 106 | } |
107 | default: // default parsing mode | 107 | default: // default parsing mode |
108 | var ch = stream.next(); | 108 | var ch = stream.next(); |
109 | 109 | ||
110 | if (ch == "\"") { | 110 | if (ch == "\"") { |
111 | state.mode = "string"; | 111 | state.mode = "string"; |
112 | returnType = STRING; | 112 | returnType = STRING; |
113 | 113 | ||
114 | } else if (ch == "'") { | 114 | } else if (ch == "'") { |
115 | returnType = ATOM; | 115 | returnType = ATOM; |
116 | } else if (ch == '#') { | 116 | } else if (ch == '#') { |
117 | if (stream.eat("|")) { // Multi-line comment | 117 | if (stream.eat("|")) { // Multi-line comment |
118 | state.mode = "comment"; // toggle to comment mode | 118 | state.mode = "comment"; // toggle to comment mode |
119 | returnType = COMMENT; | 119 | returnType = COMMENT; |
120 | } else if (stream.eat(/[tf]/)) { // #t/#f (atom) | 120 | } else if (stream.eat(/[tf]/)) { // #t/#f (atom) |
121 | returnType = ATOM; | 121 | returnType = ATOM; |
122 | } else if (stream.eat(';')) { // S-Expr comment | 122 | } else if (stream.eat(';')) { // S-Expr comment |
123 | state.mode = "s-expr-comment"; | 123 | state.mode = "s-expr-comment"; |
124 | ret |