1 | # -*- coding: utf-8 -*-
|
---|
2 | #
|
---|
3 | # TECS Generator
|
---|
4 | # Generator for TOPPERS Embedded Component System
|
---|
5 | #
|
---|
6 | # Copyright (C) 2008-2017 by TOPPERS Project
|
---|
7 | #--
|
---|
8 | # 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
|
---|
9 | # ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
|
---|
10 | # 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
|
---|
11 | # (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
|
---|
12 | # 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
|
---|
13 | # スコード中に含まれていること.
|
---|
14 | # (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
|
---|
15 | # 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
|
---|
16 | # 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
|
---|
17 | # の無保証規定を掲載すること.
|
---|
18 | # (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
|
---|
19 | # 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
|
---|
20 | # と.
|
---|
21 | # (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
|
---|
22 | # 作権表示,この利用条件および下記の無保証規定を掲載すること.
|
---|
23 | # (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
|
---|
24 | # 報告すること.
|
---|
25 | # (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
|
---|
26 | # 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
|
---|
27 | # また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
|
---|
28 | # 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
|
---|
29 | # 免責すること.
|
---|
30 | #
|
---|
31 | # 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
|
---|
32 | # よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
|
---|
33 | # に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
|
---|
34 | # アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
|
---|
35 | # の責任を負わない.
|
---|
36 | #
|
---|
37 | # $Id$
|
---|
38 | #++
|
---|
39 |
|
---|
40 | #= HasType: @type を内部に持つ型のためのモジュール
|
---|
41 | # @b_cloned::Bool : true if @type is cloned
|
---|
42 | #
|
---|
43 | # このモジュールは DefinedType, PtrType, ArrayType に include される
|
---|
44 | # 本当は typedef された時の Decl の要素のみ clone すればよいのだが、get_type, get_original_type で
|
---|
45 | # 取り出されたとき、set_scs, set_qualifier されたときに無条件で clone する (無駄にメモリを使用する)
|
---|
46 | # ただし、clone するのは一回のみである (二回 clone すると別の型を参照してしまう)
|
---|
47 | #
|
---|
48 | # initialize で clone しても、共有されているときに clone されない
|
---|
49 | #
|
---|
50 | module HasType
|
---|
51 | def initHasType
|
---|
52 | @b_cloned = false
|
---|
53 | end
|
---|
54 |
|
---|
55 | #=== HasType# @type をクローンする
|
---|
56 | def clone_type
|
---|
57 | # if @b_cloned == false then
|
---|
58 | @type = @type.clone
|
---|
59 | @b_cloned = true
|
---|
60 | # end
|
---|
61 | end
|
---|
62 | end
|
---|
63 |
|
---|
64 | class Type < Node
|
---|
65 | # @b_const : bool
|
---|
66 | # @b_volatile : bool
|
---|
67 |
|
---|
68 | def initialize
|
---|
69 | super
|
---|
70 | end
|
---|
71 |
|
---|
72 | def set_qualifier( qualifier )
|
---|
73 | case qualifier
|
---|
74 | when :CONST
|
---|
75 | # if @b_const then
|
---|
76 | # cdl_error( "T1001 const duplicate" )
|
---|
77 | # end
|
---|
78 | @b_const = true
|
---|
79 | when :VOLATILE
|
---|
80 | # if @b_volatile then
|
---|
81 | # cdl_error( "T1002 volatile duplicate" )
|
---|
82 | # end
|
---|
83 | @b_volatile = true
|
---|
84 | else
|
---|
85 | raise "Unknown qualifier #{qualifier}"
|
---|
86 | end
|
---|
87 | end
|
---|
88 |
|
---|
89 | def is_const?
|
---|
90 | if @b_const then
|
---|
91 | return true
|
---|
92 | else
|
---|
93 | return false
|
---|
94 | end
|
---|
95 | end
|
---|
96 |
|
---|
97 | def is_volatile?
|
---|
98 | if @b_volatile then
|
---|
99 | return true
|
---|
100 | else
|
---|
101 | return false
|
---|
102 | end
|
---|
103 | end
|
---|
104 |
|
---|
105 | def is_void?
|
---|
106 | if self.kind_of? DefinedType then
|
---|
107 | return @type.is_void?
|
---|
108 | elsif self.kind_of? VoidType then
|
---|
109 | return true
|
---|
110 | else
|
---|
111 | return false
|
---|
112 | end
|
---|
113 | end
|
---|
114 |
|
---|
115 | #=== size_is, count_is, string を設定
|
---|
116 | # 派生クラスでオーバーライドする(デフォルトではエラー)
|
---|
117 | def set_scs( size, count, string, max = nil, b_nullable = false )
|
---|
118 | str = ""
|
---|
119 | delim = ""
|
---|
120 | if size then
|
---|
121 | str = "size_is"
|
---|
122 | delim = ", "
|
---|
123 | end
|
---|
124 | if count then
|
---|
125 | str = "#{str}#{delim}count_is"
|
---|
126 | delim = ", "
|
---|
127 | end
|
---|
128 | if string then
|
---|
129 | str = "#{str}#{delim}string"
|
---|
130 | delim = ", "
|
---|
131 | end
|
---|
132 | if b_nullable then
|
---|
133 | str = "#{str}#{delim}nullable"
|
---|
134 | delim = ", "
|
---|
135 | end
|
---|
136 | cdl_error( "T1003 $1: unsuitable specifier for $2" , str, self.class )
|
---|
137 | end
|
---|
138 |
|
---|
139 | def clear_max
|
---|
140 | raise "clear_max called: #{self.class}"
|
---|
141 | end
|
---|
142 |
|
---|
143 | def get_type_str
|
---|
144 | str = ""
|
---|
145 | if @b_const then
|
---|
146 | str = "#{str}const "
|
---|
147 | end
|
---|
148 | if @b_volatile then
|
---|
149 | str = "#{str}volatile "
|
---|
150 | end
|
---|
151 | return str
|
---|
152 | end
|
---|
153 |
|
---|
154 | #=== 型をチェック
|
---|
155 | # 正当な型定義かどうか、チェックする
|
---|
156 | def check
|
---|
157 | # 型に誤りがあれば、エラー文字列を返す
|
---|
158 | end
|
---|
159 |
|
---|
160 | #=== struct の tag をチェック
|
---|
161 | # 正当な型定義かどうか、チェックする
|
---|
162 | #kind:: Decl の @kind を参照
|
---|
163 | def check_struct_tag kind
|
---|
164 | # tag が存在しなければエラーを出力する
|
---|
165 | # 配列型では、要素の型を再帰的にチェック
|
---|
166 | # ポインタ型では、指す先の tag チェックはしない
|
---|
167 | # 関数型ではパラメータリストのすべてについて行う
|
---|
168 | end
|
---|
169 |
|
---|
170 | #=== 初期化可能かチェック
|
---|
171 | # attribute など初期化可能かチェックする(型に対し正当な初期化子が与えられているか)
|
---|
172 | #ident:: string 被代入変数命
|
---|
173 | #initialize:: Expression, Array of initializer or C_EXP
|
---|
174 | # 代入値、C_EXP が与えられるのは IntType の場合のみ
|
---|
175 | #kind:: symbol (:ATTRIBUTE, :VAR, :CONSTNAT )
|
---|
176 | #attribute:: NameList kind == :VAR のとき参照できる attribute
|
---|
177 | #
|
---|
178 | # locale を第一引数として取るのは、以下の理由による。
|
---|
179 | # このメソッドは、変数への代入が行われる「行」に対して呼び出されるが、
|
---|
180 | # Type クラスのインスタンスは、変数が定義された「行」を記憶している。
|
---|
181 | #
|
---|
182 | # STAGE: S
|
---|
183 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
184 | #
|
---|
185 | end
|
---|
186 |
|
---|
187 | #=== const_val を指定の型にキャストする
|
---|
188 | # 派生クラスでオーバーライドしていないとエラー
|
---|
189 | def cast( const_val )
|
---|
190 | cdl_error( "T1004 cannot cast to $1" , self.class )
|
---|
191 | end
|
---|
192 |
|
---|
193 | #=== 型が一致するかのチェック
|
---|
194 | # 型名の字面でチェック.
|
---|
195 | # typedef された型も字面で一致を見るため、元の型が同じでも型名が異なれば不一致となる
|
---|
196 | def equal? type2
|
---|
197 | return ( get_type_str == type2.get_type_str ) && ( get_type_str_post == type2.get_type_str_post )
|
---|
198 | end
|
---|
199 |
|
---|
200 | #=== bit size を得る
|
---|
201 | # IntType, FloatType 以外は0
|
---|
202 | def get_bit_size
|
---|
203 | return 0
|
---|
204 | end
|
---|
205 |
|
---|
206 | #=== 元の型を得る
|
---|
207 | # typedef された型の場合、その元の型を返す.
|
---|
208 | # それ以外は、自分自身を返す.
|
---|
209 | # (DefinedType では本メソッドがオーバーライドされる)
|
---|
210 | def get_original_type
|
---|
211 | return self
|
---|
212 | end
|
---|
213 |
|
---|
214 | #=== 内部にポインタ型を持つ
|
---|
215 | # ポインタ型、またはポインタ型メンバを持つ構造体、または要素がポインタ型を持つ配列
|
---|
216 | def has_pointer?
|
---|
217 | false
|
---|
218 | end
|
---|
219 |
|
---|
220 | #=== size_is, count_is, string 指定されたポインタを持つか
|
---|
221 | # size_is, count_is, string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれをを要素に持つ配列
|
---|
222 | def has_sized_pointer?
|
---|
223 | false
|
---|
224 | end
|
---|
225 |
|
---|
226 | #=== 長さ指定のない string を持つ
|
---|
227 | # なさ指定のない string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれを要素に持つ配列
|
---|
228 | def has_unsized_string?
|
---|
229 | false
|
---|
230 | end
|
---|
231 |
|
---|
232 | def show_tree indent
|
---|
233 | indent.times { print " " }
|
---|
234 | puts "const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
|
---|
235 | indent.times { print " " }
|
---|
236 | puts "has_pointer=#{has_pointer?} has_sized_pointer=#{has_sized_pointer?} has_unsized_string=#{has_unsized_string?}"
|
---|
237 | end
|
---|
238 | end
|
---|
239 |
|
---|
240 | class DefinedType < Type
|
---|
241 | # @type_name::string
|
---|
242 | # @typedef::Typedef
|
---|
243 | # @type:: kind_of Type
|
---|
244 |
|
---|
245 | include HasType
|
---|
246 |
|
---|
247 | def initialize( type_name )
|
---|
248 | super()
|
---|
249 | @type_name = type_name
|
---|
250 |
|
---|
251 | # mikan type_name が path になっていないため暫定
|
---|
252 | @typedef = Namespace.find( [ type_name ] ) #1
|
---|
253 |
|
---|
254 | # if @type.class != Typedef then
|
---|
255 | # raise NotTypedef
|
---|
256 | # end
|
---|
257 | if @typedef == nil then
|
---|
258 | cdl_error( "T1005 \'$1\' not defined" , type_name )
|
---|
259 | elsif @typedef.class != Typedef then
|
---|
260 | cdl_error( "T1006 \'$1\' not type name. expecting type name here" , type_name )
|
---|
261 | end
|
---|
262 | @type = @typedef.get_declarator.get_type
|
---|
263 | initHasType
|
---|
264 | end
|
---|
265 |
|
---|
266 | def get_type
|
---|
267 | clone_type
|
---|
268 | return @type
|
---|
269 | end
|
---|
270 |
|
---|
271 | def get_type_str
|
---|
272 | "#{super}#{@type_name}"
|
---|
273 | end
|
---|
274 |
|
---|
275 | def get_type_str_post
|
---|
276 | ""
|
---|
277 | end
|
---|
278 |
|
---|
279 | def get_size
|
---|
280 | return @type.get_size
|
---|
281 | end
|
---|
282 |
|
---|
283 | def is_nullable?
|
---|
284 | return @type.is_nullable?
|
---|
285 | end
|
---|
286 |
|
---|
287 | #=== qualifier(const, volatile) の設定
|
---|
288 | def set_qualifier( qualifier )
|
---|
289 | clone_type
|
---|
290 | @type.set_qualifier( qualifier )
|
---|
291 | super
|
---|
292 | end
|
---|
293 |
|
---|
294 | def set_scs( size, count, string, max = nil, b_nullable = false )
|
---|
295 | clone_type
|
---|
296 | @type.set_scs( size, count, string, max, b_nullable )
|
---|
297 | end
|
---|
298 |
|
---|
299 | def clear_max
|
---|
300 | @type.clear_max
|
---|
301 | end
|
---|
302 |
|
---|
303 | def get_original_type
|
---|
304 | clone_type
|
---|
305 | return @type.get_original_type
|
---|
306 | end
|
---|
307 |
|
---|
308 | def check # 意味的誤りがあれば、文字列を返す
|
---|
309 | nil # typedef の段階で意味チェックされている
|
---|
310 | end
|
---|
311 |
|
---|
312 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
313 | get_type.check_init( locale, ident, initializer, kind, attribute )
|
---|
314 | end
|
---|
315 |
|
---|
316 | #=== 内部にポインタ型を持つ
|
---|
317 | # ポインタ型、またはポインタ型メンバを持つ構造体、または要素がポインタ型を持つ配列
|
---|
318 | def has_pointer?
|
---|
319 | @type.has_pointer?
|
---|
320 | end
|
---|
321 |
|
---|
322 | #=== size_is, count_is, string 指定されたポインタを持つか
|
---|
323 | # size_is, count_is, string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれをを要素に持つ配列
|
---|
324 | def has_sized_pointer?
|
---|
325 | @type.has_sized_pointer?
|
---|
326 | end
|
---|
327 |
|
---|
328 | #=== 長さ指定のない string を持つ
|
---|
329 | # なさ指定のない string 指定されたポインタ型、またはそれをメンバに持つ構造体、またはそれを要素に持つ配列
|
---|
330 | def has_unsized_string?
|
---|
331 | @type.has_unsized_string?
|
---|
332 | end
|
---|
333 |
|
---|
334 | def show_tree( indent )
|
---|
335 | indent.times { print " " }
|
---|
336 | if @typedef == nil then
|
---|
337 | puts "DefinedType: #{@type_name} is missing, const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
|
---|
338 | else
|
---|
339 | puts "DefinedType: #{@type_name}, const=#{@b_const} volatile=#{@b_volatile}"
|
---|
340 | end
|
---|
341 | super( indent + 1 )
|
---|
342 | @typedef.show_tree( indent + 1 )
|
---|
343 | @type.show_tree( indent + 1 )
|
---|
344 | end
|
---|
345 | end
|
---|
346 |
|
---|
347 | class VoidType < Type
|
---|
348 |
|
---|
349 | def check # 意味的誤りがあれば、文字列を返す
|
---|
350 | nil
|
---|
351 | end
|
---|
352 |
|
---|
353 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
354 | cdl_error2( locale, "T1007 $1: void type variable cannot have initializer" , ident )
|
---|
355 | end
|
---|
356 |
|
---|
357 | def get_type_str
|
---|
358 | "#{super}void"
|
---|
359 | end
|
---|
360 |
|
---|
361 | def get_type_str_post
|
---|
362 | ""
|
---|
363 | end
|
---|
364 |
|
---|
365 | def show_tree( indent )
|
---|
366 | indent.times { print " " }
|
---|
367 | puts "VoidType #{locale_str}"
|
---|
368 | super( indent + 1 )
|
---|
369 | end
|
---|
370 | end
|
---|
371 |
|
---|
372 | class BoolType < Type
|
---|
373 |
|
---|
374 | def check # 意味的誤りがあれば、文字列を返す
|
---|
375 | nil
|
---|
376 | end
|
---|
377 |
|
---|
378 | def get_type_str
|
---|
379 | "#{super}bool_t"
|
---|
380 | end
|
---|
381 |
|
---|
382 | def get_type_str_post
|
---|
383 | ""
|
---|
384 | end
|
---|
385 |
|
---|
386 | def show_tree( indent )
|
---|
387 | indent.times { print " " }
|
---|
388 | puts "BoolType #{locale_str}"
|
---|
389 | super( indent + 1 )
|
---|
390 | end
|
---|
391 | end
|
---|
392 |
|
---|
393 | class IntType < Type
|
---|
394 | # @bit_size:: -11: char, -1: char_t, -2: short, -3: int, -4: long, -5: long long
|
---|
395 | # 8, 16, 32, 64, 128
|
---|
396 | # @sign:: :SIGNED, :UNSIGNED, nil
|
---|
397 |
|
---|
398 | def initialize( bit_size )
|
---|
399 | super()
|
---|
400 | @bit_size = bit_size
|
---|
401 | @sign = nil
|
---|
402 | end
|
---|
403 |
|
---|
404 | def set_sign( sign, b_uint = false )
|
---|
405 | if @sign then
|
---|
406 | if @sign != sign then
|
---|
407 | cdl_error( "T1008 ambigous signed or unsigned" )
|
---|
408 | end
|
---|
409 | elsif b_uint == false && @bit_size > 0 then
|
---|
410 | if sign == :SIGNED then
|
---|
411 | cdl_warning( "W2001 signed int$1_t: obsolete. use int$2_t" , @bit_size, @bit_size )
|
---|
412 | else
|
---|
413 | cdl_warning( "W2002 unsinged int$1_t: obsolete. use uint$2_t" , @bit_size, @bit_size )
|
---|
414 | end
|
---|
415 | end
|
---|
416 |
|
---|
417 | @sign = sign
|
---|
418 |
|
---|
419 | if @sign != :SIGNED && @sign != :UNSIGNED then
|
---|
420 | raise "set_sign: unknown sign: #{@sign}"
|
---|
421 | end
|
---|
422 | end
|
---|
423 |
|
---|
424 | def check # 意味的誤りがあれば、文字列を返す
|
---|
425 | nil
|
---|
426 | end
|
---|
427 |
|
---|
428 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
429 | val = initializer # C_EXP, Array
|
---|
430 | if val.instance_of?( Expression ) then
|
---|
431 | val = val.eval_const2( nil, attribute )
|
---|
432 | # 評価の結果 C_EXP や Array となる可能性がある
|
---|
433 | end
|
---|
434 |
|
---|
435 | if val.instance_of? Token then # StringVal 導入により、もはや Token は来ないはず
|
---|
436 | # val が Token の場合 == の右辺が String だとエラーを起こす (#198)
|
---|
437 | cdl_error2( locale, "T1009 $1: $2: not integer" , ident, val )
|
---|
438 | return
|
---|
439 | elsif val.is_a? C_EXP then
|
---|
440 | # #192 var が attribute を参照し、attribute の右辺が C_EXP の場合
|
---|
441 | # const の右辺が C_EXP の場合も
|
---|
442 | return
|
---|
443 | elsif val.kind_of? FloatVal then
|
---|
444 | cdl_error2( locale, "T1011 $1: need cast to assign float to integer" , ident )
|
---|
445 | return
|
---|
446 | elsif val.instance_of? Array then
|
---|
447 | cdl_error2( locale, "T1017 $1: unsuitable initializer for scalar type" , ident )
|
---|
448 | return
|
---|
449 | elsif val == nil then
|
---|
450 | cdl_error2( locale, "T1010 $1: initializer is not constant" , ident )
|
---|
451 | return
|
---|
452 | end
|
---|
453 |
|
---|
454 | if ! val.kind_of? IntegerVal then
|
---|
455 | cdl_error2( locale, "T1012 $1: $2: not integer" , ident, val )
|
---|
456 | return
|
---|
457 | end
|
---|
458 |
|
---|
459 | val = val.to_i
|
---|
460 | max = get_max
|
---|
461 | min = get_min
|
---|
462 | dbgPrint "sign=#{@sign} ident=#{ident} val=#{val} max=#{max} min=#{min}\n"
|
---|
463 |
|
---|
464 | if max != nil then
|
---|
465 | if val > max then
|
---|
466 | if @sign == :SIGNED || @sign == nil then
|
---|
467 | cdl_error2( locale, "T1013 $1: too large (max=$2)" , ident, max )
|
---|
468 | else
|
---|
469 | cdl_error2( locale, "T1016 $1: too large (max=$2)" , ident, max )
|
---|
470 | end
|
---|
471 | end
|
---|
472 | end
|
---|
473 |
|
---|
474 | if min != nil then
|
---|
475 | if val < min
|
---|
476 | if @sign == :SIGNED || @sign == nil then
|
---|
477 | cdl_error2( locale, "T1014 $1: too large negative value (min=$2)" , ident, min )
|
---|
478 | else
|
---|
479 | cdl_error2( locale, "T1015 $1: negative value for unsigned" , ident )
|
---|
480 | end
|
---|
481 | end
|
---|
482 | end
|
---|
483 | end
|
---|
484 |
|
---|
485 | #=== IntType# 最大値、最小値をチェックしてクリップする
|
---|
486 | # キャスト演算を行う
|
---|
487 | #in_val:: IntegerVal, FloatVal: この型にキャストする値
|
---|
488 | #from_type:: Symbol: :IntType, :FloatType IntType の場合はビット数でクリップ、FloatType の場合は最大値でクリップ
|
---|
489 | def check_and_clip( in_val, from_type = :IntType )
|
---|
490 | bit_size = get_bit_size
|
---|
491 | if bit_size == -1 then
|
---|
492 | bit_size = 8
|
---|
493 | end
|
---|
494 | val = in_val.to_i
|
---|
495 | if get_max && val > get_max then
|
---|
496 | if from_type == :IntType then
|
---|
497 | rval = ((1 << bit_size)-1) & val # bit 数でクリップ
|
---|
498 | else
|
---|
499 | rval = get_max # 最大値でクリップ (FloatType)
|
---|
500 | end
|
---|
501 | cdl_warning( "W2003 $1: too large to cast to $2, clipped($3)" , in_val, get_type_str, rval )
|
---|
502 | elsif get_min && val < get_min then
|
---|
503 | if from_type == :IntType then
|
---|
504 | rval = ((1 << bit_size)-1) & val
|
---|
505 | else
|
---|
506 | rval = get_min
|
---|
507 | end
|
---|
508 | if @sign == :SIGNED || @sign == nil then
|
---|
509 | cdl_warning( "W2004 $1: too small to cast to $2, clipped($3)" , in_val, get_type_str, rval )
|
---|
510 | else # @sign == :UNSIGNED || @sign == nil (char の場合)
|
---|
511 | cdl_warning( "W2005 $1: negative value for unsigned: convert to $2" , in_val, rval )
|
---|
512 | end
|
---|
513 | else
|
---|
514 | rval = val
|
---|
515 | end
|
---|
516 | return rval
|
---|
517 | end
|
---|
518 |
|
---|
519 | def get_min
|
---|
520 | if @sign == :SIGNED || @sign == nil then
|
---|
521 | if @bit_size == -1 then
|
---|
522 | bit_sz = 8 # char_t は、有符号に扱う
|
---|
523 | else
|
---|
524 | bit_sz = @bit_size
|
---|
525 | end
|
---|
526 | case bit_sz
|
---|
527 | when 8, 16, 32, 64, 128
|
---|
528 | return - ( 1 << ( bit_sz - 1 ))
|
---|
529 | else # -1, -2, -3, -4, -5, -11
|
---|
530 | return nil
|
---|
531 | end
|
---|
532 | else # @sign == :UNSIGNED
|
---|
533 | return 0
|
---|
534 | end
|
---|
535 | end
|
---|
536 |
|
---|
537 | def get_max
|
---|
538 | if @bit_size == -1 then
|
---|
539 | if @sign == nil then
|
---|
540 | return 255 # char_t は、無符号に扱う
|
---|
541 | else
|
---|
542 | bit_sz = 8
|
---|
543 | end
|
---|
544 | else
|
---|
545 | bit_sz = @bit_size
|
---|
546 | end
|
---|
547 | if @sign == :SIGNED || @sign == nil then
|
---|
548 | case bit_sz
|
---|
549 | when 8, 16, 32, 64, 128
|
---|
550 | return ( 1 << ( bit_sz - 1 )) -1
|
---|
551 | else # -1, -2, -3, -4, -5, -11
|
---|
552 | return nil
|
---|
553 | end
|
---|
554 | else # @sign == :UNSIGNED
|
---|
555 | case bit_sz
|
---|
556 | when 8, 16, 32, 64, 128
|
---|
557 | return ( 1 << bit_sz ) - 1
|
---|
558 | else # -2, -3, -4, -5, -11
|
---|
559 | return nil
|
---|
560 | end
|
---|
561 | end
|
---|
562 | end
|
---|
563 |
|
---|
564 | #=== IntType# C 言語における型名(修飾子付き)
|
---|
565 | def get_type_str
|
---|
566 | str = super
|
---|
567 |
|
---|
568 | # NEW_MODE
|
---|
569 | case @sign
|
---|
570 | when :SIGNED
|
---|
571 | sign = ""
|
---|
572 | signL = "signed "
|
---|
573 | when :UNSIGNED
|
---|
574 | sign = "u"
|
---|
575 | signL = "unsigned "
|
---|
576 | else
|
---|
577 | sign = ""
|
---|
578 | signL = ""
|
---|
579 | end
|
---|
580 |
|
---|
581 | # p "get_type_str: sign:#{@sign} signL=#{signL}"
|
---|
582 |
|
---|
583 | case @bit_size
|
---|
584 | when -1 # char_t 型
|
---|
585 | if @sign == :SIGNED then
|
---|
586 | sign = "s"
|
---|
587 | end
|
---|
588 | str = "#{str}#{sign}char_t"
|
---|
589 | when -11 # char 型(obsolete)
|
---|
590 | str = "#{str}#{signL}char"
|
---|
591 | when -2 # short 型
|
---|
592 | str = "#{str}#{signL}short"
|
---|
593 | when -3 # int 型
|
---|
594 | str = "#{str}#{signL}int"
|
---|
595 | when -4 # long 型
|
---|
596 | str = "#{str}#{signL}long"
|
---|
597 | when -5 # long long 型
|
---|
598 | str = "#{str}#{signL}long long"
|
---|
599 | when 8, 16, 32, 64, 128 # int16, int32, int64, int128 型
|
---|
600 | str = "#{str}#{sign}int#{@bit_size}_t"
|
---|
601 | end
|
---|
602 |
|
---|
603 | return str
|
---|
604 | end
|
---|
605 |
|
---|
606 | #=== IntType# C 言語における型名(後置文字列)
|
---|
607 | def get_type_str_post
|
---|
608 | ""
|
---|
609 | end
|
---|
610 |
|
---|
611 | #=== IntType#bit_size を得る
|
---|
612 | # 返される値は @bit_size の仕様を参照
|
---|
613 | def get_bit_size
|
---|
614 | return @bit_size
|
---|
615 | end
|
---|
616 |
|
---|
617 | #=== IntType# sign を得る
|
---|
618 | # @sign の説明を参照
|
---|
619 | def get_sign
|
---|
620 | @sign
|
---|
621 | end
|
---|
622 |
|
---|
623 | def show_tree( indent )
|
---|
624 | indent.times { print " " }
|
---|
625 | puts "IntType bit_size=#{@bit_size} sign=#{@sign} const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
|
---|
626 | super( indent + 1 )
|
---|
627 | end
|
---|
628 | end
|
---|
629 |
|
---|
630 | class FloatType < Type
|
---|
631 | # @bit_size:: 32, 64, (80), -32, -64, -128
|
---|
632 |
|
---|
633 | def initialize( bit_size )
|
---|
634 | super()
|
---|
635 | @bit_size = bit_size
|
---|
636 | end
|
---|
637 |
|
---|
638 | def check # 意味的誤りがあれば、文字列を返す
|
---|
639 | nil
|
---|
640 | end
|
---|
641 |
|
---|
642 | # mikan Float 型の C_EXP 対応 (generate.rb にも変更必要)
|
---|
643 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
644 | # 型に対する初期値に誤りがあれば、エラー文字列を返す
|
---|
645 | val = initializer
|
---|
646 | if val.instance_of?( Expression ) then
|
---|
647 | val = val.eval_const2( nil, attribute )
|
---|
648 | # 評価の結果 C_EXP や Array となる可能性がある
|
---|
649 | end
|
---|
650 |
|
---|
651 | if val.instance_of? Token then
|
---|
652 | # val が Token の場合 == の右辺が String だとエラーを起こす
|
---|
653 | cdl_error2( locale, "T1018 $1: $2: not number" , ident, val )
|
---|
654 | return
|
---|
655 | elsif val.instance_of? Array then
|
---|
656 | cdl_error2( locale, "T1020 $1: unsuitable initializer for scalar type" , ident )
|
---|
657 | return
|
---|
658 | elsif val.instance_of? C_EXP then
|
---|
659 | return
|
---|
660 | elsif val == nil then
|
---|
661 | cdl_error2( locale, "T1019 $1: initializer is not constant" , ident )
|
---|
662 | return
|
---|
663 | elsif ! val.kind_of?( IntegerVal ) && ! val.kind_of?( FloatVal ) then
|
---|
664 | cdl_error2( locale, "T1037 $1: not number" , ident )
|
---|
665 | return
|
---|
666 | end
|
---|
667 | # else
|
---|
668 | # cdl_error2( locale, "T1020 $1: unsuitable initializer for scalar type" , ident )
|
---|
669 | # return
|
---|
670 | # end
|
---|
671 | return
|
---|
672 | end
|
---|
673 |
|
---|
674 | def get_type_str
|
---|
675 | str = super
|
---|
676 |
|
---|
677 | case @bit_size
|
---|
678 | when 32
|
---|
679 | str = "#{str}float32_t"
|
---|
680 | when 64
|
---|
681 | str = "#{str}double64_t"
|
---|
682 | when -32
|
---|
683 | str = "#{str}float"
|
---|
684 | when -64
|
---|
685 | str = "#{str}double"
|
---|
686 | when -128
|
---|
687 | str = "#{str}long double"
|
---|
688 | end
|
---|
689 | return str
|
---|
690 | end
|
---|
691 |
|
---|
692 | def get_type_str_post
|
---|
693 | ""
|
---|
694 | end
|
---|
695 |
|
---|
696 | def get_bit_size
|
---|
697 | @bit_size
|
---|
698 | end
|
---|
699 |
|
---|
700 | def show_tree( indent )
|
---|
701 | indent.times { print " " }
|
---|
702 | puts "FloatType bit_size=#{@bit_size} qualifier=#{@qualifier} #{locale_str}"
|
---|
703 | super( indent + 1 )
|
---|
704 | end
|
---|
705 | end
|
---|
706 |
|
---|
707 | class EnumType < Type # mikan
|
---|
708 | # @bit_size:: -1: enum
|
---|
709 | # 8, 16, 32, 64, 128
|
---|
710 | # @element:: []
|
---|
711 | # @element_val:: []
|
---|
712 |
|
---|
713 | def initialize( bit_size )
|
---|
714 | super()
|
---|
715 | @bit_size = bit_size
|
---|
716 | end
|
---|
717 |
|
---|
718 | def check
|
---|
719 | # mikan enum check
|
---|
720 | end
|
---|
721 |
|
---|
722 | def show_tree( indent )
|
---|
723 | indent.times { print " " }
|
---|
724 | puts "EnumType bit_size=#{@bit_size} qualifier=#{@qualifier} #{locale_str}"
|
---|
725 | super( indent + 1 )
|
---|
726 | # mikan element
|
---|
727 | end
|
---|
728 | end
|
---|
729 |
|
---|
730 | class StructType < Type
|
---|
731 | # @tag::
|
---|
732 | # @b_define:: true if define, false if refer
|
---|
733 | # @members_decl:: NamedList
|
---|
734 | # @definition:: StructType
|
---|
735 | # @b_has_pointer_member:: bool : メンバにポインタ型がある
|
---|
736 | # @b_has_sized_pointer_member:: bool : メンバにポインタ型がある
|
---|
737 | # @b_has_unsized_string_member:: bool : メンバにポインタ型がある
|
---|
738 | # @b_hasTag:: bool : タグがある
|
---|
739 | # @member_types_symbol:: Symbol : tag が無い時のみ設定 (それ以外では nil)
|
---|
740 |
|
---|
741 | @@structtype_current_stack = []
|
---|
742 | @@structtype_current_sp = -1
|
---|
743 |
|
---|
744 | # tag なし struct
|
---|
745 | @@no_struct_tag_num = 0
|
---|
746 | @@no_tag_struct_list = {}
|
---|
747 |
|
---|
748 | def initialize( tag = nil )
|
---|
749 | super()
|
---|
750 | @tag = tag
|
---|
751 | if tag then
|
---|
752 | @b_hasTag = true
|
---|
753 | else
|
---|
754 | @b_hasTag = false
|
---|
755 | end
|
---|
756 | @@structtype_current_sp += 1
|
---|
757 | @@structtype_current_stack[@@structtype_current_sp] = self
|
---|
758 | @b_has_pointer_member = false
|
---|
759 | @b_has_sized_pointer_member = false
|
---|
760 | @b_has_unsized_string_member = false
|
---|
761 | @member_types_symbol = nil
|
---|
762 | end
|
---|
763 |
|
---|
764 | def self.set_define( b_define )
|
---|
765 | @@structtype_current_stack[@@structtype_current_sp].set_define( b_define )
|
---|
766 | end
|
---|
767 |
|
---|
768 | def set_define( b_define )
|
---|
769 | @b_define = b_define
|
---|
770 | if @b_define then
|
---|
771 | @members_decl = NamedList.new( nil, "in struct #{@tag}" )
|
---|
772 | # if @tag then 登録タイミングを終わりに変更 V1.0.2.19
|
---|
773 | # Namespace.new_structtype( self )
|
---|
774 | # end
|
---|
775 | else
|
---|
776 | @definition = Namespace.find_tag( @tag )
|
---|
777 | # check_struct_tag に移す V1.0.2.19
|
---|
778 | # if @definition == nil then
|
---|
779 | # cdl_error( "T1021 \'$1\': struct not defined" , @tag )
|
---|
780 | # end
|
---|
781 | end
|
---|
782 | end
|
---|
783 |
|
---|
784 | def self.new_member( member_decl )
|
---|
785 | @@structtype_current_stack[@@structtype_current_sp].new_member( member_decl )
|
---|
786 | end
|
---|
787 |
|
---|
788 | def new_member( member_decl )
|
---|
789 | member_decl.set_owner self # Decl (StructType)
|
---|
790 | @members_decl.add_item( member_decl )
|
---|
791 | if member_decl.get_type.has_pointer?
|
---|
792 | @b_has_pointer_member = true
|
---|
793 | end
|
---|
794 | if member_decl.get_type.has_sized_pointer?
|
---|
795 | @b_has_sized_pointer_member = true
|
---|
796 | end
|
---|
797 | if member_decl.get_type.has_unsized_string?
|
---|
798 | @b_has_unsized_string_member = true
|
---|
799 | end
|
---|
800 | end
|
---|
801 |
|
---|
802 | def check # 意味的誤りがあれば、文字列を返す
|
---|
803 | nil
|
---|
804 | end
|
---|
805 |
|
---|
806 | #=== 構造体のタグをチェック
|
---|
807 | # declarator の時点でチェックする
|
---|
808 | #kind:: Decl の @kind を参照
|
---|
809 | def check_struct_tag kind
|
---|
810 | if @tag == nil
|
---|
811 | return
|
---|
812 | end
|
---|
813 |
|
---|
814 | st = Namespace.find_tag( @tag )
|
---|
815 | if st == nil then
|
---|
816 | cdl_error( "T1022 struct $1: not defined" , @tag )
|
---|
817 | end
|
---|
818 | end
|
---|
819 |
|
---|
820 | # mikan Float 型の C_EXP 対応 (generate.rb にも変更必要)
|
---|
821 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
822 |
|
---|
823 | st = Namespace.find_tag( @tag )
|
---|
824 | if st == nil then
|
---|
825 | cdl_error2( locale, "T1023 struct $1: not defined" , @tag )
|
---|
826 | return
|
---|
827 | end
|
---|
828 |
|
---|
829 | # 初期化子が式の場合、型(タグ)が一致するかチェック
|
---|
830 | if initializer.instance_of?( Expression ) then
|
---|
831 | t = initializer.get_type( attribute )
|
---|
832 | # print "Check init #{t.class} #{t.get_name}\n"
|
---|
833 | if ! t.kind_of?( StructType ) then
|
---|
834 | if t then
|
---|
835 | str = t.get_type_str
|
---|
836 | else
|
---|
837 | str = "unknown"
|
---|
838 | end
|
---|
839 | cdl_error2( locale, "T1038 $1: initializer type mismatch. '$2' & '$3'" , ident, get_type_str, str )
|
---|
840 | elsif @tag != t.get_name then
|
---|
841 | cdl_error2( locale, "T1039 $1: struct tag mismatch $2 and $3" , ident, @tag, t.get_name )
|
---|
842 | end
|
---|
843 | initializer = initializer.eval_const( attribute )
|
---|
844 | end
|
---|
845 |
|
---|
846 | if initializer.instance_of?( Array ) then
|
---|
847 | i = 0
|
---|
848 | st.get_members_decl.get_items.each { |d|
|
---|
849 | if initializer[i] then
|
---|
850 | d.get_type.check_init( locale, "#{ident}.#{d.get_identifier}", initializer[i], kind )
|
---|
851 | end
|
---|
852 | i += 1
|
---|
853 | }
|
---|
854 | else
|
---|
855 | cdl_error2( locale, "T1024 $1: unsuitable initializer for struct" , ident )
|
---|
856 | end
|
---|
857 | end
|
---|
858 |
|
---|
859 | def self.end_of_parse()
|
---|
860 | @@structtype_current_stack[@@structtype_current_sp].end_of_parse
|
---|
861 | @@structtype_current_sp -= 1
|
---|
862 | end
|
---|
863 |
|
---|
864 | def end_of_parse()
|
---|
865 | if @members_decl == nil # @b_define = false またはメンバーのない構造体(エラー)
|
---|
866 | return
|
---|
867 | end
|
---|
868 | @members_decl.get_items.each{ |md|
|
---|
869 | size = md.get_size_is
|
---|
870 | if size then
|
---|
871 | val = size.eval_const( @members_decl )
|
---|
872 | if val == nil then
|
---|
873 | type = size.get_type( @members_decl )
|
---|
874 | if ! type.kind_of?( IntType ) then
|
---|
875 | cdl_error( "T1025 size_is argument is not integer type" )
|
---|
876 | end
|
---|
877 | end
|
---|
878 | end
|
---|
879 | count = md.get_count_is
|
---|
880 | if count then
|
---|
881 | val = count.eval_const( @members_decl )
|
---|
882 | if val == nil then
|
---|
883 | type = count.get_type( @members_decl )
|
---|
884 | if ! type.kind_of?( IntType ) then
|
---|
885 | cdl_error( "T1026 count_is argument is not integer type" )
|
---|
886 | end
|
---|
887 | end
|
---|
888 | end
|
---|
889 | string = md.get_string
|
---|
890 | if string == -1 then
|
---|
891 | # 長さ指定なし
|
---|
892 | elsif string then
|
---|
893 | val = string.eval_const( @members_decl )
|
---|
894 | if val == nil then
|
---|
895 | type = string.get_type( @members_decl )
|
---|
896 | if ! type.kind_of?( IntType ) then
|
---|
897 | cdl_error( "T1027 string argument is not integer type" )
|
---|
898 | end
|
---|
899 | end
|
---|
900 | end
|
---|
901 | }
|
---|
902 |
|
---|
903 | if @tag == nil then
|
---|
904 | @member_types_symbol = get_member_types_symbol
|
---|
905 | # print "member_types_symbol = #{get_member_types_symbol}\n"
|
---|
906 | if @@no_tag_struct_list[ @member_types_symbol ] then
|
---|
907 | @tag = @@no_tag_struct_list[ @member_types_symbol ]
|
---|
908 | else
|
---|
909 | @tag = :"TAG_#{@@no_struct_tag_num}_TECS_internal__"
|
---|
910 | @@no_struct_tag_num += 1
|
---|
911 | @@no_tag_struct_list[ @member_types_symbol ] = @tag
|
---|
912 | Namespace.new_structtype( self )
|
---|
913 | end
|
---|
914 | else
|
---|
915 | if @b_define then
|
---|
916 | Namespace.new_structtype( self )
|
---|
917 | end
|
---|
918 | end
|
---|
919 | end
|
---|
920 |
|
---|
921 | def get_name
|
---|
922 | @tag
|
---|
923 | end
|
---|
924 |
|
---|
925 | def get_type_str # mikan struct get_type_str
|
---|
926 | str = super
|
---|
927 |
|
---|
928 | if @b_hasTag then
|
---|
929 | # typedef struct tag StructType; の形式の場合
|
---|
930 | # struct の本体は、別に生成される
|
---|
931 | return "#{str}struct #{@tag}"
|
---|
932 |
|
---|
933 | else
|
---|
934 | # typedef struct { int a; } StructType; の形式の場合
|
---|
935 | str += "struct {"
|
---|
936 | @members_decl.get_items.each{ |i|
|
---|
937 | str += sprintf( "%s %s%s;", "#{i.get_type.get_type_str}", "#{i.get_name}", "#{i.get_type.get_type_str_post}" )
|
---|
938 | }
|
---|
939 | str += "} "
|
---|
940 |
|
---|
941 | return str
|
---|
942 |
|
---|
943 | end
|
---|
944 | end
|
---|
945 |
|
---|
946 | def get_type_str_post
|
---|
947 | ""
|
---|
948 | end
|
---|
949 |
|
---|
950 | def get_members_decl
|
---|
951 | return @members_decl if @members_decl
|
---|
952 |
|
---|
953 | st = Namespace.find_tag( @tag )
|
---|
954 | if st then
|
---|
955 | return st.get_members_decl
|
---|
956 | end
|
---|
957 |
|
---|
958 | return nil
|
---|
959 | end
|
---|
960 |
|
---|
961 | def has_pointer?
|
---|
962 | if @definition
|
---|
963 | return @definition.has_pointer?
|
---|
964 | else
|
---|
965 | return @b_has_pointer_member
|
---|
966 | end
|
---|
967 | end
|
---|
968 |
|
---|
969 | def has_sized_pointer?
|
---|
970 | if @definition
|
---|
971 | return @definition.has_sized_pointer?
|
---|
972 | else
|
---|
973 | return @b_has_sized_pointer_member
|
---|
974 | end
|
---|
975 | end
|
---|
976 |
|
---|
977 | def has_unsized_string?
|
---|
978 | if @definition
|
---|
979 | return @definition.has_unsized_string?
|
---|
980 | else
|
---|
981 | return @b_has_unsized_string_member
|
---|
982 | end
|
---|
983 | end
|
---|
984 |
|
---|
985 | #=== 同じ構造体かどうかチェックする
|
---|
986 | # tag のチェックは行わない
|
---|
987 | # すべてのメンバの名前と型が一致することを確認する
|
---|
988 | def same? another
|
---|
989 | md = another.get_members_decl
|
---|
990 | if @members_decl == nil || md == nil
|
---|
991 | return false
|
---|
992 | end
|
---|
993 |
|
---|
994 | md1 = @members_decl.get_items
|
---|
995 | md2 = md.get_items
|
---|
996 | if( md1.length != md2.length )
|
---|
997 | return false
|
---|
998 | end
|
---|
999 |
|
---|
1000 | i = 0
|
---|
1001 | while i < md1.length
|
---|
1002 | if md1[i].get_name != md2[i].get_name ||
|
---|
1003 | md1[i].get_type.get_type_str != md2[i].get_type.get_type_str ||
|
---|
1004 | md1[i].get_type.get_type_str_post != md2[i].get_type.get_type_str_post
|
---|
1005 | return false
|
---|
1006 | end
|
---|
1007 | i += 1
|
---|
1008 | end
|
---|
1009 |
|
---|
1010 | return true
|
---|
1011 | end
|
---|
1012 |
|
---|
1013 | def get_member_types_symbol
|
---|
1014 | mts = ''
|
---|
1015 | @members_decl.get_items.each { |member|
|
---|
1016 | mts += member.get_type.get_type_str + member.get_type.get_type_str_post + ';'
|
---|
1017 | }
|
---|
1018 | return mts.to_sym
|
---|
1019 | end
|
---|
1020 |
|
---|
1021 | def show_tree( indent )
|
---|
1022 | indent.times { print " " }
|
---|
1023 | puts "StructType tag: #{@tag} qualifier=#{@qualifier} has_pointer=#{@b_has_pointer_member} #{locale_str}"
|
---|
1024 | super( indent + 1 )
|
---|
1025 | if @b_define then
|
---|
1026 | @members_decl.show_tree( indent + 1 )
|
---|
1027 | end
|
---|
1028 | end
|
---|
1029 | end
|
---|
1030 |
|
---|
1031 | class FuncType < Type
|
---|
1032 | # @paramlist:: ParamList
|
---|
1033 | # @type:: return type : PtrType, ArrayType, FuncType, IntType, FloatType, ...
|
---|
1034 | # @b_oneway:: bool: true, false
|
---|
1035 | # @has_in:: bool : has [in] parameter
|
---|
1036 | # @has_inout:: bool : has [inout] parameter
|
---|
1037 | # @has_out:: bool : has [out] parameter
|
---|
1038 | # @has_send:: bool : has [send] parameter
|
---|
1039 | # @has_receive:: bool : has [receive] parameter
|
---|
1040 |
|
---|
1041 | def initialize( paramlist = nil )
|
---|
1042 | super()
|
---|
1043 |
|
---|
1044 | @has_in = false
|
---|
1045 | @has_inout = false
|
---|
1046 | @has_out = false
|
---|
1047 | @has_send = false
|
---|
1048 | @has_receive = false
|
---|
1049 |
|
---|
1050 | @paramlist = paramlist
|
---|
1051 | @b_oneway = false
|
---|
1052 | if paramlist then
|
---|
1053 | paramlist.check_param
|
---|
1054 | else
|
---|
1055 | @paramlist = ParamList.new( nil )
|
---|
1056 | end
|
---|
1057 | @paramlist.set_owner self # ParamList
|
---|
1058 | @paramlist.get_items.each{ |p|
|
---|
1059 | case p.get_direction
|
---|
1060 | when :IN
|
---|
1061 | @has_in = true
|
---|
1062 | when :INOUT
|
---|
1063 | @has_inout = true
|
---|
1064 | when :OUT
|
---|
1065 | @has_out = true
|
---|
1066 | when :SEND
|
---|
1067 | @has_send = true
|
---|
1068 | when :RECEIVE
|
---|
1069 | @has_receive = true
|
---|
1070 | else
|
---|
1071 | raise "unkown direction"
|
---|
1072 | end
|
---|
1073 | }
|
---|
1074 |
|
---|
1075 | end
|
---|
1076 |
|
---|
1077 | def check # 意味的誤りがあれば、文字列を返す
|
---|
1078 | if @type.class == ArrayType then # 配列を返す関数
|
---|
1079 | return "function returning array"
|
---|
1080 | elsif @type.class == FuncType then # 関数を返す関数
|
---|
1081 | return "function returning function"
|
---|
1082 | end
|
---|
1083 | return @type.check # 関数の return する型のチェック
|
---|
1084 |
|
---|
1085 | # パラメータの型のチェックは ParamList#check_param で行う
|
---|
1086 | end
|
---|
1087 |
|
---|
1088 | def check_struct_tag kind
|
---|
1089 | @type.check_struct_tag kind
|
---|
1090 | # ParamDecl でもチェックされるので、ここではチェックしない
|
---|
1091 | # @paramlist.check_struct_tag kind
|
---|
1092 | end
|
---|
1093 |
|
---|
1094 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
1095 | cdl_error2( locale, "T1028 $1: cannot initialize function pointer" , ident )
|
---|
1096 | return
|
---|
1097 | end
|
---|
1098 |
|
---|
1099 | def set_type( type )
|
---|
1100 | unless @type then
|
---|
1101 | @type = type
|
---|
1102 | else
|
---|
1103 | @type.set_type( type )
|
---|
1104 | end
|
---|
1105 | end
|
---|
1106 |
|
---|
1107 | #=== return type を返す
|
---|
1108 | #
|
---|
1109 | # return type を返す
|
---|
1110 | # get_return_type とすべきだった
|
---|
1111 | def get_type
|
---|
1112 | @type
|
---|
1113 | end
|
---|
1114 |
|
---|
1115 | def get_type_str
|
---|
1116 | return @type.get_type_str
|
---|
1117 | end
|
---|
1118 |
|
---|
1119 | def get_type_str_post
|
---|
1120 | # 型だけを返す (仮引数の名前を含めない)
|
---|
1121 | @paramlist.to_str( false )
|
---|
1122 | end
|
---|
1123 |
|
---|
1124 | def get_paramlist
|
---|
1125 | @paramlist
|
---|
1126 | end
|
---|
1127 |
|
---|
1128 | def set_oneway( b_oneway )
|
---|
1129 | @b_oneway = b_oneway
|
---|
1130 |
|
---|
1131 | if ( ( @type.get_type_str != "ER" && @type.get_type_str != "void" ) || @type.get_type_str_post != "" ) then
|
---|
1132 | cdl_error( "T1029 oneway function cannot return type \'$1$2\', \'void\' or \'ER\' is permitted" , @type.get_type_str, @type.get_type_str_post )
|
---|
1133 | end
|
---|
1134 |
|
---|
1135 | if @paramlist then
|
---|
1136 | @paramlist.get_items.each{ |p|
|
---|
1137 | if p.get_direction != :IN && p.get_direction != :SEND then
|
---|
1138 | cdl_error( "T1030 oneway function cannot have $1 parameter for \'$2\'" , p.get_direction, p.get_name )
|
---|
1139 | end
|
---|
1140 | }
|
---|
1141 | end
|
---|
1142 | end
|
---|
1143 |
|
---|
1144 | def is_oneway?
|
---|
1145 | @b_oneway
|
---|
1146 | end
|
---|
1147 |
|
---|
1148 | #=== Push Pop Allocator が必要か?
|
---|
1149 | # Transparent RPC の場合 oneway かつ in の配列(size_is, count_is, string のいずれかで修飾)がある
|
---|
1150 | def need_PPAllocator?( b_opaque = false )
|
---|
1151 | if @b_oneway || b_opaque then
|
---|
1152 | return @paramlist.need_PPAllocator?( b_opaque )
|
---|
1153 | else
|
---|
1154 | return false
|
---|
1155 | end
|
---|
1156 | end
|
---|
1157 |
|
---|
1158 | #=== パラメータが in, inout, out, send, receive を持つか
|
---|
1159 | def has_in?
|
---|
1160 | @has_in
|
---|
1161 | end
|
---|
1162 | def has_inout?
|
---|
1163 | @has_inout
|
---|
1164 | end
|
---|
1165 | def has_out?
|
---|
1166 | @has_out
|
---|
1167 | end
|
---|
1168 | def has_send?
|
---|
1169 | @has_send
|
---|
1170 | end
|
---|
1171 | def has_receive?
|
---|
1172 | @has_receive
|
---|
1173 | end
|
---|
1174 |
|
---|
1175 | #=== 入力方向のパラメータを持つか
|
---|
1176 | def has_inward?
|
---|
1177 | @has_in || @has_inout || @has_send
|
---|
1178 | end
|
---|
1179 | #=== 出力方向のパラメータを持つか
|
---|
1180 | def has_outward?
|
---|
1181 | @has_inout || @has_out || @has_receive
|
---|
1182 | end
|
---|
1183 |
|
---|
1184 | def show_tree( indent )
|
---|
1185 | indent.times { print " " }
|
---|
1186 | if @b_oneway then
|
---|
1187 | puts "FunctType: oneway=true #{locale_str}"
|
---|
1188 | else
|
---|
1189 | puts "FunctType: oneway=false #{locale_str}"
|
---|
1190 | end
|
---|
1191 | super( indent + 1 )
|
---|
1192 | if @paramlist then
|
---|
1193 | @paramlist.show_tree( indent + 1 )
|
---|
1194 | end
|
---|
1195 | (indent+1).times { print " " }
|
---|
1196 | puts "return type:"
|
---|
1197 | @type.show_tree( indent + 2 )
|
---|
1198 | end
|
---|
1199 | end
|
---|
1200 |
|
---|
1201 | class ArrayType < Type
|
---|
1202 | # @type:: element type : ArrayType, FuncType, IntType, FloatType, ...
|
---|
1203 | # @subscript:: Expression, nil if '[]'
|
---|
1204 |
|
---|
1205 | include HasType
|
---|
1206 |
|
---|
1207 | def initialize( subscript = nil )
|
---|
1208 | super()
|
---|
1209 | @subscript = subscript
|
---|
1210 | initHasType
|
---|
1211 | end
|
---|
1212 |
|
---|
1213 | def set_type( type )
|
---|
1214 | unless @type then
|
---|
1215 | @type = type
|
---|
1216 | else
|
---|
1217 | @type.set_type( type )
|
---|
1218 | end
|
---|
1219 | end
|
---|
1220 |
|
---|
1221 | #=== Array#qualifier(const, volatile) の設定
|
---|
1222 | def set_qualifier( qualifier )
|
---|
1223 | clone_type
|
---|
1224 | @type.set_qualifier( qualifier )
|
---|
1225 | super
|
---|
1226 | end
|
---|
1227 |
|
---|
1228 | # 配列要素が const なら const
|
---|
1229 | def is_const?
|
---|
1230 | @type.is_const?
|
---|
1231 | end
|
---|
1232 |
|
---|
1233 | # 配列要素が volatile なら volatile
|
---|
1234 | def is_volatile?
|
---|
1235 | @type.is_volatile?
|
---|
1236 | end
|
---|
1237 |
|
---|
1238 | def get_type
|
---|
1239 | @type
|
---|
1240 | end
|
---|
1241 |
|
---|
1242 | def get_subscript
|
---|
1243 | @subscript
|
---|
1244 | end
|
---|
1245 |
|
---|
1246 | def get_type_str
|
---|
1247 | return "#{@type.get_type_str}"
|
---|
1248 | end
|
---|
1249 |
|
---|
1250 | def get_type_str_post
|
---|
1251 | if @subscript
|
---|
1252 | "[#{@subscript.eval_const(nil)}]#{@type.get_type_str_post}"
|
---|
1253 | else
|
---|
1254 | "[]#{@type.get_type_str_post}"
|
---|
1255 | end
|
---|
1256 | # "[#{@subscript.to_s}]#{@type.get_type_str_post}"
|
---|
1257 | end
|
---|
1258 |
|
---|
1259 | def check # 意味的誤りがあれば、文字列を返す
|
---|
1260 | if @type.class == FuncType then # 関数の配列
|
---|
1261 | return "array of function"
|
---|
1262 | elsif @type.class == ArrayType then # 添数なし配列の配列
|
---|
1263 | unless @type.get_subscript then
|
---|
1264 | return "subscript not specified"
|
---|
1265 | end
|
---|
1266 | end
|
---|
1267 |
|
---|
1268 | return @type.check # 配列要素の型をチェック
|
---|
1269 | end
|
---|
1270 |
|
---|
1271 | def check_struct_tag kind
|
---|
1272 | @type.check_struct_tag kind
|
---|
1273 | end
|
---|
1274 |
|
---|
1275 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
1276 | if ( initializer.instance_of?( Array ) ) then
|
---|
1277 | # 要素数が指定されている場合、初期化要素数をチェック
|
---|
1278 | if @subscript then
|
---|
1279 | n_sub = @subscript.eval_const( nil )
|
---|
1280 | if n_sub then
|
---|
1281 | if initializer.length > n_sub then
|
---|
1282 | cdl_error2( locale, "T9999 $1: too many initializer, $2 for $3" , ident, initializer.length, n_sub )
|
---|
1283 | end
|
---|
1284 | end
|
---|
1285 | end
|
---|
1286 | index = 0
|
---|
1287 | initializer.each{ |i|
|
---|
1288 | @type.check_init( locale, "#{ident}[#{index}]", i, kind, attribute = nil )
|
---|
1289 | index += 1
|
---|
1290 | }
|
---|
1291 | else
|
---|
1292 | cdl_error2( locale, "T1031 $1: unsuitable initializer for array" , ident )
|
---|
1293 | end
|
---|
1294 | end
|
---|
1295 |
|
---|
1296 | def has_pointer?
|
---|
1297 | @type.has_pointer?
|
---|
1298 | end
|
---|
1299 |
|
---|
1300 | def has_sized_pointer?
|
---|
1301 | @type.has_sized_pointer?
|
---|
1302 | end
|
---|
1303 |
|
---|
1304 | def has_unsized_string?
|
---|
1305 | @type.has_unsized_string?
|
---|
1306 | end
|
---|
1307 |
|
---|
1308 | def show_tree( indent )
|
---|
1309 | indent.times { print " " }
|
---|
1310 | puts "ArrayType: #{locale_str}"
|
---|
1311 | super( indent + 1 )
|
---|
1312 | (indent+1).times { print " " }
|
---|
1313 | puts "type:"
|
---|
1314 | @type.show_tree( indent + 2 )
|
---|
1315 | (indent+1).times { print " " }
|
---|
1316 | puts "subscript:"
|
---|
1317 | if @subscript then
|
---|
1318 | @subscript.show_tree( indent + 2 )
|
---|
1319 | else
|
---|
1320 | (indent+2).times { print " " }
|
---|
1321 | puts "no subscript"
|
---|
1322 | end
|
---|
1323 | end
|
---|
1324 | end
|
---|
1325 |
|
---|
1326 | class PtrType < Type
|
---|
1327 | # @type:: refer to : PtrType, FuncType, ArrayType, IntType, FloatType, ...
|
---|
1328 | # @size:: Expr, or nil if not specified
|
---|
1329 | # @count:: Expr, or nil if not specified
|
---|
1330 | # @string:: Expr or -1(if size not specified) (string 引数), or nil if not specified
|
---|
1331 |
|
---|
1332 | include HasType
|
---|
1333 |
|
---|
1334 | def initialize( referto = nil )
|
---|
1335 | super()
|
---|
1336 | @type = referto
|
---|
1337 | @size = nil
|
---|
1338 | @count = nil
|
---|
1339 | @string = nil
|
---|
1340 | initHasType
|
---|
1341 | end
|
---|
1342 |
|
---|
1343 | def set_type( type )
|
---|
1344 | unless @type then
|
---|
1345 | @type = type
|
---|
1346 | else
|
---|
1347 | @type.set_type( type ) # 枝先の type を設定
|
---|
1348 | end
|
---|
1349 | end
|
---|
1350 |
|
---|
1351 | def get_type_str
|
---|
1352 | if @type.kind_of?( ArrayType ) || @type.kind_of?( FuncType ) then
|
---|
1353 | parenthes = "("
|
---|
1354 | else
|
---|
1355 | parenthes = ""
|
---|
1356 | end
|
---|
1357 | return "#{@type.get_type_str}#{parenthes}*"
|
---|
1358 | end
|
---|
1359 |
|
---|
1360 | def get_type_str_post
|
---|
1361 | if @type.kind_of?( ArrayType ) || @type.kind_of?( FuncType ) then
|
---|
1362 | parenthes = ")"
|
---|
1363 | else
|
---|
1364 | parenthes = ""
|
---|
1365 | end
|
---|
1366 | "#{parenthes}#{@type.get_type_str_post}"
|
---|
1367 | end
|
---|
1368 |
|
---|
1369 | def check # 意味的誤りがあれば、文字列を返す
|
---|
1370 | return nil if @type == nil
|
---|
1371 | @type.check
|
---|
1372 | end
|
---|
1373 |
|
---|
1374 | def check_struct_tag kind
|
---|
1375 | if kind != :MEMBER # 構造体メンバーの場合、ポインタの先の構造体タグをチェックしない
|
---|
1376 | @type.check_struct_tag kind
|
---|
1377 | end
|
---|
1378 | end
|
---|
1379 |
|
---|
1380 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
1381 | if ( initializer.instance_of?( Expression ) ) then
|
---|
1382 | val = initializer.eval_const2( nil, attribute )
|
---|
1383 | if val.kind_of? PointerVal then
|
---|
1384 | type = val.get_type # PtrType
|
---|
1385 | t1 = self
|
---|
1386 | t2 = type
|
---|
1387 | while( t1.kind_of?( PtrType ) && t2.kind_of?( PtrType ) )
|
---|
1388 | t1 = t1.get_type
|
---|
1389 | t2 = t2.get_type
|
---|
1390 | if ( t1.class == t2.class ) && ( t1.get_bit_size == t2.get_bit_size ) then
|
---|
1391 | elsif ( t1.kind_of?( CDefinedType) || t2.kind_of?( CDefinedType ) )&& t1.get_type_str == t2.get_type_str && t1.get_type_str_post && t2.get_type_str_post then
|
---|
1392 | # int8_t などが、一方は .h に定義されているケース
|
---|
1393 | else
|
---|
1394 | cdl_error2( locale, "T1032 $1: incompatible pointer type" , ident )
|
---|
1395 | break
|
---|
1396 | end
|
---|
1397 | end
|
---|
1398 | elsif val.kind_of? IntegerVal then
|
---|
1399 | if val.to_i != 0 then
|
---|
1400 | cdl_error2( locale, "T1033 $1: need cast to assign integer to pointer" , ident )
|
---|
1401 | end
|
---|
1402 | elsif val.kind_of? StringVal then
|
---|
1403 | # 文字列定数
|
---|
1404 | # mikan L"wide string"
|
---|
1405 | if @type.get_bit_size != -1 && @type.get_bit_size != -11 then # -1: char_t
|
---|
1406 | cdl_error2( locale, "T1034 $1: unsuitable string constant" , ident )
|
---|
1407 | end
|
---|
1408 | elsif ( val.instance_of?( Array ) ) then
|
---|
1409 | i = 0
|
---|
1410 | val.each { |ini|
|
---|
1411 | @type.check_init( locale, "#{ident}[#{i}]", ini, kind, attribute = nil )
|
---|
1412 | i += 1
|
---|
1413 | }
|
---|
1414 | elsif val.instance_of?( C_EXP ) then
|
---|
1415 |
|
---|
1416 | else
|
---|
1417 | cdl_error2( locale, "T1035 $1: unsuitable initializer for pointer" , ident )
|
---|
1418 | end
|
---|
1419 | elsif ( initializer.instance_of?( Array ) ) then
|
---|
1420 | if @size == nil && @count == nil then
|
---|
1421 | cdl_error2( locale, "T9999 $1: non-size_is pointer cannot have array initializer", ident )
|
---|
1422 | end
|
---|
1423 |
|
---|
1424 | i = 0
|
---|
1425 | initializer.each { |ini|
|
---|
1426 | @type.check_init( locale, "#{ident}[#{i}]", ini, kind, attribute = nil )
|
---|
1427 | i += 1
|
---|
1428 | }
|
---|
1429 | elsif( initializer.instance_of?( C_EXP ) ) then
|
---|
1430 |
|
---|
1431 | else
|
---|
1432 | cdl_error2( locale, "T1036 $1: unsuitable initializer for pointer" , ident )
|
---|
1433 | end
|
---|
1434 | end
|
---|
1435 |
|
---|
1436 | def get_referto
|
---|
1437 | clone_type
|
---|
1438 | @type
|
---|
1439 | end
|
---|
1440 |
|
---|
1441 | def set_scs( size, count, string, max, b_nullable )
|
---|
1442 | @size = size
|
---|
1443 | @count = count
|
---|
1444 | @max = max
|
---|
1445 | @b_nullable = b_nullable
|
---|
1446 |
|
---|
1447 | # string は最も左側の ptr に作用する
|
---|
1448 | if @type.kind_of?( PtrType ) then
|
---|
1449 | # ptr_level が 2 以上であることは ParamDecl#initializer でチェックされる
|
---|
1450 | clone_type
|
---|
1451 | @type.set_scs( nil, nil, string, nil, false )
|
---|
1452 | elsif @type.kind_of?( VoidType ) && ( size || count || string ) then
|
---|
1453 | str = ""
|
---|
1454 | if size then
|
---|
1455 | str = "size_is"
|
---|
1456 | end
|
---|
1457 | if count then
|
---|
1458 | if str then
|
---|
1459 | str += ", "
|
---|
1460 | end
|
---|
1461 | str += "count_is"
|
---|
1462 | end
|
---|
1463 | if string then
|
---|
1464 | if str then
|
---|
1465 | str += ", "
|
---|
1466 | end
|
---|
1467 | str += "string"
|
---|
1468 | end
|
---|
1469 |
|
---|
1470 | cdl_error( "T1040 $1 specified for void pointer type", str )
|
---|
1471 | else
|
---|
1472 | @string = string
|
---|
1473 | end
|
---|
1474 |
|
---|
1475 | if (@size != nil) && (@b_nullable != false) then
|
---|
1476 | cdl_error( "T9999 size_is & nullable cannot be specified simultaneously. If size is zero, pointer must be null")
|
---|
1477 | end
|
---|
1478 | end
|
---|
1479 |
|
---|
1480 | def clear_max
|
---|
1481 | @max = nil
|
---|
1482 | end
|
---|
1483 |
|
---|
1484 | def get_size
|
---|
1485 | @size
|
---|
1486 | end
|
---|
1487 |
|
---|
1488 | def get_count
|
---|
1489 | @count
|
---|
1490 | end
|
---|
1491 |
|
---|
1492 | def get_string
|
---|
1493 | @string
|
---|
1494 | end
|
---|
1495 |
|
---|
1496 | #=== PtrType# size_is の最大値
|
---|
1497 | def get_max
|
---|
1498 | @max
|
---|
1499 | end
|
---|
1500 |
|
---|
1501 | def is_nullable?
|
---|
1502 | return @b_nullable
|
---|
1503 | end
|
---|
1504 |
|
---|
1505 | def get_type
|
---|
1506 | clone_type
|
---|
1507 | @type
|
---|
1508 | end
|
---|
1509 |
|
---|
1510 | def has_pointer?
|
---|
1511 | true
|
---|
1512 | end
|
---|
1513 |
|
---|
1514 | def has_sized_pointer?
|
---|
1515 | @size != nil || @count != nil || @string.instance_of?( Expression ) || @type.has_sized_pointer?
|
---|
1516 | end
|
---|
1517 |
|
---|
1518 | def has_unsized_string?
|
---|
1519 | @string == -1 || @type.has_unsized_string?
|
---|
1520 | end
|
---|
1521 |
|
---|
1522 | def show_tree( indent )
|
---|
1523 | indent.times { print " " }
|
---|
1524 | puts "PtrType: qualifier=#{@qualifier}, nullable=#{@b_nullable} #{locale_str}"
|
---|
1525 | super( indent + 1 )
|
---|
1526 | (indent+1).times { print " " }
|
---|
1527 | if @size then
|
---|
1528 | print "size=#{@size.to_s}, "
|
---|
1529 | else
|
---|
1530 | print "size=nil, "
|
---|
1531 | end
|
---|
1532 | if @max then
|
---|
1533 | print "max=#{@size.to_s}, "
|
---|
1534 | else
|
---|
1535 | print "max=nil, "
|
---|
1536 | end
|
---|
1537 | if @count then
|
---|
1538 | print "count=#{@count.to_s}, "
|
---|
1539 | else
|
---|
1540 | print "count=nil, "
|
---|
1541 | end
|
---|
1542 | if @string then
|
---|
1543 | if @string.instance_of?( Expression ) then
|
---|
1544 | print "string=#{@string.to_s}\n"
|
---|
1545 | else
|
---|
1546 | print "string=yes\n"
|
---|
1547 | end
|
---|
1548 | else
|
---|
1549 | print "string=nil\n"
|
---|
1550 | end
|
---|
1551 |
|
---|
1552 | (indent+1).times { print " " }
|
---|
1553 | puts "type:"
|
---|
1554 | @type.show_tree( indent + 2 )
|
---|
1555 | end
|
---|
1556 |
|
---|
1557 | end
|
---|
1558 |
|
---|
1559 | #== DescriptorType クラス
|
---|
1560 | # 動的結合で渡すデスクリプタ型
|
---|
1561 | class DescriptorType < Type
|
---|
1562 | # @sinagure_nsp::NamespacePath
|
---|
1563 |
|
---|
1564 | @@descriptors = {}
|
---|
1565 |
|
---|
1566 | def initialize( signature_nsp )
|
---|
1567 | @signature_nsp = signature_nsp
|
---|
1568 | # check_signature ##
|
---|
1569 | @@descriptors[ self ] = false
|
---|
1570 | end
|
---|
1571 |
|
---|
1572 | def get_type_str
|
---|
1573 | "Descriptor( #{@signature_nsp.get_global_name} )"
|
---|
1574 | end
|
---|
1575 |
|
---|
1576 | def get_type_str_post
|
---|
1577 | ""
|
---|
1578 | end
|
---|
1579 |
|
---|
1580 | def set_qualifier( qualifier )
|
---|
1581 | cdl_error( "T9999 '$1' cannot be specified for Descriptor", qualfier.to_s )
|
---|
1582 | end
|
---|
1583 |
|
---|
1584 | def check
|
---|
1585 | end
|
---|
1586 |
|
---|
1587 | def check_init( locale, ident, initializer, kind, attribute = nil )
|
---|
1588 | case kind
|
---|
1589 | when :PARAMETER
|
---|
1590 | # 引数は初期化できない
|
---|
1591 | else
|
---|
1592 | cdl_error2( locale, "T9999 Descriptor cannot be used for $1", kind)
|
---|
1593 | end
|
---|
1594 | end
|
---|
1595 |
|
---|
1596 | def self.check_signature
|
---|
1597 | @@descriptors.each{ |desc, val|
|
---|
1598 | if val != true then
|
---|
1599 | desc.check_signature
|
---|
1600 | @@descriptors[ desc ] = true
|
---|
1601 | end
|
---|
1602 | }
|
---|
1603 | end
|
---|
1604 |
|
---|
1605 | def check_signature
|
---|
1606 | # p "Desc #{@signature_nsp.to_s}"
|
---|
1607 | obj = Namespace.find @signature_nsp
|
---|
1608 | if ! obj.kind_of? Signature then
|
---|
1609 | cdl_error( "T9999 '$1': not signature or not found", @signature_nsp.to_s )
|
---|
1610 | else
|
---|
1611 | if obj.has_descriptor? then
|
---|
1612 | # cdl_error( "T9999 '$1': has Descriptor in function parameter", @signature_nsp.to_s )
|
---|
1613 | end
|
---|
1614 | # @signature_nsp = obj.get_namespace_path
|
---|
1615 | end
|
---|
1616 | end
|
---|
1617 |
|
---|
1618 | #== DescriptorType#
|
---|
1619 | def get_signature
|
---|
1620 | Namespace.find @signature_nsp
|
---|
1621 | end
|
---|
1622 | end
|
---|
1623 |
|
---|
1624 | # 以下単体テストコード
|
---|
1625 | if $unit_test then
|
---|
1626 | puts( "===== Unit Test: IntType ===== (types.rb)")
|
---|
1627 | sizes = [ 8, 16, 32, 64 ]
|
---|
1628 | sizes.each{ |n|
|
---|
1629 | int = IntType.new n
|
---|
1630 | printf( "%8s max: %d min:%d\n", "int#{n}_t", int.get_max, int.get_min )
|
---|
1631 | }
|
---|
1632 | puts ""
|
---|
1633 | end
|
---|