carban 0.0.1 → 0.0.2
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.
- checksums.yaml +7 -0
- data/README.md +10 -1
- data/carban.gemspec +1 -1
- data/lib/carban.rb +0 -1
- data/lib/carban/instruction_set.rb +231 -230
- data/lib/carban/op_codes.rb +40 -40
- data/lib/carban/stack_machine.rb +44 -47
- data/lib/carban/version.rb +1 -1
- metadata +9 -12
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 4827039b73fcbc027ad5d34d46f035b0bc4b6b20
|
|
4
|
+
data.tar.gz: e980586db9472ef9368bb35251b6c544177fb606
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 997006ca3977d338535c23154d2a0407edde73eb75471f9f40afcbc805dd1d2136c0464ebfe7ae4650d5a7044bc83f230c042d1a6d4d2c47f41241d034f83cb2
|
|
7
|
+
data.tar.gz: 4b2313c23e4678a63f2059fe6485ad6d58ccdee8555aace91ee3fca51db981820d3e4c1f358c62e40f9306993ecfbe62aaf50b64c1c2d0bbfbeeae3eed520333
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Carban
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A Rubygem that implements the Carban Instruction Set as a Virtual Machine.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -16,6 +16,14 @@ Or install it yourself as:
|
|
|
16
16
|
|
|
17
17
|
$ gem install carban
|
|
18
18
|
|
|
19
|
+
##Usage
|
|
20
|
+
|
|
21
|
+
1. require 'carban'
|
|
22
|
+
2. sm = Carban::StackMachine.new
|
|
23
|
+
3. sm.opcodes = [15, 1, 15, 1, 0]
|
|
24
|
+
4. sm.run
|
|
25
|
+
5. sm.data_stack #should return [2]
|
|
26
|
+
|
|
19
27
|
|
|
20
28
|
## Contributing
|
|
21
29
|
|
|
@@ -24,3 +32,4 @@ Or install it yourself as:
|
|
|
24
32
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
25
33
|
4. Push to the branch (`git push origin my-new-feature`)
|
|
26
34
|
5. Create new Pull Request
|
|
35
|
+
|
data/carban.gemspec
CHANGED
|
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
|
|
|
8
8
|
gem.version = Carban::VERSION
|
|
9
9
|
gem.authors = ["patrick"]
|
|
10
10
|
gem.email = ["patrick@patrickjones.ca"]
|
|
11
|
-
gem.description = %q{A Virtual Machine implemented as Abstract Stack Machine
|
|
11
|
+
gem.description = %q{A Virtual Machine implemented as Abstract Stack Machine}
|
|
12
12
|
gem.summary = %q{Virtual Machine implementations of the Carban Instruction Set}
|
|
13
13
|
gem.homepage = ""
|
|
14
14
|
|
data/lib/carban.rb
CHANGED
|
@@ -1,230 +1,231 @@
|
|
|
1
|
-
module Carban
|
|
2
|
-
module InstructionSet
|
|
3
|
-
include OpCodes
|
|
4
|
-
|
|
5
|
-
def self.load
|
|
6
|
-
compiled_set = {}
|
|
7
|
-
OpCodes.constants.each do |code|
|
|
8
|
-
numerical = OpCodes.const_get code
|
|
9
|
-
compiled_set[numerical] = send(code.to_s.downcase.to_sym)
|
|
10
|
-
end
|
|
11
|
-
return compiled_set
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.add
|
|
15
|
-
Proc.new do |vm|
|
|
16
|
-
left = @data_stack.pop
|
|
17
|
-
right = @data_stack.pop
|
|
18
|
-
@data_stack.push(left + right)
|
|
19
|
-
@ip += 1
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def self.sub
|
|
24
|
-
Proc.new do |vm|
|
|
25
|
-
right = @data_stack.pop
|
|
26
|
-
left = @data_stack.pop
|
|
27
|
-
@data_stack.push (left - right)
|
|
28
|
-
@ip += 1
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def self.mul
|
|
33
|
-
Proc.new do |vm|
|
|
34
|
-
left = @data_stack.pop
|
|
35
|
-
right = @data_stack.pop
|
|
36
|
-
@data_stack.push left * right
|
|
37
|
-
@ip += 1
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def self.div
|
|
42
|
-
Proc.new do |vm|
|
|
43
|
-
left = @data_stack.pop
|
|
44
|
-
right = @data_stack.pop
|
|
45
|
-
@data_stack.push left / right
|
|
46
|
-
@ip += 1
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def self.pop
|
|
51
|
-
Proc.new do |vm|
|
|
52
|
-
ret = @data_stack.pop
|
|
53
|
-
@ip += 1
|
|
54
|
-
ret
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def self.push
|
|
59
|
-
Proc.new do |vm|
|
|
60
|
-
operand = @opcodes[@ip + 1]
|
|
61
|
-
@data_stack.push operand
|
|
62
|
-
@ip += 2
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def self.equal
|
|
67
|
-
Proc.new do |vm|
|
|
68
|
-
left = @data_stack.pop
|
|
69
|
-
right = @data_stack.pop
|
|
70
|
-
result = left == right
|
|
71
|
-
@data_stack.push (result).to_s.upcase.to_sym
|
|
72
|
-
@ip += 1
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def self.greater_than
|
|
77
|
-
Proc.new do |vm|
|
|
78
|
-
left = @data_stack.pop
|
|
79
|
-
right = @data_stack.pop
|
|
80
|
-
result = left > right
|
|
81
|
-
@data_stack.push (result).to_s.upcase.to_sym
|
|
82
|
-
@ip += 1
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def self.less_than
|
|
87
|
-
Proc.new do |vm|
|
|
88
|
-
left = @data_stack.pop
|
|
89
|
-
right = @data_stack.pop
|
|
90
|
-
result = left < right
|
|
91
|
-
@data_stack.push (result).to_s.upcase.to_sym
|
|
92
|
-
@ip += 1
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def self.invert
|
|
97
|
-
Proc.new do |vm|
|
|
98
|
-
value = @data_stack.pop
|
|
99
|
-
@data_stack.push (!value).to_s.upcase.to_sym
|
|
100
|
-
@ip += 1
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def self.exit
|
|
105
|
-
Proc.new do |vm|
|
|
106
|
-
@ip = @opcodes.length
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def self.no_op
|
|
111
|
-
Proc.new do |vm|
|
|
112
|
-
@ip += 1
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def self.jump
|
|
117
|
-
Proc.new do |vm|
|
|
118
|
-
@ip = @data_stack.pop
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def self.jump_if
|
|
123
|
-
Proc.new do |vm|
|
|
124
|
-
dest = @data_stack.pop
|
|
125
|
-
left = @data_stack.pop
|
|
126
|
-
right = @data_stack.pop
|
|
127
|
-
left == right ? @ip = dest : @ip += 1
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def self.jump_unless
|
|
132
|
-
Proc.new do |vm|
|
|
133
|
-
dest = @data_stack.pop
|
|
134
|
-
left = @data_stack.pop
|
|
135
|
-
right = @data_stack.pop
|
|
136
|
-
left != right ? @ip = dest : @ip += 1
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def self.to_string
|
|
141
|
-
Proc.new do |vm|
|
|
142
|
-
value = @data_stack.pop
|
|
143
|
-
@data_stack.push value.to_s
|
|
144
|
-
@ip += 1
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def self.put_string
|
|
149
|
-
Proc.new do |vm|
|
|
150
|
-
operand = @opcodes[@ip + 1]
|
|
151
|
-
@data_stack.push operand
|
|
152
|
-
@ip += 2
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def self.dup
|
|
157
|
-
Proc.new do |vm|
|
|
158
|
-
@data_stack.push @data_stack.first
|
|
159
|
-
@ip += 1
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
def self.swap
|
|
164
|
-
Proc.new do |vm|
|
|
165
|
-
left = @data_stack.pop
|
|
166
|
-
right = @data_stack.pop
|
|
167
|
-
[left, right].each { |a| @data_stack.push a }
|
|
168
|
-
@ip += 1
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
def self.over
|
|
173
|
-
Proc.new do |vm|
|
|
174
|
-
left = @data_stack.pop
|
|
175
|
-
right = @data_stack.pop
|
|
176
|
-
[left, right, left].each { |a| @data_stack.push a }
|
|
177
|
-
@ip += 1
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
def self.rot
|
|
182
|
-
Proc.new do |vm|
|
|
183
|
-
one = @data_stack.pop
|
|
184
|
-
two = @data_stack.pop
|
|
185
|
-
three = @data_stack.pop
|
|
186
|
-
[two, three, one].each { |a| @data_stack.push a }
|
|
187
|
-
@ip += 1
|
|
188
|
-
end
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def self.print
|
|
192
|
-
Proc.new do |vm|
|
|
193
|
-
puts @data_stack.pop
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
@
|
|
202
|
-
@
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
@
|
|
212
|
-
@
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
@
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
@ip
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
end
|
|
1
|
+
module Carban
|
|
2
|
+
module InstructionSet
|
|
3
|
+
include OpCodes
|
|
4
|
+
|
|
5
|
+
def self.load
|
|
6
|
+
compiled_set = {}
|
|
7
|
+
OpCodes.constants.each do |code|
|
|
8
|
+
numerical = OpCodes.const_get code
|
|
9
|
+
compiled_set[numerical] = send(code.to_s.downcase.to_sym)
|
|
10
|
+
end
|
|
11
|
+
return compiled_set
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.add
|
|
15
|
+
Proc.new do |vm|
|
|
16
|
+
left = @data_stack.pop
|
|
17
|
+
right = @data_stack.pop
|
|
18
|
+
@data_stack.push(left + right)
|
|
19
|
+
@ip += 1
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.sub
|
|
24
|
+
Proc.new do |vm|
|
|
25
|
+
right = @data_stack.pop
|
|
26
|
+
left = @data_stack.pop
|
|
27
|
+
@data_stack.push (left - right)
|
|
28
|
+
@ip += 1
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.mul
|
|
33
|
+
Proc.new do |vm|
|
|
34
|
+
left = @data_stack.pop
|
|
35
|
+
right = @data_stack.pop
|
|
36
|
+
@data_stack.push left * right
|
|
37
|
+
@ip += 1
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.div
|
|
42
|
+
Proc.new do |vm|
|
|
43
|
+
left = @data_stack.pop
|
|
44
|
+
right = @data_stack.pop
|
|
45
|
+
@data_stack.push left / right
|
|
46
|
+
@ip += 1
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.pop
|
|
51
|
+
Proc.new do |vm|
|
|
52
|
+
ret = @data_stack.pop
|
|
53
|
+
@ip += 1
|
|
54
|
+
ret
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.push
|
|
59
|
+
Proc.new do |vm|
|
|
60
|
+
operand = @opcodes[@ip + 1]
|
|
61
|
+
@data_stack.push operand
|
|
62
|
+
@ip += 2
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.equal
|
|
67
|
+
Proc.new do |vm|
|
|
68
|
+
left = @data_stack.pop
|
|
69
|
+
right = @data_stack.pop
|
|
70
|
+
result = left == right
|
|
71
|
+
@data_stack.push (result).to_s.upcase.to_sym
|
|
72
|
+
@ip += 1
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.greater_than
|
|
77
|
+
Proc.new do |vm|
|
|
78
|
+
left = @data_stack.pop
|
|
79
|
+
right = @data_stack.pop
|
|
80
|
+
result = left > right
|
|
81
|
+
@data_stack.push (result).to_s.upcase.to_sym
|
|
82
|
+
@ip += 1
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def self.less_than
|
|
87
|
+
Proc.new do |vm|
|
|
88
|
+
left = @data_stack.pop
|
|
89
|
+
right = @data_stack.pop
|
|
90
|
+
result = left < right
|
|
91
|
+
@data_stack.push (result).to_s.upcase.to_sym
|
|
92
|
+
@ip += 1
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.invert
|
|
97
|
+
Proc.new do |vm|
|
|
98
|
+
value = @data_stack.pop
|
|
99
|
+
@data_stack.push (!value).to_s.upcase.to_sym
|
|
100
|
+
@ip += 1
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def self.exit
|
|
105
|
+
Proc.new do |vm|
|
|
106
|
+
@ip = @opcodes.length
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def self.no_op
|
|
111
|
+
Proc.new do |vm|
|
|
112
|
+
@ip += 1
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def self.jump
|
|
117
|
+
Proc.new do |vm|
|
|
118
|
+
@ip = @data_stack.pop
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def self.jump_if
|
|
123
|
+
Proc.new do |vm|
|
|
124
|
+
dest = @data_stack.pop
|
|
125
|
+
left = @data_stack.pop
|
|
126
|
+
right = @data_stack.pop
|
|
127
|
+
left == right ? @ip = dest : @ip += 1
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def self.jump_unless
|
|
132
|
+
Proc.new do |vm|
|
|
133
|
+
dest = @data_stack.pop
|
|
134
|
+
left = @data_stack.pop
|
|
135
|
+
right = @data_stack.pop
|
|
136
|
+
left != right ? @ip = dest : @ip += 1
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def self.to_string
|
|
141
|
+
Proc.new do |vm|
|
|
142
|
+
value = @data_stack.pop
|
|
143
|
+
@data_stack.push value.to_s
|
|
144
|
+
@ip += 1
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def self.put_string
|
|
149
|
+
Proc.new do |vm|
|
|
150
|
+
operand = @opcodes[@ip + 1]
|
|
151
|
+
@data_stack.push operand
|
|
152
|
+
@ip += 2
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def self.dup
|
|
157
|
+
Proc.new do |vm|
|
|
158
|
+
@data_stack.push @data_stack.first
|
|
159
|
+
@ip += 1
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def self.swap
|
|
164
|
+
Proc.new do |vm|
|
|
165
|
+
left = @data_stack.pop
|
|
166
|
+
right = @data_stack.pop
|
|
167
|
+
[left, right].each { |a| @data_stack.push a }
|
|
168
|
+
@ip += 1
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def self.over
|
|
173
|
+
Proc.new do |vm|
|
|
174
|
+
left = @data_stack.pop
|
|
175
|
+
right = @data_stack.pop
|
|
176
|
+
[left, right, left].each { |a| @data_stack.push a }
|
|
177
|
+
@ip += 1
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def self.rot
|
|
182
|
+
Proc.new do |vm|
|
|
183
|
+
one = @data_stack.pop
|
|
184
|
+
two = @data_stack.pop
|
|
185
|
+
three = @data_stack.pop
|
|
186
|
+
[two, three, one].each { |a| @data_stack.push a }
|
|
187
|
+
@ip += 1
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def self.print
|
|
192
|
+
Proc.new do |vm|
|
|
193
|
+
puts @data_stack.pop
|
|
194
|
+
@ip += 1
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def self.store_global
|
|
199
|
+
Proc.new do |vm|
|
|
200
|
+
name = @opcodes[@ip + 1]
|
|
201
|
+
val = @opcodes[@ip + 2]
|
|
202
|
+
@globals[name] = val
|
|
203
|
+
@ip += 3
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def self.store_local
|
|
209
|
+
Proc.new do |vm|
|
|
210
|
+
name = @opcodes[@ip + 1]
|
|
211
|
+
val = @opcodes[@ip + 2]
|
|
212
|
+
@locals[name] = val
|
|
213
|
+
@ip += 3
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def self.code_call
|
|
218
|
+
Proc.new do |vm|
|
|
219
|
+
@call_stack.push(@ip)
|
|
220
|
+
@ip = @opcodes[@ip + 1]
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def self.code_return
|
|
225
|
+
Proc.new do |vm|
|
|
226
|
+
@ip = @call_stack.pop
|
|
227
|
+
@ip += 1
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
data/lib/carban/op_codes.rb
CHANGED
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
module Carban
|
|
2
|
-
module OpCodes
|
|
3
|
-
|
|
4
|
-
ADD
|
|
5
|
-
SUB
|
|
6
|
-
MUL
|
|
7
|
-
DIV
|
|
8
|
-
|
|
9
|
-
POP
|
|
10
|
-
PUSH
|
|
11
|
-
|
|
12
|
-
EQUAL
|
|
13
|
-
GREATER_THAN
|
|
14
|
-
LESS_THAN
|
|
15
|
-
INVERT
|
|
16
|
-
|
|
17
|
-
EXIT
|
|
18
|
-
NO_OP
|
|
19
|
-
|
|
20
|
-
JUMP
|
|
21
|
-
JUMP_IF
|
|
22
|
-
JUMP_UNLESS
|
|
23
|
-
|
|
24
|
-
PUT_STRING
|
|
25
|
-
TO_STRING
|
|
26
|
-
|
|
27
|
-
DUP
|
|
28
|
-
SWAP
|
|
29
|
-
OVER
|
|
30
|
-
ROT
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
end
|
|
40
|
-
end
|
|
1
|
+
module Carban
|
|
2
|
+
module OpCodes
|
|
3
|
+
|
|
4
|
+
ADD = 00
|
|
5
|
+
SUB = 01
|
|
6
|
+
MUL = 02
|
|
7
|
+
DIV = 03
|
|
8
|
+
|
|
9
|
+
POP = 14
|
|
10
|
+
PUSH = 15
|
|
11
|
+
|
|
12
|
+
EQUAL = 26
|
|
13
|
+
GREATER_THAN = 27
|
|
14
|
+
LESS_THAN = 28
|
|
15
|
+
INVERT = 29
|
|
16
|
+
|
|
17
|
+
EXIT = 40
|
|
18
|
+
NO_OP = 41
|
|
19
|
+
|
|
20
|
+
JUMP = 50
|
|
21
|
+
JUMP_IF = 51
|
|
22
|
+
JUMP_UNLESS = 52
|
|
23
|
+
|
|
24
|
+
PUT_STRING = 60
|
|
25
|
+
TO_STRING = 61
|
|
26
|
+
|
|
27
|
+
DUP = 70
|
|
28
|
+
SWAP = 71
|
|
29
|
+
OVER = 72
|
|
30
|
+
ROT = 73
|
|
31
|
+
|
|
32
|
+
PRINT = 80
|
|
33
|
+
|
|
34
|
+
STORE_GLOBAL = 90
|
|
35
|
+
STORE_LOCAL = 100
|
|
36
|
+
|
|
37
|
+
CODE_CALL = 110
|
|
38
|
+
CODE_RETURN = 111
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/carban/stack_machine.rb
CHANGED
|
@@ -1,47 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
module Carban
|
|
3
|
-
class StackMachine
|
|
4
|
-
attr_accessor :opcodes, :call_stack, :data_stack, :instructions, :ip, :globals, :locals
|
|
5
|
-
extend InstructionSet
|
|
6
|
-
|
|
7
|
-
def initialize
|
|
8
|
-
@globals = {}
|
|
9
|
-
@
|
|
10
|
-
@
|
|
11
|
-
@
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
line
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
end
|
|
47
|
-
end
|
|
1
|
+
|
|
2
|
+
module Carban
|
|
3
|
+
class StackMachine
|
|
4
|
+
attr_accessor :opcodes, :call_stack, :data_stack, :instructions, :ip, :globals, :locals
|
|
5
|
+
extend InstructionSet
|
|
6
|
+
|
|
7
|
+
def initialize
|
|
8
|
+
@globals = @locals = {}
|
|
9
|
+
@opcodes = @data_stack = @call_stack = []
|
|
10
|
+
@instructions = InstructionSet.load
|
|
11
|
+
@ip = 0
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def run
|
|
15
|
+
@ip = 0
|
|
16
|
+
@data_stack = @call_stack = []
|
|
17
|
+
while(@ip < @opcodes.length) do
|
|
18
|
+
self.instance_eval &@instructions[ @opcodes[@ip] ]
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def dump
|
|
23
|
+
{
|
|
24
|
+
:opcodes => @opcodes,
|
|
25
|
+
:data_stack => @data_stack,
|
|
26
|
+
:instructions => @instructions,
|
|
27
|
+
:instruction_pointer => @ip
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def load_program(file)
|
|
32
|
+
content = File.open(file).read
|
|
33
|
+
@opcodes = assemble(content)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def assemble(str)
|
|
37
|
+
str.split("\n").map do |expr|
|
|
38
|
+
line = expr.split(", ")
|
|
39
|
+
keyword_opcode = OpCodes.const_get(line.first.to_sym)
|
|
40
|
+
line.size > 1 ? [keyword_opcode, line.last.to_i] : keyword_opcode
|
|
41
|
+
end.flatten
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/carban/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: carban
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.0.2
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- patrick
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 2019-05-30 00:00:00.000000000 Z
|
|
13
12
|
dependencies: []
|
|
14
|
-
description: A Virtual Machine implemented as Abstract Stack Machine
|
|
15
|
-
Register Machine
|
|
13
|
+
description: A Virtual Machine implemented as Abstract Stack Machine
|
|
16
14
|
email:
|
|
17
15
|
- patrick@patrickjones.ca
|
|
18
16
|
executables: []
|
|
19
17
|
extensions: []
|
|
20
18
|
extra_rdoc_files: []
|
|
21
19
|
files:
|
|
22
|
-
- .gitignore
|
|
20
|
+
- ".gitignore"
|
|
23
21
|
- Gemfile
|
|
24
22
|
- LICENSE.txt
|
|
25
23
|
- README.md
|
|
@@ -32,26 +30,25 @@ files:
|
|
|
32
30
|
- lib/carban/version.rb
|
|
33
31
|
homepage: ''
|
|
34
32
|
licenses: []
|
|
33
|
+
metadata: {}
|
|
35
34
|
post_install_message:
|
|
36
35
|
rdoc_options: []
|
|
37
36
|
require_paths:
|
|
38
37
|
- lib
|
|
39
38
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
|
-
none: false
|
|
41
39
|
requirements:
|
|
42
|
-
- -
|
|
40
|
+
- - ">="
|
|
43
41
|
- !ruby/object:Gem::Version
|
|
44
42
|
version: '0'
|
|
45
43
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
46
|
-
none: false
|
|
47
44
|
requirements:
|
|
48
|
-
- -
|
|
45
|
+
- - ">="
|
|
49
46
|
- !ruby/object:Gem::Version
|
|
50
47
|
version: '0'
|
|
51
48
|
requirements: []
|
|
52
49
|
rubyforge_project:
|
|
53
|
-
rubygems_version:
|
|
50
|
+
rubygems_version: 2.6.14
|
|
54
51
|
signing_key:
|
|
55
|
-
specification_version:
|
|
52
|
+
specification_version: 4
|
|
56
53
|
summary: Virtual Machine implementations of the Carban Instruction Set
|
|
57
54
|
test_files: []
|