nudge 0.1.3 → 0.2.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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.2.0
@@ -28,6 +28,10 @@ class Instruction
28
28
  class MissingInstructionError < RuntimeError
29
29
  end
30
30
 
31
+ class CodeOversizeError < ArgumentError
32
+ end
33
+
34
+
31
35
  def initialize(context)
32
36
  @context = context
33
37
  end
@@ -51,6 +55,9 @@ class Instruction
51
55
 
52
56
 
53
57
  def pushes(stackName, literal)
58
+ if (stackName.to_s == "code") && (literal.value.length > self.context.code_char_limit)
59
+ raise(CodeOversizeError, ":code cannot have more than #{self.context.code_char_limit} chars")
60
+ end
54
61
  @context.stacks[stackName].push literal
55
62
  end
56
63
 
@@ -62,7 +69,7 @@ class Instruction
62
69
  self.cleanup
63
70
  end
64
71
  rescue NotEnoughStackItems, MissingInstructionError,
65
- InstructionMethodError, NaNResultError, FloatDomainError => exc
72
+ InstructionMethodError, NaNResultError, FloatDomainError, CodeOversizeError => exc
66
73
  msg = ValuePoint.new("error", exc.message)
67
74
  pushes :error, msg
68
75
  end
@@ -17,6 +17,8 @@ module Nudge
17
17
  attr_accessor :stacks, :instructions_library, :variables, :names, :types
18
18
  attr_accessor :last_name, :evaluate_references
19
19
  attr_accessor :sensors
20
+ attr_accessor :code_char_limit
21
+ attr_accessor :start_time, :time_limit
20
22
 
21
23
 
22
24
  # A program to be interpreted can be passed in as an optional parameter
@@ -25,6 +27,8 @@ module Nudge
25
27
  @program = initialProgram
26
28
  @types = params[:types] || NudgeType.all_types
27
29
  @step_limit = params[:step_limit] || 3000
30
+ @time_limit = params[:time_limit] || 60.0 # seconds
31
+ @code_char_limit = params[:code_char_limit] || 2000
28
32
  @sensors = Hash.new
29
33
 
30
34
  instructions = params[:instructions] || Instruction.all_instructions
@@ -61,6 +65,7 @@ module Nudge
61
65
  @stacks[:exec].push(NudgeProgram.new(program).linked_code)
62
66
  end
63
67
  @steps = 0
68
+ @start_time = Time.now
64
69
  @evaluate_references = true
65
70
  end
66
71
 
@@ -107,7 +112,9 @@ module Nudge
107
112
  # 1. Is the <b>:exec</b> stack empty?
108
113
  # 2. Are the number of steps greater than self.step_limit?
109
114
  def notDone?
110
- @stacks[:exec].depth > 0 && @steps < @step_limit
115
+ @stacks[:exec].depth > 0 &&
116
+ @steps < @step_limit &&
117
+ (Time.now-@start_time)<@time_limit
111
118
  end
112
119
 
113
120
 
@@ -132,6 +139,7 @@ module Nudge
132
139
 
133
140
  # invoke self.step() until a termination condition is true
134
141
  def run
142
+ @start_time = Time.now
135
143
  while notDone?
136
144
  self.step
137
145
  end
@@ -1,7 +1,4 @@
1
1
  #encoding: utf-8
2
- require 'treetop'
3
- Treetop.load(File.join(File.dirname(__FILE__),'grammars', "nudge_codeblock.treetop"))
4
-
5
2
 
6
3
  module Nudge
7
4
  class NudgeProgram
@@ -22,14 +19,10 @@ module Nudge
22
19
  raise(ArgumentError, "NudgeProgram.new should be passed a string") unless sourcecode.kind_of?(String)
23
20
  @raw_code = sourcecode
24
21
 
25
- # snipped out:
26
- # program_split!
27
22
  split_at_first_guillemet=@raw_code.partition( /^(?=«)/ )
28
23
  @code_section = split_at_first_guillemet[0].strip
29
24
  @footnote_section = split_at_first_guillemet[2].strip
30
25
 
