Class: Join

Inherits:
BDNode show all
Includes:
PluginModule
Defined in:
lib/tecsgen/core/componentobj.rb,
lib/tecsgen/core/unjoin_plugin.rb

Defined Under Namespace

Classes: ThroughPluginProxy

Constant Summary collapse

@@through_count =
{ }
@@plugin_creating_join =

プラグインへの引数で渡さないものを、一時的に記憶しておく プラグインの initialize の中でコールバックして設定する

nil
@@start_region =
nil
@@end_region =
nil
@@through_type =
nil
@@region_count =
nil

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PluginModule

gen_plugin_post_code, #generate_and_parse, #load_plugin

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(name, subscript, rhs, locale = nil) ⇒ Join

Join# 初期化

name

string: 名前(属性名、呼び口名)

subscript

Nil=非配列, -1=“[]”, N=“

rhs

Expression: 右辺の式


5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
# File 'lib/tecsgen/core/componentobj.rb', line 5167

def initialize(name, subscript, rhs, locale = nil)
  # dbgPrint "Join#new: #{name}, #{subscript} #{rhs.eval_const(nil)}\n"
  dbgPrint "Join#new: #{name}, #{subscript}\n"

  super()
  if locale
    @locale = locale
  end

  @name = name
  if subscript.instance_of?(Expression)
     # mikan 配列添数が整数であることを未チェック
    @subscript = subscript.eval_const(nil)
     if @subscript.nil?
       cdl_error("S1099 array subscript not constant")
     end
  else
    @subscript = subscript
  end

  @rhs = rhs
  @definition = nil

  # 配列要素を設定
  # 本当は、初出の要素のみ設定するのが適当
  # new_join で add_array_member の中で初出要素の array_member に対し設定する
  if @subscript == -1
    @array_member  = [self]
    @array_member2 = [self]
  elsif !@subscript.nil?
    @array_member = []
    @array_member2 = []
    @array_member[@subscript]  = self
    @array_member2[@subscript] = self
  end

  @through_list = []
  @cp_through_list = []
  @region_through_list = []
  @through_generated_list = []
  @region_through_generated_list = []
end

Class Method Details

.set_through_info(plugin_object) ⇒ Object

Join# ThroughPlugin の追加情報を設定する

このメソッドは ThroughPlugin#initialize から呼び出される plugin_object を生成する際の引数では不足する情報を追加する


5860
5861
5862
5863
5864
5865
# File 'lib/tecsgen/core/componentobj.rb', line 5860

def self.set_through_info(plugin_object)
  plugin_object.set_through_info(@@start_region, @@end_region, @@through_type,
                                  @@plugin_creating_join,
                                  @@plugin_creating_join.get_cell,
                                  @@region_count)
end

Instance Method Details

#add_array_member(join2) ⇒ Object

Join# 呼び口配列の2番目以降の要素を追加する

一番最初に定義された配列要素が全要素の初期値の配列を持つ
このメソッドは非配列の場合も呼出される(join 重複エラーの場合)
join2

Join 呼び口配列要素の Join


6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
# File 'lib/tecsgen/core/componentobj.rb', line 6091

def add_array_member(join2)
  # subscript2: join2 の左辺添数
  subscript2 = join2.get_subscript

  if @subscript.nil? # not array : initialize duplicate
    # 非配列の場合、join が重複している
    cdl_error("S1127 \'$1\' duplicate", @name)
    # print "add_array_member2: #{@owner.get_name}\n"

  elsif @subscript >= 0
    # 添数指定ありの場合
    if subscript2.nil? || subscript2 < 0
      # join2 左辺は非配列または添数なし
      # 配列が不一致
      cdl_error("S1128 \'$1\' inconsistent array definition", @name)
    elsif !@array_member[subscript2].nil?
      # 同じ添数が既に定義済み
      cdl_error("S1129 \'$1\' redefinition of subscript $2", @name, subscript2)
    else
      # 添数の位置に要素を追加
      @array_member[subscript2] = join2.get_rhs
      @array_member2[subscript2] = join2
#        p "0:#{join2.get_rhs}"
    end

  else
    # 添数指定なしの場合
    if subscript2.nil? || subscript2 >= 0
      # join2 左辺は非配列または添数有
      # 配列が不一致
      cdl_error("S1130 \'R1\' inconsistent array definition", @name)
    end

    # 添数なし配列の場合、配列要素を追加
    @array_member  << join2.get_rhs
    @array_member2 << join2
  end
end

#change_name(name) ⇒ Object


6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
# File 'lib/tecsgen/core/componentobj.rb', line 6138

def change_name(name)
  # debug
  dbgPrint "change_name: #{@name} to #{name}\n"

  @name = name

  if @array_member2
    i = 0
    while i < @array_member2.length
      if @array_member2[i] != self && !@array_member[i].nil?
        # @array_member2[i] が nil になるのは optional の時と、
        # Join の initialize で無駄に @array_member2 が設定されている場合
        # 無駄に設定されているものについては、再帰的に呼び出す必要はない(clone_for_composite では対策している)
        @array_member2[i].change_name(name)
      end
      i += 1
    end
  end
end

#change_rhs(rhs) ⇒ Object

Join# rhs を入れ換える

rhs

Expression | initializer

右辺を入れ換える. このメソッドは、composite で cell の属性の初期値を attribute の値で置き換えるのに使われる このメソッドは composite 内の cell の属性の初期値が定数ではなく式になった場合、不要になる


6281
6282
6283
# File 'lib/tecsgen/core/componentobj.rb', line 6281

def change_rhs(rhs)
  @rhs = rhs
end

#change_rhs_port(clone_cell_list, celltype) ⇒ Object

composite cell を展開したセルの結合を clone したセルの名前に変更


6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
# File 'lib/tecsgen/core/componentobj.rb', line 6159

def change_rhs_port(clone_cell_list, celltype)
  dbgPrint "change_rhs_port: name=#{@name}\n"

  # debug
  if $debug
