nudge 0.1.2 → 0.1.3
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/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
|