Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pygments/lexers/dylan.py: 58%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

72 statements  

1""" 

2 pygments.lexers.dylan 

3 ~~~~~~~~~~~~~~~~~~~~~ 

4 

5 Lexers for the Dylan language. 

6 

7 :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. 

8 :license: BSD, see LICENSE for details. 

9""" 

10 

11import re 

12 

13from pygments.lexer import Lexer, RegexLexer, bygroups, do_insertions, \ 

14 default, line_re 

15from pygments.token import Comment, Operator, Keyword, Name, String, \ 

16 Number, Punctuation, Generic, Literal, Whitespace 

17 

18__all__ = ['DylanLexer', 'DylanConsoleLexer', 'DylanLidLexer'] 

19 

20 

21class DylanLexer(RegexLexer): 

22 """ 

23 For the Dylan language. 

24 """ 

25 

26 name = 'Dylan' 

27 url = 'http://www.opendylan.org/' 

28 aliases = ['dylan'] 

29 filenames = ['*.dylan', '*.dyl', '*.intr'] 

30 mimetypes = ['text/x-dylan'] 

31 version_added = '0.7' 

32 

33 flags = re.IGNORECASE 

34 

35 builtins = { 

36 'subclass', 'abstract', 'block', 'concrete', 'constant', 'class', 

37 'compiler-open', 'compiler-sideways', 'domain', 'dynamic', 

38 'each-subclass', 'exception', 'exclude', 'function', 'generic', 

39 'handler', 'inherited', 'inline', 'inline-only', 'instance', 

40 'interface', 'import', 'keyword', 'library', 'macro', 'method', 

41 'module', 'open', 'primary', 'required', 'sealed', 'sideways', 

42 'singleton', 'slot', 'thread', 'variable', 'virtual'} 

43 

44 keywords = { 

45 'above', 'afterwards', 'begin', 'below', 'by', 'case', 'cleanup', 

46 'create', 'define', 'else', 'elseif', 'end', 'export', 'finally', 

47 'for', 'from', 'if', 'in', 'let', 'local', 'otherwise', 'rename', 

48 'select', 'signal', 'then', 'to', 'unless', 'until', 'use', 'when', 

49 'while'} 

50 

51 operators = { 

52 '~', '+', '-', '*', '|', '^', '=', '==', '~=', '~==', '<', '<=', 

53 '>', '>=', '&', '|'} 

54 

55 functions = { 

56 'abort', 'abs', 'add', 'add!', 'add-method', 'add-new', 'add-new!', 

57 'all-superclasses', 'always', 'any?', 'applicable-method?', 'apply', 

58 'aref', 'aref-setter', 'as', 'as-lowercase', 'as-lowercase!', 

59 'as-uppercase', 'as-uppercase!', 'ash', 'backward-iteration-protocol', 

60 'break', 'ceiling', 'ceiling/', 'cerror', 'check-type', 'choose', 

61 'choose-by', 'complement', 'compose', 'concatenate', 'concatenate-as', 

62 'condition-format-arguments', 'condition-format-string', 'conjoin', 

63 'copy-sequence', 'curry', 'default-handler', 'dimension', 'dimensions', 

64 'direct-subclasses', 'direct-superclasses', 'disjoin', 'do', 

65 'do-handlers', 'element', 'element-setter', 'empty?', 'error', 'even?', 

66 'every?', 'false-or', 'fill!', 'find-key', 'find-method', 'first', 

67 'first-setter', 'floor', 'floor/', 'forward-iteration-protocol', 

68 'function-arguments', 'function-return-values', 

69 'function-specializers', 'gcd', 'generic-function-mandatory-keywords', 

70 'generic-function-methods', 'head', 'head-setter', 'identity', 

71 'initialize', 'instance?', 'integral?', 'intersection', 

72 'key-sequence', 'key-test', 'last', 'last-setter', 'lcm', 'limited', 

73 'list', 'logand', 'logbit?', 'logior', 'lognot', 'logxor', 'make', 

74 'map', 'map-as', 'map-into', 'max', 'member?', 'merge-hash-codes', 

75 'min', 'modulo', 'negative', 'negative?', 'next-method', 

76 'object-class', 'object-hash', 'odd?', 'one-of', 'pair', 'pop', 

77 'pop-last', 'positive?', 'push', 'push-last', 'range', 'rank', 

78 'rcurry', 'reduce', 'reduce1', 'remainder', 'remove', 'remove!', 

79 'remove-duplicates', 'remove-duplicates!', 'remove-key!', 

80 'remove-method', 'replace-elements!', 'replace-subsequence!', 

81 'restart-query', 'return-allowed?', 'return-description', 

82 'return-query', 'reverse', 'reverse!', 'round', 'round/', 

83 'row-major-index', 'second', 'second-setter', 'shallow-copy', 

84 'signal', 'singleton', 'size', 'size-setter', 'slot-initialized?', 

85 'sort', 'sort!', 'sorted-applicable-methods', 'subsequence-position', 

86 'subtype?', 'table-protocol', 'tail', 'tail-setter', 'third', 

87 'third-setter', 'truncate', 'truncate/', 'type-error-expected-type', 

88 'type-error-value', 'type-for-copy', 'type-union', 'union', 'values', 

89 'vector', 'zero?'} 

