class AdLint::Cc1::Branch

Attributes

break_event[R]
ctrlexpr[R]
group[R]

Public Class Methods

new(branch_group, *opts) click to toggle source
# File lib/adlint/cc1/branch.rb, line 41
def initialize(branch_group, *opts)
  @group = branch_group
  @options = opts
  @break_event = nil
  @ctrlexpr = nil
end

Public Instance Methods

add_options(*new_opts) click to toggle source
# File lib/adlint/cc1/branch.rb, line 56
def add_options(*new_opts)
  @options = (@options + new_opts).uniq
  @group.add_options(*new_opts)
end
break_with_break?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 141
def break_with_break?
  @break_event && @break_event.break?
end
break_with_continue?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 145
def break_with_continue?
  @break_event && @break_event.continue?
end
break_with_return?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 149
def break_with_return?
  @break_event && @break_event.return?
end
complemental?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 85
def complemental?
  @options.include?(COMPLEMENTAL)
end
execute(interp, expr = nil) { |self| ... } click to toggle source
# File lib/adlint/cc1/branch.rb, line 89
def execute(interp, expr = nil, &block)
  env.enter_versioning_group if first?
  env.begin_versioning

  @ctrlexpr = ControllingExpression.new(interp, self, expr)
  if ensure_condition(@ctrlexpr)
    @break_event = BreakEvent.catch { yield(self) }
  else
    unless final? && @group.branches.size == 1
      @break_event = BreakEvent.of_return
    end
  end

ensure
  if @ctrlexpr.complexly_compounded? && !complemental?
    # NOTE: Give up value domain thinning of the controlling variables,
    #       because the controlling expression is too complex to manage
    #       value domains correctly.
    # TODO: Study about introducing inter-value-constraints to correctly
    #       manage value domains of controlling variables related with each
    #       other.
    if @group.in_iteration? && !smother_break?
      env.end_versioning(break_with_return? || break_with_break?, true)
    else
      env.end_versioning(break_with_return?, true)
    end
  else
    if @group.in_iteration? && !smother_break?
      env.end_versioning(break_with_return? || break_with_break?, false)
    else
      env.end_versioning(break_with_return?, false)
    end
  end

  if final?
    env.leave_versioning_group(!@group.complete?)
    if @group.complete?
      rethrow_break_event
    end
  end
end
final?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 73
def final?
  @options.include?(FINAL)
end
first?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 69
def first?
  @options.include?(FIRST)
end
implicit_condition?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 81
def implicit_condition?
  @options.include?(IMPLICIT_COND)
end
narrowing?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 61
def narrowing?
  @options.include?(NARROWING)
end
restart_versioning() { || ... } click to toggle source
# File lib/adlint/cc1/branch.rb, line 131
def restart_versioning(&block)
  @ctrlexpr.save_affected_variables
  env.end_versioning(false)
  env.leave_versioning_group(true)
  env.enter_versioning_group
  env.begin_versioning
  yield
  @ctrlexpr.restore_affected_variables
end
smother_break?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 77
def smother_break?
  @options.include?(SMOTHER_BREAK)
end
trunk() click to toggle source
# File lib/adlint/cc1/branch.rb, line 52
def trunk
  @group.trunk
end
widening?() click to toggle source
# File lib/adlint/cc1/branch.rb, line 65
def widening?
  @options.include?(WIDENING)
end

Private Instance Methods

ensure_condition(ctrlexpr) click to toggle source
# File lib/adlint/cc1/branch.rb, line 154
def ensure_condition(ctrlexpr)
  case
  when narrowing?
    ctrlexpr.ensure_true_by_narrowing.commit!
  when widening?
    ctrlexpr.ensure_true_by_widening.commit!
  end
  @group.all_controlling_variables_value_exist?
end
env() click to toggle source
# File lib/adlint/cc1/branch.rb, line 173
def env
  @group.environment
end
rethrow_break_event() click to toggle source
# File lib/adlint/cc1/branch.rb, line 164
def rethrow_break_event
  case
  when @group.all_branches_break_with_break?
    BreakEvent.of_break.throw unless smother_break?
  when @group.all_branches_break_with_return?
    BreakEvent.of_return.throw
  end
end