Module: CType

Included in:
CArrayType, CBoolType, CDefinedType, CEnumType, CFloatType, CFuncType, CIntType, CPtrType, CStructType, CVoidType
Defined in:
lib/tecsgen/core/ctypes.rb

Overview

CType は C_parser で定義される型を扱う CIntType, CFloatType などに include するもの CIntType は IntType を継承するなど、C の型では TECS の型を継承する

Instance Method Summary collapse

Instance Method Details

#merge(another) ⇒ Object

構文要素 type_specifier が複数指定されている場合に merge する

merge は const(CIntType) unsigned(CIntTtype), long(CIntType), などと他の型をマージする const, unsigned, long などは、単体で int (CIntType) 型になりうる

mikan C の文法を厳密にはチェックしていない long struct 等もできてしまう



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/tecsgen/core/ctypes.rb', line 48

def merge(another)
  # p "self: #{self.class} kind_of( IntType ): #{self.kind_of?( IntType )}  another: #{another.class}"

  # signed, unsigned が Symbol として来る事は無くなった
  # if another.instance_of? Symbol then
  #   # ここで Symbol は :SIGNED, :UNSIGNED のいずれか
  #
  #   # CIntType か?
  #   if self.instance_of? CIntType then
  #     self.set_sign another
  #     return self
  #   else
  #     cdl_error( "C1001 $1: mismatch, suitable for int types" , another )
  #     return self
  #   end
  # elsif self.instance_of?( CIntType ) && another.instance_of?( CIntType )then
  if self.instance_of?(CIntType) && another.instance_of?(CIntType)
    if another.get_bit_size != -3
      if @bit_size == -4 && another.get_bit_size == -4
        @bit_size = -5 # long long
      else
        # self は int 型、another の bit_size が (int 以外であれば)そちらにする
        # mikan 上記以外で 両方 -3 でなければ、本来エラー
        @bit_size = another.get_bit_size
      end
    end

    if another.get_sign
      # another で sign が指定されていれば、そちらのものを採用する mikan 矛盾のチェック
      @sign = another.get_sign
    end

#      if another.get_qualifier then
#        # another で qualifier が指定されていれば、そちらのものを採用する mikan 矛盾のチェック
#        @qualifier = another.get_qualifier
#      end
    if another.is_const?
      @b_const = true
    end
    if another.is_volatile?
      @b_volatile = true
    end

    return self
  elsif self.instance_of?(CIntType)
    return another.merge self
  elsif self.instance_of?(CDefinedType)
    # mikan unsigned などとの merge の不正検出
    if another.is_const?
      @b_const = true
    end
    if another.is_volatile?
      @b_volatile = true
    end

#      if self.get_type.get_type_str == another.get_type_str &&
#          self.get_type.get_type_str_post == another.get_type_str_post
#        # p "typedef #{another.get_type_str} #{self.get_type_str}#{another.get_type_str_post} ;"
#      else
#        cdl_error( "C1002 $1 not compatible with previous one $2" , self.get_type_str, another.get_type_str )
#      end
    return self
  elsif self.instance_of?(CStructType)
    if another.is_const?
      @b_const = true
    end
    if another.is_volatile?
      @b_volatile = true
    end
    return self
  elsif self.instance_of?(CFloatType)
    # mikan long double
    #   TECS には long double を表現する手段がない (double80_t を定義すればよいか?)
#      cdl_warning( "C1003 $1 & $2 incompatible (\'long double\' is not supported.). Treated as $3." , self.class, another.class, self.class )
#      cdl_warning( "W9999 $1 & $2 incompatible (\'long double\' is not supported.). Treated as $3." , self.get_type_str, another.get_type_str, self.get_type_str )
    self.to_long
    return self
  else
    raise "merge: unknown type"
  end
end

#set_qualifier(qual) ⇒ Object

qualifier を設定する

元の Type クラスでは矛盾チェックしない(TECSの本来の文法では重複指定できないため)


132
133
134
135
136
137
# File 'lib/tecsgen/core/ctypes.rb', line 132

def set_qualifier(qual)
  if @qualifier
    cdl_error("C1004 $1: qualifier redefined. previous one: $2", qual, @qualifier)
  end
  super(qual)
end