99 lines
2.1 KiB
Rust
99 lines
2.1 KiB
Rust
use std::fmt::Debug;
|
|
/// Alias for &TypeStruct to reduce repetition
|
|
/// and make futura migration to interning
|
|
/// easier
|
|
pub type Type = InternedType;
|
|
|
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
|
pub struct InternedType(usize);
|
|
|
|
pub struct TypeStruct {
|
|
kind: TypeKind,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
enum TypeKind {
|
|
/// Elaboration-time types
|
|
ElabType(ElabKind),
|
|
/// Signal/Wire of generic width
|
|
Logic(ElabData),
|
|
/// UInt of generic width
|
|
UInt(ElabData),
|
|
/// Callable
|
|
Callable,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct ElabData {
|
|
typ: Type,
|
|
value: ElabValue,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
enum ElabValue {
|
|
/// the value is not given and has to be inferred
|
|
Infer,
|
|
/// the value is given as some byte representation
|
|
Concrete(ElabValueData),
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
enum ElabValueData {
|
|
U32(u32),
|
|
Bytes(Vec<u8>),
|
|
}
|
|
|
|
/// Types that are only valid during Elaboration
|
|
#[derive(Debug)]
|
|
enum ElabKind {
|
|
/// general, unsized number type
|
|
Num,
|
|
}
|
|
|
|
pub struct PrimitiveTypes {
|
|
pub elabnum: Type,
|
|
pub logic: Type,
|
|
}
|
|
|
|
pub struct TypingContext {
|
|
types: Vec<TypeStruct>,
|
|
pub primitives: PrimitiveTypes,
|
|
}
|
|
|
|
impl TypingContext {
|
|
pub fn new() -> Self {
|
|
let primitives = PrimitiveTypes {
|
|
elabnum: InternedType(0),
|
|
logic: InternedType(1),
|
|
};
|
|
Self {
|
|
types: vec![TypeStruct {
|
|
kind: TypeKind::Logic(ElabData {
|
|
typ: primitives.elabnum,
|
|
value: ElabValue::Infer,
|
|
}),
|
|
}],
|
|
primitives,
|
|
}
|
|
}
|
|
|
|
pub fn add(&mut self, typ: TypeStruct) -> Type {
|
|
let id = self.types.len();
|
|
self.types.push(typ);
|
|
InternedType(id)
|
|
}
|
|
|
|
pub fn get(&self, typ: Type) -> &TypeStruct {
|
|
&self.types[typ.0]
|
|
}
|
|
|
|
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!("print logic"),
|
|
TypeKind::UInt(_) => todo!("print uint"),
|
|
TypeKind::Callable => todo!("print callable"),
|
|
}
|
|
}
|
|
}
|