Source code for pyrser.type_system.translator

from collections import *
from pyrser.type_system.fun import *
from pyrser import error


# for type translation
[docs]class Translator: """ Handle conversion from type_source to type_target thru a function. Do error.Notification if applyiable. """
[docs] def __str__(self) -> str: import pyrser.type_system.to_fmt return str(self.to_fmt())
[docs] def __init__(self, fun: Fun, notify: error.Notification=None): if not isinstance(fun, Fun): raise TypeError("1st parameter must be a type_system.Fun") if not isinstance(notify, error.Notification): raise TypeError("2nd parameter must be a error.Notification") if fun.arity < 1: raise TypeError( ("type_system.Fun in 1st parameter" + " must have an arity >= 1 (here %d)" ) % fun.arity ) self._type_source = fun.this_type self._type_target = fun.return_type self._fun = fun self._notify = notify
[docs] def __hash__(self) -> str: return self._type_target.__hash__()
@property def source(self) -> str: return self._type_source @property def target(self) -> str: return self._type_target @property def fun(self) -> Fun: return self._fun @property def notify(self) -> error.Notification: return self._notify
[docs]class MapTargetTranslate(dict): """ Handle all translation to one type """
[docs] def __str__(self) -> str: import pyrser.type_system.to_fmt return str(self.to_fmt())
[docs] def __init__(self): self._internal = {} self._type_source = None
@property def key(self) -> str: return self._type_source
[docs] def __len__(self) -> int: return len(self._internal)
[docs] def __delitem__(self, key: str): del self._internal[key]
[docs] def __contains__(self, key: str) -> bool: return key in self._internal
[docs] def __iter__(self) -> iter: return iter(self._internal)
def __reversed(self) -> reversed: return reversed(self._internal)
[docs] def __getitem__(self, key: str) -> Translator: return self._internal[key]
[docs] def __setitem__(self, key: str, val: Translator): if not isinstance(val, Translator): raise TypeError("value must be a Translator") if key != val.target: raise KeyError( ("Key:%s != Translator:%s," + " bad key of Translator") % (key, val.target) ) if self._type_source is None: self._type_source = val.source elif self._type_source != val.source: raise KeyError( ("Map.source:%s != Translator.source:%s," + " Translator incompatible with map" ) % (self._type_source, val._type_source) ) self._internal[key] = val # forward just for annotation (not the same id that final type)
class MapSourceTranslate: pass
[docs]class MapSourceTranslate(dict): """ Handle all conversions functions provide as Translator. """
[docs] def __str__(self) -> str: import pyrser.type_system.to_fmt return str(self.to_fmt())
[docs] def __init__(self): self._internal = ChainMap()
[docs] def set_parent(self, parent: MapSourceTranslate): tmp = self._internal self._internal = parent._internal.new_child() self._internal.maps[0].update(tmp)
[docs] def __len__(self) -> int: return len(self._internal)
[docs] def __delitem__(self, key: str): del self._internal[key]
[docs] def __contains__(self, key: str or tuple) -> bool: if isinstance(key, str): return key in self._internal if isinstance(key, tuple): return (key[0] in self._internal and key[1] in self._internal[key[0]] ) raise TypeError("parameter must be str or tuple")
[docs] def __iter__(self) -> iter: return iter(self._internal)
def __reversed(self) -> reversed: return reversed(self._internal)
[docs] def addTranslator(self, val: Translator, as_global=False): if not isinstance(val, Translator): raise TypeError("value must be a Translator") t1 = val.source t2 = val.target current_map = self._internal if as_global: current_map = self._internal.maps[-1] if t1 not in current_map: current_map[t1] = MapTargetTranslate() if t2 in current_map[t1]: raise KeyError("Mapping %s to %s already exist" % (t1, t2)) current_map[t1][t2] = val
[docs] def __getitem__(self, key: str) -> MapTargetTranslate: if key not in self._internal: self._internal[key] = MapTargetTranslate() return self._internal[key]
[docs] def __setitem__(self, key: str, val: MapTargetTranslate): if not isinstance(val, MapTargetTranslate): raise TypeError("value must be a MapTargetTranslate") if key != val.key: raise KeyError( ("Key:%s != Translator:%s," + " bad key of Translator") % (key, val.key) ) if val._type_source is None: val._type_source = key elif val._type_source != key: raise KeyError( ("MapSource.key:%s != MapTarget.source:%s," + " MapTarget incompatible with key" ) % (key, val._type_source) ) self._internal[key] = val