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