futilehdl/src/frontend/types.rs

99 lines
2.1 KiB
Rust
Raw Normal View History

2022-02-15 20:32:55 +00:00
use std::fmt::Debug;
/// Alias for &TypeStruct to reduce repetition
/// and make futura migration to interning
/// easier
2022-02-15 20:32:55 +00:00
pub type Type = InternedType;
2022-02-15 20:32:55 +00:00
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct InternedType(usize);
pub struct TypeStruct {
kind: TypeKind,
}
2022-02-06 22:19:55 +00:00
#[derive(Debug)]
2022-02-15 20:32:55 +00:00
enum TypeKind {
/// Elaboration-time types
ElabType(ElabKind),
/// Signal/Wire of generic width
2022-02-15 20:32:55 +00:00
Logic(ElabData),
/// UInt of generic width
2022-02-15 20:32:55 +00:00
UInt(ElabData),
/// Callable
Callable,
}
2022-02-06 22:19:55 +00:00
#[derive(Debug)]
2022-02-15 20:32:55 +00:00
struct ElabData {
typ: Type,
value: ElabValue,
}
2022-02-06 22:19:55 +00:00
#[derive(Debug)]
2022-02-15 20:32:55 +00:00
enum ElabValue {
/// the value is not given and has to be inferred
Infer,
/// the value is given as some byte representation
2022-02-15 20:32:55 +00:00
Concrete(ElabValueData),
}
2022-02-06 22:19:55 +00:00
#[derive(Debug)]
2022-02-15 20:32:55 +00:00
enum ElabValueData {
U32(u32),
2022-02-15 20:32:55 +00:00
Bytes(Vec<u8>),
}
/// Types that are only valid during Elaboration
2022-02-06 22:19:55 +00:00
#[derive(Debug)]
enum ElabKind {
/// general, unsized number type
2022-01-23 21:52:06 +00:00
Num,
}
2022-02-15 20:32:55 +00:00
pub struct PrimitiveTypes {
pub elabnum: Type,
pub logic: Type,
}
2022-02-15 20:32:55 +00:00
pub struct TypingContext {
types: Vec<TypeStruct>,
pub primitives: PrimitiveTypes,
}
2022-02-15 20:32:55 +00:00
impl TypingContext {
pub fn new() -> Self {
let primitives = PrimitiveTypes {
elabnum: InternedType(0),
logic: InternedType(1),
};
Self {
2022-02-15 20:32:55 +00:00
types: vec![TypeStruct {
kind: TypeKind::Logic(ElabData {
typ: primitives.elabnum,
value: ElabValue::Infer,
}),
}],
primitives,
2022-02-06 20:02:55 +00:00
}
}
2022-02-15 20:32:55 +00:00
pub fn add(&mut self, typ: TypeStruct) -> Type {
let id = self.types.len();
self.types.push(typ);
InternedType(id)
2022-02-06 20:02:55 +00:00
}
2022-02-15 20:32:55 +00:00
pub fn get(&self, typ: Type) -> &TypeStruct {
&self.types[typ.0]
2022-02-06 22:19:55 +00:00
}
2022-02-15 20:32:55 +00:00
pub fn pretty_type(&self, w: &mut dyn std::fmt::Write, typ: Type) -> std::fmt::Result {
match &self.get(typ).kind {
TypeKind::ElabType(val) => write!(w, "{{{:?}}}", val),
TypeKind::Logic(_) => todo!(),
TypeKind::UInt(_) => todo!(),
TypeKind::Callable => todo!(),
2022-02-06 20:02:55 +00:00
}
}
}