robolson-simplesem 0.1.2 → 0.1.3

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
@@ -6,7 +6,7 @@ h2. Description
6
6
 
7
7
  Interpreter for the SIMPLESEM language.
8
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.
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
 
@@ -20,6 +20,16 @@ Execute a SIMPLESEM program using the simplesem command. Pass the filename of th
20
20
 
21
21
  $ simplesem simplesem_file.txt
22
22
 
23
+ h3. Command Line Options
24
+
25
+ The simplesem executable accepts a couple command line options which will display the values in the Data array at the time the program exits.
26
+
27
+ -h Print help message
28
+ -t Print Data array on exit
29
+ -v Print Data array with change history on exit. Supersedes -t if it is also specified.
30
+
31
+ Use -t if you only want to see the ending value at each position in the Data array, otherwise use -v to see each data location's history. If neither -t or -v is used the program will not display the data array.
32
+
23
33
  h2. Introduction to SIMPLESEM
24
34
 
25
35
  SIMPLESEM is an abstract semantic processor that is based on the Von Neumann model of the fetch-execute cycle.
@@ -127,11 +137,14 @@ jump 8
127
137
  </code></pre>
128
138
 
129
139
  <pre>
130
- $ simplesem sample_programs/gcd.txt
140
+ $ simplesem -v sample_programs/gcd.txt
131
141
  input: 15
132
142
  input: 35
133
143
  5
134
144
 
135
- DATA: [5, 5, 4]
145
+ DATA:
146
+ 0: [15, 10, 5]
147
+ 1: [35, 20, 5]
148
+ 2: [4]
136
149
  </pre>
137
150
 
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.2') do |p|
5
+ Echoe.new('simplesem', '0.1.3') do |p|
6
6
  p.description = "SIMPLESEM Interpreter"
7
7
  p.url = "http://github.com/robolson/simplesem"
8
8
  p.author = "Rob Olson"
data/bin/simplesem CHANGED
@@ -1,15 +1,55 @@
1
1
  #!/usr/bin/env ruby
2
+ #= Overview
3
+ #
4
+ # Interpreter for the SIMPLESEM language
5
+ #
6
+ #= Usage
7
+ #
8
+ # simplesem [-t|-v] filename
9
+ #
10
+ # Options:
11
+ # -h Print this message
12
+ # -t Print Data array on exit
13
+ # -v Print Data array with change history on exit. Supersedes -t
14
+ # if it is also specified.
15
+ #
16
+
2
17
  require 'rubygems'
18
+ require 'rdoc/usage'
19
+ require 'getoptlong'
3
20
 
4
21
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
5
22
  require 'simplesem'
6
23
 
7
- if ARGV.empty?
8
- puts "Usage:\n\nsimplesem simplesem_file.txt\n\n"
9
- exit
24
+ opts = GetoptLong.new(
25
+ [ '-h', '--help', GetoptLong::NO_ARGUMENT ],
26
+ [ '-t', GetoptLong::NO_ARGUMENT ],
27
+ [ '-v', GetoptLong::NO_ARGUMENT ]
28
+ )
29
+
30
+ verbosity = 0 # by default do not print what is in Data
31
+
32
+ opts.each do |opt, arg|
33
+ case opt
34
+ when '-h'
35
+ RDoc::usage
36
+ when '-t'
37
+ verbosity = 1
38
+ when '-v'
39
+ verbosity = 2
40
+ end
41
+ end
42
+
43
+ if ARGV.length != 1
44
+ puts "Missing filename argument (try --help)"
45
+ exit 0
10
46
  end
11
47
 
12
48
  ssp = SimpleSemProgram.new(ARGV.shift)
13
49
  ssp.run
14
50
 
15
- puts "\nDATA: " + ssp.data.inspect
51
+ if (verbosity == 1)
52
+ puts "\nDATA: \n" + ssp.inspect_data
53
+ elsif (verbosity == 2)
54
+ puts "\nDATA: \n" + ssp.inspect_data_with_history
55
+ end
@@ -20,7 +20,13 @@ grammar SimpleSem
20
20
  rule set_stmt_assign
21
21
  'set' space loc:additive comma value:additive {
22
22
  def execute(env)
23
- env.data[loc.eval(env)] = value.eval(env)
23
+ evaled_loc = loc.eval(env)
24
+ evaled_value = value.eval(env)
25
+ if env.data[evaled_loc].nil?
26
+ env.data[evaled_loc] = Array[evaled_value]
27
+ else
28
+ env.data[evaled_loc] << evaled_value
29
+ end
24
30
  end
25
31
  }
