tortoise 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.markdown +136 -0
- data/Rakefile +10 -0
- data/bin/tortoise +11 -0
- data/lib/tortoise/interpreter.rb +123 -0
- data/lib/tortoise/version.rb +3 -0
- data/lib/tortoise.rb +2 -0
- data/spec/data/complex.logo +3 -0
- data/spec/data/simple.logo +9 -0
- data/spec/data/simple_out.txt +61 -0
- data/spec/integration/tortoise_integration_spec.rb +10 -0
- data/spec/tortoise/interpreter_spec.rb +467 -0
- data/tortoise.gemspec +26 -0
- metadata +88 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
Tortoise [![Build Status](https://secure.travis-ci.org/huntca/tortoise.png)](http://travis-ci.org/huntca/tortoise)
|
2
|
+
========
|
3
|
+
[logo]: http://en.wikipedia.org/wiki/Logo_(programming_language) "Logo Programming Language"
|
4
|
+
[rubygems]: https://rubygems.org/ "Rubygems"
|
5
|
+
|
6
|
+
Tortoise is a [Logo][logo] interpreter for Ruby. To demonstrate the
|
7
|
+
awesomeness of Logo, we'll draw a ruby! This example can be found in the
|
8
|
+
repository at `spec/data/simple.logo`.
|
9
|
+
|
10
|
+
> Tortoise::Interpreter.new <<-LOGO
|
11
|
+
61
|
12
|
+
RT 135
|
13
|
+
FD 5
|
14
|
+
REPEAT 2 [ RT 90 FD 15 ]
|
15
|
+
RT 90
|
16
|
+
FD 5
|
17
|
+
RT 45
|
18
|
+
FD 20
|
19
|
+
LOGO
|
20
|
+
|
21
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
22
|
+
. . . . . . X X X X X X X X X X X X X X X X X X X X X . . . . . .
|
23
|
+
. . . . . X . . . . . . . . . . . . . . . . . . . . . X . . . . .
|
24
|
+
. . . . X . . . . . . . . . . . . . . . . . . . . . . . X . . . .
|
25
|
+
. . . X . . . . . . . . . . . . . . . . . . . . . . . . . X . . .
|
26
|
+
. . X . . . . . . . . . . . . . . . . . . . . . . . . . . . X . .
|
27
|
+
. X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X .
|
28
|
+
. . X . . . . . . . . . . . . . . . . . . . . . . . . . . . X . .
|
29
|
+
. . . X . . . . . . . . . . . . . . . . . . . . . . . . . X . . .
|
30
|
+
. . . . X . . . . . . . . . . . . . . . . . . . . . . . X . . . .
|
31
|
+
. . . . . X . . . . . . . . . . . . . . . . . . . . . X . . . . .
|
32
|
+
. . . . . . X . . . . . . . . . . . . . . . . . . . X . . . . . .
|
33
|
+
. . . . . . . X . . . . . . . . . . . . . . . . . X . . . . . . .
|
34
|
+
. . . . . . . . X . . . . . . . . . . . . . . . X . . . . . . . .
|
35
|
+
. . . . . . . . . X . . . . . . . . . . . . . X . . . . . . . . .
|
36
|
+
. . . . . . . . . . X . . . . . . . . . . . X . . . . . . . . . .
|
37
|
+
. . . . . . . . . . . X . . . . . . . . . X . . . . . . . . . . .
|
38
|
+
. . . . . . . . . . . . X . . . . . . . X . . . . . . . . . . . .
|
39
|
+
. . . . . . . . . . . . . X . . . . . X . . . . . . . . . . . . .
|
40
|
+
. . . . . . . . . . . . . . X . . . X . . . . . . . . . . . . . .
|
41
|
+
. . . . . . . . . . . . . . . X . X . . . . . . . . . . . . . . .
|
42
|
+
. . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . .
|
43
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
44
|
+
|
45
|
+
Installation
|
46
|
+
------------
|
47
|
+
Tortoise is available on [rubygems.org][rubygems]. To install, add
|
48
|
+
`gem tortoise` to your `Gemfile` or install manually with:
|
49
|
+
|
50
|
+
gem install tortoise
|
51
|
+
|
52
|
+
Usage
|
53
|
+
-----
|
54
|
+
To use Tortoise, create an instance of `Tortoise::Interpreter` and execute
|
55
|
+
any of the supported Logo commands.
|
56
|
+
|
57
|
+
# specify canvas size for this drawing
|
58
|
+
canvas_size = 11
|
59
|
+
interpreter = Tortoise::Interpreter.new(canvas_size)
|
60
|
+
|
61
|
+
# execute any supported commands
|
62
|
+
interpreter.rt(90)
|
63
|
+
interpreter.fd(3)
|
64
|
+
interpreter.lt(45)
|
65
|
+
interpreter.bk(4)
|
66
|
+
|
67
|
+
Tortoise also accepts commands as an input string:
|
68
|
+
|
69
|
+
interpreter = Tortoise::Interpreter.new(11)
|
70
|
+
interpreter.draw "RT 90"
|
71
|
+
interpreter.draw "FD 3"
|
72
|
+
interpreter.draw "LT 45"
|
73
|
+
interpreter.draw "BK 4"
|
74
|
+
|
75
|
+
You can execute entire blocks of commands at once:
|
76
|
+
|
77
|
+
interpreter = Tortoise::Interpreter.new(61)
|
78
|
+
|
79
|
+
interpreter.draw <<-STEPS
|
80
|
+
RT 135
|
81
|
+
FD 5
|
82
|
+
REPEAT 2 [ RT 90 FD 15 ]
|
83
|
+
RT 90
|
84
|
+
FD 5
|
85
|
+
RT 45
|
86
|
+
FD 20
|
87
|
+
STEPS
|
88
|
+
|
89
|
+
Finally, commands can be executed when a `Tortoise::Interpreter` is
|
90
|
+
instantiated. The command string must contain the canvas size in the
|
91
|
+
first line. This is most useful when reading commands from a file.
|
92
|
+
Assume we have the file `drawing.logo`:
|
93
|
+
|
94
|
+
61
|
95
|
+
RT 135
|
96
|
+
FD 5
|
97
|
+
REPEAT 2 [ RT 90 FD 15 ]
|
98
|
+
RT 90
|
99
|
+
FD 5
|
100
|
+
RT 45
|
101
|
+
FD 20
|
102
|
+
|
103
|
+
We can load and execute `drawing.logo` with:
|
104
|
+
|
105
|
+
file = File.new('drawing.logo')
|
106
|
+
tortoise = Tortoise::Interpreter.new(file.read)
|
107
|
+
|
108
|
+
Command Line Usage
|
109
|
+
------------------
|
110
|
+
Tortoise can be used on the command line to render logo command files. The
|
111
|
+
output is rendered to standard out.
|
112
|
+
|
113
|
+
Usage: tortoise [FILE]
|
114
|
+
|
115
|
+
For example, if you'd like to render `drawing.logo` to `drawing.txt`:
|
116
|
+
|
117
|
+
$ tortoise drawing.logo > drawing.txt
|
118
|
+
|
119
|
+
Rendering The Canvas
|
120
|
+
--------------------
|
121
|
+
Tortoise can currently render its canvas to a string. Html export is planned
|
122
|
+
soon (which will allow a very high resolution canvas). To get a string
|
123
|
+
representation of the current canvas:
|
124
|
+
|
125
|
+
interpreter = Tortoise::Interpreter.new(5)
|
126
|
+
interpreter.to_s
|
127
|
+
|
128
|
+
Supported Commands
|
129
|
+
------------------
|
130
|
+
Tortoise only supports a small subset of all [Logo][logo] commands.
|
131
|
+
|
132
|
+
- `RT x`: Turn the tortoise `x` degrees to the right (increments of 45)
|
133
|
+
- `LT x`: Turn the tortoise `x` degrees to the right (increments of 45)
|
134
|
+
- `FD x`: Move the tortoise `x` steps forward
|
135
|
+
- `BK x`: Move the tortoise `x` steps backward
|
136
|
+
- `REPEAT n [ x ]`: Repeat commands `x` a total of `n` times
|
data/Rakefile
ADDED
data/bin/tortoise
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$:.push File.expand_path("../../lib", __FILE__)
|
3
|
+
require 'tortoise/interpreter'
|
4
|
+
|
5
|
+
if ARGV.size < 1
|
6
|
+
puts "Usage: tortoise [FILE]"
|
7
|
+
raise Exception.new("Missing filename")
|
8
|
+
end
|
9
|
+
|
10
|
+
commands = File.new(ARGV.first).read
|
11
|
+
puts Tortoise::Interpreter.new(commands).to_s
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Tortoise
|
2
|
+
class Interpreter
|
3
|
+
attr_reader :size, :position, :direction, :canvas
|
4
|
+
|
5
|
+
def initialize(instructions)
|
6
|
+
lines = instructions.to_s.split("\n")
|
7
|
+
|
8
|
+
@size = lines.shift.to_i
|
9
|
+
@canvas = new_canvas
|
10
|
+
@direction = 0
|
11
|
+
center = (@size - @size/2) - 1
|
12
|
+
|
13
|
+
update_position(center, center)
|
14
|
+
draw(lines)
|
15
|
+
end
|
16
|
+
|
17
|
+
def rt(degrees)
|
18
|
+
rotate(degrees)
|
19
|
+
end
|
20
|
+
|
21
|
+
def lt(degrees)
|
22
|
+
rotate(-degrees)
|
23
|
+
end
|
24
|
+
|
25
|
+
def fd(steps)
|
26
|
+
walk(steps)
|
27
|
+
end
|
28
|
+
|
29
|
+
def bk(steps)
|
30
|
+
walk(-steps)
|
31
|
+
end
|
32
|
+
|
33
|
+
def draw(commands)
|
34
|
+
commands = commands.split("\n") if commands.respond_to?(:split)
|
35
|
+
commands.each { |command| execute(command) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
s = ''
|
40
|
+
oriented_canvas.each do |column|
|
41
|
+
column.each do |pixel|
|
42
|
+
char = pixel ? 'X' : '.'
|
43
|
+
s += "#{char} "
|
44
|
+
end
|
45
|
+
s = s.strip + "\n"
|
46
|
+
end
|
47
|
+
s
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def new_canvas
|
53
|
+
Array.new(@size) { Array.new(@size) {false} }
|
54
|
+
end
|
55
|
+
|
56
|
+
def update_position(x, y)
|
57
|
+
@position = place_in_canvas_bounds(x, y)
|
58
|
+
update_canvas
|
59
|
+
end
|
60
|
+
|
61
|
+
def rotate(degrees)
|
62
|
+
@direction += degrees
|
63
|
+
@direction += 360 while @direction < 0
|
64
|
+
@direction -= 360 while @direction >= 360
|
65
|
+
end
|
66
|
+
|
67
|
+
def execute(command)
|
68
|
+
words = command.split(' ')
|
69
|
+
if words.size == 2
|
70
|
+
method, param = words
|
71
|
+
self.send(method.downcase, param.to_i)
|
72
|
+
else
|
73
|
+
1.upto(words[1].to_i) do
|
74
|
+
commands = words[3..words.size-2]
|
75
|
+
execute(commands.shift(2).join(' ')) while commands.size > 0
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def walk(steps)
|
81
|
+
x, y = @position
|
82
|
+
step = steps < 0 ? -1 : 1
|
83
|
+
steps = steps < 0 ? -steps : steps
|
84
|
+
|
85
|
+
1.upto(steps) do
|
86
|
+
x, y = case direction
|
87
|
+
when 0; [x, y + step]
|
88
|
+
when 45; [x + step, y + step]
|
89
|
+
when 90; [x + step, y ]
|
90
|
+
when 135; [x + step, y - step]
|
91
|
+
when 180; [x, y - step]
|
92
|
+
when 225; [x - step, y - step]
|
93
|
+
when 270; [x - step, y ]
|
94
|
+
when 315; [x - step, y + step]
|
95
|
+
end
|
96
|
+
update_position(x, y)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def update_canvas
|
101
|
+
x, y = @position
|
102
|
+
@canvas[x][y] = true
|
103
|
+
end
|
104
|
+
|
105
|
+
def place_in_canvas_bounds(x, y)
|
106
|
+
x = 0 if x < 0
|
107
|
+
y = 0 if y < 0
|
108
|
+
x = @size - 1 if x >= @size
|
109
|
+
y = @size - 1 if y >= @size
|
110
|
+
[x, y]
|
111
|
+
end
|
112
|
+
|
113
|
+
def oriented_canvas
|
114
|
+
oriented = new_canvas
|
115
|
+
@canvas.each_with_index do |column, i|
|
116
|
+
column.each_with_index do |pixel, j|
|
117
|
+
oriented[@size-1-j][i] = pixel
|
118
|
+
end
|
119
|
+
end
|
120
|
+
oriented
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/tortoise.rb
ADDED
@@ -0,0 +1,3 @@
|
|
1
|
+
1001
|
2
|
+
|
3
|
+
REPEAT 4 [ FD 200 LT 45 FD 100 LT 45 FD 50 LT 45 FD 25 LT 45 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 RT 90 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 LT 45 BK 25 RT 90 FD 25 LT 45 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 RT 90 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 LT 45 BK 25 LT 45 BK 50 RT 90 FD 50 LT 45 FD 25 LT 45 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 RT 90 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 LT 45 BK 25 RT 90 FD 25 LT 45 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 RT 90 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 LT 45 BK 25 LT 45 BK 50 LT 45 BK 100 RT 90 FD 100 LT 45 FD 50 LT 45 FD 25 LT 45 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 RT 90 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 LT 45 BK 25 RT 90 FD 25 LT 45 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 RT 90 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 LT 45 BK 25 LT 45 BK 50 RT 90 FD 50 LT 45 FD 25 LT 45 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 RT 90 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 LT 45 BK 25 RT 90 FD 25 LT 45 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 RT 90 FD 12 LT 45 FD 6 LT 45 RT 90 LT 45 BK 6 RT 90 FD 6 LT 45 RT 90 LT 45 BK 6 LT 45 BK 12 LT 45 BK 25 LT 45 BK 50 LT 45 BK 100 LT 45 BK 200 RT 90 ]
|
@@ -0,0 +1,61 @@
|
|
1
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
2
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
3
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
4
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
5
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
6
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
7
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
8
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
9
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
10
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
11
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
12
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
13
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
14
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
15
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
16
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
17
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
18
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
19
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
20
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
21
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
22
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
23
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
24
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
25
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
26
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
27
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
28
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
29
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
30
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
31
|
+
. . . . . . . . . . X X X X X X X X X X X X X X X X X X X X X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
32
|
+
. . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
33
|
+
. . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
34
|
+
. . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
35
|
+
. . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . .
|
36
|
+
. . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . .
|
37
|
+
. . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . .
|
38
|
+
. . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
39
|
+
. . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
40
|
+
. . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
41
|
+
. . . . . . . . . . X . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
42
|
+
. . . . . . . . . . . X . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
43
|
+
. . . . . . . . . . . . X . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
44
|
+
. . . . . . . . . . . . . X . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
45
|
+
. . . . . . . . . . . . . . X . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
46
|
+
. . . . . . . . . . . . . . . X . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
47
|
+
. . . . . . . . . . . . . . . . X . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
48
|
+
. . . . . . . . . . . . . . . . . X . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
49
|
+
. . . . . . . . . . . . . . . . . . X . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
50
|
+
. . . . . . . . . . . . . . . . . . . X . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
51
|
+
. . . . . . . . . . . . . . . . . . . . X . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
52
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
53
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
54
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
55
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
56
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
57
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
58
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
59
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
60
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
61
|
+
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'tortoise'
|
2
|
+
|
3
|
+
describe Tortoise::Interpreter do
|
4
|
+
it 'produces the expected string output' do
|
5
|
+
input = File.new('./spec/data/simple.logo').read
|
6
|
+
output = File.new('./spec/data/simple_out.txt').read
|
7
|
+
|
8
|
+
Tortoise::Interpreter.new(input).to_s.should == output
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,467 @@
|
|
1
|
+
require 'tortoise/interpreter'
|
2
|
+
|
3
|
+
describe Tortoise::Interpreter do
|
4
|
+
let(:tortoise) { Tortoise::Interpreter.new(11) }
|
5
|
+
|
6
|
+
it 'can be initialized with a canvas size' do
|
7
|
+
tortoise = Tortoise::Interpreter.new(11)
|
8
|
+
tortoise.size.should == 11
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'can be initialized with instructions' do
|
12
|
+
instructions = <<-STEPS
|
13
|
+
5
|
14
|
+
|
15
|
+
REPEAT 2 [ RT 45 ]
|
16
|
+
FD 1
|
17
|
+
STEPS
|
18
|
+
|
19
|
+
tortoise = Tortoise::Interpreter.new(instructions)
|
20
|
+
tortoise.size.should == 5
|
21
|
+
tortoise.direction.should == 90
|
22
|
+
tortoise.position.should == [3, 2]
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'starts with a single marked pixel on the canvas' do
|
26
|
+
count = 0
|
27
|
+
tortoise.canvas.each do |column|
|
28
|
+
column.each { |pixel| count += 1 if pixel }
|
29
|
+
end
|
30
|
+
count.should == 1
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'defaults tortoise position to the center of the canvas' do
|
34
|
+
tortoise.position.should == [5, 5]
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'defaults tortoise direction to zero degrees (up)' do
|
38
|
+
tortoise.direction.should == 0
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#draw' do
|
42
|
+
it 'draws the image on the canvas when given a string' do
|
43
|
+
tortoise = Tortoise::Interpreter.new(5)
|
44
|
+
tortoise.draw <<-STEPS
|
45
|
+
RT 90
|
46
|
+
FD 1
|
47
|
+
REPEAT 2 [ RT 45 ]
|
48
|
+
FD 2
|
49
|
+
REPEAT 2 [ LT 45 ]
|
50
|
+
FD 1
|
51
|
+
RT 180
|
52
|
+
FD 2
|
53
|
+
STEPS
|
54
|
+
|
55
|
+
tortoise.canvas.should == [
|
56
|
+
[false, false, false, false, false],
|
57
|
+
[false, false, false, false, false],
|
58
|
+
[true , false, true , false, false],
|
59
|
+
[true , true , true , false, false],
|
60
|
+
[true , false, false, false, false]]
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'draws the image on the canvas when given an array' do
|
64
|
+
tortoise = Tortoise::Interpreter.new(5)
|
65
|
+
tortoise.draw([
|
66
|
+
'RT 90',
|
67
|
+
'FD 1',
|
68
|
+
'REPEAT 2 [ RT 45 ]',
|
69
|
+
'FD 2',
|
70
|
+
'REPEAT 2 [ LT 45 ]',
|
71
|
+
'FD 1',
|
72
|
+
'RT 180',
|
73
|
+
'FD 2'])
|
74
|
+
tortoise.canvas.should == [
|
75
|
+
[false, false, false, false, false],
|
76
|
+
[false, false, false, false, false],
|
77
|
+
[true , false, true , false, false],
|
78
|
+
[true , true , true , false, false],
|
79
|
+
[true , false, false, false, false]]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#to_s' do
|
84
|
+
it 'renders canvas to string' do
|
85
|
+
tortoise = Tortoise::Interpreter.new(5)
|
86
|
+
tortoise.draw <<-STEPS
|
87
|
+
RT 90
|
88
|
+
FD 1
|
89
|
+
REPEAT 2 [ RT 45 ]
|
90
|
+
FD 2
|
91
|
+
REPEAT 2 [ LT 45 ]
|
92
|
+
FD 1
|
93
|
+
RT 180
|
94
|
+
FD 2
|
95
|
+
STEPS
|
96
|
+
|
97
|
+
tortoise.to_s.should == "" +
|
98
|
+
". . . . .\n" +
|
99
|
+
". . . . .\n" +
|
100
|
+
". . X X .\n" +
|
101
|
+
". . . X .\n" +
|
102
|
+
". . X X X\n"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#rt' do
|
107
|
+
it 'can rotate the tortoise 45 degrees to the right' do
|
108
|
+
tortoise.rt(45)
|
109
|
+
tortoise.direction.should == 45
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'can rotate the tortoise 360 degrees to the right' do
|
113
|
+
tortoise.rt(360)
|
114
|
+
tortoise.direction.should == 0
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'can rotate the tortoise 495 degrees to the right' do
|
118
|
+
tortoise.rt(495)
|
119
|
+
tortoise.direction.should == 135
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'can rotate the tortoise 810 degrees to the right' do
|
123
|
+
tortoise.rt(810)
|
124
|
+
tortoise.direction.should == 90
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'can rotate the tortoise multiple times' do
|
128
|
+
tortoise.rt(90)
|
129
|
+
tortoise.rt(45)
|
130
|
+
tortoise.direction.should == 135
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#lt' do
|
135
|
+
it 'can rotate the tortoise 45 degrees to the left' do
|
136
|
+
tortoise.lt(45)
|
137
|
+
tortoise.direction.should == 315
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'can rotate the tortoise 360 degrees to the left' do
|
141
|
+
tortoise.lt(360)
|
142
|
+
tortoise.direction.should == 0
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'can rotate the tortoise 495 degrees to the left' do
|
146
|
+
tortoise.lt(495)
|
147
|
+
tortoise.direction.should == 225
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'can rotate the tortoise 810 degrees to the left' do
|
151
|
+
tortoise.lt(810)
|
152
|
+
tortoise.direction.should == 270
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'can rotate the tortoise multiple times' do
|
156
|
+
tortoise.lt(90)
|
157
|
+
tortoise.lt(45)
|
158
|
+
tortoise.direction.should == 225
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#rotate' do
|
163
|
+
it 'can rotate the tortoise 45 degrees' do
|
164
|
+
tortoise.send(:rotate, 45)
|
165
|
+
tortoise.direction.should == 45
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'can rotate the tortoise 90 degrees' do
|
169
|
+
tortoise.send(:rotate, 90)
|
170
|
+
tortoise.direction.should == 90
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'can rotate the tortoise 360 degrees' do
|
174
|
+
tortoise.send(:rotate, 360)
|
175
|
+
tortoise.direction.should == 0
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'can rotate the tortoise 495 degrees' do
|
179
|
+
tortoise.send(:rotate, 495)
|
180
|
+
tortoise.direction.should == 135
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'can rotate the tortoise 810 degrees' do
|
184
|
+
tortoise.send(:rotate, 810)
|
185
|
+
tortoise.direction.should == 90
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'can rotate the tortoise -45 degrees' do
|
189
|
+
tortoise.send(:rotate, -45)
|
190
|
+
tortoise.direction.should == 315
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'can rotate the tortoise -90 degrees' do
|
194
|
+
tortoise.send(:rotate, -90)
|
195
|
+
tortoise.direction.should == 270
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'can rotate the tortoise -360 degrees' do
|
199
|
+
tortoise.send(:rotate, -360)
|
200
|
+
tortoise.direction.should == 0
|
201
|
+
end
|
202
|
+
|
203
|
+
it 'can rotate the tortoise -495 degrees' do
|
204
|
+
tortoise.send(:rotate, -495)
|
205
|
+
tortoise.direction.should == 225
|
206
|
+
end
|
207
|
+
|
208
|
+
it 'can rotate the tortoise -810 degrees' do
|
209
|
+
tortoise.send(:rotate, -810)
|
210
|
+
tortoise.direction.should == 270
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'can rotate the tortoise multiple times' do
|
214
|
+
tortoise.send(:rotate, 90)
|
215
|
+
tortoise.send(:rotate, 45)
|
216
|
+
tortoise.direction.should == 135
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
describe '#fd' do
|
221
|
+
it 'moves the tortoise forward when facing 0 degress' do
|
222
|
+
x, y = tortoise.position
|
223
|
+
tortoise.fd(2)
|
224
|
+
tortoise.position.should == [x, y + 2]
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'moves the tortoise forward when facing 45 degress' do
|
228
|
+
x, y = tortoise.position
|
229
|
+
tortoise.rt(45)
|
230
|
+
tortoise.fd(2)
|
231
|
+
tortoise.position.should == [x + 2, y + 2]
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'moves the tortoise forward when facing 90 degress' do
|
235
|
+
x, y = tortoise.position
|
236
|
+
tortoise.rt(90)
|
237
|
+
tortoise.fd(2)
|
238
|
+
tortoise.position.should == [x + 2, y]
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'moves the tortoise forward when facing 135 degress' do
|
242
|
+
x, y = tortoise.position
|
243
|
+
tortoise.rt(135)
|
244
|
+
tortoise.fd(2)
|
245
|
+
tortoise.position.should == [x + 2, y - 2]
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'moves the tortoise forward when facing 180 degress' do
|
249
|
+
x, y = tortoise.position
|
250
|
+
tortoise.rt(180)
|
251
|
+
tortoise.fd(2)
|
252
|
+
tortoise.position.should == [x, y - 2]
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'moves the tortoise forward when facing 225 degress' do
|
256
|
+
x, y = tortoise.position
|
257
|
+
tortoise.rt(225)
|
258
|
+
tortoise.fd(2)
|
259
|
+
tortoise.position.should == [x - 2, y - 2]
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'moves the tortoise forward when facing 270 degress' do
|
263
|
+
x, y = tortoise.position
|
264
|
+
tortoise.rt(270)
|
265
|
+
tortoise.fd(2)
|
266
|
+
tortoise.position.should == [x - 2, y]
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'moves the tortoise forward when facing 315 degress' do
|
270
|
+
x, y = tortoise.position
|
271
|
+
tortoise.rt(315)
|
272
|
+
tortoise.fd(2)
|
273
|
+
tortoise.position.should == [x - 2, y + 2]
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'stops when it reaches the top of the canvas' do
|
277
|
+
tortoise.fd(100)
|
278
|
+
x, y = tortoise.position
|
279
|
+
y.should < tortoise.size
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'stops when it reaches the bottom of the canvas' do
|
283
|
+
tortoise.rt(180)
|
284
|
+
tortoise.fd(100)
|
285
|
+
x, y = tortoise.position
|
286
|
+
y.should >= 0
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'stops when it reaches the right of the canvas' do
|
290
|
+
tortoise.rt(90)
|
291
|
+
tortoise.fd(100)
|
292
|
+
x, y = tortoise.position
|
293
|
+
x.should < tortoise.size
|
294
|
+
end
|
295
|
+
|
296
|
+
it 'stops when it reaches the left of the canvas' do
|
297
|
+
tortoise.rt(270)
|
298
|
+
tortoise.fd(100)
|
299
|
+
x, y = tortoise.position
|
300
|
+
x.should >= 0
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'draws on traveled areas of the canvas' do
|
304
|
+
tortoise = Tortoise::Interpreter.new(5)
|
305
|
+
tortoise.rt(90)
|
306
|
+
tortoise.fd(1)
|
307
|
+
tortoise.rt(90)
|
308
|
+
tortoise.fd(2)
|
309
|
+
tortoise.lt(90)
|
310
|
+
tortoise.fd(1)
|
311
|
+
tortoise.rt(180)
|
312
|
+
tortoise.fd(2)
|
313
|
+
tortoise.canvas.should == [
|
314
|
+
[false, false, false, false, false],
|
315
|
+
[false, false, false, false, false],
|
316
|
+
[true , false, true , false, false],
|
317
|
+
[true , true , true , false, false],
|
318
|
+
[true , false, false, false, false]]
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
describe '#bk' do
|
323
|
+
it 'moves the tortoise forward when facing 0 degress' do
|
324
|
+
x, y = tortoise.position
|
325
|
+
tortoise.bk(2)
|
326
|
+
tortoise.position.should == [x, y - 2]
|
327
|
+
end
|
328
|
+
|
329
|
+
it 'moves the tortoise forward when facing 45 degress' do
|
330
|
+
x, y = tortoise.position
|
331
|
+
tortoise.rt(45)
|
332
|
+
tortoise.bk(2)
|
333
|
+
tortoise.position.should == [x - 2, y - 2]
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'moves the tortoise forward when facing 90 degress' do
|
337
|
+
x, y = tortoise.position
|
338
|
+
tortoise.rt(90)
|
339
|
+
tortoise.bk(2)
|
340
|
+
tortoise.position.should == [x - 2, y]
|
341
|
+
end
|
342
|
+
|
343
|
+
it 'moves the tortoise forward when facing 135 degress' do
|
344
|
+
x, y = tortoise.position
|
345
|
+
tortoise.rt(135)
|
346
|
+
tortoise.bk(2)
|
347
|
+
tortoise.position.should == [x - 2, y + 2]
|
348
|
+
end
|
349
|
+
|
350
|
+
it 'moves the tortoise forward when facing 180 degress' do
|
351
|
+
x, y = tortoise.position
|
352
|
+
tortoise.rt(180)
|
353
|
+
tortoise.bk(2)
|
354
|
+
tortoise.position.should == [x, y + 2]
|
355
|
+
end
|
356
|
+
|
357
|
+
it 'moves the tortoise forward when facing 225 degress' do
|
358
|
+
x, y = tortoise.position
|
359
|
+
tortoise.rt(225)
|
360
|
+
tortoise.bk(2)
|
361
|
+
tortoise.position.should == [x + 2, y + 2]
|
362
|
+
end
|
363
|
+
|
364
|
+
it 'moves the tortoise forward when facing 270 degress' do
|
365
|
+
x, y = tortoise.position
|
366
|
+
tortoise.rt(270)
|
367
|
+
tortoise.bk(2)
|
368
|
+
tortoise.position.should == [x + 2, y]
|
369
|
+
end
|
370
|
+
|
371
|
+
it 'moves the tortoise forward when facing 315 degress' do
|
372
|
+
x, y = tortoise.position
|
373
|
+
tortoise.rt(315)
|
374
|
+
tortoise.bk(2)
|
375
|
+
tortoise.position.should == [x + 2, y - 2]
|
376
|
+
end
|
377
|
+
|
378
|
+
it 'stops when it reaches the bottom of the canvas' do
|
379
|
+
tortoise.bk(100)
|
380
|
+
x, y = tortoise.position
|
381
|
+
y.should >= 0
|
382
|
+
end
|
383
|
+
|
384
|
+
it 'stops when it reaches the top of the canvas' do
|
385
|
+
tortoise.rt(180)
|
386
|
+
tortoise.bk(100)
|
387
|
+
x, y = tortoise.position
|
388
|
+
y.should < tortoise.size
|
389
|
+
end
|
390
|
+
|
391
|
+
it 'stops when it reaches the left of the canvas' do
|
392
|
+
tortoise.rt(90)
|
393
|
+
tortoise.bk(100)
|
394
|
+
x, y = tortoise.position
|
395
|
+
x.should >= 0
|
396
|
+
end
|
397
|
+
|
398
|
+
it 'stops when it reaches the right of the canvas' do
|
399
|
+
tortoise.rt(270)
|
400
|
+
tortoise.bk(100)
|
401
|
+
x, y = tortoise.position
|
402
|
+
x.should < tortoise.size
|
403
|
+
end
|
404
|
+
|
405
|
+
it 'draws on traveled areas of the canvas' do
|
406
|
+
tortoise = Tortoise::Interpreter.new(5)
|
407
|
+
tortoise.lt(90)
|
408
|
+
tortoise.bk(1)
|
409
|
+
tortoise.rt(90)
|
410
|
+
tortoise.bk(2)
|
411
|
+
tortoise.lt(90)
|
412
|
+
tortoise.bk(1)
|
413
|
+
tortoise.rt(180)
|
414
|
+
tortoise.bk(2)
|
415
|
+
tortoise.canvas.should == [
|
416
|
+
[false, false, false, false, false],
|
417
|
+
[false, false, false, false, false],
|
418
|
+
[true , false, true , false, false],
|
419
|
+
[true , true , true , false, false],
|
420
|
+
[true , false, false, false, false]]
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
describe '#execute' do
|
425
|
+
it 'can execute lowercase commands' do
|
426
|
+
tortoise.send(:execute, 'rt 90')
|
427
|
+
tortoise.direction.should == 90
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'can execute right turns' do
|
431
|
+
tortoise.send(:execute, 'RT 90')
|
432
|
+
tortoise.direction.should == 90
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'can execute left turns' do
|
436
|
+
tortoise.send(:execute, 'LT 90')
|
437
|
+
tortoise.direction.should == 270
|
438
|
+
end
|
439
|
+
|
440
|
+
it 'can execute forward steps' do
|
441
|
+
x, y = tortoise.position
|
442
|
+
tortoise.send(:execute, 'FD 3')
|
443
|
+
tortoise.position.should == [x, y + 3]
|
444
|
+
end
|
445
|
+
|
446
|
+
it 'can execute backward steps' do
|
447
|
+
x, y = tortoise.position
|
448
|
+
tortoise.send(:execute, 'BK 2')
|
449
|
+
tortoise.position.should == [x, y - 2]
|
450
|
+
end
|
451
|
+
|
452
|
+
it 'can execute single item repeat blocks' do
|
453
|
+
tortoise.send(:execute, 'REPEAT 2 [ RT 45 ]')
|
454
|
+
tortoise.direction.should == 90
|
455
|
+
end
|
456
|
+
|
457
|
+
it 'can execute multi-item repeat blocks' do
|
458
|
+
tortoise.send(:execute, 'REPEAT 2 [ RT 45 LT 90 ]')
|
459
|
+
tortoise.direction.should == 270
|
460
|
+
end
|
461
|
+
|
462
|
+
it 'can execute commands with extra whitespace' do
|
463
|
+
tortoise.send(:execute, ' RT 90 ')
|
464
|
+
tortoise.direction.should == 90
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|
data/tortoise.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "tortoise/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "tortoise"
|
7
|
+
s.version = Tortoise::VERSION
|
8
|
+
s.authors = ["Chris Hunt"]
|
9
|
+
s.email = ["huntca@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/huntca/tortoise"
|
11
|
+
s.summary = %q{Tortoise is a Logo interpreter for ruby.}
|
12
|
+
s.description = %q{Tortoise is a Logo interpreter for ruby.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "tortoise"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_runtime_dependency "rest-client"
|
23
|
+
|
24
|
+
s.add_development_dependency "rake"
|
25
|
+
s.add_development_dependency "rspec"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tortoise
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Chris Hunt
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &70316818801540 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70316818801540
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &70316818793360 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70316818793360
|
36
|
+
description: Tortoise is a Logo interpreter for ruby.
|
37
|
+
email:
|
38
|
+
- huntca@gmail.com
|
39
|
+
executables:
|
40
|
+
- tortoise
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- .travis.yml
|
46
|
+
- Gemfile
|
47
|
+
- README.markdown
|
48
|
+
- Rakefile
|
49
|
+
- bin/tortoise
|
50
|
+
- lib/tortoise.rb
|
51
|
+
- lib/tortoise/interpreter.rb
|
52
|
+
- lib/tortoise/version.rb
|
53
|
+
- spec/data/complex.logo
|
54
|
+
- spec/data/simple.logo
|
55
|
+
- spec/data/simple_out.txt
|
56
|
+
- spec/integration/tortoise_integration_spec.rb
|
57
|
+
- spec/tortoise/interpreter_spec.rb
|
58
|
+
- tortoise.gemspec
|
59
|
+
homepage: https://github.com/huntca/tortoise
|
60
|
+
licenses: []
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project: tortoise
|
79
|
+
rubygems_version: 1.8.10
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Tortoise is a Logo interpreter for ruby.
|
83
|
+
test_files:
|
84
|
+
- spec/data/complex.logo
|
85
|
+
- spec/data/simple.logo
|
86
|
+
- spec/data/simple_out.txt
|
87
|
+
- spec/integration/tortoise_integration_spec.rb
|
88
|
+
- spec/tortoise/interpreter_spec.rb
|