#    if @name == :cCallB then
    # dbgPrint "change_rhs name: #{@name}  cell_name: #{@cell_name} #{@cell} #{self}\n"
    print "============\n"
    print "CHANGE_RHS change_rhs name: #{@owner.get_name}.#{@name}  rhs cell_name: #{@cell_name} #{@cell} #{self}\n"

    clone_cell_list.each{|cell, ce|
      # dbgPrint "=== change_rhs:  #{cell.get_name}=#{cell} : #{ce.get_name}\n"
      print "   CHANGE_RHS  change_rhs:  #{cell.get_name}=#{cell} : #{ce.get_name}\n"
    }
    print "============\n"
  end

  c = clone_cell_list[@cell]
  return if c.nil?

  # debug
  dbgPrint "  REWRITE cell_name:  #{@owner.get_name}   #{@cell_name} => #{c.get_global_name}, #{c.get_name}\n"

  # @rhs の内容を調整しておく(この内容は、subscript を除いて、後から使われていない)
  elements = @rhs.get_elements
  if elements[0] == :OP_SUBSC # 右辺:受け口配列?
    elements  = elements[1]
  end

  # 右辺が cell.ePort の形式でない
  if elements[0] != :OP_DOT || elements[1][0] != :IDENTIFIER # 1
    return
  else
    # セル名を composite 内部の名前から、外部の名前に入れ替える
    # elements[1][1] = Token.new( c.get_name, nil, nil, nil )
    elements[1][1] = NamespacePath.new(c.get_name, false, c.get_namespace)
  end

  @cell_name = c.get_name
  @cell = c
  # @definition = nil          # @definition が有効: チェック済み(とは、しない)

  if @array_member2

    # debug
    dbgPrint "array_member2.len : #{@array_member.length}\n"

    i = 0
    while i < @array_member2.length
      # @array_member2[i] が nil になるのは optional の時と、
      # Join の initialize で無駄に @array_member2 が設定されている場合
      # 無駄に設定されているものについては、再帰的に呼び出す必要はない(clone_for_composite では対策している)
      if @array_member2[i] != self && !@array_member[i].nil?
        dbgPrint "change_rhs array_member #{i}: #{@name}  #{@cell_name}\n"
        @array_member2[i].change_rhs_port(clone_cell_list, celltype)
      end
      i += 1
    end
  end
end

#check_and_gen_throughObject

Join# through のチェックと生成

new_join の中の check_region で region 間の through が @region_through に設定される set_specifier で呼び口の結合で指定された through が @cp_through 設定される その後、このメソッドが呼ばれる


5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
# File 'lib/tecsgen/core/componentobj.rb', line 5664

def check_and_gen_through
  dbgPrint "check_and_gen_through #{@owner.get_name}.#{@name}\n"

  if !@definition.instance_of? Port
    cdl_error("S1123 $1 : not port: \'through\' can be specified only for port", @name)
    return
  end
  if @cp_through_list.length > 0
    # is_empty? must check before is_omit?
    if @definition.get_signature && @definition.get_signature.is_empty?
      cdl_warning("W9999 'through' is specified for empty signature, ignored")
      return
    elsif @definition.is_omit?
      cdl_warning("W9999 'through' is specified for omitted port, ignored")
      return
    end
  end

  @through_list = @cp_through_list + @region_through_list
    # 後から @cp_through_list と @region_through_list に分けたため、このような実装になった

  if @through_list # nil when the join is not Port
    len = @through_list.length # through が連接している数
  else
    len = 0
  end
  cp_len = @cp_through_list.length

  if @owner.is_in_composite? && len > 0
    cdl_error("S1177 cannot specify 'through' in composite in current version")
    return
  end

  # 連続した through について、受け口側から順にセルを生成し解釈する
  i = len - 1
  while i >= 0

    through = @through_list[i]
    plugin_name           = through[0]
    generating_cell_name  = through[1]
    plugin_arg            = through[2]

    if i != len - 1

      begin
        next_cell_nsp       = @through_generated_list[i + 1].get_cell_namespace_path
        next_port_name      = @through_generated_list[i + 1].get_through_entry_port_name
        next_port_subscript = @through_generated_list[i + 1].get_through_entry_port_subscript
      rescue Exception => evar
        cdl_error("S1124 $1: plugin function failed: \'get_through_entry_port_name\'", plugin_name)
        print_exception(evar)
        i -= 1
        next
      end

      next_cell = Namespace.find(next_cell_nsp) # 1
      if next_cell.nil?
        # p "next_cell_path: #{next_cell_nsp.get_path_str}"
        cdl_error("S1125 $1: not generated cell \'$2\'", @through_generated_list[i + 1].class, next_cell_nsp.get_path_str)
        return
      end

    else
      # 最後のセルの場合、次のセルの名前、ポート名
      next_cell      = @cell
      next_port_name = @port_name
      next_port_subscript = @rhs_subscript

      if next_cell.nil?
        # 結合先がない
        return
      end
    end

    if i >= cp_len
      # region_through_list 部分
      # region から @cell_name.@port_name への through がないか探す
      # rp = @through_list[i][3].find_cell_port_through_plugin( @cell_name, @port_name ) #762
      rp = @through_list[i][3].find_cell_port_through_plugin(@cell.get_global_name, @port_name, @rhs_subscript)
         # @through_list[i] と @region_through_list[i-cp_len] は同じ
      # 共用しないようにするには、見つからなかったことにすればよい
      # rp = nil
    else
      # region 以外のものは共有しない
      # 呼び口側に指定されているし、plugin_arg が異なるかもしれない
      rp = nil
    end

    if rp.nil?
      plClass = load_plugin(plugin_name, ThroughPlugin)
      if plClass
        gen_through_cell_code_and_parse(plugin_name, i, next_cell, next_port_name, next_port_subscript, plClass)
      end
    else
      # 見つかったものを共用する
      @through_generated_list[i] = rp
    end

    if i >= cp_len
      # @through_generated_list のうち @region_through_listに対応する部分
      @region_through_generated_list[i - cp_len] = @through_generated_list[i]
      if rp.nil?
        # 生成したものを region(@through_list[i][3]) のリストに追加
        # @through_list[i][3].add_cell_port_through_plugin( @cell_name, @port_name, @through_generated_list[i] ) #762
        @through_list[i][3].add_cell_port_through_plugin(@cell.get_global_name, @port_name, @rhs_subscript, @through_generated_list[i])
      end
    end

    if i == 0
      # 最も呼び口側のセルは、CDL 上の結合がないため、参照されたことにならない
      # mikan namespace 対応
      # cell = Namespace.find( [ @through_generated_list[0].get_cell_name] )    #1
      if @through_generated_list[0].nil?
        return # plugin_object の生成に失敗している
      end
      cell = Namespace.find(@through_generated_list[0].get_cell_namespace_path) # 1
      if cell.instance_of? Cell
        cell.set_f_ref
      end
    end

    i -= 1
  end
