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.
@@ -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
- TODO: A Rubygem that implements the Carban Instruction Set as a Virtual Machine.
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
+
@@ -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 and Abstract Register 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
 
@@ -4,5 +4,4 @@ require "carban/instruction_set"
4
4
  require "carban/stack_machine"
5
5
 
6
6
  module Carban
7
-
8
7
  end
@@ -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
- end
195
- end
196
-
197
- def self.store_global
198
- Proc.new do |vm|
199
- name = @opcodes[@ip + 1]
200
- val = @opcodes[@ip + 2]
201
- @globals[name] = val
202
- @ip += 3
203
- end
204
- end
205
-
206
-
207
- def self.store_local
208
- Proc.new do |vm|
209
- name = @opcodes[@ip + 1]
210
- val = @opcodes[@ip + 2]
211
- @locals[name] = val
212
- @ip += 3
213
- end
214
- end
215
-
216
- def self.code_call
217
- Proc.new do |vm|
218
- @call_stack.push(@ip)
219
- @ip = @opcodes[@ip + 1]
220
- end
221
- end
222
-
223
- def self.code_return
224
- Proc.new do |vm|
225
- @ip = @call_stack.pop
226
- @ip += 1
227
- end
228
- end
229
- end
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
@@ -1,40 +1,40 @@
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
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
@@ -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
- @locals = {}
10
- @opcodes = []
11
- @data_stack = []
12
- @call_stack = []
13
- @instructions = InstructionSet.load
14
- @ip = 0
15
- end
16
-
17
- def run
18
- @ip = 0
19
- while(@ip < @opcodes.length) do
20
- self.instance_eval &@instructions[ @opcodes[@ip] ]
21
- end
22
- end
23
-
24
- def dump
25
- {
26
- :opcodes => @opcodes,
27
- :data_stack => @data_stack,
28
- :instructions => @instructions,
29
- :instruction_pointer => @ip
30
- }
31
- end
32
-
33
- def load_program(file)
34
- content = File.open(file).read
35
- @opcodes = assemble(content)
36
- end
37
-
38
- def assemble(str)
39
- str.split("\n").map do |expr|
40
- line = expr.split(", ")
41
- keyword_opcode = OpCodes.const_get(line.first.to_sym)
42
- line.size > 1 ? [keyword_opcode, line.last.to_i] : keyword_opcode
43
- end.flatten
44
- end
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
@@ -1,3 +1,3 @@
1
1
  module Carban
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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.1
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: 2013-02-13 00:00:00.000000000 Z
11
+ date: 2019-05-30 00:00:00.000000000 Z
13
12
  dependencies: []
14
- description: A Virtual Machine implemented as Abstract Stack Machine and Abstract
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: 1.8.23
50
+ rubygems_version: 2.6.14
54
51
  signing_key:
55
- specification_version: 3
52
+ specification_version: 4
56
53
  summary: Virtual Machine implementations of the Carban Instruction Set
57
54
  test_files: []