runmat_ignition/
instr.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4pub enum Instr {
5    LoadConst(f64),
6    LoadComplex(f64, f64),
7    LoadBool(bool),
8    LoadString(String),
9    LoadCharRow(String),
10    LoadVar(usize),
11    StoreVar(usize),
12    Add,
13    Sub,
14    Mul,
15    Div,
16    Pow,
17    Neg,
18    UPlus,
19    Transpose,
20    ConjugateTranspose,
21    // Element-wise operations
22    ElemMul,
23    ElemDiv,
24    ElemPow,
25    ElemLeftDiv,
26    LessEqual,
27    Less,
28    Greater,
29    GreaterEqual,
30    Equal,
31    NotEqual,
32    // Short-circuit logicals
33    AndAnd(usize), // jump target if lhs is false (0)
34    OrOr(usize),   // jump target if lhs is true (non-zero)
35    JumpIfFalse(usize),
36    Jump(usize),
37    Pop,
38    CallBuiltin(String, usize),
39    StochasticEvolution,
40    // User function call
41    CreateMatrix(usize, usize),
42    CreateMatrixDynamic(usize), // Number of rows, each row can have variable elements
43    CreateRange(bool),          // true if step is provided, false if start:end
44    Index(usize),               // Number of indices (all numeric)
45    // Matrix slicing with colon and end support:
46    // dims = total dims, numeric = how many numeric indices were pushed,
47    // colon_mask bit i set => dim i is colon (0-based),
48    // end_mask bit i set => dim i is plain 'end' (no arithmetic) and should resolve to that dim's length
49    IndexSlice(usize, usize, u32, u32),
50    // N-D range/selectors with per-dimension modes and end arithmetic offsets for ranges
51    // dims: total dims; numeric_count: count of extra numeric scalar indices following; colon_mask/end_mask like IndexSlice;
52    // range_dims: list of dimension indices that are ranges; for each, we expect start [, step] pushed in order; end_offsets align with range_dims
53    IndexRangeEnd {
54        dims: usize,
55        numeric_count: usize,
56        colon_mask: u32,
57        end_mask: u32,
58        range_dims: Vec<usize>,
59        range_has_step: Vec<bool>,
60        end_offsets: Vec<i64>,
61    },
62    // 1-D range with end arithmetic: base on stack, then start [, step]
63    Index1DRangeEnd {
64        has_step: bool,
65        offset: i64,
66    },
67    // Store with range+end arithmetic across dims; stack layout mirrors IndexRangeEnd plus RHS (on top)
68    StoreRangeEnd {
69        dims: usize,
70        numeric_count: usize,
71        colon_mask: u32,
72        end_mask: u32,
73        range_dims: Vec<usize>,
74        range_has_step: Vec<bool>,
75        end_offsets: Vec<i64>,
76    },
77    // Extended slice: supports end arithmetic per-numeric index via offsets list.
78    // Tuple items are (numeric_position_in_order, offset) representing 'end - offset'.
79    IndexSliceEx(usize, usize, u32, u32, Vec<(usize, i64)>),
80    // Cell arrays
81    CreateCell2D(usize, usize), // rows, cols; pops rows*cols elements
82    IndexCell(usize),           // Number of indices (1D or 2D supported)
83    // Expand cell array contents into a comma-separated list (column-major),
84    // pushing exactly out_count values onto the stack
85    IndexCellExpand(usize, usize), // (num_indices, out_count)
86    // L-value element assignments
87    StoreIndex(usize), // like Index, but pops RHS and updates base, then pushes updated base
88    StoreIndexCell(usize), // like IndexCell, but for cell arrays; pops RHS and updates base
89    // Store slice with colon/end semantics (mirrors IndexSlice)
90    StoreSlice(usize, usize, u32, u32),
91    // Store slice with end arithmetic offsets applied to numeric indices
92    StoreSliceEx(usize, usize, u32, u32, Vec<(usize, i64)>),
93    // Store with 1-D range having end arithmetic: base, start, [step], rhs
94    StoreSlice1DRangeEnd {
95        has_step: bool,
96        offset: i64,
97    },
98    // Object/Class member/method operations
99    LoadMember(String),        // base on stack -> member value
100    LoadMemberDynamic,         // base, name on stack -> member value (structs and objects)
101    StoreMember(String),       // base, rhs on stack -> updated base
102    StoreMemberDynamic,        // base, name, rhs on stack -> updated base
103    LoadMethod(String),        // base on stack -> method handle
104    CallMethod(String, usize), // base on stack along with args
105    // Closures and handle invocation
106    CreateClosure(String, usize), // function name and capture count; captures expected on stack
107    // Static class access
108    LoadStaticProperty(String, String),      // class, property
109    CallStaticMethod(String, String, usize), // class, method, argc
110    // Class definition at runtime
111    RegisterClass {
112        name: String,
113        super_class: Option<String>,
114        properties: Vec<(String, bool, String, String)>, // (name, is_static, get_access, set_access)
115        methods: Vec<(String, String, bool, String)>, // (method name, function name, is_static, access)
116    },
117    // feval special path to support closures/user functions/method handles
118    CallFeval(usize), // argc
119    // feval with expansion specs for arguments
120    CallFevalExpandMulti(Vec<ArgSpec>),
121    // Stack manipulation
122    Swap, // swap top two stack values
123    // Try/Catch control flow
124    EnterTry(usize, Option<usize>), // catch_pc, catch_var (global var index)
125    PopTry,                         // pop current try frame
126    Return,
127    ReturnValue,                 // Return with a value from the stack
128    CallFunction(String, usize), // Function name and argument count
129    // Call a user function and push `out_count` return values (left-to-right), if fewer available push 0
130    CallFunctionMulti(String, usize, usize),
131    CallBuiltinMulti(String, usize, usize),
132    // Call a user function with one argument (at position) expanded from a cell indexing expression
133    // (name, before_count, num_indices, after_count)
134    CallFunctionExpandAt(String, usize, usize, usize),
135    // Call a builtin with the last argument expanded from a cell indexing expression at runtime
136    // (name, fixed_argc (count of preceding fixed args), num_indices for the cell indexing)
137    CallBuiltinExpandLast(String, usize, usize),
138    // Call a builtin with one argument (at position) expanded from a cell indexing expression
139    // (name, before_count, num_indices, after_count)
140    CallBuiltinExpandAt(String, usize, usize, usize),
141    // Multi-arg expansion for user functions (parallel to builtin)
142    CallFunctionExpandMulti(String, Vec<ArgSpec>),
143    // Multi-arg expansion: specs vector corresponds to arguments in order.
144    // For each ArgSpec { is_expand, num_indices }:
145    // - if is_expand: pop indices (num_indices), then base; expand to value(s)
146    // - else: pop one fixed argument value
147    CallBuiltinExpandMulti(String, Vec<ArgSpec>),
148    // Pack N top-of-stack values into a 1xN row tensor (left-to-right)
149    PackToRow(usize),
150    // Pack N top-of-stack values into an Nx1 column tensor (top is last)
151    PackToCol(usize),
152    // Scoping and call stack instructions
153    EnterScope(usize), // Number of local variables to allocate
154    ExitScope(usize),  // Number of local variables to deallocate
155    LoadLocal(usize),  // Load from local variable (relative to current frame)
156    StoreLocal(usize), // Store to local variable (relative to current frame)
157    // Imports
158    RegisterImport {
159        path: Vec<String>,
160        wildcard: bool,
161    },
162    // Global and Persistent declarations
163    DeclareGlobal(Vec<usize>),
164    DeclarePersistent(Vec<usize>),
165    // New named variants to bind by source names across units
166    DeclareGlobalNamed(Vec<usize>, Vec<String>),
167    DeclarePersistentNamed(Vec<usize>, Vec<String>),
168}
169
170#[derive(Debug, Clone, Serialize, Deserialize)]
171pub struct ArgSpec {
172    pub is_expand: bool,
173    pub num_indices: usize,
174    pub expand_all: bool,
175}