Class: Cell

Inherits:
NSBDNode show all
Includes:
PluginModule
Defined in:
lib/tecsgen/core/componentobj.rb,
lib/tecsflow.rb,
lib/tecsgen/core/gen_xml.rb,
lib/tecsgen/core/tecsinfo.rb,
lib/tecsgen/core/unjoin_plugin.rb

Overview

< Nestable

Constant Summary collapse

@@printed_func_nsp_list =

function path in CDL like format

{}
@@printed_cell_list =
{}
@@printed_celltype_list =
{}
@@nest_stack_index =
-1
@@nest_stack =
[]
@@current_object =
nil
@@cell_list =

定義されたすべてのセル(出現順. namespace に影響されない)

[]
@@cell_list2 =

composite の内部のセルを含まない

[]

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PluginModule

gen_plugin_post_code, #generate_and_parse, #load_plugin

Methods inherited from NSBDNode

#get_namespace, #get_namespace_path, #is_imported?, #set_namespace_path

Methods inherited from BDNode

#get_owner, #set_owner

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(ct_path, in_composite = false) ⇒ Cell

Returns a new instance of Cell.



1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
# File 'lib/tecsgen/core/componentobj.rb', line 1443

def initialize(ct_path, in_composite = false)
  super()
  @region = Region.get_current

  # celltype のplugin/存在をチェック
  object = Namespace.find(ct_path) # 1
  if object.nil?
    # mikan celltype の名前が不完全 "::ct1ct2" になる
    cdl_error("S1027 \'$1\' celltype not found", ct_path.get_path_str)
  elsif !object.instance_of?(Celltype) && !object.instance_of?(CompositeCelltype)
    # mikan celltype の名前が不完全
    cdl_error("S1028 \'$1\' not celltype", ct_path.get_path_str)
  else
    @celltype = object
  end

  @in_composite = in_composite
  if @in_composite
    @compositecelltypejoin_list = NamedList.new(nil, "in cell '#{@name}'")
    @plugin = nil
  else
    @compositecelltypejoin_list = nil
    @plugin = Generator.get_plugin
  end

  @@current_object = self
  @b_defined = false
  @b_prototype = false
  @f_ref     = false
  @f_cloned  = false
  @alloc_list = []
  @id = -1
  @id_specified = nil
  @b_duplicate = false
  @b_checked = false
  @require_joined_list = {}
  @entry_array_max_subscript = {}
  @referenced_port_list = {}
  @restrict_list = {}
  @restrict_list2 = {}
  @b_restrict_referenced = false
  @b_post_code_generated = false

  @cell_list = {}
  @cell_list2 = []
end

Class Method Details

.create_reverse_joinObject

Cell# reverse_join を生成する



2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
# File 'lib/tecsgen/core/componentobj.rb', line 2534

def self.create_reverse_join
  @@cell_list.each{|c|
    ct = c.get_celltype
    # if c.is_generate? then
    if ct
      c.create_reverse_join
    end
    # end
  }
end

.create_reverse_require_joinObject

Cell# reverse_require_join を生成する



2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
# File 'lib/tecsgen/core/componentobj.rb', line 2546

def self.create_reverse_require_join
  @@cell_list2.each{|c|
    ct = c.get_celltype
    # if c.is_generate? then
      if ct
        # self への呼び口側の結合を生成
        ct.create_reverse_require_join c
      end
    # end
  }
end

.end_of_parse(f_def) ⇒ Object



1809
1810
1811
1812
1813
1814
# File 'lib/tecsgen/core/componentobj.rb', line 1809

def self.end_of_parse(f_def)
  cell = @@current_object
  cell.end_of_parse f_def
  @@current_object = nil
  return cell
end

.external_join(internal_cell_elem_name, export_name, b_composite) ⇒ Object



1788
1789
1790
# File 'lib/tecsgen/core/componentobj.rb', line 1788

def self.external_join(internal_cell_elem_name, export_name, b_composite)
  @@current_object.external_join(internal_cell_elem_name, export_name, b_composite)
end

.get_cell_listObject

Cell# @@cell_list を得る

composite の中を含まない



2529
2530
2531
# File 'lib/tecsgen/core/componentobj.rb', line 2529

def self.get_cell_list
  @@cell_list
end

.get_cell_list2Object

Cell# @@cell_list2 を得る

composite 内を含む (compositeも含む) 意味解析後に作成される



2523
2524
2525
# File 'lib/tecsgen/core/componentobj.rb', line 2523

def self.get_cell_list2
  @@cell_list2
end

.get_currentObject



2124
2125
2126
# File 'lib/tecsgen/core/componentobj.rb', line 2124

def self.get_current
  @@current_object
end

.make_cell_list2Object

Cell# @@cell_list2 を作る

@@cell_list2 は、出現順に composite 内を含むセルのリスト



2513
2514
2515
2516
2517
2518
# File 'lib/tecsgen/core/componentobj.rb', line 2513

def self.make_cell_list2
  @@cell_list.each{|c|
    @@cell_list2 << c
    @@cell_list2 += c.get_cell_list2
  }
end

.new_defObject

Cell# cell の定義

本体(join)の定義の直前に呼び出される



1558
1559
1560
# File 'lib/tecsgen/core/componentobj.rb', line 1558

def self.new_def
  @@current_object.new_def
end

.new_join(join, b_regular = false) ⇒ Object



1585
1586
1587
# File 'lib/tecsgen/core/componentobj.rb', line 1585

def self.new_join(join, b_regular = false)
  @@current_object.new_join(join, b_regular)
end

.new_reverse_join(reverse_join) ⇒ Object

Cell.新しい逆結合



1707
1708
1709
# File 'lib/tecsgen/core/componentobj.rb', line 1707

def self.new_reverse_join(reverse_join)
  @@current_object.new_reverse_join(reverse_join)
end

.popObject



1435
1436
1437
1438
1439
1440
1441
# File 'lib/tecsgen/core/componentobj.rb', line 1435

def self.pop
  @@current_object = @@nest_stack[@@nest_stack_index]
  @@nest_stack_index -= 1
  if @@nest_stack_index < -1
    raise "TooManyRestore"
  end
end


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/tecsflow.rb', line 144

def self.print_unused_func
  parent_cell = []
  indent_level = 1
  @@printed_cell_list.keys.each{ |cell|
    cell_printed = false
    ct = cell.get_celltype
    if cell.is_in_composite? then
      # print "unreferenced in composite #{ct.get_name} #{cell.get_name}\n"
      next
    end
    # if @@printed_celltype_list[ ct ] == true then
    #   next
    # end
    # @@printed_celltype_list[ ct ] = true
    ct.get_port_list.each{ |port|
      next if port.get_port_type == :CALL
      entry_port_name = port.get_name
      port.get_signature.get_function_head_array.each{ |func|
        func_name = func.get_name
        # func_nsp = get_function_nsp port_name, func_name, parent_cell
        # if @@printed_func_nsp_list[ func_nsp ] != true then
        # end
        ep_func = "#{ct.get_global_name}_#{entry_port_name}_#{func_name}".to_sym
        # print "  ", ep_func, "\n"
        if $tcflow_funclist[ ep_func ].kind_of? TCFlow::Function then
          func = $tcflow_funclist[ ep_func ]
          if ! func.is_printed? then
            #if cell_printed == false then
            #  cell_printed = true
            # if cell.get_namespace_path == nil then
            #   cell.show_tree 0
            # end
              print "[unreferenced entry function] #{cell.get_namespace_path}.#{entry_port_name}.#{func_name}"
            #end
            cell.print_entry_func_flow entry_port_name, func_name, indent_level, parent_cell
          end
        end
      }
    }
  }
end

.pushObject

composite の内部のセルを含む (元のセルを含む) 意味解析後 make_cell_list2 にて設定される



1429
1430
1431
1432
1433
# File 'lib/tecsgen/core/componentobj.rb', line 1429

def self.push
  @@nest_stack_index += 1
  @@nest_stack[@@nest_stack_index] = @@current_object
  @@current_object = nil
end

.set_name(name) ⇒ Object



1490
1491
1492
# File 'lib/tecsgen/core/componentobj.rb', line 1490

def self.set_name(name)
  @@current_object.set_name(name)
end

Instance Method Details

#add_compositecelltypejoin(join) ⇒ Object



1995
1996
1997
# File 'lib/tecsgen/core/componentobj.rb', line 1995

def add_compositecelltypejoin(join)
  @compositecelltypejoin_list.add_item join
end

#add_restrict(entry_name, func_name, region_name_list) ⇒ Object

Cell#restrict を追加



3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
# File 'lib/tecsgen/core/componentobj.rb', line 3024

def add_restrict(entry_name, func_name, region_name_list)
  if @restrict_list[entry_name].nil?
    @restrict_list[entry_name] = {}
    @restrict_list2[entry_name] = {}
  end
  if @restrict_list[entry_name][func_name].nil?
    @restrict_list[entry_name][func_name] = []
    @restrict_list2[entry_name][func_name] = []
  end
  region_name_list.each do |rp|
    @restrict_list[ entry_name ][ func_name ] << rp
    # p "Class: " + rp.to_s
    obj = Namespace.find(rp)
    if obj.kind_of?(Region)
      @restrict_list2[entry_name][func_name] << obj.get_domain_root
    else
      cdl_error( "S9999 $1 not found or not region", rp.to_s )
    end
  end
end

#apply_plugin(plugin_name, option) ⇒ Object



1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
# File 'lib/tecsgen/core/componentobj.rb', line 1973

def apply_plugin(plugin_name, option)
  if !@b_defined
    cdl_error("S9999 plugin cannot apply to prototype cell '$1'", @name)
  end

  plClass = load_plugin(plugin_name, CellPlugin)
  # return if plClass == nil # 従来と仕様が変わるので、継続する
  if $verbose
    print "new cell plugin: plugin_object = #{plClass.class.name}.new( #{@name}, #{option} )\n"
  end

  begin
    plugin_object = plClass.new(self, option)
    plugin_object.set_locale @locale
    generate_and_parse plugin_object
  rescue Exception => evar
    cdl_error("S1166 $1: fail to new", plugin_name)
    print_exception(evar)
  end
  return plugin_object
end

#callable?(callee_cell, entry_name, func_name) ⇒ Boolean

Cell#callable?

Returns:

  • (Boolean)


3069
3070
3071
3072
3073
3074
# File 'lib/tecsgen/core/componentobj.rb', line 3069

def callable?(callee_cell, entry_name, func_name)
  # p "callable? #{@name}"
  res = callee_cell.callable_from?(entry_name, func_name, self)
  dbgPrint "callable? #{callee_cell.get_namespace_path}.#{entry_name}.#{func_name} from #{@NamespacePath} is #{res}\n"
  return res
end

#callable_from?(entry_name, func_name, caller_cell) ⇒ Boolean

Cell#callable_from? (private)

Returns:

  • (Boolean)


3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
# File 'lib/tecsgen/core/componentobj.rb', line 3077

