summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/clean.rb
blob: 031cd6177686c95c689d7ed00e9823475a0da668 (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
# -*- 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