robolson-simplesem 0.1.0 → 0.1.1
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.
- data/README.textile +18 -3
- data/Rakefile +1 -1
- data/lib/simplesem/arithmetic.rb +601 -0
- data/lib/simplesem/simple_sem.rb +823 -0
- data/simplesem.gemspec +5 -5
- metadata +6 -3
data/README.textile
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
h1. SIMPLESEM Interpreter
|
2
2
|
|
3
|
+
Author: "Rob Olson":http://thinkingdigitally.com
|
4
|
+
|
3
5
|
h2. Description
|
4
6
|
|
5
7
|
Interpreter for the SIMPLESEM language.
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
SIMPLESEM is used in the CS141 Programming Languages course taught by "Professor Shannon Tauro":http://www.ics.uci.edu/~stauro/ at UC Irvine. This Rubygem was created out of my desire to execute SIMPLESEM programs. To my knowledge, there are none publicly available.
|
9
|
+
SIMPLESEM is used in the CS141 Programming Languages course taught by Professor "Shannon Tauro":http://www.ics.uci.edu/~stauro/ at UC Irvine. This Rubygem was created out of my desire to execute SIMPLESEM programs. To my knowledge, there are none publicly available.
|
10
10
|
|
11
11
|
This interpreter utilizes Nathan Sobo's "Treetop":http://github.com/nathansobo/treetop gem to create a parsing expression grammar for parsing SIMPLESEM commands.
|
12
12
|
|
@@ -66,6 +66,13 @@ Jump to line 7 if the value at <notextile>D[1]</notextile> is equal to the value
|
|
66
66
|
|
67
67
|
SIMPLESEM supports all the common comparison operators: >, <, >=, <=, !=, and =. Take note that the equality operator is a single '=' sign, not the usual '=='.
|
68
68
|
|
69
|
+
h3. Comments
|
70
|
+
|
71
|
+
SIMPLESEM comments begin with two forward slashes. Everything on the line following @//@ is considered a comment and is ignored by the interpreter. *Important*: Comments still consume line numbers! Keep this in mind when writing jump statements.
|
72
|
+
|
73
|
+
// This is line number 0.
|
74
|
+
set write, "foo" // a comment after a statement
|
75
|
+
|
69
76
|
h2. Slightly More Advanced Features of SIMPLESEM
|
70
77
|
|
71
78
|
h3. Nested Data Lookups
|
@@ -119,4 +126,12 @@ set 0, D[0]-D[1]
|
|
119
126
|
jump 8
|
120
127
|
</code></pre>
|
121
128
|
|
129
|
+
<pre>
|
130
|
+
$ simplesem sample_programs/gcd.txt
|
131
|
+
input: 15
|
132
|
+
input: 35
|
133
|
+
5
|
134
|
+
|
135
|
+
DATA: [5, 5, 4]
|
136
|
+
</pre>
|
122
137
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,601 @@
|
|
1
|
+
module Arithmetic
|
2
|
+
include Treetop::Runtime
|
3
|
+
|
4
|
+
def root
|
5
|
+
@root || :expression
|
6
|
+
end
|
7
|
+
|
8
|
+
def _nt_expression
|
9
|
+
start_index = index
|
10
|
+
if node_cache[:expression].has_key?(index)
|
11
|
+
cached = node_cache[:expression][index]
|
12
|
+
@index = cached.interval.end if cached
|
13
|
+
return cached
|
14
|
+
end
|
15
|
+
|
16
|
+
i0 = index
|
17
|
+
r1 = _nt_comparative
|
18
|
+
if r1
|
19
|
+
r0 = r1
|
20
|
+
else
|
21
|
+
r2 = _nt_additive
|
22
|
+
if r2
|
23
|
+
r0 = r2
|
24
|
+
else
|
25
|
+
self.index = i0
|
26
|
+
r0 = nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
node_cache[:expression][start_index] = r0
|
31
|
+
|
32
|
+
return r0
|
33
|
+
end
|
34
|
+
|
35
|
+
module Comparative0
|
36
|
+
def operand_1
|
37
|
+
elements[0]
|
38
|
+
end
|
39
|
+
|
40
|
+
def space
|
41
|
+
elements[1]
|
42
|
+
end
|
43
|
+
|
44
|
+
def operator
|
45
|
+
elements[2]
|
46
|
+
end
|
47
|
+
|
48
|
+
def space
|
49
|
+
elements[3]
|
50
|
+
end
|
51
|
+
|
52
|
+
def operand_2
|
53
|
+
elements[4]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def _nt_comparative
|
58
|
+
start_index = index
|
59
|
+
if node_cache[:comparative].has_key?(index)
|
60
|
+
cached = node_cache[:comparative][index]
|
61
|
+
@index = cached.interval.end if cached
|
62
|
+
return cached
|
63
|
+
end
|
64
|
+
|
65
|
+
i0, s0 = index, []
|
66
|
+
r1 = _nt_additive
|
67
|
+
s0 << r1
|
68
|
+
if r1
|
69
|
+
r2 = _nt_space
|
70
|
+
s0 << r2
|
71
|
+
if r2
|
72
|
+
r3 = _nt_comparison_op
|
73
|
+
s0 << r3
|
74
|
+
if r3
|
75
|
+
r4 = _nt_space
|
76
|
+
s0 << r4
|
77
|
+
if r4
|
78
|
+
r5 = _nt_additive
|
79
|
+
s0 << r5
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
if s0.last
|
85
|
+
r0 = (BinaryOperation).new(input, i0...index, s0)
|
86
|
+
r0.extend(Comparative0)
|
87
|
+
else
|
88
|
+
self.index = i0
|
89
|
+
r0 = nil
|
90
|
+
end
|
91
|
+
|
92
|
+
node_cache[:comparative][start_index] = r0
|
93
|
+
|
94
|
+
return r0
|
95
|
+
end
|
96
|
+
|
97
|
+
module ComparisonOp0
|
98
|
+
def apply(a, b)
|
99
|
+
a >= b
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
module ComparisonOp1
|
104
|
+
def apply(a, b)
|
105
|
+
a <= b
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
module ComparisonOp2
|
110
|
+
def apply(a, b)
|
111
|
+
a > b
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
module ComparisonOp3
|
116
|
+
def apply(a, b)
|
117
|
+
a < b
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
module ComparisonOp4
|
122
|
+
def apply(a, b)
|
123
|
+
a != b
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
module ComparisonOp5
|
128
|
+
def apply(a, b)
|
129
|
+
a == b
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def _nt_comparison_op
|
134
|
+
start_index = index
|
135
|
+
if node_cache[:comparison_op].has_key?(index)
|
136
|
+
cached = node_cache[:comparison_op][index]
|
137
|
+
@index = cached.interval.end if cached
|
138
|
+
return cached
|
139
|
+
end
|
140
|
+
|
141
|
+
i0 = index
|
142
|
+
if input.index('>=', index) == index
|
143
|
+
r1 = (SyntaxNode).new(input, index...(index + 2))
|
144
|
+
r1.extend(ComparisonOp0)
|
145
|
+
@index += 2
|
146
|
+
else
|
147
|
+
terminal_parse_failure('>=')
|
148
|
+
r1 = nil
|
149
|
+
end
|
150
|
+
if r1
|
151
|
+
r0 = r1
|
152
|
+
else
|
153
|
+
if input.index('<=', index) == index
|
154
|
+
r2 = (SyntaxNode).new(input, index...(index + 2))
|
155
|
+
r2.extend(ComparisonOp1)
|
156
|
+
@index += 2
|
157
|
+
else
|
158
|
+
terminal_parse_failure('<=')
|
159
|
+
r2 = nil
|
160
|
+
end
|
161
|
+
if r2
|
162
|
+
r0 = r2
|
163
|
+
else
|
164
|
+
if input.index('>', index) == index
|
165
|
+
r3 = (SyntaxNode).new(input, index...(index + 1))
|
166
|
+
r3.extend(ComparisonOp2)
|
167
|
+
@index += 1
|
168
|
+
else
|
169
|
+
terminal_parse_failure('>')
|
170
|
+
r3 = nil
|
171
|
+
end
|
172
|
+
if r3
|
173
|
+
r0 = r3
|
174
|
+
else
|
175
|
+
if input.index('<', index) == index
|
176
|
+
r4 = (SyntaxNode).new(input, index...(index + 1))
|
177
|
+
r4.extend(ComparisonOp3)
|
178
|
+
@index += 1
|
179
|
+
else
|
180
|
+
terminal_parse_failure('<')
|
181
|
+
r4 = nil
|
182
|
+
end
|
183
|
+
if r4
|
184
|
+
r0 = r4
|
185
|
+
else
|
186
|
+
if input.index('!=', index) == index
|
187
|
+
r5 = (SyntaxNode).new(input, index...(index + 2))
|
188
|
+
r5.extend(ComparisonOp4)
|
189
|
+
@index += 2
|
190
|
+
else
|
191
|
+
terminal_parse_failure('!=')
|
192
|
+
r5 = nil
|
193
|
+
end
|
194
|
+
if r5
|
195
|
+
r0 = r5
|
196
|
+
else
|
197
|
+
if input.index('=', index) == index
|
198
|
+
r6 = (SyntaxNode).new(input, index...(index + 1))
|
199
|
+
r6.extend(ComparisonOp5)
|
200
|
+
@index += 1
|
201
|
+
else
|
202
|
+
terminal_parse_failure('=')
|
203
|
+
r6 = nil
|
204
|
+
end
|
205
|
+
if r6
|
206
|
+
r0 = r6
|
207
|
+
else
|
208
|
+
self.index = i0
|
209
|
+
r0 = nil
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
node_cache[:comparison_op][start_index] = r0
|
218
|
+
|
219
|
+
return r0
|
220
|
+
end
|
221
|
+
|
222
|
+
module Additive0
|
223
|
+
def operand_1
|
224
|
+
elements[0]
|
225
|
+
end
|
226
|
+
|
227
|
+
def space
|
228
|
+
elements[1]
|
229
|
+
end
|
230
|
+
|
231
|
+
def operator
|
232
|
+
elements[2]
|
233
|
+
end
|
234
|
+
|
235
|
+
def space
|
236
|
+
elements[3]
|
237
|
+
end
|
238
|
+
|
239
|
+
def operand_2
|
240
|
+
elements[4]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def _nt_additive
|
245
|
+
start_index = index
|
246
|
+
if node_cache[:additive].has_key?(index)
|
247
|
+
cached = node_cache[:additive][index]
|
248
|
+
@index = cached.interval.end if cached
|
249
|
+
return cached
|
250
|
+
end
|
251
|
+
|
252
|
+
i0 = index
|
253
|
+
i1, s1 = index, []
|
254
|
+
r2 = _nt_multitive
|
255
|
+
s1 << r2
|
256
|
+
if r2
|
257
|
+
r3 = _nt_space
|
258
|
+
s1 << r3
|
259
|
+
if r3
|
260
|
+
r4 = _nt_additive_op
|
261
|
+
s1 << r4
|
262
|
+
if r4
|
263
|
+
r5 = _nt_space
|
264
|
+
s1 << r5
|
265
|
+
if r5
|
266
|
+
r6 = _nt_additive
|
267
|
+
s1 << r6
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
if s1.last
|
273
|
+
r1 = (BinaryOperation).new(input, i1...index, s1)
|
274
|
+
r1.extend(Additive0)
|
275
|
+
else
|
276
|
+
self.index = i1
|
277
|
+
r1 = nil
|
278
|
+
end
|
279
|
+
if r1
|
280
|
+
r0 = r1
|
281
|
+
else
|
282
|
+
r7 = _nt_multitive
|
283
|
+
if r7
|
284
|
+
r0 = r7
|
285
|
+
else
|
286
|
+
self.index = i0
|
287
|
+
r0 = nil
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
node_cache[:additive][start_index] = r0
|
292
|
+
|
293
|
+
return r0
|
294
|
+
end
|
295
|
+
|
296
|
+
module AdditiveOp0
|
297
|
+
def apply(a, b)
|
298
|
+
a + b
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
module AdditiveOp1
|
303
|
+
def apply(a, b)
|
304
|
+
a - b
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
def _nt_additive_op
|
309
|
+
start_index = index
|
310
|
+
if node_cache[:additive_op].has_key?(index)
|
311
|
+
cached = node_cache[:additive_op][index]
|
312
|
+
@index = cached.interval.end if cached
|
313
|
+
return cached
|
314
|
+
end
|
315
|
+
|
316
|
+
i0 = index
|
317
|
+
if input.index('+', index) == index
|
318
|
+
r1 = (SyntaxNode).new(input, index...(index + 1))
|
319
|
+
r1.extend(AdditiveOp0)
|
320
|
+
@index += 1
|
321
|
+
else
|
322
|
+
terminal_parse_failure('+')
|
323
|
+
r1 = nil
|
324
|
+
end
|
325
|
+
if r1
|
326
|
+
r0 = r1
|
327
|
+
else
|
328
|
+
if input.index('-', index) == index
|
329
|
+
r2 = (SyntaxNode).new(input, index...(index + 1))
|
330
|
+
r2.extend(AdditiveOp1)
|
331
|
+
@index += 1
|
332
|
+
else
|
333
|
+
terminal_parse_failure('-')
|
334
|
+
r2 = nil
|
335
|
+
end
|
336
|
+
if r2
|
337
|
+
r0 = r2
|
338
|
+
else
|
339
|
+
self.index = i0
|
340
|
+
r0 = nil
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
node_cache[:additive_op][start_index] = r0
|
345
|
+
|
346
|
+
return r0
|
347
|
+
end
|
348
|
+
|
349
|
+
module Multitive0
|
350
|
+
def operand_1
|
351
|
+
elements[0]
|
352
|
+
end
|
353
|
+
|
354
|
+
def space
|
355
|
+
elements[1]
|
356
|
+
end
|
357
|
+
|
358
|
+
def operator
|
359
|
+
elements[2]
|
360
|
+
end
|
361
|
+
|
362
|
+
def space
|
363
|
+
elements[3]
|
364
|
+
end
|
365
|
+
|
366
|
+
def operand_2
|
367
|
+
elements[4]
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def _nt_multitive
|
372
|
+
start_index = index
|
373
|
+
if node_cache[:multitive].has_key?(index)
|
374
|
+
cached = node_cache[:multitive][index]
|
375
|
+
@index = cached.interval.end if cached
|
376
|
+
return cached
|
377
|
+
end
|
378
|
+
|
379
|
+
i0 = index
|
380
|
+
i1, s1 = index, []
|
381
|
+
r2 = _nt_primary
|
382
|
+
s1 << r2
|
383
|
+
if r2
|
384
|
+
r3 = _nt_space
|
385
|
+
s1 << r3
|
386
|
+
if r3
|
387
|
+
r4 = _nt_multitive_op
|
388
|
+
s1 << r4
|
389
|
+
if r4
|
390
|
+
r5 = _nt_space
|
391
|
+
s1 << r5
|
392
|
+
if r5
|
393
|
+
r6 = _nt_multitive
|
394
|
+
s1 << r6
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
if s1.last
|
400
|
+
r1 = (BinaryOperation).new(input, i1...index, s1)
|
401
|
+
r1.extend(Multitive0)
|
402
|
+
else
|
403
|
+
self.index = i1
|
404
|
+
r1 = nil
|
405
|
+
end
|
406
|
+
if r1
|
407
|
+
r0 = r1
|
408
|
+
else
|
409
|
+
r7 = _nt_primary
|
410
|
+
if r7
|
411
|
+
r0 = r7
|
412
|
+
else
|
413
|
+
self.index = i0
|
414
|
+
r0 = nil
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
node_cache[:multitive][start_index] = r0
|
419
|
+
|
420
|
+
return r0
|
421
|
+
end
|
422
|
+
|
423
|
+
module MultitiveOp0
|
424
|
+
def apply(a, b)
|
425
|
+
a * b
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
module MultitiveOp1
|
430
|
+
def apply(a, b)
|
431
|
+
a / b
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def _nt_multitive_op
|
436
|
+
start_index = index
|
437
|
+
if node_cache[:multitive_op].has_key?(index)
|
438
|
+
cached = node_cache[:multitive_op][index]
|
439
|
+
@index = cached.interval.end if cached
|
440
|
+
return cached
|
441
|
+
end
|
442
|
+
|
443
|
+
i0 = index
|
444
|
+
if input.index('*', index) == index
|
445
|
+
r1 = (SyntaxNode).new(input, index...(index + 1))
|
446
|
+
r1.extend(MultitiveOp0)
|
447
|
+
@index += 1
|
448
|
+
else
|
449
|
+
terminal_parse_failure('*')
|
450
|
+
r1 = nil
|
451
|
+
end
|
452
|
+
if r1
|
453
|
+
r0 = r1
|
454
|
+
else
|
455
|
+
if input.index('/', index) == index
|
456
|
+
r2 = (SyntaxNode).new(input, index...(index + 1))
|
457
|
+
r2.extend(MultitiveOp1)
|
458
|
+
@index += 1
|
459
|
+
else
|
460
|
+
terminal_parse_failure('/')
|
461
|
+
r2 = nil
|
462
|
+
end
|
463
|
+
if r2
|
464
|
+
r0 = r2
|
465
|
+
else
|
466
|
+
self.index = i0
|
467
|
+
r0 = nil
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
471
|
+
node_cache[:multitive_op][start_index] = r0
|
472
|
+
|
473
|
+
return r0
|
474
|
+
end
|
475
|
+
|
476
|
+
module Number0
|
477
|
+
end
|
478
|
+
|
479
|
+
module Number1
|
480
|
+
def eval(env={})
|
481
|
+
text_value.to_i
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
def _nt_number
|
486
|
+
start_index = index
|
487
|
+
if node_cache[:number].has_key?(index)
|
488
|
+
cached = node_cache[:number][index]
|
489
|
+
@index = cached.interval.end if cached
|
490
|
+
return cached
|
491
|
+
end
|
492
|
+
|
493
|
+
i0 = index
|
494
|
+
i1, s1 = index, []
|
495
|
+
if input.index('-', index) == index
|
496
|
+
r3 = (SyntaxNode).new(input, index...(index + 1))
|
497
|
+
@index += 1
|
498
|
+
else
|
499
|
+
terminal_parse_failure('-')
|
500
|
+
r3 = nil
|
501
|
+
end
|
502
|
+
if r3
|
503
|
+
r2 = r3
|
504
|
+
else
|
505
|
+
r2 = SyntaxNode.new(input, index...index)
|
506
|
+
end
|
507
|
+
s1 << r2
|
508
|
+
if r2
|
509
|
+
if input.index(Regexp.new('[1-9]'), index) == index
|
510
|
+
r4 = (SyntaxNode).new(input, index...(index + 1))
|
511
|
+
@index += 1
|
512
|
+
else
|
513
|
+
r4 = nil
|
514
|
+
end
|
515
|
+
s1 << r4
|
516
|
+
if r4
|
517
|
+
s5, i5 = [], index
|
518
|
+
loop do
|
519
|
+
if input.index(Regexp.new('[0-9]'), index) == index
|
520
|
+
r6 = (SyntaxNode).new(input, index...(index + 1))
|
521
|
+
@index += 1
|
522
|
+
else
|
523
|
+
r6 = nil
|
524
|
+
end
|
525
|
+
if r6
|
526
|
+
s5 << r6
|
527
|
+
else
|
528
|
+
break
|
529
|
+
end
|
530
|
+
end
|
531
|
+
r5 = SyntaxNode.new(input, i5...index, s5)
|
532
|
+
s1 << r5
|
533
|
+
end
|
534
|
+
end
|
535
|
+
if s1.last
|
536
|
+
r1 = (SyntaxNode).new(input, i1...index, s1)
|
537
|
+
r1.extend(Number0)
|
538
|
+
else
|
539
|
+
self.index = i1
|
540
|
+
r1 = nil
|
541
|
+
end
|
542
|
+
if r1
|
543
|
+
r0 = r1
|
544
|
+
r0.extend(Number1)
|
545
|
+
else
|
546
|
+
if input.index('0', index) == index
|
547
|
+
r7 = (SyntaxNode).new(input, index...(index + 1))
|
548
|
+
@index += 1
|
549
|
+
else
|
550
|
+
terminal_parse_failure('0')
|
551
|
+
r7 = nil
|
552
|
+
end
|
553
|
+
if r7
|
554
|
+
r0 = r7
|
555
|
+
r0.extend(Number1)
|
556
|
+
else
|
557
|
+
self.index = i0
|
558
|
+
r0 = nil
|
559
|
+
end
|
560
|
+
end
|
561
|
+
|
562
|
+
node_cache[:number][start_index] = r0
|
563
|
+
|
564
|
+
return r0
|
565
|
+
end
|
566
|
+
|
567
|
+
def _nt_space
|
568
|
+
start_index = index
|
569
|
+
if node_cache[:space].has_key?(index)
|
570
|
+
cached = node_cache[:space][index]
|
571
|
+
@index = cached.interval.end if cached
|
572
|
+
return cached
|
573
|
+
end
|
574
|
+
|
575
|
+
s0, i0 = [], index
|
576
|
+
loop do
|
577
|
+
if input.index(' ', index) == index
|
578
|
+
r1 = (SyntaxNode).new(input, index...(index + 1))
|
579
|
+
@index += 1
|
580
|
+
else
|
581
|
+
terminal_parse_failure(' ')
|
582
|
+
r1 = nil
|
583
|
+
end
|
584
|
+
if r1
|
585
|
+
s0 << r1
|
586
|
+
else
|
587
|
+
break
|
588
|
+
end
|
589
|
+
end
|
590
|
+
r0 = SyntaxNode.new(input, i0...index, s0)
|
591
|
+
|
592
|
+
node_cache[:space][start_index] = r0
|
593
|
+
|
594
|
+
return r0
|
595
|
+
end
|
596
|
+
|
597
|
+
end
|
598
|
+
|
599
|
+
class ArithmeticParser < Treetop::Runtime::CompiledParser
|
600
|
+
include Arithmetic
|
601
|
+
end
|