1#![allow(dead_code)]
13
14use super::constant;
15use super::obj::*;
16use super::objects::{ObjKey, PackageKey, ScopeKey, TCObjects, TypeKey, Types};
17use super::package::*;
18use super::scope::*;
19use super::typ::*;
20use go_parser::Map;
21
22#[derive(Copy, Clone, Debug, PartialEq, Eq)]
25pub enum ExprKind {
26 Conversion,
27 Expression,
28 Statement,
29}
30
31#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
33pub enum Builtin {
34 Append,
35 Cap,
36 Close,
37 Complex,
38 Copy,
39 Delete,
40 Imag,
41 Len,
42 Make,
43 New,
44 Panic,
45 Print,
46 Println,
47 Real,
48 Recover,
49 Alignof,
51 Offsetof,
52 Sizeof,
53 Assert,
55 Trace,
56 Ffi,
58}
59
60#[derive(Copy, Clone)]
61pub struct BuiltinInfo {
62 pub name: &'static str,
63 pub arg_count: usize,
64 pub variadic: bool,
65 pub kind: ExprKind,
66}
67
68pub struct Universe {
71 scope: ScopeKey,
72 unsafe_: PackageKey,
73 iota: ObjKey,
74 byte: TypeKey,
75 rune: TypeKey,
76 slice_of_bytes: TypeKey, no_value_tuple: TypeKey, indir: ObjKey,
84 guard_sig: TypeKey,
86 types: Map<BasicType, TypeKey>,
87 builtins: Map<Builtin, BuiltinInfo>,
88}
89
90impl Universe {
91 pub fn new(objs: &mut TCObjects) -> Universe {
92 let (uskey, unsafe_) = Universe::def_universe_unsafe(objs);
94 let types = Universe::basic_types(&mut objs.types);
96 Universe::def_basic_types(&types, &uskey, &unsafe_, objs);
97 Universe::def_basic_types(
98 &Universe::alias_types(&mut objs.types),
99 &uskey,
100 &unsafe_,
101 objs,
102 );
103 Universe::def_error_type(&types, &uskey, &unsafe_, objs);
104 Universe::def_consts(&types, &uskey, &unsafe_, objs);
106 Universe::def_nil(&types, &uskey, &unsafe_, objs);
107 let builtins = Universe::builtin_funcs();
109 let ftype = types[&BasicType::Invalid];
110 Universe::def_builtins(&builtins, ftype, &uskey, &unsafe_, objs);
111 let (iota, byte, rune) = Universe::iota_byte_rune(&uskey, objs);
113 let slice_of_bytes = objs.new_t_slice(byte);
114 let no_value_tuple = objs.new_t_tuple(vec![]);
115 let indir = objs.new_type_name(0, None, "*".to_owned(), None);
116 let guard_sig = objs.new_t_signature(None, None, no_value_tuple, no_value_tuple, false);
117 Universe {
118 scope: uskey,
119 unsafe_: unsafe_,
120 iota: iota,
121 byte: byte,
122 rune: rune,
123 slice_of_bytes: slice_of_bytes,
124 no_value_tuple: no_value_tuple,
125 indir: indir,
126 guard_sig: guard_sig,
127 types: types,
128 builtins: builtins,
129 }
130 }
131
132 pub fn scope(&self) -> &ScopeKey {
133 &self.scope
134 }
135
136 pub fn unsafe_pkg(&self) -> &PackageKey {
137 &self.unsafe_
138 }
139
140 pub fn types(&self) -> &Map<BasicType, TypeKey> {
141 &self.types
142 }
143
144 pub fn builtins(&self) -> &Map<Builtin, BuiltinInfo> {
145 &self.builtins
146 }
147
148 pub fn iota(&self) -> &ObjKey {
149 &self.iota
150 }
151
152 pub fn byte(&self) -> &TypeKey {
153 &self.byte
154 }
155
156 pub fn rune(&self) -> &TypeKey {
157 &self.rune
158 }
159
160 pub fn slice_of_bytes(&self) -> &TypeKey {
161 &self.slice_of_bytes
162 }
163
164 pub fn no_value_tuple(&self) -> &TypeKey {
165 &self.no_value_tuple
166 }
167
168 pub fn indir(&self) -> &ObjKey {
169 &self.indir
170 }
171
172 pub fn guard_sig(&self) -> &TypeKey {
173 &self.guard_sig
174 }
175
176 fn def_universe_unsafe(objs: &mut TCObjects) -> (ScopeKey, PackageKey) {
177 let uskey = objs
178 .scopes
179 .insert(Scope::new(None, 0, 0, "universe".to_owned(), false));
180 let pkg_skey = objs.scopes.insert(Scope::new(
181 Some(uskey),
182 0,
183 0,
184 "package unsafe".to_owned(),
185 false,
186 ));
187 let mut pkg = Package::new("unsafe".to_owned(), Some("unsafe".to_owned()), pkg_skey);
188 pkg.mark_complete();
189 (uskey, objs.pkgs.insert(pkg))
190 }
191
192 fn def_error_type(
197 types: &Map<BasicType, TypeKey>,
198 universe: &ScopeKey,
199 unsafe_: &PackageKey,
200 objs: &mut TCObjects,
201 ) {
202 let res = objs.lobjs.insert(LangObj::new_var(
203 0,
204 None,
205 "".to_owned(),
206 Some(types[&BasicType::Str]),
207 ));
208 let params = objs.new_t_tuple(vec![]);
209 let results = objs.new_t_tuple(vec![res]);
210 let sig = objs.new_t_signature(None, None, params, results, false);
211 let err = objs
212 .lobjs
213 .insert(LangObj::new_func(0, None, "Error".to_owned(), Some(sig)));
214 let inter_detail = InterfaceDetail::new(vec![err], vec![], objs);
215 inter_detail.complete(objs);
216 let underlying = objs.types.insert(Type::Interface(inter_detail));
217 let typ = objs.new_t_named(None, Some(underlying), vec![]);
218 let recv = objs
219 .lobjs
220 .insert(LangObj::new_var(0, None, "".to_owned(), Some(typ)));
221 objs.types[sig]
222 .try_as_signature_mut()
223 .unwrap()
224 .set_recv(Some(recv));
225 let type_name = objs.lobjs.insert(LangObj::new_type_name(
226 0,
227 None,
228 "error".to_owned(),
229 Some(typ),
230 ));
231 Universe::def(type_name, universe, unsafe_, objs);
232 }
233
234 fn def_basic_types(
235 types: &Map<BasicType, TypeKey>,
236 universe: &ScopeKey,
237 unsafe_: &PackageKey,
238 objs: &mut TCObjects,
239 ) {
240 for (_, v) in types {
241 let name = objs.types[*v].try_as_basic().unwrap().name();
242 let t = objs
243 .lobjs
244 .insert(LangObj::new_type_name(0, None, name.to_owned(), Some(*v)));
245 Universe::def(t, universe, unsafe_, objs);
246 }
247 }
248
249 fn basic_types(tobjs: &mut Types) -> Map<BasicType, TypeKey> {
250 vec![
251 (BasicType::Invalid, BasicInfo::IsInvalid, "invalid type"),
254 (BasicType::Bool, BasicInfo::IsBoolean, "bool"),
255 (BasicType::Int, BasicInfo::IsInteger, "int"),
256 (BasicType::Int8, BasicInfo::IsInteger, "int8"),
257 (BasicType::Int16, BasicInfo::IsInteger, "int16"),
258 (BasicType::Int32, BasicInfo::IsInteger, "int32"),
259 (BasicType::Int64, BasicInfo::IsInteger, "int64"),
260 (BasicType::Uint, BasicInfo::IsInteger, "uint"),
261 (BasicType::Uint8, BasicInfo::IsInteger, "uint8"),
262 (BasicType::Uint16, BasicInfo::IsInteger, "uint16"),
263 (BasicType::Uint32, BasicInfo::IsInteger, "uint32"),
264 (BasicType::Uint64, BasicInfo::IsInteger, "uint64"),
265 (BasicType::Uintptr, BasicInfo::IsInteger, "uintptr"),
266 (BasicType::Float32, BasicInfo::IsFloat, "float32"),
267 (BasicType::Float64, BasicInfo::IsFloat, "float64"),
268 (BasicType::Complex64, BasicInfo::IsComplex, "complex64"),
269 (BasicType::Complex128, BasicInfo::IsComplex, "complex128"),
270 (BasicType::Str, BasicInfo::IsString, "string"),
271 (BasicType::UnsafePointer, BasicInfo::IsInvalid, "Pointer"),
272 (BasicType::UntypedBool, BasicInfo::IsBoolean, "untyped bool"),
273 (BasicType::UntypedInt, BasicInfo::IsInteger, "untyped int"),
274 (BasicType::UntypedRune, BasicInfo::IsInteger, "untyped rune"),
275 (BasicType::UntypedFloat, BasicInfo::IsFloat, "untyped float"),
276 (
277 BasicType::UntypedComplex,
278 BasicInfo::IsComplex,
279 "untyped complex",
280 ),
281 (
282 BasicType::UntypedString,
283 BasicInfo::IsString,
284 "untyped string",
285 ),
286 (BasicType::UntypedNil, BasicInfo::IsInvalid, "untyped nil"),
287 ]
288 .into_iter()
289 .map(|(t, i, n)| (t, tobjs.insert(Type::Basic(BasicDetail::new(t, i, n)))))
290 .collect::<Map<_, _>>()
291 }
292
293 fn alias_types(tobjs: &mut Types) -> Map<BasicType, TypeKey> {
294 [
295 (BasicType::Byte, BasicInfo::IsInteger, "byte"),
296 (BasicType::Rune, BasicInfo::IsInteger, "rune"),
297 ]
298 .iter()
299 .map(|(t, i, n)| (*t, tobjs.insert(Type::Basic(BasicDetail::new(*t, *i, n)))))
300 .collect::<Map<_, _>>()
301 }
302
303 fn def_consts(
304 types: &Map<BasicType, TypeKey>,
305 universe: &ScopeKey,
306 unsafe_: &PackageKey,
307 objs: &mut TCObjects,
308 ) {
309 for (n, t, v) in vec![
310 (
312 "true",
313 BasicType::UntypedBool,
314 constant::Value::with_bool(true),
315 ),
316 (
317 "false",
318 BasicType::UntypedBool,
319 constant::Value::with_bool(false),
320 ),
321 ("iota", BasicType::UntypedInt, constant::Value::with_i64(0)),
322 ]
323 .into_iter()
324 {
325 let cst = LangObj::new_const(0, None, n.to_owned(), Some(types[&t]), v);
326 Universe::def(objs.lobjs.insert(cst), universe, unsafe_, objs);
327 }
328 }
329
330 fn def_nil(
331 types: &Map<BasicType, TypeKey>,
332 universe: &ScopeKey,
333 unsafe_: &PackageKey,
334 objs: &mut TCObjects,
335 ) {
336 let nil = LangObj::new_nil(types[&BasicType::UntypedNil]);
337 Universe::def(objs.lobjs.insert(nil), universe, unsafe_, objs);
338 }
339
340 fn builtin_funcs() -> Map<Builtin, BuiltinInfo> {
341 vec![
342 (Builtin::Append, "append", 1, true, ExprKind::Expression),
344 (Builtin::Cap, "cap", 1, false, ExprKind::Expression),
345 (Builtin::Close, "close", 1, false, ExprKind::Statement),
346 (Builtin::Complex, "complex", 2, false, ExprKind::Expression),
347 (Builtin::Copy, "copy", 2, false, ExprKind::Statement),
348 (Builtin::Delete, "delete", 2, false, ExprKind::Statement),
349 (Builtin::Imag, "imag", 1, false, ExprKind::Expression),
350 (Builtin::Len, "len", 1, false, ExprKind::Expression),
351 (Builtin::Make, "make", 1, true, ExprKind::Expression),
352 (Builtin::New, "new", 1, false, ExprKind::Expression),
353 (Builtin::Panic, "panic", 1, false, ExprKind::Statement),
354 (Builtin::Print, "print", 0, true, ExprKind::Statement),
355 (Builtin::Println, "println", 0, true, ExprKind::Statement),
356 (Builtin::Real, "real", 1, false, ExprKind::Expression),
357 (Builtin::Recover, "recover", 0, false, ExprKind::Statement),
358 (Builtin::Alignof, "Alignof", 1, false, ExprKind::Expression),
359 (
360 Builtin::Offsetof,
361 "Offsetof",
362 1,
363 false,
364 ExprKind::Expression,
365 ),
366 (Builtin::Sizeof, "Sizeof", 1, false, ExprKind::Expression),
367 (Builtin::Assert, "assert", 1, false, ExprKind::Statement),
368 (Builtin::Trace, "trace", 0, true, ExprKind::Statement),
369 (Builtin::Ffi, "ffi", 2, false, ExprKind::Expression),
370 ]
371 .into_iter()
372 .map(|(f, name, no, v, k)| {
373 (
374 f,
375 BuiltinInfo {
376 name: name,
377 arg_count: no,
378 variadic: v,
379 kind: k,
380 },
381 )
382 })
383 .collect::<Map<_, _>>()
384 }
385
386 fn def_builtins(
387 builtins: &Map<Builtin, BuiltinInfo>,
388 typ: TypeKey,
389 universe: &ScopeKey,
390 unsafe_: &PackageKey,
391 objs: &mut TCObjects,
392 ) {
393 for (f, info) in builtins.iter() {
394 let fobj = objs
395 .lobjs
396 .insert(LangObj::new_builtin(*f, info.name.to_owned(), typ));
397 Universe::def(fobj, universe, unsafe_, objs);
398 }
399 }
400
401 fn iota_byte_rune(universe: &ScopeKey, objs: &mut TCObjects) -> (ObjKey, TypeKey, TypeKey) {
402 let scope = &objs.scopes[*universe];
403 let iota = *scope.lookup("iota").unwrap();
404 let byte = objs.lobjs[*scope.lookup("byte").unwrap()].typ().unwrap();
405 let rune = objs.lobjs[*scope.lookup("rune").unwrap()].typ().unwrap();
406 (iota, byte, rune)
407 }
408
409 fn def(okey: ObjKey, universe: &ScopeKey, unsafe_: &PackageKey, objs: &mut TCObjects) {
413 let obj = &objs.lobjs[okey];
414 assert!(obj.color() == ObjColor::Black);
415 if obj.name().contains(' ') {
416 return;
417 }
418 let typ_val = &mut objs.types[obj.typ().unwrap()];
420 if let Some(n) = typ_val.try_as_named_mut() {
421 n.set_obj(okey);
422 }
423
424 let skey = if obj.exported() {
425 match obj.entity_type() {
426 EntityType::TypeName | EntityType::Builtin(_) => {
427 objs.lobjs[okey].set_pkg(Some(*unsafe_))
428 }
429 _ => unreachable!(),
430 }
431 objs.pkgs[*unsafe_].scope()
432 } else {
433 universe
434 };
435 let re = Scope::insert(*skey, okey, objs);
436 assert!(re.is_none());
437 }
438}