class Gobstones::Lang::Commands::RepeatWith

Attributes

cmd_block[R]
range_max[R]
range_min[R]
var_name[R]

Public Class Methods

new(var_name, range_min, range_max, cmd_block) click to toggle source
# File lib/gobstones/lang/commands/repeat_with.rb, line 18
def initialize(var_name, range_min, range_max, cmd_block)
  @var_name = var_name
  @range_min = range_min
  @range_max = range_max
  @cmd_block = cmd_block
end

Public Instance Methods

equality_attributes() click to toggle source
# File lib/gobstones/lang/commands/repeat_with.rb, line 25
def equality_attributes
  %i[var_name range_min range_max cmd_block]
end
evaluate(context) click to toggle source
# File lib/gobstones/lang/commands/repeat_with.rb, line 29
def evaluate(context)
  validate_range_values context
  validate_index_variable_not_defined context
  while_based_equivalent_cmd.evaluate context
  clear_index_variable_from context
end

Private Instance Methods

clear_index_variable_from(context) click to toggle source
# File lib/gobstones/lang/commands/repeat_with.rb, line 38
def clear_index_variable_from(context)
  context.clear var_name
end
validate_index_variable_not_defined(context) click to toggle source
# File lib/gobstones/lang/commands/repeat_with.rb, line 47
def validate_index_variable_not_defined(context)
  raise Runner::GobstonesRuntimeError, "index variable can't be used because it's already defined" \
  if context.has_variable_named?(var_name.name)
end
validate_range_values(context) click to toggle source
# File lib/gobstones/lang/commands/repeat_with.rb, line 42
def validate_range_values(context)
  raise Runner::GobstonesTypeError, "types don't match in range values" \
  unless range_min.evaluate(context).same_type_as(range_max.evaluate(context))
end
while_based_equivalent_cmd() click to toggle source
# File lib/gobstones/lang/commands/repeat_with.rb, line 52
def while_based_equivalent_cmd
  #
  # repeatWith var in min..max block
  #        is equivalent to
  # if (min <= max) { var := min; while (var < max) { block; var := siguiente(var) }; block }
  #
  assign_cmd = SingleAssignment.new(var_name, range_min)
  while_cond = LessThan.new(var_name, range_max)
  increment = SingleAssignment.new(var_name, Siguiente.new(var_name))
  while_block = CommandBlock.new([cmd_block, increment])
  while_cmd = While.new(while_cond, while_block)
  if_cond = LessEqual.new(range_min, range_max)
  If.new(if_cond, CommandBlock.new([assign_cmd, while_cmd, cmd_block]))
end