def callable_from?(entry_name, func_name, caller_cell)
  @b_restrict_referenced = true
  if @restrict_list.length == 0
    return true
  end

  dr = caller_cell.get_region.get_domain_root
  if @restrict_list[entry_name]
    if @restrict_list[entry_name][func_name]
      @restrict_list2[entry_name][func_name].each{ |region|
        if dr == region then
          return true
        end
      }
    elsif @restrict_list[entry_name][nil] then
      @restrict_list2[entry_name][nil].each{ |region|
        if dr == region then
          return true
        end
      }
    else
      return false
    end
  else
    return false
  end
end

#cell_pluginObject

Cell# セルプラグイン (generate 指定子)



1967
1968
1969
1970
1971
# File 'lib/tecsgen/core/componentobj.rb', line 1967

def cell_plugin
  plugin_name = @generate[0]
  option = @generate[1]
  @generate[2] = apply_plugin plugin_name, option
end

#change_rhs_port(cloned_cell_list) ⇒ Object

Cell# clone された cell の join_list の右辺の変更

呼び口の右辺の cell を他の clone された cell に置換え


2087
2088
2089
2090
2091
2092
2093
2094
# File 'lib/tecsgen/core/componentobj.rb', line 2087

def change_rhs_port(cloned_cell_list)
  # debug
  dbgPrint "=====   Cell#change_rhs_port: name=#{@name}   =====\n"

  @join_list.get_items.each {|j|
    j.change_rhs_port(cloned_cell_list, @celltype)
  }
end

#check_joinObject

Cell# 結合(Join)のチェック

   Join は呼び口の結合または attribute の初期化

mikan このメソッドは、以下の4つのチェックからなるが、分割したほうがより適切な長さのメソッドになる
・リレーアロケータの生成 => create_relay_allocator_join
・未結合の呼び口のチェック
・ポインタ型が配列で初期化される場合のチェック
・未初期化の属性のチェック


2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
# File 'lib/tecsgen/core/componentobj.rb', line 2599

def check_join
  # celltype がなければチェックしない(既にエラー)
  return if @celltype.nil?
  return if @b_defined == false
  return if @f_cloned == true # 内部セルについては、composite の定義時にチェックされている

  # debug
  # if @compositecelltypejoin_list then
  #   p "check_join"
  #   @compositecelltypejoin_list.get_items.each { |cj| p "#{cj.get_name} #{cj.get_name.object_id}" }
  # end

  # 未結合の呼び口のチェック
  @celltype.get_port_list.each {|p|

    # 呼び口でなければ、チェックしない
    next if p.get_port_type != :CALL

    # debug
    dbgPrint "check_join: #{@name} #{get_celltype.get_name} #{p.get_name}\n"

    # 結合リストの中から呼び口名に一致するものを取りだす
    j = @join_list.get_item(p.get_name)

    if j.nil?
      # 未結合の呼び口

      # composite celltype の内部の場合、composite celltype が export する呼び口に結合されているか探す
      found = false
      if @in_composite
        # composite celltype の export するものすべてから探す
        # (export するものの右辺値から探すために get_item ではダメ)
        @compositecelltypejoin_list.get_items.each{|cj|
          # 呼び口名と composite の export する名前は一致するか
          if p.get_name == cj.get_cell_elem_name
            found = true
          end
        }
      end

      # 呼び口配列の場合 optional で全ての要素が初期化されない場合に、ここへ来る
      if !found && !p.is_require? && !p.is_optional?
        if !p.is_allocator_port?
          cdl_error("S1042 call port \'$1\' not initialized in cell \'$2\'", p.get_name, @name)
        else
          cdl_error("S1043 call port \'$1\' not initialized in cell \'$2\'. this call port is created by tecsgen. check allocator specifier", p.get_name, @name)
        end
      end
    elsif p.get_array_size.is_a? Integer
      # 添数あり呼び口配列の場合、すべての添数要素が初期化されているかチェックする

      am = j.get_array_member2
      if am
        # join は配列

        # 呼び口配列定義での配列の大きさ
        length = p.get_array_size

        # 配列の大きさが呼び口配列定義と結合定義で一致するか?
        if am.length != length
          if !p.is_optional? || am.length >= length
            # optional の場合、要素数が少なすぎるのは OK
            cdl_error("S1044 $1: array initializer too many or few, $2 for $3", p.get_name, am.length, length)
          end

          # am の要素に nil を追加しておく (#_CPA_# のコード生成時、この配列要素数分生成)
          i = am.length
          while i < length
            am << nil
            i += 1
          end
        end

#          # 配列要素の抜けがないかチェック
#          if am.length < length then  # 満たない場合既にエラーだが要素のある範囲でチェック
#            length = am.length
#          end
        i = 0
        while i < length
          if am[i].nil?
            if !p.is_optional?
              cdl_error("S1045 $1[$2]: not initialized", p.get_name, i)
            end
          else
            # 生成されないリージョンへの結合かチェック
            if !@in_composite
              am[i].check_region2
            end
          end
          i += 1
        end

      # else
      # join が非配列であれば、既にエラー
      end
    elsif j.get_array_member
      # 添数なし呼び口配列の場合
      am = j.get_array_member2
      length = am.length
      i = 0
      while i < length
        if am[i].nil?
          if !p.is_optional?
            cdl_error("S1046 $1[$2]: not initialized", p.get_name, i)
          end
        end
        i += 1
      end

      # 生成されないリージョンへの結合かチェック
      if !@in_composite
        am.each {|join|
          if join
            join.check_region2
          end
        }
      end
    else
      # 呼び口[配列」でない場合

      # 生成されないリージョンへの結合かチェック
      if !@in_composite
        j.check_region2
      end

    end # j != nil
  }

  # ポインタ型が配列で初期化される場合のチェック
  (@celltype.get_attribute_list + @celltype.get_var_list).each {|a|
    if a.get_size_is

      if a.instance_of? CompositeCelltypeJoin
        # 既にエラーになっている
        # cdl_error( "S1047 size_is pointer cannot be exposed for composite attribute"  )
        next
      end

      if !a.get_type.is_a?(PtrType)
        cdl_error("S1048 $1: size_is specified for non-pointer type", a.get_name)
      else
        size = a.get_size_is.eval_const(@join_list, @celltype.get_name_list)
        a.get_type.set_scs(a.get_size_is, nil, nil, nil, false)
        if !size.is_a? Integer # C_EXP の可能性あり
          # mikan 多分ここでのエラー発生は不要、eval_const の中で変数が存在しない、型が不適切などのエラーになるはず
          cdl_error("S1049 $1: size_is arg not constant", a.get_name)
        else
          j = @join_list.get_item(a.get_identifier)
          if j
            ini = j.get_rhs
            if ini
              if !ini.instance_of?(Array)
                cdl_error("S1050 unsuitable initializer, need array initializer")
              elsif size < ini.length
                cdl_error("S1051 too many initializer for array, $1 for $2", ini.length, size)
              else
                # a.get_type.set_scs( a.get_size_is, nil, nil )
              end
            end
          else
            # size_is 引数がセルで指定されていて、初期化子がセルタイプで指定されているケースのチェック
            ini = a.get_initializer
            if ini.instance_of? Expression
              ini = ini.eval_const(@celltype.get_name_list)
            end
            if ini.instance_of? Array
              if ini.length > size
                cdl_error("S1168 too many initializer for array, $1 for $2", ini.length, size)
              end
            end
          end
        end
      end
    else
      if !a.instance_of? CompositeCelltypeJoin
        # composite は size_is 指定できない
        if a.get_type.is_a?(PtrType)
          j = @join_list.get_item(a.get_identifier)
          if j && j.get_rhs.instance_of?(Array)
            ## size_is 指定されていないポインタが Array で初期化されていたら、エラーとする
            cdl_error("S1169 $1: non-size_is pointer cannot be initialized with array initializer", a.get_identifier)
          end
        end
      end
    end
  }

  # 未初期化の属性をチェック
  @celltype.get_attribute_list.each {|a|
    b_init = false
    # self.show_tree 1
    if a.get_initializer # セルタイプで初期化されている
      b_init = true
      # @in_composite で export されている場合には、この初期値は使われない
      # export されている、いないに関わらず、初期化されていることが保証される
    elsif @join_list.get_item(a.get_name) # セルで初期化されている
      b_init = true
    elsif @in_composite && @compositecelltypejoin_list
      # 属性が export されているか調べる。export されていれば未初期化とはしない
      # mikan リニアサーチ
      @compositecelltypejoin_list.get_items.each{|cj|
        # 属性名と composite の export する名前は一致するか
        if a.get_name.to_sym == cj.get_cell_elem_name.to_sym
          b_init = true # 属性は export されているので、とりあえず未初期化とはしない
        end
      }
      if b_init
        # size_is の引数がマッチするかチェックする
        # 内部セルの size_is をエクスポートする size_is とマッチするかチェックする
        # 内部セルとエクスポートで名前を変えている可能性があるので、内部セルの size_is の名前を変換した上でチェックする
        if a.get_size_is
          ### p "attr: get_size_is"
          cj = @compositecelltypejoin_list.get_item a.get_name.to_sym
          if cj.get_port_decl.instance_of? Decl
            ### p "attr: get_size_is 2"
            # cj_size_is は、外部公開される attr の size_is
            cj_size_is = cj.get_port_decl.get_size_is
            if cj_size_is.nil?
              cdl_error("S1170 \'$1\' has size_is but export attr \'$2\' doesn't have", a.get_name, cj.get_name)
            end
            exprs = a.get_size_is.to_s
            ### p "exprs : ", exprs
            remain = exprs
            inner_to_export = {}
            ### exprs に含まれる識別子を抜き出し、対応する export される名前を探す
            while remain != "" && !remain.nil?
              ### p "remain ", remain
              remain =~ /([^\w]*)([_A-Za-z][\w\d]*)/ # 変数名文字列を取り出す
              if $2.nil?
                break
              end
              arg_name = $2.to_sym
              remain = $'
              ### p exprs, $1, $2, $'
              # size_is に含まれる変数は、composite で export されているか
              cj2 = nil
              @compositecelltypejoin_list.get_items.each{|cj2t|
                if cj2t.get_cell_elem_name == arg_name
                  cj2 = cj2t
                end
              }
              if cj2.nil?
                cdl_error("S1171 \'$1\' size_is argument of \'$2\' not exported", a.get_name, cj.get_name)
                next
              end
              if cj2.get_port_decl.instance_of? Decl
                decl2 = cj2.get_port_decl
                 # 内部の名前と外部の名前の対応関係を記憶
                 inner_to_export[arg_name] = decl2.get_name
              # else cj2 は Port (既にエラー)
              end
            end
            # 内部の名前を外部の名前で置換
            inner_to_export.each{|arg_name, exp_name|
              ### p "changing #{arg_name}=>#{exp_name}"
              # exprs.gsub!( Regexp.new("#{arg_name}[^0-9A-Za-z_]"), exp_name.to_s )
              exprs.gsub!(Regexp.new("#{arg_name}(\\W)"), exp_name.to_s + "\\1")  # 文字列末尾にないケース
              exprs.gsub!(Regexp.new("#{arg_name}\\Z"), exp_name.to_s)          # 文字列末尾にあるケース
            }
            ### p "changed: #{exprs} #{cj_size_is.to_s}"
            if exprs != cj_size_is.to_s
              cdl_error("S1172 \'$1\' size_is argument mismatch with exporting one \'$2\'", a.get_name, cj.get_name)
            end
          # else cj は Port (既にエラー)
          end
        end
      end
    end

    if b_init == false
      cdl_error("S1052 attribute \'$1\' not initialized in cell \'$2\'", a.get_name, @name)
    end

  }
