From 265b25d5f4cd44d0912f860a66e32186bf163594 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Fri, 14 Apr 2017 21:01:50 +0300 Subject: [PATCH] introduce return_sequence instruction to mom --- lib/mom/instruction.rb | 1 + lib/mom/return_sequence.rb | 24 ++++++++++++++++++++++++ lib/vool/statements/return_statement.rb | 6 +++--- test/vool/to_mom/test_return.rb | 8 +++++++- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 lib/mom/return_sequence.rb diff --git a/lib/mom/instruction.rb b/lib/mom/instruction.rb index 5782d144..0c3609cf 100644 --- a/lib/mom/instruction.rb +++ b/lib/mom/instruction.rb @@ -7,3 +7,4 @@ module Mom end require_relative "slot_load" +require_relative "return_sequence" diff --git a/lib/mom/return_sequence.rb b/lib/mom/return_sequence.rb new file mode 100644 index 00000000..7850a7cd --- /dev/null +++ b/lib/mom/return_sequence.rb @@ -0,0 +1,24 @@ +module Mom + + # The ReturnSequence models the return from a method. + # + # This involves the jump to the return address stored in the message, and + # the reinstantiation of the previous message. + # + # The machine (mom) only ever "knows" one message, the current message. + # Messages are a double linked list, calling involves going forward, + # returning means going back. + # + # The return value of the current message is transferred into the return value of the + # callers return value during the swap of messages, and just before the jump. + # + # The callers perspective of a call is the magical apperance of a return_value + # in it's message at the instruction after the call. + # + # The instruction is not parameterized as it translates to a constant + # set of lower level instructions. + # + class ReturnSequence < Instruction + end + +end diff --git a/lib/vool/statements/return_statement.rb b/lib/vool/statements/return_statement.rb index 5f33895e..076691a7 100644 --- a/lib/vool/statements/return_statement.rb +++ b/lib/vool/statements/return_statement.rb @@ -13,10 +13,10 @@ module Vool # To return form a method in mom instructions we need to do three things: # - store the given return value, this is a SlotMove / SlotConstant - # - restore the previous message - # - jump to the return address + # - activate return sequence (reinstantiate old message and jump to return address) def to_mom( method ) - [Mom::SlotConstant.new([:message , :return_value] , @return_value)] + [Mom::SlotConstant.new([:message , :return_value] , @return_value) , + Mom::ReturnSequence.new] end end diff --git a/test/vool/to_mom/test_return.rb b/test/vool/to_mom/test_return.rb index 27b07756..43a08259 100644 --- a/test/vool/to_mom/test_return.rb +++ b/test/vool/to_mom/test_return.rb @@ -15,10 +15,16 @@ module Vool def test_slot_is_set assert @stats.first.left end + def test_two_instructions_are_returned + assert_equal 2 , @stats.length + end + def test_second_is_return + assert_equal Mom::ReturnSequence, @stats.last.class + end def test_slot_starts_at_message assert_equal :message , @stats.first.left[0] end - def test_slot_gets_self + def test_slot_gets_return assert_equal :return_value , @stats.first.left[1] end def test_slot_assigns_something