1pub mod structs;
4use structs::*;
5
6pub(crate) mod fns;
7
8pub(crate) mod cmds;
9
10pub(crate) mod errors;
11
12pub(crate) mod conv;
13
14pub(crate) mod num;
15
16#[cfg(not(feature = "no_os"))]
17mod os;
18
19use std::cell::LazyCell;
20use std::io::{Write, BufRead, ErrorKind};
21use std::ptr::NonNull;
22use std::str::FromStr;
23use std::sync::{Arc, Mutex, mpsc::{Receiver, TryRecvError, RecvTimeoutError}};
24use linefeed::{DefaultTerminal, Interface};
25use bitvec::prelude::*;
26use malachite::{Natural, Integer, Rational};
27use malachite::base::num::arithmetic::traits::{DivRem, NegAssign, Pow};
28use malachite::base::num::basic::traits::{NegativeOne, Zero, One};
29use malachite::base::num::conversion::traits::{ConvertibleFrom, PowerOf2DigitIterable, PowerOf2Digits, RoundingFrom, WrappingFrom};
30use malachite::base::num::random::RandomPrimitiveInts;
31use malachite::base::rational_sequences::RationalSequence;
32use malachite::base::rounding_modes::RoundingMode;
33
34pub const STATE_FILE_HEADER: [u8;20] = *b"# ADC state file v1\n";
36
37struct LineEditor(Interface<DefaultTerminal>);
38impl Default for LineEditor {
39	fn default() -> Self {
40		use linefeed::Signal::*;
41		let iface = Interface::new("").unwrap();
42		iface.set_report_signal(Break, true);
44		iface.set_report_signal(Interrupt, true);
45		iface.set_report_signal(Quit, true);
46		Self(iface)
47	}
48}
49
50pub trait ReadLine {
54	fn read_line(&mut self) -> std::io::Result<String>;
58
59	fn clear_history(&mut self);
61}
62impl<T: BufRead> ReadLine for T {
63	fn read_line(&mut self) -> std::io::Result<String> {
64		let mut buf = String::new();
65		self.read_line(&mut buf)?;
66		Ok(buf)
67	}
68
69	fn clear_history(&mut self) {
70		}
72}
73impl ReadLine for LineEditor {
74	fn read_line(&mut self) -> std::io::Result<String> {
75		use linefeed::{ReadResult, Signal};
76		match self.0.read_line() {
77			Ok(ReadResult::Input(s)) => {
78				self.0.add_history_unique(s.clone());
79				Ok(s)
80			},
81			Ok(ReadResult::Eof) => {Err(ErrorKind::UnexpectedEof.into())},
82			Ok(ReadResult::Signal(sig)) => {
83				self.0.cancel_read_line()?;
84				match sig {
85					Signal::Break | Signal::Interrupt | Signal::Quit => {Err(ErrorKind::Interrupted.into())},
86					Signal::Continue => {Err(std::io::Error::other("Unhandled SIGCONT"))},
87					Signal::Suspend => {Err(std::io::Error::other("Unhandled SIGTSTP"))},
88					Signal::Resize => {Err(std::io::Error::other("Unhandled window resize"))},
89				}
90			},
91			Err(e) => {Err(e)}
92		}
93	}
94
95	fn clear_history(&mut self) {
96		self.0.clear_history();
97	}
98}
99
100pub struct IOStreams (
102	pub Box<dyn ReadLine + Send>,
104	pub Box<dyn Write + Send>,
106	pub Box<dyn Write + Send>
108);
109impl IOStreams {
110	pub fn empty() -> Self {
112		Self (
113			Box::new(std::io::empty()),
114			Box::new(std::io::empty()),
115			Box::new(std::io::empty())
116		)
117	}
118
119	pub fn process() -> Self {
121		Self (
122			Box::new(LineEditor::default()),
123			Box::new(std::io::stdout()),
124			Box::new(std::io::stderr())
125		)
126	}
127}
128
129#[derive(Debug, PartialEq, Eq, Clone, Copy)]
131pub enum LogLevel {
132	Normal,
134	Debug,
136	Quiet
138}
139
140lazy_static::lazy_static! {
141	pub(crate) static ref RE_CACHE: RegexCache = RegexCache::default();
142}
143
144fn rng_preset(bytes: [u8; 32]) -> RandomPrimitiveInts<u64> {
145	malachite::base::num::random::random_primitive_ints(malachite::base::random::Seed::from_bytes(bytes))
146}
147
148fn rng_os() -> RandomPrimitiveInts<u64> {
149	let mut bytes = [0u8; 32];
150	getrandom::fill(&mut bytes).unwrap();
151	rng_preset(bytes)
152}
153
154#[derive(Default, Clone, Copy)]
155enum Command {
156	Fn1(fns::Mon),
158
159	Fn2(fns::Dya),
161	
162	Fn3(fns::Tri),
164
165	Cmd(cmds::Cmd),
167
168	Exec,
170
171	ExecR,
173
174	Lit,
176
177	Space,
179
180	#[default] Wrong,
182}
183
184const CMDS: [Command; 256] = {
186	use Command::*;
187	use fns::*;
188	use cmds::*;
189	[
190		Space,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Space,		Space,		Space,		Space,		Space,		Wrong,		Wrong,
192
193		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,		Wrong,
195
196		Space,		Fn1(neg),	Exec,		Space,		Wrong,		Fn2(r#mod),	Wrong,		Lit,		Exec,		Exec,		Fn2(mul),	Fn2(add),	Wrong,		Fn2(sub),	Lit,		Fn2(div),
198
199		Lit,		Lit,		Lit,		Lit,		Lit,		Lit,		Lit,		Lit,		Lit,		Lit,		Exec,		Wrong,		Fn2(lt),	Fn2(eq),	Fn2(gt),	Exec,
201
202		Lit,		Wrong,		Wrong,		Cmd(cln),	Exec,		Wrong,		Lit,		Fn2(logb),	Wrong,		Cmd(gi),	ExecR,		Cmd(gk),	ExecR,		Cmd(gm),	Wrong,		Cmd(go),
204
205		Exec,		Exec,		Exec,		ExecR,		Lit,		Wrong,		Wrong,		Wrong,		ExecR,		Wrong,		ExecR,		Lit,		Wrong,		Wrong,		Fn2(pow),	Exec,
207
208		Exec,		Exec,		Wrong,		Cmd(cls),	Exec,		Wrong,		Exec,		Fn1(log),	Wrong,		Cmd(si),	ExecR,		Cmd(sk),	ExecR,		Cmd(sm),	Wrong,		Cmd(so),
210
211		Exec,		Exec,		Cmd(rev),	ExecR,		Wrong,		Wrong,		Wrong,		Exec,		Exec,		Wrong,		Fn1(disc),	Cmd(cbo),	Fn3(bar),	Cmd(cbc),	Fn2(euc),	Wrong,
213
214		Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,
216		Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,
217		Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,
218		Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong,Wrong
219	]
220};
221
222fn byte_cmd(b: u8) -> Command {
223	unsafe {	*CMDS.get_unchecked(b as usize)
225	}
226}
227
228fn string_or_bytes(v: &[u8]) -> String {
229	str::from_utf8(v).map(|s| s.to_owned()).unwrap_or_else(|_| {
230		let mut res = String::from("(not UTF-8: [");
231		for b in v {
232			res += &format!("\\{b:02X}");
233		}
234		res += "])";
235		res
236	})
237}
238
239fn upper_hex_to_nibble(b: u8) -> Option<u8> {
240	match b {
241		b'0'..=b'9' => Some(unsafe{b.unchecked_sub(0x30)}),	b'A'..=b'F' => Some(unsafe{b.unchecked_sub(0x37)}),
243		_ => None
244	}
245}
246
247fn mixed_ascii_to_digit(b: u8) -> Option<u8> {
248	match b {
249		b'0'..=b'9' => Some(unsafe{b.unchecked_sub(0x30)}),	b'A'..=b'Z' => Some(unsafe{b.unchecked_sub(0x37)}),
251		b'a'..=b'z' => Some(unsafe{b.unchecked_sub(0x57)}),
252		_ => None
253	}
254}
255
256fn reg_index_nice(ri: &Rational) -> String {
257	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 + "]")	})
261		.unwrap_or_else(|| {
262			num::nauto(ri, DEFAULT_PARAMS.0, &DEFAULT_PARAMS.2)	})
264}
265
266#[derive(Clone, Copy, Debug, PartialEq)]
268#[must_use] pub enum ExecResult {
269	Finished,
271
272	SoftQuit(u8),
274
275	HardQuit(u8)
277}
278
279#[cold] #[inline(never)] pub fn interpreter(
298		st: &mut State,
299		start: Utf8Iter,
300		io: Arc<Mutex<IOStreams>>,
301		mut ll: LogLevel,
302		kill: Option<&Receiver<()>>,
303		mut restrict: bool
304	) -> std::io::Result<ExecResult>
305{
306	use ExecResult::*;
307
308	let th_name = if kill.is_some() {
309		std::thread::current().name().unwrap().to_owned()
310	}
311	else {
312		String::new()
313	};
314
315	let mut pbuf: Option<String> = None;	let mut elatch: Option<(Natural, char, String)> = None;
318
319	macro_rules! synerr {
320		($c:expr, $s:expr) => {
321			if ll != LogLevel::Quiet {
322				let err = &mut io.lock().unwrap().2;
323				writeln!(err, "! {th_name}{}: {}", $c, $s)?;
324				err.flush()?;
325			}
326			elatch = Some((Natural::ZERO, $c, $s.into()));
327		};
328    	($c:expr, $f:literal, $($s:expr),*) => {
329			let s = format!($f, $($s),*);
330			if ll != LogLevel::Quiet {
331				let err = &mut io.lock().unwrap().2;
332				writeln!(err, "! {th_name}{}: {}", $c, s)?;
333				err.flush()?;
334			}
335			elatch = Some((Natural::ZERO, $c, s));
336		};
337	}
338
339	macro_rules! valerr {
340    	($c:expr, $s:expr) => {
341			if ll != LogLevel::Quiet {
342				let err = &mut io.lock().unwrap().2;
343				writeln!(err, "? {th_name}{}: {}", $c, $s)?;
344				err.flush()?;
345			}
346			elatch = Some((Natural::ZERO, $c, $s.into()));
347		};
348		($c:expr, $f:literal, $($s:expr),*) => {
349			let s = format!($f, $($s),*);
350			if ll != LogLevel::Quiet {
351				let err = &mut io.lock().unwrap().2;
352				writeln!(err, "? {th_name}{}: {}", $c, s)?;
353				err.flush()?;
354			}
355			elatch = Some((Natural::ZERO, $c, s));
356		};
357	}
358
359	let mut rptr: Option<Rational> = None;	let mut rng = LazyCell::new(rng_os);
379
380	let mut call: Vec<(Utf8Iter, Natural)> = vec![(start, Natural::const_from(1))];
381
382	'mac: while let Some((mac, count)) = call.last_mut() {	*count -= Natural::ONE;
384		let mut alt = false;
385
386		let mut abuf: Vec<Value> = Vec::new();	let mut dest: Vec<NonNull<Vec<Value>>> = Vec::new();	macro_rules! push {
390    		($v:expr) => {
391				if let Some(p) = dest.last_mut() {
392					unsafe {
393						p.as_mut().push($v);	}
395				}
396				else {
397					st.mstk.push(Arc::new($v));
398				}
399			};
400		}
401		macro_rules! append {
403    		($v:expr) => {
404				if let Some(p) = dest.last_mut() {
405					unsafe {
406						p.as_mut().append(&mut $v);	}
408				}
409				else {
410					for val in $v {
411						st.mstk.push(Arc::new(val));
412					}
413				}
414			};
415		}
416
417		'cmd: while let Some(b) = mac.next() {	if let Some(rx) = kill {	match rx.try_recv() {
420					Ok(()) => {	return Ok(Finished);
422					},
423					Err(TryRecvError::Empty) => {	},
426					Err(TryRecvError::Disconnected) => {	unreachable!()
428					}
429				}
430			}
431			
432			if let Some(e) = &mut elatch {	e.0 += Natural::ONE;
434			}
435
436			use Command::*;
437			match byte_cmd(b) {
438				Fn1(mon) => {
439					if let Some(va) = st.mstk.pop() {
440						match fns::exec1(mon, &va, alt) {
441							Ok(vz) => {
442								push!(vz);
443							}
444							Err(e) => {
445								st.mstk.push(va);
446								valerr!(b as char, e.to_string());
447							}
448						}
449					}
450					else {
451						synerr!(b as char, "Expected 1 argument, 0 given");
452					}
453				},
454				Fn2(dya) => {
455					if let Some(vb) = st.mstk.pop() {
456						if let Some(va) = st.mstk.pop() {
457							match fns::exec2(dya, &va, &vb, alt) {
458								Ok(vz) => {
459									push!(vz);
460								}
461								Err(e) => {
462									st.mstk.push(va);
463									st.mstk.push(vb);
464									valerr!(b as char, e.to_string());
465								}
466							}
467						}
468						else {
469							st.mstk.push(vb);
470							synerr!(b as char, "Expected 2 arguments, 1 given");
471						}
472					}
473					else {
474						synerr!(b as char, "Expected 2 arguments, 0 given");
475					}
476				},
477				Fn3(tri) => {
478					if let Some(vc) = st.mstk.pop() {
479						if let Some(vb) = st.mstk.pop() {
480							if let Some(va) = st.mstk.pop() {
481								match fns::exec3(tri, &va, &vb, &vc, alt) {
482									Ok(vz) => {
483										push!(vz);
484									}
485									Err(e) => {
486										st.mstk.push(va);
487										st.mstk.push(vb);
488										st.mstk.push(vc);
489										valerr!(b as char, e.to_string());
490									}
491								}
492							}
493							else {
494								st.mstk.push(vb);
495								st.mstk.push(vc);
496								synerr!(b as char, "Expected 3 arguments, 2 given");
497							}
498						}
499						else {
500							st.mstk.push(vc);
501							synerr!(b as char, "Expected 3 arguments, 1 given");
502						}
503					}
504					else {
505						synerr!(b as char, "Expected 3 arguments, 0 given");
506					}
507				},
508				Cmd(cmd) => {
509					match cmd(st) {
510						Ok(mut v) => {
511							append!(v);
512						}
513						Err(e) => {
514							if let Some(se) = e.strip_suffix('!') {
515								synerr!(b as char, se);
516							}
517							else {
518								valerr!(b as char, e);
519							}
520						}
521					}
522				},
523				Exec => {
524					match b {
525						b'`' => {	alt = true;
527							continue 'cmd;	},
529						b':' => {	if let Some(va) = st.mstk.pop() {
531								if let Value::N(r) = &*va {
532									rptr = Some(r.clone());
533								}
534								else {
535									let ta = errors::TypeLabel::from(&*va);
536									st.mstk.push(va);
537									synerr!(':', "Expected a number, {} given", ta);
538								}
539							}
540							else {
541								synerr!(':', "Expected 1 argument, 0 given");
542							}
543						},
544						b'd' => {
545							if let Some(v) = st.mstk.last() {
546								if let Some(p) = dest.last_mut() {	unsafe {
548										p.as_mut().push((**v).clone());	}
550								}
551								else {
552									st.mstk.push(Arc::clone(v));
553								}
554							}
555							else {
556								synerr!('d', "Stack is empty");
557							}
558						},
559						b'D' => {
560							if let Some(va) = st.mstk.pop() {
561								if let Value::N(r) = &*va {
562									match usize::try_from(r) {
563										Ok(0) => {},	Ok(u) => {
565											if let Some(from) = st.mstk.len().checked_sub(u) {
566												if let Some(p) = dest.last_mut() {	for v in &st.mstk[from..] {
568														unsafe {
569															p.as_mut().push((**v).clone());	}
571													}
572												}
573												else {
574													st.mstk.extend_from_within(from..);
575												}
576											}
577											else {
578												st.mstk.push(va);
579												valerr!('D', "Can't duplicate {} values, stack depth is {}", u, st.mstk.len() - 1);
580											}
581										}
582										Err(_) => {
583											let vs = va.to_string();
584											st.mstk.push(va);
585											valerr!('D', "Can't possibly duplicate {} values", vs);
586										}
587									}
588								}
589								else {
590									let ta = errors::TypeLabel::from(&*va);
591									st.mstk.push(va);
592									synerr!('D', "Expected a number, {} given", ta);
593								}
594							}
595							else {
596								synerr!('D', "Expected 1 argument, 0 given");
597							}
598						},
599						b'R' => {	if let Some(va) = st.mstk.pop() {
601								if let Value::N(r) = &*va {
602									match usize::try_from(r) {
603										Ok(0) => {},	Ok(u) => {
605											if let Some(from) = st.mstk.len().checked_sub(u) {
606												if alt {st.mstk[from..].rotate_left(1);}
607												else {st.mstk[from..].rotate_right(1);}
608											}
609											else {
610												st.mstk.push(va);
611												valerr!('R', "Can't rotate {} values, stack depth is {}", u, st.mstk.len() - 1);
612											}
613										}
614										Err(_) => {
615											let vs = va.to_string();
616											st.mstk.push(va);
617											valerr!('R', "Can't possibly rotate {} values", vs);
618										}
619									}
620								}
621								else {
622									let ta = errors::TypeLabel::from(&*va);
623									st.mstk.push(va);
624									synerr!('R', "Expected a number, {} given", ta);
625								}
626							}
627							else {
628								synerr!('R', "Expected 1 argument, 0 given");
629							}
630						},
631						b'?' => {	let res = {io.lock().unwrap().0.read_line()};	match res {
634								Ok(s) => {
635									push!(Value::S(s));
636								},
637								Err(e) => {
638									match e.kind() {
639										ErrorKind::Interrupted => {
640											valerr!('?', "Interrupted");
641										},
642										ErrorKind::UnexpectedEof => {
643											push!(Value::S(String::new()));
644										},
645										_ => {
646											return Err(e);
647										}
648									}
649								}
650							}
651						},
652						b'p' => {	if let Some(va) = st.mstk.pop() {
654								let vs = va.display(st.params.get_k(), st.params.get_o(), st.params.get_m(), alt);
655								if let Some(s) = &mut pbuf {
656									s.push_str(&vs);
657									s.push('\n');
658								}
659								else {
660									let out = &mut io.lock().unwrap().1;
661									writeln!(out, "{}", vs)?;
662									out.flush()?;
663								}
664							}
665							else {
666								synerr!('p', "Expected 1 argument, 0 given");
667							}
668						},
669						b'P' => {	if let Some(va) = st.mstk.pop() {
671								let vs = va.display(st.params.get_k(), st.params.get_o(), st.params.get_m(), alt);
672								if let Some(s) = &mut pbuf {
673									s.push_str(&vs);
674								}
675								else {
676									let out = &mut io.lock().unwrap().1;
677									write!(out, "{}", vs)?;
678									out.flush()?;
679								}
680							}
681							else {
682								synerr!('P', "Expected 1 argument, 0 given");
683							}
684						},
685						b'"' => {	if let Some(s) = pbuf.take() {	push!(Value::S(s));
688							}
689							else {	pbuf = Some(String::new());
691							}
692						},
693						b'(' => {	let nn = if let Some(p) = dest.last_mut() { unsafe {	p.as_mut().push(Value::A(Vec::new()));	let Value::A(new) = &mut p.as_mut().last_mut().unwrap_unchecked() else { std::hint::unreachable_unchecked() };	NonNull::from(new)
698							}}
699							else {
700								NonNull::from(&mut abuf)	};
702							dest.push(nn);
703						},
704						b')' => {	if dest.pop().is_some() {
706								if dest.is_empty() {	st.mstk.push(Arc::new(Value::A(std::mem::take(&mut abuf))));	}
709							}
710							else {
711								synerr!(')', "Mismatched closing ')'");
712							}
713						},
714						b'x' => {
715							if let Some(top) = st.mstk.pop() {
716								let sec = st.mstk.pop();
717								match Utf8Iter::from_vals(&top, sec.as_deref()) {
718									Ok((mut stk, ret)) => {
719										if let Some(sec) = sec && ret {	st.mstk.push(sec);
721										}
722
723										if mac.is_finished() && *count == Natural::ZERO {	call.pop();
725										}
726
727										call.append(&mut stk);
728										continue 'mac;
729									},
730									Err(e) => {
731										if let Some(sec) = sec {st.mstk.push(sec);}
732										st.mstk.push(top);
733										synerr!('x', "{}", e);
734									}
735								}
736							}
737							else {
738								synerr!('x', "Expected 1 or 2 arguments, 0 given");
739							}
740						},
741						b'q' => {
742							let u = u8::wrapping_from(&Integer::rounding_from(rptr.unwrap_or_default(), RoundingMode::Down).0);
743							return if alt {
744								Ok(HardQuit(u))
745							}
746							else {
747								Ok(SoftQuit(u))
748							};
749						},
750						b'Q' => {
751							if let Some(va) = st.mstk.pop() {
752								match &*va {
753									Value::N(r) => {
754										if let Ok(u) = usize::try_from(r) {
755											call.truncate(call.len().saturating_sub(u));
756											if !dest.is_empty() {	st.mstk.push(Arc::new(Value::A(std::mem::take(&mut abuf))));
758												dest.clear();	}
760											continue 'mac;
761										}
762										else {
763											let vs = va.to_string();
764											st.mstk.push(va);
765											valerr!('Q', "Cannot possibly break {} macros", vs);
766										}
767									},
768									_ => {
769										let ta = errors::TypeLabel::from(&*va);
770										st.mstk.push(va);
771										synerr!('Q', "Expected a number, {} given", ta);
772									}
773								}
774							}
775							else {
776								synerr!('Q', "Expected 1 argument, 0 given");
777							}
778						},
779						b'a' => {	match mac.next() {
781								Some(b) if !matches!(byte_cmd(b), Space) => {
782									match b {
783										b'a' => {
784											todo!()
785										},
786										_ => {
787											synerr!('a', "Invalid array command 'a{}'", b as char);
788										}
789									}
790								},
791								Some(_) | None => {
792									synerr!('a', "Incomplete array command 'a'");
793								}
794							}
795						},
796						b'f' => {	match mac.next() {
798								Some(b) if !matches!(byte_cmd(b), Space) => {
799									match b {
800										b'z' => {	push!(Value::N(st.mstk.len().into()));
802										},
803										b'r' => {	st.mstk.reverse();
805										},
806										b'R' => {	if let Some(va) = st.mstk.pop() {
808												if let Value::N(r) = &*va {
809													match usize::try_from(r) {
810														Ok(0) => {},	Ok(u) => {
812															if let Some(from) = st.mstk.len().checked_sub(u) {
813																st.mstk[from..].reverse();
814															}
815															else {
816																st.mstk.push(va);
817																valerr!('f', "Can't reverse {} values, stack depth is {}", u, st.mstk.len() - 1);
818															}
819														}
820														Err(_) => {
821															let vs = va.to_string();
822															st.mstk.push(va);
823															valerr!('f', "Can't possibly reverse {} values", vs);
824														}
825													}
826												}
827												else {
828													let ta = errors::TypeLabel::from(&*va);
829													st.mstk.push(va);
830													synerr!('f', "Expected a number, {} given", ta);
831												}
832											}
833											else {
834												synerr!('f', "Expected 1 argument, 0 given");
835											}
836										},
837										b'f' => {	let ri = if let Some(r) = rptr.take() {r}
839											else {
840												if matches!(mac.next().map(|b| {mac.back(); byte_cmd(b)}), None | Some(Space)) {
841													synerr!('f', "No register index");
842													alt = false;
843													continue 'cmd;
844												}
845												Rational::from(
846													match mac.try_next_char() {
847														Ok(c) => {c as u32},
848														Err(e) => {
849															*count = Natural::ZERO;
850															synerr!('\0', "Aborting invalid macro: {}", e);
851															break 'cmd;
852														}
853													}
854												)
855											};
856											let reg = st.regs.get_mut(&ri);
857											std::mem::swap(&mut st.mstk, &mut reg.v);
858										},
859										b'p' => {	for v in &st.mstk {
861												let vs = v.display(st.params.get_k(), st.params.get_o(), st.params.get_m(), alt);
862												if let Some(s) = &mut pbuf {
863													s.push_str(&vs);
864													s.push('\n');
865												}
866												else {
867													let out = &mut io.lock().unwrap().1;
868													writeln!(out, "{}", vs)?;
869													out.flush()?;
870												}
871											}
872										},
873										_ => {
874											synerr!('f', "Invalid stack command 'f{}'", b as char);
875										}
876									}
877								},
878								Some(_) | None => {
879									synerr!('f', "Incomplete stack command 'f'");
880								}
881							}
882						},
883						b'N' => {
884							match (st.mstk.pop(), alt) {
885								(Some(va), false) => {	match &*va {
887										Value::N(r) => {
888											match Natural::try_from(r) {
889												Ok(n) => {
890													push!(Value::N(Rational::from(
891														malachite::natural::random::get_random_natural_less_than(&mut rng, &n)
892													)));
893												},
894												_ => {
895													st.mstk.push(va);
896													valerr!('N', "Limit must be a natural number");
897												}
898											}
899										},
900										_ => {
901											let t = errors::TypeLabel::from(&*va);
902											st.mstk.push(va);
903											synerr!('N', "Expected a number, {} given", t);
904										}
905									}
906								}
907								(Some(va), true) => {	match &*va {
909										Value::N(r) => {
910											match Integer::try_from(r) {
911												Ok(Integer::NEGATIVE_ONE) => {	rng = LazyCell::new(rng_os);
913												},
914												Ok(i) if Natural::convertible_from(&i) => {	let n= unsafe { Natural::try_from(i).unwrap_unchecked() };	let mut bytes: Vec<u8> = PowerOf2DigitIterable::<u8>::power_of_2_digits(&n, 8).take(32).collect();
917													bytes.resize(32, 0);
918													*rng = rng_preset( unsafe { <[u8; 32]>::try_from(bytes).unwrap_unchecked() } );
919												},
920												_ => {
921													st.mstk.push(va);
922													valerr!('N', "Seed must be a natural number or `1");
923												}
924											}
925										},
926										_ => {
927											let t = errors::TypeLabel::from(&*va);
928											st.mstk.push(va);
929											synerr!('N', "Expected a number, {} given", t);
930										}
931									}
932								}
933								(None, _) => {
934									synerr!('N', "Expected 1 argument, 0 given");
935								}
936							}
937						},
938						b'w' => {	if let Some(va) = st.mstk.pop() {
940								if let Value::N(r) = &*va {
941									if let Some(dur) = Natural::try_from(r).ok().and_then(|n| {
942										let (s, ns) = n.div_rem(Natural::const_from(1_000_000_000));
943										u64::try_from(&s).ok().map(|s| {
944											let ns = unsafe { u32::try_from(&ns).unwrap_unchecked() };	std::time::Duration::new(s, ns)
946										})
947									}) {
948										if let Some(rx) = kill {
949											match rx.recv_timeout(dur) {
950												Ok(()) => {	return Ok(Finished);
952												},
953												Err(RecvTimeoutError::Timeout) => {	},
956												Err(RecvTimeoutError::Disconnected) => {	unreachable!()
958												}
959											}
960										}
961										else {
962											std::thread::sleep(dur);	}
964									}
965									else {
966										let vs = va.to_string();
967										st.mstk.push(va);
968										valerr!('w', "Can't possibly wait {} ns", vs);
969									}
970								}
971								else {
972									let ta = crate::errors::TypeLabel::from(&*va);
973									st.mstk.push(va);
974									synerr!('w', "Expected a number, {} given", ta);
975								}
976							}
977							else {
978								synerr!('w', "Expected 1 argument, 0 given");
979							}
980						},
981						b'_' => {	let mut word = Vec::new();
983							while let Some(b) = mac.next() {
984								if matches!(byte_cmd(b), Space) {
985									mac.back();
986									break;
987								}
988								else {
989									word.push(b);
990								}
991							}
992
993							match &word[..] {	b"restrict" => {
995									restrict = true;
996								},
997								b"quiet" => {
998									ll = LogLevel::Quiet;
999								},
1000								b"error" => {
1001									ll = LogLevel::Normal;
1002								},
1003								b"debug" => {
1004									ll = LogLevel::Debug;
1005								},
1006								b"err" => {
1007									push!(Value::A(
1008										if let Some((n, c, s)) = elatch.take() {
1009											vec![
1010												Value::N(n.into()),
1011												Value::S(c.into()),
1012												Value::S(s)
1013											]
1014										}
1015										else { vec![] }
1016									));
1017								},
1018								b"th" => {
1019									push!(Value::S(th_name.clone()));
1020								},
1021								b"trim" => {
1022									st.trim();
1023									RE_CACHE.clear();
1024								},
1025								b"clhist" => {
1026									io.lock().unwrap().0.clear_history();
1027								},
1028								b"clpar" => {
1029									st.params = ParamStk::default();
1030								},
1031								b"clall" => {
1032									st.clear_vals();
1033									RE_CACHE.clear();
1034								},
1035								_ => {
1036									#[cfg(feature = "no_os")]
1037									{
1038										synerr!('_', "Invalid word command '{}'", string_or_bytes(&word));
1039									}
1040									#[cfg(not(feature = "no_os"))]
1041									{
1042										match (restrict, os::OS_CMDS.get(&word).copied()) {
1043											(false, Some(oscmd)) => {
1044												match oscmd(st) {
1045													Ok(mut v) => {
1046														append!(v);
1047													}
1048													Err(e) => {
1049														if let Some(se) = e.strip_suffix('!') {
1050															synerr!('_', "OS command '{}': {}", string_or_bytes(&word), se);
1051														}
1052														else {
1053															valerr!('_', "OS command '{}': {}", string_or_bytes(&word), e);
1054														}
1055													}
1056												}
1057											}
1058											(true, Some(_)) => {
1059												synerr!('_', "OS command '{}' is disabled (restricted mode)", string_or_bytes(&word));
1060											},
1061											_ => {
1062												synerr!('_', "Invalid word command '{}'", string_or_bytes(&word));
1063											}
1064										}
1065									}
1066								}
1067							}
1068						},
1069						_ => unreachable!()
1070					}
1071				},
1072				ExecR => {
1073					let ri = if let Some(r) = rptr.take() {r}
1074					else {
1075						if matches!(mac.next().map(|b| {mac.back(); byte_cmd(b)}), None | Some(Space)) {
1076							synerr!(b as char, "No register index");
1077							alt = false;
1078							continue 'cmd;
1079						}
1080						Rational::from(
1081							match mac.try_next_char() {
1082								Ok(c) => {c as u32},
1083								Err(e) => {
1084									*count = Natural::ZERO;
1085									synerr!('\0', "Aborting invalid macro: {}", e);
1086									break 'cmd;
1087								}
1088							}
1089						)
1090					};
1091					match b {
1092						b'Z' => {	push!(Value::N(
1094								st.regs.try_get(&ri).map(|reg| reg.v.len().into()).unwrap_or_default()
1095							));
1096						},
1097						b's' => {
1098							if let Some(va) = st.mstk.pop() {
1099								let reg = st.regs.get_mut(&ri);
1100								if let Some(rv) = reg.v.last_mut() {
1101									*rv = va;
1102								}
1103								else {
1104									reg.v.push(va);
1105								}
1106							}
1107							else {
1108								synerr!('s', "Stack is empty");
1109							}
1110						},
1111						b'S' => {
1112							if let Some(va) = st.mstk.pop() {
1113								st.regs.get_mut(&ri).v.push(va);
1114							}
1115							else {
1116								synerr!('S', "Stack is empty");
1117							}
1118						},
1119						b'l' => {
1120							if let Some(rv) = st.regs.try_get(&ri).and_then(|reg| reg.v.last()) {
1121								if let Some(p) = dest.last_mut() {	unsafe {
1123										p.as_mut().push((**rv).clone());	}
1125								}
1126								else {
1127									st.mstk.push(Arc::clone(rv));
1128								}
1129							}
1130							else {
1131								synerr!('l', "Register {} is empty", reg_index_nice(&ri));
1132							}
1133						},
1134						b'L' => {
1135							if let Some(rv) = st.regs.try_get_mut(&ri).and_then(|reg| reg.v.pop()) {
1136								if let Some(p) = dest.last_mut() {	unsafe {
1138										p.as_mut().push((*rv).clone());	}
1140								}
1141								else {
1142									st.mstk.push(Arc::clone(&rv));
1143								}
1144							}
1145							else {
1146								synerr!('L', "Register {} is empty", reg_index_nice(&ri));
1147							}
1148						},
1149						b'X' => {
1150							if let Some(true) = st.regs.try_get(&ri).map(|reg| reg.th.is_some()) {
1151								valerr!('X', "Register {} is already running a thread", reg_index_nice(&ri));
1152							}
1153							else if let Some(top) = st.mstk.pop() {
1154								let sec = st.mstk.pop();
1155								match Utf8Iter::from_vals(&top, sec.as_deref()) {
1156									Ok((stk, ret)) => {
1157										if let Some(sec) = sec && ret {	st.mstk.push(sec);
1159										}
1160
1161										let (tx, rx) = std::sync::mpsc::channel::<()>();
1162										let tb = std::thread::Builder::new().name(format!("{th_name}{}: ", reg_index_nice(&ri)));
1163										let mut th_st = if alt { st.clone() } else { State::default() };
1164										let th_io = Arc::clone(&io);
1165
1166										match tb.spawn(move || {
1167											let mut th_res = (Vec::new(), Ok(Finished));
1168
1169											'all: for (th_start, th_count) in stk {
1170												for _ in malachite::natural::exhaustive::exhaustive_natural_range(Natural::ZERO, th_count) {
1171													match interpreter(&mut th_st, th_start.clone(), Arc::clone(&th_io), ll, Some(&rx), true) {
1172														Ok(Finished) => {continue;},
1173														Ok(er) => {
1174															th_res.1 = Ok(er);
1175															break 'all;
1176														},
1177														Err(e) => {
1178															th_res.1 = Err(e);
1179															break 'all;
1180														}
1181													}
1182												}
1183											}
1184
1185											th_res.0 = th_st.mstk;
1186											th_res
1187										}) {
1188											Ok(jh) => {
1189												st.regs.get_mut(&ri).th = Some((jh, tx));
1190											},
1191											Err(e) => {
1192												valerr!('X', "Can't spawn child thread: {}", e);
1193											}
1194										}
1195									},
1196									Err(e) => {
1197										if let Some(sec) = sec {st.mstk.push(sec);}
1198										st.mstk.push(top);
1199										synerr!('X', "{}", e);
1200									}
1201								}
1202							}
1203							else {
1204								synerr!('X', "Expected 1 or 2 arguments, 0 given");
1205							}
1206						},
1207						b'j' => {
1208							if let Some(reg) = st.regs.try_get_mut(&ri) && let Some((jh, tx)) = reg.th.take() {
1209								if alt {
1210									tx.send(()).unwrap_or_else(|_| panic!("Thread {} panicked, terminating!", reg_index_nice(&ri)));
1211								}
1212								match jh.join() {
1213									Ok(mut res) => {
1214										match res.1 {
1215											Err(e) => {
1216												valerr!('j', "IO error in thread {}: {}", reg_index_nice(&ri), e);
1217											},
1218											Ok(SoftQuit(c)) | Ok(HardQuit(c)) if c != 0 => {
1219												valerr!('j', "Thread {} exited with code {}", reg_index_nice(&ri), c);
1220											},
1221											_ => {}
1222										}
1223
1224										reg.v.append(&mut res.0);
1225									},
1226									Err(e) => {
1227										std::panic::resume_unwind(e);
1228									}
1229								}
1230							}
1231							else {
1232								valerr!('j', "Register {} is not running a thread", reg_index_nice(&ri));
1233							}
1234						},
1235						b'J' => {
1236							if let Some(Some((jh, _))) = st.regs.try_get(&ri).map(|reg| ®.th) {
1237								let mut bz = BitVec::new();
1238								bz.push(jh.is_finished());
1239								push!(Value::B(bz));
1240							}
1241							else {
1242								valerr!('J', "Register {} is not running a thread", reg_index_nice(&ri));
1243							}
1244						},
1245						_ => unreachable!()
1246					}
1247				},
1248				Lit => {
1249					match b {
1250						b'T' | b'F' => {	let mut bits = BitVec::new();
1252							bits.push(b == b'T');
1253							while let Some(b) = mac.next() {
1254								match b {
1255									b'T' => {bits.push(true);},
1256									b'F' => {bits.push(false);},
1257									_ => {
1258										mac.back();
1259										break;
1260									}
1261								}
1262							}
1263							push!(Value::B(bits));
1264						},
1265						b'\'' | b'0'..=b'9' | b'.' | b'@' => {	let mut ipart = Vec::new();
1267							let mut fpart = Vec::new();
1268							let mut rpart = Vec::new();
1269							let mut get_epart = true;
1270							let mut exp = None;
1271							let mut discard = false;
1272							let mut ibase = st.params.get_i().clone();
1273
1274							match (b == b'\'', ibase > Natural::const_from(36)) {
1275								(false, high_base) => {	mac.back();
1277									ibase = if high_base {Natural::const_from(10)} else {ibase};	while let Some(ib) = mac.next() {	let id = ib.wrapping_sub(0x30);
1280										match id {
1281											0..=9 if id < ibase => {ipart.push(Natural::from(id));},
1282											0..=9 => {
1283												synerr!('\'', "Digit {} is too high for base {}", id, ibase);
1284												discard = true;
1285											},
1286											_ => {
1287												mac.back();
1288												break;
1289											}
1290										}
1291									}
1292									match mac.next() {
1293										Some(b'.') => {	let mut recur = false;	while let Some(fb) = mac.next() {
1296												let fd = fb.wrapping_sub(0x30);
1297												match fd {
1298													0x30 if !recur => {recur = true;},	0..=9 if !recur && fd < ibase => {fpart.push(Natural::from(fd));},
1300													0..=9 if recur && fd < ibase => {rpart.push(Natural::from(fd));},
1301													0..=9 => {
1302														synerr!('\'', "Digit {} is too high for base {}", fd, ibase);
1303														discard = true;
1304													},
1305													_ => {
1306														mac.back();
1307														break;
1308													}
1309												}
1310											}
1311										},
1312										Some(_) => {mac.back();},
1313										None => {}
1314									}
1315								}
1316								(true, false) => {	while let Some(ib) = mac.next() {	if let Some(id) = mixed_ascii_to_digit(ib) {
1319											if id < ibase {ipart.push(Natural::from(id));}
1320											else {
1321												synerr!('\'', "Digit {} is too high for base {}", id, ibase);
1322												discard = true;
1323											}
1324										}
1325										else {
1326											mac.back();
1327											break;
1328										}
1329									}
1330									match mac.next() {
1331										Some(b'.') => {	let mut recur = false;	while let Some(fb) = mac.next() {
1334												if let Some(fd) = mixed_ascii_to_digit(fb) {
1335													if fd < ibase {
1336														if !recur {fpart.push(Natural::from(fd));}
1337														else {rpart.push(Natural::from(fd));}
1338													}
1339													else {
1340														synerr!('\'', "Digit {} is too high for base {}", fd, ibase);
1341														discard = true;
1342													}
1343												}
1344												else if !recur && fb == b'`' {recur = true;}
1345												else {
1346													mac.back();
1347													break;
1348												}
1349											}
1350										},
1351										Some(_) => {mac.back();},
1352										None => {}
1353									}
1354								},
1355								(true, true) => {	get_epart = false;
1357									let ns= mac.by_ref().take_while(|b| *b != b'\'').collect::<Vec<u8>>();
1358									if ns.is_empty() {
1359										synerr!('\'', "Empty any-base number");
1360										alt = false;
1361										continue 'cmd;
1362									}
1363									for nc in ns.iter() {
1364										match nc {
1365											b' ' | b'.' | b'0'..=b'9' | b'@' | b'`' => {}	wrong => {
1367												synerr!('\'', "Invalid character in any-base number: {}", string_or_bytes(&[*wrong]));
1368												alt = false;
1369												continue 'cmd;
1370											}
1371										}
1372									}
1373									let mut ms = Vec::new();
1374									match ns.split(|b| *b == b'@').collect::<Vec<&[u8]>>()[..] {
1375										[mpart] => {	ms = mpart.to_vec();
1377										},
1378										[mpart, epart] => {	ms = mpart.to_vec();
1380											let mut es = epart.to_vec();
1381											if let Some(first) = es.first_mut() && *first == b'`' { *first = b'-'; }
1382											match String::from_utf8(es) {
1383												Ok(es) => {
1384													match es.parse::<i64>() {
1385														Ok(i) => { exp = Some(i); },
1386														Err(e) => {
1387															use std::num::IntErrorKind::*;
1388															match e.kind() {
1389																Empty => { exp = Some(0); },
1390																InvalidDigit => {
1391																	valerr!('\'', "Invalid exponent: {}", es);
1392																	alt = false;
1393																	continue 'cmd;
1394																},
1395																PosOverflow | NegOverflow => {
1396																	valerr!('\'', "Exponent {} is unrepresentable", es);
1397																	alt = false;
1398																	continue 'cmd;
1399																},
1400																_ => { unreachable!() }
1401															}
1402														}
1403													}
1404												},
1405												_ => { unreachable!() }
1406											}
1407										},
1408										ref v => {
1409											synerr!('\'', "{} exponent signs (@) in any-base number", v.len() - 1);
1410											drop(ms);
1411											alt = false;
1412											continue 'cmd;
1413										}
1414									}
1415									let mut is = Vec::new();
1416									let mut frs = Vec::new();
1417									match ms.split(|b| *b == b'.').collect::<Vec<&[u8]>>()[..] {
1418										[ipart] => {
1419											is = ipart.to_vec();
1420										},
1421										[ipart, fpart] => {
1422											is = ipart.to_vec();
1423											frs = fpart.to_vec();
1424										},
1425										ref v => {
1426											synerr!('\'', "{} fractional points (.) in any-base number", v.len() - 1);
1427											drop(is);
1428											alt = false;
1429											continue 'cmd;
1430										}
1431									}
1432									if is.contains(&b'`') {
1433										synerr!('\'', "Negative sign (`) inside any-base number");
1434										alt = false;
1435										continue 'cmd;
1436									}
1437									let mut fs = Vec::new();
1438									let mut rs = Vec::new();
1439									match frs.split(|b| *b == b'`').collect::<Vec<&[u8]>>()[..] {
1440										[fpart] => {
1441											fs = fpart.to_vec();
1442										},
1443										[fpart, rpart] => {
1444											fs = fpart.to_vec();
1445											rs = rpart.to_vec();
1446										},
1447										ref v => {
1448											synerr!('\'', "{} recurring marks (`) in any-base number", v.len() - 1);
1449											drop(fs);
1450											alt = false;
1451											continue 'cmd;
1452										}
1453									}
1454									if !is.is_empty() { for id in is.split(|b| *b == b' ') {
1455										let id = str::from_utf8(id).unwrap();
1456										ipart.push(Natural::from_str(id).unwrap());
1457									}}
1458									if !fs.is_empty() { for fd in fs.split(|b| *b == b' ') {
1459										let fd = str::from_utf8(fd).unwrap();
1460										fpart.push(Natural::from_str(fd).unwrap());
1461									}}
1462									if !rs.is_empty() { for rd in rs.split(|b| *b == b' ') {
1463										let rd = str::from_utf8(rd).unwrap();
1464										rpart.push(Natural::from_str(rd).unwrap());
1465									}}
1466									for d in ipart.iter().chain(fpart.iter()).chain(rpart.iter()) {
1467										if *d >= ibase {
1468											synerr!('\'', "Digit {} is too high for base {}", d, ibase);
1469											alt = false;
1470											continue 'cmd;
1471										}
1472									}
1473								}
1474							}
1475
1476							let m_empty = ipart.is_empty() && fpart.is_empty() && rpart.is_empty();	let mut r;
1478							if m_empty {
1479								r = Rational::ZERO;
1480							}
1481							else {
1482								ipart.reverse();	r = Rational::from_digits(&ibase, ipart, RationalSequence::from_vecs(fpart, rpart));
1484								if alt {r.neg_assign();}	}
1486
1487							if get_epart {
1488								match mac.next() {
1489									Some(b'@') => {    let mut es = String::new();
1491										let mut eneg = false;    while let Some(eb) = mac.next() {
1493											match eb {
1494												b'`' if !eneg => { es.push('-'); }
1495												b'0'..=b'9' => { es.push(eb as char); }
1496												_ => {
1497													mac.back();
1498													break;
1499												}
1500											}
1501											eneg = true;    }
1503										if es.is_empty() { es.push('0'); }
1504										if m_empty { r = Rational::ONE; }    if let Ok(i) = es.parse::<i64>() {
1506											r *= Rational::from(st.params.get_i()).pow(i);    }
1508										else {
1509											valerr!('\'', "Exponent {} is unrepresentable", es);
1510											discard = true;
1511										}
1512									}
1513									Some(_) => { mac.back(); }
1514									None => {}
1515								}
1516							}
1517							else if let Some(i) = exp {
1518       							if m_empty { r = Rational::ONE; }    r *= Rational::from(ibase).pow(i);    }
1521
1522							if !discard {
1523								push!(Value::N(r));
1524							}
1525						},
1526						b'[' => {	let mut bytes = Vec::new();
1528							let mut discard = false;
1529							let mut nest = 1usize;
1530							while let Some(b) = mac.next() {
1531								match b {
1532									b'[' => {
1533										nest = unsafe { nest.unchecked_add(1) };
1534										bytes.push(b'[');
1535									},
1536									b']' => {
1537										nest = unsafe { nest.unchecked_sub(1) };
1538										if nest == 0 {
1539											break;
1540										}
1541										else {
1542											bytes.push(b']');
1543										}
1544									},
1545									b'\\' => {	match mac.next() {
1547											Some(b'a') => {bytes.push(0x07);},		Some(b'b') => {bytes.push(0x08);},		Some(b't') => {bytes.push(0x09);},		Some(b'n') => {bytes.push(0x0A);},		Some(b'v') => {bytes.push(0x0B);},		Some(b'f') => {bytes.push(0x0C);},		Some(b'r') => {bytes.push(0x0D);},		Some(b'e') => {bytes.push(0x1B);},		Some(b'[') => {bytes.push(b'[');},		Some(b']') => {bytes.push(b']');},		Some(b'\\') => {bytes.push(b'\\');},	Some(b0) => {							if let Some(high) = upper_hex_to_nibble(b0) {	if let Some(b1) = mac.next() {
1561														if let Some(low) = upper_hex_to_nibble(b1) {
1562															bytes.push(high << 4 | low);
1563														}
1564														else {
1565															synerr!('[', "Invalid byte escape: \\{}{}", b0 as char, b1 as char);
1566															discard = true;
1567														}
1568													}
1569													else {
1570														synerr!('[', "Incomplete byte escape: \\{}", b0 as char);
1571														discard = true;
1572													}
1573												}
1574												else {	mac.back();
1576													match mac.try_next_char() {
1577														Ok(c) => {
1578															synerr!('[', "Invalid character escape: \\{} (U+{:04X})", c, c as u32);
1579															discard = true;
1580														},
1581														Err(e) => {
1582															*count = Natural::ZERO;
1583															synerr!('\0', "Aborting invalid macro: {}", e);
1584															break 'cmd;
1585														}
1586													}
1587												}
1588											},
1589											None => {
1590												synerr!('[', "Incomplete character escape: \\");
1591												discard = true;
1592											}
1593										}
1594									},
1595									_ => {
1596										bytes.push(b);
1597									}
1598								}
1599							}
1600							if !discard {
1601								match String::try_from(Utf8Iter::from(bytes)) {
1602									Ok(s) => {
1603										push!(Value::S(s));
1604									},
1605									Err(e) => {
1606										synerr!('[', "Invalid string: {}", e);
1607									}
1608								}
1609							}
1610						},
1611						_ => unreachable!()
1612					}
1613				},
1614				Space if b == b'#' => {	mac.find(|b| *b == b'\n');
1616				},
1617				Space => {
1618					},
1620				Wrong => {
1621					mac.back();
1622					match mac.try_next_char() {
1623						Ok(c) => {
1624							synerr!(c, "Invalid command: {} (U+{:04X})", c, c as u32);
1625						},
1626						Err(e) => {
1627							*count = Natural::ZERO;
1628							synerr!('\0', "Aborting invalid macro: {}", e);
1629							break 'cmd;
1630						}
1631					}
1632				}
1633			}
1634			
1635			alt = false;	}	if !dest.is_empty() {	st.mstk.push(Arc::new(Value::A(std::mem::take(&mut abuf))));
1640			dest.clear();	}
1642
1643		if *count == Natural::ZERO {	call.pop();
1645		}
1646		else {	mac.rewind();
1648		}
1649	}	Ok(Finished)
1652}