1# -*- coding: utf-8 -*-
2"""
3    pygments.lexers.elm
4    ~~~~~~~~~~~~~~~~~~~
5
6    Lexer for the Elm programming language.
7
8    :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS.
9    :license: BSD, see LICENSE for details.
10"""
11
12from pygments.lexer import RegexLexer, words, include
13from pygments.token import Comment, Keyword, Name, Number, Punctuation, String, Text
14
15__all__ = ['ElmLexer']
16
17
18class ElmLexer(RegexLexer):
19    """
20    For `Elm <http://elm-lang.org/>`_ source code.
21
22    .. versionadded:: 2.1
23    """
24
25    name = 'Elm'
26    aliases = ['elm']
27    filenames = ['*.elm']
28    mimetypes = ['text/x-elm']
29
30    validName = r'[a-z_][a-zA-Z0-9_\']*'
31
32    specialName = r'^main '
33
34    builtinOps = (
35        '~', '||', '|>', '|', '`', '^', '\\', '\'', '>>', '>=', '>', '==',
36        '=', '<~', '<|', '<=', '<<', '<-', '<', '::', ':', '/=', '//', '/',
37        '..', '.', '->', '-', '++', '+', '*', '&&', '%',
38    )
39
40    reservedWords = words((
41        'alias', 'as', 'case', 'else', 'if', 'import', 'in',
42        'let', 'module', 'of', 'port', 'then', 'type', 'where',
43    ), suffix=r'\b')
44
45    tokens = {
46        'root': [
47
48            # Comments
49            (r'\{-', Comment.Multiline, 'comment'),
50            (r'--.*', Comment.Single),
51
52            # Whitespace
53            (r'\s+', Text),
54
55            # Strings
56            (r'"', String, 'doublequote'),
57
58            # Modules
59            (r'^\s*module\s*', Keyword.Namespace, 'imports'),
60
61            # Imports
62            (r'^\s*import\s*', Keyword.Namespace, 'imports'),
63
64            # Shaders
65            (r'\[glsl\|.*', Name.Entity, 'shader'),
66
67            # Keywords
68            (reservedWords, Keyword.Reserved),
69
70            # Types
71            (r'[A-Z][a-zA-Z0-9_]*', Keyword.Type),
72
73            # Main
74            (specialName, Keyword.Reserved),
75
76            # Prefix Operators
77            (words((builtinOps), prefix=r'\(', suffix=r'\)'), Name.Function),
78
79            # Infix Operators
80            (words(builtinOps), Name.Function),
81
82            # Numbers
83            include('numbers'),
84
85            # Variable Names
86            (validName, Name.Variable),
87
88            # Parens
89            (r'[,()\[\]{}]', Punctuation),
90
91        ],
92
93        'comment': [
94            (r'-(?!\})', Comment.Multiline),
95            (r'\{-', Comment.Multiline, 'comment'),
96            (r'[^-}]', Comment.Multiline),
97            (r'-\}', Comment.Multiline, '#pop'),
98        ],
99
100        'doublequote': [
101            (r'\\u[0-9a-fA-F]{4}', String.Escape),
102            (r'\\[nrfvb\\"]', String.Escape),
103            (r'[^"]', String),
104            (r'"', String, '#pop'),
105        ],
106
107        'imports': [
108            (r'\w+(\.\w+)*', Name.Class, '#pop'),
109        ],
110
111        'numbers': [
112            (r'_?\d+\.(?=\d+)', Number.Float),
113            (r'_?\d+', Number.Integer),
114        ],
115
116        'shader': [
117            (r'\|(?!\])', Name.Entity),
118            (r'\|\]', Name.Entity, '#pop'),
119            (r'.*\n', Name.Entity),
120        ],
121    }
122