tortoise 0.8.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/.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 [](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
|