lib/instructions/infrastructure.rb in nudge-0.0.2 vs lib/instructions/infrastructure.rb in nudge-0.1.0
- old
+ new
@@ -30,39 +30,46 @@
def initialize(context)
@context = context
end
- def needs(stackName, minimum)
- iNeed = @context.stacks[stackName]
-
- if @context.stacks[stackName].depth < minimum
- raise NotEnoughStackItems, "Stack #{stackName} too small: needs at least #{minimum} items"
- return false
+
+ def needs(infrastructure, minimum = 1)
+ unless infrastructure.is_a?(Symbol)
+ raise(InstructionNotFoundError, "#{infrastructure.to_s} is not a known Instruction") unless
+ Object.const_defined?(infrastructure.to_s)
+ raise(MissingInstructionError, "#{self.class} needs #{infrastructure}") unless
+ @context.instructions.include?(infrastructure)
else
- return true
+ iNeed = @context.stacks[infrastructure]
+ if @context.stacks[infrastructure].depth < minimum
+ raise NotEnoughStackItems,
+ "Stack #{infrastructure.to_s} too small: #{self.class.to_nudgecode} needs at least #{minimum} items"
+ end
end
+ return true
end
-
+
+
def pushes(stackName, literal)
@context.stacks[stackName].push literal
end
+
def go
- begin
if self.preconditions?
self.setup
self.derive
self.cleanup
end
- rescue NotEnoughStackItems
- logError("NOOP: Parameter shortage")
- rescue InstructionMethodError
- logError("NOOP: Calculation error")
- end
+ rescue NotEnoughStackItems, MissingInstructionError,
+ InstructionMethodError, NaNResultError, FloatDomainError => exc
+ msg = ValuePoint.new("error", exc.message)
+ pushes :error, msg
end
+
def preconditions?
raise "Your Instruction class should define its own #preconditions? method"
end
def setup
@@ -74,11 +81,322 @@
end
def cleanup
raise "Your Instruction class should define its own #cleanup method"
end
+end
+
+
+
+module IfInstruction
+ attr_reader :target_stack
- def logError(msg)
- # STDERR.puts msg
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
end
-end
\ No newline at end of file
+ def preconditions?
+ needs @target_stack, 2
+ needs :bool, 1
+ end
+ def setup
+ @stay = @context.pop_value(:bool)
+ @ifFalse = @context.pop(@target_stack)
+ @ifTrue = @context.pop(@target_stack)
+ end
+ def derive
+ end
+ def cleanup
+ @stay ? @context.stacks[@target_stack].push(@ifTrue) : @context.stacks[@target_stack].push(@ifFalse)
+ end
+end
+
+
+module PopInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ needs @target_stack, 1
+ end
+ def setup
+ @result = @context.pop(@target_stack)
+ end
+ def derive
+ end
+ def cleanup
+ end
+end
+
+
+module SwapInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ needs @target_stack, 2
+ end
+ def setup
+ @result1 = @context.pop(@target_stack)
+ @result2 = @context.pop(@target_stack)
+ end
+ def derive
+ end
+ def cleanup
+ pushes @target_stack, @result1
+ pushes @target_stack, @result2
+ end
+end
+
+
+module DuplicateInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ needs @target_stack, 1
+ end
+ def setup
+ @arg1 = @context.peek(@target_stack)
+ end
+ def derive
+ @result = @arg1.clone
+ end
+ def cleanup
+ pushes @target_stack, @result
+ end
+end
+
+
+module RotateInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ needs @target_stack, 3
+ end
+ def setup
+ @arg3 = @context.pop(@target_stack)
+ @arg2 = @context.pop(@target_stack)
+ @arg1 = @context.pop(@target_stack)
+ end
+ def derive
+ end
+ def cleanup
+ pushes @target_stack, @arg2
+ pushes @target_stack, @arg3
+ pushes @target_stack, @arg1
+ end
+end
+
+
+module DepthInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ @context.stacks[@target_stack].depth != nil
+ end
+ def setup
+ end
+ def derive
+ @result = ValuePoint.new("int",@context.stacks[@target_stack].depth.to_s)
+ end
+ def cleanup
+ pushes :int, @result
+ end
+end
+
+
+module FlushInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ @context.stacks[@target_stack].depth != nil
+ end
+ def setup
+ end
+ def derive
+ end
+ def cleanup
+ @context.stacks[@target_stack].clear
+ end
+end
+
+
+module ShoveInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ if @target_stack != :int
+ needs :int, 1
+ needs @target_stack, 1
+ else
+ needs :int, 2
+ end
+ end
+
+ def setup
+ @how_far = @context.pop_value(:int)
+ @result = @context.pop(@target_stack)
+ end
+
+ def derive
+ max = @context.stacks[@target_stack].depth
+ case
+ when @how_far <= 0
+ @new_depth = max
+ when @how_far > max
+ @new_depth = 0
+ else
+ @new_depth = max - @how_far
+ end
+ end
+
+ def cleanup
+ @context.stacks[@target_stack].entries.insert(@new_depth,@result)
+ end
+end
+
+
+module YankInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ if @target_stack != :int
+ needs :int, 1
+ needs @target_stack, 1
+ else
+ needs :int, 2
+ end
+ end
+
+ def setup
+ @from_where = @context.pop_value(:int)
+ end
+
+ def derive
+ max = @context.stacks[@target_stack].depth-1
+ case
+ when @from_where < 0
+ @which = max
+ when @from_where > max
+ @which = 0
+ else
+ @which = max - @from_where
+ end
+ end
+
+ def cleanup
+ moved_value = @context.stacks[@target_stack].entries.delete_at(@which)
+ @context.stacks[@target_stack].push(moved_value)
+ end
+end
+
+
+module YankdupInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ if @target_stack != :int
+ needs :int, 1
+ needs @target_stack, 1
+ else
+ needs :int, 2
+ end
+ end
+
+ def setup
+ @from_where = @context.pop_value(:int)
+ end
+
+ def derive
+ max = @context.stacks[@target_stack].depth-1
+ case
+ when @from_where < 0
+ @which = max
+ when @from_where > max
+ @which = 0
+ else
+ @which = max - @from_where
+ end
+ end
+
+ def cleanup
+ moved_value = @context.stacks[@target_stack].entries[@which].clone
+ @context.stacks[@target_stack].push(moved_value)
+ end
+end
+
+
+module DefineInstruction
+ attr_reader :target_stack
+
+ def initialize(context, target_stack)
+ @target_stack = target_stack
+ super(context)
+ end
+
+ def preconditions?
+ if @target_stack != :name
+ needs @target_stack, 1
+ needs :name, 1
+ else
+ needs :name, 2
+ end
+ end
+
+ def setup
+ @bound_name = @context.pop_value(:name)
+ @new_value = @context.pop(@target_stack)
+ end
+
+ def derive
+ raise Instruction::InstructionMethodError, "#{self.class} cannot redefine a variable" if
+ @context.variables[@bound_name] != nil
+ end
+
+ def cleanup
+ @context.bind_name(@bound_name, @new_value)
+ end
+end