robolson-simplesem 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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