1"""
2 pygments.lexers.smalltalk
3 ~~~~~~~~~~~~~~~~~~~~~~~~~
4
5 Lexers for Smalltalk and related languages.
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, include, bygroups, default
12from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
13 Number, Punctuation
14
15__all__ = ['SmalltalkLexer', 'NewspeakLexer']
16
17
18class SmalltalkLexer(RegexLexer):
19 """
20 For Smalltalk syntax.
21 Contributed by Stefan Matthias Aust.
22 Rewritten by Nils Winter.
23 """
24 name = 'Smalltalk'
25 url = 'http://www.smalltalk.org/'
26 filenames = ['*.st']
27 aliases = ['smalltalk', 'squeak', 'st']
28 mimetypes = ['text/x-smalltalk']
29 version_added = '0.10'
30
31 tokens = {
32 'root': [
33 (r'(<)(\w+:)(.*?)(>)', bygroups(Text, Keyword, Text, Text)),
34 include('squeak fileout'),
35 include('whitespaces'),
36 include('method definition'),
37 (r'(\|)([\w\s]*)(\|)', bygroups(Operator, Name.Variable, Operator)),
38 include('objects'),
39 (r'\^|\:=|\_', Operator),
40 # temporaries
41 (r'[\]({}.;!]', Text),
42 ],
43 'method definition': [
44 # Not perfect can't allow whitespaces at the beginning and the
45 # without breaking everything
46 (r'([a-zA-Z]+\w*:)(\s*)(\w+)',
47 bygroups(Name.Function, Text, Name.Variable)),
48 (r'^(\b[a-zA-Z]+\w*\b)(\s*)$', bygroups(Name.Function, Text)),
49 (r'^([-+*/\\~<>=|&!?,@%]+)(\s*)(\w+)(\s*)$',
50 bygroups(Name.Function, Text, Name.Variable, Text)),
51 ],
52 'blockvariables': [
53 include('whitespaces'),
54 (r'(:)(\s*)(\w+)',
55 bygroups(Operator, Text, Name.Variable)),
56 (r'\|', Operator, '#pop'),
57 default('#pop'), # else pop
58 ],
59 'literals': [
60 (r"'(''|[^'])*'", String, 'afterobject'),
61 (r'\$.', String.Char, 'afterobject'),
62 (r'#\(', String.Symbol, 'parenth'),
63 (r'\)', Text, 'afterobject'),
64 (r'(\d+r)?-?\d+(\.\d+)?(e-?\d+)?', Number, 'afterobject'),
65 ],
66 '_parenth_helper': [
67 include('whitespaces'),
68 (r'(\d+r)?-?\d+(\.\d+)?(e-?\d+)?', Number),
69 (r'[-+*/\\~<>=|&#!?,@%\w:]+', String.Symbol),
70 # literals
71 (r"'(''|[^'])*'", String),
72 (r'\$.', String.Char),
73 (r'#*\(', String.Symbol, 'inner_parenth'),
74 ],
75 'parenth': [
76 # This state is a bit tricky since
77 # we can't just pop this state
78 (r'\)', String.Symbol, ('root', 'afterobject')),
79 include('_parenth_helper'),
80 ],
81 'inner_parenth': [
82 (r'\)', String.Symbol, '#pop'),
83 include('_parenth_helper'),
84 ],
85 'whitespaces': [
86 # skip whitespace and comments
87 (r'\s+', Text),
88 (r'"(""|[^"])*"', Comment),
89 ],
90 'objects': [
91 (r'\[', Text, 'blockvariables'),
92 (r'\]', Text, 'afterobject'),
93 (r'\b(self|super|true|false|nil|thisContext)\b',
94 Name.Builtin.Pseudo, 'afterobject'),
95 (r'\b[A-Z]\w*(?!:)\b', Name.Class, 'afterobject'),
96 (r'\b[a-z]\w*(?!:)\b', Name.Variable, 'afterobject'),
97 (r'#("(""|[^"])*"|[-+*/\\~<>=|&!?,@%]+|[\w:]+)',
98 String.Symbol, 'afterobject'),
99 include('literals'),
100 ],
101 'afterobject': [
102 (r'! !$', Keyword, '#pop'), # squeak chunk delimiter
103 include('whitespaces'),
104 (r'\b(ifTrue:|ifFalse:|whileTrue:|whileFalse:|timesRepeat:)',
105 Name.Builtin, '#pop'),
106 (r'\b(new\b(?!:))', Name.Builtin),
107 (r'\:=|\_', Operator, '#pop'),
108 (r'\b[a-zA-Z]+\w*:', Name.Function, '#pop'),
109 (r'\b[a-zA-Z]+\w*', Name.Function),
110 (r'\w+:?|[-+*/\\~<>=|&!?,@%]+', Name.Function, '#pop'),
111 (r'\.', Punctuation, '#pop'),
112 (r';', Punctuation),
113 (r'[\])}]', Text),
114 (r'[\[({]', Text, '#pop'),
115 ],
116 'squeak fileout': [
117 # Squeak fileout format (optional)
118 (r'^"(""|[^"])*"!', Keyword),
119 (r"^'(''|[^'])*'!", Keyword),
120 (r'^(!)(\w+)( commentStamp: )(.*?)( prior: .*?!\n)(.*?)(!)',
121 bygroups(Keyword, Name.Class, Keyword, String, Keyword, Text, Keyword)),
122 (r"^(!)(\w+(?: class)?)( methodsFor: )('(?:''|[^'])*')(.*?!)",
123 bygroups(Keyword, Name.Class, Keyword, String, Keyword)),
124 (r'^(\w+)( subclass: )(#\w+)'
125 r'(\s+instanceVariableNames: )(.*?)'
126 r'(\s+classVariableNames: )(.*?)'
127 r'(\s+poolDictionaries: )(.*?)'
128 r'(\s+category: )(.*?)(!)',
129 bygroups(Name.Class, Keyword, String.Symbol, Keyword, String, Keyword,
130 String, Keyword, String, Keyword, String, Keyword)),
131 (r'^(\w+(?: class)?)(\s+instanceVariableNames: )(.*?)(!)',
132 bygroups(Name.Class, Keyword, String, Keyword)),
133 (r'(!\n)(\].*)(! !)$', bygroups(Keyword, Text, Keyword)),
134 (r'! !$', Keyword),
135 ],
136 }
137
138
139class NewspeakLexer(RegexLexer):
140 """
141 For Newspeak syntax.
142 """
143 name = 'Newspeak'
144 url = 'http://newspeaklanguage.org/'
145 filenames = ['*.ns2']
146 aliases = ['newspeak', ]
147 mimetypes = ['text/x-newspeak']
148 version_added = '1.1'
149
150 tokens = {
151 'root': [
152 (r'\b(Newsqueak2)\b', Keyword.Declaration),
153 (r"'[^']*'", String),
154 (r'\b(class)(\s+)(\w+)(\s*)',
155 bygroups(Keyword.Declaration, Text, Name.Class, Text)),
156 (r'\b(mixin|self|super|private|public|protected|nil|true|false)\b',
157 Keyword),
158 (r'(\w+\:)(\s*)([a-zA-Z_]\w+)',
159 bygroups(Name.Function, Text, Name.Variable)),
160 (r'(\w+)(\s*)(=)',
161 bygroups(Name.Attribute, Text, Operator)),
162 (r'<\w+>', Comment.Special),
163 include('expressionstat'),
164 include('whitespace')
165 ],
166
167 'expressionstat': [
168 (r'(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float),
169 (r'\d+', Number.Integer),
170 (r':\w+', Name.Variable),
171 (r'(\w+)(::)', bygroups(Name.Variable, Operator)),
172 (r'\w+:', Name.Function),
173 (r'\w+', Name.Variable),
174 (r'\(|\)', Punctuation),
175 (r'\[|\]', Punctuation),
176 (r'\{|\}', Punctuation),
177
178 (r'(\^|\+|\/|~|\*|<|>|=|@|%|\||&|\?|!|,|-|:)', Operator),
179 (r'\.|;', Punctuation),
180 include('whitespace'),
181 include('literals'),
182 ],
183 'literals': [
184 (r'\$.', String),
185 (r"'[^']*'", String),
186 (r"#'[^']*'", String.Symbol),
187 (r"#\w+:?", String.Symbol),
188 (r"#(\+|\/|~|\*|<|>|=|@|%|\||&|\?|!|,|-)+", String.Symbol)
189 ],
190 'whitespace': [
191 (r'\s+', Text),
192 (r'"[^"]*"', Comment)
193 ],
194 }