end

#check_call_port_initObject

Join# 呼び口の初期化チェック


5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
# File 'lib/tecsgen/core/componentobj.rb', line 5262

def check_call_port_init
  ### Port

  # 左辺は受け口か(受け口を初期化しようとしている)?
  if @definition.get_port_type == :ENTRY
    cdl_error("S1101 \'$1\' cannot initialize entry port", @name)
    return
  end

#      # 配列添数の整合性チェック
#      # 呼び口の定義で、非配列なら添数なし、添数なし配列なら添数なし、添数あり配列なら添数あり
  as = @definition.get_array_size
  if @subscript.nil? && !as.nil?
    cdl_error("S1102 $1: must specify array subscript here", @name)
  elsif !@subscript.nil? && as.nil?
    cdl_error("S1103 $1: cannot specify array subscript here", @name)
  end
#    if @subscript == nil then
#      if as != nil then
#        cdl_error( "S1103 $1: need array subscript" , @name )
#      end
#    elsif @subscript == -1 then
#      if as != "[]" then
#        cdl_error( "S1104 $1: need array subscript number. ex. \'[0]\'" , @name )
#      end
#    else # @subscript >0
#      if as == nil then
#        cdl_error( "S1105 $1: cannot specify array subscript here" , @name )
#      elsif as == "[]" then
#        cdl_error( "S1106 $1: cannot specify array subscript number. use \'[]\'" , @name )
#      end
#    end

  # mikan Expression の get_type で型導出させる方がスマート
  # mikan '=' の左辺が配列かどうか未チェック
  # (1) '=' の右辺は "Cell.ePort" の形式か?
  #     演算子は "."  かつ "." の左辺が :IDENTIFIER
  #     "." の右辺はチェック不要 (synatax 的に :IDENTIFIER)
  # (2) "Cell" は存在するか?(名前が一致するものはあるか)
  # (3) "Cell" は cell か?
  # (4) "Cell" の celltype は有効か? (無効なら既にエラー)
  # (5) "ePort" は "Cell" の celltype 内に存在するか?
  # (6) "ePort" は entry port か?
  # (7) signature は一致するか

  # 右辺がない(以前の段階でエラー)
  return unless @rhs

  # cCall = composite.cCall; のチェック.この形式は属性用
  # 呼び口を export するには cCall => composite.cCall; の形式を用いる
  if @rhs.instance_of?(Array) == true && @rhs[0] == :COMPOSITE
    cdl_error("S1107 to export port, use \'cCall => composite.cCall\'")
    return
  elsif !@rhs.instance_of?(Expression)
    raise "Unknown bug. specify -t to find problem in source"
  end

  # 右辺の Expression の要素を取り出す
  ret = @rhs.analyze_cell_join_expression
  if ret.nil? # 1
    cdl_error("S1108 $1: rhs not \'Cell.ePort\' form", @name)
    return
  end

  nsp, @rhs_subscript, @port_name = ret[0], ret[1], ret[2]
  @cell_name = nsp.get_name # mikan ns::cellname の形式の考慮

  # composite の定義の中なら object は結合先 cell か、見つからなければ nil が返る
  # composite の定義外なら false が返る
  object = CompositeCelltype.find(@cell_name)
  if object == false
#     mikan 左辺が namespace に対応していないため。 path にして find
    # p nsp.get_path_str, nsp.get_path
    object = Namespace.find(nsp) # 1
    in_composite = false
  else
    if nsp.get_path.length != 1
      cdl_error("$1 cannot have path", nsp.get_path_str)
    end
    in_composite = true
  end

  if object.nil? # (2)
    cdl_error("S1109 \'$1\' not found", nsp.to_s)
  elsif !object.instance_of?(Cell) # (3)
    cdl_error("S1110 \'$1\' not cell", nsp.to_s)
  else
    dbgPrint "set_definition: set_f_ref #{@owner.get_name}.#{@name} => #{object.get_name}\n"
    object.set_f_ref

    # 右辺のセルのセルタイプ
    celltype = object.get_celltype

    if celltype                                                # (4)
      object2 = celltype.find(@port_name)
      if object2.nil?                                        # (5)
        cdl_error("S1111 \'$1\' not found", @port_name)
      elsif !object2.instance_of? Port \
           || object2.get_port_type != :ENTRY                  # (6)
        cdl_error("S1112 \'$1\' not entry port", @port_name)
      elsif @definition.get_signature != object2.get_signature # (7)
        cdl_error("S1113 \'$1\' signature mismatch", @port_name)
      elsif object2.get_array_size
        # 受け口配列

        unless @rhs_subscript
          # 右辺に添数指定がなかった
          cdl_error("S1114 \'$1\' should be array", @port_name)
        else

          as = object2.get_array_size
          if as.is_a?(Integer) && as <= @rhs_subscript
            # 受け口配列の大きさに対し、右辺の添数が同じか大きい
            cdl_error("S1115 $1[$2]: subscript out of range (< $3)", @port_name, @rhs_subscript, as)
          else
            dbgPrint "Join OK #{@owner.get_name}.#{@name}[#{@rhs_subscript}] = #{object.get_name}.#{@port_name} #{self}\n"
            @cell = object
            @celltype = celltype
            @port = object2
            # 右辺のセルの受け口 object2 を参照済みにする
            # object2: Port, @definition: Port
            @cell.set_entry_port_max_subscript(@port, @rhs_subscript)
          end

          # debug
          dbgPrint "Join set_definition: rhs: #{@cell}  #{@cell.get_name if @cell}\n"

        end
      elsif @rhs_subscript
        # 受け口配列でないのに右辺で添数指定されている
        cdl_error("S1116 \'$1\' entry port is not array", @port_name)
      else
        dbgPrint "Join OK #{@owner.get_name}.#{@name} = #{object.get_name}.#{@port_name} #{self}\n"
        @cell = object
        @port = object2
        @celltype = celltype

        # 右辺のセル object の受け口 object2 を参照済みにする
        # object2: Port, @definition: Port

        # debug
        # p "rhs:  #{@cell}  #{@cell.get_name}"
      end # end of port (object2) チェック

      # else
      #  celltype == nil (すでにエラー)
    end # end of celltyep チェック


    check_region(object)

  end # end of cell (object) チェック
end

#check_region(object) ⇒ Object

