1# -*- coding: utf-8 -*-
2"""
3    pygments.lexers.apl
4    ~~~~~~~~~~~~~~~~~~~
5
6    Lexers for APL.
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
13from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
14    Number, Punctuation
15
16__all__ = ['APLLexer']
17
18
19class APLLexer(RegexLexer):
20    """
21    A simple `APL <https://en.m.wikipedia.org/wiki/APL_(programming_language)>`_ lexer.
22
23    .. versionadded:: 2.0
24    """
25    name = 'APL'
26    aliases = ['apl']
27    filenames = ['*.apl']
28
29    tokens = {
30        'root': [
31            # Whitespace
32            # ==========
33            (r'\s+', Text),
34            #
35            # Comment
36            # =======
37            # '⍝' is traditional; '#' is supported by GNU APL and NGN (but not Dyalog)
38            (r'[⍝#].*$', Comment.Single),
39            #
40            # Strings
41            # =======
42            (r'\'((\'\')|[^\'])*\'', String.Single),
43            (r'"(("")|[^"])*"', String.Double),  # supported by NGN APL
44            #
45            # Punctuation
46            # ===========
47            # This token type is used for diamond and parenthesis
48            # but not for bracket and ; (see below)
49            (r'[⋄◇()]', Punctuation),
50            #
51            # Array indexing
52            # ==============
53            # Since this token type is very important in APL, it is not included in
54            # the punctuation token type but rather in the following one
55            (r'[\[\];]', String.Regex),
56            #
57            # Distinguished names
58            # ===================
59            # following IBM APL2 standard
60            (r'⎕[A-Za-zΔ∆⍙][A-Za-zΔ∆⍙_¯0-9]*', Name.Function),
61            #
62            # Labels
63            # ======
64            # following IBM APL2 standard
65            # (r'[A-Za-zΔ∆⍙][A-Za-zΔ∆⍙_¯0-9]*:', Name.Label),
66            #
67            # Variables
68            # =========
69            # following IBM APL2 standard
70            (r'[A-Za-zΔ∆⍙][A-Za-zΔ∆⍙_¯0-9]*', Name.Variable),
71            #
72            # Numbers
73            # =======
74            (r'¯?(0[Xx][0-9A-Fa-f]+|[0-9]*\.?[0-9]+([Ee][+¯]?[0-9]+)?|¯|∞)'
75             r'([Jj]¯?(0[Xx][0-9A-Fa-f]+|[0-9]*\.?[0-9]+([Ee][+¯]?[0-9]+)?|¯|∞))?',
76             Number),
77            #
78            # Operators
79            # ==========
80            (r'[\.\\\/⌿⍀¨⍣⍨⍠⍤∘⌸&⌶@⌺⍥⍛⍢]', Name.Attribute),  # closest token type
81            (r'[+\-×÷⌈⌊∣|⍳?*⍟○!⌹<≤=>≥≠≡≢∊⍷∪∩~∨∧⍱⍲⍴,⍪⌽⊖⍉↑↓⊂⊃⌷⍋⍒⊤⊥⍕⍎⊣⊢⍁⍂≈⌸⍯↗⊆⊇⍸√⌾…⍮]',
82             Operator),
83            #
84            # Constant
85            # ========
86            (r'⍬', Name.Constant),
87            #
88            # Quad symbol
89            # ===========
90            (r'[⎕⍞]', Name.Variable.Global),
91            #
92            # Arrows left/right
93            # =================
94            (r'[←→]', Keyword.Declaration),
95            #
96            # D-Fn
97            # ====
98            (r'[⍺⍵⍶⍹∇:]', Name.Builtin.Pseudo),
99            (r'[{}]', Keyword.Type),
100        ],
101    }
102