303 lines
9.4 KiB
Python
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" |