Join# リージョン間の結合をチェック

リージョン間の through による @region_through_list の作成 実際の生成は check_and_gen_through で行う mikan Cell#distance とRegion へたどり着くまでための処理に共通部分が多い


5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
# File 'lib/tecsgen/core/componentobj.rb', line 5454

def check_region(object)
  # debug
  dbgPrint "check_region #{@owner.get_name}.#{@name} => #{object.get_name}\n"
  # print "DOMAIN: check_region #{@owner.get_name}.#{@name} => #{object.get_name}\n"

  # プラグインで生成されたなかでは生成しない
  # さもないとプラグイン生成されたものとの間で、無限に生成される
##    if Generator.get_nest >= 1 then
##    if Generator.get_plugin then     # mikan これは必要? (意味解析段階での実行になるので不適切)
  if @owner.get_plugin.is_a?(ThroughPlugin)
    # プラグイン生成されたセルの場合、結合チェックのみ
    return
  end

  # region のチェック
  r1 = @owner.get_region      # 呼び口セルの region
  r2 = object.get_region      # 受け口セルの region

  if !r1.equal? r2 # 同一 region なら呼出し可能

    f1 = r1.get_family_line
    len1 = f1.length
    f2 = r2.get_family_line
    len2 = f2.length

    # 不一致になるところ(兄弟)を探す
    i = 1 # i = 0 は :RootRegion なので必ず一致
    while i < len1 && i < len2
      if f1[i] != f2[i]
        break
      end
      i += 1
    end

    sibling_level = i # 兄弟となるレベル、もしくはどちらか一方が終わったレベル

    dbgPrint "sibling_level: #{i}\n"
    dbgPrint "from: #{f1[i].get_name}\n" if f1[i]
    dbgPrint "to: #{f2[i].get_name}\n" if f2[i]

    if f1[sibling_level] && f2[sibling_level]
      b_to_through = true
    else
      b_to_through = false
    end


    # 呼び側について呼び元のレベルから兄弟レベルまで(out_through をチェックおよび挿入)
    i = len1 - 1
    if b_to_through
      end_level = sibling_level
    else
      end_level = sibling_level - 1
    end
    while i > end_level
    # while i > sibling_level
    # while i >= sibling_level
      dbgPrint "going out from #{f1[i].get_name} level=#{i}\n"
      region_count = f1[i].next_out_through_count
      out_through_list = f1[i].get_out_through_list # [ plugin_name, plugin_arg ]
      domain = f1[i].get_domain_type
      if domain
        domain_through = f1[i].get_domain_type.add_through_plugin(self, f1[i], f1[i - 1], :OUT_THROUGH)
        if domain_through.nil?
          cdl_error("S9999 $1: going out from regin '$2' not permitted by domain '$3'", @name, f1[i].get_name, f1[i].get_domain_type.get_name)
        end
      elsif out_through_list.length == 0
        cdl_error("S1118 $1: going out from region \'$2\' not permitted", @name, f1[i].get_name)
      end

      out_through_list.each {|ol|
        if ol[0] # plugin_name が指定されていなければ登録しない
          plugin_arg = CDLString.remove_dquote ol[1]
          through = [ol[0], :Join_out_through_, plugin_arg, f1[i], f1[i - 1], :OUT_THROUGH, region_count]
          @region_through_list << through
        end
      }
      if domain_through && domain_through.length > 0
        through = [domain_through[0], :Join_domain_out_through_, domain_through[1], f1[i], f1[i - 1], :OUT_THROUGH, region_count]
        @region_through_list << through
      end
      i -= 1
    end

    # 兄弟レベルにおいて(to_through をチェックおよび挿入)
    if f1[sibling_level] && f2[sibling_level]
      dbgPrint "going from #{f1[sibling_level].get_name} to #{f2[sibling_level].get_name}\n"
      found = 0
      region_count = f1[i].next_to_through_count(f2[sibling_level].get_name) # to_through の region カウント
      f1[sibling_level].get_to_through_list.each {|t|
        if t[0][0] == f2[sibling_level].get_name # region 名が一致するか ?
          if t[1] # plugin_name が指定されていなければ登録しない
            plugin_arg = CDLString.remove_dquote t[2]
            through = [t[1], :Join_to_through__, plugin_arg, f1[sibling_level], f2[sibling_level], :TO_THROUGH, region_count]
            @region_through_list << through
          end
          found = 1
        end
      }
      domain = f1[sibling_level].get_domain_type
      if domain
        domain_through = f1[sibling_level].get_domain_type.add_through_plugin(self, f1[sibling_level], f2[sibling_level], :TO_THROUGH)
        if domain_through.nil?
          cdl_error("S9999 $1: going from regin '$2' not permitted by domain'$3'", @name, f1[sibling_level].get_name, f2[sibling_level].get_domain_type.get_name)
        end
        if domain_through && domain_through.length > 0
          through = [domain_through[0], :Join_domain_to_through_, domain_through[1], f1[sibling_level], f2[sibling_level], :TO_THROUGH, region_count]
          @region_through_list << through
        end
      elsif found == 0
        cdl_error("S1119 $1: going from region \'$2\' to \'$3\' not permitted", @name, f1[sibling_level].get_name, f2[sibling_level].get_name)
      end
    end

    # 受け側について兄弟レベルから受け側のレベルまで(in_through をチェックおよび挿入)
    if b_to_through
      i = sibling_level + 1 # to_through を経た場合、最初の in_through は適用しない
    else
      i = sibling_level
    end
    while i < len2
      dbgPrint "going in to #{f2[i].get_name} level=#{i}\n"
      region_count = f2[i].next_in_through_count
      in_through_list = f2[i].get_in_through_list # [ plugin_name, plugin_arg ]
      domain = f2[i].get_domain_type
      if domain
        domain_through = f2[i].get_domain_type.add_through_plugin(self, f2[i - 1], f2[i], :IN_THROUGH)
        if domain_through.nil?
          cdl_error("S9999 $1: going in from regin '$2' to '$3' not permitted by domain '$4'",
                      @name, f2[i - 1].get_name, f2[i].get_name, f2[i].get_domain_type.get_name)
        end
        if domain_through && domain_through.length > 0
          through = [domain_through[0], :Join_domain_in_through_, domain_through[1], f2[i - 1], f2[i], :IN_THROUGH, region_count]
          @region_through_list << through
        end
      elsif in_through_list.length == 0
        cdl_error("S1120 $1: going in to region \'$2\' not permitted", @name, f2[i].get_name)
      end
      in_through_list.each {|il|
        if il[0] # plugin_name が指定されていなければ登録しない
          plugin_arg = CDLString.remove_dquote il[1]
          through = [il[0], :Join_in_through_, plugin_arg, f2[i - 1], f2[i], :IN_THROUGH, region_count]
          @region_through_list << through
        end
      }
      i += 1
    end

  end
