halunke 0.1.0 → 0.2.0
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/Gemfile.lock +1 -1
- data/exe/halunke +6 -2
- data/lib/halunke/grammar.y +25 -7
- data/lib/halunke/interpreter.rb +2 -15
- data/lib/halunke/lexer.rb +124 -52
- data/lib/halunke/lexer.rl +15 -3
- data/lib/halunke/nodes.rb +45 -7
- data/lib/halunke/parser.rb +129 -51
- data/lib/halunke/runtime.rb +194 -13
- data/lib/halunke/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b621079e4a57b2e4911784de31327cff6fa30a9b
|
4
|
+
data.tar.gz: 3980f6df3d46e58cb6ee08f5a7b7654bb629dbbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 218389d784fd2ba9332c3c24b7cb18079d529dfda97f9cdfbd060ba0b1a3be6fd02418da2ae0c1483e038ca59e5fdeba047111c831c2d00817901cf48ec663b5
|
7
|
+
data.tar.gz: e16520427aca78a5277fce868353cd73d96f2e65653da777b403fda407957ae2099c0c00e10cedeeb11dc9ac4378f44457fe29ebd5c3a6cec26a9bfcd90683a1
|
data/Gemfile.lock
CHANGED
data/exe/halunke
CHANGED
@@ -7,6 +7,10 @@ interpreter = Halunke::Interpreter.new
|
|
7
7
|
|
8
8
|
puts "Halunke REPL. Ctrl+d to quit"
|
9
9
|
while (line = Readline.readline(">> ", true))
|
10
|
-
|
11
|
-
|
10
|
+
begin
|
11
|
+
value = interpreter.eval(line)
|
12
|
+
puts "=> #{value}"
|
13
|
+
rescue Exception => e
|
14
|
+
puts "An Error Occurred: #{e.message}"
|
15
|
+
end
|
12
16
|
end
|
data/lib/halunke/grammar.y
CHANGED
@@ -5,26 +5,43 @@ token STRING
|
|
5
5
|
token BAREWORD
|
6
6
|
token OPEN_PAREN
|
7
7
|
token CLOSE_PAREN
|
8
|
+
token OPEN_CURLY
|
9
|
+
token CLOSE_CURLY
|
8
10
|
token OPERATOR
|
11
|
+
token UNASSIGNED_BAREWORD
|
12
|
+
token OPEN_BRACKET
|
13
|
+
token CLOSE_BRACKET
|
14
|
+
token BAR
|
9
15
|
|
10
16
|
rule
|
11
17
|
Program:
|
12
|
-
|
13
|
-
| Expressions { result = val[0] }
|
18
|
+
Expressions { result = val[0] }
|
14
19
|
;
|
15
20
|
|
16
21
|
Expressions:
|
17
|
-
|
22
|
+
/* empty */ { result = Nodes.new }
|
23
|
+
| Expression Expressions { result = Nodes.new([val[0]]).concat(val[1]) }
|
18
24
|
;
|
19
25
|
|
20
26
|
Expression:
|
21
27
|
Literal
|
22
|
-
|
|
28
|
+
| OPEN_CURLY Expressions CLOSE_CURLY { result = Halunke::FunctionNode.new(Halunke::ArrayNode.new([]), val[1]) }
|
29
|
+
| OPEN_CURLY Args Expressions CLOSE_CURLY { result = Halunke::FunctionNode.new(val[1], val[2]) }
|
30
|
+
| OPEN_PAREN Expression Expressions CLOSE_PAREN { result = Halunke::MessageSendNode.new(val[1], MessageNode.new(val[2].nodes)) }
|
31
|
+
| OPEN_BRACKET Expressions CLOSE_BRACKET { result = ArrayNode.new(val[1].nodes) }
|
23
32
|
;
|
24
33
|
|
25
|
-
|
26
|
-
|
27
|
-
|
34
|
+
Args:
|
35
|
+
BAR UnassignedBarewords BAR { result = Halunke::ArrayNode.new(val[1].nodes) }
|
36
|
+
;
|
37
|
+
|
38
|
+
UnassignedBarewords:
|
39
|
+
/* empty */ { result = Nodes.new }
|
40
|
+
| UnassignedBareword UnassignedBarewords { result = Nodes.new([val[0]]).concat(val[1]) }
|
41
|
+
;
|
42
|
+
|
43
|
+
UnassignedBareword:
|
44
|
+
UNASSIGNED_BAREWORD { result = UnassignedNode.new(BarewordNode.new(val[0])) }
|
28
45
|
;
|
29
46
|
|
30
47
|
Literal:
|
@@ -33,6 +50,7 @@ rule
|
|
33
50
|
/* TODO: Are Operators just Barewords? */
|
34
51
|
| BAREWORD { result = BarewordNode.new(val[0]) }
|
35
52
|
| OPERATOR { result = BarewordNode.new(val[0]) }
|
53
|
+
| UNASSIGNED_BAREWORD { result = UnassignedNode.new(BarewordNode.new(val[0])) }
|
36
54
|
;
|
37
55
|
|
38
56
|
end
|
data/lib/halunke/interpreter.rb
CHANGED
@@ -4,25 +4,12 @@ module Halunke
|
|
4
4
|
class Interpreter
|
5
5
|
def initialize
|
6
6
|
@parser = Parser.new
|
7
|
-
@context =
|
8
|
-
prelude
|
7
|
+
@context = HContext.root_context
|
9
8
|
end
|
10
9
|
|
11
10
|
def eval(str)
|
12
11
|
nodes = @parser.parse(str)
|
13
|
-
nodes.eval(@context)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def prelude
|
19
|
-
@context[:Number] = Halunke::NativeClass.new(
|
20
|
-
"+" => Halunke::NativeFunction.new(->(receiver, args) { receiver.ruby_value + args.first.ruby_value })
|
21
|
-
)
|
22
|
-
|
23
|
-
@context[:String] = Halunke::NativeClass.new(
|
24
|
-
"reverse" => Halunke::NativeFunction.new(->(receiver, _args) { receiver.ruby_value.reverse })
|
25
|
-
)
|
12
|
+
nodes.eval(@context).inspect(@context)
|
26
13
|
end
|
27
14
|
end
|
28
15
|
end
|
data/lib/halunke/lexer.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# line 1 "lib/halunke/lexer.rl"
|
3
3
|
=begin
|
4
4
|
|
5
|
-
# line
|
5
|
+
# line 36 "lib/halunke/lexer.rl"
|
6
6
|
|
7
7
|
=end
|
8
8
|
|
@@ -19,7 +19,10 @@ self._lexer_actions = [
|
|
19
19
|
0, 1, 0, 1, 1, 1, 2, 1,
|
20
20
|
5, 1, 6, 1, 7, 1, 8, 1,
|
21
21
|
9, 1, 10, 1, 11, 1, 12, 1,
|
22
|
-
13,
|
22
|
+
13, 1, 14, 1, 15, 1, 16, 1,
|
23
|
+
17, 1, 18, 1, 19, 1, 20, 1,
|
24
|
+
21, 1, 22, 2, 2, 3, 2, 2,
|
25
|
+
4
|
23
26
|
]
|
24
27
|
|
25
28
|
class << self
|
@@ -27,7 +30,8 @@ class << self
|
|
27
30
|
private :_lexer_key_offsets, :_lexer_key_offsets=
|
28
31
|
end
|
29
32
|
self._lexer_key_offsets = [
|
30
|
-
0, 1,
|
33
|
+
0, 1, 3, 26, 27, 32, 34, 37,
|
34
|
+
39
|
31
35
|
]
|
32
36
|
|
33
37
|
class << self
|
@@ -35,10 +39,12 @@ class << self
|
|
35
39
|
private :_lexer_trans_keys, :_lexer_trans_keys=
|
36
40
|
end
|
37
41
|
self._lexer_trans_keys = [
|
38
|
-
34,
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
34, 48, 57, 32, 34, 39, 40, 41,
|
43
|
+
43, 45, 91, 93, 95, 123, 124, 125,
|
44
|
+
9, 13, 48, 57, 60, 62, 65, 90,
|
45
|
+
97, 122, 34, 95, 65, 90, 97, 122,
|
46
|
+
48, 57, 46, 48, 57, 48, 57, 95,
|
47
|
+
65, 90, 97, 122, 0
|
42
48
|
]
|
43
49
|
|
44
50
|
class << self
|
@@ -46,7 +52,8 @@ class << self
|
|
46
52
|
private :_lexer_single_lengths, :_lexer_single_lengths=
|
47
53
|
end
|
48
54
|
self._lexer_single_lengths = [
|
49
|
-
1,
|
55
|
+
1, 0, 13, 1, 1, 0, 1, 0,
|
56
|
+
1
|
50
57
|
]
|
51
58
|
|
52
59
|
class << self
|
@@ -54,7 +61,8 @@ class << self
|
|
54
61
|
private :_lexer_range_lengths, :_lexer_range_lengths=
|
55
62
|
end
|
56
63
|
self._lexer_range_lengths = [
|
57
|
-
0,
|
64
|
+
0, 1, 5, 0, 2, 1, 1, 1,
|
65
|
+
2
|
58
66
|
]
|
59
67
|
|
60
68
|
class << self
|
@@ -62,7 +70,8 @@ class << self
|
|
62
70
|
private :_lexer_index_offsets, :_lexer_index_offsets=
|
63
71
|
end
|
64
72
|
self._lexer_index_offsets = [
|
65
|
-
0, 2,
|
73
|
+
0, 2, 4, 23, 25, 29, 31, 34,
|
74
|
+
36
|
66
75
|
]
|
67
76
|
|
68
77
|
class << self
|
@@ -70,10 +79,13 @@ class << self
|
|
70
79
|
private :_lexer_trans_targs, :_lexer_trans_targs=
|
71
80
|
end
|
72
81
|
self._lexer_trans_targs = [
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
82
|
+
2, 0, 7, 2, 2, 3, 4, 2,
|
83
|
+
2, 5, 5, 2, 2, 8, 2, 2,
|
84
|
+
2, 2, 6, 2, 8, 8, 2, 2,
|
85
|
+
0, 4, 4, 4, 2, 6, 2, 1,
|
86
|
+
6, 2, 7, 2, 8, 8, 8, 2,
|
87
|
+
2, 2, 2, 2, 2, 2, 2, 2,
|
88
|
+
0
|
77
89
|
]
|
78
90
|
|
79
91
|
class << self
|
@@ -81,10 +93,13 @@ class << self
|
|
81
93
|
private :_lexer_trans_actions, :_lexer_trans_actions=
|
82
94
|
end
|
83
95
|
self._lexer_trans_actions = [
|
84
|
-
7, 0,
|
85
|
-
0,
|
86
|
-
25,
|
87
|
-
|
96
|
+
7, 0, 0, 37, 25, 5, 46, 9,
|
97
|
+
11, 0, 0, 17, 19, 0, 13, 21,
|
98
|
+
15, 25, 5, 23, 0, 0, 27, 7,
|
99
|
+
0, 43, 43, 43, 41, 5, 33, 0,
|
100
|
+
5, 29, 0, 29, 0, 0, 0, 31,
|
101
|
+
39, 37, 35, 41, 33, 29, 29, 31,
|
102
|
+
0
|
88
103
|
]
|
89
104
|
|
90
105
|
class << self
|
@@ -92,7 +107,8 @@ class << self
|
|
92
107
|
private :_lexer_to_state_actions, :_lexer_to_state_actions=
|
93
108
|
end
|
94
109
|
self._lexer_to_state_actions = [
|
95
|
-
0, 1, 0, 0, 0
|
110
|
+
0, 0, 1, 0, 0, 0, 0, 0,
|
111
|
+
0
|
96
112
|
]
|
97
113
|
|
98
114
|
class << self
|
@@ -100,7 +116,8 @@ class << self
|
|
100
116
|
private :_lexer_from_state_actions, :_lexer_from_state_actions=
|
101
117
|
end
|
102
118
|
self._lexer_from_state_actions = [
|
103
|
-
0, 3, 0, 0, 0
|
119
|
+
0, 0, 3, 0, 0, 0, 0, 0,
|
120
|
+
0
|
104
121
|
]
|
105
122
|
|
106
123
|
class << self
|
@@ -108,17 +125,18 @@ class << self
|
|
108
125
|
private :_lexer_eof_trans, :_lexer_eof_trans=
|
109
126
|
end
|
110
127
|
self._lexer_eof_trans = [
|
111
|
-
|
128
|
+
41, 42, 0, 43, 44, 45, 47, 47,
|
129
|
+
48
|
112
130
|
]
|
113
131
|
|
114
132
|
class << self
|
115
133
|
attr_accessor :lexer_start
|
116
134
|
end
|
117
|
-
self.lexer_start =
|
135
|
+
self.lexer_start = 2;
|
118
136
|
class << self
|
119
137
|
attr_accessor :lexer_first_final
|
120
138
|
end
|
121
|
-
self.lexer_first_final =
|
139
|
+
self.lexer_first_final = 2;
|
122
140
|
class << self
|
123
141
|
attr_accessor :lexer_error
|
124
142
|
end
|
@@ -127,10 +145,10 @@ self.lexer_error = -1;
|
|
127
145
|
class << self
|
128
146
|
attr_accessor :lexer_en_main
|
129
147
|
end
|
130
|
-
self.lexer_en_main =
|
148
|
+
self.lexer_en_main = 2;
|
131
149
|
|
132
150
|
|
133
|
-
# line
|
151
|
+
# line 43 "lib/halunke/lexer.rl"
|
134
152
|
@tokens = []
|
135
153
|
end
|
136
154
|
|
@@ -139,7 +157,7 @@ self.lexer_en_main = 1;
|
|
139
157
|
eof = data.length
|
140
158
|
|
141
159
|
|
142
|
-
# line
|
160
|
+
# line 161 "lib/halunke/lexer.rb"
|
143
161
|
begin
|
144
162
|
p ||= 0
|
145
163
|
pe ||= data.length
|
@@ -149,9 +167,9 @@ begin
|
|
149
167
|
act = 0
|
150
168
|
end
|
151
169
|
|
152
|
-
# line
|
170
|
+
# line 51 "lib/halunke/lexer.rl"
|
153
171
|
|
154
|
-
# line
|
172
|
+
# line 173 "lib/halunke/lexer.rb"
|
155
173
|
begin
|
156
174
|
_klen, _trans, _keys, _acts, _nacts = nil
|
157
175
|
_goto_level = 0
|
@@ -181,7 +199,7 @@ begin
|
|
181
199
|
begin
|
182
200
|
ts = p
|
183
201
|
end
|
184
|
-
# line
|
202
|
+
# line 203 "lib/halunke/lexer.rb"
|
185
203
|
end # from state action switch
|
186
204
|
end
|
187
205
|
if _trigger_goto
|
@@ -253,73 +271,127 @@ when 2 then
|
|
253
271
|
te = p+1
|
254
272
|
end
|
255
273
|
when 3 then
|
256
|
-
# line
|
274
|
+
# line 22 "lib/halunke/lexer.rl"
|
257
275
|
begin
|
258
|
-
act =
|
276
|
+
act = 3; end
|
259
277
|
when 4 then
|
260
|
-
# line
|
278
|
+
# line 33 "lib/halunke/lexer.rl"
|
261
279
|
begin
|
262
|
-
act =
|
280
|
+
act = 14; end
|
263
281
|
when 5 then
|
264
|
-
# line
|
282
|
+
# line 21 "lib/halunke/lexer.rl"
|
265
283
|
begin
|
266
284
|
te = p+1
|
267
285
|
begin emit(:STRING, data[ts+1...te-1]) end
|
268
286
|
end
|
269
287
|
when 6 then
|
270
|
-
# line
|
288
|
+
# line 24 "lib/halunke/lexer.rl"
|
271
289
|
begin
|
272
290
|
te = p+1
|
273
291
|
begin emit(:OPEN_PAREN, data[ts...te]) end
|
274
292
|
end
|
275
293
|
when 7 then
|
276
|
-
# line
|
294
|
+
# line 25 "lib/halunke/lexer.rl"
|
277
295
|
begin
|
278
296
|
te = p+1
|
279
297
|
begin emit(:CLOSE_PAREN, data[ts...te]) end
|
280
298
|
end
|
281
299
|
when 8 then
|
282
|
-
# line
|
300
|
+
# line 26 "lib/halunke/lexer.rl"
|
283
301
|
begin
|
284
302
|
te = p+1
|
303
|
+
begin emit(:OPEN_CURLY, data[ts...te]) end
|
285
304
|
end
|
286
305
|
when 9 then
|
287
|
-
# line
|
306
|
+
# line 27 "lib/halunke/lexer.rl"
|
288
307
|
begin
|
289
308
|
te = p+1
|
290
|
-
begin
|
309
|
+
begin emit(:CLOSE_CURLY, data[ts...te]) end
|
291
310
|
end
|
292
311
|
when 10 then
|
293
|
-
# line
|
312
|
+
# line 28 "lib/halunke/lexer.rl"
|
313
|
+
begin
|
314
|
+
te = p+1
|
315
|
+
begin emit(:OPEN_BRACKET, data[ts...te]) end
|
316
|
+
end
|
317
|
+
when 11 then
|
318
|
+
# line 29 "lib/halunke/lexer.rl"
|
319
|
+
begin
|
320
|
+
te = p+1
|
321
|
+
begin emit(:CLOSE_BRACKET, data[ts...te]) end
|
322
|
+
end
|
323
|
+
when 12 then
|
324
|
+
# line 30 "lib/halunke/lexer.rl"
|
325
|
+
begin
|
326
|
+
te = p+1
|
327
|
+
begin emit(:BAR, data[ts...te]) end
|
328
|
+
end
|
329
|
+
when 13 then
|
330
|
+
# line 31 "lib/halunke/lexer.rl"
|
331
|
+
begin
|
332
|
+
te = p+1
|
333
|
+
begin emit(:OPERATOR, data[ts ... te]) end
|
334
|
+
end
|
335
|
+
when 14 then
|
336
|
+
# line 32 "lib/halunke/lexer.rl"
|
337
|
+
begin
|
338
|
+
te = p+1
|
339
|
+
end
|
340
|
+
when 15 then
|
341
|
+
# line 33 "lib/halunke/lexer.rl"
|
342
|
+
begin
|
343
|
+
te = p+1
|
344
|
+
begin raise "Could not lex '#{ data[ts...te] }'" end
|
345
|
+
end
|
346
|
+
when 16 then
|
347
|
+
# line 20 "lib/halunke/lexer.rl"
|
348
|
+
begin
|
349
|
+
te = p
|
350
|
+
p = p - 1; begin emit(:NUMBER, data[ts...te].to_r) end
|
351
|
+
end
|
352
|
+
when 17 then
|
353
|
+
# line 23 "lib/halunke/lexer.rl"
|
294
354
|
begin
|
295
355
|
te = p
|
296
356
|
p = p - 1; begin emit(:BAREWORD, data[ts...te]) end
|
297
357
|
end
|
298
|
-
when
|
299
|
-
# line
|
358
|
+
when 18 then
|
359
|
+
# line 31 "lib/halunke/lexer.rl"
|
360
|
+
begin
|
361
|
+
te = p
|
362
|
+
p = p - 1; begin emit(:OPERATOR, data[ts ... te]) end
|
363
|
+
end
|
364
|
+
when 19 then
|
365
|
+
# line 33 "lib/halunke/lexer.rl"
|
300
366
|
begin
|
301
367
|
te = p
|
302
368
|
p = p - 1; begin raise "Could not lex '#{ data[ts...te] }'" end
|
303
369
|
end
|
304
|
-
when
|
305
|
-
# line
|
370
|
+
when 20 then
|
371
|
+
# line 20 "lib/halunke/lexer.rl"
|
372
|
+
begin
|
373
|
+
begin p = ((te))-1; end
|
374
|
+
begin emit(:NUMBER, data[ts...te].to_r) end
|
375
|
+
end
|
376
|
+
when 21 then
|
377
|
+
# line 33 "lib/halunke/lexer.rl"
|
306
378
|
begin
|
307
379
|
begin p = ((te))-1; end
|
308
380
|
begin raise "Could not lex '#{ data[ts...te] }'" end
|
309
381
|
end
|
310
|
-
when
|
382
|
+
when 22 then
|
311
383
|
# line 1 "NONE"
|
312
384
|
begin
|
313
385
|
case act
|
314
|
-
when
|
386
|
+
when 3 then
|
315
387
|
begin begin p = ((te))-1; end
|
316
|
-
emit(:
|
317
|
-
when
|
388
|
+
emit(:UNASSIGNED_BAREWORD, data[ts+1 ...te]) end
|
389
|
+
when 14 then
|
318
390
|
begin begin p = ((te))-1; end
|
319
|
-
|
391
|
+
raise "Could not lex '#{ data[ts...te] }'" end
|
320
392
|
end
|
321
393
|
end
|
322
|
-
# line
|
394
|
+
# line 395 "lib/halunke/lexer.rb"
|
323
395
|
end # action switch
|
324
396
|
end
|
325
397
|
end
|
@@ -339,7 +411,7 @@ when 0 then
|
|
339
411
|
# line 1 "NONE"
|
340
412
|
begin
|
341
413
|
ts = nil; end
|
342
|
-
# line
|
414
|
+
# line 415 "lib/halunke/lexer.rb"
|
343
415
|
end # to state action switch
|
344
416
|
end
|
345
417
|
if _trigger_goto
|
@@ -366,7 +438,7 @@ end
|
|
366
438
|
end
|
367
439
|
end
|
368
440
|
|
369
|
-
# line
|
441
|
+
# line 52 "lib/halunke/lexer.rl"
|
370
442
|
|
371
443
|
@tokens
|
372
444
|
end
|
data/lib/halunke/lexer.rl
CHANGED
@@ -2,20 +2,32 @@
|
|
2
2
|
%%{
|
3
3
|
machine lexer;
|
4
4
|
|
5
|
-
number = ('+'|'-')?[0-9]
|
5
|
+
number = ('+'|'-')?[0-9]+('.'[0-9]+)?;
|
6
6
|
string = '"' [^"]* '"';
|
7
|
+
unassigned_bareword = "'" [a-zA-Z_]+;
|
7
8
|
bareword = [a-zA-Z_]+;
|
8
9
|
open_paren = '(';
|
9
10
|
close_paren = ')';
|
10
|
-
|
11
|
+
open_curly = '{';
|
12
|
+
close_curly = '}';
|
13
|
+
open_bracket = '[';
|
14
|
+
close_bracket = ']';
|
15
|
+
bar = "|";
|
16
|
+
operator = '+' | '-' | '<' | '>' | '=';
|
11
17
|
|
12
18
|
main := |*
|
13
19
|
|
14
|
-
number => { emit(:NUMBER, data[ts...te].
|
20
|
+
number => { emit(:NUMBER, data[ts...te].to_r) };
|
15
21
|
string => { emit(:STRING, data[ts+1...te-1]) };
|
22
|
+
unassigned_bareword => { emit(:UNASSIGNED_BAREWORD, data[ts+1 ...te]) };
|
16
23
|
bareword => { emit(:BAREWORD, data[ts...te]) };
|
17
24
|
open_paren => { emit(:OPEN_PAREN, data[ts...te]) };
|
18
25
|
close_paren => { emit(:CLOSE_PAREN, data[ts...te]) };
|
26
|
+
open_curly => { emit(:OPEN_CURLY, data[ts...te]) };
|
27
|
+
close_curly => { emit(:CLOSE_CURLY, data[ts...te]) };
|
28
|
+
open_bracket => { emit(:OPEN_BRACKET, data[ts...te]) };
|
29
|
+
close_bracket => { emit(:CLOSE_BRACKET, data[ts...te]) };
|
30
|
+
bar => { emit(:BAR, data[ts...te]) };
|
19
31
|
operator => { emit(:OPERATOR, data[ts ... te]) };
|
20
32
|
space;
|
21
33
|
any => { raise "Could not lex '#{ data[ts...te] }'" };
|
data/lib/halunke/nodes.rb
CHANGED
@@ -25,31 +25,69 @@ module Halunke
|
|
25
25
|
|
26
26
|
class NumberNode < LiteralNode
|
27
27
|
def eval(context)
|
28
|
-
context[
|
28
|
+
context["Number"].create_instance(value)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
class StringNode < LiteralNode
|
33
33
|
def eval(context)
|
34
|
-
context[
|
34
|
+
context["String"].create_instance(value)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
38
|
class BarewordNode < LiteralNode
|
39
|
+
def eval(context)
|
40
|
+
context[value]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
UnassignedNode = Struct.new(:node) do
|
45
|
+
def eval(context)
|
46
|
+
raise "Not unassigned: #{node.value} has value #{context[node.value].inspect}" if context.key? node.value
|
47
|
+
context["UnassignedBareword"].create_instance(node.value)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
FunctionNode = Struct.new(:params, :body) do
|
52
|
+
def eval(_context)
|
53
|
+
signature = params.nodes.map(&:node).map(&:value)
|
54
|
+
|
55
|
+
HFunction.new(signature, lambda { |context|
|
56
|
+
body.eval(context)
|
57
|
+
})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
ArrayNode = Struct.new(:nodes) do
|
62
|
+
def initialize(nodes = [])
|
63
|
+
super(nodes)
|
64
|
+
end
|
65
|
+
|
66
|
+
def eval(context)
|
67
|
+
context["Array"].create_instance(nodes.map { |node| node.eval(context) })
|
68
|
+
end
|
39
69
|
end
|
40
70
|
|
41
71
|
MessageSendNode = Struct.new(:receiver, :message) do
|
42
72
|
def eval(context)
|
43
|
-
receiver.eval(context).receive_message(*message.eval(context))
|
73
|
+
receiver.eval(context).receive_message(context, *message.eval(context))
|
44
74
|
end
|
45
75
|
end
|
46
76
|
|
47
77
|
MessageNode = Struct.new(:nodes) do
|
48
78
|
def eval(context)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
79
|
+
if nodes.length == 1
|
80
|
+
[nodes[0].value, []]
|
81
|
+
elsif nodes.length.even?
|
82
|
+
name = []
|
83
|
+
message = []
|
84
|
+
nodes.each_slice(2) do |name_part, value|
|
85
|
+
name.push(name_part.value)
|
86
|
+
message.push(value.eval(context))
|
87
|
+
end
|
88
|
+
[name.join(" "), message]
|
89
|
+
else
|
90
|
+
raise "Parse Error"
|
53
91
|
end
|
54
92
|
end
|
55
93
|
end
|
data/lib/halunke/parser.rb
CHANGED
@@ -13,7 +13,7 @@ require "halunke/nodes"
|
|
13
13
|
module Halunke
|
14
14
|
class Parser < Racc::Parser
|
15
15
|
|
16
|
-
module_eval(<<'...end grammar.y/module_eval...', 'grammar.y',
|
16
|
+
module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 64)
|
17
17
|
|
18
18
|
def parse(code)
|
19
19
|
@tokens = Lexer.new.tokenize(code)
|
@@ -27,52 +27,74 @@ end
|
|
27
27
|
##### State transition tables begin ###
|
28
28
|
|
29
29
|
racc_action_table = [
|
30
|
-
|
31
|
-
|
32
|
-
8,
|
30
|
+
8, 9, 10, 6, 13, 5, 20, 11, 12, 7,
|
31
|
+
21, 17, 8, 9, 10, 6, 25, 5, 27, 11,
|
32
|
+
12, 7, 8, 9, 10, 6, 28, 5, 29, 11,
|
33
|
+
12, 7, 8, 9, 10, 6, 25, 5, 31, 11,
|
34
|
+
12, 7, 8, 9, 10, 6, nil, 5, nil, 11,
|
35
|
+
12, 7, 8, 9, 10, 6, nil, 5, nil, 11,
|
36
|
+
12, 7, 8, 9, 10, 6, nil, 5, nil, 11,
|
37
|
+
12, 7 ]
|
33
38
|
|
34
39
|
racc_action_check = [
|
35
|
-
|
36
|
-
|
37
|
-
|
40
|
+
5, 5, 5, 5, 1, 5, 13, 5, 5, 5,
|
41
|
+
15, 5, 0, 0, 0, 0, 17, 0, 19, 0,
|
42
|
+
0, 0, 3, 3, 3, 3, 22, 3, 23, 3,
|
43
|
+
3, 3, 6, 6, 6, 6, 24, 6, 26, 6,
|
44
|
+
6, 6, 7, 7, 7, 7, nil, 7, nil, 7,
|
45
|
+
7, 7, 16, 16, 16, 16, nil, 16, nil, 16,
|
46
|
+
16, 16, 18, 18, 18, 18, nil, 18, nil, 18,
|
47
|
+
18, 18 ]
|
38
48
|
|
39
49
|
racc_action_pointer = [
|
40
|
-
|
41
|
-
|
50
|
+
10, 4, nil, 20, nil, -2, 30, 40, nil, nil,
|
51
|
+
nil, nil, nil, 6, nil, 2, 50, 6, 60, 6,
|
52
|
+
nil, nil, 18, 15, 26, nil, 32, nil, nil, nil,
|
53
|
+
nil, nil ]
|
42
54
|
|
43
55
|
racc_action_default = [
|
44
|
-
-
|
45
|
-
-
|
56
|
+
-2, -18, -1, -2, -4, -2, -18, -2, -13, -14,
|
57
|
+
-15, -16, -17, -18, -3, -18, -2, -10, -2, -18,
|
58
|
+
32, -5, -18, -18, -10, -12, -18, -8, -6, -9,
|
59
|
+
-11, -7 ]
|
46
60
|
|
47
61
|
racc_goto_table = [
|
48
|
-
|
62
|
+
2, 23, 1, 14, 18, 15, 16, 19, 30, nil,
|
63
|
+
nil, nil, nil, nil, nil, nil, 22, nil, 26 ]
|
49
64
|
|
50
65
|
racc_goto_check = [
|
51
|
-
|
66
|
+
2, 6, 1, 2, 3, 2, 5, 2, 6, nil,
|
67
|
+
nil, nil, nil, nil, nil, nil, 2, nil, 2 ]
|
52
68
|
|
53
69
|
racc_goto_pointer = [
|
54
|
-
nil, 2,
|
70
|
+
nil, 2, 0, -2, nil, 1, -16, nil ]
|
55
71
|
|
56
72
|
racc_goto_default = [
|
57
|
-
nil, nil, nil, nil,
|
73
|
+
nil, nil, nil, 3, 4, nil, nil, 24 ]
|
58
74
|
|
59
75
|
racc_reduce_table = [
|
60
76
|
0, 0, :racc_error,
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
1,
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
77
|
+
1, 15, :_reduce_1,
|
78
|
+
0, 16, :_reduce_2,
|
79
|
+
2, 16, :_reduce_3,
|
80
|
+
1, 17, :_reduce_none,
|
81
|
+
3, 17, :_reduce_5,
|
82
|
+
4, 17, :_reduce_6,
|
83
|
+
4, 17, :_reduce_7,
|
84
|
+
3, 17, :_reduce_8,
|
85
|
+
3, 19, :_reduce_9,
|
86
|
+
0, 20, :_reduce_10,
|
87
|
+
2, 20, :_reduce_11,
|
88
|
+
1, 21, :_reduce_12,
|
89
|
+
1, 18, :_reduce_13,
|
90
|
+
1, 18, :_reduce_14,
|
91
|
+
1, 18, :_reduce_15,
|
92
|
+
1, 18, :_reduce_16,
|
93
|
+
1, 18, :_reduce_17 ]
|
94
|
+
|
95
|
+
racc_reduce_n = 18
|
96
|
+
|
97
|
+
racc_shift_n = 32
|
76
98
|
|
77
99
|
racc_token_table = {
|
78
100
|
false => 0,
|
@@ -82,9 +104,15 @@ racc_token_table = {
|
|
82
104
|
:BAREWORD => 4,
|
83
105
|
:OPEN_PAREN => 5,
|
84
106
|
:CLOSE_PAREN => 6,
|
85
|
-
:
|
107
|
+
:OPEN_CURLY => 7,
|
108
|
+
:CLOSE_CURLY => 8,
|
109
|
+
:OPERATOR => 9,
|
110
|
+
:UNASSIGNED_BAREWORD => 10,
|
111
|
+
:OPEN_BRACKET => 11,
|
112
|
+
:CLOSE_BRACKET => 12,
|
113
|
+
:BAR => 13 }
|
86
114
|
|
87
|
-
racc_nt_base =
|
115
|
+
racc_nt_base = 14
|
88
116
|
|
89
117
|
racc_use_result_var = true
|
90
118
|
|
@@ -112,13 +140,21 @@ Racc_token_to_s_table = [
|
|
112
140
|
"BAREWORD",
|
113
141
|
"OPEN_PAREN",
|
114
142
|
"CLOSE_PAREN",
|
143
|
+
"OPEN_CURLY",
|
144
|
+
"CLOSE_CURLY",
|
115
145
|
"OPERATOR",
|
146
|
+
"UNASSIGNED_BAREWORD",
|
147
|
+
"OPEN_BRACKET",
|
148
|
+
"CLOSE_BRACKET",
|
149
|
+
"BAR",
|
116
150
|
"$start",
|
117
151
|
"Program",
|
118
152
|
"Expressions",
|
119
153
|
"Expression",
|
120
154
|
"Literal",
|
121
|
-
"
|
155
|
+
"Args",
|
156
|
+
"UnassignedBarewords",
|
157
|
+
"UnassignedBareword" ]
|
122
158
|
|
123
159
|
Racc_debug_parser = false
|
124
160
|
|
@@ -126,78 +162,120 @@ Racc_debug_parser = false
|
|
126
162
|
|
127
163
|
# reduce 0 omitted
|
128
164
|
|
129
|
-
module_eval(<<'.,.,', 'grammar.y',
|
165
|
+
module_eval(<<'.,.,', 'grammar.y', 17)
|
130
166
|
def _reduce_1(val, _values, result)
|
131
|
-
result =
|
167
|
+
result = val[0]
|
132
168
|
result
|
133
169
|
end
|
134
170
|
.,.,
|
135
171
|
|
136
|
-
module_eval(<<'.,.,', 'grammar.y',
|
172
|
+
module_eval(<<'.,.,', 'grammar.y', 21)
|
137
173
|
def _reduce_2(val, _values, result)
|
138
|
-
result =
|
174
|
+
result = Nodes.new
|
139
175
|
result
|
140
176
|
end
|
141
177
|
.,.,
|
142
178
|
|
143
|
-
module_eval(<<'.,.,', 'grammar.y',
|
179
|
+
module_eval(<<'.,.,', 'grammar.y', 22)
|
144
180
|
def _reduce_3(val, _values, result)
|
145
|
-
result = Nodes.new(val)
|
181
|
+
result = Nodes.new([val[0]]).concat(val[1])
|
146
182
|
result
|
147
183
|
end
|
148
184
|
.,.,
|
149
185
|
|
150
186
|
# reduce 4 omitted
|
151
187
|
|
152
|
-
module_eval(<<'.,.,', 'grammar.y',
|
188
|
+
module_eval(<<'.,.,', 'grammar.y', 27)
|
153
189
|
def _reduce_5(val, _values, result)
|
154
|
-
result = Halunke::
|
190
|
+
result = Halunke::FunctionNode.new(Halunke::ArrayNode.new([]), val[1])
|
155
191
|
result
|
156
192
|
end
|
157
193
|
.,.,
|
158
194
|
|
159
|
-
module_eval(<<'.,.,', 'grammar.y',
|
195
|
+
module_eval(<<'.,.,', 'grammar.y', 28)
|
160
196
|
def _reduce_6(val, _values, result)
|
161
|
-
result =
|
197
|
+
result = Halunke::FunctionNode.new(val[1], val[2])
|
162
198
|
result
|
163
199
|
end
|
164
200
|
.,.,
|
165
201
|
|
166
|
-
module_eval(<<'.,.,', 'grammar.y',
|
202
|
+
module_eval(<<'.,.,', 'grammar.y', 29)
|
167
203
|
def _reduce_7(val, _values, result)
|
168
|
-
result =
|
204
|
+
result = Halunke::MessageSendNode.new(val[1], MessageNode.new(val[2].nodes))
|
169
205
|
result
|
170
206
|
end
|
171
207
|
.,.,
|
172
208
|
|
173
209
|
module_eval(<<'.,.,', 'grammar.y', 30)
|
174
210
|
def _reduce_8(val, _values, result)
|
175
|
-
result =
|
211
|
+
result = ArrayNode.new(val[1].nodes)
|
176
212
|
result
|
177
213
|
end
|
178
214
|
.,.,
|
179
215
|
|
180
|
-
module_eval(<<'.,.,', 'grammar.y',
|
216
|
+
module_eval(<<'.,.,', 'grammar.y', 34)
|
181
217
|
def _reduce_9(val, _values, result)
|
182
|
-
result =
|
218
|
+
result = Halunke::ArrayNode.new(val[1].nodes)
|
183
219
|
result
|
184
220
|
end
|
185
221
|
.,.,
|
186
222
|
|
187
|
-
module_eval(<<'.,.,', 'grammar.y',
|
223
|
+
module_eval(<<'.,.,', 'grammar.y', 38)
|
188
224
|
def _reduce_10(val, _values, result)
|
189
|
-
result =
|
225
|
+
result = Nodes.new
|
190
226
|
result
|
191
227
|
end
|
192
228
|
.,.,
|
193
229
|
|
194
|
-
module_eval(<<'.,.,', 'grammar.y',
|
230
|
+
module_eval(<<'.,.,', 'grammar.y', 39)
|
195
231
|
def _reduce_11(val, _values, result)
|
232
|
+
result = Nodes.new([val[0]]).concat(val[1])
|
233
|
+
result
|
234
|
+
end
|
235
|
+
.,.,
|
236
|
+
|
237
|
+
module_eval(<<'.,.,', 'grammar.y', 43)
|
238
|
+
def _reduce_12(val, _values, result)
|
239
|
+
result = UnassignedNode.new(BarewordNode.new(val[0]))
|
240
|
+
result
|
241
|
+
end
|
242
|
+
.,.,
|
243
|
+
|
244
|
+
module_eval(<<'.,.,', 'grammar.y', 47)
|
245
|
+
def _reduce_13(val, _values, result)
|
246
|
+
result = NumberNode.new(val[0])
|
247
|
+
result
|
248
|
+
end
|
249
|
+
.,.,
|
250
|
+
|
251
|
+
module_eval(<<'.,.,', 'grammar.y', 48)
|
252
|
+
def _reduce_14(val, _values, result)
|
253
|
+
result = StringNode.new(val[0])
|
254
|
+
result
|
255
|
+
end
|
256
|
+
.,.,
|
257
|
+
|
258
|
+
module_eval(<<'.,.,', 'grammar.y', 50)
|
259
|
+
def _reduce_15(val, _values, result)
|
196
260
|
result = BarewordNode.new(val[0])
|
197
261
|
result
|
198
262
|
end
|
199
263
|
.,.,
|
200
264
|
|
265
|
+
module_eval(<<'.,.,', 'grammar.y', 51)
|
266
|
+
def _reduce_16(val, _values, result)
|
267
|
+
result = BarewordNode.new(val[0])
|
268
|
+
result
|
269
|
+
end
|
270
|
+
.,.,
|
271
|
+
|
272
|
+
module_eval(<<'.,.,', 'grammar.y', 52)
|
273
|
+
def _reduce_17(val, _values, result)
|
274
|
+
result = UnassignedNode.new(BarewordNode.new(val[0]))
|
275
|
+
result
|
276
|
+
end
|
277
|
+
.,.,
|
278
|
+
|
201
279
|
def _reduce_none(val, _values, result)
|
202
280
|
val[0]
|
203
281
|
end
|
data/lib/halunke/runtime.rb
CHANGED
@@ -1,41 +1,222 @@
|
|
1
1
|
# This file is not tested directly right now,
|
2
2
|
# because I'm not sure if this structure is good
|
3
|
+
# They are all prefixed with H to prevent collisions with Ruby's equivalents
|
3
4
|
module Halunke
|
4
|
-
class
|
5
|
-
def initialize(methods)
|
5
|
+
class HClass
|
6
|
+
def initialize(name, methods)
|
7
|
+
@name = name
|
6
8
|
@runtime_methods = methods
|
7
9
|
end
|
8
10
|
|
9
|
-
def create_instance(ruby_value)
|
10
|
-
|
11
|
+
def create_instance(ruby_value = nil)
|
12
|
+
HObject.new(self, ruby_value)
|
11
13
|
end
|
12
14
|
|
13
15
|
def lookup(message)
|
14
|
-
@runtime_methods
|
16
|
+
@runtime_methods.fetch(message)
|
17
|
+
rescue KeyError
|
18
|
+
raise "Class #{@name} has no method to respond to message '#{message}'"
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
18
|
-
class
|
22
|
+
class HObject
|
19
23
|
attr_reader :ruby_value
|
20
24
|
|
21
|
-
def initialize(runtime_class, ruby_value)
|
25
|
+
def initialize(runtime_class, ruby_value = nil)
|
22
26
|
@runtime_class = runtime_class
|
23
27
|
@ruby_value = ruby_value
|
24
28
|
end
|
25
29
|
|
26
|
-
def receive_message(message_name, message_value)
|
30
|
+
def receive_message(context, message_name, message_value)
|
27
31
|
m = @runtime_class.lookup(message_name)
|
28
|
-
m.call(
|
32
|
+
m.call(context, [self].concat(message_value))
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect(context)
|
36
|
+
receive_message(context, "inspect", []).ruby_value
|
29
37
|
end
|
30
38
|
end
|
31
39
|
|
32
|
-
class
|
33
|
-
def initialize(fn)
|
40
|
+
class HFunction
|
41
|
+
def initialize(signature, fn)
|
42
|
+
@signature = signature
|
34
43
|
@fn = fn
|
35
44
|
end
|
36
45
|
|
37
|
-
|
38
|
-
|
46
|
+
# TODO: This is a little bit of duplication that could probably be cleaned up by making functions proper objects
|
47
|
+
def receive_message(context, message_name, message_value)
|
48
|
+
raise "Class Function has no method to respond to message '#{message_name}'" unless message_name == "call"
|
49
|
+
call(context, message_value[0].ruby_value)
|
50
|
+
end
|
51
|
+
|
52
|
+
def call(parent_context, args)
|
53
|
+
context = parent_context.create_child
|
54
|
+
@signature.zip(args).each do |name, value|
|
55
|
+
context[name.to_s] = value
|
56
|
+
end
|
57
|
+
@fn.call(context)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class HContext
|
62
|
+
def initialize(parent_context = nil)
|
63
|
+
@parent_context = parent_context
|
64
|
+
@context = {}
|
65
|
+
end
|
66
|
+
|
67
|
+
def []=(name, value)
|
68
|
+
@context[name] = value
|
69
|
+
end
|
70
|
+
|
71
|
+
def [](name)
|
72
|
+
@context.fetch(name)
|
73
|
+
rescue KeyError
|
74
|
+
raise "Undefined bareword '#{name}'" if @parent_context.nil?
|
75
|
+
@parent_context[name]
|
76
|
+
end
|
77
|
+
|
78
|
+
def parent
|
79
|
+
@parent_context
|
80
|
+
end
|
81
|
+
|
82
|
+
def key?(name)
|
83
|
+
@context.key?(name)
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_child
|
87
|
+
HContext.new(self)
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.root_context
|
91
|
+
context = new
|
92
|
+
|
93
|
+
context["Number"] = HNumber
|
94
|
+
context["String"] = HString
|
95
|
+
context["Array"] = HArray
|
96
|
+
context["UnassignedBareword"] = HUnassignedBareword
|
97
|
+
context["True"] = HTrue
|
98
|
+
context["False"] = HFalse
|
99
|
+
context["true"] = HTrue.create_instance
|
100
|
+
context["false"] = HFalse.create_instance
|
101
|
+
|
102
|
+
context
|
39
103
|
end
|
40
104
|
end
|
105
|
+
|
106
|
+
HNumber = HClass.new(
|
107
|
+
"Number",
|
108
|
+
"+" => HFunction.new([:self, :other], lambda { |context|
|
109
|
+
HNumber.create_instance(context["self"].ruby_value + context["other"].ruby_value)
|
110
|
+
}),
|
111
|
+
"<" => HFunction.new([:self, :other], lambda { |context|
|
112
|
+
if context["self"].ruby_value < context["other"].ruby_value
|
113
|
+
HTrue.create_instance
|
114
|
+
else
|
115
|
+
HFalse.create_instance
|
116
|
+
end
|
117
|
+
}),
|
118
|
+
">" => HFunction.new([:self, :other], lambda { |context|
|
119
|
+
if context["self"].ruby_value > context["other"].ruby_value
|
120
|
+
HTrue.create_instance
|
121
|
+
else
|
122
|
+
HFalse.create_instance
|
123
|
+
end
|
124
|
+
}),
|
125
|
+
"=" => HFunction.new([:self, :other], lambda { |context|
|
126
|
+
if context["self"].ruby_value == context["other"].ruby_value
|
127
|
+
HTrue.create_instance
|
128
|
+
else
|
129
|
+
HFalse.create_instance
|
130
|
+
end
|
131
|
+
}),
|
132
|
+
"inspect" => HFunction.new([:self], lambda { |context|
|
133
|
+
float_value = context["self"].ruby_value.to_f
|
134
|
+
float_value = float_value.to_i if float_value.to_i == float_value
|
135
|
+
HString.create_instance(float_value.to_s)
|
136
|
+
})
|
137
|
+
)
|
138
|
+
|
139
|
+
HString = HClass.new(
|
140
|
+
"String",
|
141
|
+
"reverse" => HFunction.new([:self], lambda { |context|
|
142
|
+
HString.create_instance(context["self"].ruby_value.reverse)
|
143
|
+
}),
|
144
|
+
"replace with" => HFunction.new([:self, :searchword, :replacement], lambda { |context|
|
145
|
+
result = context["self"].ruby_value.gsub(
|
146
|
+
context["searchword"].ruby_value,
|
147
|
+
context["replacement"].ruby_value
|
148
|
+
)
|
149
|
+
HString.create_instance(result)
|
150
|
+
}),
|
151
|
+
"=" => HFunction.new([:self, :other], lambda { |context|
|
152
|
+
if context["self"].ruby_value == context["other"].ruby_value
|
153
|
+
HTrue.create_instance
|
154
|
+
else
|
155
|
+
HFalse.create_instance
|
156
|
+
end
|
157
|
+
}),
|
158
|
+
"inspect" => HFunction.new([:self], lambda { |context|
|
159
|
+
HString.create_instance(context["self"].ruby_value.inspect)
|
160
|
+
})
|
161
|
+
)
|
162
|
+
|
163
|
+
HArray = HClass.new(
|
164
|
+
"Array",
|
165
|
+
"inspect" => HFunction.new([:self], lambda { |context|
|
166
|
+
inspected_members = context["self"].ruby_value.map { |member| member.inspect(context) }
|
167
|
+
HString.create_instance("[#{inspected_members.join(' ')}]")
|
168
|
+
}),
|
169
|
+
"=" => HFunction.new([:self, :other], lambda { |context|
|
170
|
+
return HFalse.create_instance if context["self"].ruby_value.length != context["other"].ruby_value.length
|
171
|
+
|
172
|
+
context["self"].ruby_value.zip(context["other"].ruby_value).map do |a, b|
|
173
|
+
a.receive_message(context.parent, "=", [b])
|
174
|
+
end.reduce(HTrue.create_instance) do |memo, value|
|
175
|
+
memo.receive_message(context, "and", [value])
|
176
|
+
end
|
177
|
+
})
|
178
|
+
)
|
179
|
+
|
180
|
+
HUnassignedBareword = HClass.new(
|
181
|
+
"UnassignedBareword",
|
182
|
+
"=" => HFunction.new([:self, :other], lambda { |context|
|
183
|
+
context.parent[context["self"].ruby_value] = context["other"]
|
184
|
+
HTrue.create_instance
|
185
|
+
}),
|
186
|
+
"inspect" => HFunction.new([:self], lambda { |context|
|
187
|
+
HString.create_instance("'#{context["self"].ruby_value}")
|
188
|
+
})
|
189
|
+
)
|
190
|
+
|
191
|
+
HTrue = HClass.new(
|
192
|
+
"True",
|
193
|
+
"and" => HFunction.new([:self, :other], lambda { |context|
|
194
|
+
context["other"]
|
195
|
+
}),
|
196
|
+
"or" => HFunction.new([:self, :other], lambda { |context|
|
197
|
+
context["self"]
|
198
|
+
}),
|
199
|
+
"then else" => HFunction.new([:self, :true_branch, :false_branch], lambda { |context|
|
200
|
+
context["true_branch"].receive_message(context, "call", [HArray.create_instance([])])
|
201
|
+
}),
|
202
|
+
"inspect" => HFunction.new([:self], lambda {|context|
|
203
|
+
HString.create_instance("true")
|
204
|
+
})
|
205
|
+
)
|
206
|
+
|
207
|
+
HFalse = HClass.new(
|
208
|
+
"False",
|
209
|
+
"and" => HFunction.new([:self, :other], lambda { |context|
|
210
|
+
context["self"]
|
211
|
+
}),
|
212
|
+
"or" => HFunction.new([:self, :other], lambda { |context|
|
213
|
+
context["other"]
|
214
|
+
}),
|
215
|
+
"then else" => HFunction.new([:self, :true_branch, :false_branch], lambda { |context|
|
216
|
+
context["false_branch"].receive_message(context, "call", [HArray.create_instance([])])
|
217
|
+
}),
|
218
|
+
"inspect" => HFunction.new([:self], lambda {|context|
|
219
|
+
HString.create_instance("false")
|
220
|
+
})
|
221
|
+
)
|
41
222
|
end
|
data/lib/halunke/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: halunke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Dohmen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|