Class: Decl

Inherits:
BDNode show all
Defined in:
lib/tecsgen/core/syntaxobj.rb,
lib/tecsgen/core/tecsinfo.rb

Overview

宣言

Instance Method Summary collapse

Methods inherited from BDNode

#get_owner, #set_owner

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(identifier) ⇒ Decl

mikan ParamDecl だけ別に設けたが、MemberDecl, AttrDecl なども分けるべきか(?)



459
460
461
462
463
464
465
466
467
468
469
# File 'lib/tecsgen/core/syntaxobj.rb', line 459

def initialize(identifier)
  super()
  @identifier = identifier
  @rw = false
  @omit = false
  @size_is = nil
  @count_is = nil
  @string = nil
  @choice_list = nil
  @b_referenced = false
end

Instance Method Details

#checkObject

Decl の意味的誤りをチェックする



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
515
516
517
518
519
520
521
522
523
# File 'lib/tecsgen/core/syntaxobj.rb', line 488

def check
  # return nil if @type == nil

  # 構造体タグチェック(ポインタ型から構造体が参照されている場合は、タグの存在をチェックしない)
  @type.check_struct_tag @kind

  # 型のチェックを行う
  res = @type.check
  if res
    cdl_error("S2002 $1: $2", @identifier, res)
  end

  # 不要の初期化子をチェックする
  if @initializer
    case @kind
    when :PARAMETER, :TYPEDEF, :MEMBER, :FUNCHEAD
      cdl_error("S2003 $1: $2 cannot have initializer", @identifier, @kind.to_s.downcase)
    when :VAR, :ATTRIBUTE, :CONSTANT
      # p @initializer  ここでは代入可能かどうか、チェックしない
      # :VAR, :ATTRIBUTE, :CONSTANT はそれぞれでチェックする
      # return @type.check_init( @identifier, @initializer, @kind )
    else
      raise "unknown kind in Delc::check"
    end
  end

  if (@type.is_a? ArrayType) && @type.get_subscript.nil? && (@omit == false)
    if @kind == :ATTRIBUTE
      cdl_error("S2004 $1: array subscript must be specified or omit", @identifier)
    elsif @kind == :VAR || @kind == :MEMBER
      cdl_error("S2005 $1: array subscript must be specified", @identifier)
    end
  end

  return nil
end

#get_choice_listObject



643
644
645
# File 'lib/tecsgen/core/syntaxobj.rb', line 643

def get_choice_list
  @choice_list
end

#get_count_isObject



635
636
637
# File 'lib/tecsgen/core/syntaxobj.rb', line 635

def get_count_is
  @count_is
end

#get_global_nameObject



559
560
561
# File 'lib/tecsgen/core/syntaxobj.rb', line 559

def get_global_name
  @global_name
end

#get_identifierObject



575
576
577
# File 'lib/tecsgen/core/syntaxobj.rb', line 575

def get_identifier
  @identifier
end

#get_initializerObject



475
476
477
# File 'lib/tecsgen/core/syntaxobj.rb', line 475

def get_initializer
  @initializer
end

#get_kindObject



594
595
596
# File 'lib/tecsgen/core/syntaxobj.rb', line 594

def get_kind
  @kind
end

#get_nameObject



555
556
557
# File 'lib/tecsgen/core/syntaxobj.rb', line 555

def get_name
  @identifier
end

#get_ptr_levelObject

ポインタレベルを得る

戻り値:

非ポインタ変数   = 0
ポインタ変数     = 1
二重ポインタ変数 = 2


530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
# File 'lib/tecsgen/core/syntaxobj.rb', line 530

def get_ptr_level
  level = 0
  type = @type
  while 1
    if type.is_a?(PtrType)
      level += 1
      type = type.get_referto
#      elsif type.kind_of?( ArrayType ) then  # 添数なし配列はポインタとみなす
#        if type.get_subscript == nil then
#          level += 1
#          type = type.get_type
#        else
#          break
#        end
      # mikan ポインタの添数あり配列のポインタレベルは0でよい?
    elsif type.is_a?(DefinedType)
      type = type.get_type
      # p "DefinedType: #{type} #{type.class}"
    else
      break
    end
  end
  return level
end

#get_size_isObject



631
632
633
# File 'lib/tecsgen/core/syntaxobj.rb', line 631

def get_size_is
  @size_is
end

#get_stringObject



639
640
641
# File 'lib/tecsgen/core/syntaxobj.rb', line 639

def get_string
  @string
end

#get_typeObject



571
572
573
# File 'lib/tecsgen/core/syntaxobj.rb', line 571

def get_type
  @type
end

#is_const?Boolean

Returns:

  • (Boolean)


668
669
670
671
672
673
674
675
676
677
678
679
# File 'lib/tecsgen/core/syntaxobj.rb', line 668

