4in-memory representation of a compiled
8from __future__
import annotations
10from dataclasses
import dataclass, field
11from pathlib
import Path
12from typing
import Dict, List, Optional
14from .Instruction
import Instruction
15from .OpCode
import OpCode
16from .Value
import Value
21 """In-memory representation of a compiled Phasor program.
23 Holds all data needed to run or serialise the program: the instruction
24 stream, the constant pool, the variable name→slot mapping, function entry
25 points, and the next free variable slot counter.
28 instructions: Ordered list of :class:`~phasor.Instruction.Instruction` objects forming the program.
29 constants: Constant pool; entries are indexed by :attr:`~phasor.OpCode.OpCode.PUSH_CONST` / :attr:`~phasor.OpCode.OpCode.LOAD_CONST_R`.
30 variables: Maps each variable name to its integer slot index.
31 function_entries: Maps each function name to the index of its first instruction.
32 next_var_index: Next available variable slot; serialised as part of the variables section.
35 instructions: List[Instruction] = field(default_factory=list)
36 constants: List[Value] = field(default_factory=list)
37 variables: Dict[str, int] = field(default_factory=dict)
38 function_entries: Dict[str, int] = field(default_factory=dict)
39 next_var_index: int = 0
42 """Append *value* to the constant pool and return its index."""
48 """Return the index of an existing equal constant, or add a new one."""
55 """Return the slot index for *name*, creating it if absent."""
62 op1: int = 0, op2: int = 0, op3: int = 0) -> int:
63 """Append a new :class:`~phasor.Instruction.Instruction` to :attr:`instructions` and return its index.
66 op: The :class:`~phasor.OpCode.OpCode` for this instruction.
67 op1 … op5: Operand values; unused operands should be left as ``0``.
70 The zero-based index of the newly appended instruction.
76 """Overwrite ``operand1`` of the instruction at *instr_index* in-place.
78 Typically used to back-patch forward-jump offsets after the jump target
82 instr_index: Index into :attr:`instructions` of the instruction to patch.
83 value: New value for ``operand1``.
87 def save(self, path: Path | str) ->
None:
88 """Serialise this object and write it to a ``.phsb`` file at *path*.
90 Delegates to :class:`~phasor.Serializer.BytecodeSerializer`.
92 from .Serializer
import BytecodeSerializer
96 def load(cls, path: Path | str) ->
"Bytecode":
97 """Read a ``.phsb`` file at *path* and return a deserialised :class:`Bytecode`.
99 Delegates to :class:`~phasor.Deserializer.BytecodeDeserializer`.
101 from .Deserializer
import BytecodeDeserializer
106 """Deserialise a :class:`Bytecode` from a raw ``.phsb`` byte buffer.
108 Delegates to :class:`~phasor.Deserializer.BytecodeDeserializer`.
110 from .Deserializer
import BytecodeDeserializer
114 """Serialise this object to a raw ``.phsb`` byte buffer.
116 Delegates to :class:`~phasor.Serializer.BytecodeSerializer`.
118 from .Deserializer
import BytecodeSerializer
123 """Extract and deserialise bytecode from an ELF/PE/MachO binary's ``.phsb`` section."""
124 from .Native
import extract_phsb_bytes
125 raw = extract_phsb_bytes(Path(path))
129 """Return a human-readable disassembly of :attr:`instructions`.
131 Function entry points from :attr:`function_entries` are printed as
132 ``<function name>:`` labels above their first instruction.
134 lines: List[str] = []
138 lines.append(f
"\n<function {name}>:")
139 ops = [instr.operand1, instr.operand2, instr.operand3,
140 instr.operand4, instr.operand5]
141 non_zero = [str(o)
for o
in ops
if o != 0]
142 operands = (
" " +
", ".join(non_zero))
if non_zero
else ""
143 lines.append(f
" {i:>4} {instr.op.name:<20}{operands}")
144 return "\n".join(lines)
147 """Return a summary showing instruction, constant, variable, and function counts."""
150 f
"{len(self.instructions)} instructions, "
151 f
"{len(self.constants)} constants, "
152 f
"{len(self.variables)} variables, "
153 f
"{len(self.function_entries)} functions)"
int find_or_add_constant(self, Value value)
None patch_operand1(self, int instr_index, int value)
"Bytecode" from_bytes(cls, bytes|bytearray data)
"Bytecode" from_native_binary(cls, Path|str path)
"Bytecode" load(cls, Path|str path)
int add_constant(self, Value value)
None save(self, Path|str path)
int emit(self, OpCode op, int op1=0, int op2=0, int op3=0)
int get_or_create_var(self, str name)