nudge 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/Thorfile +59 -0
- data/VERSION +1 -1
- data/bin/nudge +1 -1
- data/lib/cli/runner.rb +1 -1
- data/lib/interpreter/interpreter.rb +3 -3
- data/lib/interpreter/nudge_program.rb +10 -77
- data/lib/interpreter/parse.tab.rb +39 -21
- data/lib/interpreter/programPoints.rb +3 -6
- data/readme.md +36 -2
- data/spec/command_line/thor_spec.rb +51 -0
- data/spec/instructions/code/code_noop_spec.rb +1 -1
- data/spec/interpreter/codeblock_point_spec.rb +3 -4
- data/spec/interpreter/interpreter_spec.rb +4 -5
- data/spec/interpreter/nudge_program_spec.rb +37 -122
- data/spec/interpreter/value_point_spec.rb +9 -4
- data/spec/parsers/nudge_program_parser_spec.rb +105 -20
- data/spec/spec_helper.rb +36 -23
- data/templates/nudge_define_instruction.erb +6 -0
- data/templates/nudge_duplicate_instruction.erb +6 -0
- data/templates/nudge_equal_q_instruction.erb +19 -0
- data/templates/nudge_flush_instruction.erb +6 -0
- data/templates/nudge_pop_instruction.erb +6 -0
- data/templates/nudge_random_instruction.erb +13 -0
- data/templates/nudge_rotate_instruction.erb +6 -0
- data/templates/nudge_shove_instruction.erb +6 -0
- data/templates/nudge_swap_instruction.erb +6 -0
- data/templates/nudge_type_class.erb +50 -0
- data/templates/nudge_type_spec.erb +32 -0
- data/templates/nudge_yank_instruction.erb +6 -0
- data/templates/nudge_yankdup_instruction.erb +6 -0
- metadata +27 -14
- data/spec/interpreter/treetophelpers.rb +0 -120
data/Rakefile
CHANGED
@@ -16,8 +16,8 @@ begin
|
|
16
16
|
gemspec.required_ruby_version = '>= 1.9.1'
|
17
17
|
|
18
18
|
# dependencies
|
19
|
-
gemspec.add_dependency('treetop', '>= 1.4.3')
|
20
19
|
gemspec.add_dependency('activesupport', '>= 2.3.5')
|
20
|
+
gemspec.add_dependency('thor', '>= 0.13')
|
21
21
|
|
22
22
|
# files
|
23
23
|
gemspec.files.exclude '_spikes/**'
|
data/Thorfile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class Extend_Nudge < Thor::Group
|
4
|
+
include Thor::Actions
|
5
|
+
|
6
|
+
# Define arguments and options
|
7
|
+
argument :project_name
|
8
|
+
class_option :test_framework, :default => :rspec
|
9
|
+
|
10
|
+
def self.source_root
|
11
|
+
File.dirname(__FILE__)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
class New_Nudge_Type < Thor::Group
|
17
|
+
include Thor::Actions
|
18
|
+
|
19
|
+
# Define arguments and options
|
20
|
+
argument :type_root
|
21
|
+
class_option :test_framework, :default => :rspec
|
22
|
+
desc "Creates a new NudgeType class definition file, typical instructions, and rspec files"
|
23
|
+
|
24
|
+
|
25
|
+
def self.source_root
|
26
|
+
File.dirname(__FILE__)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.type_name(string)
|
30
|
+
string.camelize + "Type"
|
31
|
+
end
|
32
|
+
|
33
|
+
def create_lib_file
|
34
|
+
@camelcased_type_name = New_Nudge_Type.type_name(type_root)
|
35
|
+
filename = "#{@camelcased_type_name}.rb"
|
36
|
+
template('templates/nudge_type_class.erb', "#{type_root}/lib/types/#{filename}")
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_lib_spec
|
40
|
+
@camelcased_type_name = New_Nudge_Type.type_name(type_root)
|
41
|
+
filename = "#{@camelcased_type_name}_spec.rb"
|
42
|
+
template('templates/nudge_type_spec.erb', "#{type_root}/spec/#{filename}")
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_instructions
|
46
|
+
suite = ["define", "equal_q", "duplicate", "flush", "pop",
|
47
|
+
"random", "rotate", "shove", "swap", "yank", "yankdup"]
|
48
|
+
|
49
|
+
suite.each do |inst|
|
50
|
+
@core = "#{type_root}_#{inst}"
|
51
|
+
filename = "#{@core}.rb"
|
52
|
+
@instname = "#{@core.camelize}Instruction"
|
53
|
+
@type = type_root
|
54
|
+
@camelized_type = New_Nudge_Type.type_name(type_root)
|
55
|
+
template("templates/nudge_#{inst}_instruction.erb", "#{type_root}/lib/instructions/#{filename}")
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/bin/nudge
CHANGED
data/lib/cli/runner.rb
CHANGED
@@ -20,8 +20,8 @@ module Nudge
|
|
20
20
|
|
21
21
|
|
22
22
|
# A program to be interpreted can be passed in as an optional parameter
|
23
|
-
def initialize(params = {})
|
24
|
-
initialProgram =
|
23
|
+
def initialize(program = nil, params = {})
|
24
|
+
initialProgram = program
|
25
25
|
@program = initialProgram
|
26
26
|
@types = params[:types] || NudgeType.all_types
|
27
27
|
@step_limit = params[:step_limit] || 3000
|
@@ -57,7 +57,7 @@ module Nudge
|
|
57
57
|
self.clear_stacks
|
58
58
|
self.reset_names
|
59
59
|
self.reset_sensors
|
60
|
-
if program
|
60
|
+
if !program.nil?
|
61
61
|
@stacks[:exec].push(NudgeProgram.new(program).linked_code)
|
62
62
|
end
|
63
63
|
@steps = 0
|
@@ -21,86 +21,19 @@ module Nudge
|
|
21
21
|
def initialize(sourcecode)
|
22
22
|
raise(ArgumentError, "NudgeProgram.new should be passed a string") unless sourcecode.kind_of?(String)
|
23
23
|
@raw_code = sourcecode
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
def program_split!
|
24
|
+
|
25
|
+
# snipped out:
|
26
|
+
# program_split!
|
34
27
|
split_at_first_guillemet=@raw_code.partition( /^(?=«)/ )
|
35
28
|
@code_section = split_at_first_guillemet[0].strip
|
36
29
|
@footnote_section = split_at_first_guillemet[2].strip
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
breaker = /^«([a-zA-Z][a-zA-Z0-9_]*)»\s*(.*)\s*/m
|
45
|
-
pairs = shattered.collect {|fn| fn.match(breaker)[1..2]}
|
46
|
-
fn = Hash.new {|hash, key| hash[key] = [] }
|
47
|
-
@footnote_order = []
|
48
|
-
pairs.each do |key,value|
|
49
|
-
fn[key.to_sym] << value.strip
|
50
|
-
end
|
51
|
-
return fn
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
def relink_code!
|
57
|
-
if parses?
|
58
|
-
@linked_code = NudgeCodeblockParser.new.parse(@code_section).to_point
|
59
|
-
depth_first_association!
|
60
|
-
else
|
61
|
-
@linked_code = NilPoint.new
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
def depth_first_association!(program_point=@linked_code)
|
68
|
-
if program_point.kind_of?(ValuePoint)
|
69
|
-
program_point.raw = @footnotes[program_point.type].shift
|
70
|
-
if program_point.raw != nil
|
71
|
-
if program_point.type == :code
|
72
|
-
program_point.raw << pursue_more_footnotes(program_point.raw)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
elsif program_point.kind_of?(CodeblockPoint)
|
76
|
-
program_point.contents.each {|branch| depth_first_association!(branch)}
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
def pursue_more_footnotes(codepoint_as_string, collected_footnotes = "")
|
83
|
-
local_footnotes = ""
|
84
|
-
if self.contains_valuepoints?(codepoint_as_string)
|
85
|
-
local_parsetree = NudgeCodeblockParser.new.parse(codepoint_as_string)
|
86
|
-
if local_parsetree != nil
|
87
|
-
local_subtree = local_parsetree.to_point
|
88
|
-
if local_subtree.kind_of?(CodeblockPoint)
|
89
|
-
local_subtree.contents.each do |branch|
|
90
|
-
local_footnotes << pursue_more_footnotes(branch.tidy)
|
91
|
-
end
|
92
|
-
elsif local_subtree.kind_of?(ValuePoint)
|
93
|
-
local_subtree.raw = @footnotes[local_subtree.type].shift
|
94
|
-
if local_subtree.raw != nil
|
95
|
-
local_footnotes = "\n«#{local_subtree.type}» #{local_subtree.raw}"
|
96
|
-
if local_subtree.type == :code
|
97
|
-
local_footnotes << pursue_more_footnotes(local_subtree.raw,collected_footnotes)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
return collected_footnotes + local_footnotes
|
30
|
+
|
31
|
+
#snipped out:
|
32
|
+
#relink_code!
|
33
|
+
parsed_code = NudgeTree.from(@raw_code)
|
34
|
+
@linked_code = parsed_code[:tree]
|
35
|
+
@footnotes = parsed_code[:unused]
|
36
|
+
@points = self.points
|
104
37
|
end
|
105
38
|
|
106
39
|
|
@@ -1,10 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
# DO NOT MODIFY!!!!
|
4
|
-
# This file is automatically generated by racc 1.4.5
|
5
|
-
# from racc grammer file "parse.y".
|
6
|
-
#
|
7
|
-
|
8
3
|
require 'racc/parser'
|
9
4
|
require 'strscan'
|
10
5
|
|
@@ -16,30 +11,50 @@ module_eval <<'..end parse.y modeval..ida1760a43d7', 'parse.y', 22
|
|
16
11
|
nt = NudgeTree.new(string)
|
17
12
|
result = nt.send(:do_parse)
|
18
13
|
{tree:result, unused:nt.footnotes}
|
14
|
+
rescue ParseError => exc
|
15
|
+
{tree:NilPoint.new, unused:{}}
|
19
16
|
end
|
20
17
|
|
21
|
-
|
18
|
+
|
19
|
+
attr_accessor :tree, :footnotes, :unused_footnotes
|
20
|
+
|
22
21
|
|
23
22
|
def initialize(string)
|
24
23
|
@tokens = []
|
25
24
|
@string = string.strip
|
26
25
|
@footnotes = Hash.new { |hash, category| hash[category] = [] }
|
27
|
-
|
26
|
+
@unused_footnotes = {}
|
28
27
|
self.make_footnotes!
|
29
28
|
self.tokenize!
|
30
29
|
end
|
31
30
|
|
31
|
+
|
32
32
|
def make_footnotes!
|
33
|
-
return unless split_point = @string.index(
|
33
|
+
return unless split_point = @string.index(/\n«/um)
|
34
34
|
raise ParseError, "No program string" if split_point == 0
|
35
35
|
|
36
|
-
ss = StringScanner.new(@string.slice!((split_point
|
36
|
+
ss = StringScanner.new(@string.slice!((split_point)..-1))
|
37
|
+
|
38
|
+
fn_head = /\n«([\p{Alpha}][_\p{Alnum}]*)»/u
|
37
39
|
|
38
|
-
while ss.
|
39
|
-
|
40
|
+
while ss.exist?(fn_head)
|
41
|
+
ss.scan_until(fn_head)
|
42
|
+
cat = ss[1]
|
43
|
+
if ss.exist?(/\n«/um)
|
44
|
+
ss.scan_until(/(.*?)\n«/um)
|
45
|
+
fn = ss[1]
|
46
|
+
elsif ss.eos?
|
47
|
+
fn = ""
|
48
|
+
else
|
49
|
+
ss.scan_until(/(.*)$/um)
|
50
|
+
fn = ss[1]
|
51
|
+
end
|
52
|
+
ss.pos -= 3
|
53
|
+
@footnotes[cat] << fn.strip
|
40
54
|
end
|
41
55
|
end
|
42
56
|
|
57
|
+
|
43
58
|
def pop_footnote(category)
|
44
59
|
value = @footnotes[category].shift
|
45
60
|
|
@@ -52,14 +67,14 @@ module_eval <<'..end parse.y modeval..ida1760a43d7', 'parse.y', 22
|
|
52
67
|
return value
|
53
68
|
end
|
54
69
|
|
70
|
+
|
55
71
|
def collect_embedded_footnotes!(code_text, embedded_footnotes)
|
56
|
-
ss = StringScanner.new(code_text)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
footnote = @footnotes[category].shift
|
72
|
+
ss = StringScanner.new(code_text)
|
73
|
+
while ss.skip_until(/«([\p{Alpha}][\p{Alnum}_]*?)»/um)
|
74
|
+
category = ss[1]
|
75
|
+
footnote = @footnotes[category].shift || ""
|
61
76
|
|
62
|
-
embedded_footnotes << "«#{category}
|
77
|
+
embedded_footnotes << "«#{category}» #{footnote}"
|
63
78
|
|
64
79
|
if category == "code"
|
65
80
|
self.collect_embedded_footnotes!(footnote, embedded_footnotes)
|
@@ -67,10 +82,12 @@ module_eval <<'..end parse.y modeval..ida1760a43d7', 'parse.y', 22
|
|
67
82
|
end
|
68
83
|
end
|
69
84
|
|
85
|
+
|
70
86
|
def next_token
|
71
87
|
return @tokens.shift
|
72
88
|
end
|
73
89
|
|
90
|
+
|
74
91
|
def tokenize!
|
75
92
|
ss = StringScanner.new(@string)
|
76
93
|
|
@@ -80,9 +97,9 @@ module_eval <<'..end parse.y modeval..ida1760a43d7', 'parse.y', 22
|
|
80
97
|
nil
|
81
98
|
when /[{}«»]/
|
82
99
|
[c, 0]
|
83
|
-
when /[\p{Alpha}]/
|
84
|
-
ss.
|
85
|
-
ss.scan(/[\p{Alpha}][\p{Alnum}
|
100
|
+
when /[\p{Alpha}]/u
|
101
|
+
ss.unscan
|
102
|
+
ss.scan(/[\p{Alpha}][_\p{Alnum}]*/u) # <- \p{Alpha}
|
86
103
|
|
87
104
|
case m = ss.matched
|
88
105
|
when "block", "ref", "do", "value"
|
@@ -91,7 +108,7 @@ module_eval <<'..end parse.y modeval..ida1760a43d7', 'parse.y', 22
|
|
91
108
|
[:ID, m]
|
92
109
|
end
|
93
110
|
else
|
94
|
-
raise ParseError, "Couldn't tokenize program string"
|
111
|
+
raise ParseError, "Couldn't tokenize program string \"#{@string}\""
|
95
112
|
end
|
96
113
|
end
|
97
114
|
|
@@ -99,6 +116,7 @@ module_eval <<'..end parse.y modeval..ida1760a43d7', 'parse.y', 22
|
|
99
116
|
@tokens << [false, false]
|
100
117
|
end
|
101
118
|
|
119
|
+
|
102
120
|
def on_error(error_token_id, error_value, value_stack)
|
103
121
|
raise ParseError, "Couldn't parse program string"
|
104
122
|
end
|
@@ -92,10 +92,7 @@ module Nudge
|
|
92
92
|
def initialize(type,representation=nil)
|
93
93
|
raise(ArgumentError, "Type must be a symbol or string") unless [Symbol,String].include?(type.class)
|
94
94
|
@type = type.to_sym
|
95
|
-
|
96
|
-
representation = representation.to_s
|
97
|
-
end
|
98
|
-
@raw = representation
|
95
|
+
@raw = representation.nil? ? nil : representation.to_s
|
99
96
|
end
|
100
97
|
|
101
98
|
def go(context)
|
@@ -147,13 +144,13 @@ module Nudge
|
|
147
144
|
end
|
148
145
|
|
149
146
|
def blueprint_parts
|
150
|
-
fn =
|
147
|
+
fn = "«#{self.type}» #{self.raw}".strip
|
151
148
|
return [self.tidy, fn]
|
152
149
|
end
|
153
150
|
|
154
151
|
def blueprint
|
155
152
|
pts = self.blueprint_parts
|
156
|
-
return "
|
153
|
+
return "#{pts[0]} \n#{pts[1]}"
|
157
154
|
end
|
158
155
|
end
|
159
156
|
|
data/readme.md
CHANGED
@@ -8,16 +8,50 @@ See the [project Wiki](http://github.com/Vaguery/Nudge/wikis) for a more thoroug
|
|
8
8
|
|
9
9
|
## Getting started
|
10
10
|
|
11
|
+
### Ruby 1.9
|
12
|
+
|
13
|
+
Make sure your Ruby version is 1.9 (or higher) by running
|
14
|
+
|
15
|
+
ruby -v
|
16
|
+
|
17
|
+
and getting something along the lines of `ruby 1.9.1p378 (2010-01-10 revision 26273) [i386-darwin10.2.0]` as a response. If you see `ruby 1.8.7`, we'd recommend a look at [rvm](http://rvm.beginrescueend.com/).
|
18
|
+
|
19
|
+
### Installing the gem
|
20
|
+
|
11
21
|
gem install nudge
|
12
22
|
|
13
23
|
As of this writing, the `nudge` gem can be used as a library in your Ruby programs. S Real Soon Now, it'll be part of a more interesting gem…
|
14
24
|
|
15
|
-
|
25
|
+
### A test run
|
26
|
+
|
27
|
+
Meanwhile, try something like this in irb:
|
16
28
|
|
29
|
+
#encoding: utf-8
|
30
|
+
# you'll need to use unicode for all Nudge programs
|
31
|
+
|
17
32
|
require 'nudge'
|
18
33
|
include Nudge
|
19
34
|
|
20
|
-
my_program =
|
35
|
+
my_program = NudgeProgram.random(
|
36
|
+
:target_size_in_points => 50,
|
37
|
+
:reference_names => ["x1", "x2"])
|
38
|
+
|
39
|
+
puts "Your random program:\n\n#{my_program.blueprint}"
|
40
|
+
|
41
|
+
my_interpreter = Interpreter.new()
|
42
|
+
|
43
|
+
my_interpreter.reset(my_program.blueprint)
|
44
|
+
|
45
|
+
|
46
|
+
# set up some sensors, so we know what happens afterwards
|
47
|
+
my_interpreter.register_sensor("int_1") {|state| state.peek_value(:int)} # reads the top :int value
|
48
|
+
my_interpreter.register_sensor("bool_1") {|state| state.peek_value(:bool)} # reads the top :bool value
|
49
|
+
my_interpreter.register_sensor("steps") {|state| state.steps} # reads the number of steps the interpreter took
|
50
|
+
|
51
|
+
puts "\n\nsensor values: #{my_interpreter.run}"
|
52
|
+
|
53
|
+
When you run that, you'll get something [like this](http://gist.github.com/347215)—though your code and output will (hopefully) be a different random result!
|
54
|
+
|
21
55
|
## Requirements
|
22
56
|
|
23
57
|
The interpreter code relies heavily on functional programming features of Ruby 1.9+. If you have not yet installed Ruby 1.9, I'd recommend using [rvm](http://rvm.beginrescueend.com/) to set up a special "sandbox" version of 1.9 until you're ready to upgrade your development or production machine.
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#encoding: utf-8
|
2
|
+
require File.join(File.dirname(__FILE__), "./../spec_helper")
|
3
|
+
include Nudge
|
4
|
+
|
5
|
+
describe "thor new_nudge_type MY_TYPE" do
|
6
|
+
before(:each) do
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "documentation" do
|
10
|
+
it "should have a desc field"
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
describe "validating type names" do
|
15
|
+
it "should check to see the type_name matches the allowed pattern"
|
16
|
+
|
17
|
+
it "should quit and warn you if it doesn't match"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
describe "checking for preexisting files" do
|
22
|
+
it "should ask if you already have something there"
|
23
|
+
|
24
|
+
it "should replace it without asking if you use '--force'"
|
25
|
+
|
26
|
+
it "should replace it if you answer 'yes'"
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
describe "creating core lib/MyType.rb file" do
|
31
|
+
it "should use template 'templates/nudge_type_class.tt"
|
32
|
+
|
33
|
+
|
34
|
+
it "should require 'nudge'"
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
describe "creating boilerplate instruction code" do
|
40
|
+
it "should make lib/instructions/foo_define.rb"
|
41
|
+
it "should make lib/instructions/foo_equal_q.rb"
|
42
|
+
it "should make lib/instructions/foo_duplicate.rb"
|
43
|
+
it "should make lib/instructions/foo_flush.rb"
|
44
|
+
it "should make lib/instructions/foo_pop.rb"
|
45
|
+
it "should make lib/instructions/foo.random.rb" # if it's a candidate for literals
|
46
|
+
it "should make lib/instructions/foo_rotate.rb"
|
47
|
+
it "should make lib/instructions/foo_shove.rb"
|
48
|
+
it "should make lib/instructions/foo_swap.rb"
|
49
|
+
it "should make lib/instructions/foo_yank.rb"
|
50
|
+
end
|
51
|
+
end
|
@@ -26,7 +26,7 @@ describe CodeNoopInstruction do
|
|
26
26
|
|
27
27
|
describe "\#cleanup" do
|
28
28
|
it "should change nothing about the interpreter except the step count" do
|
29
|
-
@context = Interpreter.new(
|
29
|
+
@context = Interpreter.new("do code_noop")
|
30
30
|
@context.enable(CodeNoopInstruction)
|
31
31
|
earlier = @context.steps
|
32
32
|
@context.run
|
@@ -3,8 +3,7 @@ require File.join(File.dirname(__FILE__), "/../spec_helper")
|
|
3
3
|
include Nudge
|
4
4
|
|
5
5
|
def magicCodeblockPointMaker(program_blueprint)
|
6
|
-
|
7
|
-
return my_kludge.linked_code
|
6
|
+
NudgeTree.from(program_blueprint)[:tree]
|
8
7
|
end
|
9
8
|
|
10
9
|
|
@@ -43,10 +42,10 @@ describe "blueprint_parts" do
|
|
43
42
|
context "when there need to be footnotes" do
|
44
43
|
it "should work for blocks containing nil-valued ValuePoints" do
|
45
44
|
CodeblockPoint.new([ValuePoint.new("foo")]).blueprint_parts.should ==
|
46
|
-
["block {\n value «foo»}",""]
|
45
|
+
["block {\n value «foo»}","«foo»"]
|
47
46
|
annoyinglyWordy = magicCodeblockPointMaker("block { block { block { value «foo»}}}")
|
48
47
|
annoyinglyWordy.blueprint_parts.should ==
|
49
|
-
["block {\n block {\n block {\n value «foo»}}}",""]
|
48
|
+
["block {\n block {\n block {\n value «foo»}}}","«foo»"]
|
50
49
|
end
|
51
50
|
|
52
51
|
it "should work with footnotes from the root" do
|
@@ -65,8 +65,8 @@ describe "initialization" do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
it "should accept a blueprint, which should default to an empty string" do
|
68
|
-
Interpreter.new(
|
69
|
-
|
68
|
+
Interpreter.new("value «int» \n«int» 7").program.should == "value «int» \n«int» 7"
|
69
|
+
Interpreter.new().program.should == nil
|
70
70
|
end
|
71
71
|
|
72
72
|
it "should have an #enable method that works for Instructions, adding them to the #instructions hash" do
|
@@ -444,7 +444,6 @@ describe "running" do
|
|
444
444
|
|
445
445
|
it "should do nothing if the :exec stack starts empty" do
|
446
446
|
@ii.reset()
|
447
|
-
puts @ii.stacks[:exec].depth
|
448
447
|
@ii.run
|
449
448
|
@ii.steps.should == 0
|
450
449
|
end
|
@@ -461,7 +460,7 @@ end
|
|
461
460
|
|
462
461
|
describe "resetting" do
|
463
462
|
it "should clear the steps" do
|
464
|
-
ii = Interpreter.new(
|
463
|
+
ii = Interpreter.new("block {ref a ref b}")
|
465
464
|
ii.run
|
466
465
|
ii.steps.should == 3
|
467
466
|
ii.reset
|
@@ -484,7 +483,7 @@ describe "resetting" do
|
|
484
483
|
end
|
485
484
|
|
486
485
|
it "should clear the program, if none is given" do
|
487
|
-
ii = Interpreter.new(
|
486
|
+
ii = Interpreter.new("block {}")
|
488
487
|
ii.reset
|
489
488
|
ii.program.should == nil
|
490
489
|
end
|