erg_common/
traits.rs

1//! defines common traits used in the compiler.
2//!
3//! コンパイラ等で汎用的に使われるトレイトを定義する
4use 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    /// Remove all elements that don't satisfy the predicate.
259    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    /// If `limit` was set to a negative value, it will be displayed without abbreviation.
513    /// FIXME:
514    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,       // now_block Vec must contain this
526    Assignment, // =
527    ClassPriv,  // ::
528    ClassPub,   // .
529    ColonCall,  // :
530    Error,      // parser error
531    Lambda,     // =>, ->, do, do!
532    // not block
533    AtMark,       // @
534    MultiLineStr, // """
535    ClassDef,     // class definition
536    Collections,  // {}, () and []
537    None,         // one line
538}
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        // Don't add block to @ after @
584        if self.now == BlockKind::AtMark && bk == BlockKind::AtMark {
585            return;
586        }
587        // Change from AtMark to ClassDef or Assignment
588        if (bk == BlockKind::ClassDef || bk == BlockKind::Assignment)
589            && self.now == BlockKind::AtMark
590        {
591            self.now_block.pop();
592        }
593        // Change from ClassDef to ClassPriv or ClassPub
594        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) // Except MainBlock
636        }
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
667/// This trait implements REPL (Read-Eval-Print-Loop) automatically
668/// The `exec` method is called for file input, etc.
669pub 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); // called when the :exit command is received.
676    /// Erase all but immutable information.
677    fn initialize(&mut self);
678    /// Erase information that will no longer be meaningful in the next iteration
679    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                            // eval after the end of the block
804                            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                    // let bk = instance.expect_block(line);
869                    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                            // Intentionally code will be evaluated and make an error
889                            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                        // Intentionally code will be evaluated and make an error
902                        _ 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                        // single eval
916                        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                        // end of MultiLineStr
930                        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                        // end of Collection
937                        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                        // start of MultiLineStr
944                        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                        // block is expected but string
961                        _ if vm.now == BlockKind::MultiLineStr => {
962                            vm.push_code(line);
963                            vm.push_code("\n");
964                            continue;
965                        }
966                        // expect block
967                        _ => {
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    /// NOTE: `loc` cannot be treated as a light method when `self` is a large grammatical element.
1016    /// If possible, delay the computation by passing `&impl Locational` or other means.
1017    fn loc(&self) -> Location;
1018
1019    /// 1-origin
1020    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    /// 0-origin
1037    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/// `impl<T: NestedDisplay> Display for T NestedDisplay`はorphan-ruleに違反するので個別定義する
1242#[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/// For Decl, Def, Call, etc., which can occupy a line by itself
1254#[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
1333/// Equivalent to `is` in Python
1334pub 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    /// `self: Option<_>`
1353    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
1376/// Indicates that the type has no interior mutability
1377// TODO: auto trait
1378pub 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}