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
|
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
module Rouge
module Lexers
class Clean < RegexLexer
title "Clean"
desc "The Clean programming language (clean.cs.ru.nl)"
tag 'clean'
filenames '*.dcl', '*.icl'
def self.keywords
@keywords ||= Set.new %w(
if otherwise
let in
with where
case of
infix infixl infixr
class instance
generic derive
special
implementation definition system module
from import qualified as
dynamic
code inline foreign export ccall stdcall
)
end
# These are literal patterns common to the ABC intermediate language and
# Clean. Clean has more extensive literal patterns (see :basic below).
state :common_literals do
rule %r/'(?:[^'\\]|\\(?:x[0-9a-fA-F]+|\d+|.))'/, Str::Char
rule %r/[+~-]?\d+\.\d+(?:E[+-]?\d+)?\b/, Num::Float
rule %r/[+~-]?\d+E[+-]?\d+\b/, Num::Float
rule %r/[+~-]?\d+/, Num::Integer
rule %r/"/, Str::Double, :string
end
state :basic do
rule %r/\s+/m, Text::Whitespace
rule %r/\/\/\*.*/, Comment::Doc
rule %r/\/\/.*/, Comment::Single
rule %r/\/\*\*/, Comment::Doc, :comment_doc
rule %r/\/\*/, Comment::Multiline, :comment
rule %r/[+~-]?0[0-7]+/, Num::Oct
rule %r/[+~-]?0x[0-9a-fA-F]+/, Num::Hex
mixin :common_literals
rule %r/(\[)(\s*)(')(?=.*?'\])/ do
groups Punctuation, Text::Whitespace, Str::Single, Punctuation
push :charlist
end
end
# nested commenting
state :comment_doc do
rule %r/\*\//, Comment::Doc, :pop!
rule %r/\/\/.*/, Comment::Doc # Singleline comments in multiline comments are skipped
rule %r/\/\*/, Comment::Doc, :comment
rule %r/[^*\/]+/, Comment::Doc
rule %r/[*\/]/, Comment::Doc
end
# This is the same as the above, but with Multiline instead of Doc
state :comment do
rule %r/\*\//, Comment::Multiline, :pop!
rule %r/\/\/.*/, Comment::Multiline # Singleline comments in multiline comments are skipped
rule %r/\/\*/, Comment::Multiline, :comment
rule %r/[^*\/]+/, Comment::Multiline
rule %r/[*\/]/, Comment::Multiline
end
state :root do
mixin :basic
rule %r/code(\s+inline)?\s*{/, Comment::Preproc, :abc
rule %r/_*[a-z][\w`]*/ do |m|
if self.class.keywords.include?(m[0])
token Keyword
else
token Name
end
end
rule %r/_*[A-Z][\w`]*/ do |m|
if m[0]=='True' || m[0]=='False'
token Keyword::Constant
else
token Keyword::Type
end
end
rule %r/[^\w\s`]/, Punctuation
rule %r/_\b/, Punctuation
end
state :escapes do
rule %r/\\x[0-9a-fA-F]{1,2}/i, Str::Escape
rule %r/\\d\d{0,3}/i, Str::Escape
rule %r/\\0[0-7]{0,3}/, Str::Escape
rule %r/\\[0-7]{1,3}/, Str::Escape
rule %r/\\[nrfbtv\\"']/, Str::Escape
end
state :string do
rule %r/"/, Str::Double, :pop!
mixin :escapes
rule %r/[^\\"]+/, Str::Double
end
state :charlist do
rule %r/(')(\])/ do
groups Str::Single, Punctuation
pop!
end
mixin :escapes
rule %r/[^\\']/, Str::Single
end
state :abc_basic do
rule %r/\s+/, Text::Whitespace
rule %r/\|.*/, Comment::Single
mixin :common_literals
end
# The ABC intermediate language can be included, similar to C's inline
# assembly. For some information about ABC, see:
# https://en.wikipedia.org/wiki/Clean_(programming_language)#The_ABC-Machine
state :abc do
mixin :abc_basic
rule %r/}/, Comment::Preproc, :pop!
rule %r/\.\w*/, Keyword, :abc_rest_of_line
rule %r/[\w]+/, Name::Builtin, :abc_rest_of_line
end
state :abc_rest_of_line do
rule %r/\n/, Text::Whitespace, :pop!
rule %r/}/ do
token Comment::Preproc
pop!
pop!
end
mixin :abc_basic
rule %r/\S+/, Name
end
end
end
end
|