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}