Class: IntType

Inherits:
Type show all
Defined in:
lib/tecsgen/core/types.rb

Direct Known Subclasses

CIntType

Instance Method Summary collapse

Methods inherited from Type

#cast, #check_struct_tag, #clear_max, #equal?, #get_ID_str, #get_original_type, #has_pointer?, #has_sized_pointer?, #has_unsized_string?, #is_const?, #is_void?, #is_volatile?, #print_info, print_info_post, #print_info_post, reset_print_info, #set_qualifier, #set_scs

Methods inherited from Node

#cdl_error, #cdl_error2, #cdl_error3, #cdl_info, #cdl_info2, #cdl_warning, #cdl_warning2, #get_locale, #locale_str, #set_locale

Constructor Details

#initialize(bit_size) ⇒ IntType

@sign

:SIGNED, :UNSIGNED, nil



395
396
397
398
399
# File 'lib/tecsgen/core/types.rb', line 395

def initialize(bit_size)
  super()
  @bit_size = bit_size
  @sign = nil
end

Instance Method Details

#checkObject

意味的誤りがあれば、文字列を返す



421
422
423
# File 'lib/tecsgen/core/types.rb', line 421

def check # 意味的誤りがあれば、文字列を返す
  nil
end

#check_and_clip(in_val, from_type = :IntType) ⇒ Object

IntType# 最大値、最小値をチェックしてクリップする

キャスト演算を行う

in_val

IntegerVal, FloatVal: この型にキャストする値

from_type

Symbol: :IntType, :FloatType IntType の場合はビット数でクリップ、FloatType の場合は最大値でクリップ



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
# File 'lib/tecsgen/core/types.rb', line 486

def check_and_clip(in_val, from_type = :IntType)
  bit_size = get_bit_size
  if bit_size == -1
    bit_size = 8
  end
  val = in_val.to_i
  if get_max && val > get_max
    if from_type == :IntType
      rval = ((1 << bit_size) - 1) & val # bit 数でクリップ
    else
      rval = get_max # 最大値でクリップ (FloatType)
    end
    cdl_warning("W2003 $1: too large to cast to $2, clipped($3)", in_val, get_type_str, rval)
  elsif get_min && val < get_min
    if from_type == :IntType
      rval = ((1 << bit_size) - 1) & val
    else
      rval = get_min
    end
    if @sign == :SIGNED || @sign.nil?
      cdl_warning("W2004 $1: too small to cast to $2, clipped($3)", in_val, get_type_str, rval)
    else # @sign == :UNSIGNED || @sign == nil (char の場合)
      cdl_warning("W2005 $1: negative value for unsigned: convert to $2", in_val, rval)
    end
  else
    rval = val
  end
  return rval
end

#check_init(locale, ident, initializer, kind, attribute = nil) ⇒ Object



425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/tecsgen/core/types.rb', line 425

def check_init(locale, ident, initializer, kind, attribute = nil)
  val = initializer # C_EXP, Array
  if val.instance_of?(Expression)
    val = val.eval_const2(nil, attribute)
    # 評価の結果 C_EXP や Array となる可能性がある
  end

  if val.instance_of? Token # StringVal 導入により、もはや Token は来ないはず
    # val が Token の場合 == の右辺が String だとエラーを起こす (#198)
    cdl_error2(locale, "T1009 $1: $2: not integer", ident, val)
    return
  elsif val.is_a? C_EXP
    # #192 var が attribute を参照し、attribute の右辺が C_EXP の場合
    # const の右辺が C_EXP の場合も
    return
  elsif val.is_a? FloatVal
    cdl_error2(locale, "T1011 $1: need cast to assign float to integer", ident)
    return
  elsif val.instance_of? Array
    cdl_error2(locale, "T1017 $1: unsuitable initializer for scalar type", ident)
    return
  elsif val.nil?
    cdl_error2(locale, "T1010 $1: initializer is not constant", ident)
    return
  end

  if !val.is_a? IntegerVal
    cdl_error2(locale, "T1012 $1: $2: not integer", ident, val)
    return
  end

  val = val.to_i
  max = get_max
  min = get_min
  dbgPrint "sign=#{@sign} ident=#{ident} val=#{val} max=#{max} min=#{min}\n"

  if !max.nil?
    if val > max
      if @sign == :SIGNED || @sign.nil?
        cdl_error2(locale, "T1013 $1: too large (max=$2)", ident, max)
      else
        cdl_error2(locale, "T1016 $1: too large (max=$2)", ident, max)
      end
    end
  end

  if !min.nil?
    if val < min
      if @sign == :SIGNED || @sign.nil?
        cdl_error2(locale, "T1014 $1: too large negative value (min=$2)", ident, min)
      else
        cdl_error2(locale, "T1015 $1: negative value for unsigned", ident)
      end
    end
  end
