from typing import Any
from typing import Dict
from typing import List
from typing import Optional
from typing import Tuple
from typing import Type
from typing import Union
from typing import cast
from pymavryk.context.abstract import AbstractContext
from pymavryk.michelson.micheline import Micheline
from pymavryk.michelson.stack import MichelsonStack
[docs]class Wildcard:
[docs] @staticmethod
def n(count: int) -> List['Wildcard']:
return [Wildcard() for _ in range(count)]
def __repr__(self):
return '*'
[docs]def dispatch_types(
*args: Type[Micheline],
mapping: Dict[Tuple[Type[Micheline], ...], Tuple[Any, ...]],
):
key = tuple(arg.prim for arg in args)
mapping = {tuple(arg.prim for arg in k): v for k, v in mapping.items()} # type: ignore
assert key in mapping, f'unexpected types `{" * ".join(key)}`' # type: ignore
return mapping[key] # type: ignore
[docs]class MichelsonInstruction(Micheline):
args: List[Union[Type['MichelsonInstruction'], Any]] = []
field_names: List[str] = []
var_names: List[str] = []
def __init__(self, stack_items_added: int = 0) -> None:
self.stack_items_added = stack_items_added
[docs] @staticmethod
def match(expr) -> Type['MichelsonInstruction']:
return cast(Type['MichelsonInstruction'], Micheline.match(expr))
[docs] @classmethod
def create_type(
cls,
args: List[Type['Micheline']],
annots: Optional[list] = None,
**kwargs,
) -> Type['MichelsonInstruction']:
if annots:
field_names = [a[1:] for a in annots if a.startswith('%')]
var_names = [a[1:] for a in annots if a.startswith('@')]
else:
field_names, var_names = [], []
res = type(
cls.__name__,
(cls,),
{
'args': args,
'field_names': field_names,
'var_names': var_names,
**kwargs,
},
)
return cast(Type['MichelsonInstruction'], res)
[docs] @classmethod
def as_micheline_expr(cls) -> dict:
annots = []
if cls.var_names is not None:
annots.extend([f'@{x}' for x in cls.var_names])
if cls.field_names is not None:
annots.extend([f'%{x}' for x in cls.field_names])
args = [arg.as_micheline_expr() for arg in cls.args]
expr = {'prim': cls.prim, 'annots': annots, 'args': args}
return {k: v for k, v in expr.items() if v}
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
raise NotImplementedError