sardonyx 0.1.843 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: babd36be28fd243f8478626b5e9a2d878d9b02d079a2f575a51629af835f4dcb
4
- data.tar.gz: 970de1b558e7f9d98becfdc0aaafe51398f8c84dd47066b384fc7fd3c66d3a5e
3
+ metadata.gz: a47addbe2b460c689ce05c124e596fef8a63d8c9c90eb7338144d34a5932bc69
4
+ data.tar.gz: 7699f23fe1516749a0086df90f5ca7056339ff1f4a229c6cf8d31d260ba238af
5
5
  SHA512:
6
- metadata.gz: 50b2b42da15041685758cf5e07e9d6e7d7f90685d0c15bb0ac35788a938a7213e8dd5bed01a4a570a8ddd954b0e995a8a1bd8773653d323e7c0efb22f2657c71
7
- data.tar.gz: e428e7703e824dfb3dfc5510c9fcaf707df710947af0dc0f8646bd64c0cfd5c90621a29d29d9b4fc92a1dd6d19be83548cf832711e58667b3870c74baaadbc71
6
+ metadata.gz: 1f69b3a81744ab1b790c6d9f327a8e07ab55045af74c2bc852418c124e6651b8fea663c4d9b163f7eb4b7792c07678f7fa0b6c372bacdcc53fbed901a628315e
7
+ data.tar.gz: 3c0ec1b0ffe241e2996069bba3edf81a50c92e8d821397a430ca2a5edc59e57716a2c52b0f12ab8774962d0a7a539b257cf5f6ed01ecf86b44286fcfab745f6e
data/bin/sdx CHANGED
@@ -3,33 +3,57 @@ require "sdx/compiler/parser"
3
3
  require "sdx/compiler/compiler"
4
4
  require "sdx/vm/vm"
5
5
  require "stringio"
6
+ require "readline"
7
+
8
+ if (ENV.fetch("SDX_PATH", "").split ":") == []
9
+ puts "\x1b[0;33mLooks like you don't have anything in your SDX_PATH! You should install the stdlib at https://github.com/SardonyxLang/SardonyxStd.\x1b[0;0m"
10
+ end
6
11
 
7
12
  if ARGV.size == 1
8
13
  path = [(File.expand_path File.dirname ARGV[0]), *(ENV.fetch("SDX_PATH", "").split ":")]
9
14
  code = File.read ARGV[0]
10
- lexed = Parser::Lexer.lex code
11
- ast = Parser::Parser.parse lexed, path
12
- bc = Compiler::Compiler.compile ast
13
- vm = VM.new StringIO.new bc
14
- vm.interpret
15
+ lexed, lines = Parser::Lexer.lex code
16
+ ast = Parser::Parser.parse lexed, path, lines
17
+ if State::state == :ok
18
+ bc = Compiler::Compiler.compile ast
19
+ vm = VM.new StringIO.new bc
20
+ vm.interpret
21
+ end
15
22
  else
16
23
  path = [(File.expand_path Dir.pwd), *(ENV.fetch("SDX_PATH", "").split ":")]
17
24
  vm = VM.new StringIO.new ""
18
- puts "Sardonyx v0.1.8"
19
- def exit(_) end
25
+ puts "Sardonyx v0.3.1"
26
+ puts "Type :help for help, or :exit to exit"
20
27
  loop do
21
- print "> "
22
- code = gets
23
- lexed = Parser::Lexer.lex code
24
- ast = Parser::Parser.parse lexed, path
25
- bc = Compiler::Compiler.compile ast
26
- vm.bc_io = StringIO.new bc
27
- vm.byte_pos = 0
28
- vm.interpret false
29
- val = vm.stack[-1]
30
- vm.clear
31
- if val
32
- puts vm.stringify val
28
+ begin
29
+ code = Readline.readline("> ", true)
30
+ rescue Interrupt
31
+ puts "^C"
32
+ code = ""
33
+ end
34
+ unless code
35
+ puts ":exit"
36
+ exit 0
37
+ end
38
+ case code
39
+ when ":exit"
40
+ exit 0
41
+ when ":help"
42
+ puts "See sardonyxlang.github.io/docs for documentation - for now, try entering \"5 + 5\""
43
+ else
44
+ lexed, lines = Parser::Lexer.lex code
45
+ ast = Parser::Parser.parse lexed, path, lines
46
+ if State::state == :ok
47
+ bc = Compiler::Compiler.compile ast
48
+ vm.bc_io = StringIO.new bc
49
+ vm.byte_pos = 0
50
+ vm.interpret false
51
+ val = vm.stack[-1]
52
+ vm.clear
53
+ if val
54
+ puts vm.stringify val
55
+ end
56
+ end
33
57
  end
34
58
  end
35
59
  end
@@ -1,6 +1,19 @@
1
+ class State
2
+ class << self
3
+ attr_accessor :state
4
+ end
5
+ @@state = :ok
6
+ end
7
+
8
+ def error(msg)
9
+ puts "\x1b[0;31mError in parser: #{msg}\x1b[0;0m"
10
+ end
11
+
1
12
  module Parser
13
+
2
14
  class Lexer
