brainclusterfuck 0.0.1 → 0.2.0

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.
Files changed (57) hide show
  1. data/.travis.yml +6 -0
  2. data/Gemfile +1 -1
  3. data/README.md +4 -0
  4. data/lib/brainclusterfuck/compile_error.rb +10 -0
  5. data/lib/brainclusterfuck/compiler.rb +57 -35
  6. data/lib/brainclusterfuck/error.rb +5 -0
  7. data/lib/brainclusterfuck/interpreter.rb +84 -0
  8. data/lib/brainclusterfuck/interpreter_error.rb +4 -0
  9. data/lib/brainclusterfuck/lexer.rb +2 -2
  10. data/lib/brainclusterfuck/loop_error.rb +6 -0
  11. data/lib/brainclusterfuck/memory.rb +33 -0
  12. data/lib/brainclusterfuck/memory_error.rb +6 -0
  13. data/lib/brainclusterfuck/opcodes.rb +5 -0
  14. data/lib/brainclusterfuck/opcodes/base.rb +19 -0
  15. data/lib/brainclusterfuck/opcodes/loop_base.rb +27 -0
  16. data/lib/brainclusterfuck/opcodes/loop_end.rb +10 -0
  17. data/lib/brainclusterfuck/opcodes/loop_end_placeholder.rb +6 -0
  18. data/lib/brainclusterfuck/opcodes/loop_placeholder.rb +20 -0
  19. data/lib/brainclusterfuck/opcodes/loop_start.rb +10 -0
  20. data/lib/brainclusterfuck/opcodes/loop_start_placeholder.rb +6 -0
  21. data/lib/brainclusterfuck/opcodes/modify_pointer.rb +9 -0
  22. data/lib/brainclusterfuck/opcodes/modify_value.rb +6 -0
  23. data/lib/brainclusterfuck/opcodes/modifying_base.rb +27 -0
  24. data/lib/brainclusterfuck/opcodes/print.rb +13 -0
  25. data/lib/brainclusterfuck/terminal.rb +4 -0
  26. data/lib/brainclusterfuck/version.rb +1 -1
  27. data/spec/compiler_spec.rb +82 -16
  28. data/spec/integration/basic_loops_spec.rb +55 -0
  29. data/spec/integration/basic_print_spec.rb +65 -0
  30. data/spec/integration/boundary_conditions_spec.rb +81 -0
  31. data/spec/interpreter_spec.rb +154 -0
  32. data/spec/lexer_spec.rb +2 -2
  33. data/spec/memory_spec.rb +33 -0
  34. data/spec/opcodes/base_spec.rb +26 -0
  35. data/spec/opcodes/loop_end_placeholder_spec.rb +5 -0
  36. data/spec/opcodes/loop_end_spec.rb +7 -0
  37. data/spec/opcodes/loop_start_placeholder_spec.rb +5 -0
  38. data/spec/opcodes/loop_start_spec.rb +7 -0
  39. data/spec/opcodes/modify_pointer_spec.rb +6 -0
  40. data/spec/opcodes/modify_value_spec.rb +6 -0
  41. data/spec/{opcode → opcodes}/print_spec.rb +3 -3
  42. data/spec/spec_helper.rb +2 -0
  43. data/spec/support/loop_opcode_shared_behavior.rb +22 -0
  44. data/spec/support/loop_placeholder_shared_behavior.rb +12 -0
  45. data/spec/{opcode/modify_value_spec.rb → support/modifying_opcode_shared_behavior.rb} +4 -7
  46. data/spec/terminal_spec.rb +11 -0
  47. metadata +60 -20
  48. data/lib/brainclusterfuck/cells.rb +0 -9
  49. data/lib/brainclusterfuck/opcode.rb +0 -11
  50. data/lib/brainclusterfuck/opcode/modify_pointer.rb +0 -27
  51. data/lib/brainclusterfuck/opcode/modify_value.rb +0 -27
  52. data/lib/brainclusterfuck/opcode/print.rb +0 -13
  53. data/lib/brainclusterfuck/vm.rb +0 -11
  54. data/spec/cells_spec.rb +0 -8
  55. data/spec/opcode/modify_pointer_spec.rb +0 -37
  56. data/spec/opcode_spec.rb +0 -10
  57. data/spec/vm_spec.rb +0 -22