end

#check_restrict_listObject

Cell#check_restrict_list



3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
# File 'lib/tecsgen/core/componentobj.rb', line 3046

def check_restrict_list
  # p "check_restrict_list"
  @restrict_list.each{|entry_name, func_hash|
    func_hash.each{|func_name, region_list|
      region_list.each{|rp|
        obj = Namespace.find(rp)
        if obj.is_a? Region
          if obj.get_domain_root != @region.get_domain_root
          else
            cdl_info( "I9999 $1: restrict calling domain to $2, which is same domain as the cell locates", @name, rp.to_s )
            # restrict を同じドメインを指定してもよいこととする (HRP3)
            # KernelDoamin 内のセルに対し、KernelDomain に restrict している場合、
            # 無所属経由で結合されているが、KernelDomain から呼出すことを想定した許可
          end
        else
          cdl_error( "S9999 $1 not region", rp.to_s )
        end
      }
    }
  }
end

#check_reverse_requireObject

Cell# 逆 require をチェックする

逆 require 指定された受け口に複数の結合がないかチェックする composite の内部セル (f_cloned=true) もチェックする



2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
# File 'lib/tecsgen/core/componentobj.rb', line 2878

def check_reverse_require
  # celltype がなければチェックしない(既にエラー)
  return if @celltype.nil?
  return if @b_defined == false

  # p "check reverse require   #{@name}"
  # 逆require 指定された受け口に複数の結合がないかチェック
  @referenced_port_list.each{|port, count|
    # p port.class, count
    # p port.get_name, port.get_port_type, port.get_signature.get_name
    if port.is_reverse_required? && count > 1
      cdl_warning("W1009 $1: fixed join entry port has multi join", port.get_name)
    end
  }
end

#clone_for_composite(name, global_name, namespacePath, join_array, ct_name, region, plugin, locale) ⇒ Object

Cell# cell を composite セルタイプのセル用に clone する

name

string : 親 cell の名前 (cell tComposite cell1 での cell1)

global_name

string : 親 cell の global_name

join_array

Join[] : composite の cell の join で、この cell に対応するもの

ct_name

string : 親セルのセルタイプ名

region

Region : 元のセルが属する region

このメソッドは CompositeCelltype の expand から呼出される



2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
# File 'lib/tecsgen/core/componentobj.rb', line 2006

def clone_for_composite(name, global_name, namespacePath, join_array, ct_name, region, plugin, locale)
  # debug
  dbgPrint "  CLONING Cell#clone_for_composite : cloning: #{@name} #{global_name}  b_defined=#{@b_defined} #{self}=>#{@my_clone} \n"
  dbgPrint "              my_name=#{@name} name=#{name} owner class=#{@owner.class.name}\n"

  @my_clone = self.clone

  # clone したセルの内部に持つ名前情報を調整する
  @my_clone.set_cloned(name, global_name, namespacePath, join_array, ct_name, region, plugin, locale)

  # @celltype == nil は以前にセルタイプ未定義エラー
  if @b_defined == true && !@celltype.nil?
    if @celltype.instance_of?(Celltype)
      # celltype に登録(コード生成の対象となる)
      @celltype.new_cell(@my_clone)
    end
  end

  return @my_clone
end

#create_relay_allocator_joinObject

Cell# リレーアロケータの結合を生成

STAGE: S 呼び口側の結合を元に受け口側の結合を生成



2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
# File 'lib/tecsgen/core/componentobj.rb', line 2406

def create_relay_allocator_join
  # celltype がなければチェックしない(既にエラー)
  return if @celltype.nil?

  # relay allocator を生成
  @celltype.get_port_list.each {|p|
    ail = p.get_allocator_instance
    if ail
      dbgPrint "create_relay_allocator_join: #{@name}, #{p.get_name}\n"
      if p.get_array_size
        # mikan relay allocator が array に対応できてもよいのでは?
        cdl_error("S1040 array not supported for relay allocator")
        next
      end
      ail.each{|name, ai2|
        # ai2 = [ :INTERNAL_ALLOC|:RELAY_ALLOC, func_name, param_name, rhs_cp_name, rhs_func_name, rhs_param_name ]
        if ai2[0] == :RELAY_ALLOC
          dbgPrint "create_relay_allocator_join: #{@name}, #{name}\n"
          # 呼び口側の結合を取り出す
          ja = @join_list.get_item(:"#{ai2[3]}_#{ai2[4]}_#{ai2[5]}")
          if ja.nil?
            # 見つからない場合
            found = false

            # composite 内で外部に結合されているか
            if @in_composite
              @compositecelltypejoin_list.get_items.each {|cj|
                dbgPrint("create relay_allocator in_composite\n")
                dbgPrint("    #{cj.get_cell_name} #{@name} #{cj.get_cell_elem_name} #{ai2[3]}_#{ai2[4]}_#{ai2[5]}\n")
                if cj.get_cell_name == @name &&
                    cj.get_cell_elem_name == :"#{ai2[3]}_#{ai2[4]}_#{ai2[5]}"
                  found = true
                  dbgPrint "create_relay_allocator: found #{cj.get_cell_elem_name}\n"
                  break
                end
              }
            end

            if found == false
              cdl_error("S1041 \'$1_$2_$3\': not joined. cannot create internal join for relay allocator", ai2[3], ai2[4], ai2[5])
              print("      In cell #{get_name}\n")
              # join が未結合であることのエラーは二度でる (S1043)
            end
            next # 打ち切る
          end

          b_export = false
          # composite 内のセルでエクスポートされているかチェック
          #  mikan エクスポート側と、こちら側で、リレー先が一致するかチェックが必要
          if @compositecelltypejoin_list
            # export されているか調べる
            @compositecelltypejoin_list.get_items.each{|cj|
              # 属性名と composite の export する名前は一致するか
              if p.get_name == cj.get_cell_elem_name
                print "export : #{p.get_name}\n"
                b_export = true # 属性は export されているので、とりあえず未初期化とはしない
                break
              end
            }
            #
          end

          # mikan 配列
          am = nil
          if am
            am.each{|ja2|
              rhs = ja2.get_rhs
              subscript = ja2.get_subscript
              if b_export == false
                # CompositeCelltype の場合、内側のセルで生成させる
                join = Join.new(:"#{p.get_name}_#{ai2[1]}_#{ai2[2]}", subscript, rhs, @loacle)
                # p ( "#{p.get_name}_#{ai2[1]}_#{ai2[2]}", subscript, rhs )
                new_join(join)
                join.set_definition(@celltype.find(join.get_name))
                # mikan relay mismatch チェックができていない(下方を参照)
              end
              @alloc_list << [:NORMAL_ALLOC, p.get_name, subscript, ai2[1], ai2[2], rhs]
            }
          else
            if b_export == false
              # CompositeCelltype の場合、内側のセルで生成させる
              join = Join.new(:"#{p.get_name}_#{ai2[1]}_#{ai2[2]}", nil, ja.get_rhs, @locale)
              new_join(join)
              join.set_definition(@celltype.find(join.get_name))
              if @celltype.instance_of? CompositeCelltype
                jr = @join_list.get_item(:"#{ai2[3]}_#{ai2[4]}_#{ai2[5]}")
                if jr.get_rhs_cell2 != join.get_rhs_cell2 || jr.get_rhs_port2 != join.get_rhs_port2
                  cdl_error("S1167 \'$1\': relay mismatch \'$2\'",
                                    "#{p.get_name}_#{ai2[1]}_#{ai2[2]}",
                                    "#{ai2[3]}_#{ai2[4]}_#{ai2[5]}")
                  # 本当は composite の呼び口と受け口の間で行うべきだが、内部で多段接続されている場合
                else
                  dbgPrint "relay success:  #{p.get_name}_#{ai2[1]}_#{ai2[2]}=>#{ai2[3]}_#{ai2[4]}_#{ai2[5]} #{jr.get_rhs_cell2.get_name}.#{jr.get_rhs_port2} \n"
                end
              end
            end
            @alloc_list << [:NORMAL_ALLOC, p.get_name, nil, ai2[1], ai2[2], ja.get_rhs]
          end
          dbgPrint "create_relay_allocator_join: #{p.get_name}_#{ai2[1]}_#{ai2[2]} #{ai2[3]}_#{ai2[4]}_#{ai2[5]}\n"
        end
      }
    end
  }
end

#create_reverse_joinObject

Cell#逆結合から結合を生成

STAGE: S



1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
# File 'lib/tecsgen/core/componentobj.rb', line 1738

def create_reverse_join
  if @b_checked
    return
  end

  if @reverse_join_list
#      @reverse_join_list.get_items.each{ |rj|
    @reverse_join_list.each{|rj|
      # 逆結合の情報を得る
      ep_name = rj.get_name
      ep_subscript, cp_cell_nsp, cp_name, cp_subscript = rj.get_rhs_cell_and_port

      # 呼び口側のセルと、そのセルタイプ
      if !@in_composite
        cell = Namespace.find cp_cell_nsp
      else
        cell = CompositeCelltype.find cp_cell_nsp.to_s.to_sym
      end

      if !cell.instance_of? Cell
        cdl_error("S9999 '$1': not cell for reverse join", cp_cell_nsp.get_path_str)
        next
      end
      ct = cell.get_celltype
      if ct.nil?
        next
      end

      if !@in_composite
        ep_cell_nsp = get_namespace_path
        ep_cell_nsp_str = ep_cell_nsp.get_path_str
      else
        ep_cell_nsp = NamespacePath.new @name, false
        ep_cell_nsp_str = @name
      end
      ep_subscript_val = ep_subscript ? ep_subscript.eval_const(nil) : nil
      rhs = Expression.create_cell_join_expression(ep_cell_nsp, ep_subscript_val, ep_name, rj.get_locale)
      join = Join.new(cp_name, cp_subscript, rhs, rj.get_locale)
      cell.new_join(join)
      # join.set_definition( ct.find(join.get_name) )
      if cp_subscript
        ss_str = "[#{cp_subscript}]"
      else
        ss_str = ""
      end
      dbgPrint "create_reverse_join: #{cell.get_name}.#{cp_name}#{ss_str} => #{ep_cell_nsp_str}.#{ep_name}\n"
    }
  end
end

#end_of_parse(f_def) ⇒ Object



1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
# File 'lib/tecsgen/core/componentobj.rb', line 1816

