1/**
2 * @license
3 * Copyright (C) 2015 Chris Morgan
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *    http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/**
19 * @fileoverview
20 * Registers a language handler for Rust.
21 *
22 * Derived from prior experience implementing similar things in a few environments,
23 * most especially rust.vim.
24 *
25 * @author me@chrismorgan.info
26 */
27
28PR['registerLangHandler'](
29    PR['createSimpleLexer']([], [
30		// Whitespace
31		[PR['PR_PLAIN'],       /^[\t\n\r \xA0]+/],
32
33		// Single line comments
34		[PR['PR_COMMENT'], /^\/\/.*/],
35		// Block comments (sadly I do not see how to make this cope with comment nesting as it should)
36		[PR['PR_COMMENT'], /^\/\*[\s\S]*?(?:\*\/|$)/],//, null],
37		// String and character literals
38		[PR['PR_STRING'], /^b"(?:[^\\]|\\(?:.|x[\da-fA-F]{2}))*?"/],  // Bytes literal
39		[PR['PR_STRING'], /^"(?:[^\\]|\\(?:.|x[\da-fA-F]{2}|u\{\[\da-fA-F]{1,6}\}))*?"/],  // String literal
40		[PR['PR_STRING'], /^b?r(#*)\"[\s\S]*?\"\1/],  // Raw string/bytes literal
41		[PR['PR_STRING'], /^b'([^\\]|\\(.|x[\da-fA-F]{2}))'/],  // Byte literal
42		[PR['PR_STRING'], /^'([^\\]|\\(.|x[\da-fA-F]{2}|u\{[\da-fA-F]{1,6}\}))'/],  // Character literal
43
44		// Lifetime
45		[PR['PR_TAG'], /^'\w+?\b/],
46
47		// Keywords, reserved keywords and primitive types
48		[PR['PR_KEYWORD'], /^(?:match|if|else|as|break|box|continue|extern|fn|for|in|if|impl|dyn|let|loop|pub|return|super|unsafe|where|while|use|mod|trait|struct|enum|type|move|mut|ref|static|const|crate)\b/],
49		[PR['PR_KEYWORD'], /^(?:alignof|become|do|offsetof|priv|pure|sizeof|typeof|unsized|yield|async|await|try|abstract|virtual|final|override|macro)\b/],
50		[PR['PR_TYPE'], /^(?:[iu](8|16|32|64|128|size)|char|bool|f32|f64|str|Self)\b/],
51
52		// Rust 1.0 prelude items
53		[PR['PR_TYPE'], /^(?:Copy|Send|Sized|Sync|Drop|Fn|FnMut|FnOnce|Box|ToOwned|Clone|PartialEq|PartialOrd|Eq|Ord|AsRef|AsMut|Into|From|Default|Iterator|Extend|IntoIterator|DoubleEndedIterator|ExactSizeIterator|Option|Some|None|Result|Ok|Err|SliceConcatExt|String|ToString|Vec)\b/],
54
55		// Literals:
56		[PR['PR_LITERAL'], /^(self|true|false|null)\b/],
57		// A number is a hex integer literal, a decimal real literal, or in
58		// scientific notation.
59		// Integer literals: decimal, hexadecimal, octal, binary.
60		[PR['PR_LITERAL'], /^\d[0-9_]*(?:[iu](?:size|8|16|32|64|128))?/],
61		[PR['PR_LITERAL'], /^0x[a-fA-F0-9_]+(?:[iu](?:size|8|16|32|64|128))?/],
62		[PR['PR_LITERAL'], /^0o[0-7_]+(?:[iu](?:size|8|16|32|64|128))?/],
63		[PR['PR_LITERAL'], /^0b[01_]+(?:[iu](?:size|8|16|32|64|128))?/],
64		// Float literals
65		[PR['PR_LITERAL'], /^\d[0-9_]*\.(?![^\s\d.])/],
66		[PR['PR_LITERAL'], /^\d[0-9_]*(?:\.\d[0-9_]*)(?:[eE][+-]?[0-9_]+)?(?:f32|f64)?/],
67		[PR['PR_LITERAL'], /^\d[0-9_]*(?:\.\d[0-9_]*)?(?:[eE][+-]?[0-9_]+)(?:f32|f64)?/],
68		[PR['PR_LITERAL'], /^\d[0-9_]*(?:\.\d[0-9_]*)?(?:[eE][+-]?[0-9_]+)?(?:f32|f64)/],
69
70		// Macro invocations (an identifier plus a !)
71		[PR['PR_ATTRIB_NAME'], /^[a-z_]\w*!/i],
72		// An identifier (sorry, this should be unicode)
73		[PR['PR_PLAIN'], /^[a-z_]\w*/i],
74		// Attributes
75		[PR['PR_ATTRIB_VALUE'], /^#!?\[[\s\S]*?\]/],
76		// All the punctuation
77		[PR['PR_PUNCTUATION'], /^[+\-/*=^&|!<>%[\](){}?:.,;]/],
78		// Anything else (which is probably illegal, as all the legal stuff should have been covered) can be plain
79		[PR['PR_PLAIN'], /./]
80		]),
81    ['rust']);
82