90 

91 valid_name = '\\\\?[\\w!&*<>|^$%@\\-+~?/=]+' 

92 

93 def get_tokens_unprocessed(self, text): 

94 for index, token, value in RegexLexer.get_tokens_unprocessed(self, text): 

95 if token is Name: 

96 lowercase_value = value.lower() 

97 if lowercase_value in self.builtins: 

98 yield index, Name.Builtin, value 

99 continue 

100 if lowercase_value in self.keywords: 

101 yield index, Keyword, value 

102 continue 

103 if lowercase_value in self.functions: 

104 yield index, Name.Builtin, value 

105 continue 

106 if lowercase_value in self.operators: 

107 yield index, Operator, value 

108 continue 

109 yield index, token, value 

110 

111 tokens = { 

112 'root': [ 

113 # Whitespace 

114 (r'\s+', Whitespace), 

115 

116 # single line comment 

117 (r'//.*?\n', Comment.Single), 

118 

119 # lid header 

120 (r'([a-z0-9-]+)(:)([ \t]*)(.*(?:\n[ \t].+)*)', 

121 bygroups(Name.Attribute, Operator, Whitespace, String)), 

122 

123 default('code') # no header match, switch to code 

124 ], 

125 'code': [ 

126 # Whitespace 

127 (r'\s+', Whitespace), 

128 

129 # single line comment 

130 (r'(//.*?)(\n)', bygroups(Comment.Single, Whitespace)), 

131 

132 # multi-line comment 

133 (r'/\*', Comment.Multiline, 'comment'), 

134 

135 # strings and characters 

136 (r'"', String, 'string'), 

137 (r"'(\\.|\\[0-7]{1,3}|\\x[a-f0-9]{1,2}|[^\\\'\n])'", String.Char), 

138 

139 # binary integer 

140 (r'#b[01]+', Number.Bin), 

141 

142 # octal integer 

143 (r'#o[0-7]+', Number.Oct), 

144 

145 # floating point 

146 (r'[-+]?(\d*\.\d+(e[-+]?\d+)?|\d+(\.\d*)?e[-+]?\d+)', Number.Float), 

147 

148 # decimal integer 

149 (r'[-+]?\d+', Number.Integer), 

150 

151 # hex integer 

152 (r'#x[0-9a-f]+', Number.Hex), 

153 

154 # Macro parameters 

155 (r'(\?' + valid_name + ')(:)' 

156 r'(token|name|variable|expression|body|case-body|\*)', 

157 bygroups(Name.Tag, Operator, Name.Builtin)), 

158 (r'(\?)(:)(token|name|variable|expression|body|case-body|\*)', 

159 bygroups(Name.Tag, Operator, Name.Builtin)), 

160 (r'\?' + valid_name, Name.Tag), 

161 

162 # Punctuation 

163 (r'(=>|::|#\(|#\[|##|\?\?|\?=|\?|[(){}\[\],.;])', Punctuation), 

164 

165 # Most operators are picked up as names and then re-flagged. 

166 # This one isn't valid in a name though, so we pick it up now. 

167 (r':=', Operator), 

168 

169 # Pick up #t / #f before we match other stuff with #. 

170 (r'#[tf]', Literal), 

171 

172 # #"foo" style keywords 

173 (r'#"', String.Symbol, 'keyword'), 

174 

175 # #rest, #key, #all-keys, etc. 

176 (r'#[a-z0-9-]+', Keyword), 

177 

178 # required-init-keyword: style keywords. 

179 (valid_name + ':', Keyword), 

180 

181 # class names 

182 ('<' + valid_name + '>', Name.Class), 

183 

184 # define variable forms. 

185 (r'\*' + valid_name + r'\*', Name.Variable.Global), 

186 

187 # define constant forms. 

188 (r'\$' + valid_name, Name.Constant), 

189 

190 # everything else. We re-flag some of these in the method above. 

191 (valid_name, Name), 

192 ], 

193 'comment': [ 

194 (r'[^*/]+', Comment.Multiline), 

195 (r'/\*', Comment.Multiline, '#push'), 

196 (r'\*/', Comment.Multiline, '#pop'), 

197 (r'[*/]', Comment.Multiline) 

198 ], 

199 'keyword': [ 

200 (r'"', String.Symbol, '#pop'), 

201 (r'[^\\"]+', String.Symbol), # all other characters 

202 ], 

203 'string': [ 

204 (r'"', String, '#pop'), 

205 (r'\\([\\abfnrtv"\']|x[a-f0-9]{2,4}|[0-7]{1,3})', String.Escape), 

206 (r'[^\\"\n]+', String), # all other characters 

207 (r'\\\n', String), # line continuation 

208 (r'\\', String), # stray backslash 

209 ] 

210 } 