def end_of_parse(f_def)
  if @b_prototype # prototype 指定子あったか?
    f_def = false # プロトタイプ宣言とする
    @b_prototype = false
  end
  if f_def == false
    # cell tCelltype Cell; の形式の場合
    # f_def == true の場合 new_def で、呼出される
    set_specifier_list(Generator.get_statement_specifier)
  end
  if TECSGEN.post_coded?
    @b_post_code_generated = true
  end
  set_f_def f_def

  if @generate
    cell_plugin
  end
end

#exclude_info?Boolean

Returns:

  • (Boolean)


633
634
635
636
637
638
639
640
641
642
643
644
645
646
# File 'lib/tecsgen/core/tecsinfo.rb', line 633

def exclude_info?
  # print "exclude_info?: name=" + get_name.to_s
  if @celltype.nil? ||
     is_of_composite? ||
     @celltype.get_global_name == :nTECSInfo_tTECSInfoSub ||
     post_code_generated? ||
     @b_defined == false
    # print ": true celltype_is_of_composite=#{is_of_composite?} celltype_name=#{@celltype.get_global_name} celltype.need_generate=#{@celltype.need_generate?}\n"
    return true
  else
    # print ": false\n"
    return false
  end
end

#exclude_info_factory?Boolean

Returns:

  • (Boolean)


648
649
650
651
652
653
654
655
656
657
658
659
660
# File 'lib/tecsgen/core/tecsinfo.rb', line 648

def exclude_info_factory?
  # print "exclude_info_factory?: name=" + get_name.to_s
  if @celltype.nil? ||
     is_of_composite? ||
     @celltype.get_global_name == :nTECSInfo_tTECSInfoSub ||
     !@celltype.need_generate?
    # print ": true celltype_is_of_composite=#{is_of_composite?} celltype_name=#{@celltype.get_global_name} celltype.need_generate=#{@celltype.need_generate?}\n"
    return true
  else
    # print ": false\n"
    return false
  end
end

#expandObject

Cell# composite セルの展開

このセルが composite セルタイプ



2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
# File 'lib/tecsgen/core/componentobj.rb', line 2994

def expand
  # debug
  dbgPrint "=====    expanding   #{@name}     =====\n"

  # composite celltype の cell を展開
  @cell_list, @cell_list2 = @celltype.expand(@name, @global_name, @NamespacePath, @join_list, @region, @plugin, @locale)

  # プロトタイプが参照されている場合、子も参照されていることにする
  if @f_ref
    dbgPrint "expand: set_f_ref\n"
    set_f_ref
  end
end

#expand_innerObject

clone されたセルが composite の場合、内部セルを展開する

self

clone されたセルでなければならない



2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
# File 'lib/tecsgen/core/componentobj.rb', line 2073

def expand_inner
  if !@f_cloned
    raise "expnad_inner: not cloned cell"
  end

  # clone しようとするセルが composit セルタイプ?
  if @celltype.instance_of?(CompositeCelltype)
    # composite cell を再帰的に展開
    @cell_list, @cell_list2 = @celltype.expand(@name, @global_name, @NamespacePath, @join_list, @region, @plugin, @locale)
  end
end

#external_join(internal_cell_elem_name, export_name, b_composite) ⇒ Object

Cell# cell 内に記述する呼び口の外部結合

internal_cell_elem_name

string : 呼び口名

export_name

string: composite の外部に公開する呼び口名

呼び口を外部結合する.
このメソッドは、composite の中の cell でしか呼ばれない.


1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
# File 'lib/tecsgen/core/componentobj.rb', line 1797

def external_join(internal_cell_elem_name, export_name, b_composite)
  # cCall => composite.cCall; ではないか?
  if b_composite == false
    # cCall => cCall; のような場合
    if @celltype.find(export_name)
      cdl_error("S1036 $1 : cannot refer to $2\'s here. Use \'composite.$3\' to refer to composite celltype\'s", export_name, @celltype.get_name, export_name)
    end
  end
  # composite の旧文法における、cell 外の cCall = Cell.cCall; の構文処理に渡す
  CompositeCelltype.new_join(export_name, @name, internal_cell_elem_name, :CALL)
end

#gen_XML(file, nest) ⇒ Object



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/tecsgen/core/gen_xml.rb', line 321

def gen_XML(file, nest)
  indent = XML_INDENT * nest

  if is_imported?
    file.print <<EOT
#{indent}<import path='#{@import.get_cdl_name}'>
EOT
    nest += 1
    indent = XML_INDENT * nest
  end

  file.print <<EOT
#{indent}<cell>
#{indent}#{XML_INDENT}<name> #{@name} </name>
EOT
  @join_list.get_items.each{|join|
    if join.get_definition.is_a? Port
      kind = "call_join"
    elsif join.get_definition.is_a? Decl
      kind = "attr_join"
    else
      raise "Unknown"
    end
    if join.get_array_member2
      join.get_array_member2.each {|j2|
        file.print <<EOT
#{indent}#{XML_INDENT}<#{kind}>
#{indent}#{XML_INDENT}#{XML_INDENT}<name> #{join.get_name} </name>
#{indent}#{XML_INDENT}#{XML_INDENT}<subscript> #{join.get_subscript} </subscript>
#{indent}#{XML_INDENT}#{XML_INDENT}<rhs> #{join.get_rhs.to_CDL_str} </rhs>
#{indent}#{XML_INDENT}</#{kind}>
EOT
      }
    else
      file.print <<EOT
#{indent}#{XML_INDENT}<#{kind}>
#{indent}#{XML_INDENT}#{XML_INDENT}<name> #{join.get_name} </name>
#{indent}#{XML_INDENT}#{XML_INDENT}<rhs> #{join.get_rhs.to_CDL_str} </rhs>
#{indent}#{XML_INDENT}</#{kind}>
EOT
    end
  }
  file.print <<EOT
#{indent}</cell>
EOT
  if is_imported?
    nest -= 1
    indent = XML_INDENT * nest
    file.print <<EOT
#{indent}</import>
EOT
  end
end

#get_allocator_listObject



1940
1941
1942
1943
1944
1945
1946
1947
# File 'lib/tecsgen/core/componentobj.rb', line 1940

def get_allocator_list
  # 意味チェック(set_definition)されていない?
  # relay アロケータの場合、セルの意味チェックが行われていないと、@alloc_list が完成しない
  if @b_checked == false
    set_definition_join
  end
  @alloc_list
end

#get_attr_initializer(attr_name) ⇒ Object

Cell#属性の初期値を得る attr_name::Symbol 必ず初期化されていないと Ruby 例外となる



2319
2320
2321
2322
2323
2324
2325
2326
2327
# File 'lib/tecsgen/core/componentobj.rb', line 2319

def get_attr_initializer(attr_name)
  val = @join_list.get_item(attr_name)
  if val.nil?
    val = (@celltype.find attr_name).get_initializer
  else
    val = val.get_rhs
  end
  return val
end

#get_cell_list2Object



2349
2350
2351
2352
2353
2354
2355
2356
# File 'lib/tecsgen/core/componentobj.rb', line 2349

def get_cell_list2
  list = []
  @cell_list2.each{|cell|
    list << cell
    list += cell.get_cell_list2
  }
  return list
end

#get_celltypeObject



2329
2330
2331
# File 'lib/tecsgen/core/componentobj.rb', line 2329

def get_celltype
  @celltype
end

#get_entry_port_max_subscript(port) ⇒ Object

Cell# 受け口配列の添数の最大値を返す

長さは +1 する 1つもない場合は -1 を返す



2395
2396
2397
2398
2399
2400
2401
# File 'lib/tecsgen/core/componentobj.rb', line 2395

def get_entry_port_max_subscript(port)
  subscript = @entry_array_max_subscript[port]
  if subscript.nil?
    subscript = -1
  end
  return subscript
end

#get_f_defObject



2096
2097
2098
# File 'lib/tecsgen/core/componentobj.rb', line 2096

def get_f_def
  @b_defined
end

#get_f_refObject



2100
2101
2102
2103
2104
2105
2106
# File 'lib/tecsgen/core/componentobj.rb', line 2100

def get_f_ref
  if @f_ref
    return true
  else
    return false
  end
end

#get_function_nsp(port_name, func_name, parent_cell) ⇒ Object



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/tecsflow.rb', line 186

def get_function_nsp port_name, func_name, parent_cell
  if @in_composite == false then
    nsp = get_namespace_path.to_s.sub( /^::/, "")
    return "#{nsp}.#{port_name}.#{func_name}".to_sym
  else
    len = parent_cell.length
    if parent_cell[0] == nil then
      # Bug trap
      print "\nname=", @name, ", len=", len, " nsp=", get_namespace_path, "\n"
      nsp = "__" + @name.to_s
    else
      nsp = parent_cell[0].get_namespace_path.to_s
    end
    i = 1
    while i < len
      nsp = nsp + '_' + parent_cell[i].get_name.to_s
      i+=1
    end
    return "#{nsp}_#{@name}.#{port_name}.#{func_name}".to_sym
  end
end

#get_global_nameObject



2116
2117
2118
# File 'lib/tecsgen/core/componentobj.rb', line 2116

def get_global_name
  @global_name
end

#get_idObject



2341
2342
2343
# File 'lib/tecsgen/core/componentobj.rb', line 2341

def get_id
  @id
end

#get_internal_port_name(port_name) ⇒ Object



2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
# File 'lib/tecsgen/core/componentobj.rb', line 2303

def get_internal_port_name(port_name)
  if @celltype.instance_of?(CompositeCelltype)
    cj = @celltype.find_export(port_name)
#      return "#{@name}_#{cj.get_cell.get_internal_port_name cj.get_cell_elem_name}"
    return cj.get_cell.get_internal_port_name(cj.get_cell_elem_name)
  else

    # debug
    dbgPrint "  get_global_port_name: cell port: #{@global_name}_#{port_name}\n"

    return "#{@global_name}_#{port_name}"
  end
end

#get_join_listObject



2333
2334
2335
# File 'lib/tecsgen/core/componentobj.rb', line 2333

def get_join_list
  @join_list
end

#get_local_nameObject



2112
2113
2114
# File 'lib/tecsgen/core/componentobj.rb', line 2112

def get_local_name
  @local_name
end

#get_nameObject



2108
2109
2110
# File 'lib/tecsgen/core/componentobj.rb', line 2108

def get_name
  @name
end

#get_pluginObject



2345
2346
2347
# File 'lib/tecsgen/core/componentobj.rb', line 2345

def get_plugin
  @plugin
end

#get_real_cell(port_name) ⇒ Object

Cell# cell を得る

composite でなければ自分自身を返す


2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
# File 'lib/tecsgen/core/componentobj.rb', line 2248

def get_real_cell(port_name)
  # composite か?
  if @celltype.instance_of?(CompositeCelltype)

    # セルタイプ内で port_name の CompositeCelltypeJoin を探す(コード生成段階では必ず見つかる)
    # print "get_real_cell: cell=#{@name} port=#{port_name}\n"
    # pp @cell_list
    cj = @celltype.find_export(port_name)

    # composite の内部のセルに対し再帰的に get_real_port を適用
    cell = @cell_list[cj.get_cell_name.to_s].get_real_cell(cj.get_cell_elem_name)
    return cell
  else

    return self
  end
