Class: StructType

Inherits:
Type show all
Defined in:
lib/tecsgen/core/types.rb,
lib/tecsgen/core/generate.rb

Direct Known Subclasses

CStructType

Constant Summary collapse

@@structtype_current_stack =
@member_types_symbol

Symbol : tag が無い時のみ設定 (それ以外では nil)

[]
@@structtype_current_sp =
-1
@@no_struct_tag_num =

tag なし struct

0
@@no_tag_struct_list =
{}

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Type

#cast, #clear_max, #equal?, #get_ID_str, #get_bit_size, #get_original_type, #is_const?, #is_void?, #is_volatile?, #print_info, #print_info_post, print_info_post, reset_print_info, #set_qualifier, #set_scs

Methods inherited from Node

#cdl_error, #cdl_error2, #cdl_error3, #cdl_info, #cdl_info2, #cdl_warning, #cdl_warning2, #get_locale, #locale_str, #set_locale

Constructor Details

#initialize(tag = nil) ⇒ StructType

Returns a new instance of StructType.



745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
# File 'lib/tecsgen/core/types.rb', line 745

def initialize(tag = nil)
  super()
  @tag = tag
  if tag
    @b_hasTag = true
  else
    @b_hasTag = false
  end
  @@structtype_current_sp += 1
  @@structtype_current_stack[@@structtype_current_sp] = self
  @b_has_pointer_member = false
  @b_has_sized_pointer_member = false
  @b_has_unsized_string_member = false
  @member_types_symbol = nil
end

Class Method Details

.end_of_parseObject



855
856
857
858
# File 'lib/tecsgen/core/types.rb', line 855

def self.end_of_parse
  @@structtype_current_stack[@@structtype_current_sp].end_of_parse
  @@structtype_current_sp -= 1
end

.new_member(member_decl) ⇒ Object



781
782
783
# File 'lib/tecsgen/core/types.rb', line 781

def self.new_member(member_decl)
  @@structtype_current_stack[@@structtype_current_sp].new_member(member_decl)
end

.set_define(b_define) ⇒ Object



761
762
763
# File 'lib/tecsgen/core/types.rb', line 761

def self.set_define(b_define)
  @@structtype_current_stack[@@structtype_current_sp].set_define(b_define)
end

Instance Method Details

#checkObject

意味的誤りがあれば、文字列を返す



799
800
801
# File 'lib/tecsgen/core/types.rb', line 799

def check # 意味的誤りがあれば、文字列を返す
  nil
end

#check_init(locale, ident, initializer, kind, attribute = nil) ⇒ Object

mikan Float 型の C_EXP 対応 (generate.rb にも変更必要)



818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
# File 'lib/tecsgen/core/types.rb', line 818

def check_init(locale, ident, initializer, kind, attribute = nil)
  st = Namespace.find_tag(@tag)
  if st.nil?
    cdl_error2(locale, "T1023 struct $1: not defined", @tag)
    return
  end

  # 初期化子が式の場合、型(タグ)が一致するかチェック
  if initializer.instance_of?(Expression)
    t = initializer.get_type(attribute)
    # print "Check init #{t.class} #{t.get_name}\n"
    if !t.is_a?(StructType)
      if t
        str = t.get_type_str
      else
        str = "unknown"
      end
      cdl_error2(locale, "T1038 $1: initializer type mismatch. '$2' & '$3'", ident, get_type_str, str)
    elsif @tag != t.get_name
      cdl_error2(locale, "T1039 $1: struct tag mismatch $2 and $3", ident, @tag, t.get_name)
    end
    initializer = initializer.eval_const(attribute)
  end

  if initializer.instance_of?(Array)
    i = 0
    st.get_members_decl.get_items.each {|d|
      if initializer[i]
        d.get_type.check_init(locale, "#{ident}.#{d.get_identifier}", initializer[i], kind)
      end
      i += 1
    }
  else
    cdl_error2(locale, "T1024 $1: unsuitable initializer for struct", ident)
  end
end

#check_struct_tag(kind) ⇒ Object

構造体のタグをチェック

declarator の時点でチェックする
kind

Decl の @kind を参照



806
807
808
809
810
811
812
813
814
815
# File 'lib/tecsgen/core/types.rb', line 806

def check_struct_tag(kind)
  if @tag.nil?
    return
  end

  st = Namespace.find_tag(@tag)
  if st.nil?
    cdl_error("T1022 struct $1: not defined", @tag)
  end
end

#end_of_parseObject



860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
# File 'lib/tecsgen/core/types.rb', line 860

def end_of_parse
  if @members_decl.nil? # @b_define = false またはメンバーのない構造体(エラー)
    return
  end
  @members_decl.get_items.each{|md|
    size = md.get_size_is
    if size
      val = size.eval_const(@members_decl)
      if val.nil?
        type = size.get_type(@members_decl)
        if !type.is_a?(IntType)
          cdl_error("T1025 size_is argument is not integer type")
        end
      end
    end
    count = md.get_count_is
    if count
      val = count.eval_const(@members_decl)
      if val.nil?
        type = count.get_type(@members_decl)
        if !type.is_a?(IntType)
          cdl_error("T1026 count_is argument is not integer type")
        end
      end
    end
    string = md.get_string
    if string == -1
      # 長さ指定なし
    elsif string
      val = string.eval_const(@members_decl)
      if val.nil?
        type = string.get_type(@members_decl)
        if !type.is_a?(IntType)
          cdl_error("T1027 string argument is not integer type")
        end
      end
    end
  }

  if @tag.nil?
    @member_types_symbol = get_member_types_symbol
    # print "member_types_symbol = #{get_member_types_symbol}\n"
    if @@no_tag_struct_list[@member_types_symbol]
      @tag = @@no_tag_struct_list[@member_types_symbol]
    else
      @tag = :"TAG_#{@@no_struct_tag_num}_TECS_internal__"
    @@no_struct_tag_num += 1
      @@no_tag_struct_list[@member_types_symbol] = @tag
      Namespace.new_structtype(self)
    end
  else
    if @b_define
      Namespace.new_structtype(self)
    end
  end