end

#get_bit_sizeObject

IntType#bit_size を得る

返される値は @bit_size の仕様を参照


610
611
612
# File 'lib/tecsgen/core/types.rb', line 610

def get_bit_size
  return @bit_size
end

#get_maxObject



534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
# File 'lib/tecsgen/core/types.rb', line 534

def get_max
  if @bit_size == -1
    if @sign.nil?
      return 255 # char_t は、無符号に扱う
    else
      bit_sz = 8
    end
  else
    bit_sz = @bit_size
  end
  if @sign == :SIGNED || @sign.nil?
    case bit_sz
    when 8, 16, 32, 64, 128
      return (1 << (bit_sz - 1)) - 1
    else # -1, -2, -3, -4, -5, -11
      return nil
    end
  else   # @sign == :UNSIGNED
    case bit_sz
    when 8, 16, 32, 64, 128
      return (1 << bit_sz) - 1
    else # -2, -3, -4, -5, -11
      return nil
    end
  end
end

#get_minObject



516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
# File 'lib/tecsgen/core/types.rb', line 516

def get_min
  if @sign == :SIGNED || @sign.nil?
    if @bit_size == -1
      bit_sz = 8 # char_t は、有符号に扱う
    else
      bit_sz = @bit_size
    end
    case bit_sz
    when 8, 16, 32, 64, 128
      return - (1 << (bit_sz - 1))
    else # -1, -2, -3, -4, -5, -11
      return nil
    end
  else   # @sign == :UNSIGNED
    return 0
  end
end

#get_signObject

IntType# sign を得る



616
617
618
# File 'lib/tecsgen/core/types.rb', line 616

def get_sign
  @sign
end

#get_type_strObject

IntType# C 言語における型名(修飾子付き)



562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/tecsgen/core/types.rb', line 562

def get_type_str
  str = super

  # NEW_MODE
  case @sign
  when :SIGNED
    sign = ""
    signL = "signed "
  when :UNSIGNED
    sign = "u"
    signL = "unsigned "
  else
    sign = ""
    signL = ""
  end

  # p "get_type_str: sign:#{@sign} signL=#{signL}"

  case @bit_size
  when -1      # char_t 型
    if @sign == :SIGNED
      sign = "s"
    end
    str = "#{str}#{sign}char_t"
  when -11     # char 型(obsolete)
    str = "#{str}#{signL}char"
  when -2      # short 型
    str = "#{str}#{signL}short"
  when -3      # int 型
    str = "#{str}#{signL}int"
  when -4      # long 型
    str = "#{str}#{signL}long"
  when -5      # long long 型
    str = "#{str}#{signL}long long"
  when 8, 16, 32, 64, 128 # int16, int32, int64, int128 型
    str = "#{str}#{sign}int#{@bit_size}_t"
  end

  return str
end

#get_type_str_postObject

IntType# C 言語における型名(後置文字列)



604
605
606
# File 'lib/tecsgen/core/types.rb', line 604

def get_type_str_post
  ""
end

#set_sign(sign, b_uint = false) ⇒ Object



401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
# File 'lib/tecsgen/core/types.rb', line 401

def set_sign(sign, b_uint = false)
  if @sign
    if @sign != sign
      cdl_error("T1008 ambigous signed or unsigned")
    end
  elsif b_uint == false && @bit_size > 0
    if sign == :SIGNED
      cdl_warning("W2001 signed int$1_t: obsolete. use int$2_t", @bit_size, @bit_size)
    else
      cdl_warning("W2002 unsinged int$1_t: obsolete. use uint$2_t", @bit_size, @bit_size)
    end
  end

  @sign = sign

  if @sign != :SIGNED && @sign != :UNSIGNED
    raise "set_sign: unknown sign: #{@sign}"
  end
end

#show_tree(indent) ⇒ Object



620
621
622
623
624
# File 'lib/tecsgen/core/types.rb', line 620

def show_tree(indent)
  indent.times { print "  " }
  puts "IntType bit_size=#{@bit_size} sign=#{@sign} const=#{@b_const} volatile=#{@b_volatile} #{locale_str}"
  super(indent + 1)
end