26
32
  end
@@ -43,7 +49,15 @@ grammar SimpleSem
43
49
  'set' space loc:additive comma 'read' {
44
50
  def execute(env)
45
51
  print "input: "
46
- env.data[loc.eval(env)] = $stdin.gets.strip.to_i
52
+
53
+ evaled_loc = loc.eval(env)
54
+ input_value = $stdin.gets.strip.to_i
55
+
56
+ if env.data[evaled_loc].nil?
57
+ env.data[evaled_loc] = Array[input_value]
58
+ else
59
+ env.data[evaled_loc] << input_value
60
+ end
47
61
  end
48
62
  }
49
63
  end
@@ -83,7 +97,7 @@ grammar SimpleSem
83
97
  rule data_lookup
84
98
  'D[' expr:additive ']' {
85
99
  def eval(env)
86
- env.data[expr.eval(env)]
100
+ env.data[expr.eval(env)].last
87
101
  end
88
102
  }
89
103
  end
@@ -42,4 +42,16 @@ class SimpleSemProgram
42
42
  end
43
43
  end
44
44
  end
45
+
46
+ def inspect_data
47
+ res = String.new
48
+ @data.each_with_index {|loc, i| res += "#{i}: #{loc.last}\n" }
49
+ res
50
+ end
51
+
52
+ def inspect_data_with_history
53
+ res = String.new
54
+ @data.each_with_index {|loc, i| res += "#{i}: #{loc.inspect}\n" }
55
+ res
56
+ end
45
57
  end
data/simplesem.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{simplesem}
5
- s.version = "0.1.2"
5
+ s.version = "0.1.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Rob Olson"]
9
- s.date = %q{2009-03-06}
9
+ s.date = %q{2009-04-01}
10
10
  s.default_executable = %q{simplesem}
11
11
  s.description = %q{SIMPLESEM Interpreter}
12
12
  s.email = %q{rko618@gmail.com}
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  s.files = ["LICENSE", "Manifest", "README.textile", "Rakefile", "bin/simplesem", "lib/simplesem/arithmetic.treetop", "lib/simplesem/arithmetic_node_classes.rb", "lib/simplesem/simple_sem.treetop", "lib/simplesem/simplesem_program.rb", "lib/simplesem.rb", "sample_programs/case-statement.txt", "sample_programs/gcd.txt", "sample_programs/hello-world.txt", "sample_programs/while-loop.txt", "simplesem.gemspec", "simplesem.tmproj", "test/simplesem_test.rb", "test/test_helper.rb"]
16
16
  s.has_rdoc = true
