summaryrefslogtreecommitdiff
path: root/pygments/lexers/savi.py
blob: 48927f3abf10b4a999531139d730cd96c52f5a33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
"""
    pygments.lexers.savi
    ~~~~~~~~~~~~~~~~~~~~

    Lexer for Savi.

    :copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

from pygments.lexer import RegexLexer, bygroups, include
from pygments.token import Whitespace, Keyword, Name, String, Number, \
  Operator, Punctuation, Comment, Generic, Error

__all__ = ['SaviLexer']


# The canonical version of this file can be found in the following repository,
# where it is kept in sync with any language changes, as well as the other
# pygments-like lexers that are maintained for use with other tools:
# - https://github.com/savi-lang/savi/blob/main/tooling/pygments/lexers/savi.py
#
# If you're changing this file in the pygments repository, please ensure that
# any changes you make are also propagated to the official Savi repository,
# in order to avoid accidental clobbering of your changes later when an update
# from the Savi repository flows forward into the pygments repository.
#
# If you're changing this file in the Savi repository, please ensure that
# any changes you make are also reflected in the other pygments-like lexers
# (rouge, vscode, etc) so that all of the lexers can be kept cleanly in sync.

class SaviLexer(RegexLexer):
  """
  For Savi source code.

  .. versionadded: 2.10
  """

  name = 'Savi'
  url = 'https://github.com/savi-lang/savi'
  aliases = ['savi']
  filenames = ['*.savi']

  tokens = {
    "root": [
      # Line Comment
      (r'//.*?$', Comment.Single),

      # Doc Comment
      (r'::.*?$', Comment.Single),

      # Capability Operator
      (r'(\')(\w+)(?=[^\'])', bygroups(Operator, Name)),

      # Double-Quote String
      (r'\w?"', String.Double, "string.double"),

      # Single-Char String
      (r"'", String.Char, "string.char"),

      # Type Name
      (r'(_?[A-Z]\w*)', Name.Class),

      # Nested Type Name
      (r'(\.)(\s*)(_?[A-Z]\w*)', bygroups(Punctuation, Whitespace, Name.Class)),

      # Declare
      (r'^([ \t]*)(:\w+)',
        bygroups(Whitespace, Name.Tag),
        "decl"),

      # Error-Raising Calls/Names
      (r'((\w+|\+|\-|\*)\!)', Generic.Deleted),

      # Numeric Values
      (r'\b\d([\d_]*(\.[\d_]+)?)\b', Number),

      # Hex Numeric Values
      (r'\b0x([0-9a-fA-F_]+)\b', Number.Hex),

      # Binary Numeric Values
      (r'\b0b([01_]+)\b', Number.Bin),

      # Function Call (with braces)
      (r'\w+(?=\()', Name.Function),

      # Function Call (with receiver)
      (r'(\.)(\s*)(\w+)', bygroups(Punctuation, Whitespace, Name.Function)),

      # Function Call (with self receiver)
      (r'(@)(\w+)', bygroups(Punctuation, Name.Function)),

      # Parenthesis
      (r'\(', Punctuation, "root"),
      (r'\)', Punctuation, "#pop"),

      # Brace
      (r'\{', Punctuation, "root"),
      (r'\}', Punctuation, "#pop"),

      # Bracket
      (r'\[', Punctuation, "root"),
      (r'(\])(\!)', bygroups(Punctuation, Generic.Deleted), "#pop"),
      (r'\]', Punctuation, "#pop"),

      # Punctuation
      (r'[,;:\.@]', Punctuation),

      # Piping Operators
      (r'(\|\>)', Operator),

      # Branching Operators
      (r'(\&\&|\|\||\?\?|\&\?|\|\?|\.\?)', Operator),

      # Comparison Operators
      (r'(\<\=\>|\=\~|\=\=|\<\=|\>\=|\<|\>)', Operator),

      # Arithmetic Operators
      (r'(\+|\-|\/|\*|\%)', Operator),

      # Assignment Operators
      (r'(\=)', Operator),

      # Other Operators
      (r'(\!|\<\<|\<|\&|\|)', Operator),

      # Identifiers
      (r'\b\w+\b', Name),

      # Whitespace
      (r'[ \t\r]+\n*|\n+', Whitespace),
    ],

    # Declare (nested rules)
    "decl": [
      (r'\b[a-z_]\w*\b(?!\!)', Keyword.Declaration),
      (r':', Punctuation, "#pop"),
      (r'\n', Whitespace, "#pop"),
      include("root"),
    ],

    # Double-Quote String (nested rules)
    "string.double": [
      (r'\\\(', String.Interpol, "string.interpolation"),
      (r'\\u[0-9a-fA-F]{4}', String.Escape),
      (r'\\x[0-9a-fA-F]{2}', String.Escape),
      (r'\\[bfnrt\\\']', String.Escape),
      (r'\\"', String.Escape),
      (r'"', String.Double, "#pop"),
      (r'[^\\"]+', String.Double),
      (r'.', Error),
    ],

    # Single-Char String (nested rules)
    "string.char": [
      (r'\\u[0-9a-fA-F]{4}', String.Escape),
      (r'\\x[0-9a-fA-F]{2}', String.Escape),
      (r'\\[bfnrt\\\']', String.Escape),
      (r"\\'", String.Escape),
      (r"'", String.Char, "#pop"),
      (r"[^\\']+", String.Char),
      (r'.', Error),
    ],

    # Interpolation inside String (nested rules)
    "string.interpolation": [
      (r"\)", String.Interpol, "#pop"),
      include("root"),
    ]
  }