robolson-simplesem 0.1.2 → 0.1.3

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