DSM/arden_types.py

303 lines
9.4 KiB
Python

from abc import ABC, abstractmethod
from datetime import date
class BaseType(ABC):
@abstractmethod
def __str__(self):
pass
def __init__(self):
self.time = NullType(False)
def __repr__(self):
return str(self)
#def __eq__(self,b):
# return BoolType(str(type(self).__name__) is b)
def __and__(self,other):
if isinstance(other, StrType):
return StrType(str(self) + str(other))
return NullType()
def IS(self,b,invert=False):
if b is type(self):
return BoolType(True)
return BoolType(False)
def NOT(self,b,invert=False):
return NullType()
def ISNOT(self,b,invert=False):
return ~self.IS(b)
def LISTACCESS(self,b):
return NullType()
def TIME(self):
return self.time
def WHERE(self,other):
if isinstance(other, ListType):
return ListType([self for b_item in other.value if b_item.value==True])
if isinstance(other, BoolType) and other:
return self
return NullType()
class NumType(BaseType):
def __init__(self, value: (int, float)):
super().__init__()
if isinstance(value, str):
try:
value = int(value)
except ValueError:
value = float(value)
if not isinstance(value, (int, float)):
raise TypeError(f"Expected a number, got {type(value)}")
self.value = value
def __mul__(self,other):
if isinstance(other, NumType):
return NumType(self.value * other.value)
if isinstance(other, ListType):
return ListType([item * self for item in other.value])
return NullType()
def __truediv__(self,other):
if isinstance(other, NumType):
return NumType(self.value / other.value)
if isinstance(other, ListType):
return ListType([item / self for item in other.value])
return NullType()
def __add__(self,other):
if isinstance(other, NumType):
return NumType(self.value + other.value)
return NullType()
def __sub__(self,other):
if isinstance(other, NumType):
return NumType(self.value - other.value)
return NullType()
def __gt__(self, other):
if isinstance(other, NumType):
return BoolType(self.value > other.value)
return NullType()
def __lt__(self, other):
if isinstance(other, NumType):
return BoolType(self.value < other.value)
return NullType()
def __ge__(self, other):
if isinstance(other, NumType):
return BoolType(self.value >= other.value)
if isinstance(other, ListType):
return ListType([self >= item for item in other.value])
return NullType()
def __le__(self, other):
if isinstance(other, NumType):
return BoolType(self.value <= other.value)
if isinstance(other, ListType):
return ListType([self <= item for item in other.value])
return NullType()
def __pow__(self, other):
if isinstance(other, NumType):
return NumType(self.value ** other.value)
return NullType()
def __neg__(self):
return NumType(-self.value)
def __str__(self):
return str(self.value)
def IS(self,b,invert=False):
if b is type(self):
return BoolType(True)
if type(b) is self:
return BoolType(self.value == b.value)
if type(b) is Condition:
return b.value(self)
return BoolType(False)
class StrType(BaseType):
def __init__(self, value: str):
super().__init__()
if not isinstance(value, str):
raise TypeError(f"Expected a string, got {type(value)}")
self.value = value
def __and__(self,other):
return StrType(str(self) + str(other))
def __str__(self):
return self.value
class BoolType(BaseType):
def __init__(self, value: bool):
super().__init__()
if not isinstance(value, bool):
raise TypeError(f"Expected a boolean, got {type(value)}")
self.value = value
def __eq__(self, other):
return self.value == other.value
def __bool__(self):
return self.value
def __invert__(self):
return BoolType(not self.value)
def __str__(self):
if self.value:
return "true"
else:
return "false"
def __and__(self,other):
if isinstance(other, BoolType):
return BoolType(self.value and other.value)
return NullType()
def NOT(self):
return ~self
class ListType(BaseType):
def __init__(self, value: list):
super().__init__()
if not isinstance(value, list):
raise TypeError(f"Expected a list, got {type(value)}")
self.value = value
def __str__(self):
return f"[{', '.join(str(item) for item in self.value)}]"
def __gt__(self, other):
if isinstance(other, NumType):
return ListType([item > other for item in self.value])
return NullType()
def __lt__(self, other):
if isinstance(other, NumType):
return ListType([item < other for item in self.value])
return NullType()
def __ge__(self, other):
if isinstance(other, NumType):
return ListType([item >= other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item >= b_item for a_item, b_item in zip(self.value, other.value)])
return NullType()
def __le__(self, other):
if isinstance(other, NumType):
return ListType([item <= other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item <= b_item for a_item, b_item in zip(self.value, other.value)])
return NullType()
def __and__(self,other):
if isinstance(other, BoolType) or isinstance(other, NumType):
return ListType([item and other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item and b_item for a_item, b_item in zip(self.value, other.value)])
return NullType()
def __or__(self,other):
if isinstance(other, BoolType) or isinstance(other, NumType):
return ListType([item or other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item or b_item for a_item, b_item in zip(self.value, other.value)])
return NullType()
def __truediv__(self,other):
if isinstance(other, NumType):
return ListType([item / other for item in self.value])
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item / b_item for a_item, b_item in zip(self.value, other.value)])
return NullType()
def WHERE(self,other):
if isinstance(other, ListType) and len(self.value) == len(other.value):
return ListType([a_item for a_item, b_item in zip(self.value, other.value) if b_item.value==True])
if isinstance(other, BoolType) and other:
return self
return NullType()
def IS(self,a,invert=False):
if a is NumType:
return ListType([item.IS(a) for item in self.value])
if a is type(self):
return BoolType(True^invert)
if type(a) is Condition:
return a.value(self)
else:
return BoolType(False^invert)
def OCCURS(self,a):
if type(a) is Condition:
return ListType([a.value(item.time) for item in self.value])
def NOT(self):
return ListType([~item for item in self.value])
def LISTACCESS(self,a):
if type(a) is NumType:
return self.value[a.value]
return NullType()
def LISTINDEXASSIGN(self,a,b):
if type(a) is NumType:
self.value[a.value-1] = b
#self.value.insert(a.value,b)
return NullType()
def TIME(self):
return ListType([item.time for item in self.value])
class DateType(BaseType):
def __init__(self, value: date):
super().__init__()
if not isinstance(value, date):
raise TypeError(f"Expected a date, got {type(value)}")
self.value = value
def __gt__(self, other):
if isinstance(other, DateType):
return BoolType(self.value > other.value)
return NullType()
def __lt__(self, other):
if isinstance(other, DateType):
return BoolType(self.value < other.value)
return NullType()
def __str__(self):
return self.value.strftime('%Y-%m-%dT%H:%M:%S')
class Condition(BaseType):
def __init__(self, condition):
self.value = condition
def __and__(self, other):
return Condition(lambda x: self.value(x) and other.value(x))
def __or__(self,other):
return Condition(lambda x: self.value(x) or other.value(x))
def __str__(self):
return str(self.value)
class NullType(BaseType):
def __init__(self, has_time=True):
if has_time:
super().__init__()
def __str__(self):
return "Null"