1 | /*
|
---|
2 | Language: Scheme
|
---|
3 | Description: Scheme is a programming language in the Lisp family.
|
---|
4 | (keywords based on http://community.schemewiki.org/?scheme-keywords)
|
---|
5 | Author: JP Verkamp <me@jverkamp.com>
|
---|
6 | Contributors: Ivan Sagalaev <maniac@softwaremaniacs.org>
|
---|
7 | Origin: clojure.js
|
---|
8 | Website: http://community.schemewiki.org/?what-is-scheme
|
---|
9 | Category: lisp
|
---|
10 | */
|
---|
11 |
|
---|
12 | function scheme(hljs) {
|
---|
13 | const SCHEME_IDENT_RE = '[^\\(\\)\\[\\]\\{\\}",\'`;#|\\\\\\s]+';
|
---|
14 | const SCHEME_SIMPLE_NUMBER_RE = '(-|\\+)?\\d+([./]\\d+)?';
|
---|
15 | const SCHEME_COMPLEX_NUMBER_RE = SCHEME_SIMPLE_NUMBER_RE + '[+\\-]' + SCHEME_SIMPLE_NUMBER_RE + 'i';
|
---|
16 | const KEYWORDS = {
|
---|
17 | $pattern: SCHEME_IDENT_RE,
|
---|
18 | 'builtin-name':
|
---|
19 | 'case-lambda call/cc class define-class exit-handler field import ' +
|
---|
20 | 'inherit init-field interface let*-values let-values let/ec mixin ' +
|
---|
21 | 'opt-lambda override protect provide public rename require ' +
|
---|
22 | 'require-for-syntax syntax syntax-case syntax-error unit/sig unless ' +
|
---|
23 | 'when with-syntax and begin call-with-current-continuation ' +
|
---|
24 | 'call-with-input-file call-with-output-file case cond define ' +
|
---|
25 | 'define-syntax delay do dynamic-wind else for-each if lambda let let* ' +
|
---|
26 | 'let-syntax letrec letrec-syntax map or syntax-rules \' * + , ,@ - ... / ' +
|
---|
27 | '; < <= = => > >= ` abs acos angle append apply asin assoc assq assv atan ' +
|
---|
28 | 'boolean? caar cadr call-with-input-file call-with-output-file ' +
|
---|
29 | 'call-with-values car cdddar cddddr cdr ceiling char->integer ' +
|
---|
30 | 'char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? ' +
|
---|
31 | 'char-downcase char-lower-case? char-numeric? char-ready? char-upcase ' +
|
---|
32 | 'char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? ' +
|
---|
33 | 'char? close-input-port close-output-port complex? cons cos ' +
|
---|
34 | 'current-input-port current-output-port denominator display eof-object? ' +
|
---|
35 | 'eq? equal? eqv? eval even? exact->inexact exact? exp expt floor ' +
|
---|
36 | 'force gcd imag-part inexact->exact inexact? input-port? integer->char ' +
|
---|
37 | 'integer? interaction-environment lcm length list list->string ' +
|
---|
38 | 'list->vector list-ref list-tail list? load log magnitude make-polar ' +
|
---|
39 | 'make-rectangular make-string make-vector max member memq memv min ' +
|
---|
40 | 'modulo negative? newline not null-environment null? number->string ' +
|
---|
41 | 'number? numerator odd? open-input-file open-output-file output-port? ' +
|
---|
42 | 'pair? peek-char port? positive? procedure? quasiquote quote quotient ' +
|
---|
43 | 'rational? rationalize read read-char real-part real? remainder reverse ' +
|
---|
44 | 'round scheme-report-environment set! set-car! set-cdr! sin sqrt string ' +
|
---|
45 | 'string->list string->number string->symbol string-append string-ci<=? ' +
|
---|
46 | 'string-ci<? string-ci=? string-ci>=? string-ci>? string-copy ' +
|
---|
47 | 'string-fill! string-length string-ref string-set! string<=? string<? ' +
|
---|
48 | 'string=? string>=? string>? string? substring symbol->string symbol? ' +
|
---|
49 | 'tan transcript-off transcript-on truncate values vector ' +
|
---|
50 | 'vector->list vector-fill! vector-length vector-ref vector-set! ' +
|
---|
51 | 'with-input-from-file with-output-to-file write write-char zero?'
|
---|
52 | };
|
---|
53 |
|
---|
54 | const LITERAL = {
|
---|
55 | className: 'literal',
|
---|
56 | begin: '(#t|#f|#\\\\' + SCHEME_IDENT_RE + '|#\\\\.)'
|
---|
57 | };
|
---|
58 |
|
---|
59 | const NUMBER = {
|
---|
60 | className: 'number',
|
---|
61 | variants: [
|
---|
62 | {
|
---|
63 | begin: SCHEME_SIMPLE_NUMBER_RE,
|
---|
64 | relevance: 0
|
---|
65 | },
|
---|
66 | {
|
---|
67 | begin: SCHEME_COMPLEX_NUMBER_RE,
|
---|
68 | relevance: 0
|
---|
69 | },
|
---|
70 | {
|
---|
71 | begin: '#b[0-1]+(/[0-1]+)?'
|
---|
72 | },
|
---|
73 | {
|
---|
74 | begin: '#o[0-7]+(/[0-7]+)?'
|
---|
75 | },
|
---|
76 | {
|
---|
77 | begin: '#x[0-9a-f]+(/[0-9a-f]+)?'
|
---|
78 | }
|
---|
79 | ]
|
---|
80 | };
|
---|
81 |
|
---|
82 | const STRING = hljs.QUOTE_STRING_MODE;
|
---|
83 |
|
---|
84 | const COMMENT_MODES = [
|
---|
85 | hljs.COMMENT(
|
---|
86 | ';',
|
---|
87 | '$',
|
---|
88 | {
|
---|
89 | relevance: 0
|
---|
90 | }
|
---|
91 | ),
|
---|
92 | hljs.COMMENT('#\\|', '\\|#')
|
---|
93 | ];
|
---|
94 |
|
---|
95 | const IDENT = {
|
---|
96 | begin: SCHEME_IDENT_RE,
|
---|
97 | relevance: 0
|
---|
98 | };
|
---|
99 |
|
---|
100 | const QUOTED_IDENT = {
|
---|
101 | className: 'symbol',
|
---|
102 | begin: '\'' + SCHEME_IDENT_RE
|
---|
103 | };
|
---|
104 |
|
---|
105 | const BODY = {
|
---|
106 | endsWithParent: true,
|
---|
107 | relevance: 0
|
---|
108 | };
|
---|
109 |
|
---|
110 | const QUOTED_LIST = {
|
---|
111 | variants: [
|
---|
112 | {
|
---|
113 | begin: /'/
|
---|
114 | },
|
---|
115 | {
|
---|
116 | begin: '`'
|
---|
117 | }
|
---|
118 | ],
|
---|
119 | contains: [
|
---|
120 | {
|
---|
121 | begin: '\\(',
|
---|
122 | end: '\\)',
|
---|
123 | contains: [
|
---|
124 | 'self',
|
---|
125 | LITERAL,
|
---|
126 | STRING,
|
---|
127 | NUMBER,
|
---|
128 | IDENT,
|
---|
129 | QUOTED_IDENT
|
---|
130 | ]
|
---|
131 | }
|
---|
132 | ]
|
---|
133 | };
|
---|
134 |
|
---|
135 | const NAME = {
|
---|
136 | className: 'name',
|
---|
137 | relevance: 0,
|
---|
138 | begin: SCHEME_IDENT_RE,
|
---|
139 | keywords: KEYWORDS
|
---|
140 | };
|
---|
141 |
|
---|
142 | const LAMBDA = {
|
---|
143 | begin: /lambda/,
|
---|
144 | endsWithParent: true,
|
---|
145 | returnBegin: true,
|
---|
146 | contains: [
|
---|
147 | NAME,
|
---|
148 | {
|
---|
149 | endsParent: true,
|
---|
150 | variants: [
|
---|
151 | {
|
---|
152 | begin: /\(/,
|
---|
153 | end: /\)/
|
---|
154 | },
|
---|
155 | {
|
---|
156 | begin: /\[/,
|
---|
157 | end: /\]/
|
---|
158 | }
|
---|
159 | ],
|
---|
160 | contains: [ IDENT ]
|
---|
161 | }
|
---|
162 | ]
|
---|
163 | };
|
---|
164 |
|
---|
165 | const LIST = {
|
---|
166 | variants: [
|
---|
167 | {
|
---|
168 | begin: '\\(',
|
---|
169 | end: '\\)'
|
---|
170 | },
|
---|
171 | {
|
---|
172 | begin: '\\[',
|
---|
173 | end: '\\]'
|
---|
174 | }
|
---|
175 | ],
|
---|
176 | contains: [
|
---|
177 | LAMBDA,
|
---|
178 | NAME,
|
---|
179 | BODY
|
---|
180 | ]
|
---|
181 | };
|
---|
182 |
|
---|
183 | BODY.contains = [
|
---|
184 | LITERAL,
|
---|
185 | NUMBER,
|
---|
186 | STRING,
|
---|
187 | IDENT,
|
---|
188 | QUOTED_IDENT,
|
---|
189 | QUOTED_LIST,
|
---|
190 | LIST
|
---|
191 | ].concat(COMMENT_MODES);
|
---|
192 |
|
---|
193 | return {
|
---|
194 | name: 'Scheme',
|
---|
195 | illegal: /\S/,
|
---|
196 | contains: [
|
---|
197 | hljs.SHEBANG(),
|
---|
198 | NUMBER,
|
---|
199 | STRING,
|
---|
200 | QUOTED_IDENT,
|
---|
201 | QUOTED_LIST,
|
---|
202 | LIST
|
---|
203 | ].concat(COMMENT_MODES)
|
---|
204 | };
|
---|
205 | }
|
---|
206 |
|
---|
207 | module.exports = scheme;
|
---|