end

#get_real_celltype(port_name) ⇒ Object

Cell#get_real_celltype



2268
2269
2270
2271
2272
2273
2274
# File 'lib/tecsgen/core/componentobj.rb', line 2268

def get_real_celltype(port_name)
  if @celltype.instance_of?(CompositeCelltype)
    return @celltype.get_real_celltype port_name
  else
    return @celltype
  end
end

#get_real_global_name(port_name) ⇒ Object

composite cell の port に対応する内部の cell の port の名前(リンク時に必要な名前)



2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
# File 'lib/tecsgen/core/componentobj.rb', line 2170

def get_real_global_name(port_name)
  if @celltype.instance_of?(CompositeCelltype)

    # debug
    dbgPrint "get_real_global_name: cell name: #{@name} #{@local_name} #{@global_name} #{port_name}\n"
    @cell_list.each{|n, c|
      dbgPrint "   name: #{n}\n"
      dbgPrint " get_name: #{c.get_name} local_name: #{c.get_local_name}\n" if c
      dbgPrint "\n\n"
    }

    cj = @celltype.find_export(port_name)

    # debug
    dbgPrint " composite join name: #{cj.get_name}  cell: #{cj.get_cell_name}  cell elem: #{cj.get_cell_elem_name}\n"

    name = @cell_list[cj.get_cell_name.to_s].get_real_global_name(cj.get_cell_elem_name)
    return name

  else
    # debug
    dbgPrint "  get_real_global_name: cell name: #{@global_name}\n"

    return @global_name
  end
end

#get_real_global_port_name(port_name) ⇒ Object

Cell# セルの受け口 port_name に対する実際のセル名、受け口名を ‘_’ で連結

namespace 名 + '_' + セル名 + '_' + 受け口名   (このセルが composite ならば展開後のセル名、受け口名)


2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
# File 'lib/tecsgen/core/componentobj.rb', line 2199

def get_real_global_port_name(port_name)
  # composite か?
  if @celltype.instance_of?(CompositeCelltype)

    # debug
    dbgPrint "get_real_global_port_name: cell name: #{@name} #{@local_name} #{@global_name} #{port_name}\n"
    @cell_list.each{|n, c|
      dbgPrint "   name: #{n}\n"
      dbgPrint " get_name: #{c.get_name} local_name: #{c.get_local_name}\n" if c
      dbgPrint "\n"
    }

    # セルタイプ内で port_name の CompositeCelltypeJoin を探す(コード生成段階では必ず見つかる)
    cj = @celltype.find_export(port_name)

    # debug
    dbgPrint "   composite join name: #{cj.get_name}  cell: #{cj.get_cell_name}  cell elem: #{cj.get_cell_elem_name}\n"

    # composite の内部のセルに対し再帰的に get_real_global_port_name を適用
    name = @cell_list[cj.get_cell_name.to_s].get_real_global_port_name(cj.get_cell_elem_name)
    return name

  else
    # debug
    dbgPrint "get_real_global_port_name:  cell name: #{@global_name}\n"

    return "#{@global_name}_#{port_name}"
  end
end

#get_real_port(port_name) ⇒ Object

Cell# PORT (celltype の定義) を得る



2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
# File 'lib/tecsgen/core/componentobj.rb', line 2230

def get_real_port(port_name)
  # composite か?
  if @celltype.instance_of?(CompositeCelltype)

    # セルタイプ内で port_name の CompositeCelltypeJoin を探す(コード生成段階では必ず見つかる)
    cj = @celltype.find_export(port_name)

    # composite の内部のセルに対し再帰的に get_real_port を適用
    port = @cell_list[cj.get_cell_name.to_s].get_real_port(cj.get_cell_elem_name)
    return port
  else

    return @celltype.find(port_name)
  end
end

#get_regionObject



2120
2121
2122
# File 'lib/tecsgen/core/componentobj.rb', line 2120

def get_region
  @region
end

#get_restricted_regions(entry_name, func_name) ⇒ Object

Cell#get_callable_regions( entry_name, func_name )

func_name=nil の場合、entry_name の可否をチェック数る nil が返る場合、制限されていないことを意味する



3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
# File 'lib/tecsgen/core/componentobj.rb', line 3108

def get_restricted_regions( entry_name, func_name )
  # p "get_restricted_regions #{@name}"
  @b_restrict_referenced = true
  if @restrict_list[entry_name]
    if @restrict_list[entry_name][func_name]
      return @restrict_list2[entry_name][func_name]
    else
      return @restrict_list2[entry_name][nil]
    end
  end
  return nil
end

#get_specified_idObject



1949
1950
1951
# File 'lib/tecsgen/core/componentobj.rb', line 1949

def get_specified_id
  @id_specified
end

#has_ineffective_restrict_specifierObject

Cell#has_ineffective_restrict_specifier

restrict 指定子が指定されていて、参照されていない場合 true 参照は、HRPSVCPlugin のみ



3124
3125
3126
3127
3128
3129
3130
# File 'lib/tecsgen/core/componentobj.rb', line 3124

def has_ineffective_restrict_specifier
  if @restrict_list.length != 0 && @b_restrict_referenced == false
    true
  else
    false
  end
end

#is_cloned?Boolean

Cell# composite 内部の複製されたセルか?

composite 定義の内部のセル (@in_composite = true) ではない

Returns:

  • (Boolean)


2146
2147
2148
# File 'lib/tecsgen/core/componentobj.rb', line 2146

def is_cloned?
  @f_cloned
end

#is_generate?Boolean

Cell# 生成されるセルか?

最適化、コード生成中に、対象となる region に属する場合 true を返す

Returns:

  • (Boolean)


2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
# File 'lib/tecsgen/core/componentobj.rb', line 2130

def is_generate?
  if $generating_region.nil?
    # 構文解釈、意味解析段階で呼ばれると例外発生
    raise "is_generate? called before optimizing"
  end

  # print "Cell#is_generate?: #{@name} #{@region.get_name} #{$generating_region.get_name}\n"
  if $generating_region == @region.get_link_root
    return true
  else
    return false
  end
end

#is_in_composite?Boolean

Cell# composite 内部のセルか?

Returns:

  • (Boolean)


2151
2152
2153
# File 'lib/tecsgen/core/componentobj.rb', line 2151

def is_in_composite?
  @in_composite
end

#is_of_composite?Boolean

Cell# composite のセルか?

Returns:

  • (Boolean)


2156
2157
2158
2159
2160
2161
2162
# File 'lib/tecsgen/core/componentobj.rb', line 2156

def is_of_composite?
  if @celltype.is_a? CompositeCelltype
    return true
  else
    return false
  end
end

#new_defObject

Cell# cell の定義

本体(join)の定義の直前に呼び出される このメソッドは cell tCelltype Cell { }; ‘‘’ の部分がある場合に呼出される



1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
# File 'lib/tecsgen/core/componentobj.rb', line 1565

def new_def
  set_specifier_list(Generator.get_statement_specifier)

  # prototype 指定子ないか
  if !@b_prototype
    # 二重定義のチェック
    if @b_defined == true
      cdl_error("S1032 $1: duplicate cell", @name)
      dbgPrint "previous: #{@prev_locale[0]}: line #{@prev_locale[1]} '#{@name}' defined here\n"

      # セルの重複定義エラーの処置
      # 前の定義は捨てる
      @join_list = NamedList.new(nil, "in cell '#{@name}'")
    end

    @b_defined = true
    @prev_locale = @locale
  end
end

#new_join(join, b_regular = false) ⇒ Object

Cell# 新しい結合をチェック

STAGE: P

join

Join : 新しい結合

b_regular

bool : 通常の場所 (bnf.y.rb)からならば true, それ以外(allocator, require) では false



1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
# File 'lib/tecsgen/core/componentobj.rb', line 1594

def new_join(join, b_regular = false)
  join.set_owner self

  # composite の新文法対応.
  # composite の中のセルで、attribute の定義である場合
  # cell 内の attr_ext = composite.attr; 構文を処理
  if @in_composite
    if @celltype
      if @celltype.find(join.get_name).instance_of?(Decl) # mikan a::b で指定されていたものがエラーにならないかも
        rhs = join.get_rhs
        if rhs.instance_of? Expression
          ele = rhs.get_elements
          if ele[0] == :IDENTIFIER #  attr = attr_ext (右辺単項)か? #1
            if CompositeCelltype.has_attribute?(ele[1].get_name) # mikan a::b.ePort がエラーにならないかも
              ident = ele[1].get_name # 右辺は attribute.
            else
              # 右辺は attribute にないのであれば、定数のはず
              # 定数は下へ渡す (cell の join にする)
              ident = nil
            end
          else
            if join.get_rhs.eval_const2(nil).nil? # 定数式ではないか?
              # 右辺が、単一のシンボルでない場合、現状は扱えない
              cdl_error("S1033 rhs expression is not supported. Only attribute is permitted on current version.")
              return
            else
              # 定数は下へ渡す (cell の join にする)
              ident = nil
            end
          end

          if ident
            # attr = attr; のような参照はエラー (a = composite.a とする必要がある)
            if @celltype.find(ident)
              cdl_error("S1034 $1 : cannot refer to $2\'s attribute here. Use \'composite.$3\' to refer to composite celltype\'s", ident, @celltype.get_name, ident)
            end
          end
        elsif rhs.instance_of? Array
          if rhs[0] == :COMPOSITE # 右辺は composite.attr の形式
            ident = rhs[1].to_sym
          else
            ident = nil    # 右辺は { 10, -10 } の形式
          end
        else
          ident = nil      # 右辺は C_EXP の形式
        end

        # ident が見つかった(右辺は単一の ident)
        if ident
          # composite の旧文法の構文処理へ渡す.セル外の attr_ext = Cell.attr; 構文の処理に渡す
          #                        export_name, internal_cell_name, internal_cell_elem_name
          decl = CompositeCelltype.new_join(ident, @name, join.get_name, :ATTRIBUTE) # mikan a::b.ePort がエラーにならないかも
          if !decl.instance_of? Decl
            return
          end
          ini = decl.get_initializer
          if ini.nil?
            return
          end
          # 以下の旧文法実装に渡す.
          # 旧文法では cell に初期値を与えることで、composite で属性の初期値を指定することができた
          # attribute で指定された初期値を cell の属性として処理させる
          join.change_rhs(ini)
        else
          # ident がない.定数式
        end
      else
        # celltype の属性として、この join の名前がない
        # 以下の join.set_definition の中でエラーとなる
      end
    else
      return # celltype がない.すでにエラー
    end
  elsif join.get_rhs.instance_of? Array
    rhs = join.get_rhs
    if rhs[0] == :COMPOSITE
      # composite の中でないのに attr = composite.attr が使われた
      cdl_error("S1035 composite : cannot specify out of composite celltype definition")
      return
    end
  end

  # 以下 composite 文法変更前からある処理

  # 既に左辺が同じ名前の初期化が存在するか?
  j = @join_list.get_item(join.get_name) # mikan NamespacePath がパスを持っている
  if j.instance_of? Join # mikan ここでは j が Join or Nil 以外は、ないはず

    # debug
    dbgPrint "add_array_member: #{@name} port: #{j.get_port_name} rhs: #{j.get_rhs}, #{join.get_port_name} #{join.get_rhs}\n"
    # 呼び口配列(であると仮定して)要素を追加
    j.add_array_member join

  else
    dbgPrint "new_join: cell=#{@name} add_item=#{join.get_name}\n"
    # join
    @join_list.add_item(join)
  end

  # if get_owner then   # error S1030 発生時 get_owner が見つからなくて例外になる
  #   dbgPrint "Cell#new_join: #{get_owner.get_name}.#{@name}\n"
  # else
  #   dbgPrint "Cell#new_join: \"owner not fund\".#{@name}\n"
  # end
  if !@in_composite
    if join.get_cell
      dbgPrint "new_join: #{@name} #{@region.get_name} => #{join.get_cell.get_name} #{join.get_cell.get_region.get_path_string}\n"
    end
