Skip to main content

seq_runtime/variant_ops/
make.rs

1//! Variant constructor functions `patch_seq_make_variant_0` through
2//! `patch_seq_make_variant_12`: builds a tagged variant from a Symbol tag
3//! plus N field values popped off the stack.
4
5use crate::stack::{Stack, pop, push};
6use crate::value::Value;
7use std::sync::Arc;
8
9// ============================================================================
10// Type-safe variant constructors with fixed arity
11// Now accept Symbol as tag for dynamic variant construction (SON support)
12// ============================================================================
13
14/// Create a variant with 0 fields (just a tag)
15///
16/// Stack effect: ( Symbol -- Variant )
17///
18/// # Safety
19/// Stack must have at least one Symbol (the tag) on top
20#[unsafe(no_mangle)]
21pub unsafe extern "C" fn patch_seq_make_variant_0(stack: Stack) -> Stack {
22    use crate::value::VariantData;
23
24    unsafe {
25        let (stack, tag_val) = pop(stack);
26        let tag = match tag_val {
27            Value::Symbol(s) => s,
28            _ => panic!("make-variant-0: expected Symbol (tag), got {:?}", tag_val),
29        };
30
31        let variant = Value::Variant(Arc::new(VariantData::new(tag, vec![])));
32        push(stack, variant)
33    }
34}
35
36/// Create a variant with 1 field
37///
38/// Stack effect: ( field1 Symbol -- Variant )
39///
40/// # Safety
41/// Stack must have field1 and Symbol tag on top
42#[unsafe(no_mangle)]
43pub unsafe extern "C" fn patch_seq_make_variant_1(stack: Stack) -> Stack {
44    use crate::value::VariantData;
45
46    unsafe {
47        let (stack, tag_val) = pop(stack);
48        let tag = match tag_val {
49            Value::Symbol(s) => s,
50            _ => panic!("make-variant-1: expected Symbol (tag), got {:?}", tag_val),
51        };
52
53        let (stack, field1) = pop(stack);
54        let variant = Value::Variant(Arc::new(VariantData::new(tag, vec![field1])));
55        push(stack, variant)
56    }
57}
58
59/// Create a variant with 2 fields
60///
61/// Stack effect: ( field1 field2 Symbol -- Variant )
62///
63/// # Safety
64/// Stack must have field1, field2, and Symbol tag on top
65#[unsafe(no_mangle)]
66pub unsafe extern "C" fn patch_seq_make_variant_2(stack: Stack) -> Stack {
67    use crate::value::VariantData;
68
69    unsafe {
70        let (stack, tag_val) = pop(stack);
71        let tag = match tag_val {
72            Value::Symbol(s) => s,
73            _ => panic!("make-variant-2: expected Symbol (tag), got {:?}", tag_val),
74        };
75
76        let (stack, field2) = pop(stack);
77        let (stack, field1) = pop(stack);
78        let variant = Value::Variant(Arc::new(VariantData::new(tag, vec![field1, field2])));
79        push(stack, variant)
80    }
81}
82
83/// Create a variant with 3 fields
84///
85/// Stack effect: ( field1 field2 field3 Symbol -- Variant )
86///
87/// # Safety
88/// Stack must have field1, field2, field3, and Symbol tag on top
89#[unsafe(no_mangle)]
90pub unsafe extern "C" fn patch_seq_make_variant_3(stack: Stack) -> Stack {
91    use crate::value::VariantData;
92
93    unsafe {
94        let (stack, tag_val) = pop(stack);
95        let tag = match tag_val {
96            Value::Symbol(s) => s,
97            _ => panic!("make-variant-3: expected Symbol (tag), got {:?}", tag_val),
98        };
99
100        let (stack, field3) = pop(stack);
101        let (stack, field2) = pop(stack);
102        let (stack, field1) = pop(stack);
103        let variant = Value::Variant(Arc::new(VariantData::new(
104            tag,
105            vec![field1, field2, field3],
106        )));
107        push(stack, variant)
108    }
109}
110
111/// Create a variant with 4 fields
112///
113/// Stack effect: ( field1 field2 field3 field4 Symbol -- Variant )
114///
115/// # Safety
116/// Stack must have field1, field2, field3, field4, and Symbol tag on top
117#[unsafe(no_mangle)]
118pub unsafe extern "C" fn patch_seq_make_variant_4(stack: Stack) -> Stack {
119    use crate::value::VariantData;
120
121    unsafe {
122        let (stack, tag_val) = pop(stack);
123        let tag = match tag_val {
124            Value::Symbol(s) => s,
125            _ => panic!("make-variant-4: expected Symbol (tag), got {:?}", tag_val),
126        };
127
128        let (stack, field4) = pop(stack);
129        let (stack, field3) = pop(stack);
130        let (stack, field2) = pop(stack);
131        let (stack, field1) = pop(stack);
132        let variant = Value::Variant(Arc::new(VariantData::new(
133            tag,
134            vec![field1, field2, field3, field4],
135        )));
136        push(stack, variant)
137    }
138}
139
140/// Create a variant with 5 fields
141///
142/// Stack effect: ( field1 field2 field3 field4 field5 Symbol -- Variant )
143///
144/// # Safety
145/// Stack must have 5 fields and Symbol tag on top
146#[unsafe(no_mangle)]
147pub unsafe extern "C" fn patch_seq_make_variant_5(stack: Stack) -> Stack {
148    use crate::value::VariantData;
149
150    unsafe {
151        let (stack, tag_val) = pop(stack);
152        let tag = match tag_val {
153            Value::Symbol(s) => s,
154            _ => panic!("make-variant-5: expected Symbol (tag), got {:?}", tag_val),
155        };
156
157        let (stack, field5) = pop(stack);
158        let (stack, field4) = pop(stack);
159        let (stack, field3) = pop(stack);
160        let (stack, field2) = pop(stack);
161        let (stack, field1) = pop(stack);
162        let variant = Value::Variant(Arc::new(VariantData::new(
163            tag,
164            vec![field1, field2, field3, field4, field5],
165        )));
166        push(stack, variant)
167    }
168}
169
170/// Create a variant with 6 fields
171///
172/// Stack effect: ( field1 field2 field3 field4 field5 field6 Symbol -- Variant )
173///
174/// # Safety
175/// Stack must have 6 fields and Symbol tag on top
176#[unsafe(no_mangle)]
177pub unsafe extern "C" fn patch_seq_make_variant_6(stack: Stack) -> Stack {
178    use crate::value::VariantData;
179
180    unsafe {
181        let (stack, tag_val) = pop(stack);
182        let tag = match tag_val {
183            Value::Symbol(s) => s,
184            _ => panic!("make-variant-6: expected Symbol (tag), got {:?}", tag_val),
185        };
186
187        let (stack, field6) = pop(stack);
188        let (stack, field5) = pop(stack);
189        let (stack, field4) = pop(stack);
190        let (stack, field3) = pop(stack);
191        let (stack, field2) = pop(stack);
192        let (stack, field1) = pop(stack);
193        let variant = Value::Variant(Arc::new(VariantData::new(
194            tag,
195            vec![field1, field2, field3, field4, field5, field6],
196        )));
197        push(stack, variant)
198    }
199}
200
201/// Create a variant with 7 fields
202///
203/// Stack effect: ( field1 field2 field3 field4 field5 field6 field7 Symbol -- Variant )
204///
205/// # Safety
206/// Stack must have 7 fields and Symbol tag on top
207#[unsafe(no_mangle)]
208pub unsafe extern "C" fn patch_seq_make_variant_7(stack: Stack) -> Stack {
209    use crate::value::VariantData;
210
211    unsafe {
212        let (stack, tag_val) = pop(stack);
213        let tag = match tag_val {
214            Value::Symbol(s) => s,
215            _ => panic!("make-variant-7: expected Symbol (tag), got {:?}", tag_val),
216        };
217
218        let (stack, field7) = pop(stack);
219        let (stack, field6) = pop(stack);
220        let (stack, field5) = pop(stack);
221        let (stack, field4) = pop(stack);
222        let (stack, field3) = pop(stack);
223        let (stack, field2) = pop(stack);
224        let (stack, field1) = pop(stack);
225        let variant = Value::Variant(Arc::new(VariantData::new(
226            tag,
227            vec![field1, field2, field3, field4, field5, field6, field7],
228        )));
229        push(stack, variant)
230    }
231}
232
233/// Create a variant with 8 fields
234///
235/// Stack effect: ( field1 field2 field3 field4 field5 field6 field7 field8 Symbol -- Variant )
236///
237/// # Safety
238/// Stack must have 8 fields and Symbol tag on top
239#[unsafe(no_mangle)]
240pub unsafe extern "C" fn patch_seq_make_variant_8(stack: Stack) -> Stack {
241    use crate::value::VariantData;
242
243    unsafe {
244        let (stack, tag_val) = pop(stack);
245        let tag = match tag_val {
246            Value::Symbol(s) => s,
247            _ => panic!("make-variant-8: expected Symbol (tag), got {:?}", tag_val),
248        };
249
250        let (stack, field8) = pop(stack);
251        let (stack, field7) = pop(stack);
252        let (stack, field6) = pop(stack);
253        let (stack, field5) = pop(stack);
254        let (stack, field4) = pop(stack);
255        let (stack, field3) = pop(stack);
256        let (stack, field2) = pop(stack);
257        let (stack, field1) = pop(stack);
258        let variant = Value::Variant(Arc::new(VariantData::new(
259            tag,
260            vec![
261                field1, field2, field3, field4, field5, field6, field7, field8,
262            ],
263        )));
264        push(stack, variant)
265    }
266}
267
268/// Create a variant with 9 fields
269///
270/// Stack effect: ( field1 ... field9 Symbol -- Variant )
271///
272/// # Safety
273/// Stack must have 9 fields and Symbol tag on top
274#[unsafe(no_mangle)]
275pub unsafe extern "C" fn patch_seq_make_variant_9(stack: Stack) -> Stack {
276    use crate::value::VariantData;
277
278    unsafe {
279        let (stack, tag_val) = pop(stack);
280        let tag = match tag_val {
281            Value::Symbol(s) => s,
282            _ => panic!("make-variant-9: expected Symbol (tag), got {:?}", tag_val),
283        };
284
285        let (stack, field9) = pop(stack);
286        let (stack, field8) = pop(stack);
287        let (stack, field7) = pop(stack);
288        let (stack, field6) = pop(stack);
289        let (stack, field5) = pop(stack);
290        let (stack, field4) = pop(stack);
291        let (stack, field3) = pop(stack);
292        let (stack, field2) = pop(stack);
293        let (stack, field1) = pop(stack);
294        let variant = Value::Variant(Arc::new(VariantData::new(
295            tag,
296            vec![
297                field1, field2, field3, field4, field5, field6, field7, field8, field9,
298            ],
299        )));
300        push(stack, variant)
301    }
302}
303
304/// Create a variant with 10 fields
305///
306/// Stack effect: ( field1 ... field10 Symbol -- Variant )
307///
308/// # Safety
309/// Stack must have 10 fields and Symbol tag on top
310#[unsafe(no_mangle)]
311pub unsafe extern "C" fn patch_seq_make_variant_10(stack: Stack) -> Stack {
312    use crate::value::VariantData;
313
314    unsafe {
315        let (stack, tag_val) = pop(stack);
316        let tag = match tag_val {
317            Value::Symbol(s) => s,
318            _ => panic!("make-variant-10: expected Symbol (tag), got {:?}", tag_val),
319        };
320
321        let (stack, field10) = pop(stack);
322        let (stack, field9) = pop(stack);
323        let (stack, field8) = pop(stack);
324        let (stack, field7) = pop(stack);
325        let (stack, field6) = pop(stack);
326        let (stack, field5) = pop(stack);
327        let (stack, field4) = pop(stack);
328        let (stack, field3) = pop(stack);
329        let (stack, field2) = pop(stack);
330        let (stack, field1) = pop(stack);
331        let variant = Value::Variant(Arc::new(VariantData::new(
332            tag,
333            vec![
334                field1, field2, field3, field4, field5, field6, field7, field8, field9, field10,
335            ],
336        )));
337        push(stack, variant)
338    }
339}
340
341/// Create a variant with 11 fields
342///
343/// Stack effect: ( field1 ... field11 Symbol -- Variant )
344///
345/// # Safety
346/// Stack must have 11 fields and Symbol tag on top
347#[unsafe(no_mangle)]
348pub unsafe extern "C" fn patch_seq_make_variant_11(stack: Stack) -> Stack {
349    use crate::value::VariantData;
350
351    unsafe {
352        let (stack, tag_val) = pop(stack);
353        let tag = match tag_val {
354            Value::Symbol(s) => s,
355            _ => panic!("make-variant-11: expected Symbol (tag), got {:?}", tag_val),
356        };
357
358        let (stack, field11) = pop(stack);
359        let (stack, field10) = pop(stack);
360        let (stack, field9) = pop(stack);
361        let (stack, field8) = pop(stack);
362        let (stack, field7) = pop(stack);
363        let (stack, field6) = pop(stack);
364        let (stack, field5) = pop(stack);
365        let (stack, field4) = pop(stack);
366        let (stack, field3) = pop(stack);
367        let (stack, field2) = pop(stack);
368        let (stack, field1) = pop(stack);
369        let variant = Value::Variant(Arc::new(VariantData::new(
370            tag,
371            vec![
372                field1, field2, field3, field4, field5, field6, field7, field8, field9, field10,
373                field11,
374            ],
375        )));
376        push(stack, variant)
377    }
378}
379
380/// Create a variant with 12 fields
381///
382/// Stack effect: ( field1 ... field12 Symbol -- Variant )
383///
384/// # Safety
385/// Stack must have 12 fields and Symbol tag on top
386#[unsafe(no_mangle)]
387pub unsafe extern "C" fn patch_seq_make_variant_12(stack: Stack) -> Stack {
388    use crate::value::VariantData;
389
390    unsafe {
391        let (stack, tag_val) = pop(stack);
392        let tag = match tag_val {
393            Value::Symbol(s) => s,
394            _ => panic!("make-variant-12: expected Symbol (tag), got {:?}", tag_val),
395        };
396
397        let (stack, field12) = pop(stack);
398        let (stack, field11) = pop(stack);
399        let (stack, field10) = pop(stack);
400        let (stack, field9) = pop(stack);
401        let (stack, field8) = pop(stack);
402        let (stack, field7) = pop(stack);
403        let (stack, field6) = pop(stack);
404        let (stack, field5) = pop(stack);
405        let (stack, field4) = pop(stack);
406        let (stack, field3) = pop(stack);
407        let (stack, field2) = pop(stack);
408        let (stack, field1) = pop(stack);
409        let variant = Value::Variant(Arc::new(VariantData::new(
410            tag,
411            vec![
412                field1, field2, field3, field4, field5, field6, field7, field8, field9, field10,
413                field11, field12,
414            ],
415        )));
416        push(stack, variant)
417    }
418}