1# -*- coding: utf-8 -*-
2"""
3    pygments.lexers.slash
4    ~~~~~~~~~~~~~~~~~~~~~
5
6    Lexer for the `Slash <https://github.com/arturadib/Slash-A>`_ programming
7    language.
8
9    :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS.
10    :license: BSD, see LICENSE for details.
11"""
12
13from pygments.lexer import ExtendedRegexLexer, bygroups, DelegatingLexer
14from pygments.token import Name, Number, String, Comment, Punctuation, \
15    Other, Keyword, Operator, Whitespace
16
17__all__ = ['SlashLexer']
18
19
20class SlashLanguageLexer(ExtendedRegexLexer):
21    _nkw = r'(?=[^a-zA-Z_0-9])'
22
23    def move_state(new_state):
24        return ("#pop", new_state)
25
26    def right_angle_bracket(lexer, match, ctx):
27        if len(ctx.stack) > 1 and ctx.stack[-2] == "string":
28            ctx.stack.pop()
29        yield match.start(), String.Interpol, '}'
30        ctx.pos = match.end()
31        pass
32
33    tokens = {
34        "root": [
35            (r"<%=",        Comment.Preproc,    move_state("slash")),
36            (r"<%!!",       Comment.Preproc,    move_state("slash")),
37            (r"<%#.*?%>",   Comment.Multiline),
38            (r"<%",         Comment.Preproc,    move_state("slash")),
39            (r".|\n",       Other),
40        ],
41        "string": [
42            (r"\\",         String.Escape,      move_state("string_e")),
43            (r"\"",         String,             move_state("slash")),
44            (r"#\{",        String.Interpol,    "slash"),
45            (r'.|\n',       String),
46        ],
47        "string_e": [
48            (r'n',                  String.Escape,      move_state("string")),
49            (r't',                  String.Escape,      move_state("string")),
50            (r'r',                  String.Escape,      move_state("string")),
51            (r'e',                  String.Escape,      move_state("string")),
52            (r'x[a-fA-F0-9]{2}',    String.Escape,      move_state("string")),
53            (r'.',                  String.Escape,      move_state("string")),
54        ],
55        "regexp": [
56            (r'}[a-z]*',            String.Regex,       move_state("slash")),
57            (r'\\(.|\n)',           String.Regex),
58            (r'{',                  String.Regex,       "regexp_r"),
59            (r'.|\n',               String.Regex),
60        ],
61        "regexp_r": [
62            (r'}[a-z]*',            String.Regex,       "#pop"),
63            (r'\\(.|\n)',           String.Regex),
64            (r'{',                  String.Regex,       "regexp_r"),
65        ],
66        "slash": [
67            (r"%>",                     Comment.Preproc,    move_state("root")),
68            (r"\"",                     String,             move_state("string")),
69            (r"'[a-zA-Z0-9_]+",         String),
70            (r'%r{',                    String.Regex,       move_state("regexp")),
71            (r'/\*.*?\*/',              Comment.Multiline),
72            (r"(#|//).*?\n",            Comment.Single),
73            (r'-?[0-9]+e[+-]?[0-9]+',   Number.Float),
74            (r'-?[0-9]+\.[0-9]+(e[+-]?[0-9]+)?', Number.Float),
75            (r'-?[0-9]+',               Number.Integer),
76            (r'nil'+_nkw,               Name.Builtin),
77            (r'true'+_nkw,              Name.Builtin),
78            (r'false'+_nkw,             Name.Builtin),
79            (r'self'+_nkw,              Name.Builtin),
80            (r'(class)(\s+)([A-Z][a-zA-Z0-9_\']*)',
81                bygroups(Keyword, Whitespace, Name.Class)),
82            (r'class'+_nkw,             Keyword),
83            (r'extends'+_nkw,           Keyword),
84            (r'(def)(\s+)(self)(\s*)(\.)(\s*)([a-z_][a-zA-Z0-9_\']*=?|<<|>>|==|<=>|<=|<|>=|>|\+|-(self)?|~(self)?|\*|/|%|^|&&|&|\||\[\]=?)',
85                bygroups(Keyword, Whitespace, Name.Builtin, Whitespace, Punctuation, Whitespace, Name.Function)),
86            (r'(def)(\s+)([a-z_][a-zA-Z0-9_\']*=?|<<|>>|==|<=>|<=|<|>=|>|\+|-(self)?|~(self)?|\*|/|%|^|&&|&|\||\[\]=?)',
87                bygroups(Keyword, Whitespace, Name.Function)),
88            (r'def'+_nkw,               Keyword),
89            (r'if'+_nkw,                Keyword),
90            (r'elsif'+_nkw,             Keyword),
91            (r'else'+_nkw,              Keyword),
92            (r'unless'+_nkw,            Keyword),
93            (r'for'+_nkw,               Keyword),
94            (r'in'+_nkw,                Keyword),
95            (r'while'+_nkw,             Keyword),
96            (r'until'+_nkw,             Keyword),
97            (r'and'+_nkw,               Keyword),
98            (r'or'+_nkw,                Keyword),
99            (r'not'+_nkw,               Keyword),
100            (r'lambda'+_nkw,            Keyword),
101            (r'try'+_nkw,               Keyword),
102            (r'catch'+_nkw,             Keyword),
103            (r'return'+_nkw,            Keyword),
104            (r'next'+_nkw,              Keyword),
105            (r'last'+_nkw,              Keyword),
106            (r'throw'+_nkw,             Keyword),
107            (r'use'+_nkw,               Keyword),
108            (r'switch'+_nkw,            Keyword),
109            (r'\\',                     Keyword),
110            (r'λ',                      Keyword),
111            (r'__FILE__'+_nkw,          Name.Builtin.Pseudo),
112            (r'__LINE__'+_nkw,          Name.Builtin.Pseudo),
113            (r'[A-Z][a-zA-Z0-9_\']*'+_nkw, Name.Constant),
114            (r'[a-z_][a-zA-Z0-9_\']*'+_nkw, Name),
115            (r'@[a-z_][a-zA-Z0-9_\']*'+_nkw, Name.Variable.Instance),
116            (r'@@[a-z_][a-zA-Z0-9_\']*'+_nkw, Name.Variable.Class),
117            (r'\(',                     Punctuation),
118            (r'\)',                     Punctuation),
119            (r'\[',                     Punctuation),
120            (r'\]',                     Punctuation),
121            (r'\{',                     Punctuation),
122            (r'\}',                     right_angle_bracket),
123            (r';',                      Punctuation),
124            (r',',                      Punctuation),
125            (r'<<=',                    Operator),
126            (r'>>=',                    Operator),
127            (r'<<',                     Operator),
128            (r'>>',                     Operator),
129            (r'==',                     Operator),
130            (r'!=',                     Operator),
131            (r'=>',                     Operator),
132            (r'=',                      Operator),
133            (r'<=>',                    Operator),
134            (r'<=',                     Operator),
135            (r'>=',                     Operator),
136            (r'<',                      Operator),
137            (r'>',                      Operator),
138            (r'\+\+',                   Operator),
139            (r'\+=',                    Operator),
140            (r'-=',                     Operator),
141            (r'\*\*=',                  Operator),
142            (r'\*=',                    Operator),
143            (r'\*\*',                   Operator),
144            (r'\*',                     Operator),
145            (r'/=',                     Operator),
146            (r'\+',                     Operator),
147            (r'-',                      Operator),
148            (r'/',                      Operator),
149            (r'%=',                     Operator),
150            (r'%',                      Operator),
151            (r'^=',                     Operator),
152            (r'&&=',                    Operator),
153            (r'&=',                     Operator),
154            (r'&&',                     Operator),
155            (r'&',                      Operator),
156            (r'\|\|=',                  Operator),
157            (r'\|=',                    Operator),
158            (r'\|\|',                   Operator),
159            (r'\|',                     Operator),
160            (r'!',                      Operator),
161            (r'\.\.\.',                 Operator),
162            (r'\.\.',                   Operator),
163            (r'\.',                     Operator),
164            (r'::',                     Operator),
165            (r':',                      Operator),
166            (r'(\s|\n)+',               Whitespace),
167            (r'[a-z_][a-zA-Z0-9_\']*',  Name.Variable),
168        ],
169    }
170
171
172class SlashLexer(DelegatingLexer):
173    """
174    Lexer for the Slash programming language.
175
176    .. versionadded:: 2.4
177    """
178
179    name = 'Slash'
180    aliases = ['slash']
181    filenames = ['*.sla']
182
183    def __init__(self, **options):
184        from pygments.lexers.web import HtmlLexer
185        super().__init__(HtmlLexer, SlashLanguageLexer, **options)
186