end

#check_region2Object

Join# 生成しないリージョンへの結合かチェック

右辺のセルが、生成されないリージョンにあればエラー 右辺は、プラグイン生成されたセルがあれば、それを対象とする


5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
# File 'lib/tecsgen/core/componentobj.rb', line 5608

def check_region2
  lhs_cell = @owner

  # 生成しないリージョンのセルへの結合か?
  # if join.get_cell && ! join.get_cell.is_generate? then
  # if get_rhs_cell && ! get_rhs_cell.is_generate? then # composite セルがプロタイプ宣言の場合例外
  # print "Link root: (caller #{@owner.get_name}) '#{@owner.get_region.get_link_root.get_name}'"
  # print " #{@owner.get_region.get_link_root == get_rhs_region.get_link_root ? "==" : "!="} "
  # print "'#{get_rhs_region.get_link_root.get_name}'  (callee #{@cell_name})\n"

  if get_rhs_region
    dbgPrint "check_region2 #{lhs_cell.get_name} => #{get_rhs_region.get_path_string}#{@rhs}\n"

    # if get_rhs_region.is_generate? != true then  #3
    if @owner.get_region.get_link_root != get_rhs_region.get_link_root
      cdl_error("S1121 \'$1\' in region \'$2\' cannot be directly joined $3 in  $4", lhs_cell.get_name, lhs_cell.get_region.get_namespace_path.get_path_str, @rhs.to_s, get_rhs_region.get_namespace_path.get_path_str)
    end
  else
    # rhs のセルが存在しなかった (既にエラー)
  end
end

#check_var_initObject

Join# 変数の初期化チェック


5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
# File 'lib/tecsgen/core/componentobj.rb', line 5246

def check_var_init
  # attribute, var の場合
  if @definition.get_kind == :ATTRIBUTE
#        check_cell_cb_init( definition.get_type, @rhs )
    # 右辺で初期化可能かチェック
    @definition.get_type.check_init(@locale, @definition.get_identifier, @rhs, :ATTRIBUTE)
  elsif @definition.get_kind == :VAR
    # var は初期化できない
    cdl_error("S1100 $1: cannot initialize var", @name)
  else
    # Bug trap
    raise "UnknownDeclKind"
  end
end

#clone_array_member(ct_name, cell_name, prev, locale) ⇒ Object


6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
# File 'lib/tecsgen/core/componentobj.rb', line 6243

def clone_array_member(ct_name, cell_name, prev, locale)
  # 配列のコピーを作る
  am  = @array_member.clone
  am2 = @array_member2.clone

  # 配列要素のコピーを作る
  i = 0
  while i < am2.length
    if @array_member2[i] == prev
      # 自分自身である(ので、呼出すと無限再帰呼出しとなる)
      am2[i] = self
      am[i] = am2[i].get_rhs
    elsif @array_member2[i]
#        am2[i] = @array_member2[i].clone_for_composite( ct_name, cell_name, locale, false )
      am2[i] = @array_member2[i].clone_for_composite(ct_name, cell_name, locale, true)
      am[i] = am2[i].get_rhs
    else
      # 以前のエラーで array_member2[i] は nil になっている
    end

    # debug
    dbgPrint "clone_array_member: #{@name} subsript=#{i} #{am2[i]} #{@array_member2[i]}\n"

    i += 1
  end

  # i = 0 は、ここで自分自身を設定
  # am2[0] = self

  @array_member  = am
  @array_member2 = am2
end

#clone_for_composite(ct_name, cell_name, locale, b_need_recursive = true) ⇒ Object

Join# composite セル用にクローン

cell_global_name

string : 親セルのグローバル名

右辺の C_EXP に含まれる $id$, $cell$, $ct$ を置換 ここで置換するのは composite の attribute の C_EXP を composite セルタイプおよびセル名に置換するため (内部セルの C_EXP もここで置換される)


6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
# File 'lib/tecsgen/core/componentobj.rb', line 6226

def clone_for_composite(ct_name, cell_name, locale, b_need_recursive = true)
  # debug
  dbgPrint "=====  clone_for_composite: #{@name} #{@cell_name} #{self}   =====\n"
  cl = self.clone

  if @array_member2 && b_need_recursive
    cl.clone_array_member(ct_name, cell_name, self, locale)
  end

  rhs = CDLInitializer.clone_for_composite(@rhs, ct_name, cell_name, locale)
  cl.change_rhs rhs

  # debug
  dbgPrint "join cloned : #{cl}\n"
  return cl
end

#create_allocator_joinObject

Join# アロケータの結合を生成

STAGE: S

cell

呼び口の結合先のセル

ここでは呼び口側に生成されるアロケータ呼び口の結合を生成 受け口側は Cell の set_specifier_list で生成

a[*] の内容は Cell の set_specifier_list を参照

5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
# File 'lib/tecsgen/core/componentobj.rb', line 5423

def create_allocator_join
  cell = get_rhs_cell2 # 右辺のセルを得る
  port = get_rhs_port2

  if cell && cell.get_allocator_list # cell == nil なら既にエラー

    dbgPrint "create_allocator_join: #{@owner.get_name}.#{@name}=>#{cell ? cell.get_name : "nil"}\n"

    cell.get_allocator_list.each {|a|

      if a[0 + 1] == port && a[1 + 1] == @rhs_subscript
        # 名前の一致するものの結合を生成する
        # 過不足は、別途チェックされる
        cp_name = :"#{@name}_#{a[2 + 1]}_#{a[3 + 1]}"
        # p "creating allocator join #{cp_name} #{@subscript} #{a[1+1]}"
        join = Join.new(cp_name, @subscript, a[4 + 1], @locale)

        # debug
        dbgPrint "create_allocator_join: #{@owner.get_name}.#{cp_name} [#{@subscript}] #{@name}\n"
        @owner.new_join join
      else
        dbgPrint "create_allocator_join:3 not #{@owner.get_name}.#{a[0 + 1]} #{@name}\n"
      end
    }
  end
