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