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 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
- Author: "Rob Olson":http://thinkingdigitally.com
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
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('simplesem', '0.1.0') do |p|
5
+ Echoe.new('simplesem', '0.1.1') do |p|
6
6
  p.description = "SIMPLESEM Interpreter"
7
7
  p.url = "http://github.com/robolson/simplesem"
8
8
  p.author = "Rob Olson"
@@ -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