rbfunge 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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