1use std::collections::vec_deque;
5use std::collections::VecDeque;
6use std::env::consts::{ARCH, OS};
7use std::io::{stdout, BufWriter, Write};
8use std::mem;
9use std::process;
10use std::slice::{Iter, IterMut};
11
12use crate::config::ErgConfig;
13use crate::consts::{BUILD_DATE, GIT_HASH_SHORT, SEMVER};
14use crate::error::{ErrorDisplay, ErrorKind, Location, MultiErrorDisplay};
15use crate::io::{Input, InputKind};
16use crate::{addr_eq, chomp, log, switch_unreachable};
17
18pub trait DequeStream<T>: Sized {
19 fn payload(self) -> VecDeque<T>;
20 fn ref_payload(&self) -> &VecDeque<T>;
21 fn ref_mut_payload(&mut self) -> &mut VecDeque<T>;
22
23 #[inline]
24 fn is_empty(&self) -> bool {
25 self.ref_payload().is_empty()
26 }
27
28 #[inline]
29 fn push(&mut self, elem: T) {
30 self.ref_mut_payload().push_back(elem);
31 }
32
33 #[inline]
34 fn push_front(&mut self, elem: T) {
35 self.ref_mut_payload().push_front(elem);
36 }
37
38 fn pop_front(&mut self) -> Option<T> {
39 self.ref_mut_payload().pop_front()
40 }
41
42 #[inline]
43 fn get(&self, idx: usize) -> Option<&T> {
44 self.ref_payload().get(idx)
45 }
46
47 #[inline]
48 fn first(&self) -> Option<&T> {
49 self.ref_payload().front()
50 }
51
52 #[inline]
53 fn last(&self) -> Option<&T> {
54 self.ref_payload().back()
55 }
56
57 #[inline]
58 fn iter(&self) -> vec_deque::Iter<'_, T> {
59 self.ref_payload().iter()
60 }
61
62 #[inline]
63 fn len(&self) -> usize {
64 self.ref_payload().len()
65 }
66}
67
68#[macro_export]
69macro_rules! impl_displayable_deque_stream_for_wrapper {
70 ($Strc: ident, $Inner: ident) => {
71 impl $Strc {
72 pub const fn new(v: VecDeque<$Inner>) -> $Strc {
73 $Strc(v)
74 }
75 pub fn empty() -> $Strc {
76 $Strc(VecDeque::new())
77 }
78 #[inline]
79 pub fn with_capacity(capacity: usize) -> $Strc {
80 $Strc(VecDeque::with_capacity(capacity))
81 }
82 }
83
84 impl Default for $Strc {
85 #[inline]
86 fn default() -> $Strc {
87 $Strc::with_capacity(0)
88 }
89 }
90
91 impl std::ops::Index<usize> for $Strc {
92 type Output = $Inner;
93 fn index(&self, idx: usize) -> &Self::Output {
94 erg_common::traits::DequeStream::get(self, idx).unwrap()
95 }
96 }
97
98 impl From<$Strc> for VecDeque<$Inner> {
99 fn from(item: $Strc) -> VecDeque<$Inner> {
100 item.payload()
101 }
102 }
103
104 impl std::fmt::Display for $Strc {
105 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
106 write!(
107 f,
108 "[{}]",
109 erg_common::fmt_iter(self.iter()).replace("\n", "\\n")
110 )
111 }
112 }
113
114 impl IntoIterator for $Strc {
115 type Item = $Inner;
116 type IntoIter = std::collections::vec_deque::IntoIter<Self::Item>;
117 fn into_iter(self) -> Self::IntoIter {
118 self.payload().into_iter()
119 }
120 }
121
122 impl FromIterator<$Inner> for $Strc {
123 fn from_iter<I: IntoIterator<Item = $Inner>>(iter: I) -> Self {
124 $Strc(iter.into_iter().collect())
125 }
126 }
127
128 impl $crate::traits::DequeStream<$Inner> for $Strc {
129 #[inline]
130 fn payload(self) -> VecDeque<$Inner> {
131 self.0
132 }
133 #[inline]
134 fn ref_payload(&self) -> &VecDeque<$Inner> {
135 &self.0
136 }
137 #[inline]
138 fn ref_mut_payload(&mut self) -> &mut VecDeque<$Inner> {
139 &mut self.0
140 }
141 }
142 };
143}
144
145pub trait Stream<T>: Sized {
146 fn payload(self) -> Vec<T>;
147 fn ref_payload(&self) -> &Vec<T>;
148 fn ref_mut_payload(&mut self) -> &mut Vec<T>;
149
150 #[inline]
151 fn clear(&mut self) {
152 self.ref_mut_payload().clear();
153 }
154
155 #[inline]
156 fn len(&self) -> usize {
157 self.ref_payload().len()
158 }
159
160 fn size(&self) -> usize {
161 std::mem::size_of::<Vec<T>>() + std::mem::size_of::<T>() * self.ref_payload().capacity()
162 }
163
164 #[inline]
165 fn is_empty(&self) -> bool {
166 self.ref_payload().is_empty()
167 }
168
169 #[inline]
170 fn insert(&mut self, idx: usize, elem: T) {
171 self.ref_mut_payload().insert(idx, elem);
172 }
173
174 #[inline]
175 fn remove(&mut self, idx: usize) -> T {
176 self.ref_mut_payload().remove(idx)
177 }
178
179 #[inline]
180 fn push(&mut self, elem: T) {
181 self.ref_mut_payload().push(elem);
182 }
183
184 fn append<S: Stream<T>>(&mut self, s: &mut S) {
185 self.ref_mut_payload().append(s.ref_mut_payload());
186 }
187
188 #[inline]
189 fn pop(&mut self) -> Option<T> {
190 self.ref_mut_payload().pop()
191 }
192
193 fn lpop(&mut self) -> Option<T> {
194 let len = self.len();
195 if len == 0 {
196 None
197 } else {
198 Some(self.ref_mut_payload().remove(0))
199 }
200 }
201
202 #[inline]
203 fn get(&self, idx: usize) -> Option<&T> {
204 self.ref_payload().get(idx)
205 }
206
207 #[inline]
208 fn get_mut(&mut self, idx: usize) -> Option<&mut T> {
209 self.ref_mut_payload().get_mut(idx)
210 }
211
212 #[inline]
213 fn first(&self) -> Option<&T> {
214 self.ref_payload().first()
215 }
216
217 #[inline]
218 fn first_mut(&mut self) -> Option<&mut T> {
219 self.ref_mut_payload().first_mut()
220 }
221
222 #[inline]
223 fn last(&self) -> Option<&T> {
224 self.ref_payload().last()
225 }
226
227 #[inline]
228 fn last_mut(&mut self) -> Option<&mut T> {
229 self.ref_mut_payload().last_mut()
230 }
231
232 #[inline]
233 fn iter(&self) -> Iter<'_, T> {
234 self.ref_payload().iter()
235 }
236
237 #[inline]
238 fn iter_mut(&mut self) -> IterMut<'_, T> {
239 self.ref_mut_payload().iter_mut()
240 }
241
242 #[inline]
243 fn take_all(&mut self) -> Vec<T> {
244 self.ref_mut_payload().drain(..).collect()
245 }
246
247 fn extend<I>(&mut self, iter: I)
248 where
249 I: IntoIterator<Item = T>,
250 {
251 self.ref_mut_payload().extend(iter);
252 }
253
254 fn split_off(&mut self, at: usize) -> Vec<T> {
255 self.ref_mut_payload().split_off(at)
256 }
257
258 fn retain(&mut self, f: impl FnMut(&T) -> bool) {
260 self.ref_mut_payload().retain(f);
261 }
262
263 fn concat(mut self, other: Self) -> Self {
264 self.extend(other.payload());
265 self
266 }
267}
268
269#[macro_export]
270macro_rules! impl_displayable_stream_for_wrapper {
271 ($Strc: ident, $Inner: ident) => {
272 impl $Strc {
273 pub const fn new(v: Vec<$Inner>) -> $Strc {
274 $Strc(v)
275 }
276 #[inline]
277 pub fn empty() -> $Strc {
278 $Strc(Vec::with_capacity(20))
279 }
280 }
281
282 impl From<Vec<$Inner>> for $Strc {
283 #[inline]
284 fn from(errs: Vec<$Inner>) -> Self {
285 Self(errs)
286 }
287 }
288
289 impl IntoIterator for $Strc {
290 type Item = $Inner;
291 type IntoIter = std::vec::IntoIter<Self::Item>;
292 fn into_iter(self) -> Self::IntoIter {
293 self.payload().into_iter()
294 }
295 }
296
297 impl FromIterator<$Inner> for $Strc {
298 fn from_iter<I: IntoIterator<Item = $Inner>>(iter: I) -> Self {
299 $Strc(iter.into_iter().collect())
300 }
301 }
302
303 impl std::fmt::Display for $Strc {
304 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
305 write!(
306 f,
307 "[{}]",
308 erg_common::fmt_iter(self.iter()).replace("\n", "\\n")
309 )
310 }
311 }
312
313 impl Default for $Strc {
314 #[inline]
315 fn default() -> Self {
316 Self::empty()
317 }
318 }
319
320 impl std::ops::Index<usize> for $Strc {
321 type Output = $Inner;
322 fn index(&self, idx: usize) -> &Self::Output {
323 erg_common::traits::Stream::get(self, idx).unwrap()
324 }
325 }
326
327 impl erg_common::traits::Stream<$Inner> for $Strc {
328 #[inline]
329 fn payload(self) -> Vec<$Inner> {
330 self.0
331 }
332 #[inline]
333 fn ref_payload(&self) -> &Vec<$Inner> {
334 &self.0
335 }
336 #[inline]
337 fn ref_mut_payload(&mut self) -> &mut Vec<$Inner> {
338 &mut self.0
339 }
340 }
341 };
342}
343
344#[macro_export]
345macro_rules! impl_stream {
346 ($Strc: ident, $Inner: ident, $field: ident) => {
347 impl $crate::traits::Stream<$Inner> for $Strc {
348 #[inline]
349 fn payload(self) -> Vec<$Inner> {
350 self.$field
351 }
352 #[inline]
353 fn ref_payload(&self) -> &Vec<$Inner> {
354 &self.$field
355 }
356 #[inline]
357 fn ref_mut_payload(&mut self) -> &mut Vec<$Inner> {
358 &mut self.$field
359 }
360 }
361
362 impl std::ops::Index<usize> for $Strc {
363 type Output = $Inner;
364 fn index(&self, idx: usize) -> &Self::Output {
365 erg_common::traits::Stream::get(self, idx).unwrap()
366 }
367 }
368
369 impl std::ops::IndexMut<usize> for $Strc {
370 fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
371 erg_common::traits::Stream::get_mut(self, idx).unwrap()
372 }
373 }
374
375 impl From<$Strc> for Vec<$Inner> {
376 fn from(item: $Strc) -> Vec<$Inner> {
377 item.payload()
378 }
379 }
380
381 impl IntoIterator for $Strc {
382 type Item = $Inner;
383 type IntoIter = std::vec::IntoIter<Self::Item>;
384 fn into_iter(self) -> Self::IntoIter {
385 self.payload().into_iter()
386 }
387 }
388
389 impl $Strc {
390 pub fn iter(&self) -> std::slice::Iter<'_, $Inner> {
391 self.ref_payload().iter()
392 }
393 pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, $Inner> {
394 self.ref_mut_payload().iter_mut()
395 }
396 }
397 };
398 ($Strc: ident, $Inner: ident) => {
399 impl $Strc {
400 pub const fn new(v: Vec<$Inner>) -> $Strc {
401 $Strc(v)
402 }
403 pub const fn empty() -> $Strc {
404 $Strc(Vec::new())
405 }
406 #[inline]
407 pub fn with_capacity(capacity: usize) -> $Strc {
408 $Strc(Vec::with_capacity(capacity))
409 }
410 }
411
412 impl Default for $Strc {
413 #[inline]
414 fn default() -> $Strc {
415 $Strc::with_capacity(0)
416 }
417 }
418
419 impl std::ops::Index<usize> for $Strc {
420 type Output = $Inner;
421 fn index(&self, idx: usize) -> &Self::Output {
422 erg_common::traits::Stream::get(self, idx).unwrap()
423 }
424 }
425
426 impl From<$Strc> for Vec<$Inner> {
427 fn from(item: $Strc) -> Vec<$Inner> {
428 item.payload()
429 }
430 }
431
432 impl IntoIterator for $Strc {
433 type Item = $Inner;
434 type IntoIter = std::vec::IntoIter<Self::Item>;
435 fn into_iter(self) -> Self::IntoIter {
436 self.payload().into_iter()
437 }
438 }
439
440 impl FromIterator<$Inner> for $Strc {
441 fn from_iter<I: IntoIterator<Item = $Inner>>(iter: I) -> Self {
442 $Strc(iter.into_iter().collect())
443 }
444 }
445
446 impl $crate::traits::Stream<$Inner> for $Strc {
447 #[inline]
448 fn payload(self) -> Vec<$Inner> {
449 self.0
450 }
451 #[inline]
452 fn ref_payload(&self) -> &Vec<$Inner> {
453 &self.0
454 }
455 #[inline]
456 fn ref_mut_payload(&mut self) -> &mut Vec<$Inner> {
457 &mut self.0
458 }
459 }
460
461 impl $Strc {
462 pub fn iter(&self) -> std::slice::Iter<'_, $Inner> {
463 self.ref_payload().iter()
464 }
465 pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, $Inner> {
466 self.ref_mut_payload().iter_mut()
467 }
468 }
469 };
470}
471
472pub trait ImmutableStream<T>: Sized {
473 fn ref_payload(&self) -> &[T];
474 fn capacity(&self) -> usize;
475
476 #[inline]
477 fn len(&self) -> usize {
478 self.ref_payload().len()
479 }
480
481 fn size(&self) -> usize {
482 std::mem::size_of::<Vec<T>>() + std::mem::size_of::<T>() * self.capacity()
483 }
484
485 #[inline]
486 fn is_empty(&self) -> bool {
487 self.ref_payload().is_empty()
488 }
489
490 #[inline]
491 fn get(&self, idx: usize) -> Option<&T> {
492 self.ref_payload().get(idx)
493 }
494
495 #[inline]
496 fn first(&self) -> Option<&T> {
497 self.ref_payload().first()
498 }
499
500 #[inline]
501 fn last(&self) -> Option<&T> {
502 self.ref_payload().last()
503 }
504
505 #[inline]
506 fn iter(&self) -> Iter<'_, T> {
507 self.ref_payload().iter()
508 }
509}
510
511pub trait LimitedDisplay {
512 fn limited_fmt<W: std::fmt::Write>(&self, f: &mut W, limit: isize) -> std::fmt::Result;
515 fn to_string_unabbreviated(&self) -> String {
516 let mut s = "".to_string();
517 self.limited_fmt(&mut s, -1).unwrap();
518 s
519 }
520 const DEFAULT_LIMIT: isize = 10;
521}
522
523#[derive(Debug, PartialEq, Eq, Clone, Copy)]
524pub enum BlockKind {
525 Main, Assignment, ClassPriv, ClassPub, ColonCall, Error, Lambda, AtMark, MultiLineStr, ClassDef, Collections, None, }
539
540impl From<&str> for BlockKind {
541 fn from(value: &str) -> Self {
542 match value {
543 "Assignment" => BlockKind::Assignment,
544 "AtMark" => BlockKind::AtMark,
545 "ClassPriv" => BlockKind::ClassPriv,
546 "ClassPub" => BlockKind::ClassPub,
547 "ColonCall" => BlockKind::ColonCall,
548 "Error" => BlockKind::Error,
549 "Lambda" => BlockKind::Lambda,
550 "MultiLineStr" => BlockKind::MultiLineStr,
551 "ClassDef" => BlockKind::ClassDef,
552 "Collections" => BlockKind::Collections,
553 "None" => BlockKind::None,
554 _ => unimplemented!("Failed to convert to BlockKind"),
555 }
556 }
557}
558
559pub struct VirtualMachine {
560 pub codes: String,
561 pub now_block: Vec<BlockKind>,
562 pub now: BlockKind,
563 pub length: usize,
564}
565
566impl Default for VirtualMachine {
567 fn default() -> Self {
568 Self::new()
569 }
570}
571
572impl VirtualMachine {
573 pub fn new() -> Self {
574 Self {
575 codes: String::new(),
576 now_block: vec![BlockKind::Main],
577 now: BlockKind::Main,
578 length: 1,
579 }
580 }
581
582 pub fn push_block_kind(&mut self, bk: BlockKind) {
583 if self.now == BlockKind::AtMark && bk == BlockKind::AtMark {
585 return;
586 }
587 if (bk == BlockKind::ClassDef || bk == BlockKind::Assignment)
589 && self.now == BlockKind::AtMark
590 {
591 self.now_block.pop();
592 }
593 if (bk == BlockKind::ClassPriv || bk == BlockKind::ClassPub)
595 && self.now == BlockKind::ClassDef
596 {
597 self.now_block.pop();
598 }
599 self.now = bk;
600 self.now_block.push(bk);
601 if bk == BlockKind::AtMark || bk == BlockKind::ClassDef {
602 return;
603 }
604 if bk == BlockKind::MultiLineStr || bk == BlockKind::Collections {
605 self.length = 1;
606 return;
607 }
608 self.length += 1;
609 }
610
611 pub fn remove_block_kind(&mut self) {
612 self.now_block.pop().unwrap();
613 self.now = *self.now_block.last().unwrap();
614 self.length -= 1;
615 }
616
617 pub fn push_code(&mut self, src: &str) {
618 self.codes.push_str(src)
619 }
620
621 pub fn clear(&mut self) {
622 self.codes = String::new();
623 self.now_block = vec![BlockKind::Main];
624 self.now = BlockKind::Main;
625 self.length = 1;
626 }
627
628 pub fn indent(&mut self) -> String {
629 if self.now == BlockKind::MultiLineStr || self.now == BlockKind::Collections {
630 String::new()
631 } else if self.length == 0 {
632 self.length = 1;
633 " ".repeat(0)
634 } else {
635 " ".repeat(self.length - 1) }
637 }
638}
639
640#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
641pub struct ExitStatus {
642 pub code: i32,
643 pub num_warns: usize,
644 pub num_errors: usize,
645}
646
647impl ExitStatus {
648 pub const OK: ExitStatus = ExitStatus::new(0, 0, 0);
649 pub const ERR1: ExitStatus = ExitStatus::new(1, 0, 0);
650
651 pub const fn new(code: i32, num_warns: usize, num_errors: usize) -> Self {
652 Self {
653 code,
654 num_warns,
655 num_errors,
656 }
657 }
658 pub const fn compile_passed(num_warns: usize) -> Self {
659 Self::new(0, num_warns, 0)
660 }
661
662 pub const fn succeed(&self) -> bool {
663 self.code == 0 && self.num_errors == 0
664 }
665}
666
667pub trait Runnable: Sized + Default + New {
670 type Err: ErrorDisplay;
671 type Errs: MultiErrorDisplay<Self::Err>;
672 const NAME: &'static str;
673 fn cfg(&self) -> &ErgConfig;
674 fn cfg_mut(&mut self) -> &mut ErgConfig;
675 fn finish(&mut self); fn initialize(&mut self);
678 fn clear(&mut self);
680 fn eval(&mut self, src: String) -> Result<String, Self::Errs>;
681 fn exec(&mut self) -> Result<ExitStatus, Self::Errs>;
682 fn expect_block(&self, src: &str) -> BlockKind {
683 let multi_line_str = "\"\"\"";
684 if src.contains(multi_line_str) && src.rfind(multi_line_str) == src.find(multi_line_str) {
685 return BlockKind::MultiLineStr;
686 }
687 if src.trim_start().starts_with('@') {
688 return BlockKind::AtMark;
689 }
690 if src.ends_with("do!:") && !src.starts_with("do!:") {
691 return BlockKind::Lambda;
692 }
693 if src.ends_with("do:") && !src.starts_with("do:") {
694 return BlockKind::Lambda;
695 }
696 if src.ends_with(':') && !src.starts_with(':') {
697 return BlockKind::Lambda;
698 }
699 if src.ends_with('=') && !src.starts_with('=') {
700 return BlockKind::Assignment;
701 }
702 if src.ends_with('.') && !src.starts_with('.') {
703 return BlockKind::ClassPub;
704 }
705 if src.ends_with("::") && !src.starts_with("::") {
706 return BlockKind::ClassPriv;
707 }
708 if src.ends_with("=>") && !src.starts_with("=>") {
709 return BlockKind::Lambda;
710 }
711 if src.ends_with("->") && !src.starts_with("->") {
712 return BlockKind::Lambda;
713 }
714 if src.contains("Class") || src.contains("Inherit") {
715 return BlockKind::ClassDef;
716 }
717 if src.ends_with(['(', '{', '[']) {
718 return BlockKind::Collections;
719 }
720 BlockKind::None
721 }
722 fn input(&self) -> &Input {
723 &self.cfg().input
724 }
725 fn set_input(&mut self, input: Input) {
726 self.cfg_mut().input = input;
727 }
728 fn start_message(&self) -> String {
729 #[allow(clippy::const_is_empty)]
730 if GIT_HASH_SHORT.is_empty() {
731 format!("{} {SEMVER} ({BUILD_DATE}) on {ARCH}/{OS}\n", Self::NAME)
732 } else {
733 format!(
734 "{} {SEMVER} ({GIT_HASH_SHORT}, {BUILD_DATE}) on {ARCH}/{OS}\n",
735 Self::NAME
736 )
737 }
738 }
739 fn ps1(&self) -> String {
740 self.cfg().ps1.to_string()
741 }
742 fn ps2(&self) -> String {
743 self.cfg().ps2.to_string()
744 }
745
746 #[inline]
747 fn quit(&mut self, code: i32) -> ! {
748 self.finish();
749 process::exit(code);
750 }
751
752 fn quit_successfully(&mut self, mut output: BufWriter<std::io::StdoutLock>) -> ! {
753 self.finish();
754 if !self.cfg().quiet_repl {
755 log!(info_f output, "The REPL has finished successfully.\n");
756 }
757 process::exit(0);
758 }
759
760 fn run(cfg: ErgConfig) -> ExitStatus {
761 let quiet_repl = cfg.quiet_repl;
762 let mut num_errors = 0;
763 let mut instance = Self::new(cfg);
764 let res = match &instance.input().kind {
765 InputKind::File { .. } | InputKind::Pipe(_) | InputKind::Str(_) => instance.exec(),
766 InputKind::REPL | InputKind::DummyREPL(_) => {
767 let output = stdout();
768 let mut output = BufWriter::new(output.lock());
769 if !quiet_repl {
770 log!(info_f output, "The REPL has started.\n");
771 output
772 .write_all(instance.start_message().as_bytes())
773 .unwrap();
774 }
775 output.flush().unwrap();
776 let mut vm = VirtualMachine::new();
777 loop {
778 let indent = vm.indent();
779 if vm.now_block.len() > 1 {
780 output.write_all(instance.ps2().as_bytes()).unwrap();
781 output.write_all(indent.as_bytes()).unwrap();
782 output.flush().unwrap();
783 } else {
784 output.write_all(instance.ps1().as_bytes()).unwrap();
785 output.flush().unwrap();
786 }
787 instance.cfg().input.set_indent(vm.length);
788 let line = chomp(&instance.cfg_mut().input.read());
789 let line = line.trim_end();
790 match line {
791 ":quit" | ":exit" => {
792 instance.quit_successfully(output);
793 }
794 ":clear" | ":cln" => {
795 output.write_all("\x1b[2J\x1b[1;1H".as_bytes()).unwrap();
796 output.flush().unwrap();
797 instance.input().set_block_begin();
798 vm.clear();
799 instance.clear();
800 continue;
801 }
802 "" | "}" | ")" | "]" => {
803 if vm.now == BlockKind::Collections && line == "}" {
805 vm.push_code("}");
806 vm.push_code("\n");
807 } else if vm.now == BlockKind::Collections && line == ")" {
808 vm.push_code(")");
809 vm.push_code("\n");
810 } else if vm.now == BlockKind::Collections && line == "]" {
811 vm.push_code("]");
812 vm.push_code("\n");
813 } else if vm.now == BlockKind::MultiLineStr
814 || vm.now == BlockKind::Collections
815 {
816 vm.push_code(line);
817 vm.push_code("\n");
818 continue;
819 }
820
821 if vm.now_block.len() == 2 {
822 vm.remove_block_kind();
823 } else if vm.now_block.len() > 1 {
824 vm.remove_block_kind();
825 vm.push_code("\n");
826 continue;
827 }
828 match instance.eval(mem::take(&mut vm.codes)) {
829 Ok(out) if out.is_empty() => {
830 instance.input().set_block_begin();
831 }
832 Ok(out) => {
833 output.write_all((out + "\n").as_bytes()).unwrap();
834 output.flush().unwrap();
835 }
836 Err(errs) => {
837 if errs
838 .first()
839 .map(|e| e.core().kind == ErrorKind::SystemExit)
840 .unwrap_or(false)
841 {
842 instance.quit_successfully(output);
843 }
844 num_errors += errs.len();
845 errs.write_all_stderr();
846 }
847 }
848 instance.input().set_block_begin();
849 instance.clear();
850 vm.clear();
851 continue;
852 }
853 _ => {}
854 }
855 let line = if let Some(comment_start) = line.find('#') {
856 &line[..comment_start]
857 } else {
858 line
859 };
860 let bk = instance.expect_block(line);
861 let bk = if bk == BlockKind::Error
862 && (vm.now == BlockKind::MultiLineStr || vm.now == BlockKind::Collections)
863 {
864 BlockKind::None
865 } else {
866 bk
867 };
868 match bk {
870 BlockKind::None if vm.now == BlockKind::AtMark => {
871 if let Some(eq) = line.find('=') {
872 if let Some(class) = line.find("Class") {
873 if eq < class {
874 vm.push_code(indent.as_str());
875 instance.input().insert_whitespace(indent.as_str());
876 vm.push_code(line);
877 vm.push_code("\n");
878 vm.push_block_kind(bk);
879 continue;
880 }
881 }
882 vm.push_code(indent.as_str());
883 instance.input().insert_whitespace(indent.as_str());
884 vm.push_code(line);
885 vm.push_code("\n");
886 continue;
887 }
888 vm.now = BlockKind::Main;
890 }
891 BlockKind::ClassDef | BlockKind::Assignment
892 if vm.now == BlockKind::AtMark =>
893 {
894 vm.push_block_kind(bk);
895 vm.push_code(indent.as_str());
896 instance.input().insert_whitespace(indent.as_str());
897 vm.push_code(line);
898 vm.push_code("\n");
899 continue;
900 }
901 _ if vm.now == BlockKind::AtMark => {
903 vm.push_code(line);
904 vm.push_code("\n");
905 vm.now = BlockKind::Main;
906 }
907 BlockKind::None
908 if vm.now == BlockKind::MultiLineStr
909 || vm.now == BlockKind::Collections =>
910 {
911 vm.push_code(line);
912 vm.push_code("\n");
913 continue;
914 }
915 BlockKind::None => {
917 vm.push_code(indent.as_str());
918 instance.input().insert_whitespace(indent.as_str());
919 vm.push_code(line);
920 vm.push_code("\n");
921 }
922 BlockKind::Error => {
923 vm.push_code(indent.as_str());
924 instance.input().insert_whitespace(indent.as_str());
925 vm.push_code(line);
926 vm.now = BlockKind::Main;
927 vm.now_block = vec![BlockKind::Main];
928 }
929 BlockKind::MultiLineStr if vm.now == BlockKind::MultiLineStr => {
931 vm.remove_block_kind();
932 vm.length = vm.now_block.len();
933 vm.push_code(line);
934 vm.push_code("\n");
935 }
936 BlockKind::Collections if vm.now == BlockKind::Collections => {
938 vm.remove_block_kind();
939 vm.length = vm.now_block.len();
940 vm.push_code(line);
941 vm.push_code("\n");
942 }
943 BlockKind::MultiLineStr => {
945 vm.push_block_kind(BlockKind::MultiLineStr);
946 vm.push_code(indent.as_str());
947 instance.input().insert_whitespace(indent.as_str());
948 vm.push_code(line);
949 vm.push_code("\n");
950 continue;
951 }
952 BlockKind::Collections => {
953 vm.push_block_kind(BlockKind::Collections);
954 vm.push_code(indent.as_str());
955 instance.input().insert_whitespace(indent.as_str());
956 vm.push_code(line);
957 vm.push_code("\n");
958 continue;
959 }
960 _ if vm.now == BlockKind::MultiLineStr => {
962 vm.push_code(line);
963 vm.push_code("\n");
964 continue;
965 }
966 _ => {
968 vm.push_code(indent.as_str());
969 instance.input().insert_whitespace(indent.as_str());
970 vm.push_block_kind(bk);
971 vm.push_code(line);
972 vm.push_code("\n");
973 continue;
974 }
975 }
976
977 if vm.now == BlockKind::Main {
978 match instance.eval(mem::take(&mut vm.codes)) {
979 Ok(out) => {
980 output.write_all((out + "\n").as_bytes()).unwrap();
981 output.flush().unwrap();
982 }
983 Err(errs) => {
984 if errs
985 .first()
986 .map(|e| e.core().kind == ErrorKind::SystemExit)
987 .unwrap_or(false)
988 {
989 return ExitStatus::new(0, 0, num_errors);
990 }
991 num_errors += errs.len();
992 errs.write_all_stderr();
993 }
994 }
995 instance.input().set_block_begin();
996 instance.clear();
997 vm.clear();
998 }
999 }
1000 }
1001 InputKind::Dummy => switch_unreachable!(),
1002 };
1003 match res {
1004 Ok(status) => status,
1005 Err(errs) => {
1006 num_errors += errs.len();
1007 errs.write_all_stderr();
1008 ExitStatus::new(1, 0, num_errors)
1009 }
1010 }
1011 }
1012}
1013
1014pub trait Locational {
1015 fn loc(&self) -> Location;
1018
1019 fn ln_begin(&self) -> Option<u32> {
1021 match self.loc() {
1022 Location::Range { ln_begin, .. } | Location::LineRange(ln_begin, _) => Some(ln_begin),
1023 Location::Line(lineno) => Some(lineno),
1024 Location::Unknown => None,
1025 }
1026 }
1027
1028 fn ln_end(&self) -> Option<u32> {
1029 match self.loc() {
1030 Location::Range { ln_end, .. } | Location::LineRange(_, ln_end) => Some(ln_end),
1031 Location::Line(lineno) => Some(lineno),
1032 Location::Unknown => None,
1033 }
1034 }
1035
1036 fn col_begin(&self) -> Option<u32> {
1038 match self.loc() {
1039 Location::Range { col_begin, .. } => Some(col_begin),
1040 _ => None,
1041 }
1042 }
1043
1044 fn col_end(&self) -> Option<u32> {
1045 match self.loc() {
1046 Location::Range { col_end, .. } => Some(col_end),
1047 _ => None,
1048 }
1049 }
1050}
1051
1052impl<L: Locational> Locational for Option<L> {
1053 fn loc(&self) -> Location {
1054 match self {
1055 Some(l) => l.loc(),
1056 None => Location::Unknown,
1057 }
1058 }
1059}
1060
1061impl<L: Locational, R: Locational> Locational for Result<&L, &R> {
1062 fn loc(&self) -> Location {
1063 match self {
1064 Ok(l) => l.loc(),
1065 Err(r) => r.loc(),
1066 }
1067 }
1068}
1069
1070impl<L: Locational, R: Locational> Locational for (&L, &R) {
1071 fn loc(&self) -> Location {
1072 Location::concat(self.0, self.1)
1073 }
1074}
1075
1076impl Locational for () {
1077 fn loc(&self) -> Location {
1078 Location::Unknown
1079 }
1080}
1081
1082impl<T: Locational, const N: usize> Locational for [T; N] {
1083 fn loc(&self) -> Location {
1084 Location::stream(self)
1085 }
1086}
1087
1088impl<T: Locational> Locational for Vec<T> {
1089 fn loc(&self) -> Location {
1090 Location::stream(self)
1091 }
1092}
1093
1094impl<T: Locational> Locational for &T {
1095 fn loc(&self) -> Location {
1096 (*self).loc()
1097 }
1098}
1099
1100#[macro_export]
1101macro_rules! impl_locational_for_enum {
1102 ($Enum: ident; $($Variant: ident $(,)?)*) => {
1103 impl erg_common::traits::Locational for $Enum {
1104 fn loc(&self) -> erg_common::error::Location {
1105 match self {
1106 $($Enum::$Variant(v) => v.loc(),)*
1107 }
1108 }
1109 }
1110 }
1111}
1112
1113#[macro_export]
1114macro_rules! impl_locational {
1115 ($T: ty, $begin: ident, $end: ident) => {
1116 impl Locational for $T {
1117 fn loc(&self) -> Location {
1118 let begin_loc = self.$begin.loc();
1119 let end_loc = self.$end.loc();
1120 match (
1121 begin_loc.ln_begin(),
1122 begin_loc.col_begin(),
1123 end_loc.ln_end(),
1124 end_loc.col_end(),
1125 ) {
1126 (Some(lb), Some(cb), Some(le), Some(ce)) => Location::range(lb, cb, le, ce),
1127 (Some(lb), _, Some(le), _) => Location::LineRange(lb, le),
1128 (Some(l), _, _, _) | (_, _, Some(l), _) => Location::Line(l),
1129 _ => Location::Unknown,
1130 }
1131 }
1132 fn ln_begin(&self) -> Option<u32> {
1133 self.$begin.ln_begin()
1134 }
1135 fn ln_end(&self) -> Option<u32> {
1136 self.$end.ln_end()
1137 }
1138 fn col_begin(&self) -> Option<u32> {
1139 self.$begin.col_begin()
1140 }
1141 fn col_end(&self) -> Option<u32> {
1142 self.$end.col_end()
1143 }
1144 }
1145 };
1146 ($T: ty, lossy $begin: ident, $end: ident) => {
1147 impl Locational for $T {
1148 fn loc(&self) -> Location {
1149 let begin_loc = self.$begin.loc();
1150 let end_loc = self.$end.loc();
1151 if begin_loc.is_unknown() {
1152 return end_loc;
1153 }
1154 match (
1155 begin_loc.ln_begin(),
1156 begin_loc.col_begin(),
1157 end_loc.ln_end(),
1158 end_loc.col_end(),
1159 ) {
1160 (Some(lb), Some(cb), Some(le), Some(ce)) => Location::range(lb, cb, le, ce),
1161 (Some(lb), _, Some(le), _) => Location::LineRange(lb, le),
1162 (Some(l), _, _, _) | (_, _, Some(l), _) => Location::Line(l),
1163 _ => Location::Unknown,
1164 }
1165 }
1166 }
1167 };
1168 ($T: ty, $begin: ident, lossy $end: ident) => {
1169 impl Locational for $T {
1170 fn loc(&self) -> Location {
1171 let begin_loc = self.$begin.loc();
1172 let end_loc = self.$end.loc();
1173 if end_loc.is_unknown() {
1174 return begin_loc;
1175 }
1176 match (
1177 begin_loc.ln_begin(),
1178 begin_loc.col_begin(),
1179 end_loc.ln_end(),
1180 end_loc.col_end(),
1181 ) {
1182 (Some(lb), Some(cb), Some(le), Some(ce)) => Location::range(lb, cb, le, ce),
1183 (Some(lb), _, Some(le), _) => Location::LineRange(lb, le),
1184 (Some(l), _, _, _) | (_, _, Some(l), _) => Location::Line(l),
1185 _ => Location::Unknown,
1186 }
1187 }
1188 }
1189 };
1190 ($T: ty, $begin: ident, $middle: ident, $end: ident) => {
1191 impl Locational for $T {
1192 fn loc(&self) -> Location {
1193 let begin_loc = self.$begin.loc();
1194 let end_loc = self.$end.loc();
1195 if begin_loc.is_unknown() && end_loc.is_unknown() {
1196 return self.$middle.loc();
1197 }
1198 match (
1199 begin_loc.ln_begin(),
1200 begin_loc.col_begin(),
1201 end_loc.ln_end(),
1202 end_loc.col_end(),
1203 ) {
1204 (Some(lb), Some(cb), Some(le), Some(ce)) => Location::range(lb, cb, le, ce),
1205 (Some(lb), _, Some(le), _) => Location::LineRange(lb, le),
1206 (Some(l), _, _, _) | (_, _, Some(l), _) => Location::Line(l),
1207 _ => Location::Unknown,
1208 }
1209 }
1210 fn ln_begin(&self) -> Option<u32> {
1211 self.$begin.ln_begin()
1212 }
1213 fn ln_end(&self) -> Option<u32> {
1214 self.$end.ln_end()
1215 }
1216 fn col_begin(&self) -> Option<u32> {
1217 self.$begin.col_begin()
1218 }
1219 fn col_end(&self) -> Option<u32> {
1220 self.$end.col_end()
1221 }
1222 }
1223 };
1224 ($T: ty, $inner: ident) => {
1225 impl Locational for $T {
1226 fn loc(&self) -> Location {
1227 self.$inner.loc()
1228 }
1229 }
1230 };
1231}
1232
1233pub trait NestedDisplay {
1234 fn fmt_nest(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result;
1235}
1236
1237pub trait NoTypeDisplay {
1238 fn to_string_notype(&self) -> String;
1239}
1240
1241#[macro_export]
1243macro_rules! impl_display_from_nested {
1244 ($T: ty) => {
1245 impl std::fmt::Display for $T {
1246 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1247 self.fmt_nest(f, 0)
1248 }
1249 }
1250 };
1251}
1252
1253#[macro_export]
1255macro_rules! impl_nested_display_for_chunk_enum {
1256 ($Enum: ident; $($Variant: ident $(,)?)*) => {
1257 impl $crate::traits::NestedDisplay for $Enum {
1258 fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
1259 write!(f, "{}", " ".repeat(level))?;
1260 match self {
1261 $($Enum::$Variant(v) => v.fmt_nest(f, level),)*
1262 }
1263 }
1264 }
1265 }
1266}
1267
1268#[macro_export]
1269macro_rules! impl_from_trait_for_enum {
1270 ($Enum: ident; $($Variant: ident $(,)?)*) => {
1271 $(
1272 impl From<$Variant> for $Enum {
1273 fn from(v: $Variant) -> Self {
1274 $Enum::$Variant(v)
1275 }
1276 }
1277 )*
1278 }
1279}
1280
1281#[macro_export]
1282macro_rules! impl_try_from_trait_for_enum {
1283 ($Enum: ident; $($Variant: ident $(,)?)*) => {
1284 $(
1285 impl TryFrom<$Enum> for $Variant {
1286 type Error = $Enum;
1287 fn try_from(from: $Enum) -> Result<Self, Self::Error> {
1288 match from {
1289 Expr::$Variant(to) => Ok(to),
1290 _ => Err(from),
1291 }
1292 }
1293 }
1294 impl<'x> TryFrom<&'x $Enum> for &'x $Variant {
1295 type Error = &'x $Enum;
1296 fn try_from(from: &'x $Enum) -> Result<Self, Self::Error> {
1297 match from {
1298 Expr::$Variant(to) => Ok(to),
1299 _ => Err(from),
1300 }
1301 }
1302 }
1303 )*
1304 }
1305}
1306
1307#[macro_export]
1308macro_rules! impl_nested_display_for_enum {
1309 ($Enum: ident; $($Variant: ident $(,)?)*) => {
1310 impl $crate::traits::NestedDisplay for $Enum {
1311 fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
1312 match self {
1313 $($Enum::$Variant(v) => v.fmt_nest(f, level),)*
1314 }
1315 }
1316 }
1317 }
1318}
1319
1320#[macro_export]
1321macro_rules! impl_no_type_display_for_enum {
1322 ($Enum: ident; $($Variant: ident $(,)?)*) => {
1323 impl $crate::traits::NoTypeDisplay for $Enum {
1324 fn to_string_notype(&self) -> String {
1325 match self {
1326 $($Enum::$Variant(v) => v.to_string_notype(),)*
1327 }
1328 }
1329 }
1330 }
1331}
1332
1333pub trait AddrEq {
1335 #[inline]
1336 fn addr_eq(&self, other: &Self) -> bool {
1337 addr_eq!(self, other)
1338 }
1339}
1340
1341pub trait StructuralEq {
1342 fn structural_eq(&self, other: &Self) -> bool;
1343}
1344
1345pub trait __Str__ {
1346 fn __str__(&self) -> String;
1347}
1348
1349pub trait OptionalTranspose {
1350 type Output;
1351 type Fill;
1352 fn transpose(self, fill: Self::Fill) -> Self::Output
1354 where
1355 Self: Sized;
1356}
1357
1358impl<T: Clone> OptionalTranspose for Option<Vec<T>> {
1359 type Output = Vec<Option<T>>;
1360 type Fill = usize;
1361 fn transpose(self, fill: Self::Fill) -> Self::Output
1362 where
1363 Self: Sized,
1364 {
1365 match self {
1366 Some(v) => v.into_iter().map(Some).collect(),
1367 None => vec![None; fill],
1368 }
1369 }
1370}
1371
1372pub trait New {
1373 fn new(cfg: ErgConfig) -> Self;
1374}
1375
1376pub trait Immutable {}
1379
1380impl Immutable for () {}
1381impl Immutable for bool {}
1382impl Immutable for char {}
1383impl Immutable for u8 {}
1384impl Immutable for u16 {}
1385impl Immutable for u32 {}
1386impl Immutable for u64 {}
1387impl Immutable for u128 {}
1388impl Immutable for usize {}
1389impl Immutable for i8 {}
1390impl Immutable for i16 {}
1391impl Immutable for i32 {}
1392impl Immutable for i64 {}
1393impl Immutable for i128 {}
1394impl Immutable for isize {}
1395impl Immutable for f32 {}
1396impl Immutable for f64 {}
1397impl Immutable for str {}
1398impl Immutable for String {}
1399impl Immutable for crate::Str {}
1400impl Immutable for std::path::PathBuf {}
1401impl Immutable for std::path::Path {}
1402impl Immutable for std::ffi::OsString {}
1403impl Immutable for std::ffi::OsStr {}
1404impl Immutable for std::time::Duration {}
1405impl Immutable for std::time::SystemTime {}
1406impl Immutable for std::time::Instant {}
1407impl<T: Immutable + ?Sized> Immutable for &T {}
1408impl<T: Immutable> Immutable for Option<T> {}
1409impl<T: Immutable> Immutable for Vec<T> {}
1410impl<T: Immutable> Immutable for [T] {}
1411impl<T: Immutable, U: Immutable> Immutable for (T, U) {}
1412impl<T: Immutable, U: Immutable, V: Immutable> Immutable for (T, U, V) {}
1413impl<T: Immutable + ?Sized> Immutable for Box<T> {}
1414impl<T: Immutable + ?Sized> Immutable for std::rc::Rc<T> {}
1415impl<T: Immutable + ?Sized> Immutable for std::sync::Arc<T> {}
1416
1417pub trait Traversable {
1418 type Target;
1419 fn traverse(&self, rec_f: &mut impl FnMut(&Self::Target));
1420}
1421
1422#[macro_export]
1423macro_rules! impl_traversable_for_enum {
1424 ($Enum: ident; $Target: ty; $($Variant: ident $(,)?)*) => {
1425 impl Traversable for $Enum {
1426 type Target = $Target;
1427 fn traverse(&self, rec_f: &mut impl FnMut(&Self::Target)) {
1428 match self {
1429 $($Enum::$Variant(v) => v.traverse(rec_f),)*
1430 }
1431 }
1432 }
1433 }
1434}