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 fn reg_index_nice(ri: &Rational) -> String {
150 use malachite::base::num::conversion::traits::PowerOf2Digits;
151 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 + "]") })
155 .unwrap_or_else(|| {
156 crate::num::nauto(ri, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2) })
158}
159
160pub type ThreadResult = (Vec<Arc<Value>>, std::io::Result<crate::ExecResult>);
161
162#[derive(Default, Debug)]
163pub struct Register {
164 pub v: Vec<Arc<Value>>,
166 pub th: Option<(std::thread::JoinHandle<ThreadResult>, Sender<()>)>
168}
169impl Clone for Register {
171 fn clone(&self) -> Self {
172 Self {
173 v: self.v.clone(),
174 th: None
175 }
176 }
177}
178
179#[derive(Clone, Debug)]
181pub struct RegStore {
182 pub low: [Register; 128],
184
185 pub high: HashMap<Rational, Register>
187}
188impl RegStore {
189 pub fn try_get(&self, index: &Rational) -> Option<&Register> {
191 usize::try_from(index).ok()
192 .and_then(|u| self.low.get(u))
193 .or_else(|| self.high.get(index))
194 }
195
196 pub fn try_get_mut(&mut self, index: &Rational) -> Option<&mut Register> {
198 usize::try_from(index).ok()
199 .and_then(|u| self.low.get_mut(u))
200 .or_else(|| self.high.get_mut(index))
201 }
202
203 pub fn get_mut(&mut self, index: &Rational) -> &mut Register {
205 usize::try_from(index).ok()
206 .and_then(|u| self.low.get_mut(u))
207 .unwrap_or_else(|| self.high.entry(index.clone()).or_default())
208 }
209
210 pub fn trim(&mut self) {
212 for reg in &mut self.low {
213 reg.v.shrink_to_fit();
214 }
215 self.high.retain(|_, reg| {
216 if reg.v.is_empty() {
217 reg.th.is_some()
218 }
219 else {
220 reg.v.shrink_to_fit();
221 true
222 }
223 });
224 }
225
226 pub fn clear_vals(&mut self) {
228 for reg in &mut self.low {
229 reg.v = Vec::new();
230 }
231 self.high.retain(|_, reg| {
232 reg.v = Vec::new();
233 reg.th.is_some()
234 });
235 self.high.shrink_to_fit();
236 }
237
238 pub fn replace_vals(&mut self, mut other: Self) {
240 for (reg, oreg) in self.low.iter_mut().zip(other.low.into_iter()) {
241 reg.v = oreg.v;
242 }
243 self.high.retain(|ri, reg| { if let Some(oreg) = other.high.remove(ri) && !oreg.v.is_empty() { reg.v = oreg.v;
246 true
247 }
248 else { reg.v = Vec::new();
250 reg.th.is_some()
251 }
252 });
253 for (ori, oreg) in other.high.drain().filter_map(|(ori, oreg)| (!oreg.v.is_empty()).then_some((ori, Register {v: oreg.v, th: None}))) {
254 self.high.insert(ori, oreg);
255 }
256 }
257
258 pub fn end_threads(&mut self, kill: bool) -> Vec<String> {
262 use crate::ExecResult::*;
263
264 let mut res = Vec::new();
265
266 for (ri, reg) in
267 self.low.iter_mut().enumerate().map(|(ri, reg)| (Rational::from(ri), reg))
268 .chain(self.high.iter_mut().map(|(ri, reg)| (ri.clone(), reg)))
269 {
270 if let Some((jh, tx)) = reg.th.take() {
271 if kill {
272 tx.send(()).unwrap_or_else(|_| panic!("Thread {} panicked, terminating!", reg_index_nice(&ri)));
273 }
274 match jh.join() {
275 Ok(mut tr) => {
276 match tr.1 {
277 Err(e) => {
278 res.push(format!("IO error in thread {}: {}", reg_index_nice(&ri), e));
279 },
280 Ok(SoftQuit(c)) if c != 0 => {
281 res.push(format!("Thread {} quit with code {}", reg_index_nice(&ri), c));
282 },
283 Ok(HardQuit(c)) if c != 0 => {
284 res.push(format!("Thread {} hard-quit with code {}", reg_index_nice(&ri), c));
285 },
286 Ok(Killed) => {
287 res.push(format!("Thread {} was killed", reg_index_nice(&ri)));
288 },
289 _ => {}
290 }
291
292 reg.v.append(&mut tr.0);
293 },
294 Err(e) => {
295 std::panic::resume_unwind(e);
296 }
297 }
298 }
299 }
300 res
301 }
302}
303impl Default for RegStore {
304 fn default() -> Self {
305 Self {
306 low: std::array::from_fn(|_| Register::default()),
307 high: HashMap::default()
308 }
309 }
310}
311
312#[derive(Default, Debug)]
314#[repr(transparent)] pub(crate) struct RegexCache(pub(crate) RwLock<HashMap<String, Regex>>);
315
316impl RegexCache {
317 pub(crate) fn get(&self, s: &String) -> Result<Regex, String> {
319 if let Some(re) = self.0.read().unwrap().get(s) {
320 Ok(re.clone())
321 }
322 else {
323 match RegexBuilder::new(s)
324 .size_limit(usize::MAX)
325 .dfa_size_limit(usize::MAX)
326 .build() {
327 Ok(re) => {
328 self.0.write().unwrap().insert(s.clone(), re.clone());
329 Ok(re)
330 },
331 Err(e) => Err(format!("can't compile regex: {e}"))
332 }
333 }
334 }
335
336 pub(crate) fn clear(&self) {
337 *self.0.write().unwrap() = HashMap::new();
338 }
339}
340
341#[derive(Clone, Debug)]
347pub enum Utf8Iter<'a> {
348 Owned {
349 bytes: Vec<u8>,
350 pos: usize
351 },
352 Borrowed {
353 bytes: &'a [u8],
354 pos: usize
355 }
356}
357impl Default for Utf8Iter<'_> {
358 fn default() -> Self {
359 Self::Owned { bytes: Vec::new(), pos: 0 }
360 }
361}
362
363impl From<Vec<u8>> for Utf8Iter<'_> {
364 fn from(bytes: Vec<u8>) -> Self {
365 Self::Owned { bytes, pos: 0 }
366 }
367}
368impl<'a> From<&'a [u8]> for Utf8Iter<'a> {
369 fn from(bytes: &'a [u8]) -> Self {
370 Self::Borrowed { bytes, pos: 0 }
371 }
372}
373impl From<String> for Utf8Iter<'_> {
374 fn from(s: String) -> Self {
375 Self::Owned { bytes: s.into_bytes(), pos: 0 }
376 }
377}
378impl<'a> From<&'a str> for Utf8Iter<'a> {
379 fn from(s: &'a str) -> Self {
380 Self::Borrowed { bytes: s.as_bytes(), pos: 0 }
381 }
382}
383impl TryFrom<Utf8Iter<'_>> for String {
384 type Error = String;
385
386 fn try_from(mut value: Utf8Iter) -> Result<String, String> {
387 let mut res = String::new();
388 while !value.is_finished() {
389 res.push(value.try_next_char().map_err(|e| format!("At byte {}: {e}", {
390 match value {
391 Utf8Iter::Borrowed {pos, ..} => pos,
392 Utf8Iter::Owned {pos, ..} => pos
393 }
394 }))?);
395 }
396 Ok(res)
397 }
398}
399
400impl Iterator for Utf8Iter<'_> {
401 type Item = u8;
402 fn next(&mut self) -> Option<Self::Item> {
403 let (bytes, pos): (&[u8], &mut usize) = match self {
404 Self::Borrowed {bytes, pos} => (bytes, pos),
405 Self::Owned {bytes, pos} => (bytes, pos)
406 };
407 bytes.get(*pos).copied().inspect(|_| {*pos+=1;})
408 }
409}
410
411impl Utf8Iter<'_> {
412 pub fn try_next_char(&mut self) -> Result<char, String> {
424 let (bytes, pos): (&[u8], &mut usize) = match self {
425 Self::Borrowed {bytes, pos} => (bytes, pos),
426 Self::Owned {bytes, pos} => (bytes, pos)
427 };
428 if let Some(b0) = bytes.get(*pos).copied() {
429 let c;
430 match b0 {
431 0x00..=0x7F => {
433 *pos += 1;
434 Ok(b0 as char)
435 }
436
437 0x80..=0xBF => {
439 Err(format!("Continuation byte at start of character: [\\{b0:02X}]"))
440 }
441
442 0xC2..=0xDF => {
444 if let Some(b1) = bytes.get(*pos+1).copied() {
445 if !(0x80..=0xBF).contains(&b1) {
446 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}]"));
447 }
448 c = ((b0 & 0x1F) as u32) << 6
449 | (b1 & 0x3F) as u32;
450 *pos += 2;
452 Ok(unsafe{char::from_u32_unchecked(c)})
453 }
454 else {
455 Err(format!("Unexpected end of string: [\\{b0:02X}]"))
456 }
457 }
458
459 0xE0..=0xEF => {
461 if let Some(b1) = bytes.get(*pos+1).copied() {
462 if let Some(b2) = bytes.get(*pos+2).copied() {
463 if !(0x80..=0xBF).contains(&b1) {
464 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
465 }
466 if !(0x80..=0xBF).contains(&b2) {
467 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
468 }
469 c = ((b0 & 0x0F) as u32) << 12
470 | ((b1 & 0x3F) as u32) << 6
471 | (b2 & 0x3F) as u32;
472 if c < 0x0800 {
473 return Err(format!("Overlong encoding of U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
474 }
475 if (0xD800u32..=0xDFFFu32).contains(&c) {
476 return Err(format!("Unexpected UTF-16 surrogate U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"));
477 }
478 *pos += 3;
480 Ok(unsafe{char::from_u32_unchecked(c)})
481 }
482 else {
483 Err(format!("Unexpected end of string: [\\{b0:02X}\\{b1:02X}]"))
484 }
485 }
486 else {
487 Err(format!("Unexpected end of string: [\\{b0:02X}]"))
488 }
489 }
490
491 0xF0..=0xF4 => {
493 if let Some(b1) = bytes.get(*pos+1).copied() {
494 if let Some(b2) = bytes.get(*pos+2).copied() {
495 if let Some(b3) = bytes.get(*pos+3).copied() {
496 if !(0x80..=0xBF).contains(&b1) {
497 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
498 }
499 if !(0x80..=0xBF).contains(&b2) {
500 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
501 }
502 if !(0x80..=0xBF).contains(&b3) {
503 return Err(format!("Non-continuation byte in character: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
504 }
505 c = ((b0 & 0x07) as u32) << 18
506 | ((b1 & 0x3F) as u32) << 12
507 | ((b2 & 0x3F) as u32) << 6
508 | (b3 & 0x3F) as u32;
509 if c < 0x10000 {
510 return Err(format!("Overlong encoding of U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
511 }
512 if c > 0x10FFFF {
513 return Err(format!("Out-of-range character U+{c:04X}: [\\{b0:02X}\\{b1:02X}\\{b2:02X}\\{b3:02X}]"));
514 }
515 *pos += 4;
517 Ok(unsafe{char::from_u32_unchecked(c)})
518 }
519 else {
520 Err(format!("Unexpected end of string: [\\{b0:02X}\\{b1:02X}\\{b2:02X}]"))
521 }
522 }
523 else {
524 Err(format!("Unexpected end of string: [\\{b0:02X}\\{b1:02X}]"))
525 }
526 }
527 else {
528 Err(format!("Unexpected end of string: [\\{b0:02X}]"))
529 }
530 }
531
532 0xC0 | 0xC1 | 0xF5..=0xFF => Err(format!("Impossible byte in string: [\\{b0:02X}]")),
533 }
534 }
535 else {
536 Err(format!("Position out of bounds: {}", *pos))
537 }
538 }
539
540 pub fn from_vals(top: &Value, sec: Option<&Value>) -> Result<(Vec<(Self, Natural)>, bool), String> {
550 use Value::*;
551 use crate::errors::TypeLabel;
552 use crate::conv::{PromotingIter, lenck2};
553 if let Some(sec) = sec { if let Ok(res) = Self::from_vals(top, None) { return Ok(res); } match (sec, top) {
556 (A(_), A(_)) | (A(_), _) | (_, A(_)) => { if let Err(e) = lenck2(sec, top) { return Err(e.to_string()); }
558 let mut stk = vec![(PromotingIter::from(sec), PromotingIter::from(top))];
559 let mut res = vec![];
560
561 while let Some((ia, ib)) = stk.last_mut() { if let (Some(va), Some(vb)) = (ia.next(), ib.next()) { match (va, vb) {
564 (A(_), A(_)) | (A(_), _) | (_, A(_)) => { if let Err(e) = lenck2(va, vb) { return Err(e.to_string()); }
566 stk.push((PromotingIter::from(va), PromotingIter::from(vb))); },
568 (S(sa), B(bb)) => {
569 let nb = Natural::from(bb.count_ones());
570 if nb != Natural::ZERO {
571 res.push((sa.to_owned().into(), nb));
572 }
573 },
574 (S(sa), N(rb)) => {
575 if let Ok(nb) = Natural::try_from(rb) {
576 if nb != Natural::ZERO {
577 res.push((sa.to_owned().into(), nb));
578 }
579 }
580 else {
581 return Err(format!("Can't possibly repeat a macro {} times", crate::num::nauto(rb, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2)));
582 }
583 },
584 (_, S(_)) => { return Err("Unexpected string in top array".into());
586 },
587 _ => {
588 return Err(format!("Expected only matching strings and non-strings, found {} and {} in arrays", TypeLabel::from(sec), TypeLabel::from(top)));
589 }
590 }
591 }
592 else { stk.pop(); }
595 }
596
597 res.reverse();
598 Ok((res, false))
599 },
600 (S(sa), B(bb)) => {
602 let nb = Natural::from(bb.count_ones());
603 if nb != Natural::ZERO {
604 Ok((vec![(sa.to_owned().into(), nb)], false))
605 }
606 else {Ok((vec![], false))}
607 },
608 (S(sa), N(rb)) => {
609 if let Ok(nb) = Natural::try_from(rb) {
610 if nb != Natural::ZERO {
611 Ok((vec![(sa.to_owned().into(), nb)], false))
612 }
613 else {Ok((vec![], false))}
614 }
615 else {
616 Err(format!("Can't possibly repeat a macro {} times", crate::num::nauto(rb, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2)))
617 }
618 },
619 (_, S(_)) => { unsafe { std::hint::unreachable_unchecked() }
621 },
622 _ => {
623 Err(format!("Expected a string and a non-string, {} and {} given", TypeLabel::from(sec), TypeLabel::from(top)))
624 }
625 }
626 }
627 else { match top {
629 A(a) => { let mut stk: Vec<std::slice::Iter<Value>> = vec![a.iter()];
631 let mut res = Vec::new();
632 while let Some(i) = stk.last_mut() { if let Some(val) = i.next() { match val {
635 A(na) => { stk.push(na.iter()); },
638 S(s) => { res.push((s.to_owned().into(), Natural::ONE));
640 },
641 _ => {
642 return Err(format!("Expected only strings, found {} in array", TypeLabel::from(val)));
643 }
644 }
645 }
646 else { stk.pop(); }
649 }
650 res.reverse();
651 Ok((res, true))
652 },
653 S(s) => {
655 Ok((vec![(s.to_owned().into(), Natural::ONE)], true))
656 },
657 _ => {
658 Err(format!("Expected a string, {} given", TypeLabel::from(top)))
659 }
660 }
661 }
662 }
663
664 pub(crate) fn is_finished(&self) -> bool {
665 let (bytes, pos): (&[u8], &usize) = match self {
666 Self::Borrowed {bytes, pos} => (bytes, pos),
667 Self::Owned {bytes, pos} => (bytes, pos)
668 };
669 bytes.len() <= *pos
670 }
671
672 pub(crate) fn back(&mut self) {
673 let pos = match self {
674 Self::Borrowed {pos, ..} => pos,
675 Self::Owned {pos, ..} => pos
676 };
677 *pos -= 1;
678 }
679
680 pub(crate) fn rewind(&mut self) {
681 let pos = match self {
682 Self::Borrowed {pos, ..} => pos,
683 Self::Owned {pos, ..} => pos
684 };
685 *pos = 0;
686 }
687}
688
689#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
691#[repr(u8)] pub enum NumOutMode { #[default] Auto=0, Norm=1, Sci=2, Frac=3 }
692
693pub type Params = (usize, Natural, Natural, NumOutMode);
695
696pub const DEFAULT_PARAMS: Params = {
698 (0, Natural::const_from(10), Natural::const_from(10), NumOutMode::Auto)
699};
700
701#[derive(Clone, Debug)]
703#[repr(transparent)] pub struct ParamStk(Vec<Params>);
704impl ParamStk {
705 pub fn create(&mut self) {
707 self.0.push(DEFAULT_PARAMS)
708 }
709
710 pub fn destroy(&mut self) {
712 self.0.pop();
713 if self.0.is_empty() {self.create();}
714 }
715
716 pub fn clear(&mut self) {
718 *self = Self::default();
719 }
720
721 pub fn inner(&self) -> &Vec<Params> {
723 &self.0
724 }
725
726 pub fn into_inner(self) -> Vec<Params> {
728 self.0
729 }
730
731 pub fn try_set_k(&mut self, r: &Rational) -> Result<(), &'static str> {
733 if let Ok(u) = r.try_into() {
734 unsafe { self.0.last_mut().unwrap_unchecked().0 = u; }
735 Ok(())
736 }
737 else {Err(const_format::concatcp!("Output precision must be a natural number <={}", usize::MAX))}
738 }
739
740 pub fn try_set_i(&mut self, r: &Rational) -> Result<(), &'static str> {
742 if let Ok(n) = r.try_into() && n>=2u8 {
743 unsafe { self.0.last_mut().unwrap_unchecked().1 = n; }
744 Ok(())
745 }
746 else {Err("Input base must be a natural number >=2")}
747 }
748
749 pub fn try_set_o(&mut self, r: &Rational) -> Result<(), &'static str> {
751 if let Ok(n) = r.try_into() && n>=2u8 {
752 unsafe { self.0.last_mut().unwrap_unchecked().2 = n; }
753 Ok(())
754 }
755 else {Err("Output base must be a natural number >=2")}
756 }
757
758 pub fn try_set_m(&mut self, r: &Rational) -> Result<(), &'static str> {
760 if let Ok(u) = u8::try_from(r) && u<=3 {
761 unsafe { self.0.last_mut().unwrap_unchecked().3 = std::mem::transmute::<u8, NumOutMode>(u); }
762 Ok(())
763 }
764 else {Err("Output mode must be 0|1|2|3")}
765 }
766
767 pub fn set_k(&mut self, u: usize) {
769 unsafe { self.0.last_mut().unwrap_unchecked().0 = u; }
770 }
771
772 pub fn set_m(&mut self, m: NumOutMode) {
774 unsafe { self.0.last_mut().unwrap_unchecked().3 = m; }
775 }
776
777 pub fn get_k(&self) -> usize {
779 unsafe { self.0.last().unwrap_unchecked().0 }
780 }
781
782 pub fn get_i(&self) -> &Natural {
784 unsafe { &self.0.last().unwrap_unchecked().1 }
785 }
786
787 pub fn get_o(&self) -> &Natural {
789 unsafe { &self.0.last().unwrap_unchecked().2 }
790 }
791
792 pub fn get_m(&self) -> NumOutMode {
794 unsafe { self.0.last().unwrap_unchecked().3 }
795 }
796}
797impl Default for ParamStk {
799 fn default() -> Self {
800 let mut p = Self(Vec::new());
801 p.create();
802 p
803 }
804}
805impl TryFrom<Vec<Params>> for ParamStk {
807 type Error = ();
808
809 fn try_from(value: Vec<Params>) -> Result<Self, Self::Error> {
810 (!value.is_empty()).then_some(Self(value)).ok_or(())
811 }
812}
813
814#[derive(Default, Debug, Clone)]
822pub struct State {
823 pub mstk: Vec<Arc<Value>>,
825
826 pub regs: RegStore,
828
829 pub params: ParamStk
831}
832impl Display for State {
834 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
835 write!(f, "{}", String::from_utf8_lossy(&crate::STATE_FILE_HEADER))?;
836 for (lri, lreg) in self.regs.low.iter().enumerate().filter(|(_, lreg)| !lreg.v.is_empty()) {
837 for val in &lreg.v {
838 writeln!(f, "{val}")?;
839 }
840 writeln!(f, "{lri}:ff")?;
841 }
842 for (hri, hreg) in self.regs.high.iter().filter(|(_, hreg)| !hreg.v.is_empty()) {
843 for val in &hreg.v {
844 writeln!(f, "{val}")?;
845 }
846 writeln!(f, "{}:ff", crate::num::nauto(hri, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2))?;
847 }
848 for val in &self.mstk {
849 writeln!(f, "{val}")?;
850 }
851 write!(f, "{}", {
852 let v: Vec<String> = self.params.inner().iter().map(|par| {
853 let mut ps = String::new();
854 if par.0 != DEFAULT_PARAMS.0 {ps += &format!("{{{}}}k", par.0);}
855 if par.1 != DEFAULT_PARAMS.1 {ps += &format!("{{{}}}i", par.1);}
856 if par.2 != DEFAULT_PARAMS.2 {ps += &format!("{{{}}}o", par.2);}
857 if par.3 != DEFAULT_PARAMS.3 {ps += &format!("{{{}}}m", par.3 as u8);}
858 ps
859 }).collect();
860 v.join("{")
861 })?;
862 Ok(())
863 }
864}
865impl State {
866 pub fn trim(&mut self) {
868 self.mstk.shrink_to_fit();
869 self.regs.trim();
870 self.params.0.shrink_to_fit();
871 }
872
873 pub fn clear_vals(&mut self) {
875 self.mstk = Vec::new();
876 self.regs.clear_vals();
877 self.params = ParamStk::default();
878 }
879
880 pub fn replace_vals(&mut self, other: Self) {
882 self.mstk = other.mstk;
883 self.regs.replace_vals(other.regs);
884 self.params = other.params;
885 }
886}