3
15
  TOKENS = {
16
+ /\A#.*/ => :comment,
4
17
  /\Aif/ => :if,
5
18
  /\Aelse/ => :else,
6
19
  /\Awhile/ => :while,
@@ -11,11 +24,12 @@ module Parser
11
24
  /\Anew/ => :new,
12
25
  /\Arequire/ => :require,
13
26
  /\A(true|false)/ => :bool,
14
- /\A(<|>|<=|>=|==|!=)/ => :op,
15
- /\A(\+|-|\*|\/|%)?=/ => :eq,
16
- /\A(\+|-|\*|\/|%)/ => :op,
17
- /\A-?[0-9]+/ => :number,
18
27
  /\A-?[0-9]+\.[0-9]+/ => :float,
28
+ /\A-?[0-9]+/ => :number,
29
+ /\A(\+|-)/ => :l1op,
30
+ /\A(\/|\*|%|\^)/ => :l2op,
31
+ /\A(<|>|<=|>=|==|!=)/ => :l1op,
32
+ /\A(\+|-|\*|\/|%)?=/ => :eq,
19
33
  /\A"([^"]|\\")*"/ => :string,
20
34
  /\Anil/ => :nil,
21
35
  /\A\(/ => :lpar,
@@ -28,25 +42,78 @@ module Parser
28
42
  /\A[A-Za-z_][A-Za-z0-9_]*([:.][A-Za-z_][A-Za-z0-9_]*)*/ => :name
29
43
  }
30
44
 
45
+ class << self
46
+ attr_accessor :lines
47
+ end
48
+
31
49
  def self.lex(code)
50
+ @@lines = code.split "\n"
32
51
  lexed = []
