Class: Idl::FunctionType
Instance Attribute Summary collapse
-
#func_def_ast ⇒ Object
readonly
Returns the value of attribute func_def_ast.
Instance Method Summary collapse
-
#apply_arguments(symtab, argument_nodes, call_site_symtab, func_call_ast) ⇒ Object
apply the arguments as Vars.
- #apply_template_values(template_values, func_call_ast) ⇒ Object
- #argument_name(index, template_values = [], func_call_ast) ⇒ Object
- #argument_type(index, template_values, argument_nodes, call_site_symtab, func_call_ast) ⇒ Object
- #argument_values(symtab, argument_nodes, call_site_symtab, func_call_ast) ⇒ Array<Integer,Boolean>?
- #body ⇒ Object
- #builtin? ⇒ Boolean
- #clone ⇒ Object
-
#initialize(func_name, func_def_ast, symtab) ⇒ FunctionType
constructor
A new instance of FunctionType.
- #num_args ⇒ Object
-
#return_type(template_values, func_call_ast) ⇒ Object
return [Type] type of the call return.
-
#return_types(template_values, argument_nodes, call_site_symtab, func_call_ast) ⇒ Array<Type>
Return types.
- #return_value(template_values, argument_nodes, call_site_symtab, func_call_ast) ⇒ Object
- #template_names ⇒ Object
- #template_types(symtab) ⇒ Object
- #templated? ⇒ Boolean
- #type_check_call(template_values, argument_nodes, call_site_symtab, func_call_ast) ⇒ Object
Constructor Details
#initialize(func_name, func_def_ast, symtab) ⇒ FunctionType
Returns a new instance of FunctionType.
624 625 626 627 628 629 630 |
# File 'lib/idl/type.rb', line 624 def initialize(func_name, func_def_ast, symtab) super(:function, name: func_name) @func_def_ast = func_def_ast @symtab = symtab raise "symtab should be at level 1" unless symtab.levels == 1 end |
Instance Attribute Details
#func_def_ast ⇒ Object (readonly)
Returns the value of attribute func_def_ast.
622 623 624 |
# File 'lib/idl/type.rb', line 622 def func_def_ast @func_def_ast end |
Instance Method Details
#apply_arguments(symtab, argument_nodes, call_site_symtab, func_call_ast) ⇒ Object
apply the arguments as Vars. then add the value to the Var
691 692 693 694 695 696 697 698 699 700 701 702 703 |
# File 'lib/idl/type.rb', line 691 def apply_arguments(symtab, argument_nodes, call_site_symtab, func_call_ast) idx = 0 @func_def_ast.arguments(symtab).each do |atype, aname| func_call_ast.type_error "Missing argument #{idx}" if idx >= argument_nodes.size value_result = Idl::AstNode.value_try do symtab.add(aname, Var.new(aname, atype, argument_nodes[idx].value(call_site_symtab))) end Idl::AstNode.value_else(value_result) do symtab.add(aname, Var.new(aname, atype)) end idx += 1 end end |
#apply_template_values(template_values, func_call_ast) ⇒ Object
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 |
# File 'lib/idl/type.rb', line 670 def apply_template_values(template_values, func_call_ast) func_call_ast.type_error "Missing template values" if templated? && template_values.empty? func_call_ast.type_error "wrong number of template values in call to #{name}" unless template_names.size == template_values.size symtab = @symtab.global_clone func_call_ast.type_error "Symbol table should be at global scope" unless symtab.levels == 1 symtab.push(func_call_ast) template_values.each_with_index do |value, idx| func_call_ast.type_error "template value should be an Integer (found #{value.class.name})" unless value == :unknown || value.is_a?(Integer) symtab.add!(template_names[idx], Var.new(template_names[idx], template_types(symtab)[idx], value, template_index: idx, function_name: @func_def_ast.name)) end symtab end |
#argument_name(index, template_values = [], func_call_ast) ⇒ Object
782 783 784 785 786 787 788 789 790 791 792 793 794 795 |
# File 'lib/idl/type.rb', line 782 def argument_name(index, template_values = [], func_call_ast) return nil if index >= @func_def_ast.num_args symtab = apply_template_values(template_values, func_call_ast) # apply_arguments(symtab, argument_nodes, call_site_symtab) begin arguments = @func_def_ast.arguments(symtab) ensure symtab.pop symtab.relase end arguments[index][1] end |
#argument_type(index, template_values, argument_nodes, call_site_symtab, func_call_ast) ⇒ Object
767 768 769 770 771 772 773 774 775 776 777 778 779 780 |
# File 'lib/idl/type.rb', line 767 def argument_type(index, template_values, argument_nodes, call_site_symtab, func_call_ast) return nil if index >= @func_def_ast.num_args symtab = apply_template_values(template_values, func_call_ast) # apply_arguments(symtab, argument_nodes, call_site_symtab, func_call_ast) begin arguments = @func_def_ast.arguments(symtab) ensure symtab.pop symtab.release end arguments[index][0] end |
#argument_values(symtab, argument_nodes, call_site_symtab, func_call_ast) ⇒ Array<Integer,Boolean>?
707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 |
# File 'lib/idl/type.rb', line 707 def argument_values(symtab, argument_nodes, call_site_symtab, func_call_ast) idx = 0 values = [] @func_def_ast.arguments(symtab).each do |atype, aname| func_call_ast.type_error "Missing argument #{idx}" if idx >= argument_nodes.size value_result = Idl::AstNode.value_try do values << argument_nodes[idx].value(call_site_symtab) end Idl::AstNode.value_else(value_result) do return nil end idx += 1 end values end |
#body ⇒ Object
797 |
# File 'lib/idl/type.rb', line 797 def body = @func_def_ast.body |
#builtin? ⇒ Boolean
636 |
# File 'lib/idl/type.rb', line 636 def builtin? = @func_def_ast.builtin? |
#clone ⇒ Object
632 633 634 |
# File 'lib/idl/type.rb', line 632 def clone FunctionType.new(name, @func_def_ast, @symtab) end |
#num_args ⇒ Object
638 |
# File 'lib/idl/type.rb', line 638 def num_args = @func_def_ast.num_args |
#return_type(template_values, func_call_ast) ⇒ Object
return [Type] type of the call return
726 727 728 729 730 731 732 733 734 735 736 737 |
# File 'lib/idl/type.rb', line 726 def return_type(template_values, func_call_ast) symtab = apply_template_values(template_values, func_call_ast) # apply_arguments(symtab, argument_nodes, call_site_symtab) begin type = @func_def_ast.return_type(symtab) ensure symtab.pop symtab.release end type end |
#return_types(template_values, argument_nodes, call_site_symtab, func_call_ast) ⇒ Array<Type>
Return types
754 755 756 757 758 759 760 761 762 763 764 765 |
# File 'lib/idl/type.rb', line 754 def return_types(template_values, argument_nodes, call_site_symtab, func_call_ast) symtab = apply_template_values(template_values, func_call_ast) apply_arguments(symtab, argument_nodes, call_site_symtab, func_call_ast) begin types = @func_def_ast.return_types(symtab) ensure symtab.pop symtab.release end types end |
#return_value(template_values, argument_nodes, call_site_symtab, func_call_ast) ⇒ Object
739 740 741 742 743 744 745 746 747 748 749 750 |
# File 'lib/idl/type.rb', line 739 def return_value(template_values, argument_nodes, call_site_symtab, func_call_ast) symtab = apply_template_values(template_values, func_call_ast) apply_arguments(symtab, argument_nodes, call_site_symtab, func_call_ast) begin value = @func_def_ast.body.return_value(symtab) ensure symtab.pop symtab.release end value end |
#template_names ⇒ Object
664 |
# File 'lib/idl/type.rb', line 664 def template_names = @func_def_ast.template_names |
#template_types(symtab) ⇒ Object
666 |
# File 'lib/idl/type.rb', line 666 def template_types(symtab) = @func_def_ast.template_types(symtab) |
#templated? ⇒ Boolean
668 |
# File 'lib/idl/type.rb', line 668 def templated? = @func_def_ast.templated? |
#type_check_call(template_values, argument_nodes, call_site_symtab, func_call_ast) ⇒ Object
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 |
# File 'lib/idl/type.rb', line 640 def type_check_call(template_values, argument_nodes, call_site_symtab, func_call_ast) raise "Missing template values" if templated? && template_values.empty? if templated? symtab = apply_template_values(template_values, func_call_ast) apply_arguments(symtab, argument_nodes, call_site_symtab, func_call_ast) @func_def_ast.type_check_template_instance(symtab) symtab.pop symtab.release else symtab = @symtab.global_clone symtab.push(func_call_ast) # to keep things consistent with template functions, push a scope apply_arguments(symtab, argument_nodes, call_site_symtab, func_call_ast) @func_def_ast.type_check_from_call(symtab) symtab.pop symtab.release end end |