end

#gen_through_cell_code_and_parse(plugin_name, i, next_cell, next_port_name, next_port_subscript, plClass) ⇒ Object

Join# through プラグインを呼び出して CDL 生成させるとともに、import する


5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
# File 'lib/tecsgen/core/componentobj.rb', line 5801

def gen_through_cell_code_and_parse(plugin_name, i, next_cell, next_port_name, next_port_subscript, plClass)
  through = @through_list[i]
  plugin_name           = through[0]
  generating_cell_name  = :"#{through[1]}_#{get_through_count through[1]}"
  plugin_arg            = through[2]
  if through[3]
    # region 間の through の場合
    @@start_region = through[3]
    if next_cell.get_region.equal? @@start_region
      @@end_region      = @@start_region
    else
      @@end_region      = through[4]
    end
    @@through_type      = through[5]
    @@region_count      = through[6]
  else
    # 呼び口の through の場合
    @@start_region      = @owner.get_region    # 呼び口側セルの region
    @@end_region        = next_cell.get_region # 次のセルの region
    @@through_type      = :THROUGH             # 呼び口の through 指定
    @@region_count      = 0
  end
  @@plugin_creating_join = self
  caller_cell = @owner

  begin
    plugin_object = plClass.new(generating_cell_name.to_sym, plugin_arg.to_s,
                                 next_cell, next_port_name.to_sym, next_port_subscript,
                                 @definition.get_signature, @celltype, caller_cell)
    plugin_object.set_locale @locale
  rescue Exception => evar
    cdl_error("S1126 $1: fail to new", plugin_name)
    if @celltype && @definition.get_signature && caller_cell && next_cell
      print "signature: #{@definition.get_signature.get_name} from: #{caller_cell.get_name} to: #{next_cell.get_name} of celltype: #{@celltype.get_name}\n"
    end
    print_exception(evar)
    return
  end

  @through_generated_list[i] = plugin_object

  # Region に関する情報を設定
  # 後から追加したので、new の引数外で設定
  # plugin_object.set_through_info( start_region, end_region, through_type )

  generate_and_parse plugin_object
end

#get_array_memberObject


6130
6131
6132
# File 'lib/tecsgen/core/componentobj.rb', line 6130

def get_array_member
  @array_member
end

#get_array_member2Object


6134
6135
6136
# File 'lib/tecsgen/core/componentobj.rb', line 6134

def get_array_member2
  @array_member2
end

#get_cellObject


5885
5886
5887
# File 'lib/tecsgen/core/componentobj.rb', line 5885

def get_cell
  @cell
end

#get_cell_global_nameObject

受け口セル名(コンポジットなら展開した内側のセル)


5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
# File 'lib/tecsgen/core/componentobj.rb', line 5972

def get_cell_global_name # 受け口セル名(コンポジットなら展開した内側のセル)
  # debug
  dbgPrint "cell get_cell_global_name:  #{@cell_name}\n"
  # @cell.show_tree( 1 )

  if @cell
    return @cell.get_real_global_name(@port_name)
  else
    return "NonDefinedCell?"
  end
end

#get_cell_nameObject

受け口セル名


5877
5878
5879
# File 'lib/tecsgen/core/componentobj.rb', line 5877

def get_cell_name # 受け口セル名
  @cell_name
end

#get_celltypeObject


5881
5882
5883
# File 'lib/tecsgen/core/componentobj.rb', line 5881

def get_celltype
  @celltype
end

#get_definitionObject


5630
5631
5632
# File 'lib/tecsgen/core/componentobj.rb', line 5630

def get_definition
  @definition
end

#get_nameObject


5867
5868
5869
# File 'lib/tecsgen/core/componentobj.rb', line 5867

def get_name
  @name
end

#get_port_global_name(subscript = nil) ⇒ Object

Join# 結合の右辺の受け口の名前

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

Integer 呼び口配列の時添数 または nil 呼び口配列でない時


5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
# File 'lib/tecsgen/core/componentobj.rb', line 5987

def get_port_global_name(subscript = nil) # 受け口名(コンポジットなら展開した内側のセル)
  # debug
  dbgPrint "Cell get_port_global_name:  #{@cell_name}\n"

  # through 指定あり?
  if @through_list[0]

    # mikan through で生成したものが root namespace 限定
    # cell = Namespace.find( [ "::", @through_generated_list[0].get_cell_name.to_sym ] )    #1
    cell = Namespace.find(@through_generated_list[0].get_cell_namespace_path) # 1

    # through で挿入されたセルで、実際に接続されるセル(compositeの場合内部の)の受け口の C 言語名前
    return cell.get_real_global_port_name(@through_generated_list[0].get_through_entry_port_name)
  else

    # 実際に接続されるセルの受け口の C 言語名前
    if @cell
      return @cell.get_real_global_port_name(@port_name)
    else
      return "UndefinedCellsPort?"
    end

  end
end

#get_port_nameObject


6012
6013
6014
# File 'lib/tecsgen/core/componentobj.rb', line 6012

def get_port_name
  @port_name
end

#get_rhsObject


6016
6017
6018
# File 'lib/tecsgen/core/componentobj.rb', line 6016

def get_rhs
  @rhs
end

#get_rhs_cellObject

Join# 右辺の実セルを得る

実セルとは through で挿入されたもの、composite の内部など実際に結合される先
このメソッドは get_rhs_port と対になっている
このメソッドは、意味解析段階では呼び出してはならない (対象セルの意味解析が済む前には正しい結果を返さない)

5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
# File 'lib/tecsgen/core/componentobj.rb', line 5893

def get_rhs_cell
  # through 指定あり?
  if @through_list[0]
    # mikan through で生成したものが root namespace 限定
    if @through_generated_list[0]
      # cell = Namespace.find( [ "::", @through_generated_list[0].get_cell_name.to_sym ] )    #1
      cell = Namespace.find(@through_generated_list[0].get_cell_namespace_path) # 1
      # cell が nil になるのはプラグインの get_cell_namespace_path が正しくないか、
      # プラグイン生成コードがエラーになっている。
      # できの悪いプラグインが多ければ、cell == nil をはじいた方がよい。
      return cell.get_real_cell(@through_generated_list[0].get_through_entry_port_name)
    else
      return nil # generate に失敗している
    end
  elsif @cell
    return @cell.get_real_cell(@port_name)
  else
    # 右辺が未定義の場合 @cell は nil (既にエラー)
    return nil
  end
