File: objective_c.rb

package info (click to toggle)
ruby-rugments 1.0.0~beta8-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 820 kB
  • sloc: ruby: 10,293; makefile: 2
file content (188 lines) | stat: -rw-r--r-- 4,503 bytes parent folder | download | duplicates (3)
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
module Rugments
  module Lexers
    load_const :C, 'c.rb'

    class ObjectiveC < C
      tag 'objective_c'
      title 'Objective-C'
      desc 'an extension of C commonly used to write Apple software'
      aliases 'objc'
      filenames '*.m', '*.h'

      mimetypes 'text/x-objective_c', 'application/x-objective_c'

      def self.at_keywords
        @at_keywords ||= %w(
          selector private protected public encode synchronized try
          throw catch finally end property synthesize dynamic optional
          interface implementation import
        )
      end

      def self.at_builtins
        @at_builtins ||= %w(true false YES NO)
      end

      def self.builtins
        @builtins ||= %w(YES NO nil)
      end

      def self.analyze_text(text)
        return 1 if text =~ /@(end|implementation|protocol|property)\b/

        id = /[a-z$_][a-z0-9$_]*/i
        return 0.4 if text =~ %r{
          \[ \s* #{id} \s+
          (?:
            #{id} \s* \]
            | #{id}? :
          )
                }x
        return 0.4 if text.include? '@"'
      end

      id = /[a-z$_][a-z0-9$_]*/i

      prepend :statements do
        rule /@"/, Str, :string
        rule /@'(\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|\\.|[^\\'\n]')/,
             Str::Char
        rule /@(\d+[.]\d*|[.]\d+|\d+)e[+-]?\d+l?/i,
             Num::Float
        rule /@(\d+[.]\d*|[.]\d+|\d+f)f?/i, Num::Float
        rule /@0x\h+[lL]?/, Num::Hex
        rule /@0[0-7]+l?/i, Num::Oct
        rule /@\d+l?/, Num::Integer
        rule /\bin\b/, Keyword

        rule /@(?:interface|implementation)\b/ do
          token Keyword
          goto :classname
        end

        rule /@(?:class|protocol)\b/ do
          token Keyword
          goto :forward_classname
        end

        rule /@([[:alnum:]]+)/ do |m|
          if self.class.at_keywords.include? m[1]
            token Keyword
          elsif self.class.at_builtins.include? m[1]
            token Name::Builtin
          else
            token Error
          end
        end

        rule /[?]/, Punctuation, :ternary
        rule /\[/,  Punctuation, :message
      end

      state :ternary do
        rule /:/, Punctuation, :pop!
        mixin :statements
      end

      state :message_shared do
        rule /\]/, Punctuation, :pop!
        rule /;/, Error

        mixin :statement
      end

      state :message do
        rule /(#{id})(\s*)(:)/ do
          groups(Name::Function, Text, Punctuation)
          goto :message_with_args
        end

        rule /(#{id})(\s*)(\])/ do
          groups(Name::Function, Text, Punctuation)
          pop!
        end

        mixin :message_shared
      end

      state :message_with_args do
        rule /(#{id})(\s*)(:)/ do
          groups(Name::Function, Text, Punctuation)
        end

        mixin :message_shared
      end

      state :classname do
        mixin :whitespace

        rule /(#{id})(\s*)(:)(\s*)(#{id})/ do
          groups(Name::Class, Text,
                 Punctuation, Text,
                 Name::Class)
          pop!
        end

        rule /(#{id})(\s*)([(])(\s*)(#{id})(\s*)([)])/ do
          groups(Name::Class, Text,
                 Punctuation, Text,
                 Name::Label, Text,
                 Punctuation)
        end

        rule id, Name::Class, :pop!
      end

      state :forward_classname do
        mixin :whitespace

        rule /(#{id})(\s*)(,)(\s*)/ do
          groups(Name::Class, Text, Punctuation, Text)
          push
        end

        rule /(#{id})(\s*)(;?)/ do
          groups(Name::Class, Text, Punctuation)
          pop!
        end
      end

      prepend :root do
        rule %r{
          ([-+])(\s*)
          ([(].*?[)])?(\s*)
          (?=#{id}:?)
                }ix do |m|
          token Keyword, m[1]; token Text, m[2]
          recurse m[3]; token Text, m[4]
          push :method_definition
        end
      end

      state :method_definition do
        rule /,/, Punctuation
        rule /[.][.][.]/, Punctuation
        rule /([(].*?[)])(#{id})/ do |m|
          recurse m[1]; token Name::Variable, m[2]
        end

        rule /(#{id})(\s*)(:)/m do
          groups(Name::Function, Text, Punctuation)
        end

        rule /;/, Punctuation, :pop!

        rule /{/ do
          token Punctuation
          goto :function
        end

        mixin :inline_whitespace
        rule %r{//.*?\n}, Comment::Single
        rule /\s+/m, Text

        rule(//) { pop! }
      end
    end
  end
end