source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tecsgen/tecslib/core/value.rb@ 352

Last change on this file since 352 was 352, checked in by coas-nagasima, 6 years ago

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 13.9 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2014 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#= BaseVal 整数、浮動小数などの値を扱うクラスの基底クラス
41#
42# TECS の CDL で扱う値は、以下に分類される
43# ・整数
44# ・浮動小数
45# ・文字列
46# ・ブール値
47# 集成型(構造体、配列)と C_EXP はここでは扱わない
48#
49# このクラスで定義済みの演算子は、エラーとなる
50# 型により演算可能な場合、演算子をオーバーライドする
51#
52class BaseVal < Node
53 def ~@
54 unsupport "~"
55 end
56 def -@
57 unsupport "unary -"
58 end
59 def +@
60 unsupport "unary +"
61 end
62 def not # ! val
63 unsupport "!"
64 end
65
66 def * val
67 unsupport "*"
68 end
69 def / val
70 unsupport "/"
71 end
72 def % val
73 unsupport "%"
74 end
75 def + val
76 unsupport "+"
77 end
78 def - val
79 unsupport "-"
80 end
81 def << val
82 unsupport "<<"
83 end
84 def >> val
85 unsupport ">>"
86 end
87 def > val
88 unsupport ">"
89 end
90 def < val
91 unsupport "<"
92 end
93 def >= val
94 unsupport ">="
95 end
96 def <= val
97 unsupport "<="
98 end
99 def eq val # == val
100 unsupport "=="
101 end
102 def neq val # != val
103 unsupport "!="
104 end
105 def & val
106 unsupport "&"
107 end
108 def ^ val
109 unsupport "^"
110 end
111 def | val
112 unsupport "|"
113 end
114 def lAND val # && val
115 unsupport "&&"
116 end
117 def lOR val # || val
118 unsupport "||"
119 end
120 def cast( type )
121 unsupport "CAST"
122 end
123
124 def unsupport op
125 cdl_error( "V1001 $1: unable for $2" , op, self.class )
126 end
127
128 def to_s
129 raise "to_s not overridden"
130 end
131
132 def to_b
133 cdl_error( "V1002 $1: cannot cast to bool (implicitly)" , self.class )
134 false
135 end
136 def to_i
137 cdl_error( "V1003 $1: cannot cast to integer (implicitly)" , self.class )
138 1
139 end
140 def to_f
141 cdl_error( "V1004 $1: cannot cast to float (implicitly)" , self.class )
142 1.0
143 end
144end
145
146#= Pointer 値 (IntegerVal の Pointer 版)
147#
148# ポインタ値は、CDL で直接生成されることはない
149# 整数値のキャスト演算により生成される
150class PointerVal < BaseVal
151#@int_val:: IntegerVal: IntegerVal でなくてはならない
152#@ptr_type:: PtrType: ポインタの指す先の型
153
154 def initialize( int_val, ptr_type )
155 super()
156 @int_val = int_val
157 @ptr_type = ptr_type
158 end
159
160 #=== ポインタの指す先の型を得る
161 # PointerVal 専用のメソッド
162 def get_type
163 @ptr_type
164 end
165
166 def cast type
167 t = type.get_original_type # typedef の元を得る
168 if t.kind_of? IntType then
169 val = t.check_and_clip( @int_val, :IntType )
170 return IntegerVal.new( val )
171 elsif t.kind_of? FloatType then
172 cdl_error( "V1005 Cannot cast pointer to float" )
173 return FloatVal.new( @int_val )
174 elsif t.kind_of? PtrType then
175 return PointerVal.new( @int_val, type )
176 else
177 cdl_error( "V1006 pointer value cannot cast to $1" , type.class )
178 return nil
179 end
180 end
181
182 def to_s
183 "(#{@ptr_type.get_type_str}#{@ptr_type.get_type_str_post})#{sprintf("0x%X", @int_val)}"
184 end
185
186 def to_b
187 cdl_error( "V1007 convert pointer value to bool" )
188 false
189 end
190 def to_i
191 cdl_error( "V1008 convert pointer value to integer without cast" )
192 @val.to_i
193 end
194end
195
196#= IntegerVal: 整数値を扱うクラス
197class IntegerVal < BaseVal
198#@val:: Integer: value
199#@str:: string: literal
200#@sign:: Symbol: :SIGNED | :UNSIGNED
201#@size:: Symbol: :NORMAL | :SHORT | :LONG | :LONGLONG
202
203 def initialize( val, str = nil, sign = :SIGNED, size = :NORMAL )
204 super()
205 @val = val.to_i
206 @str = str
207 @sign = sign
208 @size = size
209 end
210
211 def ~@
212 IntegerVal.new( ~ @val )
213 end
214 def -@
215 IntegerVal.new( - @val )
216 end
217 def +@
218 self
219 end
220 def not # !
221 BoolVal.new( self.to_b )
222 end
223
224 def * val
225 if val.kind_of? FloatVal then
226 return FloatVal.new( @val.to_f * val.to_f )
227 else
228 return IntegerVal.new( @val * val.to_i )
229 end
230 end
231 def / val
232 if val.kind_of? FloatVal then
233 v2 = val.to_f # to_f を2回評価しない
234 if v2 == 0.0 then
235 cdl_error( "V1009 / : divieded by zero" )
236 return FloatVal.new( 1.0 )
237 end
238 return FloatVal.new( @val.to_f / v2 )
239 else
240 v2 = val.to_i # to_i を2回評価しない
241 if v2 == 0 then
242 cdl_error( "V1010 / : divieded by zero" )
243 return IntegerVal.new( 1 )
244 end
245 return IntegerVal.new( @val / v2 )
246 end
247 end
248 def % val
249 if val.kind_of? FloatVal then
250 v2 = val.to_f # to_f を2回評価しない
251 if v2 == 0.0 then
252 cdl_error( "V1011 % : divieded by zero" )
253 return FloatVal.new( 1.0 )
254 end
255 return FloatVal.new( @val.to_f % v2 )
256 else
257 v2 = val.to_i # to_i を2回評価しない
258 if v2 == 0 then
259 cdl_error( "V1012 % : divieded by zero" )
260 return IntegerVal.new( 1 )
261 end
262 return IntegerVal.new( @val % v2 )
263 end
264 end
265 def + val
266 if val.kind_of? FloatVal then
267 return FloatVal.new( @val.to_f + val.to_f )
268 else
269 return IntegerVal.new( @val + val.to_i )
270 end
271 end
272 def - val
273 if val.kind_of? FloatVal then
274 return FloatVal.new( @val.to_f - val.to_f )
275 else
276 return IntegerVal.new( @val - val.to_i )
277 end
278 end
279 def << val
280 return IntegerVal.new( @val << val.to_i )
281 end
282 def >> val
283 return IntegerVal.new( @val >> val.to_i )
284 end
285 def > val
286 if val.kind_of? FloatVal then
287 return BoolVal.new( @val.to_f > val.to_f )
288 else
289 return BoolVal.new( @val > val.to_i )
290 end
291 end
292 def < val
293 if val.kind_of? FloatVal then
294 return BoolVal.new( @val.to_f < val.to_f )
295 else
296 return BoolVal.new( @val < val.to_i )
297 end
298 end
299 def >= val
300 if val.kind_of? FloatVal then
301 return BoolVal.new( @val.to_f >= val.to_f )
302 else
303 return BoolVal.new( @val >= val.to_i )
304 end
305 end
306 def <= val
307 if val.kind_of? FloatVal then
308 return BoolVal.new( @val.to_f <= val.to_f )
309 else
310 return BoolVal.new( @val <= val.to_i )
311 end
312 end
313 def eq val # == val
314 if val.kind_of? FloatVal then
315 return BoolVal.new( @val.to_f == val.to_f )
316 else
317 return BoolVal.new( @val == val.to_i )
318 end
319 end
320 def neq val # != val
321 if val.kind_of? FloatVal then
322 return BoolVal.new( @val.to_f != val.to_f )
323 else
324 return BoolVal.new( @val != val.to_i )
325 end
326 end
327 def & val
328 IntegerVal.new( @val & val.to_i )
329 end
330 def ^ val
331 IntegerVal.new( @val ^ val.to_i )
332 end
333 def | val
334 IntegerVal.new( @val | val.to_i )
335 end
336 def lAND val # && val
337 BoolVal.new( self.to_b && val.to_b )
338 end
339 def lOR val # || val
340 BoolVal.new( self.to_b || val.to_b )
341 end
342 def cast( type )
343 t = type.get_original_type # typedef の元を得る
344 if t.kind_of? IntType then
345 val = t.check_and_clip( @val, :IntType )
346 return IntegerVal.new( val )
347 elsif t.kind_of? FloatType then
348 return FloatVal.new( @val )
349 elsif t.kind_of? PtrType then
350 return PointerVal.new( @val, type )
351 elsif t.kind_of? BoolType then
352 return BoolVal.new( @val.to_b )
353 else
354 cdl_error( "V1013 integer value cannot cast to $1" , type.class )
355 return nil
356 end
357 end
358
359 def to_s
360 if @str then
361 @str
362 else
363 @val.to_s
364 end
365 end
366 def to_b
367 @val != 0
368 end
369 def to_i
370 @val
371 end
372 def to_f
373 @val.to_f
374 end
375end
376
377#= BoolVal: bool 値を扱うクラス
378class BoolVal < BaseVal
379#@val:: bool: true, false
380
381 def initialize( val )
382 super()
383 if val == true || val == false
384 @val = val
385 elsif val.to_i != 0
386 @val = true
387 else
388 @val = false
389 end
390 # raise "No boolean val" if val != true && val != false
391 end
392
393 def not # ! val
394 BoolVal.new( ! @val )
395 end
396 def eq val # == val
397 if val.kind_of? BoolVal then
398 return BoolVal.new( self.to_i == val.to_i )
399 else
400 cdl_error( "V1014 comparing bool value with \'$1\'" , val.class )
401 return BoolVal.new( false )
402 end
403 end
404 def neq val # != val
405 if val.kind_of? BoolVal then
406 return BoolVal.new( self.to_i != val.to_i )
407 else
408 cdl_error( "V1015 comparing bool value with \'$1\'" , val.class )
409 return BoolVal.new( false )
410 end
411 end
412 def lAND val # && val
413 BoolVal.new( self.to_b && val.to_b )
414 end
415 def lOR val # || val
416 BoolVal.new( self.to_b || val.to_b )
417 end
418 def cast( type )
419 t = type.get_original_type # typedef の元を得る
420 if @val then
421 val = 1
422 else
423 val = 0
424 end
425 if t.kind_of? IntType then
426 return IntegerVal.new( val )
427 elsif t.kind_of? FloatType then
428 return FloatVal.new( val )
429 elsif t.kind_of? BoolType then
430 return self
431 else
432 cdl_error( "V1016 bool value cannot cast to $1" , type.class )
433 return nil
434 end
435 end
436
437 def to_s
438 if @val
439 return "true"
440 else
441 return "false"
442 end
443 end
444 def to_b
445 @val
446 end
447 def to_i
448 return 0 if @val == false
449 return 1
450 end
451 def to_f
452 return 0.0 if @val == false
453 return 1.0
454 end
455
456 attr_reader :val
457end
458
459#= FloatVal: 実数値を扱うクラス
460class FloatVal < BaseVal
461#@val:: Float
462 def initialize( val )
463 super()
464 @val = val.to_f
465 end
466
467 def -@
468 FloatVal.new( - @val )
469 end
470 def +@
471 self
472 end
473 def * val
474 FloatVal.new( @val * val.to_f )
475 end
476 def / val
477 v2 = val.to_f # to_f を2回評価しない
478 if v2 == 0.0 then
479 cdl_error( "V1017 / : divieded by zero" )
480 return FloatVal.new( 1.0 )
481 end
482 return FloatVal.new( @val.to_f / v2 )
483 end
484 def % val
485 v2 = val.to_f # to_f を2回評価しない
486 if v2 == 0.0 then
487 cdl_error( "V1018 % : divieded by zero" )
488 return FloatVal.new( 1.0 )
489 end
490 return FloatVal.new( @val.to_f % v2 )
491 end
492 def + val
493 FloatVal.new( @val + val.to_f )
494 end
495 def - val
496 FloatVal.new( @val - val.to_f )
497 end
498 def > val
499 BoolVal.new( @val > val.to_f )
500 end
501 def < val
502 BoolVal.new( @val < val.to_f )
503 end
504 def >= val
505 BoolVal.new( @val >= val.to_f )
506 end
507 def <= val
508 BoolVal.new( @val <= val.to_f )
509 end
510 def eq val # == val
511 BoolVal.new( @val == val.to_f )
512 end
513 def neq val # != val
514 BoolVal.new( @val != val.to_f )
515 end
516 def cast( type )
517 t = type.get_original_type # typedef の元を得る
518 if t.kind_of? IntType then
519 val = t.check_and_clip( @val, :FloatType )
520 return IntegerVal.new( val )
521 elsif t.kind_of? FloatType then
522 return self
523 else
524 cdl_error( "V1019 floating value cannot cast to $1" , type )
525 return self
526 end
527 end
528
529 def to_b
530 cdl_error( "V1020 convert floating value to bool without cast" )
531 @val.to_i
532 end
533 def to_i
534 cdl_error( "V1021 convert floating value to integer without cast" )
535 @val.to_i
536 end
537 def to_s
538 @val.to_s
539 end
540 def to_f
541 @val
542 end
543end
544
545#= 文字列リテラルを扱うクラス
546class StringVal < BaseVal
547#@str:: Token:
548#@specifier:: Symbol: :WIDE, :NORMAL
549
550 def initialize( str, spec = :NORMAL )
551 super()
552 @str = str
553 @specifier = spec # mikan L"str" wide 文字列未対応
554 end
555
556 #===
557 #
558 # string の cast はできない mikan ポインタ型への cast はできるべき
559 def cast type
560 t = type.get_original_type # typedef の元を得る
561 if t.kind_of? IntType then
562 cdl_error( "V1022 string cannot cast to integer" )
563 elsif t.kind_of? FloatType then
564 cdl_error( "V1023 string cannot cast to float" )
565 elsif t.kind_of? PtrType then
566 cdl_error( "V1024 string cannot cast to pointer" )
567 else
568 cdl_error( "V1025 string cannot cast to $1" , type )
569 end
570 end
571
572 def to_s
573 @str.to_s
574 end
575
576 def val
577 @str.to_s # Token で扱われていた名残 (val を取り出す)
578 end
579end
Note: See TracBrowser for help on using the repository browser.