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}