def is_const?
  type = @type
  while 1
    if type.is_const?
      return true
    elsif type.is_a?(DefinedType)
      type = type.get_type
    else
      return false
    end
  end
end

#is_function?Boolean

Returns:

  • (Boolean)


479
480
481
482
483
484
485
# File 'lib/tecsgen/core/syntaxobj.rb', line 479

def is_function?
  if @type.class == FuncType
    return true
  else
    return false
  end
end

#is_omit?Boolean

Returns:

  • (Boolean)


627
628
629
# File 'lib/tecsgen/core/syntaxobj.rb', line 627

def is_omit?
  @omit
end

#is_referenced?Boolean

Returns:

  • (Boolean)


651
652
653
# File 'lib/tecsgen/core/syntaxobj.rb', line 651

def is_referenced?
  @b_referenced
end

#is_rw?Boolean

Returns:

  • (Boolean)


623
624
625
# File 'lib/tecsgen/core/syntaxobj.rb', line 623

def is_rw?
  @rw
end

#is_type?(type) ⇒ Boolean

Returns:

  • (Boolean)


655
656
657
658
659
660
661
662
663
664
665
666
# File 'lib/tecsgen/core/syntaxobj.rb', line 655

def is_type?(type)
  t = @type
  while 1
    if t.is_a?(type)
      return true
    elsif t.is_a?(DefinedType)
      t = t.get_type
    else
      return false
    end
  end
end


747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
# File 'lib/tecsgen/core/tecsinfo.rb', line 747

def print_info(f, parent_ID_str, indent, decl_type)
  if @size_is
    size = "\"mikan\""
  else
    size = "(char_t*)0"
  end
  f.print <<EOT
#{indent}cell nTECSInfo::tVarDeclInfo #{parent_ID_str}_#{get_name}VarDeclInfo {
#{indent}    name            = "#{get_name}";
#{indent}    sizeIsExpr      = #{size};
#{indent}    declType        = #{decl_type};
#{indent}    offset          = C_EXP( "OFFSET_OF_#{parent_ID_str}_#{get_name}" );
#{indent}    place           = C_EXP( "PLACE_OF_#{parent_ID_str}_#{get_name}" );
#{indent}    cTypeInfo       = #{get_type.get_ID_str}TypeInfo.eTypeInfo;
#{indent}};
EOT
  get_type.print_info f, indent
end

#referencedObject



647
648
649
# File 'lib/tecsgen/core/syntaxobj.rb', line 647

def referenced
  @b_referenced = true
end

#set_initializer(initializer) ⇒ Object



471
472
473
# File 'lib/tecsgen/core/syntaxobj.rb', line 471

def set_initializer(initializer)
  @initializer = initializer
end

#set_kind(kind) ⇒ Object

STAGE: B



580
581
582
583
584
585
586
587
588
589
590
591
592
# File 'lib/tecsgen/core/syntaxobj.rb', line 580

def set_kind(kind)
  @kind = kind
  case kind
  when :TYPEDEF, :CONSTANT
    if Namespace.get_global_name.to_s == ""
      @global_name = @identifier
    else
      @global_name = :"#{Namespace.get_global_name}_#{@identifier}"
    end
  else
    @global_name = nil
  end
end

#set_specifier_list(spec_list) ⇒ Object



598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
# File 'lib/tecsgen/core/syntaxobj.rb', line 598

def set_specifier_list(spec_list)
  spec_list.each{|spec|
    case spec[0]
    when :RW
      @rw = true
    when :OMIT
      @omit = true
    when :SIZE_IS
      @size_is = spec[1]
    when :COUNT_IS
      @count_is = spec[1]
    when :STRING
      @string = spec[1]
    when :CHOICE
      @choice_list = spec[1]
    else
      raise "Unknown specifier #{spec[0]}"
    end
  }

  if @size_is || @count_is || @string
    @type.set_scs(@size_is, @count_is, @string, nil, false)
  end
end

#set_type(type) ⇒ Object



563
564
565
566
567
568
569
# File 'lib/tecsgen/core/syntaxobj.rb', line 563

def set_type(type)
  unless @type
    @type = type
  else
    @type.set_type(type) # 葉に設定
  end
end

#show_tree(indent) ⇒ Object



681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
# File 'lib/tecsgen/core/syntaxobj.rb', line 681

def show_tree(indent)
  indent.times { print "  " }
  puts "Declarator: name: #{@identifier} kind: #{@kind} global_name: #{@global_name} #{locale_str}"
  (indent + 1).times { print "  " }
  puts "type:"
  @type.show_tree(indent + 2)
  if @initializer
    (indent + 1).times { print "  " }
    puts "initializer:"
    @initializer.show_tree(indent + 2)
  else
    (indent + 1).times { print "  " }
    puts "initializer: no"
  end
  (indent + 1).times { print "  " }
  puts "size_is: #{@size_is}, count_is: #{@count_is}, string: #{@string} referenced: #{@b_referenced} "
end