1 | # -*- coding: utf-8 -*-
|
---|
2 | #
|
---|
3 | # TECS Generator
|
---|
4 | # Generator for TOPPERS Embedded Component System
|
---|
5 | #
|
---|
6 | # Copyright (C) 2015-2018 by TOPPERS Project
|
---|
7 | #
|
---|
8 | #--
|
---|
9 | # 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
|
---|
10 | # ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
|
---|
11 | # 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
|
---|
12 | # (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
|
---|
13 | # 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
|
---|
14 | # スコード中に含まれていること.
|
---|
15 | # (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
|
---|
16 | # 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
|
---|
17 | # 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
|
---|
18 | # の無保証規定を掲載すること.
|
---|
19 | # (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
|
---|
20 | # 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
|
---|
21 | # と.
|
---|
22 | # (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
|
---|
23 | # 作権表示,この利用条件および下記の無保証規定を掲載すること.
|
---|
24 | # (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
|
---|
25 | # 報告すること.
|
---|
26 | # (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
|
---|
27 | # 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
|
---|
28 | # また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
|
---|
29 | # 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
|
---|
30 | # 免責すること.
|
---|
31 | #
|
---|
32 | # 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
|
---|
33 | # よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
|
---|
34 | # に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
|
---|
35 | # アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
|
---|
36 | # の責任を負わない.
|
---|
37 | #
|
---|
38 | # $Id$
|
---|
39 | #++
|
---|
40 |
|
---|
41 | #== cell を count 個繰り返すセルプラグイン
|
---|
42 | # 不完全点:
|
---|
43 | # 指定子に対応していない
|
---|
44 | # cell の指定子 (allocator, id)
|
---|
45 | # 結合の指定子 (through)
|
---|
46 | class RepeatCellPlugin < CellPlugin
|
---|
47 |
|
---|
48 | @@plugin_list = []
|
---|
49 | RepeatCellPluginArgProc = {
|
---|
50 | "count" => Proc.new { |obj,rhs| obj.set_count rhs }
|
---|
51 | }
|
---|
52 |
|
---|
53 | def initialize( cell, option )
|
---|
54 | super
|
---|
55 | @@plugin_list << self
|
---|
56 | print "RepeatCellPlugin: #{@cell.get_name}\n"
|
---|
57 | # cell.show_tree 0
|
---|
58 | # @cell.get_join_list.get_items.each{ |j|
|
---|
59 | # print "Join: #{j.get_name} = #{j.get_rhs.to_s}\n"
|
---|
60 | # }
|
---|
61 | @count = 0
|
---|
62 | @plugin_arg_check_proc_tab = RepeatCellPluginArgProc
|
---|
63 | parse_plugin_arg
|
---|
64 | end
|
---|
65 |
|
---|
66 | def gen_cdl_file( file )
|
---|
67 | if $verbose then
|
---|
68 | print "#{self.class}: repeat #{@cell.get_name} #(num} times\n"
|
---|
69 | end
|
---|
70 |
|
---|
71 | nest = @cell.get_region.gen_region_str_pre file
|
---|
72 | indent_str = " " * nest
|
---|
73 | @cell.get_name.to_s =~ /.*[^0-9]([0-9]+)\z/
|
---|
74 | if $1 then
|
---|
75 | tail_zero = $1
|
---|
76 | bname = @cell.get_name.to_s.gsub( /[0-9]+\z/, "" )
|
---|
77 | else
|
---|
78 | cdl_error( "#{self.class}: #{@cell.get_name}'s name ends without '0-9'")
|
---|
79 | return
|
---|
80 | end
|
---|
81 | base_count = tail_zero.to_i
|
---|
82 |
|
---|
83 | count = 1
|
---|
84 | num = @count
|
---|
85 | file.print "/* #{num} times repeat of '#{@cell.get_name}' */\n"
|
---|
86 | while count < num
|
---|
87 |
|
---|
88 | # セル名のカウント
|
---|
89 | count_str = (count + base_count).to_s
|
---|
90 | if tail_zero.length > count_str.length then
|
---|
91 | leading_zero = "0" * ( tail_zero.length - count_str.length )
|
---|
92 | else
|
---|
93 | leading_zero = ""
|
---|
94 | end
|
---|
95 | cname = bname + leading_zero + count_str
|
---|
96 |
|
---|
97 | # "cell tCelltype Cell {"
|
---|
98 | file.print "#{indent_str}cell #{@cell.get_celltype.get_name} #{cname}{\n"
|
---|
99 |
|
---|
100 | # Join の CDL 文字列生成
|
---|
101 | @cell.get_join_list.get_items.each{ |j|
|
---|
102 |
|
---|
103 | # Join の右辺の解析
|
---|
104 | res = j.get_rhs.analyze_cell_join_expression
|
---|
105 | if res then
|
---|
106 | nsp, subscript, port_name = res[0], res[1], res[2]
|
---|
107 | else
|
---|
108 | nsp = j.get_rhs.analyze_single_identifier
|
---|
109 | if nsp then
|
---|
110 | subscript, port_name = nil, nil
|
---|
111 | else
|
---|
112 | file.print "#{indent_str} #{j.get_name} = #{j.get_rhs.to_s};\n"
|
---|
113 | next
|
---|
114 | end
|
---|
115 | end
|
---|
116 |
|
---|
117 | # 右辺のセル名 (末尾の数字をカウントアップ)
|
---|
118 | nsp.get_name.to_s =~ /(.*[^0-9])([0-9]+)\z/
|
---|
119 | if $2 then
|
---|
120 | rhs_tail_num = $2
|
---|
121 | rhs_name_count = count + rhs_tail_num.to_i
|
---|
122 | if rhs_tail_num.length > rhs_name_count.to_s.length then
|
---|
123 | leading_zero = "0" * ( rhs_tail_num.length - rhs_name_count.to_s.length )
|
---|
124 | else
|
---|
125 | leading_zero = ""
|
---|
126 | end
|
---|
127 | rhs_cname = $1 + leading_zero + rhs_name_count.to_s
|
---|
128 | nsp = nsp.change_name_clone rhs_cname
|
---|
129 | end
|
---|
130 |
|
---|
131 | # Join 文字列の出力
|
---|
132 | if port_name then
|
---|
133 | # 右辺は セルの結合
|
---|
134 | if subscript then
|
---|
135 | file.print "#{indent_str} #{j.get_name} = #{nsp.get_path_str}.#{port_name}[#{(count+subscript).to_s}];\n"
|
---|
136 | else
|
---|
137 | file.print "#{indent_str} #{j.get_name} = #{nsp.get_path_str}.#{port_name};\n"
|
---|
138 | end
|
---|
139 | else
|
---|
140 | # 右辺は単一の識別子
|
---|
141 | file.print "#{indent_str} #{j.get_name} = #{nsp.get_path_str};\n"
|
---|
142 | end
|
---|
143 | }
|
---|
144 |
|
---|
145 | file.print "#{indent_str}};\n\n"
|
---|
146 | count += 1
|
---|
147 | end
|
---|
148 |
|
---|
149 | @cell.get_region.gen_region_str_post file
|
---|
150 | end
|
---|
151 |
|
---|
152 | #=== count オプションの解析
|
---|
153 | def set_count rhs
|
---|
154 | if rhs =~ /\A\d+\z/
|
---|
155 | @count = rhs.to_i
|
---|
156 | else
|
---|
157 | nsp = NamespacePath.new( rhs.to_sym, true )
|
---|
158 | expr = Expression.create_single_identifier( nsp, nil )
|
---|
159 | res = expr.eval_const( nil )
|
---|
160 | if res == nil then
|
---|
161 | cdl_error( "count value ($1): not single identifier or integer number", rhs.to_s )
|
---|
162 | @count = 0
|
---|
163 | else
|
---|
164 | @count = res
|
---|
165 | end
|
---|
166 | end
|
---|
167 | end
|
---|
168 |
|
---|
169 | end
|
---|