1use std::collections::HashMap;
4use std::fmt::{Display, Formatter};
5use std::sync::{Arc, RwLock, mpsc::Sender};
6use std::thread::JoinHandle;
7use bitvec::prelude::*;
8use malachite::{Natural, Rational};
9use malachite::base::num::basic::traits::{Zero, One};
10use regex::{Regex, RegexBuilder};
11
12#[derive(Debug)]
13pub enum Value {
14 B(BitVec<usize, Lsb0>),
15 N(Rational),
16 S(String),
17 A(Vec<Value>)
18}
19impl Default for Value {
20 fn default() -> Self {
21 Self::A(Vec::new())
22 }
23}
24
25impl Drop for Value {
27 fn drop(&mut self) {
28 use Value::*;
29 use std::mem::take;
30 if let A(a) = self {
31 let mut q: Vec<Vec<Value>> = vec![take(a)]; while let Some(mut a) = q.pop() {
33 for v in &mut a { if let A(aa) = v { q.push(take(aa)) }
37 }
38 }
40 }
41 }
43}
44
45impl Clone for Value {
47 fn clone(&self) -> Self {
48 use Value::*;
49 match self {
50 B(b) => B(b.clone()),
52 N(n) => N(n.clone()),
53 S(s) => S(s.clone()),
54 A(_) => unsafe { crate::fns::exec1(|v, _| Ok(v.clone()), self, false).unwrap_unchecked() } }
58 }
59}
60
61impl Value {
62 unsafe fn display_scalar(&self, k: usize, o: &Natural, nm: NumOutMode, sb: bool) -> String {
64 use Value::*;
65 match self {
66 B(b) => {
67 b.iter().by_vals().map(|b| if b {'T'} else {'F'}).collect()
68 },
69 N(n) => {
70 use crate::num::*;
71 use NumOutMode::*;
72 match nm {
73 Auto => {
74 nauto(n, k, o)
75 },
76 Norm => {
77 let (neg, ipart, fpart, rpart) = digits(n, k, o);
78 nnorm(neg, &ipart, &fpart, &rpart, o)
79 },
80 Sci => {
81 let (neg, ipart, fpart, rpart) = digits(n, k, o);
82 nsci(neg, &ipart, &fpart, &rpart, o)
83 },
84 Frac => {
85 nfrac(n, k, o)
86 },
87 }
88 },
89 S(s) => {
90 if sb {
91 String::from("[") + s + "]"
92 }
93 else {
94 s.to_owned()
95 }
96 },
97 A(_) => {
98 unsafe { std::hint::unreachable_unchecked() }
99 }
100 }
101 }
102
103 pub fn display(&self, k: usize, o: &Natural, nm: NumOutMode, sb: bool) -> String {
105 use Value::*;
106 match self {
107 A(a) => { let mut stk: Vec<std::slice::Iter<Value>> = vec![a.iter()];
109 let mut res = String::from('(');
110 while let Some(i) = stk.last_mut() { if let Some(val) = i.next() { match val {
113 A(aa) => { if res.ends_with(' ') {res.pop();}
115 res.push('(');
116 stk.push(aa.iter()); },
118 _ => { let s = unsafe { val.display_scalar(k, o, nm, sb) };
120 res += &s; res.push(' ');
122 }
123 }
124 }
125 else { if res.ends_with(' ') {
127 res.pop(); }
129 res.push(')');
130 stk.pop(); }
132 }
133 res
134 },
135 _ => { unsafe { self.display_scalar(k, o, nm, sb) }
137 }
138 }
139 }
140}
141
142impl Display for Value {
144 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
145 write!(f, "{}", self.display(DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2, DEFAULT_PARAMS.3, true))
146 }
147}
148
149pub fn reg_index_nice(ri: &Rational) -> String {
151 use malachite::base::num::conversion::traits::PowerOf2Digits;
152 Natural::try_from(ri).ok().and_then(|n| { let bytes: Vec<u8> = n.to_power_of_2_digits_desc(8); str::from_utf8(&bytes).ok().map(|s| String::from("[") + s + "]") })
156 .unwrap_or_else(|| {
157 crate::num::nauto(ri, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2) })
159}
160
161pub type ThreadResult = (Vec<Arc<Value>>, std::io::Result<crate::ExecResult>);
162
163#[derive(Default, Debug)]
164pub struct Register {
165 pub v: Vec<Arc<Value>>,
167 pub th: Option<(JoinHandle<ThreadResult>, Sender<()>, Sender<()>)>
169}
170impl Clone for Register {
172 fn clone(&self) -> Self {
173 Self {
174 v: self.v.clone(),
175 th: None
176 }
177 }
178}
179
180#[derive(Clone, Debug)]
182pub struct RegStore {
183 pub low: [Register; 128],
185
186 pub high: HashMap<Rational, Register>
188}
189impl RegStore {
190 pub fn try_get(&self, index: &Rational) -> Option<&Register> {
192 usize::try_from(index).ok()
193 .and_then(|u| self.low.get(u))
194 .or_else(|| self.high.get(index))
195 }
196
197 pub fn try_get_mut(&mut self, index: &Rational) -> Option<&mut Register> {
199 usize::try_from(index).ok()
200 .and_then(|u| self.low.get_mut(u))
201 .or_else(|| self.high.get_mut(index))
202 }
203
204 pub fn get_mut(&mut self, index: &Rational) -> &mut Register {
206 usize::try_from(index).ok()
207 .and_then(|u| self.low.get_mut(u))
208 .unwrap_or_else(|| self.high.entry(index.clone()).or_default())
209 }
210
211 pub fn trim(&mut self) {
213 for reg in &mut self.low {
214 reg.v.shrink_to_fit();
215 }
216 self.high.retain(|_, reg| {
217 if reg.v.is_empty() {
218 reg.th.is_some()
219 }
220 else {
221 reg.v.shrink_to_fit();
222 true
223 }
224 });
225 }
226
227 pub fn clear_vals(&mut self) {
229 for reg in &mut self.low {
230 reg.v = Vec::new();
231 }
232 self.high.retain(|_, reg| {
233 reg.v = Vec::new();
234 reg.th.is_some()
235 });
236 self.high.shrink_to_fit();
237 }
238
239 pub fn replace_vals(&mut self, mut other: Self) {
241 for (reg, oreg) in self.low.iter_mut().zip(other.low.into_iter()) {
242 reg.v = oreg.v;
243 }
244 self.high.retain(|ri, reg| { if let Some(oreg) = other.high.remove(ri) && !oreg.v.is_empty() { reg.v = oreg.v;
247 true
248 }
249 else { reg.v = Vec::new();
251 reg.th.is_some()
252 }
253 });
254 for (ori, oreg) in other.high.drain().filter_map(|(ori, oreg)| (!oreg.v.is_empty()).then_some((ori, Register {v: oreg.v, th: None}))) {
255 self.high.insert(ori, oreg);
256 }
257 }
258
259 pub fn end_threads(&mut self, kill: bool) -> Vec<String> {
263 use crate::ExecResult::*;
264
265 let mut res = Vec::new();
266
267 for (ri, reg) in
268 self.low.iter_mut().enumerate().map(|(ri, reg)| (Rational::from(ri), reg))
269 .chain(self.high.iter_mut().map(|(ri, reg)| (ri.clone(), reg)))
270 {
271 if let Some((jh, ktx, jtx)) = reg.th.take() {
272 if kill {
273 ktx.send(()).unwrap_or_else(|_| panic!("Thread {} panicked, terminating!", reg_index_nice(&ri)));
274 }
275 jtx.send(()).unwrap_or_else(|_| panic!("Thread {} panicked, terminating!", reg_index_nice(&ri)));
276 match jh.join() {
277 Ok(mut tr) => {
278 match tr.1 {
279 Err(e) => {
280 res.push(format!("IO error in thread {}: {}", reg_index_nice(&ri), e));
281 },
282 Ok(SoftQuit(c)) if c != 0 => {
283 res.push(format!("Thread {} quit with code {}", reg_index_nice(&ri), c));
284 },
285 Ok(HardQuit(c)) if c != 0 => {
286 res.push(format!("Thread {} hard-quit with code {}", reg_index_nice(&ri), c));
287 },
288 Ok(Killed) => {
289 res.push(format!("Thread {} was killed", reg_index_nice(&ri)));
290 },
291 _ => {}
292 }
293
294 reg.v.append(&mut tr.0);
295 },
296 Err(e) => {
297 std::panic::resume_unwind(e);
298 }
299 }
300 }
301 }
302 res
303 }
304}
305impl Default for RegStore {
306 fn default() -> Self {
307 Self {
308 low: std::array::from_fn(|_| Register::default()),
309 high: HashMap::default()
310 }
311 }
312}
313
314#[derive(Default, Debug)]
316#[repr(transparent)] pub(crate) struct RegexCache(pub(crate) RwLock<HashMap<String, Regex>>);
317
318impl RegexCache {
319 pub(crate) fn get(&self, s: &String) -> Result<Regex, String> {
321 if let Some(re) = self.0.read().unwrap().get(s) {
322 Ok(re.clone())
323 }
324 else {
325 match RegexBuilder::new(s)
326 .size_limit(usize::MAX)
327 .dfa_size_limit(usize::MAX)
328 .build() {
329 Ok(re) => {
330 self.0.write().unwrap().insert(s.clone(), re.clone());
331 Ok(re)
332 },
333 Err(e) => Err(format!("can't compile regex: {e}"))
334 }
335 }
336 }
337
338 pub(crate) fn clear(&self) {
339 *self.0.write().unwrap() = HashMap::new();
340 }
341}
342
343#[derive(Clone, Debug)]
349pub enum Utf8Iter<'a> {
350 Owned {
351 bytes: Vec<u8>,
352 pos: usize
353 },
354 Borrowed {
355 bytes: &'a [u8],
356 pos: usize
357 }
358}
359impl Default for Utf8Iter<'_> {
360 fn default() -> Self {
361 Self::Owned { bytes: Vec::new(), pos: 0 }
362 }
363}
364
365impl From<Vec<u8>> for Utf8Iter<'_> {
366 fn from(bytes: Vec<u8>) -> Self {
367 Self::Owned { bytes, pos: 0 }
368 }
369}
370impl<'a> From<&'a [u8]> for Utf8Iter<'a> {
371 fn from(bytes: &'a [u8]) -> Self {
372 Self::Borrowed { bytes, pos: 0 }
373 }
374}
375impl From<String> for Utf8Iter<'_> {
376 fn from(s: String) -> Self {
377 Self::Owned { bytes: s.into_bytes(), pos: 0 }
378 }
379}
380impl<'a> From<&'a str> for Utf8Iter<'a> {
381 fn from(s: &'a str) -> Self {
382 Self::Borrowed { bytes: s.as_bytes(), pos: 0 }
383 }
384}
385impl TryFrom<Utf8Iter<'_>> for String {
386 type Error = String;
387
388 fn try_from(mut value: Utf8Iter) -> Result<String, String> {
389 let mut res = String::new();
390 while !value.is_finished() {
391 res.push(value.try_next_char().map_err(|e| format!("At byte {}: {e}", {
392 match value {
393 Utf8Iter::Borrowed {pos, ..} => pos,
394 Utf8Iter::Owned {pos, ..} => pos
395 }
396 }))?);
397 }
398 Ok(res)
399 }
400}
401
402impl Iterator for Utf8Iter<'_> {
403 type Item = u8;
404 fn next(&mut self) -> Option<Self::Item> {
405 let (bytes, pos): (&[u8], &mut usize) = match self {
406 Self::Borrowed {bytes, pos} => (bytes, pos),
407 Self::Owned {bytes, pos} => (bytes, pos)
408 };
409 bytes.get(*pos).copied().inspect(|_| {*pos+=1;})
410 }
411}
412
413impl Utf8Iter<'_> {
414 pub fn try_next_char(&mut self) -> Result<char, String> {
426 let (bytes, pos): (&[u8], &mut usize) = match self {
427 Self::Borrowed {bytes, pos} => (bytes, pos),
428 Self::Owned {bytes, pos} => (bytes, pos)
429 };
430 if let Some(b0) = bytes.get(*pos).copied() {
431 let c;
432 match b0 {
433 0x00..=0x7F => {
435 *pos += 1;
436 Ok(b0 as char)
437 }
438
439 0x80..=0xBF => {
441 Err(format!("Continuation byte at start of character: [\\{b0:02X}]"))
442 }
443
444 0xC2..=0xDF => {
446 if let Some(b1) = bytes.get(*pos+1).copied() {
447 if !(0x80..=0xBF).contains(&b1) {
448 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}]"));
449 }
450 c = ((b0 & 0x1F) as u32) << 6
451 | (b1 & 0x3F) as u32;
452 *pos += 2;
454 Ok(unsafe{char::from_u32_unchecked(c)})
455 }
456 else {
457 Err(format!("Unexpected end of string: [\\{b0:02X}]"))
458 }
459 }
460
461 0xE0..=0xEF => {
463 if let Some(b1) = bytes.get(*pos+1).copied() {
464 if let Some(b2) = bytes.get(*pos+2).copied() {
465 if !(0x80..=0xBF).contains(&b1) {
466 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
467 }
468 if !(0x80..=0xBF).contains(&b2) {
469 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
470 }
471 c = ((b0 & 0x0F) as u32) << 12
472 | ((b1 & 0x3F) as u32) << 6
473 | (b2 & 0x3F) as u32;
474 if c < 0x0800 {
475 return Err(format!("Overlong encoding of U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
476 }
477 if (0xD800u32..=0xDFFFu32).contains(&c) {
478 return Err(format!("Unexpected UTF-16 surrogate U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
479 }
480 *pos += 3;
482 Ok(unsafe{char::from_u32_unchecked(c)})
483 }
484 else {
485 Err(format!("Unexpected end of string: [\\{b0:02X}\\{b1:02X}]"))
486 }
487 }
488 else {
489 Err(format!("Unexpected end of string: [\\{b0:02X}]"))
490 }
491 }
492
493 0xF0..=0xF4 => {
495 if let Some(b1) = bytes.get(*pos+1).copied() {
496 if let Some(b2) = bytes.get(*pos+2).copied() {
497 if let Some(b3) = bytes.get(*pos+3).copied() {
498 if !(0x80..=0xBF).contains(&b1) {
499 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
500 }
501 if !(0x80..=0xBF).contains(&b2) {
502 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
503 }
504 if !(0x80..=0xBF).contains(&b3) {
505 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
506 }
507 c = ((b0 & 0x07) as u32) << 18
508 | ((b1 & 0x3F) as u32) << 12
509 | ((b2 & 0x3F) as u32) << 6
510 | (b3 & 0x3F) as u32;
511 if c < 0x10000 {
512 return Err(format!("Overlong encoding of U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
513 }
514 if c > 0x10FFFF {
515 return Err(format!("Out-of-range character U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
516 }
517 *pos += 4;
519 Ok(unsafe{char::from_u32_unchecked(c)})
520 }
521 else {
522 Err(format!("Unexpected end of string: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"))
523 }
524 }
525 else {
526 Err(format!("Unexpected end of string: [\\{b0:02X}\\{b1:02X}]"))
527 }
528 }
529 else {
530 Err(format!("Unexpected end of string: [\\{b0:02X}]"))
531 }
532 }
533
534 0xC0 | 0xC1 | 0xF5..=0xFF => Err(format!("Impossible byte in string: [\\{b0:02X}]")),
535 }
536 }
537 else {
538 Err(format!("Position out of bounds: {}", *pos))
539 }
540 }
541
542 pub fn from_vals(top: &Value, sec: Option<&Value>) -> Result<(Vec<(Self, Natural)>, bool), String> {
552 use Value::*;
553 use crate::errors::TypeLabel;
554 use crate::conv::{PromotingIter, lenck2};
555 if let Some(sec) = sec { if let Ok(res) = Self::from_vals(top, None) { return Ok(res); } match (sec, top) {
558 (A(_), A(_)) | (A(_), _) | (_, A(_)) => { if let Err(e) = lenck2(sec, top) { return Err(e.to_string()); }
560 let mut stk = vec![(PromotingIter::from(sec), PromotingIter::from(top))];
561 let mut res = vec![];
562
563 while let Some((ia, ib)) = stk.last_mut() { if let (Some(va), Some(vb)) = (ia.next(), ib.next()) { match (va, vb) {
566 (A(_), A(_)) | (A(_), _) | (_, A(_)) => { if let Err(e) = lenck2(va, vb) { return Err(e.to_string()); }
568 stk.push((PromotingIter::from(va), PromotingIter::from(vb))); },
570 (S(sa), B(bb)) => {
571 let nb = Natural::from(bb.count_ones());
572 if nb != Natural::ZERO {
573 res.push((sa.to_owned().into(), nb));
574 }
575 },
576 (S(sa), N(rb)) => {
577 if let Ok(nb) = Natural::try_from(rb) {
578 if nb != Natural::ZERO {
579 res.push((sa.to_owned().into(), nb));
580 }
581 }
582 else {
583 return Err(format!("Can't possibly repeat a macro {} times", crate::num::nauto(rb, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2)));
584 }
585 },
586 (_, S(_)) => { return Err("Unexpected string in top array".into());
588 },
589 _ => {
590 return Err(format!("Expected only matching strings and non-strings, found {} and {} in arrays", TypeLabel::from(sec), TypeLabel::from(top)));
591 }
592 }
593 }
594 else { stk.pop(); }
597 }
598
599 res.reverse();
600 Ok((res, false))
601 },
602 (S(sa), B(bb)) => {
604 let nb = Natural::from(bb.count_ones());
605 if nb != Natural::ZERO {
606 Ok((vec![(sa.to_owned().into(), nb)], false))
607 }
608 else {Ok((vec![], false))}
609 },
610 (S(sa), N(rb)) => {
611 if let Ok(nb) = Natural::try_from(rb) {
612 if nb != Natural::ZERO {
613 Ok((vec![(sa.to_owned().into(), nb)], false))
614 }
615 else {Ok((vec![], false))}
616 }
617 else {
618 Err(format!("Can't possibly repeat a macro {} times", crate::num::nauto(rb, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2)))
619 }
620 },
621 (_, S(_)) => { unsafe { std::hint::unreachable_unchecked() }
623 },
624 _ => {
625 Err(format!("Expected a string and a non-string, {} and {} given", TypeLabel::from(sec), TypeLabel::from(top)))
626 }
627 }
628 }
629 else { match top {
631 A(a) => { let mut stk: Vec<std::slice::Iter<Value>> = vec![a.iter()];
633 let mut res = Vec::new();
634 while let Some(i) = stk.last_mut() { if let Some(val) = i.next() { match val {
637 A(na) => { stk.push(na.iter()); },
640 S(s) => { res.push((s.to_owned().into(), Natural::ONE));
642 },
643 _ => {
644 return Err(format!("Expected only strings, found {} in array", TypeLabel::from(val)));
645 }
646 }
647 }
648 else { stk.pop(); }
651 }
652 res.reverse();
653 Ok((res, true))
654 },
655 S(s) => {
657 Ok((vec![(s.to_owned().into(), Natural::ONE)], true))
658 },
659 _ => {
660 Err(format!("Expected a string, {} given", TypeLabel::from(top)))
661 }
662 }
663 }
664 }
665
666 pub(crate) fn is_finished(&self) -> bool {
667 let (bytes, pos): (&[u8], &usize) = match self {
668 Self::Borrowed {bytes, pos} => (bytes, pos),
669 Self::Owned {bytes, pos} => (bytes, pos)
670 };
671 bytes.len() <= *pos
672 }
673
674 pub(crate) fn back(&mut self) {
675 let pos = match self {
676 Self::Borrowed {pos, ..} => pos,
677 Self::Owned {pos, ..} => pos
678 };
679 *pos -= 1;
680 }
681
682 pub(crate) fn rewind(&mut self) {
683 let pos = match self {
684 Self::Borrowed {pos, ..} => pos,
685 Self::Owned {pos, ..} => pos
686 };
687 *pos = 0;
688 }
689}
690
691#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
693#[repr(u8)] pub enum NumOutMode { #[default] Auto=0, Norm=1, Sci=2, Frac=3 }
694
695pub type Params = (usize, Natural, Natural, NumOutMode);
697
698pub const DEFAULT_PARAMS: Params = {
700 (0, Natural::const_from(10), Natural::const_from(10), NumOutMode::Auto)
701};
702
703#[derive(Clone, Debug)]
705#[repr(transparent)] pub struct ParamStk(Vec<Params>);
706impl ParamStk {
707 pub fn create(&mut self) {
709 self.0.push(DEFAULT_PARAMS)
710 }
711
712 pub fn destroy(&mut self) {
714 self.0.pop();
715 if self.0.is_empty() {self.create();}
716 }
717
718 pub fn clear(&mut self) {
720 *self = Self::default();
721 }
722
723 pub fn inner(&self) -> &Vec<Params> {
725 &self.0
726 }
727
728 pub fn into_inner(self) -> Vec<Params> {
730 self.0
731 }
732
733 pub fn try_set_k(&mut self, r: &Rational) -> Result<(), &'static str> {
735 if let Ok(u) = r.try_into() {
736 unsafe { self.0.last_mut().unwrap_unchecked().0 = u; }
737 Ok(())
738 }
739 else {Err(const_format::concatcp!("Output precision must be a natural number <={}", usize::MAX))}
740 }
741
742 pub fn try_set_i(&mut self, r: &Rational) -> Result<(), &'static str> {
744 if let Ok(n) = r.try_into() && n>=2u8 {
745 unsafe { self.0.last_mut().unwrap_unchecked().1 = n; }
746 Ok(())
747 }
748 else {Err("Input base must be a natural number >=2")}
749 }
750
751 pub fn try_set_o(&mut self, r: &Rational) -> Result<(), &'static str> {
753 if let Ok(n) = r.try_into() && n>=2u8 {
754 unsafe { self.0.last_mut().unwrap_unchecked().2 = n; }
755 Ok(())
756 }
757 else {Err("Output base must be a natural number >=2")}
758 }
759
760 pub fn try_set_m(&mut self, r: &Rational) -> Result<(), &'static str> {
762 if let Ok(u) = u8::try_from(r) && u<=3 {
763 unsafe { self.0.last_mut().unwrap_unchecked().3 = std::mem::transmute::<u8, NumOutMode>(u); }
764 Ok(())
765 }
766 else {Err("Output mode must be 0|1|2|3")}
767 }
768
769 pub fn set_k(&mut self, u: usize) {
771 unsafe { self.0.last_mut().unwrap_unchecked().0 = u; }
772 }
773
774 pub fn set_m(&mut self, m: NumOutMode) {
776 unsafe { self.0.last_mut().unwrap_unchecked().3 = m; }
777 }
778
779 pub fn get_k(&self) -> usize {
781 unsafe { self.0.last().unwrap_unchecked().0 }
782 }
783
784 pub fn get_i(&self) -> &Natural {
786 unsafe { &self.0.last().unwrap_unchecked().1 }
787 }
788
789 pub fn get_o(&self) -> &Natural {
791 unsafe { &self.0.last().unwrap_unchecked().2 }
792 }
793
794 pub fn get_m(&self) -> NumOutMode {
796 unsafe { self.0.last().unwrap_unchecked().3 }
797 }
798}
799impl Default for ParamStk {
801 fn default() -> Self {
802 let mut p = Self(Vec::new());
803 p.create();
804 p
805 }
806}
807impl TryFrom<Vec<Params>> for ParamStk {
809 type Error = ();
810
811 fn try_from(value: Vec<Params>) -> Result<Self, Self::Error> {
812 (!value.is_empty()).then_some(Self(value)).ok_or(())
813 }
814}
815
816#[derive(Default, Debug, Clone)]
824pub struct State {
825 pub mstk: Vec<Arc<Value>>,
827
828 pub regs: RegStore,
830
831 pub params: ParamStk
833}
834impl Display for State {
836 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
837 write!(f, "{}", String::from_utf8_lossy(&crate::STATE_FILE_HEADER))?;
838 for (lri, lreg) in self.regs.low.iter().enumerate().filter(|(_, lreg)| !lreg.v.is_empty()) {
839 for val in &lreg.v {
840 writeln!(f, "{val}")?;
841 }
842 writeln!(f, "{lri}:ff")?;
843 }
844 for (hri, hreg) in self.regs.high.iter().filter(|(_, hreg)| !hreg.v.is_empty()) {
845 for val in &hreg.v {
846 writeln!(f, "{val}")?;
847 }
848 writeln!(f, "{}:ff", crate::num::nauto(hri, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2))?;
849 }
850 for val in &self.mstk {
851 writeln!(f, "{val}")?;
852 }
853 write!(f, "{}", {
854 let v: Vec<String> = self.params.inner().iter().map(|par| {
855 let mut ps = String::new();
856 if par.0 != DEFAULT_PARAMS.0 {ps += &format!("{{{}}}k", par.0);}
857 if par.1 != DEFAULT_PARAMS.1 {ps += &format!("{{{}}}i", par.1);}
858 if par.2 != DEFAULT_PARAMS.2 {ps += &format!("{{{}}}o", par.2);}
859 if par.3 != DEFAULT_PARAMS.3 {ps += &format!("{{{}}}m", par.3 as u8);}
860 ps
861 }).collect();
862 v.join("{")
863 })?;
864 Ok(())
865 }
866}
867impl State {
868 pub fn trim(&mut self) {
870 self.mstk.shrink_to_fit();
871 self.regs.trim();
872 self.params.0.shrink_to_fit();
873 }
874
875 pub fn clear_vals(&mut self) {
877 self.mstk = Vec::new();
878 self.regs.clear_vals();
879 self.params = ParamStk::default();
880 }
881
882 pub fn replace_vals(&mut self, other: Self) {
884 self.mstk = other.mstk;
885 self.regs.replace_vals(other.regs);
886 self.params = other.params;
887 }
888}