summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/rouge-4.7.0/lib/rouge/lexers/lasso.rb
blob: cad38e9ec224e0c139c2a3ae6f4154fb67b3b42b (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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# -*- coding: utf-8 -*- #
# frozen_string_literal: true

require 'yaml'

module Rouge
  module Lexers
    class Lasso < TemplateLexer
      title "Lasso"
      desc "The Lasso programming language (lassosoft.com)"
      tag 'lasso'
      aliases 'lassoscript'
      filenames '*.lasso', '*.lasso[89]'
      mimetypes 'text/x-lasso', 'text/html+lasso', 'application/x-httpd-lasso'

      option :start_inline, 'Whether to start inline instead of requiring <?lasso or ['

      def self.detect?(text)
        return true if text.shebang?('lasso9')
        return true if text =~ /\A.*?<\?(lasso(script)?|=)/
      end

      def initialize(*)
        super

        @start_inline = bool_option(:start_inline)
      end

      def start_inline?
        @start_inline
      end

      start do
        push :lasso if start_inline?
      end

      # self-modifying method that loads the keywords file
      def self.keywords
        Kernel::load File.join(Lexers::BASE_DIR, 'lasso/keywords.rb')
        keywords
      end

      id = /[a-z_][\w.]*/i

      state :root do
        rule %r/^#![ \S]+lasso9\b/, Comment::Preproc, :lasso
        rule(/(?=\[|<)/) { push :delimiters }
        rule %r/\s+/, Text::Whitespace
        rule(//) { push :delimiters; push :lassofile }
      end

      state :delimiters do
        rule %r/\[no_square_brackets\]/, Comment::Preproc, :nosquarebrackets
        rule %r/\[noprocess\]/, Comment::Preproc, :noprocess
        rule %r/\[/, Comment::Preproc, :squarebrackets
        rule %r/<\?(lasso(script)?|=)/i, Comment::Preproc, :anglebrackets
        rule(/([^\[<]|<!--.*?-->|<(script|style).*?\2>|<(?!\?(lasso(script)?|=)))+/im) { delegate parent }
      end

      state :nosquarebrackets do
        rule %r/\[noprocess\]/, Comment::Preproc, :noprocess
        rule %r/<\?(lasso(script)?|=)/i, Comment::Preproc, :anglebrackets
        rule(/([^\[<]|<!--.*?-->|<(script|style).*?\2>|<(?!\?(lasso(script)?|=))|\[(?!noprocess))+/im) { delegate parent }
      end

      state :noprocess do
        rule %r(\[/noprocess\]), Comment::Preproc, :pop!
        rule(%r(([^\[]|\[(?!/noprocess))+)i) { delegate parent }
      end

      state :squarebrackets do
        rule %r/\]/, Comment::Preproc, :pop!
        mixin :lasso
      end

      state :anglebrackets do
        rule %r/\?>/, Comment::Preproc, :pop!
        mixin :lasso
      end

      state :lassofile do
        rule %r/\]|\?>/, Comment::Preproc, :pop!
        mixin :lasso
      end

      state :whitespacecomments do
        rule %r/\s+/, Text
        rule %r(//.*?\n), Comment::Single
        rule %r(/\*\*!.*?\*/)m, Comment::Doc
        rule %r(/\*.*?\*/)m, Comment::Multiline
      end

      state :lasso do
        mixin :whitespacecomments

        # literals
        rule %r/\d*\.\d+(e[+-]?\d+)?/i, Num::Float
        rule %r/0x[\da-f]+/i, Num::Hex
        rule %r/\d+/, Num::Integer
        rule %r/(infinity|NaN)\b/i, Num
        rule %r/'[^'\\]*(\\.[^'\\]*)*'/m, Str::Single
        rule %r/"[^"\\]*(\\.[^"\\]*)*"/m, Str::Double
        rule %r/`[^`]*`/m, Str::Backtick

        # names
        rule %r/\$#{id}/, Name::Variable
        rule %r/#(#{id}|\d+\b)/, Name::Variable::Instance
        rule %r/(\.\s*)('#{id}')/ do
          groups Name::Builtin::Pseudo, Name::Variable::Class
        end
        rule %r/(self)(\s*->\s*)('#{id}')/i do
          groups Name::Builtin::Pseudo, Operator, Name::Variable::Class
        end
        rule %r/(\.\.?\s*)(#{id}(=(?!=))?)/ do
          groups Name::Builtin::Pseudo, Name::Other
        end
        rule %r/(->\\?\s*|&\s*)(#{id}(=(?!=))?)/ do
          groups Operator, Name::Other
        end
        rule %r/(?<!->)(self|inherited|currentcapture|givenblock)\b/i, Name::Builtin::Pseudo
        rule %r/-(?!infinity)#{id}/i, Name::Attribute
        rule %r/::\s*#{id}/, Name::Label

        # definitions
        rule %r/(define)(\s+)(#{id})(\s*=>\s*)(type|trait|thread)\b/i do
          groups Keyword::Declaration, Text, Name::Class, Operator, Keyword
        end
        rule %r((define)(\s+)(#{id})(\s*->\s*)(#{id}=?|[-+*/%]))i do
          groups Keyword::Declaration, Text, Name::Class, Operator, Name::Function
          push :signature
        end
        rule %r/(define)(\s+)(#{id})/i do
          groups Keyword::Declaration, Text, Name::Function
          push :signature
        end
        rule %r((public|protected|private|provide)(\s+)((#{id}=?|[-+*/%])(?=\s*\()))i do
          groups Keyword, Text, Name::Function
          push :signature
        end
        rule %r/(public|protected|private|provide)(\s+)(#{id})/i do
          groups Keyword, Text, Name::Function
        end

        # keywords
        rule %r/(true|false|none|minimal|full|all|void)\b/i, Keyword::Constant
        rule %r/(local|var|variable|global|data(?=\s))\b/i, Keyword::Declaration
        rule %r/(#{id})(\s+)(in)\b/i do
          groups Name, Text, Keyword
        end
        rule %r/(let|into)(\s+)(#{id})/i do
          groups Keyword, Text, Name
        end

        # other
        rule %r/,/, Punctuation, :commamember
        rule %r/(and|or|not)\b/i, Operator::Word
        rule %r/(#{id})(\s*::\s*#{id})?(\s*=(?!=|>))/ do
          groups Name, Name::Label, Operator
        end

        rule %r((/?)([\w.]+)) do |m|
          name = m[2].downcase

          if m[1] != ''
            token Punctuation, m[1]
          end

          if name == 'namespace_using'
            token Keyword::Namespace, m[2]
          elsif self.class.keywords[:exceptions].include? name
            token Name::Exception, m[2]
          elsif self.class.keywords[:types].include? name
            token Keyword::Type, m[2]
          elsif self.class.keywords[:traits].include? name
            token Name::Decorator, m[2]
          elsif self.class.keywords[:keywords].include? name
            token Keyword, m[2]
          elsif self.class.keywords[:builtins].include? name
            token Name::Builtin, m[2]
          else
            token Name::Other, m[2]
          end
        end

        rule %r/(=)(n?bw|n?ew|n?cn|lte?|gte?|n?eq|n?rx|ft)\b/i do
          groups Operator, Operator::Word
        end
        rule %r(:=|[-+*/%=<>&|!?\\]+), Operator
        rule %r/[{}():;,@^]/, Punctuation
      end

      state :signature do
        rule %r/\=>/, Operator, :pop!
        rule %r/\)/, Punctuation, :pop!
        rule %r/[(,]/, Punctuation, :parameter
        mixin :lasso
      end

      state :parameter do
        rule %r/\)/, Punctuation, :pop!
        rule %r/-?#{id}/, Name::Attribute, :pop!
        rule %r/\.\.\./, Name::Builtin::Pseudo
        mixin :lasso
      end

      state :commamember do
        rule %r((#{id}=?|[-+*/%])(?=\s*(\(([^()]*\([^()]*\))*[^\)]*\)\s*)?(::[\w.\s]+)?=>)), Name::Function, :signature
        mixin :whitespacecomments
        rule %r//, Text, :pop!
      end

    end
  end
end