end

#gen_gh(f) ⇒ Object



957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
# File 'lib/tecsgen/core/generate.rb', line 957

def gen_gh(f)
#    print "StructType.gen_gh\n"
#    show_tree 1

  if !@b_define
    return
  end

  f.print "struct #{@tag} {\n"

  @members_decl.get_items.each{|i|
    f.printf("                %-14s %s%s;\n", i.get_type.get_type_str, i.get_name, i.get_type.get_type_str_post)
  }

  f.print "};\n"
end

#get_member_types_symbolObject



1009
1010
1011
1012
1013
1014
1015
# File 'lib/tecsgen/core/types.rb', line 1009

def get_member_types_symbol
  mts = ""
  @members_decl.get_items.each {|member|
    mts += member.get_type.get_type_str + member.get_type.get_type_str_post + ";"
  }
  return mts.to_sym
end

#get_members_declObject



946
947
948
949
950
951
952
953
954
955
# File 'lib/tecsgen/core/types.rb', line 946

def get_members_decl
  return @members_decl if @members_decl

  st = Namespace.find_tag(@tag)
  if st
    return st.get_members_decl
  end

  return nil
end

#get_nameObject



917
918
919
# File 'lib/tecsgen/core/types.rb', line 917

def get_name
  @tag
end

#get_type_strObject

mikan struct get_type_str



921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
# File 'lib/tecsgen/core/types.rb', line 921

def get_type_str # mikan struct get_type_str
  str = super

  if @b_hasTag
    # typedef struct tag StructType; の形式の場合
    # struct の本体は、別に生成される
    return "#{str}struct #{@tag}"

  else
    # typedef struct { int a; } StructType; の形式の場合
    str += "struct {"
    @members_decl.get_items.each{|i|
      str += sprintf("%s %s%s;", i.get_type.get_type_str, i.get_name, i.get_type.get_type_str_post)
    }
    str += "} "

    return str

  end
end

#get_type_str_postObject



942
943
944
# File 'lib/tecsgen/core/types.rb', line 942

def get_type_str_post
  ""
end

#has_pointer?Boolean

Returns:

  • (Boolean)


957
958
959
960
961
962
963
# File 'lib/tecsgen/core/types.rb', line 957

def has_pointer?
  if @definition
    return @definition.has_pointer?
  else
    return @b_has_pointer_member
  end
end

#has_sized_pointer?Boolean

Returns:

  • (Boolean)


965
966
967
968
969
970
971
# File 'lib/tecsgen/core/types.rb', line 965

def has_sized_pointer?
  if @definition
    return @definition.has_sized_pointer?
  else
    return @b_has_sized_pointer_member
  end
end

#has_unsized_string?Boolean

Returns:

  • (Boolean)


973
974
975
976
977
978
979
# File 'lib/tecsgen/core/types.rb', line 973

def has_unsized_string?
  if @definition
    return @definition.has_unsized_string?
  else
    return @b_has_unsized_string_member
  end
end

#new_member(member_decl) ⇒ Object



785
786
787
788
789
790
791
792
793
794
795
796
797
# File 'lib/tecsgen/core/types.rb', line 785

def new_member(member_decl)
  member_decl.set_owner self # Decl (StructType)
  @members_decl.add_item(member_decl)
  if member_decl.get_type.has_pointer?
    @b_has_pointer_member = true
  end
  if member_decl.get_type.has_sized_pointer?
    @b_has_sized_pointer_member = true
  end
  if member_decl.get_type.has_unsized_string?
    @b_has_unsized_string_member = true
  end
end

#same?(another) ⇒ Boolean

同じ構造体かどうかチェックする

tag のチェックは行わない すべてのメンバの名前と型が一致することを確認する

Returns:

  • (Boolean)


984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
# File 'lib/tecsgen/core/types.rb', line 984

def same?(another)
  md = another.get_members_decl
  if @members_decl.nil? || md.nil?
    return false
  end

  md1 = @members_decl.get_items
  md2 = md.get_items
  if md1.length != md2.length
    return false
  end

  i = 0
  while i < md1.length
    if md1[i].get_name != md2[i].get_name ||
        md1[i].get_type.get_type_str != md2[i].get_type.get_type_str ||
        md1[i].get_type.get_type_str_post != md2[i].get_type.get_type_str_post
      return false
    end
    i += 1
  end

  return true
end

#set_define(b_define) ⇒ Object



765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
# File 'lib/tecsgen/core/types.rb', line 765

def set_define(b_define)
  @b_define = b_define
  if @b_define
    @members_decl = NamedList.new(nil, "in struct #{@tag}")
    # if @tag then    登録タイミングを終わりに変更 V1.0.2.19
    #  Namespace.new_structtype( self )
    # end
  else
    @definition = Namespace.find_tag(@tag)
    # check_struct_tag に移す V1.0.2.19
    # if @definition == nil then
    #  cdl_error( "T1021 \'$1\': struct not defined" , @tag )
    # end
  end
end

#show_tree(indent) ⇒ Object



1017
1018
1019
1020
1021
1022
1023
1024
# File 'lib/tecsgen/core/types.rb', line 1017

def show_tree(indent)
  indent.times { print "  " }
  puts "StructType tag: #{@tag} qualifier=#{@qualifier} has_pointer=#{@b_has_pointer_member} #{locale_str}"
  super(indent + 1)
  if @b_define
    @members_decl.show_tree(indent + 1)
  end
end