Phasor 3.1.1
Stack VM based Programming Language
Loading...
Searching...
No Matches
Instruction.py
Go to the documentation of this file.
1"""
2phasor.Instruction
3==================
4Single VM instruction as it appears both in memory and on disk.
5
6Wire layout (21 bytes)::
7
8 opcode : uint8
9 operand1 : int32
10 operand2 : int32
11 operand3 : int32
12 operand4 : int32
13 operand5 : int32
14"""
15
16from __future__ import annotations
17
18from dataclasses import dataclass, field
19
20from .OpCode import OpCode
21
22_WIRE_SIZE = 21 # bytes on disk
23
24
25@dataclass
27 """A single Phasor VM instruction with an :class:`~phasor.OpCode.OpCode` and up to five ``int32`` operands.
28
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.
33 """
34
35 op: OpCode
36 operand1: int = 0
37 operand2: int = 0
38 operand3: int = 0
39
40 @classmethod
41 def halt(cls) -> "Instruction":
42 """Return a :attr:`~phasor.OpCode.OpCode.HALT` instruction."""
43 return cls(OpCode.HALT)
44
45 @classmethod
46 def push_const(cls, const_index: int) -> "Instruction":
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)
49
50 @classmethod
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)
54
55 @classmethod
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)
59
60 @classmethod
61 def call(cls, name_const_index: int, arg_count: int = 0) -> "Instruction":
62 """Return a :attr:`~phasor.OpCode.OpCode.CALL` instruction.
63
64 Args:
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``).
67 """
68 return cls(OpCode.CALL, name_const_index, arg_count)
69
70 @classmethod
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)
74
75 @classmethod
76 def jump_if_false(cls, offset: int) -> "Instruction":
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)
79
80 @classmethod
81 def jump_if_true(cls, offset: int) -> "Instruction":
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)
84
85 def __repr__(self) -> str:
86 """Return a concise debug representation showing the opcode name and non-zero operands."""
87 ops = [self.operand1, self.operand2, self.operand3]
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)