robolson-simplesem 0.1.3 → 0.1.4
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/Manifest +18 -0
- data/README.textile +26 -24
- data/Rakefile +6 -8
- data/bin/simplesem +26 -45
- data/lib/simplesem/arithmetic.treetop +98 -96
- data/lib/simplesem/arithmetic_node_classes.rb +9 -5
- data/lib/simplesem/simple_sem.treetop +112 -111
- data/lib/simplesem/simplesem_program.rb +50 -48
- data/lib/simplesem/version.rb +5 -0
- data/lib/simplesem.rb +2 -2
- data/lib/trollop/trollop.rb +695 -0
- data/sample_programs/gcd.txt +1 -1
- data/sample_programs/hello-world.txt +1 -1
- data/sample_programs/while-loop.txt +1 -1
- data/simplesem.gemspec +9 -10
- data/test/simplesem_test.rb +10 -8
- data/test/test_helper.rb +2 -2
- metadata +15 -11
@@ -1,117 +1,118 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
rule halt
|
9
|
-
'halt' {
|
10
|
-
def execute(env={})
|
11
|
-
raise ProgramHalt
|
12
|
-
end
|
13
|
-
}
|
14
|
-
end
|
15
|
-
|
16
|
-
rule set_stmt
|
17
|
-
set_stmt_assign / set_stmt_write / set_stmt_read
|
18
|
-
end
|
1
|
+
module SimpleSem
|
2
|
+
grammar SimpleSem
|
3
|
+
include Arithmetic
|
4
|
+
|
5
|
+
rule statement
|
6
|
+
set_stmt / jump_stmt / jumpt_stmt / halt
|
7
|
+
end
|
19
8
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
9
|
+
rule halt
|
10
|
+
'halt' {
|
11
|
+
def execute(env={})
|
12
|
+
raise ProgramHalt
|
29
13
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
rule set_stmt_read
|
49
|
-
'set' space loc:additive comma 'read' {
|
50
|
-
def execute(env)
|
51
|
-
print "input: "
|
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
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
rule set_stmt
|
18
|
+
set_stmt_assign / set_stmt_write / set_stmt_read
|
19
|
+
end
|
20
|
+
|
21
|
+
rule set_stmt_assign
|
22
|
+
'set' space loc:additive comma value:additive {
|
23
|
+
def execute(env)
|
24
|
+
evaled_loc = loc.eval(env)
|
25
|
+
evaled_value = value.eval(env)
|
26
|
+
if env.data[evaled_loc].nil?
|
27
|
+
env.data[evaled_loc] = Array[evaled_value]
|
28
|
+
else
|
29
|
+
env.data[evaled_loc] << evaled_value
|
30
|
+
end
|
60
31
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
rule set_stmt_write
|
36
|
+
'set' space 'write' comma expression {
|
37
|
+
def execute(env)
|
38
|
+
puts expression.eval(env)
|
39
|
+
end
|
40
|
+
}
|
41
|
+
/
|
42
|
+
'set' space 'write' comma '"' string:(!'"' . )* '"' {
|
43
|
+
def execute(env)
|
44
|
+
puts string.text_value
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
rule set_stmt_read
|
50
|
+
'set' space loc:additive comma 'read' {
|
51
|
+
def execute(env)
|
52
|
+
print "input: "
|
53
|
+
|
54
|
+
evaled_loc = loc.eval(env)
|
55
|
+
input_value = $stdin.gets.strip.to_i
|
56
|
+
|
57
|
+
if env.data[evaled_loc].nil?
|
58
|
+
env.data[evaled_loc] = Array[input_value]
|
59
|
+
else
|
60
|
+
env.data[evaled_loc] << input_value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
rule jump_stmt
|
67
|
+
'jump' space loc:additive {
|
68
|
+
def execute(env)
|
77
69
|
env.pc = loc.eval(env)
|
78
70
|
end
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
env
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
rule jumpt_stmt
|
75
|
+
'jumpt' space loc:additive comma expression {
|
76
|
+
def execute(env)
|
77
|
+
if expression.eval(env)
|
78
|
+
env.pc = loc.eval(env)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
rule primary
|
85
|
+
ip
|
86
|
+
/
|
87
|
+
data_lookup
|
88
|
+
/
|
89
|
+
number
|
90
|
+
/
|
91
|
+
'(' space expression space ')' {
|
92
|
+
def eval(env={})
|
93
|
+
expression.eval(env)
|
94
|
+
end
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
rule data_lookup
|
99
|
+
'D[' expr:additive ']' {
|
100
|
+
def eval(env)
|
101
|
+
env.data[expr.eval(env)].last
|
102
|
+
end
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
rule ip
|
107
|
+
'ip' {
|
108
|
+
def eval(env)
|
109
|
+
env.pc
|
110
|
+
end
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
rule comma
|
115
|
+
space ',' space
|
116
|
+
end
|
115
117
|
end
|
116
|
-
|
117
|
-
end
|
118
|
+
end
|
@@ -1,57 +1,59 @@
|
|
1
|
-
require 'rubygems'
|
2
1
|
require 'treetop'
|
2
|
+
require 'simplesem/arithmetic_node_classes'
|
3
3
|
dir = File.dirname(__FILE__)
|
4
|
-
|
5
|
-
Treetop.load File.expand_path(
|
6
|
-
Treetop.load File.expand_path("#{dir}/simple_sem")
|
4
|
+
Treetop.load File.expand_path(File.join(dir, 'arithmetic'))
|
5
|
+
Treetop.load File.expand_path(File.join(dir, 'simple_sem'))
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
module SimpleSem
|
8
|
+
|
9
|
+
class ProgramHalt < Exception
|
10
|
+
end
|
11
|
+
|
12
|
+
class Program
|
13
|
+
attr_reader :code
|
14
|
+
attr_accessor :data, :pc
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
if filepath
|
22
|
-
IO.foreach(filepath) do |line|
|
23
|
-
@code << line.split("//", 2)[0].strip # seperate the comment from the code
|
16
|
+
# Create a SimpleSemProgram instance
|
17
|
+
# Params:
|
18
|
+
# (String)filepath: path to SimpleSem source file.
|
19
|
+
# Optional because it's useful to use in tests without needing to load a file
|
20
|
+
def initialize filepath=nil
|
21
|
+
@code = Array.new
|
22
|
+
if filepath
|
23
|
+
IO.foreach(filepath) do |line|
|
24
|
+
@code << line.split("//", 2)[0].strip # seperate the comment from the code
|
25
|
+
end
|
24
26
|
end
|
27
|
+
|
28
|
+
@data = Array.new
|
29
|
+
@pc = 0
|
25
30
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
@parser.parse(instruction).execute(self) # decode and execute
|
40
|
-
rescue ProgramHalt
|
41
|
-
break
|
31
|
+
|
32
|
+
def run
|
33
|
+
@parser = SimpleSemParser.new
|
34
|
+
|
35
|
+
@pc = 0
|
36
|
+
loop do
|
37
|
+
instruction = @code[@pc] # fetch
|
38
|
+
@pc += 1 # increment
|
39
|
+
begin
|
40
|
+
@parser.parse(instruction).execute(self) # decode and execute
|
41
|
+
rescue ProgramHalt
|
42
|
+
break
|
43
|
+
end
|
42
44
|
end
|
43
45
|
end
|
46
|
+
|
47
|
+
def inspect_data
|
48
|
+
res = String.new
|
49
|
+
@data.each_with_index {|loc, i| res += "#{i}: #{loc.last}\n" }
|
50
|
+
res
|
51
|
+
end
|
52
|
+
|
53
|
+
def inspect_data_with_history
|
54
|
+
res = String.new
|
55
|
+
@data.each_with_index {|loc, i| res += "#{i}: #{loc.inspect}\n" }
|
56
|
+
res
|
57
|
+
end
|
44
58
|
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
|
57
|
-
end
|
59
|
+
end
|
data/lib/simplesem.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
|
2
|
-
require
|
1
|
+
require 'simplesem/version'
|
2
|
+
require 'simplesem/simplesem_program'
|