211 

212 

213class DylanLidLexer(RegexLexer): 

214 """ 

215 For Dylan LID (Library Interchange Definition) files. 

216 """ 

217 

218 name = 'DylanLID' 

219 aliases = ['dylan-lid', 'lid'] 

220 filenames = ['*.lid', '*.hdp'] 

221 mimetypes = ['text/x-dylan-lid'] 

222 url = 'http://www.opendylan.org/' 

223 version_added = '1.6' 

224 flags = re.IGNORECASE 

225 

226 tokens = { 

227 'root': [ 

228 # Whitespace 

229 (r'\s+', Whitespace), 

230 

231 # single line comment 

232 (r'(//.*?)(\n)', bygroups(Comment.Single, Whitespace)), 

233 

234 # lid header 

235 (r'(.*?)(:)([ \t]*)(.*(?:\n[ \t].+)*)', 

236 bygroups(Name.Attribute, Operator, Whitespace, String)), 

237 ] 

238 } 

239 

240 

241class DylanConsoleLexer(Lexer): 

242 """ 

243 For Dylan interactive console output. 

244 

245 This is based on a copy of the ``RubyConsoleLexer``. 

246 """ 

247 name = 'Dylan session' 

248 aliases = ['dylan-console', 'dylan-repl'] 

249 filenames = ['*.dylan-console'] 

250 mimetypes = ['text/x-dylan-console'] 

251 url = 'http://www.opendylan.org/' 

252 version_added = '1.6' 

253 _example = 'dylan-console/console.dylan-console' 

254 

255 _prompt_re = re.compile(r'\?| ') 

256 

257 def get_tokens_unprocessed(self, text): 

258 dylexer = DylanLexer(**self.options) 

259 

260 curcode = '' 

261 insertions = [] 

262 for match in line_re.finditer(text): 

263 line = match.group() 

264 m = self._prompt_re.match(line) 

265 if m is not None: 

266 end = m.end() 

267 insertions.append((len(curcode), 

268 [(0, Generic.Prompt, line[:end])])) 

269 curcode += line[end:] 

270 else: 

271 if curcode: 

272 yield from do_insertions(insertions, 

273 dylexer.get_tokens_unprocessed(curcode)) 

274 curcode = '' 

275 insertions = [] 

276 yield match.start(), Generic.Output, line 

277 if curcode: 

278 yield from do_insertions(insertions, 

279 dylexer.get_tokens_unprocessed(curcode))