class Rucc::Type

Constants

BOOL
CHAR
DOUBLE
ENUM
FLOAT
INT
LDOUBLE
LLONG
LONG
SHORT
UCHAR
UINT
ULLONG
ULONG
USHORT
VOID

Objects representing basic types. All variables will be of one of these types or a derived type from one of them.

Attributes

align[RW]
bitoff[RW]
bitsize[RW]
fields[RW]
hasva[RW]
is_struct[R]
isstatic[RW]
kind[R]
len[RW]
offset[RW]
oldstyle[R]
params[RW]
ptr[RW]
rettype[R]
size[RW]
usig[RW]

Public Class Methods

char_type(enc) click to toggle source

@param [ENC] @return [Type]

# File lib/rucc/type.rb, line 192
def char_type(enc)
  case enc
  when ENC::NONE, ENC::WCHAR
    return Type::INT
  when ENC::CHAR16
    return Type::USHORT
  when ENC::CHAR32
    return Type::UINT
  else
    raise "internal error"
  end
end
copy_incomplete_type(ty) click to toggle source

@param [Type, NilClass] ty @return [Type, NilClass]

# File lib/rucc/type.rb, line 279
def copy_incomplete_type(ty)
  return nil if ty.nil?
  (ty.len == -1) ? ty.dup : ty
end
ensure_assignable!(totype, fromtype) click to toggle source

@param [Type] totype @param [Type] fromtype

# File lib/rucc/type.rb, line 214
def ensure_assignable!(totype, fromtype)
  if (Type.is_arithtype(totype) || (totype.kind == Kind::PTR)) &&
      (Type.is_arithtype(fromtype) || (fromtype.kind == Kind::PTR))
    return
  end
  if is_same_struct?(totype, fromtype)
    return
  end
  raise "incompatible kind: <#{totype}> <#{fromtype}>"
end
is_same_struct?(a, b) click to toggle source

@param [Type] a @param [Type] b @return [Boolean]

# File lib/rucc/type.rb, line 228
def is_same_struct?(a, b)
  if a.kind != b.kind
    return false
  end

  case a.kind
  when Kind::ARRAY
    return a.len == b.len && is_same_struct?(a.ptr, b.ptr)
  when Kind::PTR
    return is_same_struct?(a.ptr, b.ptr)
  when Kind::STRUCT
    if a.is_struct != b.is_struct
      return false
    end
    ka = a.fields.values
    kb = b.fields.values
    if ka.size != kb.size
      return false
    end
    ka.zip(kb).each do |(x, y)|
      if !is_same_struct?(x, y)
        return false
      end
    end
    return true
  else
    return true
  end
end
make_array_type(ty, len) click to toggle source

@param [Type] ty @param [Integer] len @return [Type]

# File lib/rucc/type.rb, line 131
def make_array_type(ty, len)
  if len < 0
    size = -1
  else
    size = ty.size * len
  end
  Type.new(Kind::ARRAY,
           ptr:   ty,
           size:  size,
           len:   len,
           align: ty.align)
end
make_func_type(rettype, paramtypes, has_varargs, oldstyle) click to toggle source

@param [Type] rettype @param [Array] paramtypes @param [Boolean] has_varargs @param [Boolean] oldstyle @return [Type]

# File lib/rucc/type.rb, line 149
def make_func_type(rettype, paramtypes, has_varargs, oldstyle)
  Type.new(Kind::FUNC,
           rettype:  rettype,
           params:   paramtypes,
           hasva:    has_varargs,
           oldstyle: oldstyle)
end
make_numtype(kind, usig) click to toggle source

@param [Kind] kind @param [Boolean] usig @return [Type]

# File lib/rucc/type.rb, line 160
def make_numtype(kind, usig)
  size = align =
    case kind
    when Kind::VOID    then 0
    when Kind::BOOL    then 1
    when Kind::CHAR    then 1
    when Kind::SHORT   then 2
    when Kind::INT     then 4
    when Kind::LONG    then 8
    when Kind::LLONG   then 8
    when Kind::FLOAT   then 4
    when Kind::DOUBLE  then 8
    when Kind::LDOUBLE then 8
    else
      raise "internal error"
    end
  Type.new(kind, size: size, align: align, usig: usig)
end
make_ptr_type(ty) click to toggle source

@param [Type] ty @return [Type]

# File lib/rucc/type.rb, line 121
def make_ptr_type(ty)
  Type.new(Kind::PTR,
           ptr:   ty,
           size:  8,
           align: 8)
end
make_rectype(is_struct) click to toggle source

@param [Boolean] is_struct @return [Type]

# File lib/rucc/type.rb, line 186
def make_rectype(is_struct)
  Type.new(Kind::STRUCT, is_struct: is_struct)
end
make_stub_type() click to toggle source

