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
use std::rc::Rc;
use strtab::StringTable;
use super::{checker::SemanticContext, type_system::*};
pub struct BuiltinTypes<'src> {
pub string: CheckedType<'src>,
}
impl<'src, 'ast> BuiltinTypes<'src> {
pub fn add_to<'ts>(
type_system: &'ts mut TypeSystem<'src, 'ast>,
strtab: &'_ mut StringTable<'src>,
context: &'_ mut SemanticContext<'_, 'src>,
) -> BuiltinTypes<'src> {
let int_ty = CheckedType::Int;
let reader_class_id = {
let mut reader_class_def = ClassDef::new(strtab.intern("$Reader"));
reader_class_def.comparable = false;
reader_class_def
.add_method(ClassMethodDef {
name: strtab.intern("read"),
body: ClassMethodBody::Builtin(BuiltinMethodBody::SystemInRead),
params: vec![],
return_ty: int_ty.clone(),
is_static: false,
is_main: false,
})
.unwrap();
type_system.add_class_def(reader_class_def).unwrap()
};
let writer_class_id = {
let arg_sym = strtab.intern("data");
let mut writer_class_def = ClassDef::new(strtab.intern("$Writer"));
writer_class_def.comparable = false;
writer_class_def
.add_method(ClassMethodDef {
name: strtab.intern("println"),
body: ClassMethodBody::Builtin(BuiltinMethodBody::SystemOutPrintln),
params: vec![Rc::new(MethodParamDef::new(arg_sym, int_ty.clone()))],
return_ty: CheckedType::Void,
is_static: false,
is_main: false,
})
.unwrap();
writer_class_def
.add_method(ClassMethodDef {
name: strtab.intern("write"),
body: ClassMethodBody::Builtin(BuiltinMethodBody::SystemOutWrite),
params: vec![Rc::new(MethodParamDef::new(arg_sym, int_ty.clone()))],
return_ty: CheckedType::Void,
is_static: false,
is_main: false,
})
.unwrap();
writer_class_def
.add_method(ClassMethodDef {
name: strtab.intern("flush"),
body: ClassMethodBody::Builtin(BuiltinMethodBody::SystemOutFlush),
params: vec![],
return_ty: CheckedType::Void,
is_static: false,
is_main: false,
})
.unwrap();
type_system.add_class_def(writer_class_def).unwrap()
};
let system_class_id = {
let mut system_class_def = ClassDef::new(strtab.intern("$System"));
system_class_def.comparable = false;
system_class_def
.add_field(ClassFieldDef {
name: strtab.intern("in"),
ty: reader_class_id.into(),
can_write: false,
})
.unwrap();
system_class_def
.add_field(ClassFieldDef {
name: strtab.intern("out"),
ty: writer_class_id.into(),
can_write: false,
})
.unwrap();
type_system.add_class_def(system_class_def).unwrap()
};
context
.global_vars
.insert(strtab.intern("System"), system_class_id.into());
let string_class_def = ClassDef::new(strtab.intern("$String"));
let string_class_id = type_system.add_class_def(string_class_def).unwrap();
BuiltinTypes {
string: string_class_id.into(),
}
}
}