module AdLint::Cc1::ConstantEvaluator

Public Instance Methods

eval_constant(const_spec) click to toggle source

NOTE: Host class of this module must include InterpreterMediator.

# File lib/adlint/cc1/const.rb, line 40
def eval_constant(const_spec)
  eval_as_integer_constant(const_spec.constant.value) or
  eval_as_floating_constant(const_spec.constant.value) or
  eval_as_character_constant(const_spec.constant.value)
end

Private Instance Methods

eval_as_character_constant(str) click to toggle source
# File lib/adlint/cc1/const.rb, line 168
def eval_as_character_constant(str)
  if str =~ /\A(L?)'(.*)'\z/i
    case $2.length
    when 0
      char_code = 0
    when 1
      char_code = $2[0].ord
    else
      char_code = $2[0] == "\\" ? EscapeSequence.new($2).value : $2[0].ord
    end

    if $1 == "L"
      create_tmpvar(wchar_t, scalar_value_of(char_code))
    else
      create_tmpvar(int_t, scalar_value_of(char_code))
    end
  else
    nil
  end
end
eval_as_decimal_integer_constant_unsuffixed(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 189
def eval_as_decimal_integer_constant_unsuffixed(i)
  case
  when int_range.include?(i)
    create_tmpvar(int_t, scalar_value_of(i))
  when long_int_range.include?(i)
    create_tmpvar(long_int_t, scalar_value_of(i))
  when long_long_int_range.include?(i)
    create_tmpvar(long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_decimal_integer_constant_with_l(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 233
def eval_as_decimal_integer_constant_with_l(i)
  case
  when long_int_range.include?(i)
    create_tmpvar(long_int_t, scalar_value_of(i))
  when long_long_int_range.include?(i)
    create_tmpvar(long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_decimal_integer_constant_with_ll(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 273
def eval_as_decimal_integer_constant_with_ll(i)
  case
  when long_long_int_range.include?(i)
    create_tmpvar(long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_decimal_integer_constant_with_u(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 211
def eval_as_decimal_integer_constant_with_u(i)
  case
  when unsigned_int_range.include?(i)
    create_tmpvar(unsigned_int_t, scalar_value_of(i))
  when unsigned_long_int_range.include?(i)
    create_tmpvar(unsigned_long_int_t, scalar_value_of(i))
  when unsigned_long_long_int_range.include?(i)
    create_tmpvar(unsigned_long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_decimal_integer_constant_with_ul(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 253
def eval_as_decimal_integer_constant_with_ul(i)
  case
  when unsigned_long_int_range.include?(i)
    create_tmpvar(unsigned_long_int_t, scalar_value_of(i))
  when unsigned_long_long_int_range.include?(i)
    create_tmpvar(unsigned_long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_decimal_integer_constant_with_ull(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 291
def eval_as_decimal_integer_constant_with_ull(i)
  case
  when unsigned_long_long_int_range.include?(i)
    create_tmpvar(unsigned_long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_floating_constant(str) click to toggle source
# File lib/adlint/cc1/const.rb, line 149
def eval_as_floating_constant(str)
  # TODO: Must implement hexadecimal-floating-constant evaluation.
  case str
  when /\A([0-9]*\.[0-9]*E[+-]?[0-9]+)\z/i,
       /\A([0-9]+\.?E[+-]?[0-9]+)\z/i,
       /\A([0-9]*\.[0-9]+|[0-9]+\.)\z/
    return create_tmpvar(double_t, scalar_value_of($1.to_f))
  when /\A([0-9]*\.[0-9]*E[+-]?[0-9]+)F\z/i,
       /\A([0-9]+\.?E[+-]?[0-9]+)F\z/i,
       /\A([0-9]*\.[0-9]+|[0-9]+\.)F\z/i
    return create_tmpvar(float_t, scalar_value_of($1.to_f))
  when /\A([0-9]*\.[0-9]*E[+-]?[0-9]+)L\z/i,
       /\A([0-9]+\.?E[+-]?[0-9]+)L\z/i,
       /\A([0-9]*\.[0-9]+|[0-9]+\.)L\z/i
    return create_tmpvar(long_double_t, scalar_value_of($1.to_f))
  end
  nil
end
eval_as_integer_constant(str) click to toggle source
# File lib/adlint/cc1/const.rb, line 47
def eval_as_integer_constant(str)
  # NOTE: The ISO C99 standard says;
  #
  # 6.4.4.1 Integer constants
  #
  # 5 The type of an integer constant is the first of the corresponding
  #   list in which its value can be represented.
  #
  #               |        decimal         |  octal or hexadecimal
  #   ------------+------------------------+------------------------
  #   unsuffixed  | int                    | int
  #               | long int               | unsigned int
  #               | long long int          | long int
  #               |                        | unsigned long int
  #               |                        | long long int
  #               |                        | unsigned long long int
  #   ------------+------------------------+------------------------
  #    u or U     | unsigned int           | unsigned int
  #               | unsigned long int      | unsigned long int
  #               | unsigned long long int | unsigned long long int
  #   ------------+------------------------+------------------------
  #    l or L     | long int               | long int
  #               | long long int          | unsigned long int
  #               |                        | long long int
  #               |                        | unsigned long long int
  #   ------------+------------------------+------------------------
  #    u or U and | unsigned long int      | unsigned long int
  #    l or L     | unsigned long long int | unsigned long long int
  #   ------------+------------------------+------------------------
  #    ll or LL   | long long int          | long long int
  #               |                        | unsigned long long int
  #   ------------+------------------------+------------------------
  #    u or U and | unsigned long long int | unsigned long long int
  #    ll or LL   |                        |

  # NOTE: For binary constants.
  case str
  when /\A0b([01]+)(?:ULL|LLU)\z/i
    return eval_as_non_decimal_integer_constant_with_ull($1.to_i(2))
  when /\A0b([01]+)LL\z/i
    return eval_as_non_decimal_integer_constant_with_ll($1.to_i(2))
  when /\A0b([01]+)(?:UL|LU)\z/i
    return eval_as_non_decimal_integer_constant_with_ul($1.to_i(2))
  when /\A0b([01]+)L\z/i
    return eval_as_non_decimal_integer_constant_with_l($1.to_i(2))
  when /\A0b([01]+)U\z/i
    return eval_as_non_decimal_integer_constant_with_u($1.to_i(2))
  when /\A0b([01]+)\z/i
    return eval_as_non_decimal_integer_constant_unsuffixed($1.to_i(2))
  end

  # NOTE: For octal constants.
  case str
  when /\A0([0-9]+)(?:ULL|LLU)\z/i
    return eval_as_non_decimal_integer_constant_with_ull($1.to_i(8))
  when /\A0([0-9]+)LL\z/i
    return eval_as_non_decimal_integer_constant_with_ll($1.to_i(8))
  when /\A0([0-9]+)(?:UL|LU)\z/i
    return eval_as_non_decimal_integer_constant_with_ul($1.to_i(8))
  when /\A0([0-9]+)L\z/i
    return eval_as_non_decimal_integer_constant_with_l($1.to_i(8))
  when /\A0([0-9]+)U\z/i
    return eval_as_non_decimal_integer_constant_with_u($1.to_i(8))
  when /\A0([0-9]+)\z/
    return eval_as_non_decimal_integer_constant_unsuffixed($1.to_i(8))
  end

  # NOTE: For decimal constants.
  case str
  when /\A([0-9]+)(?:ULL|LLU)\z/i
    return eval_as_decimal_integer_constant_with_ull($1.to_i(10))
  when /\A([0-9]+)LL\z/i
    return eval_as_decimal_integer_constant_with_ll($1.to_i(10))
  when /\A([0-9]+)(?:UL|LU)\z/i
    return eval_as_decimal_integer_constant_with_ul($1.to_i(10))
  when /\A([0-9]+)L\z/i
    return eval_as_decimal_integer_constant_with_l($1.to_i(10))
  when /\A([0-9]+)U\z/i
    return eval_as_decimal_integer_constant_with_u($1.to_i(10))
  when /\A([0-9]+)\z/
    return eval_as_decimal_integer_constant_unsuffixed($1.to_i(10))
  end

  # NOTE: For hexadecimal constants.
  case str
  when /\A0x([0-9A-F]+)(?:ULL|LLU)\z/i
    return eval_as_non_decimal_integer_constant_with_ull($1.to_i(16))
  when /\A0x([0-9A-F]+)LL\z/i
    return eval_as_non_decimal_integer_constant_with_ll($1.to_i(16))
  when /\A0x([0-9A-F]+)(?:UL|LU)\z/i
    return eval_as_non_decimal_integer_constant_with_ul($1.to_i(16))
  when /\A0x([0-9A-F]+)L\z/i
    return eval_as_non_decimal_integer_constant_with_l($1.to_i(16))
  when /\A0x([0-9A-F]+)U\z/i
    return eval_as_non_decimal_integer_constant_with_u($1.to_i(16))
  when /\A0x([0-9A-F]+)\z/i
    return eval_as_non_decimal_integer_constant_unsuffixed($1.to_i(16))
  end

  nil
end
eval_as_non_decimal_integer_constant_unsuffixed(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 309
def eval_as_non_decimal_integer_constant_unsuffixed(i)
  case
  when int_range.include?(i)
    create_tmpvar(int_t, scalar_value_of(i))
  when unsigned_int_range.include?(i)
    create_tmpvar(unsigned_int_t, scalar_value_of(i))
  when long_int_range.include?(i)
    create_tmpvar(long_int_t, scalar_value_of(i))
  when unsigned_long_int_range.include?(i)
    create_tmpvar(unsigned_long_int_t, scalar_value_of(i))
  when long_long_int_range.include?(i)
    create_tmpvar(long_long_int_t, scalar_value_of(i))
  when unsigned_long_long_int_range.include?(i)
    create_tmpvar(unsigned_long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_non_decimal_integer_constant_with_l(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 359
def eval_as_non_decimal_integer_constant_with_l(i)
  case
  when long_int_range.include?(i)
    create_tmpvar(long_int_t, scalar_value_of(i))
  when unsigned_long_int_range.include?(i)
    create_tmpvar(unsigned_long_int_t, scalar_value_of(i))
  when long_long_int_range.include?(i)
    create_tmpvar(long_long_int_t, scalar_value_of(i))
  when unsigned_long_long_int_range.include?(i)
    create_tmpvar(unsigned_long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_non_decimal_integer_constant_with_ll(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 403
def eval_as_non_decimal_integer_constant_with_ll(i)
  case
  when long_long_int_range.include?(i)
    create_tmpvar(long_long_int_t, scalar_value_of(i))
  when unsigned_long_long_int_range.include?(i)
    create_tmpvar(unsigned_long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_non_decimal_integer_constant_with_u(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 337
def eval_as_non_decimal_integer_constant_with_u(i)
  case
  when unsigned_int_range.include?(i)
    create_tmpvar(unsigned_int_t, scalar_value_of(i))
  when unsigned_long_int_range.include?(i)
    create_tmpvar(unsigned_long_int_t, scalar_value_of(i))
  when unsigned_long_long_int_range.include?(i)
    create_tmpvar(unsigned_long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_non_decimal_integer_constant_with_ul(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 383
def eval_as_non_decimal_integer_constant_with_ul(i)
  case
  when unsigned_long_int_range.include?(i)
    create_tmpvar(unsigned_long_int_t, scalar_value_of(i))
  when unsigned_long_long_int_range.include?(i)
    create_tmpvar(unsigned_long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
eval_as_non_decimal_integer_constant_with_ull(i) click to toggle source
# File lib/adlint/cc1/const.rb, line 423
def eval_as_non_decimal_integer_constant_with_ull(i)
  case
  when unsigned_long_long_int_range.include?(i)
    create_tmpvar(unsigned_long_long_int_t, scalar_value_of(i))
  else
    # NOTE: The ISO C99 standard says;
    #
    # 6.4.4.1 Integer constants
    #
    # 6 If an integer constant cannot be represented by any type in its
    #   list and has no extended integer type, then the integer constant
    #   has no type.
    #
    # NOTE: Use ExtendedBigIntType for unrepresentable integer constants.
    create_tmpvar(extended_big_int_t, scalar_value_of(i))
  end
end
int_range() click to toggle source
# File lib/adlint/cc1/const.rb, line 441
def int_range
  int_t.min..int_t.max
end
long_int_range() click to toggle source
# File lib/adlint/cc1/const.rb, line 445
def long_int_range
  long_int_t.min..long_int_t.max
end
long_long_int_range() click to toggle source
# File lib/adlint/cc1/const.rb, line 449
def long_long_int_range
  long_long_int_t.min..long_long_int_t.max
end
unsigned_int_range() click to toggle source
# File lib/adlint/cc1/const.rb, line 453
def unsigned_int_range
  unsigned_int_t.min..unsigned_int_t.max
end
unsigned_long_int_range() click to toggle source
# File lib/adlint/cc1/const.rb, line 457
def unsigned_long_int_range
  unsigned_long_int_t.min..unsigned_long_int_t.max
end
unsigned_long_long_int_range() click to toggle source
# File lib/adlint/cc1/const.rb, line 461
def unsigned_long_long_int_range
  unsigned_long_long_t.min..unsigned_long_long_t.max
end