@return [Type]

# File lib/rucc/type.rb, line 180
def make_stub_type
  Type.new(Kind::STUB, size: 0)
end
new(kind, size: nil, align: nil, usig: nil, isstatic: nil, ptr: nil, len: nil, fields: nil, offset: nil, is_struct: nil, bitoff: nil, bitsize: nil, rettype: nil, params: nil, hasva: nil, oldstyle: nil ) click to toggle source

@param [Kind] kind the kind of type @param [Integer] size @param [Integer] align @param [Boolean] usig true if unsigned @param [Integer] len array length

# File lib/rucc/type.rb, line 15
def initialize(kind,
               size: nil, align: nil, usig: nil, isstatic: nil,
               ptr: nil,                                             # Pointer or Array
               len: nil,                                             # Array
               fields: nil, offset: nil,                             # Struct
               is_struct: nil,                                       # true if Struct, false if Union
               bitoff: nil, bitsize: nil,                            # Bitfield
               rettype: nil, params: nil, hasva: nil, oldstyle: nil  # Function
              )
  @kind = kind
  @size = size; @align = align; @usig = usig; @isstatic = isstatic
  @ptr = ptr                                                                  # Pointer or Array
  @len = len                                                                  # Array
  @fields = fields; @offset = offset                                          # Struct
  @is_struct = is_struct                                                      # true if Struct, false if Union
  @bitoff = bitoff; @bitsize = bitsize                                        # Bitfield
  @rettype = rettype; @params = params; @hasva = hasva; @oldstyle = oldstyle  # Function
end
same_arith_type(t, u) click to toggle source

@param [Type] t @param [Type] u @return [Boolean]

# File lib/rucc/type.rb, line 208
def same_arith_type(t, u)
  t.kind == u.kind && t.usig == u.usig
end
type_compatible?(a, b) click to toggle source

@param [Type] a @param [Type] b @return [Boolean]

# File lib/rucc/type.rb, line 261
def type_compatible?(a, b)
  if a.kind == Kind::STRUCT
    return is_same_struct?(a, b)
  end
  if a.kind != b.kind
    return false
  end
  if a.ptr && b.ptr
    return type_compatible?(a.ptr, b.ptr)
  end
  if is_arithtype(a) && is_arithtype(b)
    return same_arith_type(a, b)
  end
  true
end

Public Instance Methods

decorate_int(name) click to toggle source

@param [String] name @return [String]

# File lib/rucc/type.rb, line 103
def decorate_int(name)
  u = usig ? "u" : ""
  if bitsize && bitsize > 0
    return "#{u}#{name}:#{bitoff}:#{bitoff + bitsize}"
  end
  "#{u}#{name}"
end
replace_by!(tmpl) click to toggle source

@param [Type] tmpl

# File lib/rucc/type.rb, line 112
def replace_by!(tmpl)
  tmpl.instance_variables.each do |ivar|
    self.instance_variable_set(ivar, tmpl.instance_variable_get(ivar))
  end
end
to_s() click to toggle source

@return [String]

# File lib/rucc/type.rb, line 49
def to_s
  to_s_impl({})
end
to_s_impl(dict) click to toggle source

@param [Hash] dict @return [String]

# File lib/rucc/type.rb, line 55
def to_s_impl(dict)
  # TODO(south37) Consider nil case
  # if (!ty)
  #     return "(nil)";
  case kind
  when Kind::VOID    then return "void"
  when Kind::BOOL    then return "_Bool"
  when Kind::CHAR    then return decorate_int("char")
  when Kind::SHORT   then return decorate_int("short")
  when Kind::INT     then return decorate_int("int")
  when Kind::LONG    then return decorate_int("long")
  when Kind::LLONG   then return decorate_int("llong")
  when Kind::FLOAT   then return "float"
  when Kind::DOUBLE  then return "double"
  when Kind::LDOUBLE then return "long double"
  when Kind::PTR
    return "*#{ptr.to_s_impl(dict)}"
  when Kind::ARRAY
    return "[#{len}]#{ptr.to_s_impl(dict)}"
  when Kind::STRUCT
    k = is_struct ? "struct" : "union"
    if !dict[self.object_id].nil?
      return "(#{k})"
    end
    dict[self.object_id] = true
    if fields
      s = "(#{k}"
      fields.each do |_, fieldtype|
        s << " (#{fieldtype.to_s_impl(dict)})"
      end
      s << ")"
      return s
    end
    raise "Must not reach here"  # TODO(south37) Confirm occurance
  when Kind::FUNC
    s = "("
    if params
      s << params.map { |param| param.to_s_impl(dict) }.join(",")
    end
    s << ")=>#{rettype.to_s_impl(dict)}"
    return s
  else
    return "(Unknown ty: #{kind})"
  end
end