17
17
  s.homepage = %q{http://github.com/robolson/simplesem}
18
- s.rdoc_options = ["--line-numbers", "--title", "Simplesem", "--main", "README.textile"]
18
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Simplesem", "--main", "README.textile"]
19
19
  s.require_paths = ["lib"]
20
20
  s.rubyforge_project = %q{simplesem}
21
21
  s.rubygems_version = %q{1.3.1}
@@ -9,16 +9,37 @@ class SimpleSemParserTest < Test::Unit::TestCase
9
9
  def setup
10
10
  @parser = SimpleSemParser.new
11
11
  @ssp = SimpleSemProgram.new
12
- @ssp.data[0] = 1
12
+ @ssp.data[0] = [1]
13
13
  end
14
14
 
15
15
  def test_set_stmt_assign
16
16
  parse('set 1, D[0]').execute(@ssp)
17
- assert_equal [1, 1], @ssp.data
17
+ assert_equal [[1], [1]], @ssp.data
18
18
  end
19
19
 
20
- def test_set_stmt_write
21
- assert_nil parse('set write, "hello world!"').execute(@ssp)
20
+ def test_set_stmt_write_string
21
+ out = capture_stdout do
22
+ parse('set write, "Hello World!"').execute(@ssp)
23
+ end
24
+ assert_equal "Hello World!\n", out.string
25
+ end
26
+
27
+ def test_set_stmt_write_expr
28
+ out = capture_stdout do
29
+ parse('set write, 2 > 1').execute(@ssp)
30
+ end
31
+ assert_equal "true\n", out.string
32
+ end
33
+
34
+ def test_set_stmt_read
35
+ fake_in = StringIO.new("2\n3\n")
36
+ $stdin = fake_in
37
+
38
+ capture_stdout do # capture_stdout because we do not want "input:"'s in the test output
39
+ parse('set 1, read').execute(@ssp)
40
+ parse('set 1, read').execute(@ssp)
41
+ end
42
+ assert_equal [2, 3], @ssp.data[1]
22
43
  end
23
44
 
24
45
  def test_jump_stmt
@@ -28,56 +49,54 @@ class SimpleSemParserTest < Test::Unit::TestCase
28
49
 
29
50
  def test_set_to_data_loc
30
51
  parse('set D[0], 2').execute(@ssp)
31
- assert_equal 2, @ssp.data[1]
52
+ assert_equal 2, @ssp.data[1].last
32
53
  end
33
54
 
34
55
  def test_complex_expr
35
- @ssp.data[1] = 2
56
+ @ssp.data[1] = [2]
36
57
  parse('set 2, D[0]+D[1]*2').execute(@ssp)
37
- assert_equal 5, @ssp.data[2]
58
+ assert_equal 5, @ssp.data[2].last
38
59
  end
39
60
 
40
61
  def test_parenthesis
41
- @ssp.data[1] = 2
62
+ @ssp.data[1] = [2]
42
63
  parse('set 2, (D[0]+D[1])*2').execute(@ssp)
43
- assert_equal 6, @ssp.data[2]
64
+ assert_equal 6, @ssp.data[2].last
44
65
  end
45
66
 
46
67
  def test_set_increment_instr
47
68
  parse('set 0, D[0]+1').execute(@ssp)
48
- assert_equal 2, @ssp.data[0]
69
+ assert_equal 2, @ssp.data[0].last
49
70
  end
50
71
 
51
72
  def test_nested_data_lookup
52
- @ssp.data[0] = 0
53
- @ssp.data[1] = 1
73
+ @ssp.data[0] = [0]
74
+ @ssp.data[1] = [1]
54
75
  parse('set 2, D[D[0]+1]').execute(@ssp)
55
- assert_equal 1, @ssp.data[2]
76
+ assert_equal 1, @ssp.data[2].last
56
77
  end
57
78
 
58
79
  def test_instruction_pointer
59
- # run two dummy instructions, manually incrementing the program counter
80
+ # manually incrementing the program counter is required here
60
81
  @ssp.pc = 1
61
- parse('set 0, 0').execute(@ssp)
62
- @ssp.pc = 2
63
82
  parse('set 0, ip').execute(@ssp)
64
- assert_equal 2, @ssp.data[0] # check that the parser was able to read the ip correctly
83
+ assert_equal 1, @ssp.data[0].last # checking that the parser was able to evaluate ip correctly
65
84
  end
66
85
 
67
86
  def test_jump_to_data_loc
68
- @ssp.data[0] = 2
87
+ @ssp.data[0] = [2]
69
88
  parse('jump D[0]').execute(@ssp)
70
89
  assert_equal 2, @ssp.pc
71
90
  end
72
91
 
73
92
  def test_jumpt_stmt_true
74
- @ssp.data[0] = 1
93
+ @ssp.data[0] = [1]
75
94
  parse('jumpt 5, D[0]=D[0]').execute(@ssp)
76
95
  assert_equal 5, @ssp.pc
77
96
  end
78
97
 
79
98
  def test_jumpt_stmt_false
80
- @ssp.data[0] = 1
99
+ @ssp.data[0] = [1]
81
100
  parse('jumpt 5, D[0]=2').execute(@ssp)
82
101
  assert_equal 0, @ssp.pc # pc should not have changed
83
102
  end
@@ -108,7 +127,7 @@ class SimpleSemParserTest < Test::Unit::TestCase
108
127
 
109
128
  def test_negative_number
110
129
  parse('set 0, -1').execute(@ssp)
111
- assert_equal -1, @ssp.data[0]
130
+ assert_equal -1, @ssp.data[0].last
112
131
  end
113
132
 
114
133
  def test_halt
data/test/test_helper.rb CHANGED
@@ -15,4 +15,14 @@ module ParserTestHelper
15
15
  assert !result.nil?
16
16
  result
17
17
  end
18
+ end
19
+
20
+ module Kernel
21
+ def capture_stdout
22
+ out = StringIO.new
23
+ $stdout = out
24
+ yield
25
+ $stdout = STDOUT
26
+ return out
27
+ end
18
28
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: robolson-simplesem
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rob Olson
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-06 00:00:00 -08:00
12
+ date: 2009-04-01 00:00:00 -07:00
13
13
  default_executable: simplesem
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -61,6 +61,7 @@ homepage: http://github.com/robolson/simplesem
61
61
  post_install_message:
62
62
  rdoc_options:
63
63
  - --line-numbers
64
+ - --inline-source
64
65
  - --title
65
66
  - Simplesem
66
67
  - --main