1
Files
lecture-interpreters/de.churl.simple/objmodel.py
Christoph 81e2dd0745 cleanup
2021-09-02 18:26:59 +02:00

153 lines
3.8 KiB
Python

from c3computation import compute_C3_mro as c3
class AbstractObject(object):
def __init__(self):
self.mark = False # gc marker
def call(self, w_receiver, args_w):
return self
def istrue(self):
return True
def clone(self):
raise NotImplementedError
def hasslot(self, value):
raise NotImplementedError
def getvalue(self, name):
for obj in self.get_mro():
if not obj.hasslot(name):
continue
return obj.slots[name]
def get_mro(self):
return c3(self)
class W_NormalObject(AbstractObject):
def __init__(self, name=None, slots=None, parents=None, space=None):
super().__init__()
self.space = space
self.name = name
if slots:
self.slots = slots
else:
self.slots = {}
if parents is None:
parents = []
if len(parents) > 0:
for x in parents:
assert x in slots
self.parents = parents
def getparents(self):
parents = self.parents
if '__parent__' not in parents:
parents.append('__parent__')
return [self.slots[p] for p in parents if p in self.slots]
def hasslot(self, name):
return name in self.slots
def setvalue(self, name, w_value):
self.slots[name] = w_value
def addparent(self, name):
self.parents.append(name)
def __str__(self):
return self.getname()
__repr__ = __str__
def getname(self):
return "<Object {name} {slots}>".format(
name=self.name if self.name else '',
slots=self.slots)
def clone(self):
return W_NormalObject(
name=self.name,
parents=self.parents,
slots=self.slots.copy())
# Project -----
class PrimitiveObject(AbstractObject):
def __init__(self, value, trait, space=None):
super().__init__()
self.value = value
self._trait = trait
self.space = space
def getparents(self):
if self.space is None:
return [] # for tests
trait = self.space.getbuiltin(self._trait)
assert trait is not None, 'O_o bogus state'
return [trait]
def hasslot(self, name):
return False
def __str__(self):
return str(self.value)
__repr__ = __str__
def istrue(self):
return bool(self.value)
class W_Integer(PrimitiveObject):
def __init__(self, value, space=None):
super().__init__(int(value), "inttrait", space=space)
class W_Boolean(PrimitiveObject):
def __init__(self, value, space=None):
super().__init__(int(value), "booltrait", space=space)
def __str__(self):
return str(bool(self.value)) # true instead of 1
__repr__ = __str__
class W_String(PrimitiveObject):
def __init__(self, value, space=None):
super().__init__(str(value), "strtrait", space=space)
class W_Double(PrimitiveObject):
def __init__(self, value, space=None):
super().__init__(float(value), "doubletrait", space=space)
# -------------
class W_Method(W_NormalObject):
def __init__(self, code, *args, **kwargs):
super(W_Method, self).__init__(*args, **kwargs)
self.code = code
def clone(self):
return W_Method(code=self.code,
name=self.name, parents=self.parents,
slots=self.slots.copy())
def getname(self):
return "<W_Method({name})>".format(name=self.name)
def call(self, w_receiver, args_w):
w_context = self.clone()
assert len(args_w) == self.code.numargs
for i in range(self.code.numargs):
self.space.setvalue(w_context, self.code.symbols[i], args_w[i])
self.space.setvalue(w_context, 'self', w_receiver)
return self.space.execute(w_context.code, w_context)