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
|
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
module Rouge
module Lexers
class Meson < RegexLexer
title "Meson"
desc "Meson's specification language (mesonbuild.com)"
tag 'meson'
filenames 'meson.build', 'meson_options.txt'
mimetypes 'text/x-meson'
def self.keywords
@keywords ||= %w(
continue break elif else endif
if true false foreach endforeach
)
end
def self.builtin_variables
@builtin_variables ||= %w(
meson host_machine build_machine target_machine
)
end
def self.builtin_functions
@builtin_functions ||= %w(
add_global_arguments add_project_arguments
add_global_link_arguments add_project_link_arguments add_test_setup add_languages
alias_target assert benchmark both_libraries build_target configuration_data configure_file
custom_target declare_dependency dependency disabler environment error executable
generator gettext get_option get_variable files find_library find_program
include_directories import install_data install_headers install_man install_subdir
is_disabler is_variable jar join_paths library message option project
run_target run_command set_variable subdir subdir_done
subproject summary shared_library shared_module static_library test vcs_tag warning
)
end
identifier = /[[:alpha:]_][[:alnum:]_]*/
def current_string
@current_string ||= StringRegister.new
end
state :root do
rule %r/\n+/m, Text
rule %r/[^\S\n]+/, Text
rule %r(#(.*)?\n?), Comment::Single
rule %r/[\[\]{}:(),;.]/, Punctuation
rule %r/\\\n/, Text
rule %r/\\/, Text
rule %r/(in|and|or|not)\b/, Operator::Word
rule %r/[-+\/*%=<>]=?|!=/, Operator
rule %r/([f]?)('''|['])/i do |m|
groups Str::Affix, Str
current_string.register type: m[1].downcase, delim: m[2]
push :generic_string
end
rule %r/(?<!\.)#{identifier}\b\s*(?=\()/ do |m|
if self.class.builtin_functions.include? m[0]
token Name::Builtin
else
token Name
end
end
rule %r/(?<!\.)#{identifier}(?!\s*?:)/ do |m|
if self.class.builtin_variables.include? m[0]
token Name::Builtin
elsif self.class.keywords.include? m[0]
token Keyword
else
token Name
end
end
rule identifier, Name
rule %r/0b(_?[0-1])+/i, Num::Bin
rule %r/0o(_?[0-7])+/i, Num::Oct
rule %r/0x(_?[a-f0-9])+/i, Num::Hex
rule %r/([1-9](_?[0-9])*|0(_?0)*)/, Num::Integer
end
state :generic_string do
rule %r/[^'\\\@]+/, Str
rule %r/'''|[']/ do |m|
token Str
if current_string.delim? m[0]
current_string.remove
pop!
end
end
rule %r/(?=\\)/, Str, :generic_escape
rule %r/\@/ do |m|
if current_string.type? "f"
token Str::Interpol
push :generic_interpol
else
token Str
end
end
end
state :generic_escape do
rule %r(\\
( [\\abfnrtv']
| N{[a-zA-Z][a-zA-Z ]+[a-zA-Z]}
| u[a-fA-F0-9]{4}
| U[a-fA-F0-9]{8}
| x[a-fA-F0-9]{2}
| [0-7]{1,3}
)
)x do
token(Str::Escape)
pop!
end
rule %r/\\./, Str, :pop!
end
state :generic_interpol do
rule %r/[^\@]+/ do |m|
recurse m[0]
end
rule %r/\@/, Str::Interpol, :pop!
end
class StringRegister < Array
def delim?(delim)
self.last[1] == delim
end
def register(type: "u", delim: "'")
self.push [type, delim]
end
def remove
self.pop
end
def type?(type)
self.last[0].include? type
end
end
private_constant :StringRegister
end
end
end
|