from typing import List
from typing import Tuple
from typing import Type
from typing import cast
from pymavryk.context.abstract import AbstractContext
from pymavryk.michelson.instructions.base import MichelsonInstruction
from pymavryk.michelson.instructions.base import Wildcard
from pymavryk.michelson.instructions.base import format_stdout
from pymavryk.michelson.micheline import Micheline
from pymavryk.michelson.stack import MichelsonStack
from pymavryk.michelson.types.base import MichelsonType
[docs]class PushInstruction(MichelsonInstruction, prim='PUSH', args_len=2):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
res_type, literal = cast(Tuple[Type[MichelsonType], Type[Micheline]], cls.args)
assert res_type.is_pushable(), f'{res_type.prim} contains non-pushable arguments'
res = res_type.from_literal(literal)
stack.push(res)
stdout.append(format_stdout(cls.prim, [], [res])) # type: ignore
return cls(stack_items_added=1)
[docs]class DropnInstruction(MichelsonInstruction, prim='DROP', args_len=1):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
count = cls.args[0].get_int() # type: ignore
dropped = stack.pop(count=count)
stdout.append(format_stdout(cls.prim, dropped, [], count)) # type: ignore
return cls()
[docs]class DropInstruction(MichelsonInstruction, prim='DROP'):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
dropped = stack.pop1()
stdout.append(format_stdout(cls.prim, [dropped], [])) # type: ignore
return cls()
[docs]class DupnInstruction(MichelsonInstruction, prim='DUP', args_len=1):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
depth = cls.args[0].get_int() - 1 # type: ignore
stack.protect(count=depth)
res = stack.peek().duplicate()
stack.restore(count=depth)
stack.push(res)
stdout.append(format_stdout(cls.prim, [*Wildcard.n(depth), res], [res, *Wildcard.n(depth), res], depth)) # type: ignore
return cls(stack_items_added=1)
[docs]class DupInstruction(MichelsonInstruction, prim='DUP'):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
res = stack.peek().duplicate()
stack.push(res)
stdout.append(format_stdout(cls.prim, [res], [res, res])) # type: ignore
return cls(stack_items_added=1)
[docs]class SwapInstruction(MichelsonInstruction, prim='SWAP'):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
a, b = stack.pop2()
stack.push(a)
stack.push(b)
stdout.append(format_stdout(cls.prim, [a, b], [b, a])) # type: ignore
return cls(stack_items_added=2)
[docs]class DigInstruction(MichelsonInstruction, prim='DIG', args_len=1):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
depth = cls.args[0].get_int() # type: ignore
stack.protect(count=depth)
res = stack.pop1()
stack.restore(count=depth)
stack.push(res)
stdout.append(format_stdout(cls.prim, [*Wildcard.n(depth), res], [res, *Wildcard.n(depth)], depth)) # type: ignore
return cls(stack_items_added=1)
[docs]class DugInstruction(MichelsonInstruction, prim='DUG', args_len=1):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
depth = cls.args[0].get_int() # type: ignore
res = stack.pop1()
stack.protect(count=depth)
stack.push(res)
stack.restore(count=depth)
stdout.append(format_stdout(cls.prim, [res, *Wildcard.n(depth)], [*Wildcard.n(depth), res], depth)) # type: ignore
return cls(stack_items_added=1)
[docs]class CastIntruction(MichelsonInstruction, prim='CAST', args_len=1):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
res = stack.pop1()
# TODO: will become obsolete in the next protocol? (because annots are no longer part of the type)
# cast_type = cast(Type[MichelsonType], cls.args[0])
# res = cast_type.from_micheline_value(top.to_micheline_value())
stack.push(res)
stdout.append(format_stdout(cls.prim, [res], [res])) # type: ignore
return cls(stack_items_added=1)
[docs]class RenameInstruction(MichelsonInstruction, prim='RENAME'):
[docs] @classmethod
def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
return cls()