class AdLint::Cc1::Interpreter

Attributes

environment[R]
type_resolver[R]

Public Class Methods

new(type_tbl, env = nil) click to toggle source
# File lib/adlint/cc1/interp.rb, line 77
def initialize(type_tbl, env = nil)
  @type_table    = type_tbl
  @environment   = env || Environment.new(type_tbl)
  @type_resolver = DynamicTypeResolver.new(type_tbl, self)

  @sub_interpreters = [
    DeclarationInterpreter.new(self),
    ParameterDefinitionInterpreter.new(self),
    FunctionInterpreter.new(self),
    SwitchStatementInterpreter.new(self),
    StatementInterpreter.new(self),
    ExpressionInterpreter.new(self)
  ]

  @options_stack = []

  # NOTE: Active (executing) function may be nested if the nested
  #       function-definition of the GCC extension is used.
  @active_function_stack = []
end

Private Class Methods

def_plugin_and_notifier(event_name, *arg_names) click to toggle source
# File lib/adlint/cc1/interp.rb, line 109
    def self.def_plugin_and_notifier(event_name, *arg_names)
      class_eval <<-EOS
        def_plugin :on_#{event_name}
        def notify_#{event_name}(#{arg_names.join(",")})
          unless quiet?
            on_#{event_name}.invoke(#{arg_names.join(",")})
          end
        end
      EOS
    end

Public Instance Methods

_active_function() click to toggle source
# File lib/adlint/cc1/interp.rb, line 497
def _active_function
  # NOTE: This method is called only from
  #       StatementInterpreter#visit_return_statement.
  # NOTE: To convert returning object, StatementInterpreter must have
  #       knowledge about conversion destination type.
  @active_function_stack.last
end
_enter_function(fun_def) click to toggle source
# File lib/adlint/cc1/interp.rb, line 505
def _enter_function(fun_def)
  # NOTE: This method is called only from FunctionInterpreter.
  @active_function_stack.push(fun_def)
end
_leave_function(*) click to toggle source
# File lib/adlint/cc1/interp.rb, line 510
def _leave_function(*)
  # NOTE: This method is called only from FunctionInterpreter.
  @active_function_stack.pop
end
_quiet=(quiet) click to toggle source
# File lib/adlint/cc1/interp.rb, line 475
def _quiet=(quiet)
  # NOTE: This method is called only from ControllingExpression.
  if quiet
    cur_opts.add(QUIET)
  else
    cur_opts.delete(QUIET)
  end
end
_without_side_effects=(without_side_effects) click to toggle source
# File lib/adlint/cc1/interp.rb, line 488
def _without_side_effects=(without_side_effects)
  # NOTE: This method is called only from ExpressionEvaluator.
  if without_side_effects
    cur_opts.add(WITHOUT_SIDE_EFFECTS)
  else
    cur_opts.delete(WITHOUT_SIDE_EFFECTS)
  end
end
execute(node, *opts) click to toggle source
# File lib/adlint/cc1/interp.rb, line 454
def execute(node, *opts)
  @options_stack.push(cur_opts + opts)
  if without_side_effects?
    rslt = nil
    branched_eval(nil, FINAL) do
      rslt = node.accept(interpreter_for(node))
      # NOTE: To rollback latest variable value versions.
      BreakEvent.of_return.throw
    end
  else
    rslt = node.accept(interpreter_for(node))
  end
  rslt
ensure
  @options_stack.pop
end
quiet?() click to toggle source
# File lib/adlint/cc1/interp.rb, line 471
def quiet?
  cur_opts.include?(QUIET)
end
without_side_effects?() click to toggle source
# File lib/adlint/cc1/interp.rb, line 484
def without_side_effects?
  cur_opts.include?(WITHOUT_SIDE_EFFECTS)
end

Private Instance Methods

cur_opts() click to toggle source
# File lib/adlint/cc1/interp.rb, line 522
def cur_opts
  @options_stack.last || Set.new
end
interpreter() click to toggle source
# File lib/adlint/cc1/interp.rb, line 526
def interpreter
  # NOTE: This method is of the requirement for including
  #       InterpreterMediator.
  self
end
interpreter_for(node) click to toggle source
# File lib/adlint/cc1/interp.rb, line 516
def interpreter_for(node)
  @sub_interpreters.find do |interp|
    node.kind_of?(interp.target_node_class)
  end
end