4Single VM instruction as it appears both in memory and on disk.
6Wire layout (21 bytes)::
16from __future__
import annotations
18from dataclasses
import dataclass, field
20from .OpCode
import OpCode
27 """A single Phasor VM instruction with an :class:`~phasor.OpCode.OpCode` and up to five ``int32`` operands.
29 Unused operands default to ``0``. The on-disk representation is always
30 :data:`_WIRE_SIZE` (21) bytes: one ``uint8`` opcode followed by five ``int32`` fields.
31 Prefer the factory class-methods (:meth:`halt`, :meth:`push_const`, etc.) for
32 common opcodes rather than constructing instances directly.
41 def halt(cls) -> "Instruction":
42 """Return a :attr:`~phasor.OpCode.OpCode.HALT` instruction."""
43 return cls(OpCode.HALT)
47 """Return a :attr:`~phasor.OpCode.OpCode.PUSH_CONST` instruction that pushes :attr:`Bytecode.constants[const_index] <phasor.Bytecode.Bytecode.constants>` onto the stack."""
48 return cls(OpCode.PUSH_CONST, const_index)
51 def load_var(cls, var_index: int) ->
"Instruction":
52 """Return a :attr:`~phasor.OpCode.OpCode.LOAD_VAR` instruction that pushes variable slot *var_index* onto the stack."""
53 return cls(OpCode.LOAD_VAR, var_index)
56 def store_var(cls, var_index: int) ->
"Instruction":
57 """Return a :attr:`~phasor.OpCode.OpCode.STORE_VAR` instruction that pops TOS into variable slot *var_index*."""
58 return cls(OpCode.STORE_VAR, var_index)
61 def call(cls, name_const_index: int, arg_count: int = 0) ->
"Instruction":
62 """Return a :attr:`~phasor.OpCode.OpCode.CALL` instruction.
65 name_const_index: Index into the constant pool where the function name string is stored.
66 arg_count: Number of arguments already pushed onto the stack (default ``0``).
68 return cls(OpCode.CALL, name_const_index, arg_count)
71 def jump(cls, offset: int) ->
"Instruction":
72 """Return a :attr:`~phasor.OpCode.OpCode.JUMP` instruction that unconditionally transfers control to instruction *offset*."""
73 return cls(OpCode.JUMP, offset)
77 """Return a :attr:`~phasor.OpCode.OpCode.JUMP_IF_FALSE` instruction that branches to *offset* and pops TOS when it is falsy."""
78 return cls(OpCode.JUMP_IF_FALSE, offset)
82 """Return a :attr:`~phasor.OpCode.OpCode.JUMP_IF_TRUE` instruction that branches to *offset* and pops TOS when it is truthy."""
83 return cls(OpCode.JUMP_IF_TRUE, offset)
86 """Return a concise debug representation showing the opcode name and non-zero operands."""
88 non_zero = [str(o)
for o
in ops
if o != 0]
89 suffix = (
", " +
", ".join(non_zero))
if non_zero
else ""
90 return f
"Instruction({self.op.name}{suffix})"
"Instruction" call(cls, int name_const_index, int arg_count=0)
"Instruction" load_var(cls, int var_index)
"Instruction" jump_if_true(cls, int offset)
"Instruction" jump_if_false(cls, int offset)
"Instruction" push_const(cls, int const_index)
"Instruction" jump(cls, int offset)
"Instruction" store_var(cls, int var_index)