abstract CallStatement base class, just like in ruby
to_mom differs much more than the to_vool in ruby, but data and base functionality still warrent unification also we can check for CallStatement now
This commit is contained in:
parent
198a43cc8d
commit
1d2ec8e8ac
31
lib/vool/call_statement.rb
Normal file
31
lib/vool/call_statement.rb
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
module Vool
|
||||||
|
|
||||||
|
class CallStatement < Statement
|
||||||
|
attr_reader :name , :receiver , :arguments
|
||||||
|
|
||||||
|
def initialize(name , receiver , arguments )
|
||||||
|
@name , @receiver , @arguments = name , receiver , arguments
|
||||||
|
@arguments ||= []
|
||||||
|
end
|
||||||
|
|
||||||
|
# When used as right hand side, this tells what data to move to get the result into
|
||||||
|
# a varaible. It is (off course) the return value of the message
|
||||||
|
def slot_definition(compiler)
|
||||||
|
Mom::SlotDefinition.new(:message ,[ :return_value])
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s(depth = 0)
|
||||||
|
sen = "#{receiver}.#{name}(#{@arguments.collect{|a| a.to_s}.join(', ')})"
|
||||||
|
at_depth(depth , sen)
|
||||||
|
end
|
||||||
|
|
||||||
|
def each(&block)
|
||||||
|
block.call(self)
|
||||||
|
block.call(@receiver)
|
||||||
|
@arguments.each do |arg|
|
||||||
|
block.call(arg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
@ -9,13 +9,8 @@ module Vool
|
|||||||
#
|
#
|
||||||
# As cache key we must use the type of the object (which is the first word of _every_ object)
|
# As cache key we must use the type of the object (which is the first word of _every_ object)
|
||||||
# as that is constant, and function implementations depend on the type (not class)
|
# as that is constant, and function implementations depend on the type (not class)
|
||||||
class SendStatement < Statement
|
class SendStatement < CallStatement
|
||||||
attr_reader :name , :receiver , :arguments , :block
|
attr_reader :block
|
||||||
|
|
||||||
def initialize(name , receiver , arguments )
|
|
||||||
@name , @receiver , @arguments = name , receiver , arguments
|
|
||||||
@arguments ||= []
|
|
||||||
end
|
|
||||||
|
|
||||||
def block
|
def block
|
||||||
return nil if arguments.empty?
|
return nil if arguments.empty?
|
||||||
@ -27,15 +22,8 @@ module Vool
|
|||||||
@arguments << block
|
@arguments << block
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s
|
|
||||||
"#{receiver}.#{name}(#{arguments.join(', ')})"
|
|
||||||
end
|
|
||||||
def each(&block)
|
def each(&block)
|
||||||
block.call(self)
|
super
|
||||||
block.call(@receiver)
|
|
||||||
@arguments.each do |arg|
|
|
||||||
block.call(arg)
|
|
||||||
end
|
|
||||||
self.block.each(&block) if self.block
|
self.block.each(&block) if self.block
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -56,12 +44,6 @@ module Vool
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# When used as right hand side, this tells what data to move to get the result into
|
|
||||||
# a varaible. It is (off course) the return value of the message
|
|
||||||
def slot_definition(compiler)
|
|
||||||
Mom::SlotDefinition.new(:message ,[ :return_value])
|
|
||||||
end
|
|
||||||
|
|
||||||
def message_setup(compiler,called_method)
|
def message_setup(compiler,called_method)
|
||||||
setup = Mom::MessageSetup.new( called_method )
|
setup = Mom::MessageSetup.new( called_method )
|
||||||
mom_receive = @receiver.slot_definition(compiler)
|
mom_receive = @receiver.slot_definition(compiler)
|
||||||
|
@ -65,6 +65,7 @@ require_relative "assignment"
|
|||||||
require_relative "array_statement"
|
require_relative "array_statement"
|
||||||
require_relative "basic_values"
|
require_relative "basic_values"
|
||||||
require_relative "block_statement"
|
require_relative "block_statement"
|
||||||
|
require_relative "call_statement"
|
||||||
require_relative "class_statement"
|
require_relative "class_statement"
|
||||||
require_relative "hash_statement"
|
require_relative "hash_statement"
|
||||||
require_relative "if_statement"
|
require_relative "if_statement"
|
||||||
|
@ -1,34 +1,17 @@
|
|||||||
module Vool
|
module Vool
|
||||||
|
|
||||||
class YieldStatement < Statement
|
# A Yield is a lot like a Send, which is why they share the base class CallStatement
|
||||||
attr_reader :arguments
|
# That means it has a receiver (self), arguments and an (implicitly assigned) name
|
||||||
|
#
|
||||||
|
# On the ruby side, normalisation works pretty much the same too.
|
||||||
|
#
|
||||||
|
# On the way down to Mom, small differences become abvious, as the block that is
|
||||||
|
# yielded to is an argument. Whereas in a send it is either statically known
|
||||||
|
# or resolved and cached. Here it is dynamic, but sort of known dynamic.
|
||||||
|
# All we do before calling it is check that it is the right type.
|
||||||
|
class YieldStatement < CallStatement
|
||||||
|
|
||||||
def initialize(name , receiver , arguments)
|
# A Yield breaks down to 2 steps:
|
||||||
@arguments = arguments
|
|
||||||
@receiver = receiver
|
|
||||||
@name = name
|
|
||||||
@arguments ||= []
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"#{receiver}.#{name}(#{arguments.join(', ')})"
|
|
||||||
end
|
|
||||||
|
|
||||||
def each(&block)
|
|
||||||
block.call(self)
|
|
||||||
block.call(@receiver)
|
|
||||||
@arguments.each do |arg|
|
|
||||||
block.call(arg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# When used as right hand side, this tells what data to move to get the result into
|
|
||||||
# a varaible. It is (off course) the return value of the message
|
|
||||||
def slot_definition(compiler)
|
|
||||||
Mom::SlotDefinition.new(:message ,[ :return_value])
|
|
||||||
end
|
|
||||||
|
|
||||||
# A Send breaks down to 2 steps:
|
|
||||||
# - Setting up the next message, with receiver, arguments, and (importantly) return address
|
# - Setting up the next message, with receiver, arguments, and (importantly) return address
|
||||||
# - a SimpleCall,
|
# - a SimpleCall,
|
||||||
def to_mom( compiler )
|
def to_mom( compiler )
|
||||||
@ -76,10 +59,5 @@ module Vool
|
|||||||
setup << Mom::BlockYield.new( arg_index )
|
setup << Mom::BlockYield.new( arg_index )
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_s(depth = 0)
|
|
||||||
sen = "#{receiver}.#{name}(#{@arguments.collect{|a| a.to_s}.join(', ')})"
|
|
||||||
at_depth(depth , sen)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user