1"""
2 pygments.lexers.whiley
3 ~~~~~~~~~~~~~~~~~~~~~~
4
5 Lexers for the Whiley language.
6
7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9"""
10
11from pygments.lexer import RegexLexer, bygroups, words
12from pygments.token import Comment, Keyword, Name, Number, Operator, \
13 Punctuation, String, Text
14
15__all__ = ['WhileyLexer']
16
17
18class WhileyLexer(RegexLexer):
19 """
20 Lexer for the Whiley programming language.
21 """
22 name = 'Whiley'
23 url = 'http://whiley.org/'
24 filenames = ['*.whiley']
25 aliases = ['whiley']
26 mimetypes = ['text/x-whiley']
27 version_added = '2.2'
28
29 # See the language specification:
30 # http://whiley.org/download/WhileyLanguageSpec.pdf
31
32 tokens = {
33 'root': [
34 # Whitespace
35 (r'\s+', Text),
36
37 # Comments
38 (r'//.*', Comment.Single),
39 # don't parse empty comment as doc comment
40 (r'/\*\*/', Comment.Multiline),
41 (r'(?s)/\*\*.*?\*/', String.Doc),
42 (r'(?s)/\*.*?\*/', Comment.Multiline),
43
44 # Keywords
45 (words((
46 'if', 'else', 'while', 'for', 'do', 'return',
47 'switch', 'case', 'default', 'break', 'continue',
48 'requires', 'ensures', 'where', 'assert', 'assume',
49 'all', 'no', 'some', 'in', 'is', 'new',
50 'throw', 'try', 'catch', 'debug', 'skip', 'fail',
51 'finite', 'total'), suffix=r'\b'), Keyword.Reserved),
52 (words((
53 'function', 'method', 'public', 'private', 'protected',
54 'export', 'native'), suffix=r'\b'), Keyword.Declaration),
55 # "constant" & "type" are not keywords unless used in declarations
56 (r'(constant|type)(\s+)([a-zA-Z_]\w*)(\s+)(is)\b',
57 bygroups(Keyword.Declaration, Text, Name, Text, Keyword.Reserved)),
58 (r'(true|false|null)\b', Keyword.Constant),
59 (r'(bool|byte|int|real|any|void)\b', Keyword.Type),
60 # "from" is not a keyword unless used with import
61 (r'(import)(\s+)(\*)([^\S\n]+)(from)\b',
62 bygroups(Keyword.Namespace, Text, Punctuation, Text, Keyword.Namespace)),
63 (r'(import)(\s+)([a-zA-Z_]\w*)([^\S\n]+)(from)\b',
64 bygroups(Keyword.Namespace, Text, Name, Text, Keyword.Namespace)),
65 (r'(package|import)\b', Keyword.Namespace),
66
67 # standard library: https://github.com/Whiley/WhileyLibs/
68 (words((
69 # types defined in whiley.lang.Int
70 'i8', 'i16', 'i32', 'i64',
71 'u8', 'u16', 'u32', 'u64',
72 'uint', 'nat',
73
74 # whiley.lang.Any
75 'toString'), suffix=r'\b'), Name.Builtin),
76
77 # byte literal
78 (r'[01]+b', Number.Bin),
79
80 # decimal literal
81 (r'[0-9]+\.[0-9]+', Number.Float),
82 # match "1." but not ranges like "3..5"
83 (r'[0-9]+\.(?!\.)', Number.Float),
84
85 # integer literal
86 (r'0x[0-9a-fA-F]+', Number.Hex),
87 (r'[0-9]+', Number.Integer),
88
89 # character literal
90 (r"""'[^\\]'""", String.Char),
91 (r"""(')(\\['"\\btnfr])(')""",
92 bygroups(String.Char, String.Escape, String.Char)),
93
94 # string literal
95 (r'"', String, 'string'),
96
97 # operators and punctuation
98 (r'[{}()\[\],.;]', Punctuation),
99 (r'[+\-*/%&|<>^!~@=:?'
100 # unicode operators
101 r'\u2200\u2203\u2205\u2282\u2286\u2283\u2287'
102 r'\u222A\u2229\u2264\u2265\u2208\u2227\u2228'
103 r']', Operator),
104
105 # identifier
106 (r'[a-zA-Z_]\w*', Name),
107 ],
108 'string': [
109 (r'"', String, '#pop'),
110 (r'\\[btnfr]', String.Escape),
111 (r'\\u[0-9a-fA-F]{4}', String.Escape),
112 (r'\\.', String),
113 (r'[^\\"]+', String),
114 ],
115 }