31
- #snipped out:
32
- #relink_code!
33
26
  parsed_code = NudgeTree.from(@raw_code)
34
27
  @linked_code = parsed_code[:tree]
35
28
  @footnotes = parsed_code[:unused]
@@ -152,14 +145,13 @@ module Nudge
152
145
 
153
146
 
154
147
  def parses?(program_blueprint = @code_section)
155
- (NudgeCodeblockParser.new.parse(program_blueprint) != nil)
148
+ !NudgeTree.from(program_blueprint)[:tree].kind_of?(NilPoint)
156
149
  end
157
150
 
158
151
 
159
152
 
160
153
  def tidy
161
- framework = NudgeCodeblockParser.new.parse(@code_section)
162
- framework ? framework.tidy : ""
154
+ NudgeTree.from(@raw_code)[:tree].tidy
163
155
  end
164
156
 
165
157
 
data/lib/nudge.rb CHANGED
@@ -1,22 +1,10 @@
1
1
  $: << File.join(File.dirname(__FILE__), "/../lib")
2
2
 
3
3
  require 'rubygems'
4
- require 'treetop'
5
4
  require 'active_support'
6
5
 
7
6
  require 'interpreter/parse.tab'
8
7
 
9
- require 'interpreter/grammars/nudge_common'
10
-
11
- require 'interpreter/grammars/nudge_value_helpers'
12
- require 'interpreter/grammars/nudge_reference_helpers'
13
- require 'interpreter/grammars/nudge_instruction_helpers'
14
- require 'interpreter/grammars/nudge_codeblock_helpers'
15
- require 'interpreter/grammars/nudge_reference'
16
- require 'interpreter/grammars/nudge_instruction'
17
- require 'interpreter/grammars/nudge_value'
18
- require 'interpreter/grammars/nudge_codeblock'
19
-
20
8
  require 'interpreter/nudge_program'
21
9
 
22
10
  require 'cli/runner'
data/readme.md CHANGED
@@ -58,7 +58,9 @@ The interpreter code relies heavily on functional programming features of Ruby 1
58
58
 
59
59
  The following gems need to be present to run the code:
60
60
 
