module Operations

This module is responsible for performing operations. It keeps all logic based on opertaions encapsulated. It is meant to be included with the top-level BefungeInterpreter.

Constants

DIRECTIONS
DIRECTIONS_MAP
DIRECTION_OPS
MATH_OPS

Bunch of Constants here. Important thing: %i() defines array of symbols while %w() defines array of strings. The Hash pattern I’ve chosen to employ here simply maps the string/symbol single character representation of the operation to it’s actual method name here. For instance: OPERATORS_MAP => :logical_not We can just send that symbol in our operate! method.

OPERATORS
OPERATORS_MAP

Public Instance Methods

change_dir(op) click to toggle source

I call this method two different ways - one with directional operational arguments < > ^ v and one with actual directions :n :e :s :w. This is the reason for the unless statement here.

# File lib/operations.rb, line 53
def change_dir(op)
  op = DIRECTIONS_MAP[op] unless DIRECTIONS.include?(op)
  @code_map.pointer.direction = op
end
duplicate_stack_top() click to toggle source
# File lib/operations.rb, line 85
def duplicate_stack_top
  @stack.push(0) and return if @stack.empty?
  @stack.push(@stack.last)
end
end_program() click to toggle source
# File lib/operations.rb, line 140
def end_program
  @computing = false
end
get_call() click to toggle source
# File lib/operations.rb, line 122
def get_call
  y = @stack.pop
  x = @stack.pop
  @stack.push(@code_map.get_operation_at(y, x).ord)
end
get_user_input_char() click to toggle source
# File lib/operations.rb, line 133
def get_user_input_char
  puts 'Befunge needs your input for char!'
  input = $stdin.gets.chomp
  raise 'Must be a single character' unless input.length == 1
  @stack.push(input.ord)
end
get_user_input_int() click to toggle source
# File lib/operations.rb, line 128
def get_user_input_int
  puts 'Befunge needs your input for int!'
  @stack.push(Integer($stdin.gets.chomp))
end
greater_than() click to toggle source
# File lib/operations.rb, line 62
def greater_than
  a = @stack.pop
  b = @stack.pop
  b > a ? @stack.push(1) : @stack.push(0)
end
left_right() click to toggle source
# File lib/operations.rb, line 72
def left_right
  @stack.pop == 0 ? change_dir(:e) : change_dir(:w)
end
logical_not() click to toggle source
# File lib/operations.rb, line 58
def logical_not
  @stack.pop == 0 ? @stack.push(1) : @stack.push(0)
end
operate!(op) click to toggle source
# File lib/operations.rb, line 26
def operate!(op)
  string_mode and return if op == '"'
  push_ascii_value(op) and return if @string_mode
  return if op == ' '
  send(op) and return if MATH_OPS.include?(op.to_sym)
  push_num(op) and return if Integer(op) rescue false
  change_dir(op.to_sym) and return if DIRECTION_OPS.include?(op.to_sym)
  send(OPERATORS_MAP[op])
end
pop_and_discard() click to toggle source
# File lib/operations.rb, line 95
def pop_and_discard
  @stack.pop
end
pop_and_display_char() click to toggle source
# File lib/operations.rb, line 105
def pop_and_display_char
  display_char = @stack.pop.chr
  @return_string << display_char
  print display_char
end
pop_and_display_int() click to toggle source
# File lib/operations.rb, line 99
def pop_and_display_int
  display_int = @stack.pop
  @return_string << display_int.to_s
  print display_int
end
push_ascii_value(op) click to toggle source
# File lib/operations.rb, line 144
def push_ascii_value(op)
  @stack.push(op.ord)
end
push_num(num) click to toggle source
# File lib/operations.rb, line 46
def push_num(num)
  @stack.push(num.to_i)
end
put_call() click to toggle source
# File lib/operations.rb, line 115
def put_call
  y = @stack.pop
  x = @stack.pop
  v = @stack.pop
  @code_map.set_operation(y, x, v.chr)
end
rand_direction() click to toggle source
# File lib/operations.rb, line 68
def rand_direction
  @code_map.pointer.direction = DIRECTIONS.sample
end
string_mode() click to toggle source
# File lib/operations.rb, line 80
def string_mode
  @string_mode = !@string_mode
  true
end
swap_stack_top() click to toggle source
# File lib/operations.rb, line 90
def swap_stack_top
  return if @stack.length < 2
  @stack[-1], @stack[-2] = @stack[-2], @stack[-1]
end
trampoline() click to toggle source
# File lib/operations.rb, line 111
def trampoline
  @code_map.pointer.trampoline = true
end
up_down() click to toggle source
# File lib/operations.rb, line 76
def up_down
  @stack.pop == 0 ? change_dir(:s) : change_dir(:n)
end