#     p "region: generate? #{@region.is_generate?}"
  end
end

#new_reverse_join(reverse_join) ⇒ Object

Cell#新しい逆結合



1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
# File 'lib/tecsgen/core/componentobj.rb', line 1712

def new_reverse_join(reverse_join)
  dbgPrint("new_reverse_join name=#{reverse_join.get_name}\n")
  b_cb = false
  if @celltype
    ep_name = reverse_join.get_name
    port = @celltype.find ep_name
    if port && port.get_signature
      if port.get_signature.is_callback?
        b_cb = true
      end
    end
  end
  if !@b_prototype && !b_cb
    cdl_error("S9999 '$1': reverse join can be used in prototype cell, or with callback signature", @name)
  end
  if @reverse_join_list.nil?
#      @reverse_join_list = NamedList.new( reverse_join, "in cell '#{@name}'" )
    @reverse_join_list = [reverse_join]
  else
#      @reverse_join_list.add_item( reverse_join )
    @reverse_join_list << reverse_join
  end
end

#port_referenced(port) ⇒ Object

Cell# 受け口のport の参照カウントをアップする

port_name

Symbol : ポート名



2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
# File 'lib/tecsgen/core/componentobj.rb', line 2278

def port_referenced(port)
  if @referenced_port_list[port]
    @referenced_port_list[port] += 1
  else
    @referenced_port_list[port] = 1
  end

  # composite か?
  if @celltype.instance_of?(CompositeCelltype)

    # セルタイプ内で port_name の CompositeCelltypeJoin を探す(コード生成段階では必ず見つかる)
    cj = @celltype.find_export(port.get_name)

    dbgPrint " port_referenced: #{@celltype.get_name} #{@name} cj=#{cj && cj.get_name || "nil"}\n"

    if cj # 既にエラー
      # composite の内部のセルに対し再帰的に get_real_port を適用
      cell = @cell_list[cj.get_cell_name.to_s]
      if cell && cell.get_celltype
        cell.port_referenced(cell.get_celltype.find(cj.get_cell_elem_name))
      end
    end
  end
end

#post_code_generated?Boolean

Cell# tmp_plugin_post_code.cdl で生成されたセルか?

Returns:

  • (Boolean)


2165
2166
2167
# File 'lib/tecsgen/core/componentobj.rb', line 2165

def post_code_generated?
  @b_post_code_generated
end


249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/tecsflow.rb', line 249

def print_call_func_flow no_caller_cell, call_func_name, indent_level, parent_cell = []
  m = TECSFlow.analyze_call_port_func_name call_func_name
  if m then
    call_port = m[0]
    function = m[1]
    call_subsc = m[2]
    # print "print_call_func_flow: #{call_func_name} => #{call_port}.#{function}\n"
    # p "call_subsc=", call_subsc
    if call_subsc == nil then
      join = get_join_list.get_item call_port
      print_call_func_flow_sub indent_level, no_caller_cell, call_port, call_subsc, function, join, parent_cell
    else
      # print "call_subsc=#{call_subsc}\n"
      join_0 = get_join_list.get_item call_port
      if join_0 then
        am = join_0.get_array_member2
        call_subsc = 0
        am.each{ |join|
          print_call_func_flow_sub indent_level, no_caller_cell, call_port, call_subsc, function, join, parent_cell
          call_subsc += 1
        }
      else
        print_call_func_flow_sub indent_level, no_caller_cell, call_port, call_subsc, function, join, parent_cell
      end
    end
  else
    # non TECS function
    func = $tcflow_funclist[ call_func_name ]
    if func.kind_of? TCFlow::Function then
      if func.is_printed? then
        indent_level = print_indent indent_level
        print func.get_name, ": printed\n"
      else
        indent_level = print_indent indent_level
        print "#{call_func_name}   [Function Out of TECS]\n"
        func.set_printed
        func.get_call_funcs.each{ |cf, cff|
          no_caller_cell = false
          print_call_func_flow no_caller_cell, cf, indent_level + 1, parent_cell
        }
      end
    else
      indent_level = print_indent indent_level
      print call_func_name, ": [Function Out of TECS, not defined]\n"
    end
      # print "#{"    "*indent_level}fail to analyze #{call_func_name}\n"
  end
end


298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
# File 'lib/tecsflow.rb', line 298

def print_call_func_flow_sub indent_level, no_caller_cell, call_port, call_subsc, function, join, parent_cell
  j = join
  if j != nil then
    if ! $unopt then
      callee_cell = j.get_rhs_cell
      callee_port = j.get_rhs_port.get_name
      callee_subsc = j.get_rhs_subscript
    else
      callee_cell = j.get_rhs_cell1
      callee_port = j.get_rhs_port1
      callee_subsc = j.get_rhs_subscript1
    end
    print_flow indent_level, no_caller_cell, call_port, call_subsc, callee_cell, callee_port, callee_subsc, function
    callee_cell.print_entry_func_flow callee_port, function, indent_level + 1, parent_cell
  else
    if parent_cell.length > 0 then
      # print "len = ", parent_cell.length, "\n"
      composite = parent_cell.last.get_celltype
      compjoin = nil
      # search from exporting ports to find call port which matches inner cell's call port
      composite.get_port_list.each{|cj|
        if cj.get_cell.get_name == @name && cj.get_cell_elem_name == call_port then
          compjoin = cj
          break
        end
      }
      if compjoin then
        indent_level = print_indent indent_level
        if no_caller_cell == false then
          print "[inner]#{@name}."
        end
        print "#{call_port} == "
        j = parent_cell.last.get_join_list.get_item compjoin.get_name
        if j != nil then
          if ! $unopt then
            callee_cell = j.get_rhs_cell
            callee_port = j.get_rhs_port.get_name
            callee_subsc = j.get_rhs_subscript
          else
            callee_cell = j.get_rhs_cell1
            callee_port = j.get_rhs_port1
            callee_subsc = j.get_rhs_subscript1
          end
          no_caller_cell = false
          parent_cell.last.print_flow (-indent_level), no_caller_cell, call_port, call_subsc, callee_cell, callee_port, callee_subsc, function
          pc = parent_cell.dup
          # print "#{pc.last.get_name} POP\n"
          pc.pop
          callee_cell.print_entry_func_flow callee_port, function, indent_level + 1, pc
          # break
        else
          # recursive case, parent's port is joined to grand parent's exporting port.
          cf_name = "->#{compjoin.get_name}.#{function}__T".to_sym
          pc = parent_cell.dup
          # print "func = ", cf_name, "\n"
          # print "#{pc.last.get_name} POP\n"
          pc.pop
          # print parent_cell.last.get_name, ".", compjoin.get_name, ".", function, "\n"
          if indent_level > 0 then
            tmp_indent_level = - indent_level
          else
            tmp_indent_level = indent_level
          end
          no_caller_cell = false
          parent_cell.last.print_call_func_flow no_caller_cell, cf_name, tmp_indent_level, pc
          # break
        end
      else
        # print "name=", @name, "  "
        # composite.get_port_list.each{|cj|
        #  print cj.get_name, ", "
        # }
        print "\n"
        indent_level = print_indent indent_level
        print "#{@name}.#{call_port} not found in composite #{parent_cell.last.get_name}\n"
        # break
      end
    else
      indent_level = print_indent indent_level
      print "#{@name}.#{call_port} not joined\n"
    end   # end while
  end
end

#print_entry_func_flow(entry_port_name, func_name, indent_level, parent_cell) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/tecsflow.rb', line 208

def print_entry_func_flow entry_port_name, func_name, indent_level, parent_cell
  func_nsp = get_function_nsp entry_port_name, func_name, parent_cell
  # print "\nentry:", func_nsp, "\n"
  @@printed_cell_list[ self ] = true
  if @@printed_func_nsp_list[ func_nsp ] then
    # print "\n"
    # print_indent indent_level
    # print func_nsp
    print ": printed\n"
    return
  end
  @@printed_func_nsp_list[ func_nsp ] = true
  if ! @celltype.kind_of? CompositeCelltype
    print "\n"
    ep_func = "#{@celltype.get_global_name}_#{entry_port_name}_#{func_name}".to_sym
    if $tcflow_funclist[ ep_func ] then
      function = $tcflow_funclist[ ep_func ]
      function.set_printed
      function.get_call_funcs.each{ |call_func_name, func|
        # print "#{indent}#{fname} \n"
        # decompose
        no_caller_cell = true
        print_call_func_flow no_caller_cell, call_func_name, indent_level, parent_cell
      }
    else
      indent_level = print_indent indent_level
      print "not found '#{ep_func}' !!!\n"
    end
  else
    cj = @celltype.find_export entry_port_name
    cell = cj.get_cell
    ep_name = cj.get_cell_elem_name
    print " == [inner]#{cell.get_name}.#{ep_name}"
    parent_cell = parent_cell.dup
    # print "\n#{@name} PUSH\n"
    parent_cell.push self
    # parent_cell.each{|c| print c.get_name, "\n" }
    cell.print_entry_func_flow ep_name, func_name, indent_level, parent_cell
  end
end


400
401
402
403
404
405
406
407
# File 'lib/tecsflow.rb', line 400

def print_flow indent_level, no_caller_cell, call_port_name, call_subsc, callee_cell, entry_port_name, callee_subsc, func_name
  indent_level = print_indent indent_level
  no_cell_name = no_caller_cell
  print_name no_cell_name, call_port_name, call_subsc, func_name
  print " => "
  no_cell_name = false
  callee_cell.print_name no_cell_name, entry_port_name, callee_subsc, func_name
end


585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
# File 'lib/tecsgen/core/tecsinfo.rb', line 585

def print_info(f, indent)
  if exclude_info?
    return
  end
  f.print <<EOT

