braingasm 0.1.0 → 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.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/README.md +5 -5
- data/braingasm.gemspec +3 -3
- data/examples/io.b +25 -0
- data/exe/braingasm +30 -3
- data/lib/braingasm/errors.rb +7 -0
- data/lib/braingasm/machine.rb +25 -15
- data/lib/braingasm/options.rb +39 -0
- data/lib/braingasm/parser.rb +17 -11
- data/lib/braingasm/version.rb +1 -1
- metadata +10 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3239900206d0d94f1e850e61fdd57d58e3b86bcd
|
4
|
+
data.tar.gz: 4fd0c8ad374a69870fe4798d9534ed3030f4ef3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5584e4ae8b22e9124b4d1195826abdb5c8f8e9c41080b76c86f7e42a42f20266d028c3bc937bcd065b4c3c0c63759c5b23f4d2aa9c754312a705ea01ca04fc5
|
7
|
+
data.tar.gz: 0b7042686c1af47686a8bc6428703457b9e4e390a1bc2cb17f4d1655c1192358f128bbb96225936e54ac16510297daaa980590773c9ddd1adc491e2e6741772f
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -28,7 +28,11 @@ More information about the different prefixes and registers will come.
|
|
28
28
|
|
29
29
|
## Installation
|
30
30
|
|
31
|
-
|
31
|
+
Install Braingasm from the command line with:
|
32
|
+
|
33
|
+
$ gem install braingasm
|
34
|
+
|
35
|
+
Or to use it in your application, add this line to your Gemfile:
|
32
36
|
|
33
37
|
```ruby
|
34
38
|
gem 'braingasm'
|
@@ -38,10 +42,6 @@ And then execute:
|
|
38
42
|
|
39
43
|
$ bundle
|
40
44
|
|
41
|
-
Or install it yourself as:
|
42
|
-
|
43
|
-
$ gem install braingasm
|
44
|
-
|
45
45
|
## Usage
|
46
46
|
|
47
47
|
$ braingasm my_program.bg
|
data/braingasm.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.add_development_dependency "bundler", "~> 1.12"
|
23
|
-
spec.add_development_dependency "rake", "~> 11.2"
|
24
|
-
spec.add_development_dependency "rspec", "~> 3.
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.12.5"
|
23
|
+
spec.add_development_dependency "rake", "~> 11.2.2"
|
24
|
+
spec.add_development_dependency "rspec", "~> 3.5"
|
25
25
|
end
|
data/examples/io.b
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
[
|
2
|
+
Written by Daniel B Cristofani, fetched from
|
3
|
+
http://www.hevanet.com/cristofd/brainfuck/tests.b
|
4
|
+
|
5
|
+
This is for testing i/o; give it a return followed by an EOF. (Try it both
|
6
|
+
with file input--a file consisting only of one blank line--and with
|
7
|
+
keyboard input, i.e. hit return and then ctrl-d (Unix) or ctrl-z
|
8
|
+
(Windows).)
|
9
|
+
|
10
|
+
It should give two lines of output; the two lines should be identical, and
|
11
|
+
should be lined up one over the other. If that doesn't happen, ten is not
|
12
|
+
coming through as newline on output.
|
13
|
+
|
14
|
+
The content of the lines tells how input is being processed; each line
|
15
|
+
should be two uppercase letters.
|
16
|
+
|
17
|
+
Anything with O in it means newline is not coming through as ten on input.
|
18
|
+
* LK means newline input is working fine, and EOF leaves the cell unchanged
|
19
|
+
(which I recommend).
|
20
|
+
* LB means newline input is working fine, and EOF translates as 0.
|
21
|
+
* LA means newline input is working fine, and EOF translates as -1.
|
22
|
+
Anything else is fairly unexpected.
|
23
|
+
]
|
24
|
+
|
25
|
+
>,>+++++++++,>+++++++++++[<++++++<++++++<+>>>-]<<.>.<<-.>.>.<<.
|
data/exe/braingasm
CHANGED
@@ -1,14 +1,41 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'braingasm'
|
4
|
+
require 'braingasm/version'
|
4
5
|
require 'braingasm/errors'
|
6
|
+
require 'braingasm/options'
|
7
|
+
require 'trollop'
|
5
8
|
|
6
|
-
|
9
|
+
def err(message)
|
10
|
+
$stderr.puts message
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
opts = Trollop::options do
|
15
|
+
version "Braingasm v#{Braingasm::VERSION}"
|
16
|
+
|
17
|
+
opt :zero, "EOF returns 0 (default)"
|
18
|
+
opt :negative, "EOF returns -1"
|
19
|
+
opt :as_is, "EOF leaves cell unchanged"
|
20
|
+
conflicts :zero, :negative, :as_is
|
21
|
+
|
22
|
+
opt :unbound, "Allow aritrarily large cells"
|
23
|
+
opt :cell_size, "Cell size in bits",
|
24
|
+
:short => '-s',
|
25
|
+
:default => 8
|
26
|
+
conflicts :unbound, :cell_size
|
27
|
+
end
|
28
|
+
|
29
|
+
Braingasm.handle_options(opts)
|
30
|
+
|
31
|
+
filename = ARGV.shift
|
32
|
+
err "Error: No filname given" unless filename
|
33
|
+
err "Error: No such file: #{filename}" unless File.exists?(filename)
|
7
34
|
|
8
35
|
begin
|
36
|
+
input = IO.read(filename)
|
9
37
|
machine = Braingasm.initialize_machine(input)
|
10
38
|
machine.run
|
11
39
|
rescue Braingasm::BraingasmError => e
|
12
|
-
|
13
|
-
exit 1
|
40
|
+
err "#{e.type}: #{e.message}"
|
14
41
|
end
|
data/lib/braingasm/errors.rb
CHANGED
data/lib/braingasm/machine.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "braingasm/errors"
|
2
|
+
require "braingasm/options"
|
2
3
|
|
3
4
|
module Braingasm
|
4
5
|
|
@@ -23,8 +24,10 @@ module Braingasm
|
|
23
24
|
end
|
24
25
|
|
25
26
|
def step
|
26
|
-
|
27
|
-
@ip
|
27
|
+
@program[@ip].call(self)
|
28
|
+
@ip += 1
|
29
|
+
rescue JumpSignal => jump
|
30
|
+
@ip = jump.to
|
28
31
|
end
|
29
32
|
|
30
33
|
def inst_right(n=1)
|
@@ -37,47 +40,54 @@ module Braingasm
|
|
37
40
|
end
|
38
41
|
|
39
42
|
@dp = new_dp
|
40
|
-
@ip + 1
|
41
43
|
end
|
42
44
|
|
43
45
|
def inst_left(n=1)
|
44
|
-
@dp
|
45
|
-
|
46
|
-
|
46
|
+
new_dp = @dp - n
|
47
|
+
|
48
|
+
if new_dp < 0
|
49
|
+
n.times do
|
50
|
+
@tape.unshift 0
|
51
|
+
end
|
52
|
+
new_dp = 0
|
53
|
+
end
|
54
|
+
|
55
|
+
@dp = new_dp
|
47
56
|
end
|
48
57
|
|
49
58
|
def inst_print_tape
|
50
59
|
p @tape
|
51
|
-
@ip + 1
|
52
60
|
end
|
53
61
|
|
54
62
|
def inst_inc(n=1)
|
55
63
|
@tape[@dp] += n
|
56
|
-
|
64
|
+
wrap_cell
|
57
65
|
end
|
58
66
|
|
59
67
|
def inst_dec(n=1)
|
60
68
|
@tape[@dp] -= n
|
61
|
-
|
69
|
+
wrap_cell
|
62
70
|
end
|
63
71
|
|
64
72
|
def inst_jump(to)
|
65
|
-
to
|
73
|
+
raise JumpSignal.new(to)
|
66
74
|
end
|
67
75
|
|
68
76
|
def inst_jump_if_zero(to)
|
69
|
-
@tape[@dp] == 0
|
77
|
+
raise JumpSignal.new(to) if @tape[@dp] == 0
|
70
78
|
end
|
71
79
|
|
72
80
|
def inst_print_cell
|
73
|
-
|
74
|
-
@ip + 1
|
81
|
+
putc @tape[@dp]
|
75
82
|
end
|
76
83
|
|
77
84
|
def inst_read_byte
|
78
|
-
@tape[@dp] = ARGF.getbyte ||
|
79
|
-
@ip + 1
|
85
|
+
@tape[@dp] = ARGF.getbyte || Options[:eof] || @tape[@dp]
|
80
86
|
end
|
81
87
|
|
88
|
+
private
|
89
|
+
def wrap_cell
|
90
|
+
@tape[@dp] %= Options[:cell_limit] if Options[:wrap_cells]
|
91
|
+
end
|
82
92
|
end
|
83
93
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Braingasm
|
2
|
+
module Options
|
3
|
+
@options = {}
|
4
|
+
@defaults = {
|
5
|
+
eof: 0,
|
6
|
+
wrap_cells: true,
|
7
|
+
cell_limit: 256
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
def self.[](option)
|
11
|
+
return @options[option] if @options.has_key?(option)
|
12
|
+
check_defaults(option)
|
13
|
+
@defaults[option]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.[]=(option, value)
|
17
|
+
check_defaults(option)
|
18
|
+
@options[option] = value
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def self.check_defaults(option)
|
23
|
+
raise ArgumentError, "Unknown option '#{option}'" unless @defaults.has_key?(option)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.handle_options(**command_line_options)
|
28
|
+
Options[:eof] = 0 if command_line_options[:zero]
|
29
|
+
Options[:eof] = -1 if command_line_options[:negative]
|
30
|
+
Options[:eof] = nil if command_line_options[:as_is]
|
31
|
+
|
32
|
+
Options[:wrap_cells] = false if command_line_options[:unbound]
|
33
|
+
|
34
|
+
if command_line_options[:cell_size_given]
|
35
|
+
cell_size = command_line_options[:cell_size]
|
36
|
+
Options[:cell_limit] = 2**cell_size
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/braingasm/parser.rb
CHANGED
@@ -36,17 +36,9 @@ module Braingasm
|
|
36
36
|
when :comma
|
37
37
|
read()
|
38
38
|
when :loop_start
|
39
|
-
|
40
|
-
@loop_stack.push(new_loop)
|
41
|
-
new_loop.start_index = @program.size
|
42
|
-
new_loop
|
39
|
+
loop_start()
|
43
40
|
when :loop_end
|
44
|
-
|
45
|
-
raise_parsing_error("Unmatched `]`") unless current_loop
|
46
|
-
instruction = jump(current_loop.start_index)
|
47
|
-
index = @program.size
|
48
|
-
current_loop.stop_index = index
|
49
|
-
instruction
|
41
|
+
loop_end()
|
50
42
|
end
|
51
43
|
end
|
52
44
|
|
@@ -84,13 +76,27 @@ module Braingasm
|
|
84
76
|
-> m { m.inst_jump(to) }
|
85
77
|
end
|
86
78
|
|
79
|
+
def loop_start()
|
80
|
+
new_loop = Loop.new
|
81
|
+
@loop_stack.push(new_loop)
|
82
|
+
new_loop.start_index = @program.size
|
83
|
+
new_loop
|
84
|
+
end
|
85
|
+
|
86
|
+
def loop_end
|
87
|
+
current_loop = @loop_stack.pop
|
88
|
+
raise_parsing_error("Unmatched `]`") unless current_loop
|
89
|
+
index = @program.size
|
90
|
+
current_loop.stop_index = index
|
91
|
+
jump(current_loop.start_index)
|
92
|
+
end
|
93
|
+
|
87
94
|
class Loop
|
88
95
|
attr_accessor :start_index, :stop_index
|
89
96
|
|
90
97
|
def call(machine)
|
91
98
|
machine.inst_jump_if_zero(stop_index + 1)
|
92
99
|
end
|
93
|
-
|
94
100
|
end
|
95
101
|
|
96
102
|
def raise_parsing_error(message)
|
data/lib/braingasm/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: braingasm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Rødskog
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,42 +16,42 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.12.5
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.12.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 11.2.2
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 11.2.2
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.5'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
54
|
+
version: '3.5'
|
55
55
|
description: braingasm combines the readability of brainfuck with the high-level functionality
|
56
56
|
of assembly
|
57
57
|
email: danielmero@gmail.com
|
@@ -70,10 +70,12 @@ files:
|
|
70
70
|
- bin/console
|
71
71
|
- bin/setup
|
72
72
|
- braingasm.gemspec
|
73
|
+
- examples/io.b
|
73
74
|
- exe/braingasm
|
74
75
|
- lib/braingasm.rb
|
75
76
|
- lib/braingasm/errors.rb
|
76
77
|
- lib/braingasm/machine.rb
|
78
|
+
- lib/braingasm/options.rb
|
77
79
|
- lib/braingasm/parser.rb
|
78
80
|
- lib/braingasm/tokenizer.rb
|
79
81
|
- lib/braingasm/version.rb
|