33
- found = false
34
- while code.size > 0
35
- TOKENS.each { |re, tag|
36
- if (code =~ re) != nil
37
- found = true
38
- m = (re.match code)
39
- lexed << [ m[0], tag ]
40
- code = code[(m.end 0)..code.size].lstrip
52
+ comment = false
53
+ line = col = 0
54
+ State::state = :ok
55
+ while State::state == :ok and code.size > 0
56
+ while true
57
+ if code.size != 0 and code[0] == "\n"
58
+ col = 0
59
+ line += 1
60
+ code = code[1..-1]
61
+ elsif code.size != 0 and code[0].strip.empty?
62
+ if State::state == :ok
63
+ col += 1
64
+ end
65
+ code = code[1..-1]
66
+ else
41
67
  break
42
68
  end
43
- }
44
- if !found
45
- puts "Syntax error: ", code
46
- Kernel.exit 1
69
+ end
70
+ if !comment && (code.start_with? "#>")
71
+ comment = true
72
+ code = code[2..-1]
73
+ elsif comment && (code.start_with? "<#")
74
+ comment = false
75
+ code = code[2..-1]
76
+ elsif comment
77
+ code = code[1..-1]
78
+ else
79
+ found = false
80
+ TOKENS.each { |re, tag|
81
+ if (code =~ re) != nil
82
+ found = true
83
+ m = (re.match code)
84
+ if tag != :comment
85
+ lexed << [ m[0], tag, line, col ]
86
+ end
87
+ code = code[(m.end 0)..-1]
88
+ col += (m.end 0)
89
+ while true
90
+ if code.size != 0 and code[0] == "\n"
91
+ col = 0
92
+ line += 1
93
+ code = code[1..-1]
94
+ elsif code.size != 0 and code[0].strip.empty?
95
+ if State::state == :ok
96
+ col += 1
97
+ end
98
+ code = code[1..-1]
99
+ else
100
+ break
101
+ end
102
+ end
103
+ break
104
+ end
105
+ }
106
+ if !found
107
+ error %{
108
+ Invalid code at #{line}:#{col}
109
+ #{" " * line.to_s.size} |
110
+ #{line} | #{@@lines[line].rstrip}
111
+ #{" " * line.to_s.size} | #{" " * col}^ here}
112
+ State::state = :error
113
+ end
47
114
  end
48
115
  end
49
- lexed
116
+ [ lexed, @@lines ]
50
117
  end
51
118
  end
52
119
 
@@ -124,13 +191,15 @@ module Parser
124
191
 
125
192
  def self.parse_parens(tokens)
126
193
  if self.expect tokens, :lpar
127
- tokens = tokens[1..tokens.size]
128
- unless self.parse_expr tokens
194
+ tokens = tokens[1..-1]
195
+ res = self.parse_expr tokens
196
+ unless res
129
197
  return nil
130
198
  end
131
199
  e, part = self.parse_expr tokens
132
- tokens = tokens[part..tokens.size]
133
- unless self.expect tokens, :rpar
200
+ tokens = tokens[part..-1]
201
+ res = self.expect tokens, :rpar
202
+ unless res
134
203
  return nil
135
204
  end
136
205
  return [e, part + 2]
@@ -143,7 +212,7 @@ module Parser
143
212
  unless (self.expect tokens, :lbrack)
144
213
  return nil
145
214
  end
146
- tokens = tokens[1..tokens.size]
215
+ tokens = tokens[1..-1]
147
216
  children = []
148
217
  total = 1
149
218
  while true
@@ -151,13 +220,14 @@ module Parser
151
220
  total += 1
152
221
  break
153
222
  end
154
- unless self.parse_expr tokens
223
+ res = self.parse_expr tokens
224
+ unless res
155
225
  return nil
156
226
  end
157
- e, part = self.parse_expr tokens
227
+ e, part = res
158
228
  children << e
159
229
  total += part
160
- tokens = tokens[part..tokens.size]
230
+ tokens = tokens[part..-1]
161
231
  if self.expect tokens, :rbrack
162
232
  total += 1
163
233
  break
@@ -166,7 +236,7 @@ module Parser
166
236
  return nil
167
237
  end
168
238
  total += 1
169
- tokens = tokens[1..tokens.size]
239
+ tokens = tokens[1..-1]
170
240
  end
171
241
  [ (Node.new :list, "", children), total ]
172
242
  end
@@ -175,7 +245,7 @@ module Parser
175
245
  unless (self.expect tokens, :lbrace)
176
246
  return nil
177
247
  end
178
- tokens = tokens[1..tokens.size]
248
+ tokens = tokens[1..-1]
179
249
  children = []
180
250
  total = 1
181
251
  while true
@@ -187,7 +257,7 @@ module Parser
187
257
  if e
188
258
  children << e[0]
189
259
  total += e[1]
190
- tokens = tokens[e[1]..tokens.size]
260
+ tokens = tokens[e[1]..-1]
191
261
  else
192
262
  puts "Syntax error at token ", tokens[0]
193
263
  Kernel.exit 1
@@ -198,41 +268,52 @@ module Parser
198
268
  end
199
269
 
200
270
  def self.parse_literal(tokens)
201
- (self.parse_block tokens) || (self.parse_bool tokens) || (self.parse_float tokens) || (self.parse_name tokens) || (self.parse_number tokens) || (self.parse_list tokens) || (self.parse_string tokens) || (self.parse_nil tokens) || (self.parse_parens tokens)
271
+ (self.parse_block tokens) ||
272
+ (self.parse_bool tokens) ||
273
+ (self.parse_float tokens) ||
274
+ (self.parse_name tokens) ||
275
+ (self.parse_number tokens) ||
276
+ (self.parse_list tokens) ||
277
+ (self.parse_string tokens) ||
278
+ (self.parse_nil tokens) ||
279
+ (self.parse_parens tokens)
202
280
  end
203
281
 
204
282
  def self.parse_call(tokens)
205
- unless (self.parse_literal tokens)
283
+ res = (self.parse_literal tokens)
284
+ unless res
206
285
  return nil
207
286
  end
208
- callee = (self.parse_literal tokens)
287
+ callee = res
209
288
  total = callee[1]
210
- tokens = tokens[total..tokens.size]
289
+ tokens = tokens[total..-1]
211
290
  callee = callee[0]
212
291
  if self.expect tokens, :lpar
213
292
  args = []
214
- tokens = tokens[1..tokens.size]
293
+ tokens = tokens[1..-1]
215
294
  total += 1
216
295
  if self.expect tokens, :rpar
217
296
  return [ (Node.new :call, callee, args), total + 1 ]
218
297
  end
219
298
  while true
220
- unless (self.parse_expr tokens)
299
+ res = (self.parse_expr tokens)
300
+ unless res
221
301
  return nil
222
302
  end
223
- arg, part = (self.parse_expr tokens)
303
+ arg, part = res
224
304
  total += part
225
- tokens = tokens[part..tokens.size]
305
+ tokens = tokens[part..-1]
226
306
  args << arg
227
- total += 1
228
307
  if self.expect tokens, :rpar
229
- tokens = tokens[1..tokens.size]
308
+ tokens = tokens[1..-1]
309
+ total += 1
230
310
  break
231
311
  end
232
312
  unless (self.expect tokens, :comma)
233
313
  return nil
234
314
  end
235
- tokens = tokens[1..tokens.size]
315
+ total += 1
316
+ tokens = tokens[1..-1]
236
317
  end
237
318
  return [ (Node.new :call, callee, args), total ]
238
319
  else
@@ -245,36 +326,38 @@ module Parser
245
326
  return nil
246
327
  end
247
328
  total = 1
248
- tokens = tokens[1..tokens.size]
329
+ tokens = tokens[1..-1]
249
330
  if self.lookahead tokens, :lpar, 1
250
- unless (self.parse_literal tokens)
331
+ res = (self.parse_literal tokens)
332
+ unless res
251
333
  return nil
252
334
  end
253
- callee = (self.parse_literal tokens)
335
+ callee = res
254
336
  callee = callee[0]
255
337
  args = []
256
- tokens = tokens[2..tokens.size]
338
+ tokens = tokens[2..-1]
257
339
  total += 2
258
340
  if self.expect tokens, :rpar
259
341
  return [ (Node.new :call, callee, args), total + 1 ]
260
342
  end
261
343
  while true
262
- unless (self.parse_expr tokens)
344
+ res = (self.parse_expr tokens)
345
+ unless res
263
346
  return nil
264
347
  end
265
- arg, part = (self.parse_expr tokens)
348
+ arg, part = res
266
349
  total += part
267
- tokens = tokens[part..tokens.size]
350
+ tokens = tokens[part..-1]
268
351
  args << arg
269
352
  total += 1
270
353
  if self.expect tokens, :rpar
271
- tokens = tokens[1..tokens.size]
354
+ tokens = tokens[1..-1]
272
355
  break
273
356
  end
274
357
  unless (self.expect tokens, :comma)
275
358
  return nil
276
359
  end
277
- tokens = tokens[1..tokens.size]
360
+ tokens = tokens[1..-1]
278
361
  end
279
362
  return [ (Node.new :new, callee, args), total ]
280
363
  else
@@ -287,30 +370,33 @@ module Parser
287
370
  return nil
288
371
  end
289
372
  total = 1
290
- tokens = tokens[1..tokens.size]
291
- unless self.parse_expr tokens
373
+ tokens = tokens[1..-1]
374
+ res = self.parse_expr tokens
375
+ unless res
292
376
  return nil
293
377
  end
294
- e, part = self.parse_expr tokens
378
+ e, part = res
295
379
  total += part
296
- tokens = tokens[part..tokens.size]
297
- unless self.parse_expr tokens
380
+ tokens = tokens[part..-1]
381
+ res = self.parse_expr tokens
382
+ unless res
298
383
  return nil
299
384
  end
300
- block, part = self.parse_expr tokens
385
+ block, part = res
301
386
  total += part
302
- tokens = tokens[part..tokens.size]
387
+ tokens = tokens[part..-1]
303
388
  el = nil
304
389
  if self.expect tokens, :else
305
390
  total += 1
306
- tokens = tokens[1..tokens.size]
307
- unless self.parse_expr tokens
391
+ tokens = tokens[1..-1]
392
+ res = self.parse_expr tokens
393
+ unless res
308
394
  return nil
309
395
  end
310
- el, part = self.parse_expr tokens
396
+ el, part = res
311
397
  total += part
312
398
  end
313
- return [ (Node.new :if, e, [block, el]), total ]
399
+ [ (Node.new :if, e, [block, el]), total ]
314
400
  end
315
401
 
316
402
  def self.parse_while(tokens)
@@ -318,19 +404,21 @@ module Parser
318
404
  return nil
319
405
  end
320
406
  total = 1
321
- tokens = tokens[1..tokens.size]
322
- unless self.parse_expr tokens
407
+ tokens = tokens[1..-1]
408
+ res = self.parse_expr tokens
409
+ unless res
323
410
  return nil
324
411
  end
325
- e, part = self.parse_expr tokens
412
+ e, part = res
326
413
  total += part
327
- tokens = tokens[part..tokens.size]
328
- unless self.parse_expr tokens
414
+ tokens = tokens[part..-1]
415
+ res = self.parse_expr tokens
416
+ unless res
329
417
  return nil
330
418
  end
331
- block, part = self.parse_expr tokens
419
+ block, part = res
332
420
  total += part
333
- return [ (Node.new :while, e, [block]), total ]
421
+ [ (Node.new :while, e, [block]), total ]
334
422
  end
335
423
 
336
424
  def self.parse_for(tokens)
@@ -338,47 +426,120 @@ module Parser
338
426
  return nil
339
427
  end
340
428
  total = 1
341
- tokens = tokens[1..tokens.size]
429
+ tokens = tokens[1..-1]
342
430
  name = nil
343
431
  if self.expect tokens, :name and self.lookahead tokens, :in, 1
344
432
  name = tokens[0][0]
345
433
  total += 2
346
- tokens = tokens[2..tokens.size]
434
+ tokens = tokens[2..-1]
347
435
  end
348
- unless self.parse_expr tokens
436
+ res = self.parse_expr tokens
437
+ unless res
349
438
  return nil
350
439
  end
351
- e, part = self.parse_expr tokens
440
+ e, part = res
352
441
  total += part
353
- tokens = tokens[part..tokens.size]
354
- unless self.parse_expr tokens
442
+ tokens = tokens[part..-1]
443
+ res = self.parse_expr tokens
444
+ unless res
355
445
  return nil
356
446
  end
357
- block, part = self.parse_expr tokens
447
+ block, part = res
358
448
  total += part
359
- return [ (Node.new :for, e, [name, block]), total ]
449
+ [ (Node.new :for, e, [name, block]), total ]
360
450
  end
361
451
 
362
- def self.parse_op(tokens)
452
+ def self.parse_factor(tokens)
453
+ (self.parse_call tokens) ||
454
+ (self.parse_require tokens) ||
455
+ (self.parse_new tokens) ||
456
+ (self.parse_object tokens) ||
457
+ (self.parse_fn tokens) ||
458
+ (self.parse_assign tokens) ||
459
+ (self.parse_literal tokens) ||
460
+ (self.parse_if tokens) ||
461
+ (self.parse_while tokens) ||
462
+ (self.parse_for tokens)
463
+ end
464
+
465
+ def self.parse_term(tokens)
363
466
  total = 0
364
- unless self.parse_literal tokens
467
+ res = self.parse_factor tokens
468
+ unless res
365
469
  return nil
366
470
  end
367
- lhs, part = self.parse_literal tokens
471
+ lhs, part = res
368
472
  total += part
369
- tokens = tokens[part..tokens.size]
370
- unless self.expect tokens, :op
473
+ tokens = tokens[part..-1]
474
+ unless self.expect tokens, :l2op
475
+ return [lhs, part]
476
+ end
477
+ op = tokens[0][0]
478
+ total += 1
479
+ tokens = tokens[1..-1]
480
+ res = self.parse_factor tokens
481
+ unless res
371
482
  return nil
372
483
  end
484
+ rhs, part = res
485
+ total += part
486
+ tokens = tokens[part..-1]
487
+ out = (Node.new :op, op, [lhs])
488
+ while self.expect tokens, :l2op
489
+ op = tokens[0][0]
490
+ total += 1
491
+ tokens = tokens[1..-1]
492
+ res = self.parse_term tokens
493
+ unless res
494
+ return nil
495
+ end
496
+ rhs2, part = res
497
+ total += part
498
+ tokens = tokens[part..-1]
499
+ rhs = Node.new :op, op, [rhs, rhs2]
500
+ end
501
+ out.children << rhs
502
+ [out, total]
503
+ end
504
+
505
+ def self.parse_op(tokens)
506
+ total = 0
507
+ res = self.parse_term tokens
508
+ unless res
509
+ return nil
510
+ end
511
+ lhs, part = res
512
+ total += part
513
+ tokens = tokens[part..-1]
514
+ unless self.expect tokens, :l1op
515
+ return [lhs, part]
516
+ end
373
517
  op = tokens[0][0]
374
518
  total += 1
375
- tokens = tokens[1..tokens.size]
376
- unless self.parse_expr tokens
519
+ tokens = tokens[1..-1]
520
+ res = self.parse_term tokens
521
+ unless res
377
522
  return nil
378
523
  end
379
- rhs, part = self.parse_expr tokens
524
+ rhs, part = res
380
525
  total += part
381
- return [ (Node.new :op, op, [lhs, rhs]), total]
526
+ tokens = tokens[part..-1]
527
+ out = (Node.new :op, op, [lhs])
528
+ while self.expect tokens, :l1op
529
+ op = tokens[0][0]
530
+ total += 1
531
+ tokens = tokens[1..-1]
532
+ res = self.parse_term tokens
533
+ unless res
534
+ return nil
535
+ end
536
+ rhs2, part = res
537
+ total += part
538
+ tokens = tokens[part..-1]
539
+ rhs = Node.new :op, op, [rhs, rhs2]
540
+ end
541
+ out.children << rhs
542
+ [out, total]
382
543
  end
383
544
 
384
545
  def self.parse_assign(tokens)
@@ -388,19 +549,20 @@ module Parser
388
549
  end
389
550
  name = tokens[0][0]
390
551
  total += 1
391
- tokens = tokens[1..tokens.size]
552
+ tokens = tokens[1..-1]
392
553
  unless self.expect tokens, :eq
393
554
  return nil
394
555
  end
395
556
  eq = tokens[0][0]
396
557
  total += 1
397
- tokens = tokens[1..tokens.size]
398
- unless self.parse_expr tokens
558
+ tokens = tokens[1..-1]
559
+ res = self.parse_expr tokens
560
+ unless res
399
561
  return nil
400
562
  end
401
- rhs, part = self.parse_expr tokens
563
+ rhs, part = res
402
564
  total += part
403
- return [ (Node.new :assign, eq, [name, rhs]), total]
565
+ [ (Node.new :assign, eq, [name, rhs]), total]
404
566
  end
405
567
 
406
568
  def self.parse_fn(tokens)
@@ -408,23 +570,23 @@ module Parser
408
570
  return nil
409
571
  end
410
572
  total = 1
411
- tokens = tokens[1..tokens.size]
573
+ tokens = tokens[1..-1]
412
574
  unless self.expect tokens, :name
413
575
  return nil
414
576
  end
415
577
  name = tokens[0][0]
416
578
  total += 1
417
- tokens = tokens[1..tokens.size]
579
+ tokens = tokens[1..-1]
418
580
  unless self.expect tokens, :lpar
419
581
  return nil
420
582
  end
421
583
  total += 1
422
- tokens = tokens[1..tokens.size]
584
+ tokens = tokens[1..-1]
423
585
  args = []
424
586
  while true
425
587
  if self.expect tokens, :rpar
426
588
  total += 1
427
- tokens = tokens[1..tokens.size]
589
+ tokens = tokens[1..-1]
428
590
  break
429
591
  end
430
592
  unless self.expect tokens, :name
@@ -432,24 +594,25 @@ module Parser
432
594
  end
433
595
  args << tokens[0][0]
434
596
  total += 1
435
- tokens = tokens[1..tokens.size]
597
+ tokens = tokens[1..-1]
436
598
  if self.expect tokens, :rpar
437
599
  total += 1
438
- tokens = tokens[1..tokens.size]
600
+ tokens = tokens[1..-1]
439
601
  break
440
602
  end
441
603
  unless self.expect tokens, :comma
442
604
  return nil
443
605
  end
444
606
  total += 1
445
- tokens = tokens[1..tokens.size]
607
+ tokens = tokens[1..-1]
446
608
  end
447
- unless self.parse_expr tokens
609
+ res = self.parse_expr tokens
610
+ unless res
448
611
  return nil
449
612
  end
450
- body, part = self.parse_expr tokens
613
+ body, part = res
451
614
  total += part
452
- return [ (Node.new :fn, name, [args, body]), total ]
615
+ [ (Node.new :fn, name, [args, body]), total ]
453
616
  end
454
617
 
455
618
  def self.parse_object(tokens)
@@ -457,21 +620,21 @@ module Parser
457
620
  return nil
458
621
  end
459
622
  total = 1
460
- tokens = tokens[1..tokens.size]
623
+ tokens = tokens[1..-1]
461
624
  unless self.expect tokens, :name
462
625
  return nil
463
626
  end
464
627
  name = tokens[0][0]
465
628
  total += 1
466
- tokens = tokens[1..tokens.size]
629
+ tokens = tokens[1..-1]
467
630
  args = []
468
631
  if self.expect tokens, :lpar
469
632
  total += 1
470
- tokens = tokens[1..tokens.size]
633
+ tokens = tokens[1..-1]
471
634
  while true
472
635
  if self.expect tokens, :rpar
473
636
  total += 1
474
- tokens = tokens[1..tokens.size]
637
+ tokens = tokens[1..-1]
475
638
  break
476
639
  end
477
640
  unless self.expect tokens, :name
@@ -479,45 +642,56 @@ module Parser
479
642
  end
480
643
  args << tokens[0][0]
481
644
  total += 1
482
- tokens = tokens[1..tokens.size]
645
+ tokens = tokens[1..-1]
483
646
  if self.expect tokens, :rpar
484
647
  total += 1
485
- tokens = tokens[1..tokens.size]
648
+ tokens = tokens[1..-1]
486
649
  break
487
650
  end
488
651
  unless self.expect tokens, :comma
489
652
  return nil
490
653
  end
491
654
  total += 1
492
- tokens = tokens[1..tokens.size]
655
+ tokens = tokens[1..-1]
493
656
  end
494
657
  end
495
- unless self.parse_expr tokens
658
+ res = self.parse_expr tokens
659
+ unless res
496
660
  return nil
497
661
  end
498
- body, part = self.parse_expr tokens
662
+ body, part = res
499
663
  total += part
500
- return [ (Node.new :object, name, [args, body]), total ]
664
+ [ (Node.new :object, name, [args, body]), total ]
501
665
  end
502
666
 
503
667
  def self.parse_require(tokens)
504
668
  unless self.expect tokens, :require
505
669
  return nil
506
670
  end
507
- tokens = tokens[1..tokens.size]
671
+ tokens = tokens[1..-1]
508
672
  unless self.expect tokens, :string
509
673
  return nil
510
674
  end
511
- return [ (Node.new :require, tokens[0][0][1..-2], []), 2 ]
675
+ [ (Node.new :require, tokens[0][0][1..-2], []), 2 ]
512
676
  end
513
677
 
514
678
  def self.parse_expr(tokens)
515
- (self.parse_require tokens) || (self.parse_new tokens) || (self.parse_object tokens) || (self.parse_fn tokens) || (self.parse_assign tokens) || (self.parse_op tokens) || (self.parse_call tokens) || (self.parse_literal tokens) || (self.parse_if tokens) || (self.parse_while tokens) || (self.parse_for tokens)
679
+ (self.parse_op tokens) ||
680
+ (self.parse_call tokens) ||
681
+ (self.parse_require tokens) ||
682
+ (self.parse_new tokens) ||
683
+ (self.parse_object tokens) ||
684
+ (self.parse_fn tokens) ||
685
+ (self.parse_assign tokens) ||
686
+ (self.parse_literal tokens) ||
687
+ (self.parse_if tokens) ||
688
+ (self.parse_while tokens) ||
689
+ (self.parse_for tokens)
516
690
  end
517
691
 
518
- def self.parse(tokens, path)
692
+ def self.parse(tokens, path, lines)
519
693
  parsed = []
520
- while tokens.size > 0
694
+ while State::state == :ok and tokens.size > 0
521
695
  e = self.parse_expr tokens
522
696
  if e
523
697
  if e[0].nodetype == :require
@@ -530,19 +704,23 @@ module Parser
530
704
  end
531
705
  end
532
706
  unless code
533
- puts "Cannot find file #{e[0].value}.sdx anywhere in path"
534
- Kernel.exit 1
707
+ error "Cannot find file #{e[0].value}.sdx anywhere in path"
708
+ State::state = :error
535
709
  end
536
710
  lexed = Lexer.lex code
537
- ast = self.parse lexed, path
711
+ ast = self.parse lexed, path, (code.split "\n")
538
712
  parsed.concat ast
539
713
  else
540
714
  parsed << e[0]
541
715
  end
542
- tokens = tokens[e[1]..tokens.size]
716
+ tokens = tokens[e[1]..-1]
543
717
  else
544
- puts "Syntax error at token ", tokens[0][1]
545
- Kernel.exit 1
718
+ error %{
719
+ Unexpected token #{tokens[0][1]} at #{tokens[0][2]}:#{tokens[0][3]}
720
+ #{" " * tokens[0][2].to_s.size} |
721
+ #{tokens[0][2]} | #{lines[tokens[0][2]].rstrip}
722
+ #{" " * tokens[0][2].to_s.size} | #{" " * tokens[0][3]}^ here}
723
+ State::state = :error
546
724
  end
547
725
  end
548
726
  parsed
@@ -1,5 +1,3 @@
1
- require "sdx/vm/vm"
2
- require "sdx/vm/variables"
3
1
  require "stringio"
4
2
 
5
3
  class DataType
@@ -3,7 +3,6 @@ class GLOBAL_SCOPE
3
3
 
4
4
  def error(msg)
5
5
  puts "\x1b[0;31mError in VM: #{msg}\x1b[0;0m"
6
- exit 1
7
6
  end
8
7
 
9
8
  def initialize(variables={})
@@ -25,7 +24,7 @@ class GLOBAL_SCOPE
25
24
  name.each do |part|
26
25
  val = scope.variables[part]
27
26
  unless val
28
- error "No such variable #{part}"
27
+ return nil
29
28
  end
30
29
  case val.value
31
30
  when InstantiatedObj
@@ -165,7 +165,8 @@ class VM
165
165
  0x36 => :lt,
166
166
  0x37 => :gt,
167
167
  0x38 => :le,
168
- 0x39 => :ge
168
+ 0x39 => :ge,
169
+ 0x28 => :pow,
169
170
  }
170
171
  bytes = []
171
172
  begin
@@ -219,13 +220,15 @@ class VM
219
220
 
220
221
  def error(msg)
221
222
  puts "\x1b[0;31mError in VM: #{msg}\x1b[0;0m"
222
- exit 1
223
+ @stack = []
224
+ State::state = :error
223
225
  end
224
226
 
225
227
  def interpret(do_end=true) # builds stack from bytecode
226
228
  loop do
227
229
  loaded_bytes = load_bytes(1) # loads in first byte for initial instruction
228
230
  break if loaded_bytes[0] == :end_prg # end of program reached
231
+ break if State::state != :ok
229
232
 
230
233
  case loaded_bytes[0]
231
234
  when :make
@@ -301,7 +304,7 @@ class VM
301
304
  res = (call a.value.fields["__add"], b.value)
302
305
  push_to_stack (to_var res)
303
306
  else
304
- error "Cannot use + on #{a.type}"
307
+ error "Cannot use + on #{codify a}"
305
308
  end
306
309
  when :sub
307
310
  b, a = pop_from_stack, pop_from_stack
@@ -309,7 +312,7 @@ class VM
309
312
  res = (call a.value.fields["__sub"], b.value)
310
313
  push_to_stack (Variable.new res, (get_type res), @global)
311
314
  else
312
- error "Cannot use - on #{a.type}"
315
+ error "Cannot use - on #{codify a}"
313
316
  end
314
317
  when :mul
315
318
  b, a = pop_from_stack, pop_from_stack
@@ -317,7 +320,7 @@ class VM
317
320
  res = (call a.value.fields["__mul"], b.value)
318
321
  push_to_stack (Variable.new res, (get_type res), @global)
319
322
  else
320
- error "Cannot use * on #{a.type}"
323
+ error "Cannot use * on #{codify a}"
321
324
  end
322
325
  when :div
323
326
  b, a = pop_from_stack, pop_from_stack
@@ -325,7 +328,7 @@ class VM
325
328
  res = (call a.value.fields["__div"], b.value)
326
329
  push_to_stack (Variable.new res, (get_type res), @global)
327
330
  else
328
- error "Cannot use / on #{a.type}"
331
+ error "Cannot use / on #{codify a}"
329
332
  end
330
333
  when :mod
331
334
  b, a = pop_from_stack, pop_from_stack
@@ -333,7 +336,7 @@ class VM
333
336
  res = (call a.value.fields["__mod"], b.value)
334
337
  push_to_stack (Variable.new res, (get_type res), @global)
335
338
  else
336
- error "Cannot use % on #{a.type}"
339
+ error "Cannot use % on #{codify a}"
337
340
  end
338
341
  when :pow
339
342
  b, a = pop_from_stack, pop_from_stack
@@ -341,7 +344,7 @@ class VM
341
344
  res = (call a.value.fields["__pow"], b.value)
342
345
  push_to_stack (Variable.new res, (get_type res), @global)
343
346
  else
344
- error "Cannot use ^ on #{a.type}"
347
+ error "Cannot use ^ on #{codify a}"
345
348
  end
346
349
  when :eq
347
350
  b, a = pop_from_stack, pop_from_stack
@@ -349,7 +352,7 @@ class VM
349
352
  res = (call a.value.fields["__eq"], b.value)
350
353
  push_to_stack (Variable.new res, (get_type res), @global)
351
354
  else
352
- error "Cannot use == on #{a.type}"
355
+ error "Cannot use == on #{codify a}"
353
356
  end
354
357
  when :ne
355
358
  b, a = pop_from_stack, pop_from_stack
@@ -357,7 +360,7 @@ class VM
357
360
  res = (call a.value.fields["__neq"], b.value)
358
361
  push_to_stack (Variable.new res, (get_type res), @global)
359
362
  else
360
- error "Cannot use != on #{a.type}"
363
+ error "Cannot use != on #{codify a}"
361
364
  end
362
365
  when :lt
363
366
  b, a = pop_from_stack, pop_from_stack
@@ -365,7 +368,7 @@ class VM
365
368
  res = (call a.value.fields["__lt"], b.value)
366
369
  push_to_stack (Variable.new res, (get_type res), @global)
367
370
  else
368
- error "Cannot use < on #{a.type}"
371
+ error "Cannot use < on #{codify a}"
369
372
  end
370
373
  when :gt
371
374
  b, a = pop_from_stack, pop_from_stack
@@ -373,7 +376,7 @@ class VM
373
376
  res = (call a.value.fields["__gt"], b.value)
374
377
  push_to_stack (Variable.new res, (get_type res), @global)
375
378
  else
376
- error "Cannot use > on #{a.type}"
379
+ error "Cannot use > on #{codify a}"
377
380
  end
378
381
  when :le
379
382
  b, a = pop_from_stack, pop_from_stack
@@ -381,7 +384,7 @@ class VM
381
384
  res = (call a.value.fields["__le"], b.value)
382
385
  push_to_stack (Variable.new res, (get_type res), @global)
383
386
  else
384
- error "Cannot use <= on #{a.type}"
387
+ error "Cannot use <= on #{codify a}"
385
388
  end
386
389
  when :ge
387
390
  b, a = pop_from_stack, pop_from_stack
@@ -389,7 +392,7 @@ class VM
389
392
  res = (call a.value.fields["__ge"], b.value)
390
393
  push_to_stack (Variable.new res, (get_type res), @global)
391
394
  else
392
- error "Cannot use >= on #{a.type}"
395
+ error "Cannot use >= on #{codify a}"
393
396
  end
394
397
  when :jmpi
395
398
  val = pop_from_stack
@@ -419,12 +422,16 @@ class VM
419
422
  if val.value.fields["__reset"]
420
423
  call val.value.fields["__reset"]
421
424
  push_to_stack val
425
+ else
426
+ error "Cannot reset #{codify val}"
422
427
  end
423
428
  when :iter
424
429
  val = pop_from_stack
425
430
  if val.value.fields["__iter"]
426
431
  res = call val.value.fields["__iter"]
427
432
  push_to_stack res
433
+ else
434
+ error "Cannot iterate #{codify val}"
428
435
  end
429
436
  when :end
430
437
  if do_end
@@ -435,45 +442,53 @@ class VM
435
442
  if callable val
436
443
  args = []
437
444
  (arity val).internal.times do
445
+ break if State::state != :ok
438
446
  this = pop_from_stack
439
- unless this
447
+ if !this
440
448
  error "Not enough arguments: expected #{val.value.fields["__arity"].internal}, got #{args.size}"
449
+ else
450
+ args << this
441
451
  end
442
- args << this
443
452
  end
444
- scope = nil
445
- begin
446
- scope = val.scope
447
- rescue
448
- scope = @global
449
- end
450
- ret = call val, *args
451
- if ret
452
- push_to_stack ret
453
+ if State::state == :ok
454
+ scope = nil
455
+ begin
456
+ scope = val.scope
457
+ rescue
458
+ scope = @global
459
+ end
460
+ ret = call val, *args
461
+ if ret
462
+ push_to_stack ret
463
+ end
453
464
  end
454
465
  else
455
- error "Cannot call #{stringify val}"
466
+ error "Cannot call #{codify val}"
456
467
  end
457
468
  when :new
458
469
  val = pop_from_stack
459
470
  if val.value.fields["__new"] and val.value.fields["__arity"]
460
471
  args = []
461
472
  val.value.fields["__arity"].internal.times do
473
+ break if State::state != :ok
462
474
  this = pop_from_stack
463
- unless this
475
+ if !this
464
476
  error "Not enough arguments: expected #{val.value.fields["__arity"].internal}, got #{args.size}"
477
+ else
478
+ args << this
465
479
  end
466
- args << this
467
- end
468
- f = Proc.new do |args, scope|
469
- call val.value.fields["__new"], args, scope
470
480
  end
471
- ret = Variable.new (InstantiatedObj.new f.call args, @global), :instobj, @global
472
- if ret
473
- push_to_stack ret
481
+ if State::state == :ok
482
+ f = Proc.new do |args, scope|
483
+ call val.value.fields["__new"], args, scope
484
+ end
485
+ ret = Variable.new (InstantiatedObj.new f.call args, @global), :instobj, @global
486
+ if ret
487
+ push_to_stack ret
488
+ end
474
489
  end
475
490
  else
476
- error "Cannot instantiate #{stringify val}"
491
+ error "Cannot instantiate #{codify val}"
477
492
  end
478
493
  end
479
494
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sardonyx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.843
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - sugarfi