88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
from typing import Optional as O, Generic as G, Sequence, TypeVar, Any
|
|
from .base import Type, Context, PathElement, Error
|
|
from .io import Stream
|
|
from . import to_type
|
|
|
|
|
|
T = TypeVar('T')
|
|
|
|
class Wrapper(G[T], Type[T]):
|
|
def __init__(self, child: Type[T]) -> None:
|
|
self.child = child
|
|
|
|
def parse(self, context: Context, stream: Stream) -> T:
|
|
return context.parse(to_type(self.child), stream)
|
|
|
|
def dump(self, context: Context, stream: Stream, value: O[T]) -> None:
|
|
context.dump(to_type(self.child), stream, value)
|
|
|
|
def sizeof(self, context: Context, value: O[T]) -> O[int]:
|
|
return context.sizeof(to_type(self.child), value)
|
|
|
|
def offsetof(self, context: Context, path: Sequence[PathElement], value: O[T]) -> O[int]:
|
|
return context.offsetof(to_type(self.child), path, value)
|
|
|
|
def default(self, context: Context) -> T:
|
|
return context.default(to_type(self.child))
|
|
|
|
def __str__(self) -> str:
|
|
return str(self.child)
|
|
|
|
def __repr__(self) -> str:
|
|
return repr(self.child)
|
|
|
|
class Generic(Type):
|
|
__slots__ = ('name', 'stack')
|
|
|
|
def __init__(self, name: str) -> None:
|
|
self.name = name
|
|
self.stack = []
|
|
|
|
def push(self, value: Any) -> None:
|
|
if isinstance(value, Generic):
|
|
self.stack.append(value.stack[-1])
|
|
else:
|
|
self.stack.append(value)
|
|
|
|
def pop(self) -> None:
|
|
self.stack.pop()
|
|
|
|
def _get_sx_type_(self, ident: Any) -> Type:
|
|
return to_type(self.stack[-1])
|
|
|
|
def parse(self, context: Context, stream: Stream) -> Any:
|
|
if not self.stack:
|
|
raise Error(context, 'unresolved generic')
|
|
return context.parse(to_type(self.stack[-1]), stream)
|
|
|
|
def dump(self, context: Context, stream: Stream, value: O[Any]) -> None:
|
|
if not self.stack:
|
|
raise Error(context, 'unresolved generic')
|
|
context.dump(to_type(self.stack[-1]), stream, value)
|
|
|
|
def sizeof(self, context: Context, value: O[Any]) -> O[int]:
|
|
if not self.stack:
|
|
return None
|
|
return context.sizeof(to_type(self.stack[-1]), value)
|
|
|
|
def offsetof(self, context: Context, path: Sequence[PathElement], value: O[Any]) -> O[int]:
|
|
if not self.stack:
|
|
return None
|
|
return context.offsetof(to_type(self.stack[-1]), path, value)
|
|
|
|
def default(self, context: Context) -> Any:
|
|
if not self.stack:
|
|
raise Error(context, 'unresolved generic')
|
|
return context.default(to_type(self.stack[-1]))
|
|
|
|
def __str__(self) -> str:
|
|
if self.stack:
|
|
return f'${self.name}:{to_type(self.stack[-1])}'
|
|
return f'${self.name}:unresolved'
|
|
|
|
def __repr__(self) -> str:
|
|
return f'<{__name__}.{self.__class__.__name__}({self.stack!r})>'
|
|
|
|
def __deepcopy__(self, memo: Any) -> Any:
|
|
return self
|