61
- * [treetop](http://treetop.rubyforge.org/)
62
- * [activesupport](http://as.rubyonrails.org/)
61
+ * [activesupport](http://as.rubyonrails.org/) (`gem install activesupport`)
62
+
63
+ To use the fancypants command line generators we're building, you'll need thor:
64
+ * [thor](http://github.com/wycats/thor/) (`gem install thor`)
63
65
 
64
- and you will want [rspec](http://rspec.info/) to be able to run the specs and confirm the codebase works on your system.
66
+ and you will definitely want [rspec](http://rspec.info/) to be able to run the specs and confirm the codebase works on your system: `gem install rspec`.
@@ -15,6 +15,7 @@ describe "Instruction has a master list" do
15
15
  end
16
16
  end
17
17
 
18
+
18
19
  describe "capturing errors" do
19
20
  describe "NotEnoughStackItems" do
20
21
  describe "#preconditions?" do
@@ -36,5 +37,16 @@ describe "capturing errors" do
36
37
  context.stacks[:error].peek.blueprint.should include "needs IntAddInstruction"
37
38
  end
38
39
  end
39
-
40
+ end
41
+
42
+
43
+ describe ":code stack has a special rule" do
44
+ it "should be impossible to use #pushes to push a :code item that is too large for the context" do
45
+ small_box = Interpreter.new("block {}", code_char_limit:20)
46
+ small_code = ValuePoint.new("code","block { do a }")
47
+ long_code = ValuePoint.new("code","block { do a do b do c do d do e do f do g }")
48
+ throwaway = IntAddInstruction.new(small_box)
49
+ lambda{throwaway.pushes(:code, long_code)}.should raise_error(Instruction::CodeOversizeError)
50
+ lambda{throwaway.pushes(:code, small_code)}.should_not raise_error(Instruction::CodeOversizeError)
51
+ end
40
52
  end
@@ -68,6 +68,7 @@ describe IntPowerInstruction do
68
68
  context.peek(:error).blueprint.should include("Infinity")
69
69
  context.stacks[:int].depth.should == 0
70
70
  end
71
+
71
72
  end
72
73
  end
73
74
  end
@@ -45,12 +45,30 @@ describe "initialization" do
45
45
  @ii.steps.should == 0
46
46
  end
47
47
 
48
+ it "#reset should reset the start_time counter to 0" do
49
+ @ii.start_time = 999999999999
50
+ @ii.reset
51
+ @ii.start_time.should be_a_kind_of(Time)
52
+ end
53
+
48
54
  it "#reset should reset the #sensors Hash" do
49
55
  @ii.register_sensor("z") {1201}
50
56
  @ii.reset
51
57
  @ii.sensors["z"].should == nil
52
58
  end
53
59
 
60
+ it "should have a code_char_limit" do
61
+ lambda{@ii.code_char_limit}.should_not raise_error
62
+ end
63
+
64
+ it "should have a default code_char_limit of 2000 characters" do
65
+ @ii.code_char_limit.should == 2000
66
+ end
67
+
68
+ it "should be possible to set code_char_limit with an option" do
69
+ Interpreter.new("block {}",code_char_limit:171).code_char_limit.should == 171
70
+ end
71
+
54
72
 
55
73
  it "should load a complex CodeBlock as a single item on the exec stack" do
56
74
  myCode = "block {\ndo foo\n do bar\n block {\ndo baz}}"
@@ -421,6 +439,13 @@ describe "stepping" do
421
439
  @ii.steps.should == 20
422
440
  end
423
441
 
442
+ it "should step only until its time_limit is reached or exceeded" do
443
+ @ii.reset("block {}")
444
+ @ii.start_time = (Time.now - 10000)
445
+ @ii.run
446
+ @ii.steps.should == 1
447
+ end
448
+
424
449
  end
425
450
 
426
451
  describe "running" do
@@ -489,7 +514,7 @@ describe "resetting" do
489
514
  end
490
515
 
491
516
  it "should not affect variable bindings" do
492
- ii = Interpreter.new
517
+ ii = Interpreter.new("block {}")
493
518
  ii.bind_variable("a", ValuePoint.new("int",3))
494
519
  ii.variables.keys.should == ["a"]
495
520
  ii.reset
@@ -1,6 +1,5 @@
1
1
  #encoding: utf-8
2
2
  require File.join(File.dirname(__FILE__), "./../spec_helper")
3
- load_grammar('codeblock')
4
3
  include Nudge
5
4
 
6
5
 
data/spec/spec_helper.rb CHANGED
@@ -4,7 +4,7 @@ $: << File.join(File.dirname(__FILE__), "/../lib")
4
4
 
5
5
  require 'spec'
6
6
  require 'pp'
7
- require 'nudge'
7
+ require 'lib/nudge'
8
8
  require 'erb'
9
9
 
10
10
  Spec::Runner.configure do |config|
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
8
- - 3
9
- version: 0.1.3
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Bill Tozier
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2010-04-01 00:00:00 -04:00
19
+ date: 2010-04-08 00:00:00 -04:00
20
20
  default_executable: nudge
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -216,15 +216,6 @@ files:
216
216
  - lib/instructions/name/name_unbind.rb
217
217
  - lib/instructions/name/name_yank.rb
218
218
  - lib/instructions/name/name_yankdup.rb
219
- - lib/interpreter/grammars/nudge_codeblock.treetop
220
- - lib/interpreter/grammars/nudge_codeblock_helpers.rb
221
- - lib/interpreter/grammars/nudge_common.treetop
222
- - lib/interpreter/grammars/nudge_instruction.treetop
223
- - lib/interpreter/grammars/nudge_instruction_helpers.rb
224
- - lib/interpreter/grammars/nudge_reference.treetop
225
- - lib/interpreter/grammars/nudge_reference_helpers.rb
226
- - lib/interpreter/grammars/nudge_value.treetop
227
- - lib/interpreter/grammars/nudge_value_helpers.rb
228
219
  - lib/interpreter/interpreter.rb
229
220
  - lib/interpreter/nudge_program.rb
230
221
  - lib/interpreter/parse.tab.rb
@@ -1,17 +0,0 @@
1
- require 'nudge'
2
-
3
-
4
- grammar NudgeCodeblock
5
- include NudgeCommon
6
- include NudgeReference
7
- include NudgeInstruction
8
- include NudgeValue
9
-
10
- rule codesection
11
- value / instruction / reference / (block_statement <CodeblockParseNode>)
12
- end
13
-
14
- rule block_statement
15
- 'block' spcs? '{' spcs? block_contents:(codesection spcs?)* '}'
16
- end
17
- end
@@ -1,19 +0,0 @@
1
- # coding: utf-8
2
- module CodeblockParseNode
3
- def contents
4
- block_contents.elements.collect {|e| e.elements[0]}
5
- end
6
-
7
- def tidy(level=1)
8
- tt = "block {"
9
- indent = level*2
10
- contents.each {|item| tt += ("\n" + (" "*indent) + item.tidy(level+1))}
11
- tt += "}"
12
- return tt
13
- end
14
-
15
- def to_point
16
- c = CodeblockPoint.new(contents.collect {|e| e.to_point})
17
- end
18
- end
19
-
@@ -1,15 +0,0 @@
1
- # encoding: utf-8
2
- grammar NudgeCommon
3
- rule common
4
- spcs / alphas_and_underscores
5
- end
6
-
7
- rule spcs
8
- [\s\t\n]+
9
- end
10
-
11
- rule alphas_and_underscores
12
- [\p{Alpha}] [_\p{Alnum}/u]*
13
- end
14
-
15
- end
@@ -1,14 +0,0 @@
1
- #encoding: utf-8
2
- require 'interpreter/grammars/nudge_common'
3
-
4
- grammar NudgeInstruction
5
- include NudgeCommon
6
-
7
- rule instruction
8
- 'do' spcs opcode <InstructionParseNode>
9
- end
10
-
11
- rule opcode
12
- alphas_and_underscores
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- # coding: utf-8
2
- class InstructionParseNode < Treetop::Runtime::SyntaxNode
3
- def instruction_name
4
- opcode.text_value
5
- end
6
-
7
- def tidy(level=1)
8
- "do #{instruction_name}"
9
- end
10
-
11
- def to_point
12
- InstructionPoint.new(instruction_name)
13
- end
14
- end
@@ -1,9 +0,0 @@
1
- require 'interpreter/grammars/nudge_common'
2
-
3
- grammar NudgeReference
4
- include NudgeCommon
5
-
6
- rule reference
7
- 'ref' spcs vname:alphas_and_underscores <ReferenceParseNode>
8
- end
9
- end
@@ -1,14 +0,0 @@
1
- # coding: utf-8
2
- class ReferenceParseNode < Treetop::Runtime::SyntaxNode
3
- def variable_name
4
- vname.text_value
5
- end
6
-
7
- def tidy(level=1)
8
- "ref #{variable_name}"
9
- end
10
-
11
- def to_point
12
- ReferencePoint.new(variable_name)
13
- end
14
- end
@@ -1,14 +0,0 @@
1
- # encoding: utf-8
2
- require 'interpreter/grammars/nudge_common'
3
-
4
- grammar NudgeValue
5
- include NudgeCommon
6
-
7
- rule value
8
- 'value' spcs? '«' footnote_type '»' <ValueParseNode>
9
- end
10
-
11
- rule footnote_type
12
- alphas_and_underscores
13
- end
14
- end
@@ -1,19 +0,0 @@
1
- # coding: utf-8
2
- class ValueParseNode < Treetop::Runtime::SyntaxNode
3
- def type=(new_type)
4
- @type = new_type
5
- end
6
-
7
- def type
8
- @type ||= footnote_type.text_value
9
- end
10
-
11
- def tidy(level=1)
12
- "value «#{type}»"
13
- end
14
-
15
- def to_point
16
- return ValuePoint.new(type)
17
- end
18
-
19
- end