use std::collections::{HashMap, HashSet};
use uuid::Uuid;
use crate::module::low::TypeRef;
use crate::ty::low::{Type, TypeKind};
pub mod high;
pub mod low;
lazy_static::lazy_static! {
pub static ref UNIT_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap();
pub static ref BOOLEAN_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap();
pub static ref I8_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000002").unwrap();
pub static ref I16_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000003").unwrap();
pub static ref I32_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000004").unwrap();
pub static ref I64_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000005").unwrap();
pub static ref U8_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000006").unwrap();
pub static ref U16_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000007").unwrap();
pub static ref U32_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000008").unwrap();
pub static ref U64_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000009").unwrap();
pub static ref F32_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-00000000000a").unwrap();
pub static ref F64_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-00000000000b").unwrap();
pub static ref STRING_ID: Uuid = Uuid::parse_str("00000000-0000-0000-0000-00000000000c").unwrap();
pub static ref PRIMITIVE_IDS: HashSet<Uuid> = {
let mut ids = HashSet::new();
ids.insert(*UNIT_ID);
ids.insert(*BOOLEAN_ID);
ids.insert(*I8_ID);
ids.insert(*I16_ID);
ids.insert(*I32_ID);
ids.insert(*I64_ID);
ids.insert(*U8_ID);
ids.insert(*U16_ID);
ids.insert(*U32_ID);
ids.insert(*U64_ID);
ids.insert(*F32_ID);
ids.insert(*F64_ID);
ids.insert(*STRING_ID);
ids
};
pub static ref PRIMITIVE_LOW_TYPE_REFS: HashMap<Uuid, TypeRef> = {
let mut types: HashMap<Uuid, TypeRef> = HashMap::new();
let make_scalar = |id: &Uuid| TypeRef::Scalar { id: *id };
let mut insert_scalar_id = |id: &Uuid| types.insert(*id, make_scalar(id));
insert_scalar_id(&UNIT_ID);
insert_scalar_id(&BOOLEAN_ID);
insert_scalar_id(&I8_ID);
insert_scalar_id(&I16_ID);
insert_scalar_id(&I32_ID);
insert_scalar_id(&I64_ID);
insert_scalar_id(&U8_ID);
insert_scalar_id(&U16_ID);
insert_scalar_id(&U32_ID);
insert_scalar_id(&U64_ID);
insert_scalar_id(&F32_ID);
insert_scalar_id(&F64_ID);
insert_scalar_id(&STRING_ID); types
};
pub static ref PRIMITIVE_TYPES: HashMap<Uuid, Type> = {
let mut types: HashMap<Uuid, Type> = HashMap::new();
let mut insert_primitive_type = |id: &Uuid, name: &str, description: &str| {
types.insert(*id, Type {
name: name.to_string(),
id: *id,
description: description.to_string(),
kind: TypeKind::Primitive(PRIMITIVE_LOW_TYPE_REFS.get(id).unwrap().clone()),
});
};
insert_primitive_type(&UNIT_ID, "unit", "a.k.a. \"nothing\"");
insert_primitive_type(&BOOLEAN_ID, "boolean", "either true or false");
insert_primitive_type(&I8_ID, "i8", "8-bit signed integer");
insert_primitive_type(&I16_ID, "i16", "16-bit signed integer");
insert_primitive_type(&I32_ID, "i32", "32-bit signed integer");
insert_primitive_type(&I64_ID, "i64", "64-bit signed integer");
insert_primitive_type(&U8_ID, "u8", "8-bit unsigned integer");
insert_primitive_type(&U16_ID, "u16", "16-bit unsigned integer");
insert_primitive_type(&U32_ID, "u32", "32-bit unsigned integer");
insert_primitive_type(&U64_ID, "u64", "64-bit unsigned integer");
insert_primitive_type(&F32_ID, "f32", "32-bit floating point decimal, a.k.a. \"float\"");
insert_primitive_type(&F64_ID, "f64", "64-bit floating point decimal, a.k.a. \"double\"");
insert_primitive_type(&STRING_ID, "str", "a string of u8 characters");
types
};
}