1"""
2 pygments.lexers.j
3 ~~~~~~~~~~~~~~~~~
4
5 Lexer for the J programming 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, words, include, bygroups
12from pygments.token import Comment, Keyword, Name, Number, Operator, \
13 Punctuation, String, Whitespace
14
15__all__ = ['JLexer']
16
17
18class JLexer(RegexLexer):
19 """
20 For J source code.
21 """
22
23 name = 'J'
24 url = 'http://jsoftware.com/'
25 aliases = ['j']
26 filenames = ['*.ijs']
27 mimetypes = ['text/x-j']
28 version_added = '2.1'
29
30 validName = r'\b[a-zA-Z]\w*'
31
32 tokens = {
33 'root': [
34 # Shebang script
35 (r'#!.*$', Comment.Preproc),
36
37 # Comments
38 (r'NB\..*', Comment.Single),
39 (r'(\n+\s*)(Note)', bygroups(Whitespace, Comment.Multiline),
40 'comment'),
41 (r'(\s*)(Note.*)', bygroups(Whitespace, Comment.Single)),
42
43 # Whitespace
44 (r'\s+', Whitespace),
45
46 # Strings
47 (r"'", String, 'singlequote'),
48
49 # Definitions
50 (r'0\s+:\s*0', Name.Entity, 'nounDefinition'),
51 (r'(noun)(\s+)(define)(\s*)$', bygroups(Name.Entity, Whitespace,
52 Name.Entity, Whitespace), 'nounDefinition'),
53 (r'([1-4]|13)\s+:\s*0\b',
54 Name.Function, 'explicitDefinition'),
55 (r'(adverb|conjunction|dyad|monad|verb)(\s+)(define)\b',
56 bygroups(Name.Function, Whitespace, Name.Function),
57 'explicitDefinition'),
58
59 # Flow Control
60 (words(('for_', 'goto_', 'label_'), suffix=validName+r'\.'), Name.Label),
61 (words((
62 'assert', 'break', 'case', 'catch', 'catchd',
63 'catcht', 'continue', 'do', 'else', 'elseif',
64 'end', 'fcase', 'for', 'if', 'return',
65 'select', 'throw', 'try', 'while', 'whilst',
66 ), suffix=r'\.'), Name.Label),
67
68 # Variable Names
69 (validName, Name.Variable),
70
71 # Standard Library
72 (words((
73 'ARGV', 'CR', 'CRLF', 'DEL', 'Debug',
74 'EAV', 'EMPTY', 'FF', 'JVERSION', 'LF',
75 'LF2', 'Note', 'TAB', 'alpha17', 'alpha27',
76 'apply', 'bind', 'boxopen', 'boxxopen', 'bx',
77 'clear', 'cutLF', 'cutopen', 'datatype', 'def',
78 'dfh', 'drop', 'each', 'echo', 'empty',
79 'erase', 'every', 'evtloop', 'exit', 'expand',
80 'fetch', 'file2url', 'fixdotdot', 'fliprgb', 'getargs',
81 'getenv', 'hfd', 'inv', 'inverse', 'iospath',
82 'isatty', 'isutf8', 'items', 'leaf', 'list',
83 'nameclass', 'namelist', 'names', 'nc',
84 'nl', 'on', 'pick', 'rows',
85 'script', 'scriptd', 'sign', 'sminfo', 'smoutput',
86 'sort', 'split', 'stderr', 'stdin', 'stdout',
87 'table', 'take', 'timespacex', 'timex', 'tmoutput',
88 'toCRLF', 'toHOST', 'toJ', 'tolower', 'toupper',
89 'type', 'ucp', 'ucpcount', 'usleep', 'utf8',
90 'uucp',
91 )), Name.Function),
92
93 # Copula
94 (r'=[.:]', Operator),
95
96 # Builtins
97 (r'[-=+*#$%@!~`^&";:.,<>{}\[\]\\|/?]', Operator),
98
99 # Short Keywords
100 (r'[abCdDeEfHiIjLMoprtT]\.', Keyword.Reserved),
101 (r'[aDiLpqsStux]\:', Keyword.Reserved),
102 (r'(_[0-9])\:', Keyword.Constant),
103
104 # Parens
105 (r'\(', Punctuation, 'parentheses'),
106
107 # Numbers
108 include('numbers'),
109 ],
110
111 'comment': [
112 (r'[^)]', Comment.Multiline),
113 (r'^\)', Comment.Multiline, '#pop'),
114 (r'[)]', Comment.Multiline),
115 ],
116
117 'explicitDefinition': [
118 (r'\b[nmuvxy]\b', Name.Decorator),
119 include('root'),
120 (r'[^)]', Name),
121 (r'^\)', Name.Label, '#pop'),
122 (r'[)]', Name),
123 ],
124
125 'numbers': [
126 (r'\b_{1,2}\b', Number),
127 (r'_?\d+(\.\d+)?(\s*[ejr]\s*)_?\d+(\.?=\d+)?', Number),
128 (r'_?\d+\.(?=\d+)', Number.Float),
129 (r'_?\d+x', Number.Integer.Long),
130 (r'_?\d+', Number.Integer),
131 ],
132
133 'nounDefinition': [
134 (r'[^)]+', String),
135 (r'^\)', Name.Label, '#pop'),
136 (r'[)]', String),
137 ],
138
139 'parentheses': [
140 (r'\)', Punctuation, '#pop'),
141 # include('nounDefinition'),
142 include('explicitDefinition'),
143 include('root'),
144 ],
145
146 'singlequote': [
147 (r"[^']+", String),
148 (r"''", String),
149 (r"'", String, '#pop'),
150 ],
151 }