data/spec/lexer_spec.rb CHANGED
@@ -21,8 +21,8 @@ describe Brainclusterfuck::Lexer do
21
21
  expect(lexer.tokens).to eq([
22
22
  :v_incr,
23
23
  :p_incr,
24
- :end_loop,
25
- :loop,
24
+ :loop_end,
25
+ :loop_start,
26
26
  :p_decr,
27
27
  :v_decr,
28
28
  :print
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+ require 'brainclusterfuck/memory'
3
+
4
+ describe Brainclusterfuck::Memory do
5
+ let(:memory) { Brainclusterfuck::Memory.new(5) }
6
+ it 'initializes with a size' do
7
+ expect(memory.size).to eq(5)
8
+ end
9
+
10
+ it 'starts at value 0' do
11
+ expect(memory.current_value).to eq(0)
12
+ end
13
+
14
+ it 'can modify the current value' do
15
+ memory.modify_value(5)
16
+
17
+ expect(memory.current_value).to eq(5)
18
+ end
19
+
20
+ it 'can modify the pointer' do
21
+ memory.modify_value(5)
22
+
23
+ memory.modify_pointer(1)
24
+ expect(memory.current_value).to eq(0)
25
+
26
+ memory.modify_pointer(-1)
27
+ expect(memory.current_value).to eq(5)
28
+ end
29
+
30
+ it 'raises if modifying the pointer out of bounds' do
31
+ expect { memory.modify_pointer(-1) }.to raise_error(Brainclusterfuck::MemoryError)
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+ require 'brainclusterfuck/opcodes/base'
3
+
4
+ describe Brainclusterfuck::Opcodes::Base do
5
+ describe '#can_squeeze_with?' do
6
+ it 'is false' do
7
+ expect(described_class.new.can_squeeze_with?(described_class.new)).to eq(false)
8
+ end
9
+ end
10
+
11
+ describe '#unresolve_loop' do
12
+ it 'returns self' do
13
+ op = described_class.new
14
+
15
+ expect(op.unresolve_loop).to equal(op)
16
+ end
17
+ end
18
+
19
+ describe '#resolve_loop' do
20
+ it 'returns self' do
21
+ op = described_class.new
22
+
23
+ expect(op.resolve_loop).to equal(op)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ require 'brainclusterfuck/opcodes/loop_end_placeholder'
2
+
3
+ describe Brainclusterfuck::Opcodes::LoopEndPlaceholder do
4
+ it_behaves_like 'a loop placeholder'
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+ require 'brainclusterfuck/opcodes/loop_end'
3
+
4
+ describe Brainclusterfuck::Opcodes::LoopEnd do
5
+ let(:placeholder_class) { Brainclusterfuck::Opcodes::LoopEndPlaceholder }
6
+ it_behaves_like 'a loop opcode'
7
+ end
@@ -0,0 +1,5 @@
1
+ require 'brainclusterfuck/opcodes/loop_start_placeholder'
2
+
3
+ describe Brainclusterfuck::Opcodes::LoopStartPlaceholder do
4
+ it_behaves_like 'a loop placeholder'
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+ require 'brainclusterfuck/opcodes/loop_start'
3
+
4
+ describe Brainclusterfuck::Opcodes::LoopStart do
5
+ let(:placeholder_class) { Brainclusterfuck::Opcodes::LoopStartPlaceholder }
6
+ it_behaves_like 'a loop opcode'
7
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'brainclusterfuck/opcodes/modify_pointer'
3
+
4
+ describe Brainclusterfuck::Opcodes::ModifyPointer do
5
+ it_behaves_like 'a modifying opcode'
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+ require 'brainclusterfuck/opcodes/modify_value'
3
+
4
+ describe Brainclusterfuck::Opcodes::ModifyValue do
5
+ it_behaves_like 'a modifying opcode'
6
+ end
@@ -1,13 +1,13 @@
1
1
  require 'spec_helper'
2
- require 'brainclusterfuck/opcode/print'
2
+ require 'brainclusterfuck/opcodes/print'
3
3
 
4
- describe Brainclusterfuck::Opcode::Print do
4
+ describe Brainclusterfuck::Opcodes::Print do
5
5
  it 'has 1 cycle' do
6
6
  expect(described_class.new.cycles).to eq(1)
7
7
  end
8
8
 
9
9
  it 'has correct equality behavior' do
10
10
  expect(described_class.new).to eq(described_class.new)
11
- expect(described_class.new).not_to eq(Brainclusterfuck::Opcode.new)
11
+ expect(described_class.new).not_to eq(Brainclusterfuck::Opcodes::Base.new)
12
12
  end
13
13
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
2
3
 
3
4
  require 'rspec'
5
+ require 'should_not/rspec'
4
6
 
5
7
  RSpec.configure do |config|
6
8
  config.expect_with :rspec do |c|
@@ -0,0 +1,22 @@
1
+ require 'brainclusterfuck/loop_error'
2
+
3
+ shared_examples 'a loop opcode' do
4
+ it 'has num_operations' do
5
+ op = described_class.new(3)
6
+
7
+ expect(op.num_operations).to eq(3)
8
+ end
9
+
10
+ it 'uses equality' do
11
+ expect(described_class.new(1)).to eq(described_class.new(1))
12
+ expect(described_class.new(1)).not_to eq(described_class.new(2))
13
+ end
14
+
15
+ it 'can unresolve' do
16
+ expect(described_class.new(1).unresolve_loop).to be_a(placeholder_class)
17
+ end
18
+
19
+ it 'raises on resolve' do
20
+ expect { described_class.new(1).resolve_loop }.to raise_error(Brainclusterfuck::LoopError)
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ require 'brainclusterfuck/loop_error'
2
+
3
+ shared_examples 'a loop placeholder' do
4
+ it 'uses equality' do
5
+ expect(described_class.new).to eq(described_class.new)
6
+ expect(described_class.new).not_to eq(Brainclusterfuck::Opcodes::Base.new)
7
+ end
8
+
9
+ it 'raises on unresolve' do
10
+ expect { described_class.new.unresolve_loop }.to raise_error(Brainclusterfuck::LoopError)
11
+ end
12
+ end
@@ -1,7 +1,4 @@
1
- require 'spec_helper'
2
- require 'brainclusterfuck/opcode/modify_value'
3
-
4
- describe Brainclusterfuck::Opcode::ModifyValue do
1
+ shared_examples 'a modifying opcode' do
5
2
  it 'stores the modify by and cycle count' do
6
3
  op = described_class.new(5, 8)
7
4
 
@@ -15,7 +12,7 @@ describe Brainclusterfuck::Opcode::ModifyValue do
15
12
  end
16
13
 
17
14
  describe 'squeezing' do
18
- it 'can squeeze with another ModifyValue' do
15
+ it "can squeeze with another #{described_class}" do
19
16
  op1 = described_class.new(1, 1)
20
17
  op2 = described_class.new(1, 1)
21
18
 
@@ -25,13 +22,13 @@ describe Brainclusterfuck::Opcode::ModifyValue do
25
22
 
26
23
  it 'cannot squeeze with a generic opcode' do
27
24
  op = described_class.new(1, 1)
28
- expect(op.can_squeeze_with?(Brainclusterfuck::Opcode.new)).to eq(false)
25
+ expect(op.can_squeeze_with?(Brainclusterfuck::Opcodes::Base.new)).to eq(false)
29
26
  end
30
27
 
31
28
  it 'raises if trying to squeeze with an incompatible object' do
32
29
  op = described_class.new(1, 1)
33
30
 
34
- expect { op.squeeze_with(Brainclusterfuck::Opcode.new) }.to raise_error
31
+ expect { op.squeeze_with(Brainclusterfuck::Opcodes::Base.new) }.to raise_error
35
32
  end
36
33
  end
37
34
  end
@@ -5,4 +5,15 @@ describe Brainclusterfuck::Terminal do
5
5
  it 'starts with empty text' do
6
6
  expect(Brainclusterfuck::Terminal.new.text).to eq('')
7
7
  end
8
+
9
+ it 'can print' do
10
+ terminal = Brainclusterfuck::Terminal.new
11
+ terminal.print('a')
12
+
13
+ expect(terminal.text).to eq('a')
14
+
15
+ terminal.print('b')
16
+
17
+ expect(terminal.text).to eq('ab')
18
+ end
8
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainclusterfuck
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-21 00:00:00.000000000 Z
12
+ date: 2013-04-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -68,33 +68,57 @@ extensions: []
68
68
  extra_rdoc_files: []
69
69
  files:
70
70
  - .gitignore
71
+ - .travis.yml
71
72
  - Gemfile
72
73
  - LICENSE.mit
73
74
  - README.md
74
75
  - Rakefile
75
76
  - brainclusterfuck.gemspec
76
77
  - lib/brainclusterfuck.rb
77
- - lib/brainclusterfuck/cells.rb
78
+ - lib/brainclusterfuck/compile_error.rb
78
79
  - lib/brainclusterfuck/compiler.rb
80
+ - lib/brainclusterfuck/error.rb
81
+ - lib/brainclusterfuck/interpreter.rb
82
+ - lib/brainclusterfuck/interpreter_error.rb
79
83
  - lib/brainclusterfuck/lexer.rb
80
- - lib/brainclusterfuck/opcode.rb
81
- - lib/brainclusterfuck/opcode/modify_pointer.rb
82
- - lib/brainclusterfuck/opcode/modify_value.rb
83
- - lib/brainclusterfuck/opcode/print.rb
84
+ - lib/brainclusterfuck/loop_error.rb
85
+ - lib/brainclusterfuck/memory.rb
86
+ - lib/brainclusterfuck/memory_error.rb
87
+ - lib/brainclusterfuck/opcodes.rb
88
+ - lib/brainclusterfuck/opcodes/base.rb
89
+ - lib/brainclusterfuck/opcodes/loop_base.rb
90
+ - lib/brainclusterfuck/opcodes/loop_end.rb
91
+ - lib/brainclusterfuck/opcodes/loop_end_placeholder.rb
92
+ - lib/brainclusterfuck/opcodes/loop_placeholder.rb
93
+ - lib/brainclusterfuck/opcodes/loop_start.rb
94
+ - lib/brainclusterfuck/opcodes/loop_start_placeholder.rb
95
+ - lib/brainclusterfuck/opcodes/modify_pointer.rb
96
+ - lib/brainclusterfuck/opcodes/modify_value.rb
97
+ - lib/brainclusterfuck/opcodes/modifying_base.rb
98
+ - lib/brainclusterfuck/opcodes/print.rb
84
99
  - lib/brainclusterfuck/terminal.rb
85
100
  - lib/brainclusterfuck/version.rb
86
- - lib/brainclusterfuck/vm.rb
87
- - spec/cells_spec.rb
88
101
  - spec/compiler_spec.rb
102
+ - spec/integration/basic_loops_spec.rb
103
+ - spec/integration/basic_print_spec.rb
104
+ - spec/integration/boundary_conditions_spec.rb
105
+ - spec/interpreter_spec.rb
89
106
  - spec/lexer_spec.rb
90
- - spec/opcode/modify_pointer_spec.rb
91
- - spec/opcode/modify_value_spec.rb
92
- - spec/opcode/print_spec.rb
93
- - spec/opcode_spec.rb
107
+ - spec/memory_spec.rb
108
+ - spec/opcodes/base_spec.rb
109
+ - spec/opcodes/loop_end_placeholder_spec.rb
110
+ - spec/opcodes/loop_end_spec.rb
111
+ - spec/opcodes/loop_start_placeholder_spec.rb
112
+ - spec/opcodes/loop_start_spec.rb
113
+ - spec/opcodes/modify_pointer_spec.rb
114
+ - spec/opcodes/modify_value_spec.rb
115
+ - spec/opcodes/print_spec.rb
94
116
  - spec/should_not_spec.rb
95
117
  - spec/spec_helper.rb
118
+ - spec/support/loop_opcode_shared_behavior.rb
119
+ - spec/support/loop_placeholder_shared_behavior.rb
120
+ - spec/support/modifying_opcode_shared_behavior.rb
96
121
  - spec/terminal_spec.rb
97
- - spec/vm_spec.rb
98
122
  homepage: http://github.com/mark-rushakoff/brainclusterfuck
99
123
  licenses:
100
124
  - MIT
@@ -108,12 +132,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
132
  - - ! '>='
109
133
  - !ruby/object:Gem::Version
110
134
  version: '0'
135
+ segments:
136
+ - 0
137
+ hash: 1832149583258745697
111
138
  required_rubygems_version: !ruby/object:Gem::Requirement
112
139
  none: false
113
140
  requirements:
114
141
  - - ! '>='
115
142
  - !ruby/object:Gem::Version
116
143
  version: '0'
144
+ segments:
145
+ - 0
146
+ hash: 1832149583258745697
117
147
  requirements: []
118
148
  rubyforge_project:
119
149
  rubygems_version: 1.8.25
@@ -121,14 +151,24 @@ signing_key:
121
151
  specification_version: 3
122
152
  summary: Clean API to arrays of Brainfuck VMs
123
153
  test_files:
124
- - spec/cells_spec.rb
125
154
  - spec/compiler_spec.rb
155
+ - spec/integration/basic_loops_spec.rb
156
+ - spec/integration/basic_print_spec.rb
157
+ - spec/integration/boundary_conditions_spec.rb
158
+ - spec/interpreter_spec.rb
126
159
  - spec/lexer_spec.rb
127
- - spec/opcode/modify_pointer_spec.rb
128
- - spec/opcode/modify_value_spec.rb
129
- - spec/opcode/print_spec.rb
130
- - spec/opcode_spec.rb
160
+ - spec/memory_spec.rb
161
+ - spec/opcodes/base_spec.rb
162
+ - spec/opcodes/loop_end_placeholder_spec.rb
163
+ - spec/opcodes/loop_end_spec.rb
164
+ - spec/opcodes/loop_start_placeholder_spec.rb
165
+ - spec/opcodes/loop_start_spec.rb
166
+ - spec/opcodes/modify_pointer_spec.rb
167
+ - spec/opcodes/modify_value_spec.rb
168
+ - spec/opcodes/print_spec.rb
131
169
  - spec/should_not_spec.rb
132
170
  - spec/spec_helper.rb
171
+ - spec/support/loop_opcode_shared_behavior.rb
172
+ - spec/support/loop_placeholder_shared_behavior.rb
173
+ - spec/support/modifying_opcode_shared_behavior.rb
133
174
  - spec/terminal_spec.rb
134
- - spec/vm_spec.rb
@@ -1,9 +0,0 @@
1
- module Brainclusterfuck
2
- class Cells
3
- attr_reader :size
4
-
5
- def initialize(size)
6
- @size = size.to_i
7
- end
8
- end
9
- end
@@ -1,11 +0,0 @@
1
- require 'brainclusterfuck/opcode/modify_value'
2
-
3
- module Brainclusterfuck
4
- class Opcode
5
- attr_reader :cycles
6
-
7
- def can_squeeze_with?(other)
8
- false
9
- end
10
- end
11
- end
@@ -1,27 +0,0 @@
1
- module Brainclusterfuck
2
- class Opcode
3
- class ModifyPointer < Opcode
4
- attr_reader :modify_by
5
-
6
- def initialize(modify_by, cycles)
7
- @modify_by = modify_by.to_i
8
- @cycles = cycles.to_i
9
- end
10
-
11
- def ==(other)
12
- other.is_a?(ModifyPointer) &&
13
- other.modify_by == modify_by &&
14
- other.cycles == cycles
15
- end
16
-
17
- def can_squeeze_with?(other)
18
- other.is_a?(ModifyPointer)
19
- end
20
-
21
- def squeeze_with(other)
22
- raise "Cannot squeeze: #{self}, #{other}" unless can_squeeze_with?(other)
23
- ModifyPointer.new(modify_by + other.modify_by, cycles + other.cycles)
24
- end
25
- end
26
- end
27
- end
@@ -1,27 +0,0 @@
1
- module Brainclusterfuck
2
- class Opcode
3
- class ModifyValue < Opcode
4
- attr_reader :modify_by
5
-
6
- def initialize(modify_by, cycles)
7
- @modify_by = modify_by.to_i
8
- @cycles = cycles.to_i
9
- end
10
-
11
- def ==(other)
12
- other.is_a?(ModifyValue) &&
13
- other.modify_by == modify_by &&
14
- other.cycles == cycles
15
- end
16
-
17
- def can_squeeze_with?(other)
18
- other.is_a?(ModifyValue)
19
- end
20
-
21
- def squeeze_with(other)
22
- raise "Cannot squeeze: #{self}, #{other}" unless can_squeeze_with?(other)
23
- ModifyValue.new(modify_by + other.modify_by, cycles + other.cycles)
24
- end
25
- end
26
- end
27
- end