diff --git a/lib/register/builtin/integer.rb b/lib/register/builtin/integer.rb index d298e93e..bd80baac 100644 --- a/lib/register/builtin/integer.rb +++ b/lib/register/builtin/integer.rb @@ -8,99 +8,98 @@ module Register plus_function.source.return_type = Virtual::Integer plus_function.source.receiver = Virtual::Integer plus_function.source.add_code Register::OperatorInstruction.new( plus_function, :add , 0 , 0 ) - return plus_function end - # The conversion to base10 is quite a bit more complicated than i thought. - # The bulk of it is in div10 - # We set up variables, do the devision and write the result to the string - # then check if were done and recurse if neccessary - # As we write before we recurse (save a push) we write the number backwards - # arguments: string address , integer - # def utoa context - # utoa_function = Virtual::MethodSource.create_method(:Integer ,:utoa , [ Virtual::Integer ] ) - # function.source.return_type = Virtual::Integer - # function.source.receiver = Virtual::Integer - # return utoa_function - # # str_addr = utoa_function.receiver - # # number = utoa_function.args.first - # # remainder = utoa_function.new_local - # # Virtual::RegisterMachine.instance.div10( utoa_function , number , remainder ) - # # # make char out of digit (by using ascii encoding) 48 == "0" - # # utoa_function.instance_eval do - # # add( remainder , remainder , 48) - # # strb( remainder, str_addr ) - # # sub( str_addr, str_addr , 1 ) - # # cmp( number , 0 ) - # # callne( utoa_function ) - # # end - # # return utoa_function - # end + # The conversion to base10 is quite a bit more complicated than i thought. + # The bulk of it is in div10 + # We set up variables, do the devision and write the result to the string + # then check if were done and recurse if neccessary + # As we write before we recurse (save a push) we write the number backwards + # arguments: string address , integer + # def utoa context + # utoa_function = Virtual::MethodSource.create_method(:Integer ,:utoa , [ Virtual::Integer ] ) + # function.source.return_type = Virtual::Integer + # function.source.receiver = Virtual::Integer + # return utoa_function + # # str_addr = utoa_function.receiver + # # number = utoa_function.args.first + # # remainder = utoa_function.new_local + # # Virtual::RegisterMachine.instance.div10( utoa_function , number , remainder ) + # # # make char out of digit (by using ascii encoding) 48 == "0" + # # utoa_function.instance_eval do + # # add( remainder , remainder , 48) + # # strb( remainder, str_addr ) + # # sub( str_addr, str_addr , 1 ) + # # cmp( number , 0 ) + # # callne( utoa_function ) + # # end + # # return utoa_function + # end - def putint context - putint_function = Virtual::MethodSource.create_method(:Integer,:putint , [] ) - putint_function.source.return_type = Virtual::Integer - putint_function.source.receiver = Virtual::Integer - return putint_function - # buffer = Parfait::Word.new(" ") # create a buffer - # context.object_space.add_object buffer # and save it (function local variable: a no no) - # int = putint_function.receiver - # moved_int = putint_function.new_local - # utoa = context.object_space.get_class_by_name(:Object).resolve_method(:utoa) - # putint_function.instance_eval do - # mov( moved_int , int ) # move arg up - # add( int , buffer ,nil ) # string to write to (add string address to pc) - # add( int , int , buffer.length - 3) # 3 for good measure , ahem. - # call( utoa ) - # after = new_block("after_call") - # insert_at after - # # And now we "just" have to print it, using the write_stdout - # add( int , buffer , nil ) # string to write to - # mov( moved_int , buffer.length ) - # end - # Virtual::RegisterMachine.instance.write_stdout(putint_function) - # putint_function - end + def putint context + putint_function = Virtual::MethodSource.create_method(:Integer,:putint , [] ) + putint_function.source.return_type = Virtual::Integer + putint_function.source.receiver = Virtual::Integer + return putint_function + # buffer = Parfait::Word.new(" ") # create a buffer + # context.object_space.add_object buffer # and save it (function local variable: a no no) + # int = putint_function.receiver + # moved_int = putint_function.new_local + # utoa = context.object_space.get_class_by_name(:Object).resolve_method(:utoa) + # putint_function.instance_eval do + # mov( moved_int , int ) # move arg up + # add( int , buffer ,nil ) # string to write to (add string address to pc) + # add( int , int , buffer.length - 3) # 3 for good measure , ahem. + # call( utoa ) + # after = new_block("after_call") + # insert_at after + # # And now we "just" have to print it, using the write_stdout + # add( int , buffer , nil ) # string to write to + # mov( moved_int , buffer.length ) + # end + # Virtual::RegisterMachine.instance.write_stdout(putint_function) + # putint_function + end - # testing method, hand coded fibo, expects arg in receiver_register - # result comes in return_register - # a hand coded version of the fibonachi numbers - # not my hand off course, found in the net http://www.peter-cockerell.net/aalp/html/ch-5.html - def fibo context - fibo_function = Virtual::MethodSource.create_method(:Integer,:fibo , [] ) - fibo_function.source.return_type = Virtual::Integer - fibo_function.source.receiver = Virtual::Integer - return fibo_function - # result = fibo_function.return_type - # int = fibo_function.receiver - # - # last = fibo_function.new_block("return") - # - # f1 = fibo_function.new_local - # f2 = fibo_function.new_local - # - # fibo_function.instance_eval do - # cmp int , 1 - # mov( result, int , condition_code: :le) - # ble( last ) #branch to return, rather than return (as the original) - # mov f1 , 1 #set up initial values - # mov f2 , 0 - # end - # - # loop = fibo_function.new_block("loop") - # fibo_function.insert_at loop - # - # fibo_function.instance_eval do #loop through - # add f1 , f1 , f2 # f1 = f1 + f2 - # sub f2 , f1 , f2 # f2 = f1 -f2 - # sub int , int , 1 # todo: set.. should do below cmp, but doesn't , set_update_status: 1 - # cmp int , 1 - # bne( loop ) - # mov( result , f1 ) - # end - # - # fibo_function - end + # testing method, hand coded fibo, expects arg in receiver_register + # result comes in return_register + # a hand coded version of the fibonachi numbers + # not my hand off course, found in the net http://www.peter-cockerell.net/aalp/html/ch-5.html + def fibo context + fibo_function = Virtual::MethodSource.create_method(:Integer,:fibo , [] ) + fibo_function.source.return_type = Virtual::Integer + fibo_function.source.receiver = Virtual::Integer + return fibo_function + # result = fibo_function.return_type + # int = fibo_function.receiver + # + # last = fibo_function.new_block("return") + # + # f1 = fibo_function.new_local + # f2 = fibo_function.new_local + # + # fibo_function.instance_eval do + # cmp int , 1 + # mov( result, int , condition_code: :le) + # ble( last ) #branch to return, rather than return (as the original) + # mov f1 , 1 #set up initial values + # mov f2 , 0 + # end + # + # loop = fibo_function.new_block("loop") + # fibo_function.insert_at loop + # + # fibo_function.instance_eval do #loop through + # add f1 , f1 , f2 # f1 = f1 + f2 + # sub f2 , f1 , f2 # f2 = f1 -f2 + # sub int , int , 1 # todo: set.. should do below cmp, but doesn't , set_update_status: 1 + # cmp int , 1 + # bne( loop ) + # mov( result , f1 ) + # end + # + # fibo_function + end end extend ClassMethods end diff --git a/lib/virtual/boot.rb b/lib/virtual/boot.rb index 97d2791b..972985b8 100644 --- a/lib/virtual/boot.rb +++ b/lib/virtual/boot.rb @@ -160,8 +160,6 @@ module Virtual [:putint,:fibo , :plus].each do |f| obj.add_instance_method Register::Builtin::Integer.send(f , nil) end -# obj.alias :plus , :+ - end end end diff --git a/lib/virtual/passes/send_implementation.rb b/lib/virtual/passes/send_implementation.rb index b1b32b63..d34115da 100644 --- a/lib/virtual/passes/send_implementation.rb +++ b/lib/virtual/passes/send_implementation.rb @@ -32,9 +32,10 @@ module Virtual raise "Method not implemented #{me.class}.#{code.name}" unless method new_codes << MethodCall.new( method ) elsif( me.is_a? Fixnum ) - # get the function from my class. easy peasy - method = Virtual.machine.space.get_class_by_name(:Integer).get_instance_method(code.name) - raise "Method not implemented #{me.class}.#{code.name}" unless method + name = code.name + name = :plus if name == :+ + method = Virtual.machine.space.get_class_by_name(:Integer).get_instance_method(name) + raise "Method not implemented Integer.#{name}" unless method new_codes << MethodCall.new( method ) else # note: this is the current view: call internal send, even the method name says else