WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

Commit aa5e2d0d authored by Stefan Marr's avatar Stefan Marr
Browse files

Move primitives to top level and make sure they are not closures


Signed-off-by: default avatarStefan Marr <git@stefan-marr.de>
parent d3108714
......@@ -6,6 +6,9 @@ class Interpreter(object):
self._universe = universe
self._frame = None
def get_universe(self):
return self._universe
def _do_dup(self):
# Handle the dup bytecode
self.get_frame().push(self.get_frame().get_stack_element(0))
......
from som.vmobjects.primitive import Primitive
from som.primitives.primitives import Primitives
class ArrayPrimitives(Primitives):
def install_primitives(self):
def _at(ivkbl, frame, interpreter):
def _at(ivkbl, frame, interpreter):
i = frame.pop()
rcvr = frame.pop()
frame.push(rcvr.get_indexable_field(i.get_embedded_integer() - 1))
self._install_instance_primitive(Primitive("at:", self._universe, _at))
def _atPut(ivkbl, frame, interpreter):
def _atPut(ivkbl, frame, interpreter):
value = frame.pop()
index = frame.pop()
rcvr = frame.get_stack_element(0)
rcvr.set_indexable_field(index.get_embedded_integer() - 1, value)
self._install_instance_primitive(Primitive("at:put:", self._universe, _atPut))
def _length(ivkbl, frame, interpreter):
def _length(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(self._universe.new_integer(rcvr.get_number_of_indexable_fields()))
self._install_instance_primitive(Primitive("length", self._universe, _length))
frame.push(interpreter.get_universe().new_integer(rcvr.get_number_of_indexable_fields()))
def _new(ivkbl, frame, interpreter):
def _new(ivkbl, frame, interpreter):
length = frame.pop()
frame.pop() # not required
frame.push(self._universe.new_array_with_length(length.get_embedded_integer()))
frame.push(interpreter.get_universe().new_array_with_length(length.get_embedded_integer()))
class ArrayPrimitives(Primitives):
def install_primitives(self):
self._install_instance_primitive(Primitive("at:", self._universe, _at))
self._install_instance_primitive(Primitive("at:put:", self._universe, _atPut))
self._install_instance_primitive(Primitive("length", self._universe, _length))
self._install_class_primitive(Primitive("new:", self._universe, _new))
......@@ -4,102 +4,104 @@ from som.vmobjects.integer import integer_value_fits
import math
class BigIntegerPrimitives(Primitives):
def install_primitives(self):
def _asString(ivkbl, frame, interpreter):
def _asString(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(self._universe.new_string(str(rcvr.get_embedded_biginteger())))
self._install_instance_primitive(Primitive("asString", self._universe, _asString))
frame.push(interpreter.get_universe().new_string(str(rcvr.get_embedded_biginteger())))
def _sqrt(ivkbl, frame, interpreter):
def _sqrt(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(self._universe.new_double(
frame.push(interpreter.get_universe().new_double(
math.sqrt(rcvr.get_embedded_biginteger())))
self._install_instance_primitive(Primitive("sqrt", self._universe, _sqrt))
def _plus(ivkbl, frame, interpreter):
def _plus(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() + right_obj.get_embedded_value()
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
frame.push(interpreter.get_universe().new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
self._install_instance_primitive(Primitive("+", self._universe, _plus))
frame.push(interpreter.get_universe().new_biginteger(result))
def _minus(ivkbl, frame, interpreter):
def _minus(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() - right_obj.get_embedded_value()
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
frame.push(interpreter.get_universe().new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
self._install_instance_primitive(Primitive("-", self._universe, _minus))
frame.push(interpreter.get_universe().new_biginteger(result))
def _mult(ivkbl, frame, interpreter):
def _mult(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() * right_obj.get_embedded_value()
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
frame.push(interpreter.get_universe().new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
self._install_instance_primitive(Primitive("*", self._universe, _mult))
frame.push(interpreter.get_universe().new_biginteger(result))
def _div(ivkbl, frame, interpreter):
def _div(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() / right_obj.get_embedded_value()
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
frame.push(interpreter.get_universe().new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
self._install_instance_primitive(Primitive("/", self._universe, _div))
frame.push(interpreter.get_universe().new_biginteger(result))
def _mod(ivkbl, frame, interpreter):
def _mod(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Do operation:
frame.push(self._universe.new_biginteger(left.get_embedded_biginteger() % right_obj.get_embedded_value()))
self._install_instance_primitive(Primitive("%", self._universe, _mod))
frame.push(interpreter.get_universe().new_biginteger(left.get_embedded_biginteger() % right_obj.get_embedded_value()))
def _and(ivkbl, frame, interpreter):
def _and(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Do operation:
frame.push(self._universe.new_biginteger(left.get_embedded_biginteger() & right_obj.get_embedded_value()))
self._install_instance_primitive(Primitive("&", self._universe, _and))
frame.push(interpreter.get_universe().new_biginteger(left.get_embedded_biginteger() & right_obj.get_embedded_value()))
def _equals(ivkbl, frame, interpreter):
def _equals(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Do operation:
if left.get_embedded_biginteger() == right_obj.get_embedded_value():
frame.push(self._universe.trueObject)
frame.push(interpreter.get_universe().trueObject)
else:
frame.push(self._universe.falseObject)
self._install_instance_primitive(Primitive("=", self._universe, _equals))
frame.push(interpreter.get_universe().falseObject)
def _lessThan(ivkbl, frame, interpreter):
def _lessThan(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Do operation:
if left.get_embedded_biginteger() < right_obj.get_embedded_value():
frame.push(self._universe.trueObject)
frame.push(interpreter.get_universe().trueObject)
else:
frame.push(self._universe.falseObject)
frame.push(interpreter.get_universe().falseObject)
class BigIntegerPrimitives(Primitives):
def install_primitives(self):
self._install_instance_primitive(Primitive("asString", self._universe, _asString))
self._install_instance_primitive(Primitive("sqrt", self._universe, _sqrt))
self._install_instance_primitive(Primitive("+", self._universe, _plus))
self._install_instance_primitive(Primitive("-", self._universe, _minus))
self._install_instance_primitive(Primitive("*", self._universe, _mult))
self._install_instance_primitive(Primitive("/", self._universe, _div))
self._install_instance_primitive(Primitive("%", self._universe, _mod))
self._install_instance_primitive(Primitive("&", self._universe, _and))
self._install_instance_primitive(Primitive("=", self._universe, _equals))
self._install_instance_primitive(Primitive("<", self._universe, _lessThan))
from som.primitives.primitives import Primitives
from som.vmobjects.primitive import Primitive
def _restart(ivkbl, frame, interpreter):
frame.set_bytecode_index(0)
frame.reset_stack_pointer()
class BlockPrimitives(Primitives):
def install_primitives(self):
def _restart(ivkbl, frame, interpreter):
frame.set_bytecode_index(0)
frame.reset_stack_pointer()
self._install_instance_primitive(Primitive("restart", self._universe, _restart))
......@@ -2,9 +2,10 @@ from som.primitives.primitives import Primitives
from som.vmobjects.primitive import Primitive
def _new(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(interpreter.get_universe().new_instance(rcvr))
class ClassPrimitives(Primitives):
def install_primitives(self):
def _new(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(self._universe.new_instance(rcvr))
self._install_instance_primitive(Primitive("new", self._universe, _new))
\ No newline at end of file
......@@ -5,75 +5,75 @@ from som.vmobjects.integer import Integer
import math
class DoublePrimitives(Primitives):
def _coerce_to_double(self, obj):
def _coerce_to_double(obj, universe):
if isinstance(obj, Double):
return obj
if isinstance(obj, Integer):
return self._universe.new_double(obj.get_embedded_integer())
return universe.new_double(obj.get_embedded_integer())
raise ValueError("Cannot coerce %s to Double!" % obj)
def install_primitives(self):
def _asString(ivkbl, frame, interpreter):
def _asString(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(self._universe.new_string(str(rcvr.get_embedded_double())))
self._install_instance_primitive(Primitive("asString", self._universe, _asString))
frame.push(interpreter.get_universe().new_string(str(rcvr.get_embedded_double())))
def _sqrt(ivkbl, frame, interpreter):
def _sqrt(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(self._universe.new_double(math.sqrt(rcvr.get_embedded_double())))
self._install_instance_primitive(Primitive("sqrt", self._universe, _sqrt))
frame.push(interpreter.get_universe().new_double(math.sqrt(rcvr.get_embedded_double())))
def _plus(ivkbl, frame, interpreter):
op1 = self._coerce_to_double(frame.pop())
def _plus(ivkbl, frame, interpreter):
op1 = _coerce_to_double(frame.pop(), interpreter.get_universe())
op2 = frame.pop()
frame.push(self._universe.new_double(op1.get_embedded_double()
frame.push(interpreter.get_universe().new_double(op1.get_embedded_double()
+ op2.get_embedded_double()))
self._install_instance_primitive(Primitive("+", self._universe, _plus))
def _minus(ivkbl, frame, interpreter):
op1 = self._coerce_to_double(frame.pop())
def _minus(ivkbl, frame, interpreter):
op1 = _coerce_to_double(frame.pop(), interpreter.get_universe())
op2 = frame.pop()
frame.push(self._universe.new_double(op2.get_embedded_double()
frame.push(interpreter.get_universe().new_double(op2.get_embedded_double()
- op1.get_embedded_double()))
self._install_instance_primitive(Primitive("-", self._universe, _minus))
def _mult(ivkbl, frame, interpreter):
op1 = self._coerce_to_double(frame.pop())
def _mult(ivkbl, frame, interpreter):
op1 = _coerce_to_double(frame.pop(), interpreter.get_universe())
op2 = frame.pop()
frame.push(self._universe.new_double(op2.get_embedded_double()
frame.push(interpreter.get_universe().new_double(op2.get_embedded_double()
* op1.get_embedded_double()))
self._install_instance_primitive(Primitive("*", self._universe, _mult))
def _doubleDiv(ivkbl, frame, interpreter):
op1 = self._coerce_to_double(frame.pop())
def _doubleDiv(ivkbl, frame, interpreter):
op1 = _coerce_to_double(frame.pop(), interpreter.get_universe())
op2 = frame.pop()
frame.push(self._universe.new_double(op2.get_embedded_double()
frame.push(interpreter.get_universe().new_double(op2.get_embedded_double()
/ op1.get_embedded_double()))
self._install_instance_primitive(Primitive("//", self._universe, _doubleDiv))
def _mod(ivkbl, frame, interpreter):
op1 = self._coerce_to_double(frame.pop())
def _mod(ivkbl, frame, interpreter):
op1 = _coerce_to_double(frame.pop(), interpreter.get_universe())
op2 = frame.pop()
frame.push(self._universe.new_double(op2.get_embedded_double()
frame.push(interpreter.get_universe().new_double(op2.get_embedded_double()
% op1.get_embedded_double()))
self._install_instance_primitive(Primitive("%", self._universe, _mod))
def _equals(ivkbl, frame, interpreter):
op1 = self._coerce_to_double(frame.pop())
def _equals(ivkbl, frame, interpreter):
op1 = _coerce_to_double(frame.pop(), interpreter.get_universe())
op2 = frame.pop()
if op1.get_embedded_double() == op2.get_embedded_double():
frame.push(self._universe.trueObject)
frame.push(interpreter.get_universe().trueObject)
else:
frame.push(self._universe.falseObject)
self._install_instance_primitive(Primitive("=", self._universe, _equals))
frame.push(interpreter.get_universe().falseObject)
def _lessThan(ivkbl, frame, interpreter):
op1 = self._coerce_to_double(frame.pop())
def _lessThan(ivkbl, frame, interpreter):
op1 = _coerce_to_double(frame.pop(), interpreter.get_universe())
op2 = frame.pop()
if op2.get_embedded_double() < op1.get_embedded_double():
frame.push(self._universe.trueObject)
frame.push(interpreter.get_universe().trueObject)
else:
frame.push(self._universe.falseObject)
frame.push(interpreter.get_universe().falseObject)
class DoublePrimitives(Primitives):
def install_primitives(self):
self._install_instance_primitive(Primitive("asString", self._universe, _asString))
self._install_instance_primitive(Primitive("sqrt", self._universe, _sqrt))
self._install_instance_primitive(Primitive("+", self._universe, _plus))
self._install_instance_primitive(Primitive("-", self._universe, _minus))
self._install_instance_primitive(Primitive("*", self._universe, _mult))
self._install_instance_primitive(Primitive("//", self._universe, _doubleDiv))
self._install_instance_primitive(Primitive("%", self._universe, _mod))
self._install_instance_primitive(Primitive("=", self._universe, _equals))
self._install_instance_primitive(Primitive("<", self._universe, _lessThan))
......@@ -7,196 +7,198 @@ from som.vmobjects.double import Double
import math
import random
class IntegerPrimitives(Primitives):
def _push_long_result(self, frame, result):
def _push_long_result(frame, result, universe):
# Check with integer bounds and push:
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
frame.push(universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
frame.push(universe.new_biginteger(result))
def _resend_as_biginteger(self, operator, left, right):
left_biginteger = self._universe.new_biginteger(left.get_embedded_integer())
def _resend_as_biginteger(operator, left, right, universe):
left_biginteger = universe.new_biginteger(left.get_embedded_integer())
operands = [right]
left_biginteger.send(operator, operands, self._universe, self._universe.get_interpreter())
left_biginteger.send(operator, operands, universe, universe.get_interpreter())
def _resend_as_double(self, operator, left, right):
left_double = self._universe.new_double(left.get_embedded_integer())
def _resend_as_double(operator, left, right, universe):
left_double = universe.new_double(left.get_embedded_integer())
operands = [right]
left_double.send(operator, operands, self._universe, self._universe.get_interpreter())
left_double.send(operator, operands, universe, universe.get_interpreter())
def install_primitives(self):
def _asString(ivkbl, frame, interpreter):
def _asString(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(self._universe.new_string(str(rcvr.get_embedded_integer())))
self._install_instance_primitive(Primitive("asString", self._universe, _asString))
frame.push(interpreter.get_universe().new_string(str(rcvr.get_embedded_integer())))
def _sqrt(ivkbl, frame, interpreter):
def _sqrt(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(self._universe.new_double(math.sqrt(rcvr.get_embedded_integer())))
self._install_instance_primitive(Primitive("sqrt", self._universe, _sqrt))
frame.push(interpreter.get_universe().new_double(math.sqrt(rcvr.get_embedded_integer())))
def _atRandom(ivkbl, frame, interpreter):
def _atRandom(ivkbl, frame, interpreter):
rcvr = frame.pop()
frame.push(self._universe.new_integer(rcvr.get_embedded_integer() * random.random()))
self._install_instance_primitive(Primitive("atRandom", self._universe, _atRandom))
frame.push(interpreter.get_universe().new_integer(rcvr.get_embedded_integer() * random.random()))
def _plus(ivkbl, frame, interpreter):
def _plus(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Check second parameter type:
if isinstance(right_obj, BigInteger):
# Second operand was BigInteger
self._resend_as_biginteger("+", left, right_obj)
_resend_as_biginteger("+", left, right_obj, interpreter.get_universe())
elif isinstance(right_obj, Double):
self._resend_as_double("+", left, right_obj)
_resend_as_double("+", left, right_obj, interpreter.get_universe())
else:
# Do operation:
right = right_obj
result = left.get_embedded_integer() + right.get_embedded_integer()
self._push_long_result(frame, result)
self._install_instance_primitive(Primitive("+", self._universe, _plus))
_push_long_result(frame, result, interpreter.get_universe())
def _minus(ivkbl, frame, interpreter):
def _minus(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Check second parameter type:
if isinstance(right_obj, BigInteger):
# Second operand was BigInteger
self._resend_as_biginteger("-", left, right_obj)
_resend_as_biginteger("-", left, right_obj, interpreter.get_universe())
elif isinstance(right_obj, Double):
self._resend_as_double("-", left, right_obj)
_resend_as_double("-", left, right_obj, interpreter.get_universe())
else:
# Do operation:
right = right_obj
result = left.get_embedded_integer() - right.get_embedded_integer()
self._push_long_result(frame, result)
self._install_instance_primitive(Primitive("-", self._universe, _minus))
_push_long_result(frame, result, interpreter.get_universe())
def _mult(ivkbl, frame, interpreter):
def _mult(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Check second parameter type:
if isinstance(right_obj, BigInteger):
# Second operand was BigInteger
self._resend_as_biginteger("*", left, right_obj)
_resend_as_biginteger("*", left, right_obj, interpreter.get_universe())
elif isinstance(right_obj, Double):
self._resend_as_double("*", left, right_obj)
_resend_as_double("*", left, right_obj, interpreter.get_universe())
else:
# Do operation:
right = right_obj
result = left.get_embedded_integer() * right.get_embedded_integer()
self._push_long_result(frame, result)
self._install_instance_primitive(Primitive("*", self._universe, _mult))
_push_long_result(frame, result, interpreter.get_universe())
def _doubleDiv(ivkbl, frame, interpreter):
def _doubleDiv(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Check second parameter type:
if isinstance(right_obj, BigInteger):
# Second operand was BigInteger
self._resend_as_biginteger("/", left, right_obj)
_resend_as_biginteger("/", left, right_obj, interpreter.get_universe())
elif isinstance(right_obj, Double):
self._resend_as_double("/", left, right_obj)
_resend_as_double("/", left, right_obj, interpreter.get_universe())
else:
# Do operation:
right = right_obj
result = float(left.get_embedded_integer()) / float(right.get_embedded_integer())
frame.push(self._universe.new_double(result))
self._install_instance_primitive(Primitive("//", self._universe, _doubleDiv))
frame.push(interpreter.get_universe().new_double(result))
def _intDiv(ivkbl, frame, interpreter):
def _intDiv(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Check second parameter type:
if isinstance(right_obj, BigInteger):
# Second operand was BigInteger
self._resend_as_biginteger("/", left, right_obj)
_resend_as_biginteger("/", left, right_obj, interpreter.get_universe())
elif isinstance(right_obj, Double):
self._resend_as_double("/", left, right_obj)
_resend_as_double("/", left, right_obj, interpreter.get_universe())
else:
# Do operation:
right = right_obj
result = left.get_embedded_integer() / right.get_embedded_integer()
self._push_long_result(frame, result)
self._install_instance_primitive(Primitive("/", self._universe, _intDiv))
_push_long_result(frame, result, interpreter.get_universe())
def _mod(ivkbl, frame, interpreter):
def _mod(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Check second parameter type:
if isinstance(right_obj, BigInteger):
# Second operand was BigInteger
self._resend_as_biginteger("%", left, right_obj)
_resend_as_biginteger("%", left, right_obj, interpreter.get_universe())
elif isinstance(right_obj, Double):
self._resend_as_double("%", left, right_obj)
_resend_as_double("%", left, right_obj, interpreter.get_universe())
else:
# Do operation:
self._push_long_result(frame, left.get_embedded_integer() % right_obj.get_embedded_integer())
self._install_instance_primitive(Primitive("%", self._universe, _mod))
_push_long_result(frame, left.get_embedded_integer() % right_obj.get_embedded_integer(), interpreter.get_universe())
def _and(ivkbl, frame, interpreter):
def _and(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Check second parameter type:
if isinstance(right_obj, BigInteger):
# Second operand was BigInteger
self._resend_as_biginteger("&", left, right_obj)
_resend_as_biginteger("&", left, right_obj, interpreter.get_universe())
elif isinstance(right_obj, Double):
self._resend_as_double("&", left, right_obj)
_resend_as_double("&", left, right_obj, interpreter.get_universe())
else:
# Do operation:
right = right_obj
result = left.get_embedded_integer() & right.get_embedded_integer()
self._push_long_result(frame, result)
self._install_instance_primitive(Primitive("&", self._universe, _and))
_push_long_result(frame, result, interpreter.get_universe())
def _equals(ivkbl, frame, interpreter):
def _equals(ivkbl, frame, interpreter):
right_obj = frame.pop()
left = frame.pop()
# Check second parameter type:
if isinstance(right_obj, BigInteger):
# Second operand was BigInteger
self._resend_as_biginteger("=", left, right_obj)
_resend_as_biginteger("=", left, right_obj, interpreter.get_universe())
elif isinstance(right_obj, Integer):
if left.get_embedded_integer() == right_obj.get_embedded_integer():
frame.push(self._universe.trueObject)
frame.push(interpreter.get_universe().trueObject)
else:
frame.push(self._universe.falseObject)
frame.push