1use std::collections::HashMap;
4use std::fmt::{Display, Formatter};
5use std::sync::{Arc, RwLock, mpsc::Sender};
6use bitvec::prelude::*;
7use malachite::{Natural, Rational};
8use malachite::base::num::basic::traits::{Zero, One};
9use regex::{Regex, RegexBuilder};
10
11#[derive(Debug)]
12pub enum Value {
13 B(BitVec<usize, Lsb0>),
14 N(Rational),
15 S(String),
16 A(Vec<Value>)
17}
18impl Default for Value {
19 fn default() -> Self {
20 Self::A(Vec::new())
21 }
22}
23
24impl Drop for Value {
26 fn drop(&mut self) {
27 use Value::*;
28 use std::mem::take;
29 if let A(a) = self {
30 let mut q: Vec<Vec<Value>> = vec![take(a)]; while let Some(mut a) = q.pop() {
32 for v in &mut a { if let A(aa) = v { q.push(take(aa)) }
36 }
37 }
39 }
40 }
42}
43
44impl Clone for Value {
46 fn clone(&self) -> Self {
47 use Value::*;
48 match self {
49 B(b) => B(b.clone()),
51 N(n) => N(n.clone()),
52 S(s) => S(s.clone()),
53 A(_) => unsafe { crate::fns::exec1(|v, _| Ok(v.clone()), self, false).unwrap_unchecked() } }
57 }
58}
59
60impl Value {
61 unsafe fn display_scalar(&self, k: usize, o: &Natural, nm: NumOutMode, sb: bool) -> String {
63 use Value::*;
64 match self {
65 B(b) => {
66 b.iter().by_vals().map(|b| if b {'T'} else {'F'}).collect()
67 },
68 N(n) => {
69 use crate::num::*;
70 use NumOutMode::*;
71 match nm {
72 Auto => {
73 nauto(n, k, o)
74 },
75 Norm => {
76 let (neg, ipart, fpart, rpart) = digits(n, k, o);
77 nnorm(neg, &ipart, &fpart, &rpart, o)
78 },
79 Sci => {
80 let (neg, ipart, fpart, rpart) = digits(n, k, o);
81 nsci(neg, &ipart, &fpart, &rpart, o)
82 },
83 Frac => {
84 nfrac(n, k, o)
85 },
86 }
87 },
88 S(s) => {
89 if sb {
90 String::from("[") + s + "]"
91 }
92 else {
93 s.to_owned()
94 }
95 },
96 A(_) => {
97 unsafe { std::hint::unreachable_unchecked() }
98 }
99 }
100 }
101
102 pub fn display(&self, k: usize, o: &Natural, nm: NumOutMode, sb: bool) -> String {
104 use Value::*;
105 match self {
106 A(a) => { let mut stk: Vec<std::slice::Iter<Value>> = vec![a.iter()];
108 let mut res = String::from('(');
109 while let Some(i) = stk.last_mut() { if let Some(val) = i.next() { match val {
112 A(aa) => { if res.ends_with(' ') {res.pop();}
114 res.push('(');
115 stk.push(aa.iter()); },
117 _ => { let s = unsafe { val.display_scalar(k, o, nm, sb) };
119 res += &s; res.push(' ');
121 }
122 }
123 }
124 else { if res.ends_with(' ') {
126 res.pop(); }
128 res.push(')');
129 stk.pop(); }
131 }
132 res
133 },
134 _ => { unsafe { self.display_scalar(k, o, nm, sb) }
136 }
137 }
138 }
139}
140
141impl Display for Value {
143 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
144 write!(f, "{}", self.display(DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2, DEFAULT_PARAMS.3, true))
145 }
146}
147
148pub type ThreadResult = (Vec<Arc<Value>>, std::io::Result<crate::ExecResult>);
149
150#[derive(Default, Debug)]
151pub struct Register {
152 pub v: Vec<Arc<Value>>,
154 pub th: Option<(std::thread::JoinHandle<ThreadResult>, Sender<()>)>
156}
157impl Clone for Register {
159 fn clone(&self) -> Self {
160 Self {
161 v: self.v.clone(),
162 th: None
163 }
164 }
165}
166
167#[derive(Clone, Debug)]
169pub struct RegStore {
170 pub low: [Register; 128],
172
173 pub high: HashMap<Rational, Register>
175}
176impl RegStore {
177 pub fn try_get(&self, index: &Rational) -> Option<&Register> {
179 usize::try_from(index).ok()
180 .and_then(|u| self.low.get(u))
181 .or_else(|| self.high.get(index))
182 }
183
184 pub fn try_get_mut(&mut self, index: &Rational) -> Option<&mut Register> {
186 usize::try_from(index).ok()
187 .and_then(|u| self.low.get_mut(u))
188 .or_else(|| self.high.get_mut(index))
189 }
190
191 pub fn get_mut(&mut self, index: &Rational) -> &mut Register {
193 usize::try_from(index).ok()
194 .and_then(|u| self.low.get_mut(u))
195 .unwrap_or_else(|| self.high.entry(index.clone()).or_default())
196 }
197
198 pub fn trim(&mut self) {
200 for reg in &mut self.low {
201 reg.v.shrink_to_fit();
202 }
203 self.high.retain(|_, reg| {
204 if reg.v.is_empty() {
205 reg.th.is_some()
206 }
207 else {
208 reg.v.shrink_to_fit();
209 true
210 }
211 });
212 }
213
214 pub fn clear_vals(&mut self) {
216 for reg in &mut self.low {
217 reg.v = Vec::new();
218 }
219 self.high.retain(|_, reg| {
220 reg.v = Vec::new();
221 reg.th.is_some()
222 });
223 self.high.shrink_to_fit();
224 }
225
226 pub fn replace_vals(&mut self, mut other: Self) {
228 for (reg, oreg) in self.low.iter_mut().zip(other.low.into_iter()) {
229 reg.v = oreg.v;
230 }
231 self.high.retain(|ri, reg| { if let Some(oreg) = other.high.remove(ri) && !oreg.v.is_empty() { reg.v = oreg.v;
234 true
235 }
236 else { reg.v = Vec::new();
238 reg.th.is_some()
239 }
240 });
241 for (ori, oreg) in other.high.drain().filter(|(_, oreg)| !oreg.v.is_empty()) { self.high.insert(ori, oreg);
243 }
244 }
245}
246impl Default for RegStore {
247 fn default() -> Self {
248 Self {
249 low: std::array::from_fn(|_| Register::default()),
250 high: HashMap::default()
251 }
252 }
253}
254
255#[derive(Default, Debug)]
257#[repr(transparent)] pub(crate) struct RegexCache(pub(crate) RwLock<HashMap<String, Regex>>);
258
259impl RegexCache {
260 pub(crate) fn get(&self, s: &String) -> Result<Regex, String> {
262 if let Some(re) = self.0.read().unwrap().get(s) {
263 Ok(re.clone())
264 }
265 else {
266 match RegexBuilder::new(s)
267 .size_limit(usize::MAX)
268 .dfa_size_limit(usize::MAX)
269 .build() {
270 Ok(re) => {
271 self.0.write().unwrap().insert(s.clone(), re.clone());
272 Ok(re)
273 },
274 Err(e) => Err(format!("can't compile regex: {e}"))
275 }
276 }
277 }
278
279 pub(crate) fn clear(&self) {
280 *self.0.write().unwrap() = HashMap::new();
281 }
282}
283
284#[derive(Clone, Debug)]
290pub enum Utf8Iter<'a> {
291 Owned {
292 bytes: Vec<u8>,
293 pos: usize
294 },
295 Borrowed {
296 bytes: &'a [u8],
297 pos: usize
298 }
299}
300impl Default for Utf8Iter<'_> {
301 fn default() -> Self {
302 Self::Owned { bytes: Vec::new(), pos: 0 }
303 }
304}
305
306impl From<Vec<u8>> for Utf8Iter<'_> {
307 fn from(bytes: Vec<u8>) -> Self {
308 Self::Owned { bytes, pos: 0 }
309 }
310}
311impl<'a> From<&'a [u8]> for Utf8Iter<'a> {
312 fn from(bytes: &'a [u8]) -> Self {
313 Self::Borrowed { bytes, pos: 0 }
314 }
315}
316impl From<String> for Utf8Iter<'_> {
317 fn from(s: String) -> Self {
318 Self::Owned { bytes: s.into_bytes(), pos: 0 }
319 }
320}
321impl<'a> From<&'a str> for Utf8Iter<'a> {
322 fn from(s: &'a str) -> Self {
323 Self::Borrowed { bytes: s.as_bytes(), pos: 0 }
324 }
325}
326impl TryFrom<Utf8Iter<'_>> for String {
327 type Error = String;
328
329 fn try_from(mut value: Utf8Iter) -> Result<String, String> {
330 let mut res = String::new();
331 while !value.is_finished() {
332 res.push(value.try_next_char().map_err(|e| format!("At byte {}: {e}", {
333 match value {
334 Utf8Iter::Borrowed {pos, ..} => pos,
335 Utf8Iter::Owned {pos, ..} => pos
336 }
337 }))?);
338 }
339 Ok(res)
340 }
341}
342
343impl Iterator for Utf8Iter<'_> {
344 type Item = u8;
345 fn next(&mut self) -> Option<Self::Item> {
346 let (bytes, pos): (&[u8], &mut usize) = match self {
347 Self::Borrowed {bytes, pos} => (bytes, pos),
348 Self::Owned {bytes, pos} => (bytes, pos)
349 };
350 bytes.get(*pos).copied().inspect(|_| {*pos+=1;})
351 }
352}
353
354impl Utf8Iter<'_> {
355 pub fn try_next_char(&mut self) -> Result<char, String> {
367 let (bytes, pos): (&[u8], &mut usize) = match self {
368 Self::Borrowed {bytes, pos} => (bytes, pos),
369 Self::Owned {bytes, pos} => (bytes, pos)
370 };
371 if let Some(b0) = bytes.get(*pos).copied() {
372 let c;
373 match b0 {
374 0x00..=0x7F => {
376 *pos += 1;
377 Ok(b0 as char)
378 }
379
380 0x80..=0xBF => {
382 Err(format!("Continuation byte at start of character: [\\{b0:02X}]"))
383 }
384
385 0xC2..=0xDF => {
387 if let Some(b1) = bytes.get(*pos+1).copied() {
388 if !(0x80..=0xBF).contains(&b1) {
389 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}]"));
390 }
391 c = ((b0 & 0x1F) as u32) << 6
392 | (b1 & 0x3F) as u32;
393 *pos += 2;
395 Ok(unsafe{char::from_u32_unchecked(c)})
396 }
397 else {
398 Err(format!("Unexpected end of string: [\\{b0:02X}]"))
399 }
400 }
401
402 0xE0..=0xEF => {
404 if let Some(b1) = bytes.get(*pos+1).copied() {
405 if let Some(b2) = bytes.get(*pos+2).copied() {
406 if !(0x80..=0xBF).contains(&b1) {
407 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
408 }
409 if !(0x80..=0xBF).contains(&b2) {
410 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
411 }
412 c = ((b0 & 0x0F) as u32) << 12
413 | ((b1 & 0x3F) as u32) << 6
414 | (b2 & 0x3F) as u32;
415 if c < 0x0800 {
416 return Err(format!("Overlong encoding of U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
417 }
418 if (0xD800u32..=0xDFFFu32).contains(&c) {
419 return Err(format!("Unexpected UTF-16 surrogate U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
420 }
421 *pos += 3;
423 Ok(unsafe{char::from_u32_unchecked(c)})
424 }
425 else {
426 Err(format!("Unexpected end of string: [\\{b0:02X}\\{b1:02X}]"))
427 }
428 }
429 else {
430 Err(format!("Unexpected end of string: [\\{b0:02X}]"))
431 }
432 }
433
434 0xF0..=0xF4 => {
436 if let Some(b1) = bytes.get(*pos+1).copied() {
437 if let Some(b2) = bytes.get(*pos+2).copied() {
438 if let Some(b3) = bytes.get(*pos+3).copied() {
439 if !(0x80..=0xBF).contains(&b1) {
440 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
441 }
442 if !(0x80..=0xBF).contains(&b2) {
443 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
444 }
445 if !(0x80..=0xBF).contains(&b3) {
446 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
447 }
448 c = ((b0 & 0x07) as u32) << 18
449 | ((b1 & 0x3F) as u32) << 12
450 | ((b2 & 0x3F) as u32) << 6
451 | (b3 & 0x3F) as u32;
452 if c < 0x10000 {
453 return Err(format!("Overlong encoding of U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
454 }
455 if c > 0x10FFFF {
456 return Err(format!("Out-of-range character U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
457 }
458 *pos += 4;
460 Ok(unsafe{char::from_u32_unchecked(c)})
461 }
462 else {
463 Err(format!("Unexpected end of string: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"))
464 }
465 }
466 else {
467 Err(format!("Unexpected end of string: [\\{b0:02X}\\{b1:02X}]"))
468 }
469 }
470 else {
471 Err(format!("Unexpected end of string: [\\{b0:02X}]"))
472 }
473 }
474
475 0xC0 | 0xC1 | 0xF5..=0xFF => Err(format!("Impossible byte in string: [\\{b0:02X}]")),
476 }
477 }
478 else {
479 Err(format!("Position out of bounds: {}", *pos))
480 }
481 }
482
483 pub fn from_vals(top: &Value, sec: Option<&Value>) -> Result<(Vec<(Self, Natural)>, bool), String> {
493 use Value::*;
494 use crate::errors::TypeLabel;
495 use crate::conv::{PromotingIter, lenck2};
496 if let Some(sec) = sec { if let Ok(res) = Self::from_vals(top, None) { return Ok(res); } match (sec, top) {
499 (A(_), A(_)) | (A(_), _) | (_, A(_)) => { if let Err(e) = lenck2(sec, top) { return Err(e.to_string()); }
501 let mut stk = vec![(PromotingIter::from(sec), PromotingIter::from(top))];
502 let mut res = Vec::new();
503
504 while let Some((ia, ib)) = stk.last_mut() { if let (Some(va), Some(vb)) = (ia.next(), ib.next()) { match (va, vb) {
507 (A(_), A(_)) | (A(_), _) | (_, A(_)) => { if let Err(e) = lenck2(va, vb) { return Err(e.to_string()); }
509 stk.push((PromotingIter::from(va), PromotingIter::from(vb))); },
511 (S(sa), B(bb)) => {
512 let nb = Natural::from(bb.count_ones());
513 if nb != Natural::ZERO {
514 res.push((sa.to_owned().into(), nb));
515 }
516 },
517 (S(sa), N(rb)) => {
518 if let Ok(nb) = Natural::try_from(rb) {
519 if nb != Natural::ZERO {
520 res.push((sa.to_owned().into(), nb));
521 }
522 }
523 else {
524 return Err(format!("Can't possibly repeat a macro {} times", crate::num::nauto(rb, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2)));
525 }
526 },
527 (_, S(_)) => { return Err("Unexpected string in second array".into());
529 },
530 _ => {
531 return Err(format!("Expected pairs of only strings and non-strings, found {} and {} in arrays", TypeLabel::from(sec), TypeLabel::from(top)));
532 }
533 }
534 }
535 else { stk.pop(); }
538 }
539
540 res.reverse();
541 Ok((res, false))
542 },
543 (S(sa), B(bb)) => {
545 let nb = Natural::from(bb.count_ones());
546 if nb != Natural::ZERO {
547 Ok((vec![(sa.to_owned().into(), nb)], false))
548 }
549 else {Ok((vec![], false))}
550 },
551 (S(sa), N(rb)) => {
552 if let Ok(nb) = Natural::try_from(rb) {
553 if nb != Natural::ZERO {
554 Ok((vec![(sa.to_owned().into(), nb)], false))
555 }
556 else {Ok((vec![], false))}
557 }
558 else {
559 Err(format!("Can't possibly repeat a macro {} times", crate::num::nauto(rb, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2)))
560 }
561 },
562 (_, S(_)) => { unsafe { std::hint::unreachable_unchecked() }
564 },
565 _ => {
566 Err(format!("Expected a string and a non-string, {} and {} given", TypeLabel::from(sec), TypeLabel::from(top)))
567 }
568 }
569 }
570 else { match top {
572 A(a) => { let mut stk: Vec<std::slice::Iter<Value>> = vec![a.iter()];
574 let mut res = Vec::new();
575 while let Some(i) = stk.last_mut() { if let Some(val) = i.next() { match val {
578 A(na) => { stk.push(na.iter()); },
581 S(s) => { res.push((s.to_owned().into(), Natural::ONE));
583 },
584 _ => {
585 return Err(format!("Expected only strings, found {} in array", TypeLabel::from(val)));
586 }
587 }
588 }
589 else { stk.pop(); }
592 }
593 res.reverse();
594 Ok((res, true))
595 },
596 S(s) => {
598 Ok((vec![(s.to_owned().into(), Natural::ONE)], true))
599 },
600 _ => {
601 Err(format!("Expected a string, {} given", TypeLabel::from(top)))
602 }
603 }
604 }
605 }
606
607 pub(crate) fn is_finished(&self) -> bool {
608 let (bytes, pos): (&[u8], &usize) = match self {
609 Self::Borrowed {bytes, pos} => (bytes, pos),
610 Self::Owned {bytes, pos} => (bytes, pos)
611 };
612 bytes.len() <= *pos
613 }
614
615 pub(crate) fn back(&mut self) {
616 let pos = match self {
617 Self::Borrowed {pos, ..} => pos,
618 Self::Owned {pos, ..} => pos
619 };
620 *pos -= 1;
621 }
622
623 pub(crate) fn rewind(&mut self) {
624 let pos = match self {
625 Self::Borrowed {pos, ..} => pos,
626 Self::Owned {pos, ..} => pos
627 };
628 *pos = 0;
629 }
630}
631
632#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
634#[repr(u8)] pub enum NumOutMode { #[default] Auto=0, Norm=1, Sci=2, Frac=3 }
635
636pub type Params = (usize, Natural, Natural, NumOutMode);
638
639pub const DEFAULT_PARAMS: Params = {
641 (0, Natural::const_from(10), Natural::const_from(10), NumOutMode::Auto)
642};
643
644#[derive(Clone, Debug)]
646#[repr(transparent)] pub struct ParamStk(Vec<Params>);
647impl ParamStk {
648 pub fn create(&mut self) {
650 self.0.push(DEFAULT_PARAMS)
651 }
652
653 pub fn destroy(&mut self) {
655 self.0.pop();
656 if self.0.is_empty() {self.create();}
657 }
658
659 pub fn clear(&mut self) {
661 *self = Self::default();
662 }
663
664 pub fn inner(&self) -> &Vec<Params> {
666 &self.0
667 }
668
669 pub fn into_inner(self) -> Vec<Params> {
671 self.0
672 }
673
674 pub fn try_set_k(&mut self, r: &Rational) -> Result<(), &'static str> {
676 if let Ok(u) = r.try_into() {
677 unsafe { self.0.last_mut().unwrap_unchecked().0 = u; }
678 Ok(())
679 }
680 else {Err(const_format::concatcp!("Output precision must be a natural number <={}", usize::MAX))}
681 }
682
683 pub fn try_set_i(&mut self, r: &Rational) -> Result<(), &'static str> {
685 if let Ok(n) = r.try_into() && n>=2u8 {
686 unsafe { self.0.last_mut().unwrap_unchecked().1 = n; }
687 Ok(())
688 }
689 else {Err("Input base must be a natural number >=2")}
690 }
691
692 pub fn try_set_o(&mut self, r: &Rational) -> Result<(), &'static str> {
694 if let Ok(n) = r.try_into() && n>=2u8 {
695 unsafe { self.0.last_mut().unwrap_unchecked().2 = n; }
696 Ok(())
697 }
698 else {Err("Output base must be a natural number >=2")}
699 }
700
701 pub fn try_set_m(&mut self, r: &Rational) -> Result<(), &'static str> {
703 if let Ok(u) = u8::try_from(r) && u<=3 {
704 unsafe { self.0.last_mut().unwrap_unchecked().3 = std::mem::transmute::<u8, NumOutMode>(u); }
705 Ok(())
706 }
707 else {Err("Output mode must be 0|1|2|3")}
708 }
709
710 pub fn set_k(&mut self, u: usize) {
712 unsafe { self.0.last_mut().unwrap_unchecked().0 = u; }
713 }
714
715 pub fn set_m(&mut self, m: NumOutMode) {
717 unsafe { self.0.last_mut().unwrap_unchecked().3 = m; }
718 }
719
720 pub fn get_k(&self) -> usize {
722 unsafe { self.0.last().unwrap_unchecked().0 }
723 }
724
725 pub fn get_i(&self) -> &Natural {
727 unsafe { &self.0.last().unwrap_unchecked().1 }
728 }
729
730 pub fn get_o(&self) -> &Natural {
732 unsafe { &self.0.last().unwrap_unchecked().2 }
733 }
734
735 pub fn get_m(&self) -> NumOutMode {
737 unsafe { self.0.last().unwrap_unchecked().3 }
738 }
739}
740impl Default for ParamStk {
742 fn default() -> Self {
743 let mut p = Self(Vec::new());
744 p.create();
745 p
746 }
747}
748impl TryFrom<Vec<Params>> for ParamStk {
750 type Error = ();
751
752 fn try_from(value: Vec<Params>) -> Result<Self, Self::Error> {
753 (!value.is_empty()).then_some(Self(value)).ok_or(())
754 }
755}
756
757#[derive(Default, Debug, Clone)]
765pub struct State {
766 pub mstk: Vec<Arc<Value>>,
768
769 pub regs: RegStore,
771
772 pub params: ParamStk
774}
775impl Display for State {
777 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
778 write!(f, "{}", String::from_utf8_lossy(&crate::STATE_FILE_HEADER))?;
779 for (lri, lreg) in self.regs.low.iter().enumerate().filter(|(_, lreg)| !lreg.v.is_empty()) {
780 for val in &lreg.v {
781 writeln!(f, "{val}")?;
782 }
783 writeln!(f, "{lri}:ff")?;
784 }
785 for (hri, hreg) in self.regs.high.iter().filter(|(_, hreg)| !hreg.v.is_empty()) {
786 for val in &hreg.v {
787 writeln!(f, "{val}")?;
788 }
789 writeln!(f, "{}:ff", crate::num::nauto(hri, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2))?;
790 }
791 for val in &self.mstk {
792 writeln!(f, "{val}")?;
793 }
794 write!(f, "{}", {
795 let v: Vec<String> = self.params.inner().iter().map(|par| {
796 let mut ps = String::new();
797 if par.0 != DEFAULT_PARAMS.0 {ps += &format!("{{{}}}k", par.0);}
798 if par.1 != DEFAULT_PARAMS.1 {ps += &format!("{{{}}}i", par.1);}
799 if par.2 != DEFAULT_PARAMS.2 {ps += &format!("{{{}}}o", par.2);}
800 if par.3 != DEFAULT_PARAMS.3 {ps += &format!("{{{}}}m", par.3 as u8);}
801 ps
802 }).collect();
803 v.join("{")
804 })?;
805 Ok(())
806 }
807}
808impl State {
809 pub fn trim(&mut self) {
811 self.mstk.shrink_to_fit();
812 self.regs.trim();
813 self.params.0.shrink_to_fit();
814 }
815
816 pub fn clear_vals(&mut self) {
818 self.mstk = Vec::new();
819 self.regs.clear_vals();
820 self.params = ParamStk::default();
821 }
822
823 pub fn replace_vals(&mut self, other: Self) {
825 self.mstk = other.mstk;
826 self.regs.replace_vals(other.regs);
827 self.params = other.params;
828 }
829}