1 | # -*- coding: utf-8 -*-
|
---|
2 | #
|
---|
3 | # TECS Generator
|
---|
4 | # Generator for TOPPERS Embedded Component System
|
---|
5 | #
|
---|
6 | # Copyright (C) 2008-2016 by TOPPERS Project
|
---|
7 | #--
|
---|
8 | # ä¸è¨èä½æ¨©è
|
---|
9 | ã¯ï¼ä»¥ä¸ã®(1)ï½(4)ã®æ¡ä»¶ãæºããå ´åã«éãï¼æ¬ã½ããã¦ã§
|
---|
10 | # ã¢ï¼æ¬ã½ããã¦ã§ã¢ãæ¹å¤ãããã®ãå«ãï¼ä»¥ä¸åãï¼ã使ç¨ã»è¤è£½ã»æ¹
|
---|
11 | # å¤ã»åé
|
---|
12 | å¸ï¼ä»¥ä¸ï¼å©ç¨ã¨å¼ã¶ï¼ãããã¨ãç¡åã§è¨±è«¾ããï¼
|
---|
13 | # (1) æ¬ã½ããã¦ã§ã¢ãã½ã¼ã¹ã³ã¼ãã®å½¢ã§å©ç¨ããå ´åã«ã¯ï¼ä¸è¨ã®èä½
|
---|
14 | # 権表示ï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãï¼ãã®ã¾ã¾ã®å½¢ã§ã½ã¼
|
---|
15 | # ã¹ã³ã¼ãä¸ã«å«ã¾ãã¦ãããã¨ï¼
|
---|
16 | # (2) æ¬ã½ããã¦ã§ã¢ãï¼ã©ã¤ãã©ãªå½¢å¼ãªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
|
---|
17 | # ç¨ã§ããå½¢ã§åé
|
---|
18 | å¸ããå ´åã«ã¯ï¼åé
|
---|
19 | å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨
|
---|
20 | # è
|
---|
21 | ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®èä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨
|
---|
22 | # ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
|
---|
23 | # (3) æ¬ã½ããã¦ã§ã¢ãï¼æ©å¨ã«çµã¿è¾¼ããªã©ï¼ä»ã®ã½ããã¦ã§ã¢éçºã«ä½¿
|
---|
24 | # ç¨ã§ããªãå½¢ã§åé
|
---|
25 | å¸ããå ´åã«ã¯ï¼æ¬¡ã®ããããã®æ¡ä»¶ãæºããã
|
---|
26 | # ã¨ï¼
|
---|
27 | # (a) åé
|
---|
28 | å¸ã«ä¼´ãããã¥ã¡ã³ãï¼å©ç¨è
|
---|
29 | ããã¥ã¢ã«ãªã©ï¼ã«ï¼ä¸è¨ã®è
|
---|
30 | # ä½æ¨©è¡¨ç¤ºï¼ãã®å©ç¨æ¡ä»¶ããã³ä¸è¨ã®ç¡ä¿è¨¼è¦å®ãæ²è¼ãããã¨ï¼
|
---|
31 | # (b) åé
|
---|
32 | å¸ã®å½¢æ
|
---|
33 | ãï¼å¥ã«å®ããæ¹æ³ã«ãã£ã¦ï¼TOPPERSããã¸ã§ã¯ãã«
|
---|
34 | # å ±åãããã¨ï¼
|
---|
35 | # (4) æ¬ã½ããã¦ã§ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ
|
---|
36 | # 害ãããï¼ä¸è¨èä½æ¨©è
|
---|
37 | ããã³TOPPERSããã¸ã§ã¯ããå
|
---|
38 | 責ãããã¨ï¼
|
---|
39 | # ã¾ãï¼æ¬ã½ããã¦ã§ã¢ã®ã¦ã¼ã¶ã¾ãã¯ã¨ã³ãã¦ã¼ã¶ããã®ãããªãç
|
---|
40 | # ç±ã«åºã¥ãè«æ±ãããï¼ä¸è¨èä½æ¨©è
|
---|
41 | ããã³TOPPERSããã¸ã§ã¯ãã
|
---|
42 | # å
|
---|
43 | 責ãããã¨ï¼
|
---|
44 | #
|
---|
45 | # æ¬ã½ããã¦ã§ã¢ã¯ï¼ç¡ä¿è¨¼ã§æä¾ããã¦ãããã®ã§ããï¼ä¸è¨èä½æ¨©è
|
---|
46 | ã
|
---|
47 | # ãã³TOPPERSããã¸ã§ã¯ãã¯ï¼æ¬ã½ããã¦ã§ã¢ã«é¢ãã¦ï¼ç¹å®ã®ä½¿ç¨ç®ç
|
---|
48 | # ã«å¯¾ããé©åæ§ãå«ãã¦ï¼ãããªãä¿è¨¼ãè¡ããªãï¼ã¾ãï¼æ¬ã½ããã¦ã§
|
---|
49 | # ã¢ã®å©ç¨ã«ããç´æ¥çã¾ãã¯éæ¥çã«çãããããªãæ害ã«é¢ãã¦ãï¼ã
|
---|
50 | # ã®è²¬ä»»ãè² ããªãï¼
|
---|
51 | #
|
---|
52 | # $Id: syntaxobj.rb 1011 2016-07-11 02:20:01Z coas-nagasima $
|
---|
53 | #++
|
---|
54 |
|
---|
55 | # mikan ruby ã® symbol ã¨æååã®ä½¿ãåããã©ããã¦ããã¾ããããªããã¨ãæã
|
---|
56 | ããã®ã§ name.to_sym ãå
|
---|
57 | ¥ãããã¨ã«ãã
|
---|
58 |
|
---|
59 | #== Node
|
---|
60 | #
|
---|
61 | # Node ã®ç´æ¥ã®åã¯ã©ã¹ï¼ C_EXP, Type, BaseVal, BDNode(ã»ã¨ãã©ã®ãã®ã¯ BDNode ã®åã¯ã©ã¹)
|
---|
62 | # Node ã« (BDNodeã«ã) å
|
---|
63 | ¥ããªããã®: Token, Import, Import_C, Generate
|
---|
64 | #
|
---|
65 | # owner ãæããªããã®ã Node ã¨ãªã
|
---|
66 | # ã¨ã©ã¼ã¯ãcdl_error ãéãã¦å ±åãã (æå³è§£æãæ§æ解æå¾ã«è¡ãããå ´åã«ã¯ãè¡çªå·ãæ£ããåºåã§ãã
|
---|
67 | #
|
---|
68 |
|
---|
69 | class Node
|
---|
70 | #@locale:: [@file, @lineno, @col]
|
---|
71 |
|
---|
72 | def initialize
|
---|
73 | @locale = Generator.current_locale
|
---|
74 | end
|
---|
75 |
|
---|
76 | #=== ã¨ã©ã¼ãåºåãã
|
---|
77 | def cdl_error( message, *arg )
|
---|
78 | Generator.error2( @locale, message, *arg )
|
---|
79 | end
|
---|
80 |
|
---|
81 | #=== ã¨ã©ã¼ãåºåãã
|
---|
82 | #locale:: Array(locale info) : æ§æ解æä¸ã¯ç¡è¦ããã
|
---|
83 | def cdl_error2( locale, message, *arg )
|
---|
84 | Generator.error2( locale, message, *arg )
|
---|
85 | end
|
---|
86 |
|
---|
87 | #=== ã¨ã©ã¼ãåºåãã
|
---|
88 | #locale:: Array(locale info)
|
---|
89 | # æ§æ解æä¸ cdl_error2 ã§ã¯ locale ãç¡è¦ããããããå¥ã« locale ãåºåãã
|
---|
90 | def cdl_error3( locale, message, *arg )
|
---|
91 | Generator.error( message, *arg )
|
---|
92 | Console.puts "check: #{locale[0]}: line #{locale[1]} for above error"
|
---|
93 | end
|
---|
94 |
|
---|
95 | #=== ã¦ã©ã¼ãã³ã°åºåãã
|
---|
96 | def cdl_warning( message, *arg )
|
---|
97 | Generator.warning2( @locale, message, *arg )
|
---|
98 | end
|
---|
99 |
|
---|
100 | #=== ã¦ã©ã¼ãã³ã°åºåãã
|
---|
101 | def cdl_warning2( locale, message, *arg )
|
---|
102 | Generator.warning2( locale, message, *arg )
|
---|
103 | end
|
---|
104 |
|
---|
105 | #=== æ
|
---|
106 | å ±ã表示ãã
|
---|
107 | def cdl_info( message )
|
---|
108 | Console.puts "info: #{message}"
|
---|
109 | end
|
---|
110 |
|
---|
111 | def get_locale
|
---|
112 | @locale
|
---|
113 | end
|
---|
114 |
|
---|
115 | def set_locale locale
|
---|
116 | @locale = locale
|
---|
117 | end
|
---|
118 |
|
---|
119 | def locale_str
|
---|
120 | "locale=( #{@locale[0]}, #{@locale[1]} )"
|
---|
121 | end
|
---|
122 | end
|
---|
123 |
|
---|
124 | #== åæ¹å Node (Bi Direction Node)
|
---|
125 | #
|
---|
126 | # Node ã®åã¯ã©ã¹
|
---|
127 | # owner Node ããåç
|
---|
128 | §ããã¦ãããã® (owner ã¸ã®ãªã³ã¯ãåãåºãã)
|
---|
129 | #
|
---|
130 | # get_owner ã§å¾ããããã®
|
---|
131 | # FuncHead => Signature
|
---|
132 | # Decl => Namespace(const), Typedef(typedef),
|
---|
133 | # Celltype, CompositeCelltype(attr,var)
|
---|
134 | # Struct(member), ParamDecl(parameter), FuncHead(funchead)
|
---|
135 | # Signature, Celltype, CompositeCelltype, Typedef => Namespace
|
---|
136 | #, Namespace => Namespace, Generator.class (root Namespace ã®å ´å)
|
---|
137 | # Cell => Region, CompositeCelltype(in_composite)
|
---|
138 | # Port => Celltype, Composite
|
---|
139 | # Factory => Celltype
|
---|
140 | # Join => Cell
|
---|
141 | # CompositeCelltypeJoin => CompositeCelltype
|
---|
142 | # Region => Region,
|
---|
143 | # ParamDecl => ParamList
|
---|
144 | # ParamList => FuncHead
|
---|
145 | # Expression => Namespace
|
---|
146 | # 大åã®ãã®ã¯ new_* ã¡ã½ãã㧠owner Node ã«ä¼éããã
|
---|
147 | # ãã®ã¡ã½ãããå¼ã³åºãããã¨ãã« owner Node ãè¨é²ããã
|
---|
148 | # new_* ããªããã®ï¼
|
---|
149 | # Decl(parameter), ParamDecl, ParamList, FuncHead, Expression
|
---|
150 | #
|
---|
151 | # Expression ã¯ãowner Node ã¨ãªããã®ãå¤ãããããæ¹é ãå°é£ã§ãããã
|
---|
152 | # Expression ãå®ç¾©ãããã¨ãã® Namespace ã owner Node ã¨ãã
|
---|
153 | # StructType 㯠Type ã®ä¸ç¨®ãªã®ã§ owner ãæããªã
|
---|
154 | #
|
---|
155 | class BDNode < Node
|
---|
156 | #@owner::Node
|
---|
157 | #@NamespacePath:: NamespacePath
|
---|
158 | #@Generator::
|
---|
159 | #@import::Import :
|
---|
160 |
|
---|
161 | def initialize
|
---|
162 | super
|
---|
163 | @owner = nil
|
---|
164 | @NamespacePath = nil
|
---|
165 | @import = Import.get_current
|
---|
166 |
|
---|
167 | end
|
---|
168 |
|
---|
169 | #=== owner ãè¨å®ãã
|
---|
170 | def set_owner owner
|
---|
171 | dbgPrint "set_owner: #{owner.class.name}\n"
|
---|
172 | @owner = owner
|
---|
173 | end
|
---|
174 |
|
---|
175 | #=== owner ãå¾ã
|
---|
176 | # class ã®èª¬æãåç
|
---|
177 | §
|
---|
178 | def get_owner
|
---|
179 | if @owner == nil
|
---|
180 | raise "Node have no owner #{self.class.name} #{get_name}"
|
---|
181 | end
|
---|
182 | @owner
|
---|
183 | end
|
---|
184 | end
|
---|
185 |
|
---|
186 | #== Namespace åãæ㤠BDNode
|
---|
187 | # Namespace(Region), Signature, Celltype, CompositeCelltype, Cell
|
---|
188 | class NSBDNode < BDNode
|
---|
189 |
|
---|
190 | def initialize
|
---|
191 | super
|
---|
192 | end
|
---|
193 |
|
---|
194 | #=== å±ãã namespace ãå¾ã
|
---|
195 | # owner ã namespace ã«ãã©ãçãã¾ã§ä¸ã«ãã©ã
|
---|
196 | def get_namespace
|
---|
197 | if @owner.kind_of? Namespace
|
---|
198 | return @owner
|
---|
199 | elsif @owner != nil then
|
---|
200 | return @owner.get_namespace
|
---|
201 | else
|
---|
202 | # @owner == nil ãªã "::"
|
---|
203 | if @name != "::" then
|
---|
204 | raise "non-root namespace has no owner #{self.class.name}##{@name} #{self}"
|
---|
205 | end
|
---|
206 | return nil
|
---|
207 | end
|
---|
208 | end
|
---|
209 |
|
---|
210 | def set_namespace_path
|
---|
211 | ns = get_namespace
|
---|
212 | if ns then
|
---|
213 | @NamespacePath = ns.get_namespace_path.append( get_name )
|
---|
214 | else
|
---|
215 | raise "get_namespace_path: no namespace found"
|
---|
216 | end
|
---|
217 | end
|
---|
218 |
|
---|
219 | #=== NamespacePath ãå¾ã
|
---|
220 | def get_namespace_path
|
---|
221 | return @NamespacePath
|
---|
222 | end
|
---|
223 |
|
---|
224 | def is_imported?
|
---|
225 | if @import then
|
---|
226 | return @import.is_imported?
|
---|
227 | else
|
---|
228 | return false # mikan: ä»® @import ã nil ã«ãªãã±ã¼ã¹ã追æ±ã§ãã¦ããªã
|
---|
229 | end
|
---|
230 | end
|
---|
231 | end
|
---|
232 |
|
---|
233 | class NamedList
|
---|
234 | # @names:: {} of items
|
---|
235 | # @items:: [] of items : item ã® CLASS 㯠get_name ã¡ã½ãããæã¤ã㨠get_name ã®æ»ãå¤ã¯ Symbol ã§ãªãã¦ã¯ãªããªã
|
---|
236 | # NamedList ã clone_for_composite ããå ´åã¯ãitem ã«ãã¡ã½ãããå¿
|
---|
237 | è¦
|
---|
238 | # @type:: string ã¨ã©ã¼ã¡ãã»ã¼ã¸
|
---|
239 |
|
---|
240 | def initialize( item, type )
|
---|
241 | @names = {}
|
---|
242 | @items = []
|
---|
243 | @type = type
|
---|
244 | add_item( item )
|
---|
245 | end
|
---|
246 |
|
---|
247 | #=== è¦ç´ ãå ãã
|
---|
248 | # parse ããæç¹ã§å ãããã¨(å ´æãè¨æ¶ãã)
|
---|
249 | def add_item( item )
|
---|
250 |
|
---|
251 | if item then
|
---|
252 | assert_name item
|
---|
253 | name = item.get_name
|
---|
254 | prev = @names[name]
|
---|
255 | if prev then
|
---|
256 | Generator.error( "S2001 \'$1\' duplicate $2" , name, @type )
|
---|
257 | prev_locale = prev.get_locale
|
---|
258 | puts "previous: #{prev_locale[0]}: line #{prev_locale[1]} \'#{name}\' defined here"
|
---|
259 | return self
|
---|
260 | end
|
---|
261 |
|
---|
262 | @names[name]=item
|
---|
263 | @items << item
|
---|
264 | end
|
---|
265 |
|
---|
266 | return self
|
---|
267 | end
|
---|
268 |
|
---|
269 | def change_item( item )
|
---|
270 | assert_name item
|
---|
271 | name = item.get_name
|
---|
272 |
|
---|
273 | prev_one = @names[name]
|
---|
274 | @names[name]=item
|
---|
275 |
|
---|
276 | @items = @items - [ prev_one ]
|
---|
277 | @items << item
|
---|
278 | end
|
---|
279 |
|
---|
280 | def del_item( item )
|
---|
281 | assert_name item
|
---|
282 | name = item.get_name
|
---|
283 | @names.delete name
|
---|
284 |
|
---|
285 | @items = @items - [ item ]
|
---|
286 | end
|
---|
287 |
|
---|
288 | def get_item( name )
|
---|
289 | if ! name.kind_of? Symbol
|
---|
290 | print "get_item: '#{name}', items are below\n"
|
---|
291 | @names.each{ |nm,item|
|
---|
292 | p nm
|
---|
293 | }
|
---|
294 | raise "get_item: #{name}: not Symbol"
|
---|
295 | end
|
---|
296 | if name then
|
---|
297 | return @names[name.to_sym]
|
---|
298 | else
|
---|
299 | return nil
|
---|
300 | end
|
---|
301 | end
|
---|
302 |
|
---|
303 | def get_items
|
---|
304 | return @items
|
---|
305 | end
|
---|
306 |
|
---|
307 | #=== composite cell ã clone ããæã«è¦ç´ (JOIN) ã® clone ãã
|
---|
308 | #
|
---|
309 | # mikan ãã®ã¡ã½ãã㯠Join ã«ç¹åããã¦ããã®ã§ NamedList ããåé¢ãã¹ã
|
---|
310 | def clone_for_composite( ct_name, cell_name, locale )
|
---|
311 | cl = self.clone
|
---|
312 | cl.set_cloned( ct_name, cell_name, locale )
|
---|
313 | return cl
|
---|
314 | end
|
---|
315 |
|
---|
316 | #=== clone ããã NamedList ã¤ã³ã¹ã¿ã³ã¹ã®åç
|
---|
317 | §ãããã®(item)ã clone
|
---|
318 | #
|
---|
319 | # mikan ãã®ã¡ã½ãã㯠Join ã«ç¹åããã¦ããã®ã§ NamedList ããåé¢ãã¹ã
|
---|
320 | def set_cloned( ct_name, cell_name, locale )
|
---|
321 | items = []
|
---|
322 | names = {}
|
---|
323 | @items.each { |i|
|
---|
324 | dbgPrint "NamedList clone #{ct_name}, #{cell_name}, #{i.get_name}\n"
|
---|
325 |
|
---|
326 | cl = i.clone_for_composite( ct_name, cell_name, locale )
|
---|
327 | names[cl.get_name] = cl
|
---|
328 | items << cl
|
---|
329 | }
|
---|
330 | @items = items
|
---|
331 | @names = names
|
---|
332 | end
|
---|
333 |
|
---|
334 | def assert_name item
|
---|
335 | if ! item.get_name.kind_of? Symbol
|
---|
336 | raise "Not symbol for NamedList item"
|
---|
337 | end
|
---|
338 | end
|
---|
339 |
|
---|
340 | def show_tree( indent )
|
---|
341 | @items.each { |i|
|
---|
342 | i.show_tree( indent )
|
---|
343 | }
|
---|
344 | end
|
---|
345 |
|
---|
346 | end
|
---|
347 |
|
---|
348 | class Typedef < BDNode
|
---|
349 | # @declarator:: Decl
|
---|
350 |
|
---|
351 | def self.new_decl_list( type_spec_qual_list, decl_list )
|
---|
352 | decl_list.each { |decl|
|
---|
353 | Typedef.new( type_spec_qual_list, decl )
|
---|
354 | }
|
---|
355 | end
|
---|
356 |
|
---|
357 | def initialize( type_spec_qual_list, decl )
|
---|
358 | super()
|
---|
359 | decl.set_type( type_spec_qual_list )
|
---|
360 | @declarator = decl
|
---|
361 | decl.set_owner self # Decl(Typedef)
|
---|
362 |
|
---|
363 | Namespace.new_typedef( self )
|
---|
364 | end
|
---|
365 |
|
---|
366 | def get_name
|
---|
367 | @declarator.get_name
|
---|
368 | end
|
---|
369 |
|
---|
370 | def get_declarator
|
---|
371 | @declarator
|
---|
372 | end
|
---|
373 |
|
---|
374 | def show_tree( indent )
|
---|
375 | indent.times { print " " }
|
---|
376 | puts "Typedef: #{locale_str}"
|
---|
377 | @declarator.show_tree( indent + 1 )
|
---|
378 | end
|
---|
379 | end
|
---|
380 |
|
---|
381 | #== é¢æ°é é¨
|
---|
382 | # signature ã«ç»é²ãããé¢æ°
|
---|
383 | class FuncHead <BDNode
|
---|
384 | # @declarator:: Decl
|
---|
385 |
|
---|
386 | def initialize( declarator, type, b_oneway )
|
---|
387 | super()
|
---|
388 | declarator.set_type( type )
|
---|
389 | @declarator = declarator
|
---|
390 | @declarator.set_owner self # Decl (FuncHead)
|
---|
391 |
|
---|
392 | if @declarator.get_type.kind_of?( FuncType ) then
|
---|
393 | if b_oneway then
|
---|
394 | @declarator.get_type.set_oneway( b_oneway )
|
---|
395 | end
|
---|
396 | end
|
---|
397 | @declarator.get_type.check_struct_tag :FUNCHEAD
|
---|
398 |
|
---|
399 | # check if return type is pointer
|
---|
400 | if declarator.get_type.kind_of? FuncType then
|
---|
401 | if declarator.get_type.get_type.get_original_type.kind_of?( PtrType ) &&
|
---|
402 | Signature.get_current.is_deviate? == false then
|
---|
403 | cdl_warning( "W3004 $1 pointer type has returned. specify deviate or stop return pointer" , @declarator.get_identifier )
|
---|
404 | end
|
---|
405 | end
|
---|
406 | end
|
---|
407 |
|
---|
408 | def get_name
|
---|
409 | @declarator.get_name
|
---|
410 | end
|
---|
411 |
|
---|
412 | def get_declarator
|
---|
413 | @declarator
|
---|
414 | end
|
---|
415 |
|
---|
416 | def is_oneway?
|
---|
417 | if @declarator.is_function? then
|
---|
418 | return @declarator.get_type.is_oneway?
|
---|
419 | end
|
---|
420 | return false
|
---|
421 | end
|
---|
422 |
|
---|
423 | def is_function?
|
---|
424 | @declarator.is_function?
|
---|
425 | end
|
---|
426 |
|
---|
427 | #=== FuncHead# é¢æ°ã®ååãè¿ã
|
---|
428 | def get_name
|
---|
429 | return @declarator.get_name
|
---|
430 | end
|
---|
431 |
|
---|
432 | #=== FuncHead# é¢æ°ã®æ»ãå¤ã®åãè¿ã
|
---|
433 | # types.rb ã«å®ç¾©ããã¦ããå
|
---|
434 | # é¢æ°ãããã®å®ç¾©ã¨ãã¦ä¸å®å
|
---|
435 | ¨ãªå ´å nil ãè¿ã
|
---|
436 | def get_return_type
|
---|
437 | if is_function? then
|
---|
438 | return @declarator.get_type.get_type
|
---|
439 | end
|
---|
440 | end
|
---|
441 |
|
---|
442 | #=== FuncHead# é¢æ°ã®å¼æ°ã®ãªã¹ããè¿ã
|
---|
443 | # ParamList ãè¿ã
|
---|
444 | # é¢æ°ãããã®å®ç¾©ã¨ãã¦ä¸å®å
|
---|
445 | ¨ãªå ´å nil ãè¿ã
|
---|
446 | def get_paramlist
|
---|
447 | if is_function? then
|
---|
448 | return @declarator.get_type.get_paramlist
|
---|
449 | end
|
---|
450 | end
|
---|
451 |
|
---|
452 | def show_tree( indent )
|
---|
453 | indent.times { print " " }
|
---|
454 | puts "FuncHead: #{locale_str}"
|
---|
455 | @declarator.show_tree( indent + 1 )
|
---|
456 | end
|
---|
457 | end
|
---|
458 |
|
---|
459 | #=== 宣è¨
|
---|
460 | # @kind ã§ç¤ºãããå種ã®å®£è¨
|
---|
461 | class Decl < BDNode
|
---|
462 |
|
---|
463 | # @identifer:: String
|
---|
464 | # @global_name:: String | nil : String(@kind=TYPEDEF||:CONSTANT), nil(@kind=ãã®ä»)
|
---|
465 | # set_kind ã«ã¦è¨å®ããã
|
---|
466 | # @type:: ArrayType, FuncType, PtrType, IntType, StructType
|
---|
467 | # VoidType, FloatType, DefinedType, BoolType
|
---|
468 | # @initializer:: constant_expression, mikan { initlist }
|
---|
469 | # @kind:: :VAR, :ATTRIBUTE, :PARAMETER, :TYPEDEF, :CONSTANT, :MEMBER, :FUNCHEAD(signatureã®é¢æ°å®ç¾©)
|
---|
470 | # @b_referenced:: bool
|
---|
471 | #
|
---|
472 | # 以ä¸ã¯ã@kind ã :VAR, :ATTRIBUTE ã®ã¨ãã«æå¹
|
---|
473 | # @rw:: bool # å¤ãææ³ã§ã¯ attr ã«æå®å¯è½ã ã£ãï¼æ¶ãã«ã¯ generate ã®ä¿®æ£ãå¿
|
---|
474 | è¦ï¼
|
---|
475 | # @omit:: bool
|
---|
476 | # @choice_list:: [String] attr åæå¤ã®é¸æè¢
|
---|
477 | # 以ä¸ã¯ã@kind ã :VAR, :ATTRIBUTE, :MEMBER ã®ã¨ãã«æå¹
|
---|
478 | # @size_is:: Expression or nil unless specified
|
---|
479 | # 以ä¸ã¯ã@kind ã :MEMBER ã®ã¨ãã«æå¹
|
---|
480 | # @count_is:: Expression or nil unless specified
|
---|
481 | # attr, var ã®å ´åãcount_is ã¯æå®ã§ããªã
|
---|
482 | # @string:: Expression, -1 (length not specified) or nil (not specified)
|
---|
483 | #
|
---|
484 | # mikan ParamDecl ã ãå¥ã«è¨ããããMemberDecl, AttrDecl ãªã©ãåããã¹ãã(ï¼)
|
---|
485 |
|
---|
486 | def initialize( identifier )
|
---|
487 | super()
|
---|
488 | @identifier = identifier
|
---|
489 | @rw = false
|
---|
490 | @omit = false
|
---|
491 | @size_is = nil
|
---|
492 | @count_is = nil
|
---|
493 | @string = nil
|
---|
494 | @choice_list = nil
|
---|
495 | @b_referenced = false
|
---|
496 | end
|
---|
497 |
|
---|
498 | def set_initializer( initializer )
|
---|
499 | @initializer = initializer
|
---|
500 | end
|
---|
501 |
|
---|
502 | def get_initializer
|
---|
503 | @initializer
|
---|
504 | end
|
---|
505 |
|
---|
506 | def is_function?
|
---|
507 | if @type.class == FuncType then
|
---|
508 | return true
|
---|
509 | else
|
---|
510 | return false
|
---|
511 | end
|
---|
512 | end
|
---|
513 |
|
---|
514 | #== Decl ã®æå³ç誤ãããã§ãã¯ãã
|
---|
515 | def check
|
---|
516 | # return nil if @type == nil
|
---|
517 |
|
---|
518 | # æ§é ä½ã¿ã°ãã§ãã¯ï¼ãã¤ã³ã¿åããæ§é ä½ãåç
|
---|
519 | §ããã¦ããå ´åã¯ãã¿ã°ã®åå¨ããã§ãã¯ããªãï¼
|
---|
520 | @type.check_struct_tag @kind
|
---|
521 |
|
---|
522 | # åã®ãã§ãã¯ãè¡ã
|
---|
523 | res = @type.check
|
---|
524 | if res then
|
---|
525 | cdl_error( "S2002 $1: $2" , @identifier, res )
|
---|
526 | end
|
---|
527 |
|
---|
528 | # ä¸è¦ã®åæååããã§ãã¯ãã
|
---|
529 | if @initializer then
|
---|
530 | case @kind
|
---|
531 | when :PARAMETER, :TYPEDEF, :MEMBER, :FUNCHEAD
|
---|
532 | cdl_error( "S2003 $1: $2 cannot have initializer" , @identifier, @kind.to_s.downcase )
|
---|
533 | when :VAR, :ATTRIBUTE, :CONSTANT
|
---|
534 | # p @initializer ããã§ã¯ä»£å
|
---|
535 | ¥å¯è½ãã©ããããã§ãã¯ããªã
|
---|
536 | # :VAR, :ATTRIBUTE, :CONSTANT ã¯ããããã§ãã§ãã¯ãã
|
---|
537 | # return @type.check_init( @identifier, @initializer, @kind )
|
---|
538 | else
|
---|
539 | raise "unknown kind in Delc::check"
|
---|
540 | end
|
---|
541 | end
|
---|
542 |
|
---|
543 | if( @type.kind_of? ArrayType ) && ( @type.get_subscript == nil ) && ( @omit == false ) then
|
---|
544 | if @kind == :ATTRIBUTE then
|
---|
545 | cdl_error( "S2004 $1: array subscript must be specified or omit" , @identifier )
|
---|
546 | elsif @kind == :VAR || @kind == :MEMBER then
|
---|
547 | cdl_error( "S2005 $1: array subscript must be specified" , @identifier )
|
---|
548 | end
|
---|
549 | end
|
---|
550 |
|
---|
551 | return nil
|
---|
552 | end
|
---|
553 |
|
---|
554 | #== ãã¤ã³ã¿ã¬ãã«ãå¾ã
|
---|
555 | # æ»ãå¤ï¼
|
---|
556 | # éãã¤ã³ã¿å¤æ° = 0
|
---|
557 | # ãã¤ã³ã¿å¤æ° = 1
|
---|
558 | # äºéãã¤ã³ã¿å¤æ° = 2
|
---|
559 | def get_ptr_level
|
---|
560 | level = 0
|
---|
561 | type = @type
|
---|
562 | while 1
|
---|
563 | if type.kind_of?( PtrType ) then
|
---|
564 | level += 1
|
---|
565 | type = type.get_referto
|
---|
566 | # elsif type.kind_of?( ArrayType ) then # æ·»æ°ãªãé
|
---|
567 | åã¯ãã¤ã³ã¿ã¨ã¿ãªã
|
---|
568 | # if type.get_subscript == nil then
|
---|
569 | # level += 1
|
---|
570 | # type = type.get_type
|
---|
571 | # else
|
---|
572 | # break
|
---|
573 | # end
|
---|
574 | # mikan ãã¤ã³ã¿ã®æ·»æ°ããé
|
---|
575 | åã®ãã¤ã³ã¿ã¬ãã«ã¯ï¼ã§ããï¼
|
---|
576 | elsif type.kind_of?( DefinedType ) then
|
---|
577 | type = type.get_type
|
---|
578 | # p "DefinedType: #{type} #{type.class}"
|
---|
579 | else
|
---|
580 | break
|
---|
581 | end
|
---|
582 | end
|
---|
583 | return level
|
---|
584 | end
|
---|
585 |
|
---|
586 | def get_name
|
---|
587 | @identifier
|
---|
588 | end
|
---|
589 |
|
---|
590 | def get_global_name
|
---|
591 | @global_name
|
---|
592 | end
|
---|
593 |
|
---|
594 | def set_type( type )
|
---|
595 | unless @type then
|
---|
596 | @type = type
|
---|
597 | else
|
---|
598 | @type.set_type( type ) # èã«è¨å®
|
---|
599 | end
|
---|
600 | end
|
---|
601 |
|
---|
602 | def get_type
|
---|
603 | @type
|
---|
604 | end
|
---|
605 |
|
---|
606 | def get_identifier
|
---|
607 | @identifier
|
---|
608 | end
|
---|
609 |
|
---|
610 | # STAGE: B
|
---|
611 | def set_kind( kind )
|
---|
612 | @kind = kind
|
---|
613 | case kind
|
---|
614 | when :TYPEDEF, :CONSTANT
|
---|
615 | if Namespace.get_global_name.to_s == "" then
|
---|
616 | @global_name = @identifier
|
---|
617 | else
|
---|
618 | @global_name = :"#{Namespace.get_global_name}_#{@identifier}"
|
---|
619 | end
|
---|
620 | else
|
---|
621 | @global_name = nil
|
---|
622 | end
|
---|
623 | end
|
---|
624 |
|
---|
625 | def get_kind
|
---|
626 | @kind
|
---|
627 | end
|
---|
628 |
|
---|
629 | def set_specifier_list( spec_list )
|
---|
630 | spec_list.each{ |spec|
|
---|
631 | case spec[0]
|
---|
632 | when :RW
|
---|
633 | @rw = true
|
---|
634 | when :OMIT
|
---|
635 | @omit = true
|
---|
636 | when :SIZE_IS
|
---|
637 | @size_is = spec[1]
|
---|
638 | when :COUNT_IS
|
---|
639 | @count_is = spec[1]
|
---|
640 | when :STRING
|
---|
641 | @string = spec[1]
|
---|
642 | when :CHOICE
|
---|
643 | @choice_list = spec[1]
|
---|
644 | else
|
---|
645 | raise "Unknown specifier #{spec[0]}"
|
---|
646 | end
|
---|
647 | }
|
---|
648 |
|
---|
649 | if @size_is || @count_is || @string
|
---|
650 | @type.set_scs( @size_is, @count_is, @string, nil, false )
|
---|
651 | end
|
---|
652 | end
|
---|
653 |
|
---|
654 | def is_rw?
|
---|
655 | @rw
|
---|
656 | end
|
---|
657 |
|
---|
658 | def is_omit?
|
---|
659 | @omit
|
---|
660 | end
|
---|
661 |
|
---|
662 | def get_size_is
|
---|
663 | @size_is
|
---|
664 | end
|
---|
665 |
|
---|
666 | def get_count_is
|
---|
667 | @count_is
|
---|
668 | end
|
---|
669 |
|
---|
670 | def get_string
|
---|
671 | @string
|
---|
672 | end
|
---|
673 |
|
---|
674 | def get_choice_list
|
---|
675 | @choice_list
|
---|
676 | end
|
---|
677 |
|
---|
678 | def referenced
|
---|
679 | @b_referenced = true
|
---|
680 | end
|
---|
681 |
|
---|
682 | def is_referenced?
|
---|
683 | @b_referenced
|
---|
684 | end
|
---|
685 |
|
---|
686 | def is_type?( type )
|
---|
687 | t = @type
|
---|
688 | while 1
|
---|
689 | if t.kind_of?( type ) then
|
---|
690 | return true
|
---|
691 | elsif t.kind_of?( DefinedType ) then
|
---|
692 | t = t.get_type
|
---|
693 | else
|
---|
694 | return false
|
---|
695 | end
|
---|
696 | end
|
---|
697 | end
|
---|
698 |
|
---|
699 | def is_const?
|
---|
700 | type = @type
|
---|
701 | while 1
|
---|
702 | if type.is_const? then
|
---|
703 | return true
|
---|
704 | elsif type.kind_of?( DefinedType ) then
|
---|
705 | type = type.get_type
|
---|
706 | else
|
---|
707 | return false
|
---|
708 | end
|
---|
709 | end
|
---|
710 | end
|
---|
711 |
|
---|
712 | def show_tree( indent )
|
---|
713 | indent.times { print " " }
|
---|
714 | puts "Declarator: name: #{@identifier} kind: #{@kind} global_name: #{@global_name} #{locale_str}"
|
---|
715 | (indent+1).times { print " " }
|
---|
716 | puts "type:"
|
---|
717 | @type.show_tree( indent + 2 )
|
---|
718 | if @initializer then
|
---|
719 | (indent+1).times { print " " }
|
---|
720 | puts "initializer:"
|
---|
721 | @initializer.show_tree( indent + 2 )
|
---|
722 | else
|
---|
723 | (indent+1).times { print " " }
|
---|
724 | puts "initializer: no"
|
---|
725 | end
|
---|
726 | (indent+1).times { print " " }
|
---|
727 | puts "size_is: #{@size_is.to_s}, count_is: #{@count_is.to_s}, string: #{@string.to_s} referenced: #{@b_referenced} "
|
---|
728 |
|
---|
729 | end
|
---|
730 |
|
---|
731 | end
|
---|
732 |
|
---|
733 | # é¢æ°ãã©ã¡ã¼ã¿ã®å®£è¨
|
---|
734 | class ParamDecl < BDNode
|
---|
735 |
|
---|
736 | # @declarator:: Decl: Token, ArrayType, FuncType, PtrType
|
---|
737 | # @direction:: :IN, :OUT, :INOUT, :SEND, :RECEIVE
|
---|
738 | # @size:: Expr (size_is å¼æ°)
|
---|
739 | # @count:: Expr (count_is å¼æ°)
|
---|
740 | # @max:: Expr (size_is ã®ç¬¬äºå¼æ°)
|
---|
741 | # @b_nullable:: Bool : nullable
|
---|
742 | # @string:: Expr or -1(if size not specified) ï¼string å¼æ°ï¼
|
---|
743 | # @allocator:: Signature of allocator
|
---|
744 | # @b_ref:: bool : size_is, count_is, string_is å¼æ°ã¨ãã¦åç
|
---|
745 | §ããã¦ãã
|
---|
746 | #
|
---|
747 | # 1. é¢æ°åã§ãªããã¨
|
---|
748 | # 2. ï¼æ¬¡å
|
---|
749 | 以ä¸ã®é
|
---|
750 | åã§ãã£ã¦æãå
|
---|
751 | å´ä»¥å¤ã®æ·»æ°ããããã¨
|
---|
752 | # 3. in, out, ..., size_is, count_is, ... ã®éè¤æå®ããªããã¨
|
---|
753 | # 4. ãã¤ã³ã¿ã¬ãã«ãé©åãªãã¨
|
---|
754 |
|
---|
755 | def initialize( declarator, specifier, param_specifier )
|
---|
756 | super()
|
---|
757 | @declarator = declarator
|
---|
758 | @declarator.set_owner self # Decl (ParamDecl)
|
---|
759 | @declarator.set_type( specifier )
|
---|
760 | @param_specifier = param_specifier
|
---|
761 | @b_ref = false
|
---|
762 | @b_nullable = false
|
---|
763 |
|
---|
764 | if @declarator.is_function? then # (1)
|
---|
765 | cdl_error( "S2006 \'$1\' function" , get_name )
|
---|
766 | return
|
---|
767 | end
|
---|
768 |
|
---|
769 | res = @declarator.check
|
---|
770 | if res then # (2)
|
---|
771 | cdl_error( "S2007 \'$1\' $2" , get_name, res )
|
---|
772 | return
|
---|
773 | end
|
---|
774 |
|
---|
775 | @param_specifier.each { |i|
|
---|
776 | case i[0] # (3)
|
---|
777 | when :IN, :OUT, :INOUT, :SEND, :RECEIVE
|
---|
778 | if @direction == nil then
|
---|
779 | @direction = i[0]
|
---|
780 | elsif i[0] == @direction then
|
---|
781 | cdl_warning( "W3001 $1: duplicate" , i[0] )
|
---|
782 | next
|
---|
783 | else
|
---|
784 | cdl_error( "S2008 $1: inconsitent with previous one" , i[0] )
|
---|
785 | next
|
---|
786 | end
|
---|
787 |
|
---|
788 | case i[0]
|
---|
789 | when :SEND, :RECEIVE
|
---|
790 | @allocator = Namespace.find( i[1] ) #1
|
---|
791 | if ! @allocator.instance_of?( Signature ) then
|
---|
792 | cdl_error( "S2009 $1: not found or not signature" , i[1] )
|
---|
793 | next
|
---|
794 | elsif ! @allocator.is_allocator? then
|
---|
795 | # cdl_error( "S2010 $1: not allocator signature" , i[1] )
|
---|
796 | end
|
---|
797 | end
|
---|
798 |
|
---|
799 | when :SIZE_IS
|
---|
800 | if @size then
|
---|
801 | cdl_error( "S2011 size_is duplicate" )
|
---|
802 | else
|
---|
803 | @size = i[1]
|
---|
804 | end
|
---|
805 | when :COUNT_IS
|
---|
806 | if @count then
|
---|
807 | cdl_error( "S2012 count_is duplicate" )
|
---|
808 | else
|
---|
809 | @count = i[1]
|
---|
810 | end
|
---|
811 | when :STRING
|
---|
812 | if @string then
|
---|
813 | cdl_error( "S2013 string duplicate" )
|
---|
814 | elsif i[1] then
|
---|
815 | @string = i[1]
|
---|
816 | else
|
---|
817 | @string = -1
|
---|
818 | end
|
---|
819 | when :MAX_IS
|
---|
820 | # max_is ã¯ãå
|
---|
821 | é¨çãªãã® bnf.y.rb åç
|
---|
822 | §
|
---|
823 | # size_is ã§éè¤ãã§ãã¯ããã
|
---|
824 | @max = i[1]
|
---|
825 | when :NULLABLE
|
---|
826 | # if ! @declarator.get_type.kind_of?( PtrType ) then
|
---|
827 | # cdl_error( "S2026 '$1' nullable specified for non-pointer type", @declarator.get_name )
|
---|
828 | # else
|
---|
829 | @b_nullable = true
|
---|
830 | # end
|
---|
831 | end
|
---|
832 |
|
---|
833 | }
|
---|
834 |
|
---|
835 | if @direction == nil then
|
---|
836 | cdl_error( "S2014 No direction specified. [in/out/inout/send/receive]" )
|
---|
837 | end
|
---|
838 |
|
---|
839 | if ( @direction == :OUT || @direction == :INOUT ) && @string == -1 then
|
---|
840 | cdl_warning( "W3002 $1: this string might cause buffer over run" , get_name )
|
---|
841 | end
|
---|
842 |
|
---|
843 | # mikan ãã¤ã³ã¿ã®é
|
---|
844 | åï¼æ·»æ°æï¼ã®ã¬ãã«ãï¼
|
---|
845 | ptr_level = @declarator.get_ptr_level
|
---|
846 |
|
---|
847 | # p "ptr_level: #{@declarator.get_identifier} #{ptr_level}"
|
---|
848 | # p @declarator
|
---|
849 |
|
---|
850 | #---- set req_level, min_level & max_level ----#
|
---|
851 | if !(@size||@count||@string) then # (4)
|
---|
852 | req_level = 1
|
---|
853 | elsif (@size||@count)&&@string then
|
---|
854 | req_level = 2
|
---|
855 | else
|
---|
856 | req_level = 1
|
---|
857 | end
|
---|
858 |
|
---|
859 | if @direction == :RECEIVE then
|
---|
860 | req_level += 1
|
---|
861 | end
|
---|
862 | min_level = req_level
|
---|
863 | max_level = req_level
|
---|
864 |
|
---|
865 | # IN without pointer specifier can be non-pointer type
|
---|
866 | if @direction == :IN && !(@size||@count||@string) then
|
---|
867 | min_level = 0
|
---|
868 | end
|
---|
869 |
|
---|
870 | # if size_is specified and pointer refer to struct, max_level increase
|
---|
871 | if @size then
|
---|
872 | type = @declarator.get_type.get_original_type
|
---|
873 | while type.kind_of? PtrType
|
---|
874 | type = type.get_referto.get_original_type
|
---|
875 | end
|
---|
876 | if type.kind_of? StructType then
|
---|
877 | max_level += 1
|
---|
878 | end
|
---|
879 | end
|
---|
880 | #---- end req_level & max_level ----#
|
---|
881 |
|
---|
882 | # p "req_level: #{req_level} ptr_level: #{ptr_level}"
|
---|
883 | #if ptr_level < req_level && ! ( @direction == :IN && req_level == 1 && ptr_level == 0) then
|
---|
884 | if ptr_level < min_level then
|
---|
885 | cdl_error( "S2014 $1 need pointer or more pointer" , @declarator.get_identifier )
|
---|
886 | elsif ptr_level > max_level then
|
---|
887 | # note: æ§æ解æ段éã§å®è¡ã®ãã get_current å¯
|
---|
888 | if Signature.get_current == nil || Signature.get_current.is_deviate? == false then
|
---|
889 | cdl_warning( "W3003 $1 pointer level mismatch" , @declarator.get_identifier )
|
---|
890 | end
|
---|
891 | end
|
---|
892 |
|
---|
893 | type = @declarator.get_type
|
---|
894 | while type.kind_of?( DefinedType )
|
---|
895 | type = type.get_original_type
|
---|
896 | end
|
---|
897 |
|
---|
898 | if ptr_level > 0 then
|
---|
899 | # size_is, count_is, string ãã»ãã
|
---|
900 | if @direction == :RECEIVE && ptr_level > 1 then
|
---|
901 | type.get_type.set_scs( @size, @count, @string, @max, @b_nullable )
|
---|
902 | else
|
---|
903 | type.set_scs( @size, @count, @string, @max, @b_nullable )
|
---|
904 | end
|
---|
905 |
|
---|
906 | #p ptr_level
|
---|
907 | #type.show_tree 1
|
---|
908 |
|
---|
909 | # ãã¤ã³ã¿ãæãã¦ããå
|
---|
910 | ã®ãã¼ã¿åãå¾ã
|
---|
911 | i = 0
|
---|
912 | t2 = type
|
---|
913 | while i < ptr_level
|
---|
914 | t2 = t2.get_referto
|
---|
915 | while t2.kind_of?( DefinedType )
|
---|
916 | t2 = t2.get_original_type
|
---|
917 | end
|
---|
918 | i += 1
|
---|
919 | end
|
---|
920 |
|
---|
921 | # p @declarator.get_name
|
---|
922 | # t2.show_tree 1
|
---|
923 | # p t2.is_const?
|
---|
924 |
|
---|
925 | # const 修飾ãé©åããã§ãã¯
|
---|
926 | if @direction == :IN then
|
---|
927 | if ! t2.is_const? then
|
---|
928 | cdl_error( "S2015 '$1' must be const for \'in\' parameter $2" , get_name, type.class )
|
---|
929 | end
|
---|
930 | else
|
---|
931 | if t2.is_const? then
|
---|
932 | cdl_error( "S2016 '$1' can not be const for $2 parameter" , get_name, @direction )
|
---|
933 | end
|
---|
934 | end
|
---|
935 | else
|
---|
936 | # éãã¤ã³ã¿ã¿ã¤ã
|
---|
937 | if @size != nil || @count != nil || @string != nil || @max != nil || @b_nullable then
|
---|
938 | type.set_scs( @size, @count, @string, @max, @b_nullable )
|
---|
939 | end
|
---|
940 | end
|
---|
941 |
|
---|
942 | # if ptr_level > 0 && @direction == :IN then
|
---|
943 | # if type.is_const != :CONST
|
---|
944 | # end
|
---|
945 |
|
---|
946 | # p self
|
---|
947 |
|
---|
948 | end
|
---|
949 |
|
---|
950 | def check_struct_tag kind
|
---|
951 | @declarator.get_type.check_struct_tag :PARAMETER
|
---|
952 | end
|
---|
953 |
|
---|
954 | def get_name
|
---|
955 | @declarator.get_name
|
---|
956 | end
|
---|
957 |
|
---|
958 | def get_size
|
---|
959 | @size
|
---|
960 | end
|
---|
961 |
|
---|
962 | def get_count
|
---|
963 | @count
|
---|
964 | end
|
---|
965 |
|
---|
966 | def get_string
|
---|
967 | @string
|
---|
968 | end
|
---|
969 |
|
---|
970 | def get_max
|
---|
971 | @max
|
---|
972 | end
|
---|
973 |
|
---|
974 | def clear_max
|
---|
975 | # p "clear_max: #{@declarator.get_name} #{@max.to_s}"
|
---|
976 | @max = nil
|
---|
977 | @declarator.get_type.clear_max
|
---|
978 | end
|
---|
979 |
|
---|
980 | def is_nullable?
|
---|
981 | @b_nullable
|
---|
982 | end
|
---|
983 |
|
---|
984 | def get_type
|
---|
985 | @declarator.get_type
|
---|
986 | end
|
---|
987 |
|
---|
988 | def get_direction
|
---|
989 | @direction
|
---|
990 | end
|
---|
991 |
|
---|
992 | def get_declarator
|
---|
993 | @declarator
|
---|
994 | end
|
---|
995 |
|
---|
996 | def get_allocator
|
---|
997 | @allocator
|
---|
998 | end
|
---|
999 |
|
---|
1000 | def referenced
|
---|
1001 | @b_ref = true
|
---|
1002 | end
|
---|
1003 |
|
---|
1004 | def is_referenced?
|
---|
1005 | @b_ref
|
---|
1006 | end
|
---|
1007 |
|
---|
1008 | #=== PPAllocator ãå¿
|
---|
1009 | è¦ã
|
---|
1010 | # Transparent RPC ã®å ´å in 㧠size_is, count_is, string ã®ãããããæå®ããã¦ããå ´å oneway ã§ã¯ PPAllocator ãå¿
|
---|
1011 | è¦
|
---|
1012 | # Transparent PC 㧠oneway ãã©ããã¯ãããã§ã¯å¤æããªãã®ã§å¥éå¤æãå¿
|
---|
1013 | è¦
|
---|
1014 | # Opaque RPC ã®å ´å size_is, count_is, string ã®ãããããæå®ããã¦ããå ´åãPPAllocator ãå¿
|
---|
1015 | è¦
|
---|
1016 | def need_PPAllocator?( b_opaque = false )
|
---|
1017 | if ! b_opaque then
|
---|
1018 | # if @direction == :IN && ( @size || @count || @string ) then
|
---|
1019 | if @direction == :IN && @declarator.get_type.get_original_type.kind_of?( PtrType ) then
|
---|
1020 | return true
|
---|
1021 | end
|
---|
1022 | else
|
---|
1023 | if (@direction == :IN || @direction == :OUT || @direction == :INOUT ) &&
|
---|
1024 | @declarator.get_type.get_original_type.kind_of?( PtrType ) then
|
---|
1025 | return true
|
---|
1026 | end
|
---|
1027 | end
|
---|
1028 | return false
|
---|
1029 | end
|
---|
1030 |
|
---|
1031 | def show_tree( indent )
|
---|
1032 | indent.times { print " " }
|
---|
1033 | puts "ParamDecl: direction: #{@direction} #{locale_str}"
|
---|
1034 | @declarator.show_tree( indent + 1 )
|
---|
1035 | if @size then
|
---|
1036 | (indent+1).times { print " " }
|
---|
1037 | puts "size:"
|
---|
1038 | @size.show_tree( indent + 2 )
|
---|
1039 | end
|
---|
1040 | if @count then
|
---|
1041 | (indent+1).times { print " " }
|
---|
1042 | puts "count:"
|
---|
1043 | @count.show_tree( indent + 2 )
|
---|
1044 | end
|
---|
1045 | if @string then
|
---|
1046 | (indent+1).times { print " " }
|
---|
1047 | puts "string:"
|
---|
1048 | if @string == -1 then
|
---|
1049 | (indent+2).times { print " " }
|
---|
1050 | puts "size is not specified"
|
---|
1051 | else
|
---|
1052 | @string.show_tree( indent + 2 )
|
---|
1053 | end
|
---|
1054 | end
|
---|
1055 | if @allocator then
|
---|
1056 | (indent+1).times { print " " }
|
---|
1057 | puts "allocator: signature: #{@allocator.get_name}"
|
---|
1058 | end
|
---|
1059 | end
|
---|
1060 | end
|
---|
1061 |
|
---|
1062 | # é¢æ°ãã©ã¡ã¼ã¿ãªã¹ã
|
---|
1063 | class ParamList < BDNode
|
---|
1064 | # @param_list:: NamedList : item: ParamDecl
|
---|
1065 |
|
---|
1066 | def initialize( paramdecl )
|
---|
1067 | super()
|
---|
1068 | @param_list = NamedList.new( paramdecl, "parameter" )
|
---|
1069 | @param_list.get_items.each { |paramdecl|
|
---|
1070 | paramdecl.set_owner self # ParamDecl
|
---|
1071 | }
|
---|
1072 | end
|
---|
1073 |
|
---|
1074 | def add_param( paramdecl )
|
---|
1075 | return if paramdecl == nil # æ¢ã«ã¨ã©ã¼
|
---|
1076 |
|
---|
1077 | @param_list.add_item( paramdecl )
|
---|
1078 | paramdecl.set_owner self # ParamDecl
|
---|
1079 | end
|
---|
1080 |
|
---|
1081 | def get_items
|
---|
1082 | @param_list.get_items
|
---|
1083 | end
|
---|
1084 |
|
---|
1085 | #=== size_is, count_is, string ã®å¼æ°ã®å¼ããã§ãã¯
|
---|
1086 | # å¤æ°ã¯åæ¹åç
|
---|
1087 | §å¯è½ãªãããé¢æ°é é¨ã®æ§æ解éãçµãã£ãå¾ã«ãã§ãã¯ãã
|
---|
1088 | def check_param
|
---|
1089 | @param_list.get_items.each { |i|
|
---|
1090 | next if i == nil # i == nil : ã¨ã©ã¼æ
|
---|
1091 |
|
---|
1092 | if i.get_type.class == VoidType then
|
---|
1093 | # åä¸ã® void åã¯ããã«ã¯ããªã
|
---|
1094 | cdl_error( "S2027 '$1' parameter cannot be void type", i.get_name )
|
---|
1095 | end
|
---|
1096 |
|
---|
1097 | size = i.get_size # Expression
|
---|
1098 | if size then
|
---|
1099 | val = size.eval_const( @param_list )
|
---|
1100 | if val == nil then # å®æ°å¼ã§ãªããï¼
|
---|
1101 | # mikan å¤æ°ãå«ãå¼ï¼åä¸ã®å¤æ°ã®ã¿ OK
|
---|
1102 | type = size.get_type( @param_list )
|
---|
1103 | unless type.kind_of?( IntType ) then
|
---|
1104 | cdl_error( "S2017 size_is argument is not integer type" )
|
---|
1105 | else
|
---|
1106 | size.check_dir_for_param( @param_list, i.get_direction, "size_is" )
|
---|
1107 | end
|
---|
1108 | else
|
---|
1109 | if val != Integer( val ) then
|
---|
1110 | cdl_error( "S2018 \'$1\' size_is parameter not integer" , i.get_declarator.get_identifier )
|
---|
1111 | elsif val <= 0 then
|
---|
1112 | cdl_error( "S2019 \'$1\' size_is parameter negative or zero" , i.get_declarator.get_identifier )
|
---|
1113 | end
|
---|
1114 | end
|
---|
1115 | end
|
---|
1116 |
|
---|
1117 | max = i.get_max
|
---|
1118 | if max then
|
---|
1119 | val2 = max.eval_const( @param_list )
|
---|
1120 | if val2 == nil then
|
---|
1121 | cdl_error( "S2028 '$1' max (size_is 2nd parameter) not constant", i.get_name )
|
---|
1122 | elsif val2 != Integer( val2 ) || val2 <= 0 then
|
---|
1123 | cdl_error( "S2029 '$1' max (size_is 2nd parameter) negative or zero, or not integer", i.get_name )
|
---|
1124 | end
|
---|
1125 | end
|
---|
1126 |
|
---|
1127 | if val != nil && val2 != nil then
|
---|
1128 | if val < val2 then
|
---|
1129 | cdl_warning( "W3005 '$1' size_is always lower than max. max is ignored", i.get_name )
|
---|
1130 | i.clear_max
|
---|
1131 | else
|
---|
1132 | cdl_error( "S2030 '$1' both size_is and max are const. size_is larger than max", i.get_name )
|
---|
1133 | end
|
---|
1134 | end
|
---|
1135 |
|
---|
1136 | count = i.get_count # Expression
|
---|
1137 | if count then
|
---|
1138 | val = count.eval_const( @param_list )
|
---|
1139 | if val == nil then # å®æ°å¼ã§ãªããï¼
|
---|
1140 | # mikan å¤æ°ãå«ãå¼ï¼åä¸ã®å¤æ°ã®ã¿ OK
|
---|
1141 | type = count.get_type( @param_list )
|
---|
1142 | unless type.kind_of?( IntType ) then
|
---|
1143 | cdl_error( "S2020 count_is argument is not integer type" )
|
---|
1144 | else
|
---|
1145 | count.check_dir_for_param( @param_list, i.get_direction, "count_is" )
|
---|
1146 | end
|
---|
1147 | else
|
---|
1148 | if val != Integer( val ) then
|
---|
1149 | cdl_error( "S2021 \'$1\' count_is parameter not integer" , i.get_declarator.get_identifier )
|
---|
1150 | elsif val <= 0 then
|
---|
1151 | cdl_error( "S2022 \'$1\' count_is parameter negative or zero" , i.get_declarator.get_identifier )
|
---|
1152 | end
|
---|
1153 | end
|
---|
1154 | end
|
---|
1155 |
|
---|
1156 | string = i.get_string # Expression
|
---|
1157 | if string != -1 && string then
|
---|
1158 | val = string.eval_const( @param_list )
|
---|
1159 | if val == nil then # å®æ°å¼ã§ãªããï¼
|
---|
1160 | # mikan å¤æ°ãå«ãå¼ï¼åä¸ã®å¤æ°ã®ã¿ OK
|
---|
1161 | type = string.get_type( @param_list )
|
---|
1162 | unless type.kind_of?( IntType ) then
|
---|
1163 | cdl_error( "S2023 string argument is not integer type" )
|
---|
1164 | else
|
---|
1165 | string.check_dir_for_param( @param_list, i.get_direction, "string" )
|
---|
1166 | end
|
---|
1167 | else
|
---|
1168 | if val != Integer( val ) then
|
---|
1169 | cdl_error( "S2024 \'$1\' string parameter not integer" , i.get_declarator.get_identifier )
|
---|
1170 | elsif val <= 0 then
|
---|
1171 | cdl_error( "S2025 \'$1\' string parameter negative or zero" , i.get_declarator.get_identifier )
|
---|
1172 | end
|
---|
1173 | end
|
---|
1174 | end
|
---|
1175 | }
|
---|
1176 | end
|
---|
1177 |
|
---|
1178 | def check_struct_tag kind
|
---|
1179 | @param_list.get_items.each{ |p|
|
---|
1180 | p.check_struct_tag kind
|
---|
1181 | }
|
---|
1182 | end
|
---|
1183 |
|
---|
1184 | #=== Push Pop Allocator ãå¿
|
---|
1185 | è¦ãï¼
|
---|
1186 | # Transparent RPC ã®å ´å (oneway ãã¤) in ã®é
|
---|
1187 | å(size_is, count_is, string ã®ããããã§ä¿®é£¾ï¼ããã
|
---|
1188 | def need_PPAllocator?( b_opaque = false )
|
---|
1189 | @param_list.get_items.each { |i|
|
---|
1190 | if i.need_PPAllocator?( b_opaque ) then
|
---|
1191 | return true
|
---|
1192 | end
|
---|
1193 | }
|
---|
1194 | false
|
---|
1195 | end
|
---|
1196 |
|
---|
1197 | def find( name )
|
---|
1198 | @param_list.get_item( name )
|
---|
1199 | end
|
---|
1200 |
|
---|
1201 | #== ParamList# æååå
|
---|
1202 | #b_name:: Bool: ãã©ã¡ã¼ã¿åãå«ãã
|
---|
1203 | def to_str( b_name )
|
---|
1204 | str = "("
|
---|
1205 | delim = ""
|
---|
1206 | @param_list.get_items.each{ |paramdecl|
|
---|
1207 | decl = paramdecl.get_declarator
|
---|
1208 | str += delim + decl.get_type
|
---|
1209 | if b_name then
|
---|
1210 | str += " " + decl.get_name
|
---|
1211 | end
|
---|
1212 | str += decl.get_type_post
|
---|
1213 | delim = ", "
|
---|
1214 | }
|
---|
1215 | str += ")"
|
---|
1216 | end
|
---|
1217 |
|
---|
1218 | def show_tree( indent )
|
---|
1219 | indent.times { print " " }
|
---|
1220 | puts "ParamList: #{locale_str}"
|
---|
1221 | @param_list.show_tree( indent + 1 )
|
---|
1222 | end
|
---|
1223 | end
|
---|
1224 |
|
---|
1225 | #== CDL ã®æååãªãã©ã«ãæ±ãããã®ã¯ã©ã¹
|
---|
1226 | # CDL ã®æååãªãã©ã«ãã®ãã®ã§ã¯ãªã
|
---|
1227 | class CDLString
|
---|
1228 | # ã¨ã¹ã±ã¼ãæåãå¤æ
|
---|
1229 | def self.escape str
|
---|
1230 | str = str.dup
|
---|
1231 | str.gsub!( /\\a/, "\x07" )
|
---|
1232 | str.gsub!( /\\b/, "\x08" )
|
---|
1233 | str.gsub!( /\\f/, "\x0c" )
|
---|
1234 | str.gsub!( /\\n/, "\x0a" )
|
---|
1235 | str.gsub!( /\\r/, "\x0d" )
|
---|
1236 | str.gsub!( /\\t/, "\x08" )
|
---|
1237 | str.gsub!( /\\v/, "\x0b" )
|
---|
1238 | str.gsub!( /(\\[Xx][0-9A-Fa-f]{1,2})/, '{printf \"\\1\"}' )
|
---|
1239 | str.gsub!( /(\\[0-7]{1,3})/, '{printf \"\\1\"}' )
|
---|
1240 | str.gsub!( /\\(.)/, "\\1" ) # mikan æªå®ç¾©ã®ã¨ã¹ã±ã¼ãã·ã¼ã±ã³ã¹ãå¤æãã¦ãã¾ã (gcc V3.4.4 ã§ã¯è¦åãåºããã)
|
---|
1241 | return str
|
---|
1242 | end
|
---|
1243 |
|
---|
1244 | #=== CDLString#åå¾ã® " ãåãé¤ã
|
---|
1245 | def self.remove_dquote str
|
---|
1246 | s = str.sub( /\A"/, "" )
|
---|
1247 | s.sub!( /"\z/, "" )
|
---|
1248 | return s
|
---|
1249 | end
|
---|
1250 | end
|
---|
1251 |
|
---|
1252 | #== CDL ã®åæååãæ±ãããã®ã¯ã©ã¹
|
---|
1253 | # CDL ã®åæååãã®ãã®ã§ã¯ãªã
|
---|
1254 | class CDLInitializer
|
---|
1255 | #=== åæååã®ã¯ãã¼ã³
|
---|
1256 | # åæåå㯠Expression, C_EXP, Array ã®ãããã
|
---|
1257 | def self.clone_for_composite( rhs, ct_name, cell_name, locale )
|
---|
1258 | if rhs.instance_of? C_EXP then
|
---|
1259 | # C_EXP ã® clone ãä½ãã¨ã¨ãã«ç½®æ
|
---|
1260 | rhs = rhs.clone_for_composite( ct_name, cell_name, locale )
|
---|
1261 | elsif rhs.instance_of? Expression then
|
---|
1262 | rhs = rhs.clone_for_composite
|
---|
1263 | elsif rhs.instance_of? Array then
|
---|
1264 | rhs = clone_for_compoiste_array( rhs, ct_name, cell_name, locale )
|
---|
1265 | else
|
---|
1266 | raise "unknown rhs for join"
|
---|
1267 | end
|
---|
1268 | return rhs
|
---|
1269 | end
|
---|
1270 |
|
---|
1271 | #=== åæååï¼é
|
---|
1272 | åï¼ã®ã¯ãã¼ã³
|
---|
1273 | # è¦ç´ 㯠clone_for_composite ãæã¤ãã®ã ã
|
---|
1274 | def self.clone_for_compoiste_array( array, ct_name, cell_name, locale )
|
---|
1275 | # "compoiste.identifier" ã®å ´å (CDL ã¨ãã¦ã¯èª¤ã)
|
---|
1276 | if array[0] == :COMPOSITE then
|
---|
1277 | return array.clone
|
---|
1278 | end
|
---|
1279 |
|
---|
1280 | new_array = array.map{ |m|
|
---|
1281 | clone_for_composite( m, ct_name, cell_name, locale )
|
---|
1282 | }
|
---|
1283 | return new_array
|
---|
1284 | end
|
---|
1285 | end
|
---|