sardonyx 0.1.5

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 134db5d432fc5be113fff903e155f16cfd8d756b3ee89846cb542fe282d831d0
4
+ data.tar.gz: a89c2707cb7a86c09f6ac5afe265bff9913d55c87346f7ffc75c274c0436b042
5
+ SHA512:
6
+ metadata.gz: ae6c5e8daab94393ae813c3980950ad3cf22e075820f6cdbef46cab336283098bf2aa9d80008185cba53493ea78297fec3b5c0171124082fa50f38243f83b9c7
7
+ data.tar.gz: 2279b27b460bc419e3992d78548e46503eec909695f813e0a6072dcc777ecfc35da19e8ab614de60f0e0356a22711ad391753bafa732b848745fe04cd35db64b
data/bin/sdx ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/ruby
2
+ require "sdx/compiler/parser"
3
+ require "sdx/compiler/compiler"
4
+ require "sdx/vm/vm"
5
+ require "stringio"
6
+
7
+ if ARGV.size == 1
8
+ path = [(File.expand_path File.dirname ARGV[0]), *(ENV.fetch("SDX_PATH", "").split ":")]
9
+ 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
+ else
16
+ path = [(File.expand_path Dir.pwd), *(ENV.fetch("SDX_PATH", "").split ":")]
17
+ vm = VM.new StringIO.new ""
18
+ puts "Sardonyx v 0.0.1"
19
+ def exit(_) end
20
+ 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
29
+ val = vm.stack[-1]
30
+ puts stringify val
31
+ end
32
+ end
@@ -0,0 +1,183 @@
1
+ module Compiler
2
+ class Compiler
3
+ def self.compile(ast)
4
+ bc = ""
5
+ ast.each do |line|
6
+ bc += self.encode_node line
7
+ end
8
+ bc + "\x16"
9
+ end
10
+
11
+ def self.encode_block(node)
12
+ bc = ""
13
+ node.children.each do |child|
14
+ bc += self.encode_node child
15
+ end
16
+ bc
17
+ end
18
+
19
+ def self.encode_node(node)
20
+ bc = ""
21
+ case node.nodetype
22
+ when :assign
23
+ name = node.children[0]
24
+ val = node.children[1]
25
+ case node.value
26
+ when "=" # could also be +=, -=, etc.
27
+ bc += "#{self.encode_node val}\x01\x10#{name}\x18"
28
+ else
29
+ nil
30
+ end
31
+ when :number
32
+ bc += "\x21\x13#{node.value}\x18"
33
+ when :float
34
+ bc += "\x21\x15#{node.value}\x18"
35
+ when :string
36
+ bc += "\x21\x14#{node.value}\x18"
37
+ when :call
38
+ node.children.each do |item|
39
+ bc += self.encode_node item
40
+ end
41
+ bc += self.encode_node node.value
42
+ bc += "\x02"
43
+ when :new
44
+ node.children.each do |item|
45
+ bc += self.encode_node item
46
+ end
47
+ bc += self.encode_node node.value
48
+ bc += "\x31"
49
+ when :op
50
+ node.children.each do |child|
51
+ bc += self.encode_node child
52
+ end
53
+ case node.value
54
+ when "+"
55
+ bc += "\x23"
56
+ when "-"
57
+ bc += "\x24"
58
+ when "*"
59
+ bc += "\x25"
60
+ when "/"
61
+ bc += "\x26"
62
+ when "%"
63
+ bc += "\x27"
64
+ when "^"
65
+ bc += "\x28"
66
+ end
67
+ when :if
68
+ bc += self.encode_node node.value
69
+ case node.children[0].nodetype
70
+ when :block
71
+ i = self.encode_block node.children[0]
72
+ else
73
+ i = self.encode_node node.children[0]
74
+ end
75
+ e = nil
76
+ if node.children[1]
77
+ case node.children[1].nodetype
78
+ when :block
79
+ e = self.encode_block node.children[1]
80
+ else
81
+ e = self.encode_node node.children[1]
82
+ end
83
+ i += "\x2a#{e.size}\x18"
84
+ end
85
+ bc += "\x29#{i.size}\x18" + i
86
+ if e
87
+ bc += e
88
+ end
89
+ when :name
90
+ bc += "\x20#{node.value}\x18"
91
+ when :nil
92
+ bc += "\x21\x2f"
93
+ when :while
94
+ e = self.encode_node node.value
95
+ bc += e
96
+ total = e.size
97
+ b = nil
98
+ case node.children[0].nodetype
99
+ when :block
100
+ b = self.encode_block node.children[0]
101
+ else
102
+ b = self.encode_node node.children[0]
103
+ end
104
+ add = ""
105
+ #bc += "\x2b#{b.size}\x18"
106
+ total += "\x29#{b.size}\x18".size
107
+ add += b
108
+ total += b.size
109
+ total += "\x2a-#{total}\x18".size
110
+ add += "\x2a-#{total}\x18"
111
+ total -= "\x29#{b.size}\x18".size
112
+ total -= e.size
113
+ add = "\x2b#{total}\x18" + add
114
+ bc += add
115
+ when :for
116
+ bc += self.encode_node node.value
117
+ sym = (0...8).map { (65 + rand(26)).chr }.join
118
+ bc += "\x01\x10__#{sym}\x18"
119
+ e = "\x20__#{sym}\x18\x2e"
120
+ if node.children[0]
121
+ e += "\x01\x10#{node.children[0]}\x18"
122
+ else
123
+ e += "\x01\x10_\x18"
124
+ end
125
+ bc += e
126
+ total = e.size
127
+ b = nil
128
+ case node.children[1].nodetype
129
+ when :block
130
+ b = self.encode_block node.children[1]
131
+ else
132
+ b = self.encode_node node.children[1]
133
+ end
134
+ add = ""
135
+ total += "\x29#{b.size}\x18".size
136
+ add += b
137
+ total += b.size
138
+ total += "\x2a-#{total}\x18".size
139
+ add += "\x2a-#{total}\x18"
140
+ total -= "\x29#{b.size}\x18".size
141
+ total -= e.size
142
+ add = "\x2b#{total}\x18" + add
143
+ bc += add
144
+ when :fn
145
+ name = node.value
146
+ args, body = node.children
147
+ if body.nodetype == :block
148
+ body = self.encode_block body
149
+ else
150
+ body = self.encode_node body
151
+ end
152
+ body += "\x16"
153
+ args = args.join "\x07"
154
+ bc += "\x01\x17#{name}\x18#{args}\x08#{body.size}\x18"
155
+ bc += body
156
+ when :object
157
+ name = node.value
158
+ args, body = node.children
159
+ if body.nodetype == :block
160
+ body = self.encode_block body
161
+ else
162
+ body = self.encode_node body
163
+ end
164
+ body += "\x16"
165
+ if args
166
+ args = args.join "\x07"
167
+ else
168
+ args = ""
169
+ end
170
+ bc += "\x01\x30#{name}\x18#{args}\x08#{body.size}\x18"
171
+ bc += body
172
+ when :list
173
+ node.children.each do |item|
174
+ bc += self.encode_node item
175
+ end
176
+ bc += "\x21\x2c#{node.children.size}\x18"
177
+ else
178
+ nil
179
+ end
180
+ bc
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,522 @@
1
+ module Parser
2
+ class Lexer
3
+ TOKENS = {
4
+ /\Aif/ => :if,
5
+ /\Aelse/ => :else,
6
+ /\Awhile/ => :while,
7
+ /\Afor/ => :for,
8
+ /\Ain/ => :in,
9
+ /\Afn/ => :fn,
10
+ /\Aobject/ => :object,
11
+ /\Anew/ => :new,
12
+ /\Arequire/ => :require,
13
+ /\A(<|>|<=|>=|==)/ => :op,
14
+ /\A(\+|-|\*|\/|%)?=/ => :eq,
15
+ /\A(\+|-|\*|\/|%)/ => :op,
16
+ /\A-?[0-9]+/ => :number,
17
+ /\A-?[0-9]+\.[0-9]+/ => :float,
18
+ /\A"([^"]|\\")*"/ => :string,
19
+ /\Anil/ => :nil,
20
+ /\A\(/ => :lpar,
21
+ /\A\)/ => :rpar,
22
+ /\A\[/ => :lbrack,
23
+ /\A\]/ => :rbrack,
24
+ /\A\{/ => :lbrace,
25
+ /\A\}/ => :rbrace,
26
+ /\A,/ => :comma,
27
+ /\A[A-Za-z_][A-Za-z0-9_]*([:.][A-Za-z_][A-Za-z0-9_]*)*/ => :name
28
+ }
29
+
30
+ def self.lex(code)
31
+ lexed = []
32
+ found = false
33
+ while code.size > 0
34
+ TOKENS.each { |re, tag|
35
+ if (code =~ re) != nil
36
+ found = true
37
+ m = (re.match code)
38
+ lexed << [ m[0], tag ]
39
+ code = code[(m.end 0)..code.size].lstrip
40
+ break
41
+ end
42
+ }
43
+ if !found
44
+ puts "Syntax error: ", code
45
+ Kernel.exit 1
46
+ end
47
+ end
48
+ lexed
49
+ end
50
+ end
51
+
52
+ class Node
53
+ attr_reader :nodetype
54
+ attr_reader :children
55
+ attr_reader :value
56
+
57
+ def initialize(nodetype, value = "", children = [])
58
+ @nodetype = nodetype
59
+ @value = value
60
+ @children = children
61
+ end
62
+ end
63
+
64
+ class Parser
65
+ def self.lookahead(tokens, toktype, n)
66
+ if n >= tokens.size
67
+ return false
68
+ end
69
+ tokens[n][1] == toktype
70
+ end
71
+
72
+ def self.expect(tokens, toktype)
73
+ self.lookahead(tokens, toktype, 0)
74
+ end
75
+
76
+ def self.parse_name(tokens)
77
+ if self.expect tokens, :name
78
+ [ (Node.new :name, tokens[0][0], []), 1 ]
79
+ else
80
+ nil
81
+ end
82
+ end
83
+
84
+ def self.parse_nil(tokens)
85
+ if self.expect tokens, :nil
86
+ [ (Node.new :nil, tokens[0][0], []), 1 ]
87
+ else
88
+ nil
89
+ end
90
+ end
91
+
92
+ def self.parse_number(tokens)
93
+ if self.expect tokens, :number
94
+ [ (Node.new :number, tokens[0][0], []), 1 ]
95
+ else
96
+ nil
97
+ end
98
+ end
99
+
100
+ def self.parse_float(tokens)
101
+ if self.expect tokens, :float
102
+ [ (Node.new :float, tokens[0][0], []), 1 ]
103
+ else
104
+ nil
105
+ end
106
+ end
107
+
108
+ def self.parse_string(tokens)
109
+ if self.expect tokens, :string
110
+ [ (Node.new :string, tokens[0][0][1..-2], []), 1 ]
111
+ else
112
+ nil
113
+ end
114
+ end
115
+
116
+ def self.parse_list(tokens)
117
+ unless (self.expect tokens, :lbrack)
118
+ return nil
119
+ end
120
+ tokens = tokens[1..tokens.size]
121
+ children = []
122
+ total = 1
123
+ while true
124
+ if self.expect tokens, :rbrack
125
+ total += 1
126
+ break
127
+ end
128
+ unless self.parse_expr tokens
129
+ return nil
130
+ end
131
+ e, part = self.parse_expr tokens
132
+ children << e
133
+ total += part
134
+ tokens = tokens[part..tokens.size]
135
+ if self.expect tokens, :rbrack
136
+ total += 1
137
+ break
138
+ end
139
+ unless (self.expect tokens, :comma)
140
+ return nil
141
+ end
142
+ total += 1
143
+ tokens = tokens[1..tokens.size]
144
+ end
145
+ [ (Node.new :list, "", children), total ]
146
+ end
147
+
148
+ def self.parse_block(tokens)
149
+ unless (self.expect tokens, :lbrace)
150
+ return nil
151
+ end
152
+ tokens = tokens[1..tokens.size]
153
+ children = []
154
+ total = 1
155
+ while true
156
+ if self.expect tokens, :rbrace
157
+ total += 1
158
+ break
159
+ end
160
+ e = self.parse_expr tokens
161
+ if e
162
+ children << e[0]
163
+ total += e[1]
164
+ tokens = tokens[e[1]..tokens.size]
165
+ else
166
+ puts "Syntax error at token ", tokens[0]
167
+ Kernel.exit 1
168
+ end
169
+ end
170
+ [ (Node.new :block, "", children), total ]
171
+ end
172
+
173
+ def self.parse_literal(tokens)
174
+ self.parse_float(tokens) || (self.parse_block tokens) || (self.parse_name tokens) || (self.parse_number tokens) || (self.parse_list tokens) || (self.parse_string tokens) || (self.parse_nil tokens)
175
+ end
176
+
177
+ def self.parse_call(tokens)
178
+ if self.lookahead tokens, :lpar, 1
179
+ unless (self.parse_literal tokens)
180
+ return nil
181
+ end
182
+ callee = (self.parse_literal tokens)
183
+ callee = callee[0]
184
+ args = []
185
+ tokens = tokens[2..tokens.size]
186
+ total = 2
187
+ if self.expect tokens, :rpar
188
+ return [ (Node.new :call, callee, args), total + 1 ]
189
+ end
190
+ while true
191
+ unless (self.parse_expr tokens)
192
+ return nil
193
+ end
194
+ arg, part = (self.parse_expr tokens)
195
+ total += part
196
+ tokens = tokens[part..tokens.size]
197
+ args << arg
198
+ total += 1
199
+ if self.expect tokens, :rpar
200
+ tokens = tokens[1..tokens.size]
201
+ break
202
+ end
203
+ unless (self.expect tokens, :comma)
204
+ return nil
205
+ end
206
+ tokens = tokens[1..tokens.size]
207
+ end
208
+ return [ (Node.new :call, callee, args), total ]
209
+ else
210
+ nil
211
+ end
212
+ end
213
+
214
+ def self.parse_new(tokens)
215
+ unless self.expect tokens, :new
216
+ return nil
217
+ end
218
+ total = 1
219
+ tokens = tokens[1..tokens.size]
220
+ if self.lookahead tokens, :lpar, 1
221
+ unless (self.parse_literal tokens)
222
+ return nil
223
+ end
224
+ callee = (self.parse_literal tokens)
225
+ callee = callee[0]
226
+ args = []
227
+ tokens = tokens[2..tokens.size]
228
+ total += 2
229
+ if self.expect tokens, :rpar
230
+ return [ (Node.new :call, callee, args), total + 1 ]
231
+ end
232
+ while true
233
+ unless (self.parse_expr tokens)
234
+ return nil
235
+ end
236
+ arg, part = (self.parse_expr tokens)
237
+ total += part
238
+ tokens = tokens[part..tokens.size]
239
+ args << arg
240
+ total += 1
241
+ if self.expect tokens, :rpar
242
+ tokens = tokens[1..tokens.size]
243
+ break
244
+ end
245
+ unless (self.expect tokens, :comma)
246
+ return nil
247
+ end
248
+ tokens = tokens[1..tokens.size]
249
+ end
250
+ return [ (Node.new :new, callee, args), total ]
251
+ else
252
+ nil
253
+ end
254
+ end
255
+
256
+ def self.parse_if(tokens)
257
+ unless self.expect tokens, :if
258
+ return nil
259
+ end
260
+ total = 1
261
+ tokens = tokens[1..tokens.size]
262
+ unless self.parse_expr tokens
263
+ return nil
264
+ end
265
+ e, part = self.parse_expr tokens
266
+ total += part
267
+ tokens = tokens[part..tokens.size]
268
+ unless self.parse_expr tokens
269
+ return nil
270
+ end
271
+ block, part = self.parse_expr tokens
272
+ total += part
273
+ tokens = tokens[part..tokens.size]
274
+ el = nil
275
+ if self.expect tokens, :else
276
+ total += 1
277
+ tokens = tokens[1..tokens.size]
278
+ unless self.parse_expr tokens
279
+ return nil
280
+ end
281
+ el, part = self.parse_expr tokens
282
+ total += part
283
+ end
284
+ return [ (Node.new :if, e, [block, el]), total ]
285
+ end
286
+
287
+ def self.parse_while(tokens)
288
+ unless self.expect tokens, :while
289
+ return nil
290
+ end
291
+ total = 1
292
+ tokens = tokens[1..tokens.size]
293
+ unless self.parse_expr tokens
294
+ return nil
295
+ end
296
+ e, part = self.parse_expr tokens
297
+ total += part
298
+ tokens = tokens[part..tokens.size]
299
+ unless self.parse_expr tokens
300
+ return nil
301
+ end
302
+ block, part = self.parse_expr tokens
303
+ total += part
304
+ return [ (Node.new :while, e, [block]), total ]
305
+ end
306
+
307
+ def self.parse_for(tokens)
308
+ unless self.expect tokens, :for
309
+ return nil
310
+ end
311
+ total = 1
312
+ tokens = tokens[1..tokens.size]
313
+ name = nil
314
+ if self.expect tokens, :name and self.lookahead tokens, :in, 1
315
+ name = tokens[0][0]
316
+ total += 2
317
+ tokens = tokens[2..tokens.size]
318
+ end
319
+ unless self.parse_expr tokens
320
+ return nil
321
+ end
322
+ e, part = self.parse_expr tokens
323
+ total += part
324
+ tokens = tokens[part..tokens.size]
325
+ unless self.parse_expr tokens
326
+ return nil
327
+ end
328
+ block, part = self.parse_expr tokens
329
+ total += part
330
+ return [ (Node.new :for, e, [name, block]), total ]
331
+ end
332
+
333
+ def self.parse_op(tokens)
334
+ total = 0
335
+ unless self.parse_literal tokens
336
+ return nil
337
+ end
338
+ lhs, part = self.parse_literal tokens
339
+ total += part
340
+ tokens = tokens[part..tokens.size]
341
+ unless self.expect tokens, :op
342
+ return nil
343
+ end
344
+ op = tokens[0][0]
345
+ total += 1
346
+ tokens = tokens[1..tokens.size]
347
+ unless self.parse_expr tokens
348
+ return nil
349
+ end
350
+ rhs, part = self.parse_expr tokens
351
+ total += part
352
+ return [ (Node.new :op, op, [lhs, rhs]), total]
353
+ end
354
+
355
+ def self.parse_assign(tokens)
356
+ total = 0
357
+ unless self.expect tokens, :name
358
+ return nil
359
+ end
360
+ name = tokens[0][0]
361
+ total += 1
362
+ tokens = tokens[1..tokens.size]
363
+ unless self.expect tokens, :eq
364
+ return nil
365
+ end
366
+ eq = tokens[0][0]
367
+ total += 1
368
+ tokens = tokens[1..tokens.size]
369
+ unless self.parse_expr tokens
370
+ return nil
371
+ end
372
+ rhs, part = self.parse_expr tokens
373
+ total += part
374
+ return [ (Node.new :assign, eq, [name, rhs]), total]
375
+ end
376
+
377
+ def self.parse_fn(tokens)
378
+ unless self.expect tokens, :fn
379
+ return nil
380
+ end
381
+ total = 1
382
+ tokens = tokens[1..tokens.size]
383
+ unless self.expect tokens, :name
384
+ return nil
385
+ end
386
+ name = tokens[0][0]
387
+ total += 1
388
+ tokens = tokens[1..tokens.size]
389
+ unless self.expect tokens, :lpar
390
+ return nil
391
+ end
392
+ total += 1
393
+ tokens = tokens[1..tokens.size]
394
+ args = []
395
+ while true
396
+ if self.expect tokens, :rpar
397
+ total += 1
398
+ tokens = tokens[1..tokens.size]
399
+ break
400
+ end
401
+ unless self.expect tokens, :name
402
+ return nil
403
+ end
404
+ args << tokens[0][0]
405
+ total += 1
406
+ tokens = tokens[1..tokens.size]
407
+ if self.expect tokens, :rpar
408
+ total += 1
409
+ tokens = tokens[1..tokens.size]
410
+ break
411
+ end
412
+ unless self.expect tokens, :comma
413
+ return nil
414
+ end
415
+ total += 1
416
+ tokens = tokens[1..tokens.size]
417
+ end
418
+ unless self.parse_expr tokens
419
+ return nil
420
+ end
421
+ body, part = self.parse_expr tokens
422
+ total += part
423
+ return [ (Node.new :fn, name, [args, body]), total ]
424
+ end
425
+
426
+ def self.parse_object(tokens)
427
+ unless self.expect tokens, :object
428
+ return nil
429
+ end
430
+ total = 1
431
+ tokens = tokens[1..tokens.size]
432
+ unless self.expect tokens, :name
433
+ return nil
434
+ end
435
+ name = tokens[0][0]
436
+ total += 1
437
+ tokens = tokens[1..tokens.size]
438
+ args = []
439
+ if self.expect tokens, :lpar
440
+ total += 1
441
+ tokens = tokens[1..tokens.size]
442
+ while true
443
+ if self.expect tokens, :rpar
444
+ total += 1
445
+ tokens = tokens[1..tokens.size]
446
+ break
447
+ end
448
+ unless self.expect tokens, :name
449
+ return nil
450
+ end
451
+ args << tokens[0][0]
452
+ total += 1
453
+ tokens = tokens[1..tokens.size]
454
+ if self.expect tokens, :rpar
455
+ total += 1
456
+ tokens = tokens[1..tokens.size]
457
+ break
458
+ end
459
+ unless self.expect tokens, :comma
460
+ return nil
461
+ end
462
+ total += 1
463
+ tokens = tokens[1..tokens.size]
464
+ end
465
+ end
466
+ unless self.parse_expr tokens
467
+ return nil
468
+ end
469
+ body, part = self.parse_expr tokens
470
+ total += part
471
+ return [ (Node.new :object, name, [args, body]), total ]
472
+ end
473
+
474
+ def self.parse_require(tokens)
475
+ unless self.expect tokens, :require
476
+ return nil
477
+ end
478
+ tokens = tokens[1..tokens.size]
479
+ unless self.expect tokens, :string
480
+ return nil
481
+ end
482
+ return [ (Node.new :require, tokens[0][0][1..-2], []), 2 ]
483
+ end
484
+
485
+ def self.parse_expr(tokens)
486
+ (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)
487
+ end
488
+
489
+ def self.parse(tokens, path)
490
+ parsed = []
491
+ while tokens.size > 0
492
+ e = self.parse_expr tokens
493
+ if e
494
+ if e[0].nodetype == :require
495
+ code = nil
496
+ path.each do |search|
497
+ begin
498
+ code = File.read "#{File.join(search, e[0].value)}.sdx"
499
+ rescue
500
+ nil
501
+ end
502
+ end
503
+ unless code
504
+ puts "Cannot find file #{e[0].value}.sdx anywhere in path"
505
+ Kernel.exit 1
506
+ end
507
+ lexed = Lexer.lex code
508
+ ast = self.parse lexed, path
509
+ parsed.concat ast
510
+ else
511
+ parsed << e[0]
512
+ end
513
+ tokens = tokens[e[1]..tokens.size]
514
+ else
515
+ puts "Syntax error at token ", tokens[0][1]
516
+ Kernel.exit 1
517
+ end
518
+ end
519
+ parsed
520
+ end
521
+ end
522
+ end