rbfunge 0.1.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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "bundler", "~> 1.0.0"
11
+ gem "jeweler", "~> 1.5.2"
12
+ gem "rcov", ">= 0"
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,20 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ git (1.2.5)
5
+ jeweler (1.5.2)
6
+ bundler (~> 1.0.0)
7
+ git (>= 1.2.5)
8
+ rake
9
+ rake (0.8.7)
10
+ rcov (0.9.9)
11
+ shoulda (2.11.3)
12
+
13
+ PLATFORMS
14
+ x86-mingw32
15
+
16
+ DEPENDENCIES
17
+ bundler (~> 1.0.0)
18
+ jeweler (~> 1.5.2)
19
+ rcov
20
+ shoulda
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 'Chris
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,20 @@
1
+ = rbfunge
2
+
3
+ Rbfunge is a Befunge-93 interpreter for Ruby (although I may implement Befunge-98 support later).
4
+ Right now it's not so perfect, but I'll keep working on it.
5
+
6
+ == Usage
7
+
8
+ To installl rbfunge:
9
+
10
+ % gem install rbfunge
11
+
12
+ Once rbfunge is installed, you can use it to interpret your Befunge-93 code.
13
+
14
+ Load a file via the command line:
15
+
16
+ % rbfunge test.bf
17
+
18
+ == History
19
+
20
+ * 0.1.0 - Initial release. Pretty unstable.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'rake'
11
+
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
15
+ gem.name = "rbfunge"
16
+ gem.homepage = "http://github.com/ctoneal/rbfunge"
17
+ gem.license = "MIT"
18
+ gem.summary = %Q{A Befunge interpreter in Ruby}
19
+ gem.description = %Q{A Befunge interpreter in Ruby}
20
+ gem.email = "ctoneal@gmail.com"
21
+ gem.authors = ["Chris ONeal"]
22
+ # Include your dependencies below. Runtime dependencies are required when using your gem,
23
+ # and development dependencies are only needed for development (ie running rake tasks, tests, etc)
24
+ # gem.add_runtime_dependency 'jabber4r', '> 0.1'
25
+ # gem.add_development_dependency 'rspec', '> 1.2.3'
26
+ end
27
+ Jeweler::RubygemsDotOrgTasks.new
28
+
29
+ require 'rake/testtask'
30
+ Rake::TestTask.new(:test) do |test|
31
+ test.libs << 'lib' << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+
36
+ require 'rcov/rcovtask'
37
+ Rcov::RcovTask.new do |test|
38
+ test.libs << 'test'
39
+ test.pattern = 'test/**/test_*.rb'
40
+ test.verbose = true
41
+ end
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "rbfunge #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/rbfunge ADDED
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "rbfunge.rb"))
4
+
5
+ options = { }
6
+ op = OptionParser.new do |x|
7
+ x.banner = "rbfunge <options> <file>"
8
+ x.separator ""
9
+ x.on("-h", "Show this message") do
10
+ puts op
11
+ exit
12
+ end
13
+ end
14
+ begin
15
+ op.parse(ARGV)
16
+ rescue
17
+ puts "Could not parse command line arguments."
18
+ exit
19
+ end
20
+
21
+ if ARGV.length > 0
22
+ puts "Running file #{ARGV[0]}..."
23
+ rbf = Rbfunge::Base.new
24
+ rbf.load_file(ARGV[0])
25
+ end
data/lib/rbfunge.rb ADDED
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "rbfunge", "interpreter.rb"))
2
+
3
+ module Rbfunge
4
+ # creates the interpreter and loads programs from files
5
+ class Base
6
+
7
+ # initialize the class
8
+ def initialize
9
+ @interpreter = Interpreter.new
10
+ end
11
+
12
+ # load a file and interpret it
13
+ # currently, this is assuming Befunge-93 80x25 layout
14
+ def load_file(file_path)
15
+ code = File.open(file_path) { |f| f.read }
16
+ @interpreter.run(code)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,196 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "memory_stack.rb"))
2
+ require File.expand_path(File.join(File.dirname(__FILE__), "program.rb"))
3
+
4
+ module Rbfunge
5
+ class Interpreter
6
+
7
+ def initialize
8
+ @program = Program.new
9
+ @memory = Memory_Stack.new
10
+ @string_mode = false
11
+ @commands = {
12
+ '+' => :add,
13
+ '-' => :subtract,
14
+ '*' => :multiply,
15
+ '/' => :divide,
16
+ '%' => :mod,
17
+ '!' => :not,
18
+ '`' => :greater_than,
19
+ '>' => :move_right,
20
+ '<' => :move_left,
21
+ '^' => :move_up,
22
+ 'v' => :move_down,
23
+ '?' => :move_random,
24
+ '_' => :horizontal_if,
25
+ '|' => :vertical_if,
26
+ '"' => :toggle_string_mode,
27
+ ':' => :duplicate,
28
+ '\\' => :swap,
29
+ '$' => :pop,
30
+ '.' => :output_int,
31
+ ',' => :output_ascii,
32
+ '#' => :trampoline,
33
+ 'p' => :put,
34
+ 'g' => :get,
35
+ '&' => :input_int,
36
+ '~' => :input_ascii,
37
+ '@' => :quit,
38
+ ' ' => :noop,
39
+ }
40
+ end
41
+
42
+ def run(code)
43
+ @program.load_code(code)
44
+ catch :quit do
45
+ while true
46
+ evaluate_instruction(@program.get_current.chr)
47
+ @program.move
48
+ end
49
+ end
50
+ end
51
+
52
+ def evaluate_instruction(instruction)
53
+ if @string_mode and @commands[instruction] != :toggle_string_mode
54
+ @memory.push instruction[0].ord
55
+ elsif ("0".."9").include? instruction
56
+ @memory.push instruction.to_i
57
+ else
58
+ if @commands.has_key? instruction
59
+ send @commands[instruction]
60
+ else
61
+ raise "Invalid instruction: #{instruction}"
62
+ end
63
+ end
64
+ end
65
+
66
+ def add
67
+ a = @memory.pop
68
+ b = @memory.pop
69
+ value = b + a
70
+ @memory.push value
71
+ end
72
+
73
+ def subtract
74
+ a = @memory.pop
75
+ b = @memory.pop
76
+ value = b - a
77
+ @memory.push value
78
+ end
79
+
80
+ def multiply
81
+ a = @memory.pop
82
+ b = @memory.pop
83
+ value = b * a
84
+ @memory.push value
85
+ end
86
+
87
+ def divide
88
+ a = @memory.pop
89
+ b = @memory.pop
90
+ value = b / a
91
+ @memory.push value
92
+ end
93
+
94
+ def mod
95
+ a = @memory.pop
96
+ b = @memory.pop
97
+ value = b % a
98
+ @memory.push value
99
+ end
100
+
101
+ def not
102
+ @memory.push(@memory.pop == 0 ? 1 : 0)
103
+ end
104
+
105
+ def greater_than
106
+ a = @memory.pop
107
+ b = @memory.pop
108
+ @memory.push(b > a ? 1 : 0)
109
+ end
110
+
111
+ def move_right
112
+ @program.direction = :right
113
+ end
114
+
115
+ def move_left
116
+ @program.direction = :left
117
+ end
118
+
119
+ def move_up
120
+ @program.direction = :up
121
+ end
122
+
123
+ def move_down
124
+ @program.direction = :down
125
+ end
126
+
127
+ def move_random
128
+ dir = [:right, :left, :up, :down]
129
+ @program.direction = dir[rand(dir.size)]
130
+ end
131
+
132
+ def horizontal_if
133
+ @program.direction = (@memory.pop.to_i == 0) ? :right : :left
134
+ end
135
+
136
+ def vertical_if
137
+ @program.direction = (@memory.pop == 0) ? :down : :up
138
+ end
139
+
140
+ def toggle_string_mode
141
+ @string_mode = !@string_mode
142
+ end
143
+
144
+ def duplicate
145
+ @memory.dup
146
+ end
147
+
148
+ def swap
149
+ @memory.swap
150
+ end
151
+
152
+ def pop
153
+ @memory.pop
154
+ end
155
+
156
+ def output_int
157
+ print @memory.pop.to_i
158
+ end
159
+
160
+ def output_ascii
161
+ print @memory.pop.chr
162
+ end
163
+
164
+ def trampoline
165
+ @program.move
166
+ end
167
+
168
+ def put
169
+ y = @memory.pop
170
+ x = @memory.pop
171
+ @program.put(x, y, @memory.pop)
172
+ end
173
+
174
+ def get
175
+ y = @memory.pop
176
+ x = @memory.pop
177
+ @memory.push(@program.get(x, y))
178
+ end
179
+
180
+ def input_int
181
+ @memory.push(STDIN.readline.to_i)
182
+ end
183
+
184
+ def input_ascii
185
+ @memory.push(STDIN.getc[0].ord)
186
+ end
187
+
188
+ def quit
189
+ puts "\nExiting..."
190
+ throw :quit
191
+ end
192
+
193
+ def noop
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,35 @@
1
+ module Rbfunge
2
+ # memory stack for Befunge programs
3
+ class Memory_Stack
4
+
5
+ # initialize the memory
6
+ def initialize
7
+ @stack = []
8
+ end
9
+
10
+ # pop the first top element off the stack
11
+ def pop
12
+ return @stack.empty? ? 0 : @stack.pop
13
+ end
14
+
15
+ # push an element onto the stack
16
+ def push(value)
17
+ @stack.push value
18
+ end
19
+
20
+ # swap the top two items in the stack
21
+ def swap
22
+ first = pop
23
+ second = pop
24
+ push first
25
+ push second
26
+ end
27
+
28
+ # duplicate the top item
29
+ def dup
30
+ top = pop
31
+ push top
32
+ push top
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,57 @@
1
+ module Rbfunge
2
+ class Program
3
+
4
+ attr_accessor :direction
5
+
6
+ def initialize
7
+ @program = []
8
+ @current_x = 0
9
+ @current_y = 0
10
+ @direction = :right
11
+ end
12
+
13
+ def load_code(code)
14
+ line_array = code.split("\n")
15
+ 25.times do
16
+ line = line_array.shift
17
+ line = pad_line(line)
18
+ byte_array = []
19
+ line.each_byte { |b| byte_array << b}
20
+ @program << byte_array
21
+ end
22
+ end
23
+
24
+ def pad_line(line)
25
+ if line.nil?
26
+ padded_line = "".ljust(80)
27
+ else
28
+ padded_line = line[0..79].ljust(80)
29
+ end
30
+ end
31
+
32
+ def move
33
+ case @direction
34
+ when :right
35
+ @current_x = (@current_x + 1) % 80
36
+ when :left
37
+ @current_x = (@current_x - 1) % 80
38
+ when :up
39
+ @current_y = (@current_y - 1) % 25
40
+ when :down
41
+ @current_y = (@current_y + 1) % 25
42
+ end
43
+ end
44
+
45
+ def get(x, y)
46
+ @program[y][x]
47
+ end
48
+
49
+ def get_current
50
+ get(@current_x, @current_y)
51
+ end
52
+
53
+ def put(x, y, value)
54
+ @program[x][y] = value
55
+ end
56
+ end
57
+ end
data/rbfunge.gemspec ADDED
@@ -0,0 +1,69 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rbfunge}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Chris ONeal"]
12
+ s.date = %q{2011-06-15}
13
+ s.default_executable = %q{rbfunge}
14
+ s.description = %q{A Befunge interpreter in Ruby}
15
+ s.email = %q{ctoneal@gmail.com}
16
+ s.executables = ["rbfunge"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE.txt",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "bin/rbfunge",
30
+ "lib/rbfunge.rb",
31
+ "lib/rbfunge/interpreter.rb",
32
+ "lib/rbfunge/memory_stack.rb",
33
+ "lib/rbfunge/program.rb",
34
+ "rbfunge.gemspec",
35
+ "test/helper.rb",
36
+ "test/test_rbfunge.rb"
37
+ ]
38
+ s.homepage = %q{http://github.com/ctoneal/rbfunge}
39
+ s.licenses = ["MIT"]
40
+ s.require_paths = ["lib"]
41
+ s.rubygems_version = %q{1.6.2}
42
+ s.summary = %q{A Befunge interpreter in Ruby}
43
+ s.test_files = [
44
+ "test/helper.rb",
45
+ "test/test_rbfunge.rb"
46
+ ]
47
+
48
+ if s.respond_to? :specification_version then
49
+ s.specification_version = 3
50
+
51
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
52
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
53
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
54
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
55
+ s.add_development_dependency(%q<rcov>, [">= 0"])
56
+ else
57
+ s.add_dependency(%q<shoulda>, [">= 0"])
58
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
59
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
60
+ s.add_dependency(%q<rcov>, [">= 0"])
61
+ end
62
+ else
63
+ s.add_dependency(%q<shoulda>, [">= 0"])
64
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
65
+ s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
66
+ s.add_dependency(%q<rcov>, [">= 0"])
67
+ end
68
+ end
69
+
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'rbfunge'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestRbfunge < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbfunge
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris ONeal
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-06-15 00:00:00.000000000 -05:00
13
+ default_executable: rbfunge
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: shoulda
17
+ requirement: &7578276 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *7578276
26
+ - !ruby/object:Gem::Dependency
27
+ name: bundler
28
+ requirement: &7577688 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *7577688
37
+ - !ruby/object:Gem::Dependency
38
+ name: jeweler
39
+ requirement: &7575156 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: 1.5.2
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *7575156
48
+ - !ruby/object:Gem::Dependency
49
+ name: rcov
50
+ requirement: &7573896 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *7573896
59
+ description: A Befunge interpreter in Ruby
60
+ email: ctoneal@gmail.com
61
+ executables:
62
+ - rbfunge
63
+ extensions: []
64
+ extra_rdoc_files:
65
+ - LICENSE.txt
66
+ - README.rdoc
67
+ files:
68
+ - .document
69
+ - Gemfile
70
+ - Gemfile.lock
71
+ - LICENSE.txt
72
+ - README.rdoc
73
+ - Rakefile
74
+ - VERSION
75
+ - bin/rbfunge
76
+ - lib/rbfunge.rb
77
+ - lib/rbfunge/interpreter.rb
78
+ - lib/rbfunge/memory_stack.rb
79
+ - lib/rbfunge/program.rb
80
+ - rbfunge.gemspec
81
+ - test/helper.rb
82
+ - test/test_rbfunge.rb
83
+ has_rdoc: true
84
+ homepage: http://github.com/ctoneal/rbfunge
85
+ licenses:
86
+ - MIT
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ segments:
98
+ - 0
99
+ hash: -279970413
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 1.6.2
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: A Befunge interpreter in Ruby
112
+ test_files:
113
+ - test/helper.rb
114
+ - test/test_rbfunge.rb