xmk 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3821a25480789beeb46b176c9c0b3b51fa285e9245e45e9787f508c0b82804f5
4
+ data.tar.gz: 554630e394e1fbd0a4f905f938f1e4cd1311f1189394cd493e9d590d2d79ac71
5
+ SHA512:
6
+ metadata.gz: 4db33b8cd0340b19c8526aad808f77fb645d48aa98d550867879cc775aa918ddeb6c138f05caf218871536d73664b549ceb161705842d742cba974cf52980063
7
+ data.tar.gz: e7834f5626629dd5cef037bbf67701c541e86a1a52ad4ae7b2a20349ea07b271cb227e7d7ea41c9947d2cbff1e6b7d82ec064df7a768a4f7df1b667a7b6b8558
data/bin/xmk ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'xmk'
3
+ Xmk.main()
data/lib/xmk/lexer.rb ADDED
@@ -0,0 +1,224 @@
1
+ class Lexer
2
+
3
+ def initialize
4
+ @tokens = Array.new
5
+ @start = 0
6
+ @current = -1
7
+ @line = 0
8
+ @string = ""
9
+ @file = nil
10
+ @in_label = false
11
+ @assignment_type = ""
12
+
13
+ if File.exists?("xmkfile")
14
+ @file = File.open("xmkfile", "r")
15
+ else
16
+ puts "No xmkfile found"
17
+ end
18
+ end
19
+
20
+ def scan
21
+ while (c = self.advance) != nil
22
+ @start = @current
23
+ case c
24
+ when "#" # comment
25
+ self.end_line
26
+ when "+" # append/declaration
27
+ if self.peek == "="
28
+ @assignment_type = "append"
29
+ @tokens.push(Token.new(Token::ADD, '+=', @line))
30
+ self.advance(2)
31
+ self.get_value(Token::VAL)
32
+ end
33
+ when "=" # declaration
34
+ @assignment_type = "assign"
35
+ @tokens.push(Token.new(Token::SET, '=', @line))
36
+ self.advance
37
+ self.get_value(Token::VAL)
38
+ when "@" # target
39
+ loop do
40
+ c = self.advance
41
+ c = self.handle_comment_backslash(c)
42
+ break if self.terminates?(c)
43
+ end
44
+ @tokens.push(Token.new(Token::TAR, @string[@start+1 .. @current].strip,
45
+ @line))
46
+ when "$" # cmd
47
+ self.get_value(Token::CMD)
48
+ when "_" # label
49
+ self.handle_label
50
+ else
51
+ if self.terminates?(c)
52
+ @in_label = false
53
+ @tokens.push(Token.new(Token::LBR, c, @line))
54
+ elsif c.match?(/[A-Z]/) # var
55
+ loop do
56
+ self.advance
57
+ break unless self.peek.match?(/[A-Z_]/)
58
+ end
59
+ @tokens.push(Token.new(
60
+ Token::VAR, @string[@start .. @current].strip, @line))
61
+ elsif c.match?(/[a-z]/) # cmd / label / platform
62
+ if @in_label # cmd
63
+ self.get_value(Token::CMD)
64
+ else # label || platform
65
+ if self.find("@") # platform
66
+ loop do
67
+ self.advance
68
+ break if self.peek == ":"
69
+ end
70
+ @tokens.push(Token.new(Token::PLAT, @string[@start .. @current],
71
+ @line))
72
+ parse_target = false
73
+ loop do
74
+ c = self.advance
75
+ if c == "@"
76
+ self.advance
77
+ parse_target = true
78
+ @start = @current
79
+ end
80
+ if (c == " " || self.terminates?(c)) && parse_target
81
+ parse_target = false
82
+ @tokens.push(Token.new(Token::TARLINK,
83
+ @string[@start .. @current-1], @line))
84
+ end
85
+ break if self.terminates?(c)
86
+ end
87
+ else
88
+ self.handle_label
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ @file.close
95
+ @tokens.push(Token.new(Token::LBR, "", @line))
96
+ @tokens.push(Token.new(Token::EOF, "end_of_file", @line))
97
+ @tokens
98
+ end
99
+
100
+ def find(c)
101
+ # check if char occurs before comment or newline
102
+ res = false
103
+ i = 0
104
+ backup = Array.new
105
+ loop do
106
+ d = self.consume
107
+ backup.push(d)
108
+ i += 1
109
+ res = true if d == c
110
+ break if d == "#"
111
+ break if self.terminates?(d)
112
+ end
113
+ i.times do |j|
114
+ self.push_back(backup[i-j-1])
115
+ end
116
+ res
117
+ end
118
+
119
+ def get_value(t)
120
+ if self.terminates?(@string[@current])
121
+ return @tokens.push(Token.new(Token::LBR, "", @line))
122
+ end
123
+ @start = @current
124
+ loop do
125
+ c = self.advance
126
+ c = self.handle_comment_backslash(c)
127
+ break if self.terminates?(c)
128
+ end
129
+ str = @string[@start .. @current-1].rstrip
130
+ if t == Token::VAL && @assignment_type == "assign"
131
+ str = str.lstrip
132
+ end
133
+ @tokens.push(Token.new(t, str, @line))
134
+ end
135
+
136
+ def handle_label
137
+ @in_label = true
138
+ loop do
139
+ self.advance
140
+ break if self.peek == ":"
141
+ end
142
+ @tokens.push(Token.new(Token::LAB, @string[@start .. @current],
143
+ @line))
144
+ self.end_line
145
+ end
146
+
147
+ def handle_comment_backslash(c)
148
+ if c == "\\"
149
+ loop do
150
+ if self.terminates?(self.peek)
151
+ @string[@current] = self.consume
152
+ break
153
+ else
154
+ @string[@current] = self.consume
155
+ end
156
+ end
157
+ while self.terminates?(@string[@current])
158
+ @string[@current] = self.consume
159
+ end
160
+ while @string[@current] == " "
161
+ @string[@current] = self.consume
162
+ end
163
+ elsif c == "#"
164
+ loop do
165
+ @string[@current] = self.consume
166
+ if self.terminates?(self.peek)
167
+ @string[@current] = self.consume
168
+ c = @string[@current]
169
+ break
170
+ end
171
+ end
172
+ end
173
+ c
174
+ end
175
+
176
+ def advance(n = 1)
177
+ c = ""
178
+ i = n
179
+ @current += n
180
+ loop do
181
+ c = self.consume
182
+ @string << c if c
183
+ i -= 1
184
+ break if i == 0
185
+ end
186
+ c
187
+ end
188
+
189
+ def peek
190
+ c = self.consume
191
+ self.push_back(c)
192
+ c
193
+ end
194
+
195
+ def consume
196
+ if self.terminates?(@string[@current])
197
+ @line += 1
198
+ end
199
+ @file.getc
200
+ end
201
+
202
+ def push_back(c)
203
+ if self.terminates?(c)
204
+ @line -= 1
205
+ end
206
+ @file.ungetc(c)
207
+ end
208
+
209
+ def terminates?(c)
210
+ return true if c == "\n"
211
+ return true if c.nil?
212
+ return true if c == "\r"
213
+ return false
214
+ end
215
+
216
+ def end_line
217
+ # strips away characters until line break
218
+ loop do
219
+ c = self.advance
220
+ break if self.terminates?(c)
221
+ end
222
+ end
223
+
224
+ end
data/lib/xmk/parser.rb ADDED
@@ -0,0 +1,347 @@
1
+ require 'pathname'
2
+
3
+ class Parser
4
+
5
+
6
+ def initialize(tokens)
7
+ @failsafe = false
8
+ @state = State::ROOT
9
+ @tokens = tokens
10
+ @env_stack = Array.new
11
+ @env_stack.push(Hash.new)
12
+ @i = 0
13
+ @i_memory = 0
14
+ @env_label = ""
15
+ @env_name = "root"
16
+ @plat_name = ""
17
+ @target_state = Hash.new
18
+ @target_name = ""
19
+ end
20
+
21
+ def parse
22
+ loop do
23
+ case @tokens[@i].type
24
+ when Token::LBR
25
+ if @env_label != ""
26
+ if Xmk.options[:verbose]
27
+ Xmk.print("leave label: #{@env_label}")
28
+ end
29
+ @env_label = ""
30
+ end
31
+ if @tokens[@i+1].type == Token::PLAT && @state == State::PLAT
32
+ self.leave_platform
33
+ end
34
+ if @tokens[@i+1].type == Token::TAR && @state == State::TAR
35
+ self.leave_target
36
+ end
37
+ when Token::PLAT
38
+ @plat_name = @tokens[@i].lexeme
39
+ case @state
40
+ when State::ROOT
41
+ loop do
42
+ @i += 1
43
+ break if @tokens[@i+1].type == Token::EOF
44
+ end
45
+ when State::TAR
46
+ allow = false
47
+ if Xmk.platforms.empty? || Xmk.platforms.include?(@plat_name)
48
+ while @tokens[@i+1].type == Token::TARLINK
49
+ @i += 1
50
+ if @env_name == @tokens[@i].lexeme
51
+ allow = true
52
+ break
53
+ end
54
+ end
55
+ end
56
+ if @target_state[:"#{@env_name}"].include?(@plat_name)
57
+ # leave target
58
+ allow = false
59
+ self.leave_target
60
+ @state = State::QUIT
61
+ loop do
62
+ @i += 1
63
+ break if @tokens[@i+1].type == Token::EOF
64
+ end
65
+ end
66
+ if allow
67
+ @src_files = Array.new
68
+ @obj_files = Array.new
69
+ @compilation_flags = Array.new
70
+ if Xmk.options[:verbose]
71
+ Xmk.print("ENTER PLATFORM: #{@plat_name}")
72
+ end
73
+ @env_memory = @env_name
74
+ @env_name = @plat_name
75
+ @state = State::PLAT
76
+ self.env_stack_grow
77
+ else
78
+ unless @state == State::QUIT
79
+ unless @failsafe
80
+ @i = @i_memory
81
+ @failsafe = true
82
+ else
83
+ loop do
84
+ @i += 1
85
+ break if @tokens[@i+1].type == Token::PLAT
86
+ end
87
+ end
88
+ end
89
+ end
90
+ when State::PLAT
91
+ Xmk.error("Invalid state.", @tokens[@i].line)
92
+ end
93
+ when Token::TAR
94
+ case @state
95
+ when State::ROOT, State::TAR
96
+ if @state == State::TAR
97
+ self.leave_target
98
+ end
99
+ if Xmk.targets.empty? || Xmk.targets.include?(@tokens[@i].lexeme)
100
+ if Xmk.options[:verbose]
101
+ Xmk.print("@ENTER TARGET: #{@tokens[@i].lexeme}")
102
+ end
103
+ @target_name = @tokens[@i].lexeme
104
+ @target_state[:"#{@tokens[@i].lexeme}"] = Array.new
105
+ @env_name = @tokens[@i].lexeme
106
+ @state = State::TAR
107
+ self.env_stack_grow
108
+ else
109
+ loop do
110
+ @i += 1
111
+ if @tokens[@i+1].type == Token::EOF
112
+ break
113
+ end
114
+ break if @tokens[@i+1].type == Token::TAR
115
+ end
116
+ end
117
+ when State::TAR
118
+ when State::PLAT
119
+ Xmk.error("Hierarchy violation. Target scope required" <<
120
+ " to appear before platform scope.", $tokens[@i].line)
121
+ end
122
+ when Token::CMD
123
+ if @env_label == "_rule"
124
+ @src_files = Array.new
125
+ @obj_files = Array.new
126
+ @compilation_flags = Array.new
127
+ @env_stack.last[:SRC].split.each do |src|
128
+ Dir.glob(src) do |f|
129
+ @src_files.push(f)
130
+ i = File.dirname(f).index('/')
131
+ i = File.dirname(f).length if i.nil?
132
+ @obj_files.push(File.join(@env_stack.last[:OBJ],
133
+ File.dirname(f)[i .. -1],
134
+ "#{File.basename(f,'.*')}.o"))
135
+ end
136
+ end
137
+ @obj_files.each do |o|
138
+ Pathname(o).dirname.mkpath
139
+ @compilation_flags.push(!File.exist?(o))
140
+ end
141
+ @src_files.each_with_index do |src, i|
142
+ next if @compilation_flags[i]
143
+ recipe = Parser.run_print_verbose_only(
144
+ var_replace(@tokens[@i].lexeme).gsub('$~', src), true)
145
+ recipe.slice!(0..recipe.index(':'))
146
+ recipe.gsub!("\n", '')
147
+ recipe.gsub!("\\", '')
148
+ recipe.squeeze(" ")
149
+ recipe = recipe[1..-1]
150
+ recipe = recipe.split(" ")
151
+ objmtime = File.mtime(@obj_files[i])
152
+ recipe.each do |dep|
153
+ if File.mtime(dep) > objmtime
154
+ @compilation_flags[i] = (File.mtime(dep) > objmtime)
155
+ end
156
+ end
157
+ end
158
+ elsif @env_label == "_compile"
159
+ @src_files.each_with_index do |src, i|
160
+ if @compilation_flags[i]
161
+ if Xmk.options[:verbose]
162
+ Xmk.print("Recompilation for #{src}.")
163
+ end
164
+ Parser.run(var_replace(@tokens[@i].lexeme.gsub('$~', src).gsub(
165
+ '$&', @obj_files[i])))
166
+ end
167
+ end
168
+ elsif @env_label == "_link"
169
+ Parser.run(var_replace(@tokens[@i].lexeme.gsub('$&&',
170
+ @obj_files.join(" "))))
171
+ else
172
+ Parser.run(var_replace(@tokens[@i].lexeme))
173
+ end
174
+ when Token::LAB
175
+ if Xmk.options[:verbose]
176
+ Xmk.print("attempt label: #{@tokens[@i].lexeme}")
177
+ end
178
+ unless @tokens[@i].lexeme[0] == "_"
179
+ unless Xmk.labels.include?(@tokens[@i].lexeme)
180
+ # if not included skip to end of label
181
+ if Xmk.options[:verbose]
182
+ Xmk.print("skip label: #{@tokens[@i].lexeme}")
183
+ end
184
+ loop do
185
+ @i += 1
186
+ break if @tokens[@i].type == Token::LBR
187
+ end
188
+ else
189
+ if Xmk.options[:verbose]
190
+ Xmk.print("enter label: #{@tokens[@i].lexeme}")
191
+ end
192
+ @env_label = @tokens[@i].lexeme
193
+ end
194
+ else
195
+ if @tokens[@i].lexeme == "_plat" && @state == State::TAR
196
+ @i_memory = @i
197
+ loop do
198
+ @i += 1
199
+ if @tokens[@i].type == Token::EOF
200
+ @i = @i_memory
201
+ break
202
+ end
203
+ break if @tokens[@i+1].type == Token::PLAT
204
+ end
205
+ else
206
+ if Xmk.options[:verbose]
207
+ Xmk.print("enter label: #{@tokens[@i].lexeme}")
208
+ end
209
+ @env_label = @tokens[@i].lexeme
210
+ end
211
+ end
212
+ when Token::VAR
213
+ unless @tokens[@i+1].type == Token::SET ||
214
+ @tokens[@i+1].type == Token::ADD
215
+ Xmk.error("Expect '=' or '+=' after variable",
216
+ @tokens[@i].line)
217
+ end
218
+ when Token::SET, Token::ADD
219
+ unless @tokens[@i-1].type == Token::VAR &&
220
+ @tokens[@i+1].type == Token::VAL
221
+ Xmk.error("Expect <VAR>=|+=<VALUE>.",
222
+ @tokens[@i].line)
223
+ else
224
+ case @tokens[@i].type
225
+ when Token::SET
226
+ self.set_var
227
+ when Token::ADD
228
+ if @env_stack.last.has_key?(:"#{@tokens[@i-1].lexeme}")
229
+ self.add_var
230
+ else
231
+ self.set_var
232
+ end
233
+ end
234
+ end
235
+ if Xmk.options[:verbose]
236
+ Xmk.print("$(#{@tokens[@i-1].lexeme}): " <<
237
+ " #{@env_stack.last[:"#{@tokens[@i-1].lexeme}"]}")
238
+ end
239
+ when Token::EOF
240
+ if @state == State::PLAT
241
+ self.leave_platform
242
+ else
243
+ break
244
+ end
245
+ else
246
+ end
247
+ @i += 1
248
+ end
249
+ end
250
+
251
+ def leave_platform
252
+ i = @i
253
+ loop do
254
+ i -= 1
255
+ break if @tokens[i].type == Token::PLAT
256
+ end
257
+ if Xmk.options[:verbose]
258
+ Xmk.print("LEAVE PLATFORM: #{@tokens[i].lexeme}")
259
+ end
260
+ @state = State::TAR
261
+ @env_name = @env_memory
262
+ @env_stack.pop
263
+ @target_state[:"#{@env_name}"].push(@tokens[i].lexeme)
264
+ loop do
265
+ if @tokens[@i].type == Token::EOF
266
+ @i = @i_memory
267
+ break
268
+ end
269
+ break if @tokens[@i+1].type == Token::PLAT
270
+ @i += 1
271
+ end
272
+ end
273
+
274
+ def leave_target
275
+ if Xmk.options[:verbose]
276
+ i = @i
277
+ loop do
278
+ i -= 1
279
+ break if @tokens[i].type == Token::TAR
280
+ end
281
+ Xmk.print("@LEAVE TARGET: #{@tokens[i].lexeme}")
282
+ end
283
+ @env_name = "root"
284
+ @state = State::ROOT
285
+ @env_stack.pop
286
+ end
287
+
288
+ def env_stack_grow
289
+ h = Hash.new
290
+ @env_stack.last.each do |k,v|
291
+ h[k] = v.dup
292
+ end
293
+ @env_stack.push(h)
294
+ end
295
+
296
+ def set_var
297
+ @env_stack.last[:"#{@tokens[@i-1].lexeme}"] =
298
+ self.var_replace(@tokens[@i+1].lexeme)
299
+ end
300
+
301
+ def add_var
302
+ @env_stack.last[:"#{@tokens[@i-1].lexeme}"] <<
303
+ self.var_replace(@tokens[@i+1].lexeme)
304
+ end
305
+
306
+ def var_replace(str)
307
+ str2 = str.dup
308
+ str2.scan(/\${1}\({1}([A-Z_]+){1}\)/) do |m|
309
+ if @env_stack.last.has_key?(:"#{m[0]}")
310
+ str.gsub!("$(#{m[0]})", @env_stack.last[:"#{m[0]}"])
311
+ else
312
+ Xmk.error("Variable #{m[0]} not defined",
313
+ @tokens[@i+1].line)
314
+ end
315
+ end
316
+ str.gsub('$@', @target_name).gsub('$!',@plat_name)
317
+ end
318
+
319
+ def self.run(cmd, noprint = false)
320
+ unless Xmk.options[:disable_cmd]
321
+ if Xmk.options[:verbose]
322
+ Xmk.print("execute #{cmd}")
323
+ end
324
+ v = %x{#{cmd}}
325
+ return v if v.strip.empty?
326
+ puts v unless noprint
327
+ return v
328
+ end
329
+ nil
330
+ end
331
+
332
+ def self.run_print_verbose_only(cmd, noprint = false)
333
+ unless Xmk.options[:disable_cmd]
334
+ if Xmk.options[:verbose]
335
+ Xmk.print("execute #{cmd}")
336
+ end
337
+ v = %x{#{cmd}}
338
+ return v if v.strip.empty?
339
+ if Xmk.options[:verbose]
340
+ puts v unless noprint
341
+ end
342
+ return v
343
+ end
344
+ nil
345
+ end
346
+
347
+ end
data/lib/xmk/token.rb ADDED
@@ -0,0 +1,29 @@
1
+ class Token
2
+ attr_reader :type, :lexeme, :literal, :line
3
+
4
+ VAR = 0 # variable
5
+ SET = 1 # set var =
6
+ ADD = 2 # append var +=
7
+ TAR = 3 # target
8
+ WS = 4 # whitespace
9
+ CMD = 5 # commang
10
+ LAB = 6 # label
11
+ VAL = 7 # value
12
+ PLAT = 8 # platform
13
+ TARLINK = 9 # platform-target link
14
+ LBR = 10 # linebreak
15
+
16
+ EOF =9999
17
+
18
+
19
+ def initialize(type, lexeme, line)
20
+ @type = type
21
+ @lexeme = lexeme
22
+ @line = line
23
+ end
24
+
25
+ def to_s
26
+ "#{@type} #{@lexeme} #{@line}"
27
+ end
28
+
29
+ end
data/lib/xmk.rb ADDED
@@ -0,0 +1,87 @@
1
+ require 'optparse'
2
+ require 'xmk/token.rb'
3
+ require 'xmk/lexer.rb'
4
+ require 'xmk/parser.rb'
5
+
6
+ module State
7
+
8
+ ROOT = 0
9
+ TAR = 1
10
+ PLAT = 2
11
+ QUIT = 3
12
+
13
+ end
14
+
15
+ module Xmk
16
+
17
+ def self.main()
18
+ @@targets = Array.new
19
+ @@platforms = Array.new
20
+ @@labels = Array.new
21
+ options = {}
22
+ options[:verbose] = false
23
+ options[:skipcomp] = false
24
+ options[:disable_cmd] = false
25
+ optparse = OptionParser.new do|opts|
26
+ opts.banner = "Usage: xmk [options]"
27
+ opts.on('-h', '--help', 'Display this screen') do
28
+ puts opts
29
+ exit
30
+ end
31
+
32
+ opts.on('-t', '--target TARGET', 'Target') do |arg|
33
+ @@targets.push(arg)
34
+ end
35
+
36
+ opts.on('-p', '--platform PLATFORM', 'Platform') do |arg|
37
+ @@platforms.push(arg)
38
+ end
39
+
40
+ opts.on('-l', '--label LABEL', 'Label') do |arg|
41
+ @@labels.push(arg)
42
+ end
43
+
44
+ opts.on('-v', '--verbose', 'Verbose mode') do
45
+ options[:verbose] = true
46
+ end
47
+ opts.on('-s', '--skip-compilation', 'Skip compilation') do
48
+ options[:skipcomp] = true
49
+ end
50
+ opts.on('-d', '--disable-commands', 'Disable commands') do
51
+ options[:disable_cmd] = true
52
+ end
53
+ end
54
+ optparse.parse!
55
+
56
+ @@options = options
57
+
58
+ lexer = Lexer.new
59
+ Parser.new(lexer.scan).parse
60
+ end
61
+
62
+ def self.error(msg, l)
63
+ puts "#{msg} on line #{l}"
64
+ exit(65)
65
+ end
66
+
67
+ def self.options
68
+ @@options
69
+ end
70
+
71
+ def self.labels
72
+ @@labels
73
+ end
74
+
75
+ def self.platforms
76
+ @@platforms
77
+ end
78
+
79
+ def self.targets
80
+ @@targets
81
+ end
82
+
83
+ def self.print(msg)
84
+ puts "xmk: #{msg}"
85
+ end
86
+
87
+ end
data/syntax/rouge.rb ADDED
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ class Xmk < RegexLexer
7
+ title 'xmk'
8
+ desc 'XMake Prototype'
9
+ tag 'xmk'
10
+ filenames 'xmkfile', '*.xmk'
11
+
12
+ state :whitespace do
13
+ rule %r/\s+/m, Text::Whitespace
14
+ end
15
+
16
+ #rule %r/(?<==).*(?=($|\\|#))/, Name
17
+
18
+ state :root do
19
+ mixin :whitespace
20
+
21
+ rule /#.*/, Comment::Single
22
+ rule %r/[A-Z]+(?=\+|\=){1}/, Text
23
+ rule %r/[+=]/, Operator
24
+ #rule %r/(?<=\=).*$/, String
25
+ rule %r/[_a-z0-9]+:/, Str
26
+ rule %r/@[a-z0-9]+/, Name::Function
27
+ rule %r/\$(~|!|@|&{1,2})/, Name::Variable
28
+ rule %r/\$\([A-Z]+\)/, Name
29
+ rule %r/\\/, Str::Escape
30
+ rule %r/.*/, Name
31
+ end
32
+
33
+ end
34
+ end
35
+ end
data/syntax/vim.vim ADDED
@@ -0,0 +1,35 @@
1
+ " detect file
2
+ autocmd BufRead,BufNewFile xmkfile setlocal filetype=xmk
3
+
4
+ " syntax highlighting
5
+ syn keyword xmkKeyword _cmd _plat _pre _post _link _compile _rule
6
+
7
+ syntax match xmkComment "\v#.*$"
8
+ "syntax match xmkVar "\v[A-Z]"
9
+ "syntax match xmkVar "\v[A-Z]+((\+|\=){1})\@="
10
+ syntax match xmkVar "\v\zs[A-Z]+\ze(\+|\=){1}"
11
+ syntax match xmkTarget "\v\@[a-z]+"
12
+ syntax match xmkKeyword "\v[a-z0-9]+:{1}"
13
+ syntax match xmkReplace "\v\$\("
14
+ syntax match xmkReplace "\v\("
15
+ syntax match xmkReplace "\v\)"
16
+ syntax match xmkReplace "\v\$\@"
17
+ syntax match xmkReplace "\v\$\!"
18
+ syntax match xmkReplace "\v\$\~"
19
+ syntax match xmkReplace "\v\$\&"
20
+ syntax match xmkReplace "\v\$\&\&"
21
+ syntax match xmkNewlineTerm "\v\\"
22
+ syntax match xmkOperator "\v\+"
23
+ syntax match xmkOperator "\v\="
24
+
25
+ highlight link xmkComment Comment
26
+ highlight link xmkVar Type
27
+ highlight link xmkTarget Structure
28
+ highlight link xmkKeyword Keyword
29
+ highlight link xmkReplace Type
30
+ highlight link xmkNewlineTerm Delimiter
31
+ highlight link xmkOperator Operator
32
+
33
+ hi Structure ctermfg=darkcyan
34
+ hi Type ctermfg=darkmagenta
35
+ hi Operator ctermfg=darkred
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xmk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - ryu
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-03-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'A working protorype for yet another build automation tool inspired by
14
+ Make. '
15
+ email: ryu@tohya.net
16
+ executables:
17
+ - xmk
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/xmk
22
+ - lib/xmk.rb
23
+ - lib/xmk/lexer.rb
24
+ - lib/xmk/parser.rb
25
+ - lib/xmk/token.rb
26
+ - syntax/rouge.rb
27
+ - syntax/vim.vim
28
+ homepage: https://www.tohya.net
29
+ licenses:
30
+ - MIT
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 2.7.6.2
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: Build automation tool for C and C++ projects
52
+ test_files: []