#{indent}/*** #{@global_name} cell information ****/
#{indent}cell nTECSInfo::tCellInfo #{@global_name}CellInfo {
#{indent}    name            = "#{@name}";
#{indent}    cbp             = C_EXP( \"#{@global_name}__CBP\" );
#{indent}    inibp           = C_EXP( \"#{@global_name}__INIBP\" );
#{indent}    cCelltypeInfo   = #{@celltype.get_global_name}CelltypeInfo.eCelltypeInfo;
EOT
  @celltype.get_port_list.each{|port|
    next if port.get_port_type != :ENTRY

    f.print <<EOT
#{indent}    cRawEntryDescriptor[] = #{@global_name}_#{port.get_name}RawEntryDescriptorInfo.eRawEntryDescriptor;
EOT
  }
  f.print "#{indent}};\n"

  # RawEntryDescriptorInfo cells
  @celltype.get_port_list.each{|port|
    next if port.get_port_type != :ENTRY

    size = port.get_array_size
    if size.nil?
      size = 1
    elsif size == "[]"
      size = @entry_array_max_subscript[port]
    end
    if !port.is_omit?
      red = "C_EXP( \"&#{@global_name}_#{port.get_name}_des\" )"
    else
      red = "(void *)0"
    end
    # mikan 受け口配列
    f.print <<EOT
#{indent}cell nTECSInfo::tRawEntryDescriptorInfo #{@global_name}_#{port.get_name}RawEntryDescriptorInfo {
#{indent}   size = #{size};
#{indent}   rawEntryDescriptor = { #{red} };
EOT
#  #{indent}   cEntryInfo = #{@celltype.get_global_name}_#{port.get_name}EntryInfo.eEntryInfo;
    f.print "#{indent}};\n"
  }
end


382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# File 'lib/tecsflow.rb', line 382

def print_name no_cell_name, port_name, subsc, func_name
  if ! no_cell_name then
    nsp = get_namespace_path.to_s.sub( /^::/, "")
    # pp nsp.class.name
    if nsp != "" then
      print nsp, "."
    else
      print @name, "."
    end
  end

  print port_name
  if subsc then
    print '[', subsc, ']'
  end
  print ".", func_name
end

#set_cloned(name, global_name, namespacePath, join_array, parent_ct_name, region, plugin, locale) ⇒ Object

Cell# clone されたセルの内部に持つ名前情報を調整する

name

string : 親 cell の名前 (cell tComposite cell1 での cell1)

global_name

string : 親 cell の global_name

join_array

Join[] : composite の cell の join で、この cell に対応するもの

parent_ct_name

string : 親セルのセルタイプ名(composite セルタイプ)

このメソッドはすぐ上の clone_for_composite から呼出され、clone されたセルを整える


2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
# File 'lib/tecsgen/core/componentobj.rb', line 2033

def set_cloned(name, global_name, namespacePath, join_array, parent_ct_name, region, plugin, locale)
  # debug
  dbgPrint "cell.set_cloned : global_name: #{global_name}  name: #{name}  @name: #{@name}\n"
  dbgPrint "set_cloned:  entry_array_max_subscript.len=#{@entry_array_max_subscript.length}\n"
  @global_name = :"#{global_name}_#{@name}"
  @name = :"#{name}_#{@name}"
  @NamespacePath = namespacePath.change_name @name
  @region = region
  @plugin = plugin
  @locale = locale

  @in_composite = false
  @b_checked = false
  @f_cloned = true

  # Namespace.new_cell( self )  # mikan namespace 対応
  region.new_cell(self) # mikan  namespace に cell を置けないことを仮定

  # join_list : NamedList の clone を作る
  if @celltype
    dbgPrint "set_cloned: #{@celltype.get_name} #{@name} #{region.get_name}\n"
  end
  @join_list = @join_list.clone_for_composite(parent_ct_name, name, locale)
  @referenced_port_list = {}

  @alloc_list = []
  @require_joined_list = {}
  @entry_array_max_subscript = @entry_array_max_subscript.dup
  @cell_list = {}
  @cell_list2 = []

  # このセルのグローバル名を与える
  # C_EXP の$id$ 置換はこのセルの名前になる
  join_array.each {|j|
    @join_list.change_item j
  }
end

#set_definition_joinObject

Cell# Join の definition の設定とチェック

STAGE: S



2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
# File 'lib/tecsgen/core/componentobj.rb', line 2943

def set_definition_join
  return if @celltype.nil?    # 既にエラー:打ち切る
  return if @b_defined == false # プロトタイプ宣言のみ
  return if @b_checked == true  # 既に設定(チェック)済み

  dbgPrint "set_definition_join in #{@name}\n"

  # relay allocator をたどって再入しないよう、先頭で @b_checked を true にする
  @b_checked = true

  if !@f_cloned
    check_restrict_list

    # compoiste セルのクローンされたものは、set_definition 不要
    # 元の join は既に definition されている
    # 元のセルにおいて、代入チェックされているので、二重にチェック(through適用)されてしまう
    @join_list.get_items.each{|join|
      dbgPrint " set_definition_join: checking #{@name}.#{join.get_name}\n"
      if join.get_array_member
        port = @celltype.find(join.get_name)
        join.get_array_member2.each {|am|
          if am.nil? # 未結合の場合、エラーチェックは check_join
            if port && !port.is_optional?
              # テスト用にエラーメッセージ出力
              # cdl_error( "TEMPORAL set_definition_join: uninitialized array member"  )
            end
            next
          end
          am.set_definition(port)
        }
      else
        dbgPrint "set_definition_join: #{@name}.#{join.get_name} celltype=#{@celltype.get_name}\n"
        join.set_definition(@celltype.find(join.get_name))
      end
    }
  end

  # リレー join は through プラグイン生成後にしかできない
  # through 後に結合先が入れ替えられる
  create_relay_allocator_join

  # composite セルの展開
  if !@in_composite && !@f_cloned && @celltype.instance_of?(CompositeCelltype)
    # composite セルタイプ内の composite は展開しない
    # compoiste セル展開中の composite は展開しない (CompositeCelltype::expand 内で再帰的に expnad)
    expand
  end
end

#set_entry_inner_port_max_subscript(port, num) ⇒ Object

Cell# composite の内側セルの受け口配列の添数の最大値を設定



2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
# File 'lib/tecsgen/core/componentobj.rb', line 2370

def set_entry_inner_port_max_subscript(port, num)
  if @cell_list.nil?
    return # プロトタイプ宣言しかされていなくて、内側セルが展開されていない or composite 展開前
  end

  # composite の内側のセルに伝播
  if @celltype.instance_of? CompositeCelltype
    dbgPrint "set_entry_inner_port_max_subscript #{@name} #{@port} #{num} cell_list.len=#{@cell_list.length}\n"
    # @cell_list.each{ |c, p| print c, p, '\n' }

    cj = @celltype.find_export port.get_name
    if cj && @cell_list[cj.get_cell_name.to_s]
      inner_cell = @cell_list[cj.get_cell_name.to_s]
      ct = inner_cell.get_celltype
      if ct
        inner_port = ct.find(cj.get_cell_elem_name)
        inner_cell.set_entry_port_max_subscript(inner_port, num)
      end
    end
  end
end

#set_entry_port_max_subscript(port, num) ⇒ Object

Cell# 受け口配列の添数の最大値を設定



2359
2360
2361
2362
2363
2364
2365
2366
2367
# File 'lib/tecsgen/core/componentobj.rb', line 2359

def set_entry_port_max_subscript(port, num)
  dbgPrint("set_entry_port_max_subscript: #{@name}.#{port.get_name}: #{num}\n")
  subscript = @entry_array_max_subscript[port]

  if subscript.nil? || num > subscript
    @entry_array_max_subscript[port] = num
    set_entry_inner_port_max_subscript(port, num)
  end
end

#set_f_def(f_def) ⇒ Object

Cell# プロトタイプ宣言(false)か定義(true)かを設定

このメソッドは構文解釈の最後に呼出される
f_def

bool false if prototype, true if definition



1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
# File 'lib/tecsgen/core/componentobj.rb', line 1839

def set_f_def(f_def)
  if !f_def
    return
  end

  if !@in_composite
    # if @celltype.instance_of? Celltype then
    if @celltype # composite でも呼びだす, エラー時 nil
      @celltype.new_cell self
    end
    @@cell_list << self
  end
end

#set_f_refObject



1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
# File 'lib/tecsgen/core/componentobj.rb', line 1853

def set_f_ref
  dbgPrint "set_f_ref: #{@global_name}\n"
  @f_ref = true

  # composite の内部セルを参照されたことにする
  # 今のところ問題ないが、未参照であるべきものまで参照されたことになる
  if @cell_list
    @cell_list.each{|cn, cell|
      cell.set_f_ref
    }
  end
end

#set_id(id) ⇒ Object



2337
2338
2339
# File 'lib/tecsgen/core/componentobj.rb', line 2337

def set_id(id)
  @id = id
end

#set_max_entry_port_inner_cellObject

Cell#内部セルの受け口添数最大値を設定



3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
# File 'lib/tecsgen/core/componentobj.rb', line 3009

def set_max_entry_port_inner_cell
  if @cell_list.nil?
    return
  end

  dbgPrint "set_max_entry_port_inner_cell name=#{@name} entry_array_max_subscript.len=#{@entry_array_max_subscript.length}\n"

  # プロトタイプ宣言で設定されていたものを反映する
  @entry_array_max_subscript.each{|port, name|
    dbgPrint "set_entry_inner_port_max_subscript( #{port}, #{name} )\n"
    set_entry_inner_port_max_subscript(port, name)
  }
end

#set_name(name) ⇒ Object



1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
# File 'lib/tecsgen/core/componentobj.rb', line 1494

def set_name(name)
  @name = name
  @local_name = name
  if Namespace.get_global_name&.empty?
    @global_name = name
  else
    @global_name = :"#{Namespace.get_global_name}_#{name}"
  end

  # この時点ではプロトタイプか、定義か分らないが、自己参照のために登録
  # set_f_def で再度登録しなおす
  # Celltype への登録は、end_of_parse で行う
  if @in_composite
    cell_prev = CompositeCelltype.find(name)
    if cell_prev.nil?
      CompositeCelltype.new_cell_in_composite(self)
    end
  else
    # cell_prev = Namespace.find( [ name ] )   # 親まで捜しにいく
    cell_prev = Namespace.get_current.find(name)
    if cell_prev.nil?
      Namespace.new_cell(self)
      set_namespace_path # @NamespacePath の設定
    end
  end

  if cell_prev
    if !cell_prev.instance_of?(Cell)
      cdl_error("S1029 $1 mismatch with previous one", name)
      # celltype が一致しているか ?
    elsif get_celltype != cell_prev.get_celltype
      cdl_error("S1030 $1: celltype mismatch with previous one", name)
    else
      # region が一致しているか?
      if !cell_prev.get_region.equal? get_region
        cdl_error("S1031 $1 region \'$2\' mismatch  with previous one \'$3\'", name, @region.get_name, cell_prev.get_region.get_name)
      end

      @@current_object = cell_prev
      # この時点では、まだプロトタイプ宣言か定義か分らない
      # 以前が定義であって、今回も定義の場合、重複エラーである
    end
  end

  @join_list = NamedList.new(nil, "in cell '#{@name}'")
  @reverse_join_list = nil

  # debug
  dbgPrint "Cell new_cell: #{@global_name} #{@in_composite} #{self}\n"

  # 内部アロケータを @alloc_list に追加
  if @celltype.instance_of? CompositeCelltype
    @celltype.get_internal_allocator_list.each{|cell, cp_internal_name, port_name, fd_name, par_name, ext_alloc_ent|
      nsp = NamespacePath.new(@name, false)
      rhs = Expression.new([:OP_DOT, [:IDENTIFIER, nsp], Token.new(ext_alloc_ent.to_s.to_sym, nil, nil, nil)]) # 1 構文解析段階なので locale 不要

      @alloc_list << [:NORMAL_ALLOC, port_name, nil, fd_name, par_name, rhs]
# print "add alloc_list: #{port_name}.#{fd_name}.#{par_name}=#{rhs.to_s}\n"
    }
  end
