lat 0.1.1 → 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 +4 -4
- data/bin/lat +2 -2
- data/compiler/codegen.rb +49 -3
- data/compiler/compile.rb +18 -18
- data/compiler/parser.rb +106 -75
- data/compiler/tokenizer.rb +30 -20
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79c0178cf5e3b3e1168af97aec3a318b082b25c43a2835464682f6bdcdf545f7
|
|
4
|
+
data.tar.gz: ef5b003a8c15b86ffd3575844232bfe909b084844587a114312b35d5d76e113b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a8377175fe6c7cb97521c4a51c6a7a5b2ebe0aa1a9bb9c3a0f19299fdd2e7d9f08fc9c5efe86098b716063ea656293d4612fc5575cfb39481d81fadd2282210b
|
|
7
|
+
data.tar.gz: 50e003a2f76a40427759f032ce0da3355422c481d6089f99d2deb1f1d384ca137478ffc0b14dd64c74ab3c856edc09c19ac99dc8b3665214d608e6b847ab39b7
|
data/bin/lat
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
$LOAD_PATH.unshift File.join(__dir__, "../compiler")
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
$LOAD_PATH.unshift File.join(__dir__, "../compiler")
|
|
3
3
|
require_relative "../compiler/compile"
|
data/compiler/codegen.rb
CHANGED
|
@@ -7,9 +7,8 @@ class Generator
|
|
|
7
7
|
case node
|
|
8
8
|
|
|
9
9
|
when ImportNode
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
]
|
|
10
|
+
"require(\"#{node.location}\")"
|
|
11
|
+
|
|
13
12
|
when ClassNode
|
|
14
13
|
out = []
|
|
15
14
|
out << "local #{node.name} = {}"
|
|
@@ -90,6 +89,50 @@ class Generator
|
|
|
90
89
|
body_code
|
|
91
90
|
]
|
|
92
91
|
|
|
92
|
+
when ForNode
|
|
93
|
+
body_code =
|
|
94
|
+
if node.body.is_a?(Array)
|
|
95
|
+
node.body.map{ |n| generate (n) }.join("\n")
|
|
96
|
+
else
|
|
97
|
+
generate(node.body)
|
|
98
|
+
end
|
|
99
|
+
increment = ", #{node.step.nil? ? "" : generate(node.step)}"
|
|
100
|
+
"for %s = %s, %s%s do\n %s \nend" % [
|
|
101
|
+
generate(node.var),
|
|
102
|
+
generate(node.start),
|
|
103
|
+
generate(node.stop),
|
|
104
|
+
increment,
|
|
105
|
+
body_code
|
|
106
|
+
]
|
|
107
|
+
|
|
108
|
+
when ForPairNode
|
|
109
|
+
body_code =
|
|
110
|
+
if node.body.is_a?(Array)
|
|
111
|
+
node.body.map{ |n| generate (n) }.join("\n")
|
|
112
|
+
else
|
|
113
|
+
generate(node.body)
|
|
114
|
+
end
|
|
115
|
+
"for %s, %s in pairs(%s) do\n %s \nend" % [
|
|
116
|
+
node.key,
|
|
117
|
+
node.val,
|
|
118
|
+
generate(node.t),
|
|
119
|
+
body_code
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
when ForPairNode
|
|
123
|
+
body_code =
|
|
124
|
+
if node.body.is_a?(Array)
|
|
125
|
+
node.body.map{ |n| generate (n) }.join("\n")
|
|
126
|
+
else
|
|
127
|
+
generate(node.body)
|
|
128
|
+
end
|
|
129
|
+
"for %s, %s in ipairs(%s) do\n %s \nend" % [
|
|
130
|
+
generate(node.index),
|
|
131
|
+
generate(node.val),
|
|
132
|
+
generate(node.t),
|
|
133
|
+
body_code
|
|
134
|
+
]
|
|
135
|
+
|
|
93
136
|
when SwitchNode
|
|
94
137
|
compiled = ""
|
|
95
138
|
node.cases.each_with_index do |c, i|
|
|
@@ -169,6 +212,9 @@ class Generator
|
|
|
169
212
|
when IntegerNode
|
|
170
213
|
node.value.to_s
|
|
171
214
|
|
|
215
|
+
when FloatNode
|
|
216
|
+
node.value.to_s
|
|
217
|
+
|
|
172
218
|
when StringNode
|
|
173
219
|
"\"%s\"" % [
|
|
174
220
|
node.value
|
data/compiler/compile.rb
CHANGED
|
@@ -19,8 +19,10 @@ def detect_os
|
|
|
19
19
|
:linux
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
OS = detect_os
|
|
23
|
+
|
|
22
24
|
def love_installed?
|
|
23
|
-
if
|
|
25
|
+
if OS == :windows
|
|
24
26
|
common_paths = [
|
|
25
27
|
"C:/Program Files/LOVE/love.exe",
|
|
26
28
|
"C:/Program Files (x86)/LOVE/love.exe",
|
|
@@ -33,15 +35,14 @@ def love_installed?
|
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def install_love
|
|
36
|
-
os = detect_os
|
|
37
38
|
puts "[lat] Love2D not found, attempting to install"
|
|
38
|
-
print "Do you want to install
|
|
39
|
+
print "Do you want to install LOVE2D? (y/n)"
|
|
39
40
|
answer = $stdin.gets.chomp.downcase
|
|
40
41
|
|
|
41
42
|
if %w[y yes].include?(answer.downcase)
|
|
42
43
|
puts "installing love..."
|
|
43
44
|
|
|
44
|
-
case
|
|
45
|
+
case OS
|
|
45
46
|
when :arch
|
|
46
47
|
system("sudo pacman -S --noconfirm love")
|
|
47
48
|
when :debian
|
|
@@ -52,11 +53,11 @@ def install_love
|
|
|
52
53
|
if system("which brew > /dev/null 2>&1")
|
|
53
54
|
system("brew install love")
|
|
54
55
|
else
|
|
55
|
-
puts "[lat] Homebrew not found. Install
|
|
56
|
+
puts "[lat] Homebrew not found. Install LOVE2D from https://love2d.org"
|
|
56
57
|
exit 1
|
|
57
58
|
end
|
|
58
59
|
when :windows
|
|
59
|
-
puts "[lat] Please install
|
|
60
|
+
puts "[lat] Please install LOVE2D from https://love2d.org"
|
|
60
61
|
puts "[lat] Set LOVE_PATH to the love.exe location:"
|
|
61
62
|
puts '[lat] setx LOVE_PATH "C:\\Program Files\\LOVE\\love.exe"'
|
|
62
63
|
else
|
|
@@ -74,22 +75,19 @@ end
|
|
|
74
75
|
def find_love
|
|
75
76
|
install_love unless love_installed?
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
"love",
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
candidates.each do |path|
|
|
85
|
-
return path if system("where #{path} >nul 2>&1") || File.exist?(path.to_s)
|
|
78
|
+
if OS == :windows
|
|
79
|
+
candidates = [ENV["LOVE_PATH"], "C:/Program Files/LOVE/love.exe", "C:/Program Files (x86)/LOVE/love.exe"].compact
|
|
80
|
+
candidates.each { |p| return p if File.exist?(p) }
|
|
81
|
+
else
|
|
82
|
+
["love", "love2d"].each do |cmd|
|
|
83
|
+
return cmd if system("which #{cmd} > /dev/null 2>&1")
|
|
84
|
+
end
|
|
86
85
|
end
|
|
87
86
|
|
|
88
87
|
puts "Error: LOVE2D not found. Install it from https://love2d.org or set LOVE_PATH env variable."
|
|
89
88
|
exit 1
|
|
90
89
|
end
|
|
91
90
|
skip_run = false
|
|
92
|
-
love = find_love()
|
|
93
91
|
|
|
94
92
|
if ARGV[0] == "run"
|
|
95
93
|
latcDir = File.join(Dir.pwd, ".latc")
|
|
@@ -102,6 +100,7 @@ if ARGV[0] == "run"
|
|
|
102
100
|
puts "Error: .latc exists but no main.lua found"
|
|
103
101
|
exit 1
|
|
104
102
|
end
|
|
103
|
+
love = find_love()
|
|
105
104
|
exec(love, latcDir)
|
|
106
105
|
elsif ARGV[0] == "build"
|
|
107
106
|
ARGV.shift
|
|
@@ -110,7 +109,7 @@ end
|
|
|
110
109
|
inputFile = ARGV[0] || "main.lat"
|
|
111
110
|
|
|
112
111
|
unless File.exist?(inputFile)
|
|
113
|
-
puts "Error:
|
|
112
|
+
puts "Error: file `#{inputFile}` not found"
|
|
114
113
|
exit 1
|
|
115
114
|
end
|
|
116
115
|
|
|
@@ -139,6 +138,7 @@ generated = Generator.new.generate(tree)
|
|
|
139
138
|
# puts generated
|
|
140
139
|
File.open(outputFile, 'w') { |file| file.write(generated)}
|
|
141
140
|
|
|
142
|
-
|
|
141
|
+
|
|
142
|
+
exec(find_love(), latcDir) unless skip_run
|
|
143
143
|
|
|
144
144
|
# ln -s "$(pwd)/compiler/compile.rb" /usr/local/bin/lat
|
data/compiler/parser.rb
CHANGED
|
@@ -6,9 +6,16 @@ IfNode = Struct.new(:condition, :body, :elif_blocks, :else_body)
|
|
|
6
6
|
ElifBlock = Struct.new(:condition, :body)
|
|
7
7
|
|
|
8
8
|
ImportNode = Struct.new(:location)
|
|
9
|
+
|
|
9
10
|
WhileNode = Struct.new(:statement, :body)
|
|
11
|
+
ForNode = Struct.new(:var, :start, :stop, :step, :body)
|
|
12
|
+
ForPairNode = Struct.new(:key, :val, :t, :body)
|
|
13
|
+
ForIPairNode = Struct.new(:index, :val, :t, :body)
|
|
14
|
+
|
|
10
15
|
IntegerNode = Struct.new(:value)
|
|
16
|
+
FloatNode = Struct.new(:value)
|
|
11
17
|
StringNode = Struct.new(:value)
|
|
18
|
+
|
|
12
19
|
CallNode = Struct.new(:name, :arg_expr)
|
|
13
20
|
VarRefNode = Struct.new(:value)
|
|
14
21
|
VarAssignNode = Struct.new(:name, :value)
|
|
@@ -89,6 +96,12 @@ class Parser
|
|
|
89
96
|
parse_if
|
|
90
97
|
elsif peek(:while)
|
|
91
98
|
parse_while
|
|
99
|
+
elsif peek(:for)
|
|
100
|
+
parse_for
|
|
101
|
+
elsif peek(:forpairs)
|
|
102
|
+
parse_forpairs
|
|
103
|
+
elsif peek(:foripairs)
|
|
104
|
+
parse_foripairs
|
|
92
105
|
elsif peek(:switch)
|
|
93
106
|
parse_switch
|
|
94
107
|
elsif peek(:print)
|
|
@@ -142,14 +155,8 @@ class Parser
|
|
|
142
155
|
consume(:def)
|
|
143
156
|
name = "#{name}:#{consume(:identifier).value}"
|
|
144
157
|
args = parse_args
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
body = []
|
|
158
|
+
body = parse_block
|
|
148
159
|
|
|
149
|
-
until peek(:end)
|
|
150
|
-
body << parse_statement
|
|
151
|
-
skip_newlines
|
|
152
|
-
end
|
|
153
160
|
consume(:end)
|
|
154
161
|
ClassDefNode.new(name, args, body)
|
|
155
162
|
end
|
|
@@ -165,13 +172,7 @@ class Parser
|
|
|
165
172
|
name = consume(:identifier).value
|
|
166
173
|
args = parse_args
|
|
167
174
|
|
|
168
|
-
|
|
169
|
-
body = []
|
|
170
|
-
|
|
171
|
-
until peek(:end)
|
|
172
|
-
body << parse_statement
|
|
173
|
-
skip_newlines
|
|
174
|
-
end
|
|
175
|
+
body = parse_block
|
|
175
176
|
consume(:end)
|
|
176
177
|
DefNode.new(type, name, args, body)
|
|
177
178
|
end
|
|
@@ -207,11 +208,8 @@ class Parser
|
|
|
207
208
|
consume(:else)
|
|
208
209
|
skip_newlines
|
|
209
210
|
|
|
210
|
-
else_body =
|
|
211
|
-
|
|
212
|
-
else_body << parse_statement
|
|
213
|
-
skip_newlines
|
|
214
|
-
end
|
|
211
|
+
else_body = parse_block
|
|
212
|
+
|
|
215
213
|
end
|
|
216
214
|
|
|
217
215
|
consume(:end)
|
|
@@ -230,16 +228,57 @@ class Parser
|
|
|
230
228
|
statement = parse_expr
|
|
231
229
|
end
|
|
232
230
|
|
|
233
|
-
|
|
234
|
-
body = []
|
|
231
|
+
body = parse_block
|
|
235
232
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
233
|
+
consume(:end)
|
|
234
|
+
WhileNode.new(statement, body)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def parse_for
|
|
238
|
+
consume(:for)
|
|
239
|
+
var = parse_expr
|
|
240
|
+
consume(:equal)
|
|
241
|
+
start = parse_expr
|
|
242
|
+
consume(:comma)
|
|
243
|
+
stop = parse_expr
|
|
244
|
+
|
|
245
|
+
step = nil
|
|
246
|
+
if peek(:comma)
|
|
247
|
+
consume(:comma)
|
|
248
|
+
step = parse_expr
|
|
239
249
|
end
|
|
250
|
+
body = parse_block
|
|
240
251
|
|
|
241
252
|
consume(:end)
|
|
242
|
-
|
|
253
|
+
ForNode.new(var, start, stop, step, body)
|
|
254
|
+
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def parse_forpairs
|
|
258
|
+
consume(:forpairs)
|
|
259
|
+
key = consume(:identifier).value
|
|
260
|
+
consume(:comma)
|
|
261
|
+
val = consume(:identifier).value
|
|
262
|
+
consume(:in)
|
|
263
|
+
t = parse_expr
|
|
264
|
+
body = parse_block
|
|
265
|
+
consume(:end)
|
|
266
|
+
|
|
267
|
+
ForPairNode.new(key, val, t, body)
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def parse_foripairs
|
|
272
|
+
consume(:foripairs)
|
|
273
|
+
index = consume(:identifier).value
|
|
274
|
+
consume(:comma)
|
|
275
|
+
val = consume(:identifier).value
|
|
276
|
+
consume(:in)
|
|
277
|
+
t = parse_expr
|
|
278
|
+
body = parse_block
|
|
279
|
+
consume(:end)
|
|
280
|
+
|
|
281
|
+
ForIPairNode.new(index, val, t, body)
|
|
243
282
|
end
|
|
244
283
|
|
|
245
284
|
def parse_switch
|
|
@@ -306,24 +345,6 @@ class Parser
|
|
|
306
345
|
|
|
307
346
|
left
|
|
308
347
|
end
|
|
309
|
-
# consume(:if)
|
|
310
|
-
|
|
311
|
-
# if peek(:oparen)
|
|
312
|
-
# consume(:oparen)
|
|
313
|
-
# statement = parse_expr
|
|
314
|
-
# consume(:cparen)
|
|
315
|
-
# else
|
|
316
|
-
# statement = parse_expr
|
|
317
|
-
# end
|
|
318
|
-
# skip_newlines
|
|
319
|
-
# body = []
|
|
320
|
-
|
|
321
|
-
# until peek(:elif) peek(:end)
|
|
322
|
-
# body << parse_statement
|
|
323
|
-
# skip_newlines
|
|
324
|
-
# end
|
|
325
|
-
# consume(:end)
|
|
326
|
-
# IfNode.new(statement, body)
|
|
327
348
|
|
|
328
349
|
def parse_args
|
|
329
350
|
consume(:oparen)
|
|
@@ -339,6 +360,17 @@ class Parser
|
|
|
339
360
|
args
|
|
340
361
|
end
|
|
341
362
|
|
|
363
|
+
def parse_block
|
|
364
|
+
skip_newlines
|
|
365
|
+
body = []
|
|
366
|
+
|
|
367
|
+
until peek(:end)
|
|
368
|
+
body << parse_statement
|
|
369
|
+
skip_newlines
|
|
370
|
+
end
|
|
371
|
+
body
|
|
372
|
+
end
|
|
373
|
+
|
|
342
374
|
|
|
343
375
|
|
|
344
376
|
def parse_additive
|
|
@@ -362,41 +394,31 @@ class Parser
|
|
|
362
394
|
end
|
|
363
395
|
left
|
|
364
396
|
end
|
|
365
|
-
# def parse_operators
|
|
366
|
-
# left = parse_term
|
|
367
|
-
|
|
368
|
-
# left = parse_op(left, :divide)
|
|
369
|
-
# left = parse_op(left, :multiply)
|
|
370
|
-
# left = parse_op(left, :plus)
|
|
371
|
-
# left = parse_op(left, :minus)
|
|
372
|
-
|
|
373
|
-
# left
|
|
374
|
-
# end
|
|
375
397
|
|
|
376
|
-
# def parse_op(left, operator)
|
|
377
|
-
|
|
378
|
-
# while peek(operator)
|
|
379
|
-
# consume(operator)
|
|
380
|
-
# right = parse_term
|
|
381
|
-
# left = BinOpNode.new(left, operator, right)
|
|
382
|
-
# end
|
|
383
|
-
# left
|
|
384
|
-
|
|
385
|
-
# end
|
|
386
398
|
|
|
387
399
|
def parse_term
|
|
400
|
+
skip_newlines
|
|
388
401
|
if peek(:integer)
|
|
389
402
|
IntegerNode.new(consume(:integer).value.to_i)
|
|
390
403
|
|
|
404
|
+
elsif peek(:float)
|
|
405
|
+
FloatNode.new(consume(:float).value.to_f)
|
|
406
|
+
|
|
391
407
|
elsif peek(:identifier) && peek(:oparen, 1)
|
|
392
408
|
parse_call
|
|
393
409
|
|
|
410
|
+
elsif peek(:identifier) && peek(:lbracket, 1)
|
|
411
|
+
parse_array_access
|
|
412
|
+
|
|
413
|
+
elsif peek(:lbrace)
|
|
414
|
+
parse_array
|
|
415
|
+
|
|
394
416
|
elsif peek(:identifier)
|
|
395
417
|
VarRefNode.new(consume(:identifier).value)
|
|
396
418
|
|
|
397
419
|
elsif peek(:string)
|
|
398
420
|
strVal = consume(:string).value
|
|
399
|
-
StringNode.new(strVal[1..-2])
|
|
421
|
+
StringNode.new(strVal[1..-2])
|
|
400
422
|
|
|
401
423
|
elsif peek(:oparen)
|
|
402
424
|
# consume(:oparen)
|
|
@@ -407,15 +429,19 @@ class Parser
|
|
|
407
429
|
|
|
408
430
|
first = parse_expr
|
|
409
431
|
items = [first]
|
|
410
|
-
until peek(:identifier)
|
|
432
|
+
until peek(:identifier) || peek(:dequal)
|
|
411
433
|
break
|
|
412
434
|
end
|
|
413
435
|
|
|
414
|
-
if !peek(:identifier) && peek(:or)
|
|
436
|
+
if !peek(:identifier) && peek(:or) || peek(:and)
|
|
415
437
|
while peek(:or)
|
|
416
438
|
consume(:or)
|
|
417
439
|
items << parse_expr
|
|
418
440
|
end
|
|
441
|
+
while peek(:and)
|
|
442
|
+
consume(:and)
|
|
443
|
+
items << parse_expr
|
|
444
|
+
end
|
|
419
445
|
consume(:cparen)
|
|
420
446
|
return AndOrListNode.new(items)
|
|
421
447
|
end
|
|
@@ -426,8 +452,7 @@ class Parser
|
|
|
426
452
|
elsif peek(:self)
|
|
427
453
|
parse_self_node
|
|
428
454
|
|
|
429
|
-
|
|
430
|
-
parse_array
|
|
455
|
+
|
|
431
456
|
|
|
432
457
|
|
|
433
458
|
elsif LOVE_NAMESPACES.keys.include?(peek_type)
|
|
@@ -444,7 +469,8 @@ class Parser
|
|
|
444
469
|
prefix = @tokens.shift.type
|
|
445
470
|
namespace = LOVE_NAMESPACES[prefix]
|
|
446
471
|
|
|
447
|
-
name =
|
|
472
|
+
name = @tokens.shift.value
|
|
473
|
+
|
|
448
474
|
args = parse_arg_expr
|
|
449
475
|
|
|
450
476
|
LoveCallNode.new(namespace, name, args)
|
|
@@ -499,25 +525,30 @@ class Parser
|
|
|
499
525
|
end
|
|
500
526
|
|
|
501
527
|
def parse_array
|
|
502
|
-
consume(:
|
|
528
|
+
consume(:lbrace)
|
|
529
|
+
skip_newlines
|
|
503
530
|
elements = []
|
|
504
|
-
unless peek(:
|
|
531
|
+
unless peek(:rbrace)
|
|
505
532
|
elements << parse_expr
|
|
533
|
+
skip_newlines
|
|
506
534
|
while peek(:comma)
|
|
507
535
|
consume(:comma)
|
|
536
|
+
skip_newlines
|
|
508
537
|
elements << parse_expr
|
|
538
|
+
skip_newlines
|
|
509
539
|
end
|
|
510
540
|
end
|
|
511
|
-
|
|
541
|
+
skip_newlines
|
|
542
|
+
consume(:rbrace)
|
|
512
543
|
ArrayNode.new(elements)
|
|
513
544
|
end
|
|
514
545
|
|
|
515
546
|
|
|
516
547
|
def parse_array_access
|
|
517
548
|
name = consume(:identifier).value
|
|
518
|
-
consume(:
|
|
549
|
+
consume(:lbracket)
|
|
519
550
|
index = parse_expr
|
|
520
|
-
consume(:
|
|
551
|
+
consume(:rbracket)
|
|
521
552
|
ArrayAccessNode.new(name, index)
|
|
522
553
|
end
|
|
523
554
|
|
|
@@ -534,4 +565,4 @@ class Parser
|
|
|
534
565
|
def peek_type(offset = 0)
|
|
535
566
|
@tokens[offset]&.type
|
|
536
567
|
end
|
|
537
|
-
end
|
|
568
|
+
end
|
data/compiler/tokenizer.rb
CHANGED
|
@@ -3,56 +3,66 @@ Token = Struct.new(:type, :value)
|
|
|
3
3
|
class Tokenizer
|
|
4
4
|
|
|
5
5
|
TOKEN_TYPES = [
|
|
6
|
+
|
|
7
|
+
#love
|
|
8
|
+
[:lgraphics, /-G:/],
|
|
9
|
+
[:laudio, /-A:/],
|
|
10
|
+
[:ldata, /-D:/],
|
|
11
|
+
[:levent, /-E:/],
|
|
12
|
+
[:lfilesystem, /-FS:/],
|
|
13
|
+
[:lfont, /-F:/],
|
|
14
|
+
[:limage, /-I:/],
|
|
15
|
+
[:ljoystick, /-J:/],
|
|
16
|
+
[:lmouse, /-M:/],
|
|
17
|
+
[:lkeyboard, /-K:/],
|
|
18
|
+
[:love, /\blove\b/],
|
|
19
|
+
|
|
6
20
|
[:local, /\bnat\b/],
|
|
7
21
|
[:def, /\bcall\b/],
|
|
8
22
|
[:end, /\bdone\b/],
|
|
9
23
|
[:if, /\bif\b/],
|
|
10
24
|
[:elif, /\belif\b/],
|
|
11
25
|
[:else, /\belse\b/],
|
|
26
|
+
|
|
12
27
|
[:while, /\bwhen\b/],
|
|
28
|
+
[:for, /\bfor\b/],
|
|
29
|
+
[:forpairs, /\beach\b/],
|
|
30
|
+
[:foripairs, /\bseq\b/],
|
|
31
|
+
|
|
13
32
|
[:print, /\bprint\b/],
|
|
14
33
|
[:return, /\breturn\b/],
|
|
15
34
|
[:or, /\bor\b/],
|
|
16
35
|
[:and, /\band\b/],
|
|
36
|
+
[:in, /\bas\b/],
|
|
17
37
|
[:switch, /\bswitch\b/],
|
|
18
38
|
[:to, /\bto\b/],
|
|
19
39
|
[:class, /\bclass\b/],
|
|
20
40
|
[:self, /\bself\b/],
|
|
21
41
|
[:import, /\bbring\b/],
|
|
22
42
|
|
|
23
|
-
|
|
24
|
-
[:lgraphics, /-G:/],
|
|
25
|
-
[:laudio, /-A:/],
|
|
26
|
-
[:ldata, /-D:/],
|
|
27
|
-
[:levent, /-E:/],
|
|
28
|
-
[:lfilesystem, /-FS:/],
|
|
29
|
-
[:lfont, /-F:/],
|
|
30
|
-
[:limage, /-I:/],
|
|
31
|
-
[:ljoystick, /-J:/],
|
|
32
|
-
[:lmouse, /-M:/],
|
|
33
|
-
[:lkeyboard, /-K:/],
|
|
34
|
-
[:love, /\blove\b/],
|
|
43
|
+
|
|
35
44
|
|
|
36
45
|
# thingies
|
|
37
|
-
[:identifier, /\b[a-zA-
|
|
46
|
+
[:identifier, /\b[a-zA-Z_][a-zA-Z0-9_]*\b/],
|
|
38
47
|
[:string, /"([^"]*)"/],
|
|
39
|
-
[:
|
|
48
|
+
[:float, /(?:\d+\.\d*|\.\d+)/],
|
|
49
|
+
[:integer, /\b\d+\b/],
|
|
40
50
|
[:oparen, /\(/],
|
|
41
51
|
[:cparen, /\)/],
|
|
42
|
-
[:
|
|
43
|
-
[:
|
|
44
|
-
[:
|
|
45
|
-
[:
|
|
52
|
+
[:lbracket, /\[/],
|
|
53
|
+
[:rbracket, /\]/],
|
|
54
|
+
[:lbrace, /\{/],
|
|
55
|
+
[:rbrace, /\}/],
|
|
46
56
|
[:comma, /,/],
|
|
47
57
|
[:dot, /\./],
|
|
48
58
|
[:colon, /:/],
|
|
49
59
|
|
|
50
60
|
# operators
|
|
51
61
|
[:dequal, /==/],
|
|
52
|
-
[:greater, />/],
|
|
53
|
-
[:lesser, /</],
|
|
54
62
|
[:grequal, />=/],
|
|
55
63
|
[:lequal, /<=/],
|
|
64
|
+
[:greater, />/],
|
|
65
|
+
[:lesser, /</],
|
|
56
66
|
[:equal, /=/],
|
|
57
67
|
[:divide, /\//],
|
|
58
68
|
[:multiply, /\*/],
|