end

#get_rhs_cell1Object

末尾数字1 : CDL で指定された、右辺のセルを返す


6021
6022
6023
# File 'lib/tecsgen/core/componentobj.rb', line 6021

def get_rhs_cell1   # get_cell と同じ
  @cell
end

#get_rhs_cell2Object

Join# 右辺のセルを得る

右辺のセルを得る。ただし、composite 展開されていない composite 展開されたものを得るには get_rhs_cell を使う プロトタイプ宣言しかされていない場合には、こちらしか使えない このメソッドは get_rhs_port2 と対になっている


5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
# File 'lib/tecsgen/core/componentobj.rb', line 5920

def get_rhs_cell2
  # through 指定あり?
  if @through_list[0]
    # mikan through で生成したものが root namespace 限定
    # cell = Namespace.find( [ "::", @through_generated_list[0].get_cell_name ] )
    if @through_generated_list[0]
      # cell = Namespace.find( [ @through_generated_list[0].get_cell_name ] )    #1
      cell = Namespace.find(@through_generated_list[0].get_cell_namespace_path) # 1
    else
      cell = @cell # generate に失敗している
    end
  else
    cell = @cell
  end

  return cell
end

#get_rhs_cell3Object

Join# 右辺のセルを得る

through は適用しないが、composite は展開した後のセル (意味解析が終わっていないと、composite 展開が終わっていない) このメソッドは get_rhs_port3 と対になっている


5942
5943
5944
5945
5946
# File 'lib/tecsgen/core/componentobj.rb', line 5942

def get_rhs_cell3
  if @cell
    return @cell.get_real_cell(@port_name)
  end
end

#get_rhs_portObject

Join# 右辺のポートを得る

右辺が composite の場合は、内部の繋がるセルのポート, through の場合は挿入されたセルのポート
このメソッドは get_rhs_cell と対になっている

6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
# File 'lib/tecsgen/core/componentobj.rb', line 6036

def get_rhs_port
  # through 指定あり?
  if @through_list[0]
    # through で生成されたセルを探す
    cell = Namespace.find(@through_generated_list[0].get_cell_namespace_path) # 1
    # cell のプラグインで生成されたポート名のポートを探す (composite なら内部の繋がるポート)
    return cell.get_real_port(@through_generated_list[0].get_through_entry_port_name)
  else
    # ポートを返す(composite なら内部の繋がるポートを返す)
    return @cell.get_real_port(@port_name)
  end
end

#get_rhs_port1Object

get_port_name 同じ


6025
6026
6027
# File 'lib/tecsgen/core/componentobj.rb', line 6025

def get_rhs_port1   # get_port_name 同じ
  @port_name
end

#get_rhs_port2Object

Join# 右辺のポートを得る

右辺のポートを得る。 これはプロトタイプ宣言しかされていない場合には、こちらしか使えない


6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
# File 'lib/tecsgen/core/componentobj.rb', line 6064

def get_rhs_port2
  # through 指定あり?
  if @through_list[0]
    if @through_generated_list[0]
      port = @through_generated_list[0].get_through_entry_port_name.to_sym
    else
      port = @port_name # generate に失敗している
    end
  else
    port = @port_name
  end

  return port
end

#get_rhs_port3Object

Join# 右辺のポートを得る

through は適用しないが、composite は展開した後のセルの対応するポート


6081
6082
6083
6084
6085
# File 'lib/tecsgen/core/componentobj.rb', line 6081

def get_rhs_port3
  if @cell
    return @cell.get_real_port(@port_name)
  end
end

#get_rhs_regionObject

Join# 右辺のセルのリージョンを得る

右辺が未定義の場合、nil を返す composite の場合、実セルではなく composite cell の region を返す(composite はすべて同じ region に属する) composite の cell がプロトタイプ宣言されているとき get_rhs_cell/get_real_cell は ruby の例外となる


5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
# File 'lib/tecsgen/core/componentobj.rb', line 5952

def get_rhs_region
  # through 指定あり?
  if @through_list[0]
    if @through_generated_list[0]
      # mikan through で生成したものが root namespace 限定
      # cell = Namespace.find( [ "::", @through_generated_list[0].get_cell_name.to_sym ] )    #1
      cell = Namespace.find(@through_generated_list[0].get_cell_namespace_path) # 1
      if cell
        return cell.get_region
      end
    else
      return nil # generate に失敗している
    end
  elsif @cell
    return @cell.get_region
  end
  # 右辺が未定義の場合 @cell は nil (既にエラー)
  return nil
end

#get_rhs_subscriptObject

Join# 右辺の配列添数を得る

右辺が through の場合は挿入されたセルの添数
右辺が composite の場合は、内部の繋がるセルのポートの添数 (composite では変わらない)
このメソッドは get_rhs_cell,  と対になっている

6053
6054
6055
6056
6057
6058
6059
# File 'lib/tecsgen/core/componentobj.rb', line 6053

def get_rhs_subscript
  if @through_list[0]
    return @through_generated_list[0].get_through_entry_port_subscript
  else
    return @rhs_subscript
  end
end

#get_rhs_subscript1Object


6029
6030
6031
# File 'lib/tecsgen/core/componentobj.rb', line 6029

def get_rhs_subscript1
  @rhs_subscript
end

#get_subscriptObject

Join#配列添数を得る


5873
5874
5875
# File 'lib/tecsgen/core/componentobj.rb', line 5873

def get_subscript
  @subscript
end

#get_through_count(name) ⇒ Object


5790
5791
5792
5793
5794
5795
5796
5797
5798
# File 'lib/tecsgen/core/componentobj.rb', line 5790

def get_through_count(name)
  sym = name.to_sym
  if @@through_count[sym]
    @@through_count[sym] += 1
  else
    @@through_count[sym] = 0
  end
  return @@through_count[sym]
end

#set_cloned(owner) ⇒ Object

Join# clone された join の owner を変更


6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
# File 'lib/tecsgen/core/componentobj.rb', line 6286

def set_cloned(owner)
  dbgPrint "Join#set_cloned: #{@name}  prev owner: #{@owner.get_name} new owner: #{owner.get_name}\n"
  @owner = owner
  if @array_member2
    @array_member2.each{|join|
      dbgPrint "Joinarray#set_cloned: #{@name}  prev owner: #{join.get_owner.get_name} new owner: #{owner.get_name}\n"
      join.set_owner owner
    }
  end
