Commit e58e8bd2 authored by Stefan Marr's avatar Stefan Marr

Removed block instance variables from language, and slightly optimized the...

Removed block instance variables from language, and slightly optimized the evaluation primitive handling
Signed-off-by: default avatarStefan Marr <git@stefan-marr.de>
parent a3adc27e
Subproject commit 692cfb135a04b47a2393cbae7c7b72f4d8c0869e
Subproject commit 52591c6d7c559f3bd4d783ba81c6e63181b9ac39
......@@ -3,51 +3,32 @@ from som.vmobjects.primitive import Primitive
class Block(Object):
METHOD_INDEX = Object.NUMBER_OF_OBJECT_FIELDS
CONTEXT_INDEX = 1 + METHOD_INDEX
NUMBER_OF_BLOCK_FIELDS = 1 + CONTEXT_INDEX
NUMBER_OF_BLOCK_FIELDS = Object.NUMBER_OF_OBJECT_FIELDS
_immutable_fields_ = ["_method", "_context"]
def __init__(self, nilObject, method, context):
Object.__init__(self, nilObject)
self._number_of_arguments = 0
self._set_method(method)
self._set_context(context)
self._method = method
self._context = context
def get_method(self):
# Get the method of this block by reading the field with method index
return self.get_field(self.METHOD_INDEX)
def _set_method(self, value):
# Set the method of this block by writing to the field with method index
self.set_field(self.METHOD_INDEX, value)
return self._method
def get_context(self):
# Get the context of this block by reading the field with context index
return self.get_field(self.CONTEXT_INDEX)
def _set_context(self, value):
# Set the context of this block by writing to the field with context index
return self.set_field(self.CONTEXT_INDEX, value)
return self._context
def _get_default_number_of_fields(self):
# Return the default number of fields for a block
return self.NUMBER_OF_BLOCK_FIELDS
class Evaluation(Primitive):
def __init__(self, num_args, universe):
def _invoke(ivkbl, frame, interpreter):
# Get the block (the receiver) from the stack
rcvr = frame.get_stack_element(ivkbl._number_of_arguments - 1)
# Get the context of the block...
context = rcvr.get_context()
# Push a new frame and set its context to be the one specified in
# the block
new_frame = interpreter.push_new_frame(rcvr.get_method(), context)
new_frame.copy_arguments_from(frame)
Primitive.__init__(self, self._compute_signature_string(num_args), universe, _invoke)
def __init__(self, num_args, universe, invoke):
Primitive.__init__(self, self._compute_signature_string(num_args),
universe, invoke)
self._number_of_arguments = num_args
def _compute_signature_string(self, num_args):
......@@ -55,13 +36,25 @@ class Block(Object):
signature_string = "value"
if num_args > 1:
signature_string += ":"
# Add extra value: selector elements if necessary
for _ in range(2, num_args):
signature_string += "with:"
if num_args > 2:
# Add extra with: selector elements if necessary
signature_string += "with:" * (num_args - 2)
# Return the signature string
return signature_string
def block_evaluation_primitive(num_args, universe):
return Block.Evaluation(num_args, universe)
return Block.Evaluation(num_args, universe, _invoke)
def _invoke(ivkbl, frame, interpreter):
# Get the block (the receiver) from the stack
assert isinstance(ivkbl, Block.Evaluation)
rcvr = frame.get_stack_element(ivkbl._number_of_arguments - 1)
# Get the context of the block...
context = rcvr.get_context()
# Push a new frame and set its context to be the one specified in
# the block
new_frame = interpreter.push_new_frame(rcvr.get_method(), context)
new_frame.copy_arguments_from(frame)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment