1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#[allow(unused_imports)]
use erg_common::log;

use crate::ty::constructors::*;
use crate::ty::typaram::TyParam;
use crate::ty::{Type, Visibility};
use Type::*;

use crate::context::initialize::*;
use crate::context::Context;
use crate::varinfo::Mutability;
use Mutability::*;

impl Context {
    pub(super) fn init_builtin_procs(&mut self) {
        let vis = if PYTHON_MODE {
            Visibility::BUILTIN_PUBLIC
        } else {
            Visibility::BUILTIN_PRIVATE
        };
        let T = mono_q("T", instanceof(Type));
        let U = mono_q("U", instanceof(Type));
        let t_dir = no_var_proc(
            vec![kw("obj", ref_(Obj))],
            vec![],
            array_t(Str, TyParam::erased(Nat)),
        );
        let t_print = proc(
            vec![],
            Some(kw("objects", ref_(Obj))),
            vec![
                kw("sep", Str),
                kw("end", Str),
                kw("file", mono("Writable!")),
                kw("flush", Bool),
            ],
            None,
            NoneType,
        );
        let t_id = nd_func(vec![kw("old", Obj)], None, Nat);
        let t_input = no_var_proc(vec![], vec![kw("msg", Str)], Str);
        let t_if = no_var_proc(
            vec![
                kw("cond", Bool),
                kw("then", nd_proc(vec![], None, T.clone())),
            ],
            vec![kw_default(
                "else",
                nd_proc(vec![], None, U.clone()),
                nd_proc(vec![], None, NoneType),
            )],
            or(T.clone(), U.clone()),
        )
        .quantify();
        let t_for = nd_proc(
            vec![
                kw("iterable", poly("Iterable", vec![ty_tp(T.clone())])),
                kw("proc!", nd_proc(vec![anon(T.clone())], None, NoneType)),
            ],
            None,
            NoneType,
        )
        .quantify();
        let t_globals = no_var_proc(vec![], vec![], dict! { Str => Obj }.into());
        let t_locals = no_var_proc(vec![], vec![], dict! { Str => Obj }.into());
        let t_next = nd_proc(
            vec![kw(
                "iterable",
                ref_mut(poly("Iterable", vec![ty_tp(T.clone())]), None),
            )],
            None,
            T.clone(),
        )
        .quantify();
        let t_cond = if PYTHON_MODE {
            Bool
        } else {
            // not Bool! type because `cond` may be the result of evaluation of a mutable object's method returns Bool.
            nd_proc(vec![], None, Bool)
        };
        let t_while = nd_proc(
            vec![
                kw("cond!", t_cond),
                kw("proc!", nd_proc(vec![], None, NoneType)),
            ],
            None,
            NoneType,
        );
        let P = mono_q("P", subtypeof(mono("PathLike")));
        let t_open = no_var_proc(
            vec![kw("file", P)],
            vec![
                kw("mode", Str),
                kw("buffering", Int),
                kw("encoding", or(Str, NoneType)),
                kw("errors", or(Str, NoneType)),
                kw("newline", or(Str, NoneType)),
                kw("closefd", Bool),
                // param_t("opener", option),
            ],
            mono("File!"),
        )
        .quantify();
        let C = if PYTHON_MODE {
            mono("ContextManager").structuralize()
        } else {
            mono("ContextManager")
        };
        let t_with = nd_proc(
            vec![
                kw("obj", C),
                kw("proc!", nd_proc(vec![anon(T)], None, U.clone())),
            ],
            None,
            U,
        )
        .quantify();
        self.register_builtin_py_impl("dir!", t_dir, Immutable, vis.clone(), Some("dir"));
        self.register_py_builtin("print!", t_print, Some("print"), 81);
        self.register_builtin_py_impl("id!", t_id, Immutable, vis.clone(), Some("id"));
        self.register_builtin_py_impl("input!", t_input, Immutable, vis.clone(), Some("input"));
        self.register_builtin_py_impl(
            "globals!",
            t_globals,
            Immutable,
            vis.clone(),
            Some("globals"),
        );
        self.register_builtin_py_impl("locals!", t_locals, Immutable, vis.clone(), Some("locals"));
        self.register_builtin_py_impl("next!", t_next, Immutable, vis.clone(), Some("next"));
        self.register_py_builtin("open!", t_open, Some("open"), 198);
        let name = if PYTHON_MODE { "if" } else { "if__" };
        self.register_builtin_py_impl("if!", t_if, Immutable, vis.clone(), Some(name));
        let name = if PYTHON_MODE { "for" } else { "for__" };
        self.register_builtin_py_impl("for!", t_for, Immutable, vis.clone(), Some(name));
        let name = if PYTHON_MODE { "while" } else { "while__" };
        self.register_builtin_py_impl("while!", t_while, Immutable, vis.clone(), Some(name));
        let name = if PYTHON_MODE { "with" } else { "with__" };
        self.register_builtin_py_impl("with!", t_with, Immutable, vis, Some(name));
    }
}