end

#set_definition(definition) ⇒ Object

Join# 左辺に対応する celltype の定義を設定するとともにチェックする

STAGE: S

代入可能かチェックする
definition

Decl (attribute,varの時) または Port (callの時) または nil (definition が見つからなかった時)


5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
# File 'lib/tecsgen/core/componentobj.rb', line 5216

def set_definition(definition)
  dbgPrint "set_definition: #{@owner.get_name}.#{@name} = #{definition.class}\n"

  # 二重チェックの防止
  if @definition
    # set_definition を個別に行うケースで、二重に行われる可能性がある(異常ではない)
    # 二重に set_definition が実行されると through が二重に適用されてしまう
    # cdl_warning( "W9999 $1, internal error: set_definition duplicate", @name )
    return
  end

  @definition = definition

  # mikan 左辺値、右辺値の型チェックなど
  if @definition.instance_of?(Decl)
    check_var_init
  elsif @definition.instance_of?(Port)
    check_call_port_init
    if @definition.get_port_type == :CALL # :ENTRY ならエラー。無視しない
      check_and_gen_through
      create_allocator_join # through プラグイン生成した後でないと、挿入前のセルのアロケータを結合してしまう
    end
  elsif @definition.nil?
    cdl_error("S1117 \'$1\' not in celltype", @name)
  else
    raise "UnknownToken"
  end
end

#set_specifier_list(specifier_list) ⇒ Object

Join# specifier を設定

STAGE: B set_specifier_list は、join の解析の最後で呼び出される through 指定子を設定

check_and_gen_through を呼出して、through 生成

5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
# File 'lib/tecsgen/core/componentobj.rb', line 5639

def set_specifier_list(specifier_list)
  specifier_list.each {|s|
    case s[0]
    when :THROUGH
      # set plugin_name
      plugin_name = s[1].to_s
      plugin_name[0] = plugin_name.capitalize # 先頭文字を大文字に : ruby のクラス名の制約

      # set cell_name
      cell_name = :"#{s[1].to_s}_"

      # set plugin_arg
      plugin_arg = CDLString.remove_dquote s[2].to_s
      # plugin_arg = s[2].to_s.gsub( /\A"(.*)/, '\1' )   # 前後の "" を取り除く
      # plugin_arg.sub!( /(.*)"\z/, '\1' )

      @cp_through_list << [plugin_name, cell_name, plugin_arg]
    end
  }
end

#show_tree(indent) ⇒ Object


6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
# File 'lib/tecsgen/core/componentobj.rb', line 6297

def show_tree(indent)
  indent.times { print "  " }
  puts "Join: name: #{@name} owner: #{@owner.get_name} id: #{self}"
  if @subscript.nil?
  elsif @subscript >= 0
    (indent + 1).times { print "  " }
    puts "subscript: #{@subscript}"
  else
    (indent + 1).times { print "  " }
    puts "subscript: not specified"
  end
  (indent + 1).times { print "  " }
  puts "rhs: "
  if @rhs.instance_of?(Array)
    @rhs.each{|i|
      if i.instance_of?(Array)
        i.each{|j|
          j.show_tree(indent + 3)
        }
      elsif i.instance_of? Symbol
        (indent + 2).times { print "  " }
        print i
        print "\n"
      else
        i.show_tree(indent + 2)
      end
    }
  else
    @rhs.show_tree(indent + 2)
    (indent + 1).times { print "  " }
    if @definition
      puts "definition:"
      @definition.show_tree(indent + 2)
    else
      puts "definition: not found"
    end
  end
  if @definition.instance_of?(Port)
    (indent + 2).times { print "  " }
    if @cell
      puts "cell: #{@cell_name} #{@cell}  port: #{@port_name}  cell_global_name: #{@cell.get_global_name}"
    else
      puts "cell: #{@cell_name} port: #{@port_name}  (cell not found)"
    end
  end
  if @through_list
    i = 0
    @through_list.each {|t|
      (indent + 2).times { print "  " }
      puts "through: plugin name :  '#{t[0]}' arg : '#{t[2]}'"
      if @through_generated_list[i]
        @through_generated_list[i].show_tree(indent + 3)
      end
      i += 1
    }
  end
  if @array_member2
    (indent + 1).times { print "  " }
    puts "array member:"
    i = 0
    @array_member2.each {|j|
      if j
        (indent + 2).times { print "  " }
        puts "[#{i}]: #{j.get_name}  id: #{j} owner=#{j.get_owner.get_name}"
        j.get_rhs.show_tree(indent + 3)
#          (indent+3).times { print "  " }
#          puts "cell global name: #{j.get_cell_global_name}"
#          puts "cell global name: #{j.get_rhs_cell.get_global_name}"
#          (indent+3).times { print "  " }
#          puts "port global name: #{j.get_port_global_name}"
#          puts "port global name: #{j.get_rhs_port.get_name}"
      else
        (indent + 2).times { print "  " }
        puts "[#{i}]: [optional]  id: #{j}"
      end
      i += 1
    }
  end
end

#unjoin_pluginObject


194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/tecsgen/core/unjoin_plugin.rb', line 194

def unjoin_plugin
  # @thourhg_generated_list is refered in get_rhs_cell, get_rhs_port
  @through_generated_list.map!{|po| # po: plugin object
    ThroughPluginProxy.new po.get_cell_namespace_path, po.get_through_entry_port_name, po.get_through_entry_port_subscript
  }
  @region_through_generated_list.map!{|po| # po: plugin object
    ThroughPluginProxy.new po.get_cell_namespace_path, po.get_through_entry_port_name, po.get_through_entry_port_subscript
  }
  if @array_member2 then
    @array_member2.each{ |j| 
      if j then
        j.unjoin_plugin2
      end
    }
  end
end

#unjoin_plugin2Object


210
211
212
213
214
215
216
217
# File 'lib/tecsgen/core/unjoin_plugin.rb', line 210

def unjoin_plugin2
  @through_generated_list.map!{|po| # po: plugin object
    ThroughPluginProxy.new po.get_cell_namespace_path, po.get_through_entry_port_name, po.get_through_entry_port_subscript
  }
  @region_through_generated_list.map!{|po| # po: plugin object
    ThroughPluginProxy.new po.get_cell_namespace_path, po.get_through_entry_port_name, po.get_through_entry_port_subscript
  }
end