end

#set_port_reference_countObject

Cell# 受け口のport の参照カウントを設定する

self は呼び元のセル 呼び先セルの受け口の参照カウントをアップする



2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
# File 'lib/tecsgen/core/componentobj.rb', line 2561

def set_port_reference_count
  @join_list.get_items.each {|j|
    if j.get_definition.instance_of? Port
      am = j.get_array_member2
      if am # 呼び口配列
        am.each {|j2|
          next if j2.nil? # optional で一部が欠落しているケース
          cell = j2.get_rhs_cell2
          next if cell.nil? # 右辺が見つからなかった.既にエラー
          port = cell.get_celltype.find(j2.get_rhs_port2)
          dbgPrint("set_port_reference_count: #{@name}.#{j2.get_name} => #{cell.get_name}.#{port.get_name}\n")
          cell.port_referenced port
        }
      else
        cell = j.get_rhs_cell2
        next if cell.nil? || cell.get_celltype.nil? # 右辺が見つからなかった.既にエラー
        port = cell.get_celltype.find(j.get_rhs_port2)
        if port.nil?
          dbgPrint "set_port_ref: #{@name}.#{j.get_name} = #{cell.get_name}.#{j.get_rhs_port2}\n"
          # through プラグインで生成されたセルの受け口が見つからないケース (のハズ)
          cdl_error("entry '$1' not found in '$2' refered from $3.$4", j.get_rhs_port2, cell.get_name, @name, j.get_name)
          next
        end
        dbgPrint("set_port_reference_count: #{@name}.#{j.get_name} => #{cell.get_name}.#{port.get_name}\n")
        cell.port_referenced port
      end
    end
  }
end

#set_require_join(cp_name, cell_or_ct, port) ⇒ Object

Cell# require 呼び口の結合を行う

STAGE: S

cp_name

Symbol : 呼び口名

cell_or_t

Celltype|Cell : celltype の require の右辺で指定されたセルタイプまたはセル

port

Port : celltype の Port オブジェクト



2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
# File 'lib/tecsgen/core/componentobj.rb', line 2899

def set_require_join(cp_name, cell_or_ct, port)
  # set_require_join は2度呼び出される
  # 2度目は post コードを生成した後       #####  いったん見合わせ(重複エラーを見逃す)
  # if @require_joined_list[ cp_name ] then
  #   return
  # else
  #   @require_joined_list[ cp_name ] = true
  # end

  dbgPrint "set_require_join: #{@name}.#{cp_name} = #{cell_or_ct.get_name}.#{port.get_name}\n"

  if cell_or_ct.instance_of? Celltype
    # print "DOMAIN: not considered\n"
    cell = cell_or_ct.get_singleton_cell @region
    if cell.nil?
      cdl_error("S1025 not found reachable cell for require \'$1\' in celltype \'$2\'", port.get_name, cell_or_ct.get_name)
      return
    end
  else
    # require: cell で指定
    cell = cell_or_ct
    if @region.distance(cell.get_region).nil?
      cdl_error("S1026 required cell \'$1\' not reachable", cell.get_name)
    end
  end

  if @join_list.get_item(cp_name)
    cdl_warning("W1003 $1 : require call port overridden in $2", cp_name, @name)
  else
    # require の join を生成(呼び口の結合)
#      rhs = Expression.new( [ :OP_DOT, [ :IDENTIFIER, Token.new( cell.get_name, nil, nil, nil ) ],
    nsp = NamespacePath.new(cell.get_name, false, cell.get_namespace)
    nsp.set_locale @locale
    rhs = Expression.new([:OP_DOT, [:IDENTIFIER, nsp],
                            Token.new(port.get_name, nil, nil, nil)], @locale) # 1
    join = Join.new(cp_name, nil, rhs, @locale)
    self.new_join(join)

    join.set_definition(@celltype.find(join.get_name))
  end
end

#set_specified_id(id) ⇒ Object

id 指定子の値を設定

このメソッドは、プラグインで cell の生成順序を制御したい場合のために設けた 通常の id 指定子では使っていない



1956
1957
1958
1959
1960
1961
1962
1963
1964
# File 'lib/tecsgen/core/componentobj.rb', line 1956

def set_specified_id(id)
  if Integer(id) != id || id <= 0
    cdl_error("S1164 '$1' set_specified_id: id not positive integer '$2'", @name, id)
  elsif @id_specified
    cdl_error("S1165 '$1' set_specified_id: id duplicate", @name)
  else
    @id_specified = id
  end
end

#set_specifier_list(spec_list) ⇒ Object

Cell# cell の指定子を設定

STAGE: B

bnf.y.rb  statement_specifiler_list
spec_list
:ALLOCATOR, [ [ :NORMAL_ALLOC, ep_name, subscript, func_name, param_name, expr ], …

]

s[0]      s[1]   a[0]        a[1]       a[2]        a[3]     a[4]       a[5]
セルに指定されたアロケータ指定子
a[1] の subscript はこのメソッドの中で Expression から Integer に評価される
受け口側に生成されるアロケータ呼び口の結合を内部生成する
呼び口側は Port の create_allocator_join にて生成
リレーアロケータの場合 create_relay_allocator_join にて生成す


1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
# File 'lib/tecsgen/core/componentobj.rb', line 1877

def set_specifier_list(spec_list)
  return if spec_list.nil? # 空ならば何もしない

  dbgPrint("set_spec_list: #{@name}\n")
  b_generate = false # generate が指定された

  spec_list.each{|s|
    case s[0]             # statement_specifier
    when :ALLOCATOR       # [allocator(ePort.func.param=allocCell.eA,ePort.func2.param=allocCell.eA)]
      s[1].each {|a|     # alloc_list : allocator の内部の ',' で区切られた部分の配列
        cp_name = :"#{a[0 + 1]}_#{a[2 + 1]}_#{a[3 + 1]}" # アロケータ呼び口の名前:'=' の左辺を '.' に変えて '_' で連結
        # p "#{a[0]} #{a[0+1]} #{a[2+1]} #{a[3+1]} #{cp_name}"
        if a[1 + 1]
          subscript = a[1 + 1].eval_const nil
          a[1 + 1] = subscript
        else
          subscript = nil
        end
        # アロケータ呼び口の結合を生成
        join = Join.new(cp_name, subscript, a[4 + 1]) # 構文解析段階なので locale 不要
        dbgPrint("new allocator join #{cp_name} #{subscript} #{a[4 + 1]}\n")
        Cell.new_join(join)
        @alloc_list << a
      }
    when :ID # [id(0)]
      if !s[1].instance_of? Expression
        cdl_error("S1160 $1 must be constant for id", s[1].to_s)
      else
        id = s[1].eval_const nil
        if id.nil? || Integer(id) != id
          cdl_error("S1161 $1 must be constant for id", s[1].to_s)
        elsif id == 0
          cdl_error("S1162 $1: id cannot be 0", s[1].to_s)
        else
          @id_specified = id
        end
      end
    when :GENERATE # [generate(CellPlugin,"option")]
      if @generate
        cdl_error("S1163 generate specifier duplicate")
      end
      @generate = [s[1], s[2]] # [ PluginName, "option" ]
      b_generate = true
    when :PROTOTYPE     # [prototype]
      @b_prototype = true
    when :RESTRICT      # [restrict]
      s[1].each{|re|
        add_restrict re[0], re[1], re[2]
      }
    else
      cdl_error("S1039 \'$1\': unknown specifier for cell", s[0])
    end
  }
  if @b_prototype
    if b_generate
      cdl_error("S9999 '$1': generate and prototype specified simultaneously", @name)
    end
    if @b_defined
      cdl_error("S9999 '$1': prototype specified after definition", @name)
    end
  end
end

#show_tree(indent) ⇒ Object



3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
# File 'lib/tecsgen/core/componentobj.rb', line 3132

def show_tree(indent)
  indent.times { print "  " }
  puts "Cell: name: #{@name} in_composite: #{@in_composite} def: #{@b_defined} ref: #{@f_ref} cloned: #{@f_cloned}"
  (indent + 1).times { print "  " }
  puts "Cell locale: #{@name}@#{@locale[0]}##{@locale[1]}"
  (indent + 1).times { print "  " }
  puts "id: #{@id}  global_name: #{@global_name}  region: #{@region.get_name} plugin: #{@plugin.class.name} #{self}"
  (indent + 1).times { print "  " }
  puts "namespace_path: #{@NamespacePath}"

  if @celltype
    (indent + 1).times { print "  " }
    puts "celltype: #{@celltype.get_name}"
  end
  @join_list.show_tree(indent + 1)
  @entry_array_max_subscript.each{|port, num|
    (indent + 1).times { print "  " }
    puts "entry array #{port.get_name}: max subscript=#{num}"
  }
  if @cell_list # ここで @cell_list が nil なのは Bug
    (indent + 1).times { print "  " }
    puts "cloned cell list:"
    @cell_list.each {|n, c|
      (indent + 2).times { print "  " }
      puts "inner cell : #{n} = #{c.get_name}"
    }
  end
  if @compositecelltypejoin_list
    @compositecelltypejoin_list.get_items.each{|cj|
      cj.show_tree(indent + 1)
    }
  end
  if @alloc_list.length > 0
    (indent + 1).times { print "  " }
    puts "allocator list: "
    @alloc_list.each {|a|
      cp_name = :"#{a[0 + 1]}_#{a[2 + 1]}_#{a[3 + 1]}"
      if a[1 + 1]
        # subscript = "[#{a[1+1].eval_const nil}]"
        subscript = "[#{a[1 + 1]}]"
      else
        subscript = ""
      end
      # アロケータ呼び口の結合を生成
      (indent + 2).times { print "  " }
      puts "#{cp_name}#{subscript} = #{a[4 + 1]}"
    }
  end
  @referenced_port_list.each{|port, count|
    (indent + 1).times { print "  " }
    puts("#{port.get_name} : #{count} times referenced")
  }
end

#unjoin_pluginObject



169
170
171
172
173
# File 'lib/tecsgen/core/unjoin_plugin.rb', line 169

def unjoin_plugin
  @generate = nil
  @plugin   = nil
  @join_list.get_items.each{ |j| j.unjoin_plugin }
end