From c346260bde5a2a6964c5150dcaf592b7740d4d84 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Tue, 13 Dec 2016 18:47:44 +0200 Subject: [PATCH] change method arguments to be a type instance where is was a list of variables (half baked) variables also having values (not applicable) --- lib/typed/parfait/typed_method.rb | 37 +++++++++++++++----------- test/typed/parfait/test_method.rb | 44 ++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/lib/typed/parfait/typed_method.rb b/lib/typed/parfait/typed_method.rb index b21e950d..261b1d1d 100644 --- a/lib/typed/parfait/typed_method.rb +++ b/lib/typed/parfait/typed_method.rb @@ -13,7 +13,7 @@ # - instructions: The sequence of instructions the source (ast) was compiled to # Instructions derive from class Instruction and form a linked list # - binary: The binary (jumpable) code that the instructions get assembled into -# - arguments: A List of Variables that can/are passed +# - arguments: A type object describing the arguments (name+types) to be passed # - locals: A List of Variables that the method has # - for_class: The class the Method is for (TODO, should be Type) @@ -26,32 +26,37 @@ module Parfait # not part of the parfait model, hence ruby accessor attr_accessor :source - def initialize clazz , name , arguments + def initialize( clazz , name , arguments ) super() raise "No class #{name}" unless clazz + raise "Wrong argument type, expect Type not #{arguments.class}" unless arguments.is_a? Type self.for_class = clazz self.name = name self.binary = BinaryCode.new 0 - raise "Wrong type, expect List not #{arguments.class}" unless arguments.is_a? List - arguments.each do |var| - raise "Must be variable argument, not #{var}" unless var.is_a? Variable - end self.arguments = arguments self.locals = List.new end # determine whether this method has an argument by the name - def has_arg name + def has_arg( name ) raise "has_arg #{name}.#{name.class}" unless name.is_a? Symbol - max = self.arguments.get_length - counter = 1 - while( counter <= max ) - if( self.arguments.get(counter).name == name) - return counter - end - counter = counter + 1 - end - return nil + index = arguments.variable_index( name ) + index ? (index - 1) : index + end + + def add_argument(name , type) + self.arguments = self.arguments.add_instance_variable(name,type) + end + + def arguments_length + arguments.instance_length - 1 + end + + def argument_name(index) + arguments.get(index * 2 + 1) + end + def argument_type(index) + arguments.get(index * 2 + 2) end # determine if method has a local variable or tmp (anonymous local) by given name diff --git a/test/typed/parfait/test_method.rb b/test/typed/parfait/test_method.rb index e9c603a6..dfe4e3d2 100644 --- a/test/typed/parfait/test_method.rb +++ b/test/typed/parfait/test_method.rb @@ -4,20 +4,52 @@ class TestMethod < MiniTest::Test def setup obj = Register.machine.space.get_class_by_name(:Object) - args = Parfait.new_list [ Parfait::Variable.new(:Integer , :bar )] - @method = ::Parfait::TypedMethod.new obj , :foo , args + args = Parfait::Type.new_for_hash( obj , { bar: :Integer , foo: :Type}) + @method = ::Parfait::TypedMethod.new obj , :meth , args end def test_method_name - assert_equal :foo , @method.name + assert_equal :meth , @method.name + end + + def test_class_for + assert_equal :Object , @method.for_class.name end def test_arg1 - assert_equal 1 , @method.arguments.get_length - assert_equal Parfait::Variable , @method.arguments.first.class - assert_equal :bar , @method.arguments.first.name + assert_equal 2 , @method.arguments_length , @method.arguments.inspect + assert_equal Symbol , @method.arguments.first.class + assert_equal :bar , @method.argument_name(1) end + def test_has_arg assert_equal 1 , @method.has_arg(:bar) + assert_equal 2 , @method.has_arg(:foo) + end + + def test_add_arg + @method.add_argument(:foo2 , :Object) + assert_equal 3 , @method.arguments_length + assert_equal :foo2 , @method.argument_name(3) + assert_equal :Object , @method.argument_type(3) + end + + def test_get_arg_name1 + index = @method.has_arg(:bar) + assert_equal 1 , index + assert_equal :bar , @method.argument_name(index) + end + def test_get_arg_name1 + index = @method.has_arg(:bar) + assert_equal :Integer , @method.argument_type(index) + end + def test_get_arg_name2 + index = @method.has_arg(:foo) + assert_equal 2 , index + assert_equal :foo , @method.argument_name(index) + end + def test_get_arg_name2 + index = @method.has_arg(:foo) + assert_equal :Type , @method.argument_type(index) end end