random spot with parser rewrite (still broken)
This commit is contained in:
@@ -28,7 +28,7 @@ pub struct UGeneric {}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct UVar {
|
||||
pub ty: Type,
|
||||
pub ty: TypeID,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
@@ -48,12 +48,8 @@ pub type Origin = FileSpan;
|
||||
impl UFunc {
|
||||
pub fn ty(&self, program: &UProgram) -> Type {
|
||||
Type::Fn {
|
||||
args: self
|
||||
.args
|
||||
.iter()
|
||||
.map(|a| program.expect(*a).ty.clone())
|
||||
.collect(),
|
||||
ret: Box::new(self.ret.clone()),
|
||||
args: self.args.iter().map(|a| program.expect(*a).ty).collect(),
|
||||
ret: self.ret,
|
||||
}
|
||||
}
|
||||
pub fn flat_iter(&self) -> impl Iterator<Item = &UInstrInst> {
|
||||
@@ -116,15 +112,15 @@ macro_rules! impl_kind {
|
||||
impl_kind!(UFunc, 0, fns, "func", nofin);
|
||||
impl_kind!(UVar, 1, vars, "var");
|
||||
impl_kind!(UStruct, 2, structs, "struct");
|
||||
impl_kind!(UGeneric, 3, types, "type");
|
||||
impl_kind!(Type, 3, types, "type");
|
||||
impl_kind!(UData, 4, data, "data");
|
||||
pub const NAMED_KINDS: usize = 6;
|
||||
pub const NAMED_KINDS: usize = 5;
|
||||
|
||||
pub type FnID = ID<UFunc>;
|
||||
pub type VarID = ID<UVar>;
|
||||
pub type StructID = ID<UStruct>;
|
||||
pub type DataID = ID<UData>;
|
||||
pub type GenericID = ID<UGeneric>;
|
||||
pub type TypeID = ID<Type>;
|
||||
|
||||
impl Finish for UFunc {
|
||||
fn finish(p: &mut UProgram, id: ID<Self>, name: &str) {
|
||||
|
||||
@@ -6,13 +6,14 @@ pub struct UProgram {
|
||||
pub fns: Vec<Option<UFunc>>,
|
||||
pub vars: Vec<Option<UVar>>,
|
||||
pub structs: Vec<Option<UStruct>>,
|
||||
pub types: Vec<Option<UGeneric>>,
|
||||
pub types: Vec<Option<Type>>,
|
||||
pub data: Vec<Option<UData>>,
|
||||
// associated data
|
||||
pub names: NameMap,
|
||||
pub origins: OriginMap,
|
||||
pub fn_var: FnVarMap,
|
||||
// utils for creation
|
||||
error: Option<TypeID>,
|
||||
pub path: Vec<String>,
|
||||
pub name_stack: Vec<HashMap<String, Idents>>,
|
||||
pub temp: usize,
|
||||
@@ -29,11 +30,16 @@ impl UProgram {
|
||||
names: NameMap::new(),
|
||||
origins: OriginMap::new(),
|
||||
fn_var: FnVarMap::new(),
|
||||
error: None,
|
||||
path: Vec::new(),
|
||||
name_stack: Vec::new(),
|
||||
temp: 0,
|
||||
}
|
||||
}
|
||||
pub fn error_type(&mut self) -> TypeID {
|
||||
self.error
|
||||
.unwrap_or_else(|| self.def("error", Some(Type::Error), Origin::builtin()))
|
||||
}
|
||||
pub fn set_module(&mut self, path: Vec<String>) {
|
||||
self.path = path;
|
||||
self.name_stack = vec![HashMap::new()];
|
||||
@@ -69,6 +75,9 @@ impl UProgram {
|
||||
self.get(id)
|
||||
.unwrap_or_else(|| panic!("{id:?} not defined yet!"))
|
||||
}
|
||||
pub fn expect_type(&self, var: VarID) -> &Type {
|
||||
self.expect(self.expect(var).ty)
|
||||
}
|
||||
pub fn expect_mut<K: Kind + Named>(&mut self, id: ID<K>) -> &mut K {
|
||||
self.get_mut(id)
|
||||
.unwrap_or_else(|| panic!("{id:?} not defined yet!"))
|
||||
@@ -77,16 +86,12 @@ impl UProgram {
|
||||
self.fns[self.fn_var.fun(id)?.0].as_ref()
|
||||
}
|
||||
|
||||
pub fn temp_var(&mut self, origin: Origin, ty: impl Into<Type>) -> VarInst {
|
||||
pub fn temp_var(&mut self, origin: Origin, ty: TypeID) -> VarInst {
|
||||
self.temp_var_inner(origin, ty)
|
||||
}
|
||||
|
||||
fn temp_var_inner(&mut self, origin: Origin, ty: impl Into<Type>) -> VarInst {
|
||||
let v = self.def(
|
||||
&format!("temp{}", self.temp),
|
||||
Some(UVar { ty: ty.into() }),
|
||||
origin,
|
||||
);
|
||||
fn temp_var_inner(&mut self, origin: Origin, ty: TypeID) -> VarInst {
|
||||
let v = self.def(&format!("temp{}", self.temp), Some(UVar { ty }), origin);
|
||||
self.temp += 1;
|
||||
VarInst {
|
||||
id: v,
|
||||
@@ -128,76 +133,64 @@ impl UProgram {
|
||||
id
|
||||
}
|
||||
|
||||
pub fn struct_field_type<'a>(&'a self, sty: &'a StructTy, field: &str) -> Option<&'a Type> {
|
||||
let struc = self.get(sty.id)?;
|
||||
let field = struc.fields.get(field)?;
|
||||
if let Type::Generic { id } = field.ty {
|
||||
for (i, g) in struc.generics.iter().enumerate() {
|
||||
if *g == id {
|
||||
return Some(&sty.args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(&field.ty)
|
||||
}
|
||||
|
||||
pub fn field_type<'a>(&'a self, ty: &'a Type, field: &str) -> Option<&'a Type> {
|
||||
if let Type::Struct(sty) = ty {
|
||||
self.struct_field_type(sty, field)
|
||||
} else if let Type::Module(path) = ty {
|
||||
let id = self.names.id::<UVar>(path, field)?;
|
||||
Some(&self.get(id)?.ty)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn follow_ref(&self, m: &FieldRef) -> Option<&Type> {
|
||||
let parent = self.get(m.parent)?;
|
||||
self.field_type(self.follow_type(&parent.ty)?, &m.name)
|
||||
}
|
||||
|
||||
pub fn get_type<'a>(&'a self, v: VarID) -> Option<&'a Type> {
|
||||
self.follow_type(&self.get(v)?.ty)
|
||||
}
|
||||
|
||||
pub fn set_type(&mut self, mut var: VarID, set: Type) -> Option<()> {
|
||||
let mut path = Vec::new();
|
||||
while let Type::Field(parent) = &self.get(var)?.ty {
|
||||
var = parent.parent;
|
||||
path.push(parent.name.clone());
|
||||
}
|
||||
let mut ty = &mut self.vars[var.0].as_mut()?.ty;
|
||||
'outer: while let Type::Struct(sty) = ty {
|
||||
let Some(name) = path.pop() else {
|
||||
break;
|
||||
};
|
||||
let struc = &self.structs[sty.id.0].as_ref()?;
|
||||
let field = struc.fields.get(&name)?;
|
||||
let Type::Generic { id } = field.ty else {
|
||||
return None;
|
||||
};
|
||||
for (i, g) in struc.generics.iter().enumerate() {
|
||||
if *g == id {
|
||||
ty = &mut sty.args[i];
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
*ty = set;
|
||||
Some(())
|
||||
}
|
||||
|
||||
pub fn follow_type<'a>(&'a self, ty: &'a Type) -> Option<&'a Type> {
|
||||
match ty {
|
||||
Type::Field(m) => {
|
||||
let parent = self.get(m.parent)?;
|
||||
self.field_type(self.follow_type(&parent.ty)?, &m.name)
|
||||
}
|
||||
ty => Some(ty),
|
||||
}
|
||||
}
|
||||
// hopefully these are not needed after redoing types
|
||||
// pub fn field_type<'a>(&'a self, ty: &'a Type, field: &str) -> Option<&'a Type> {
|
||||
// if let Type::Struct(sty) = ty {
|
||||
// Some(&self.get(*sty.fields.get(field)?)?.ty)
|
||||
// } else if let Type::Module(path) = ty {
|
||||
// let id = self.names.id::<UVar>(path, field)?;
|
||||
// Some(&self.get(id)?.ty)
|
||||
// } else {
|
||||
// None
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// pub fn follow_ref(&self, m: &FieldRef) -> Option<&Type> {
|
||||
// let parent = self.get(m.parent)?;
|
||||
// self.field_type(self.follow_type(&parent.ty)?, &m.name)
|
||||
// }
|
||||
//
|
||||
// pub fn get_type<'a>(&'a self, v: VarID) -> Option<&'a Type> {
|
||||
// self.follow_type(&self.get(v)?.ty)
|
||||
// }
|
||||
//
|
||||
// pub fn set_type(&mut self, mut var: VarID, set: Type) -> Option<()> {
|
||||
// let mut path = Vec::new();
|
||||
// while let Type::Field(parent) = &self.get(var)?.ty {
|
||||
// var = parent.parent;
|
||||
// path.push(parent.name.clone());
|
||||
// }
|
||||
// let mut ty = &mut self.vars[var.0].as_mut()?.ty;
|
||||
// 'outer: while let Type::Struct(sty) = ty {
|
||||
// let Some(name) = path.pop() else {
|
||||
// break;
|
||||
// };
|
||||
// let struc = &self.structs[sty.id.0].as_ref()?;
|
||||
// let field = struc.fields.get(&name)?;
|
||||
// let Type::Generic { id } = field.ty else {
|
||||
// return None;
|
||||
// };
|
||||
// for (i, g) in struc.generics.iter().enumerate() {
|
||||
// if *g == id {
|
||||
// ty = &mut sty.args[i];
|
||||
// continue 'outer;
|
||||
// }
|
||||
// }
|
||||
// return None;
|
||||
// }
|
||||
// *ty = set;
|
||||
// Some(())
|
||||
// }
|
||||
//
|
||||
// pub fn follow_type<'a>(&'a self, ty: &'a Type) -> Option<&'a Type> {
|
||||
// match ty {
|
||||
// Type::Field(m) => {
|
||||
// let parent = self.get(m.parent)?;
|
||||
// self.field_type(self.follow_type(&parent.ty)?, &m.name)
|
||||
// }
|
||||
// ty => Some(ty),
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn type_name(&self, ty: &Type) -> String {
|
||||
let mut str = String::new();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use super::{assoc::NamePath, GenericID, Len, StructID, UInstruction, UProgram, UVar, VarID};
|
||||
use super::{assoc::NamePath, Len, StructID, TypeID, UInstruction, UProgram, VarID};
|
||||
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||
pub struct FieldRef {
|
||||
@@ -8,22 +8,20 @@ pub struct FieldRef {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Hash, Eq, PartialEq)]
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub struct StructTy {
|
||||
pub id: StructID,
|
||||
pub args: Vec<Type>,
|
||||
pub fields: HashMap<String, VarID>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum Type {
|
||||
Bits(u32),
|
||||
Struct(StructTy),
|
||||
// is this real? I don't know, it's kind of like infer
|
||||
Generic { id: GenericID },
|
||||
Fn { args: Vec<Type>, ret: Box<Type> },
|
||||
Ref(Box<Type>),
|
||||
Slice(Box<Type>),
|
||||
Array(Box<Type>, Len),
|
||||
Fn { args: Vec<TypeID>, ret: TypeID },
|
||||
Ref(TypeID),
|
||||
Slice(TypeID),
|
||||
Array(TypeID, Len),
|
||||
Unit,
|
||||
// fake types
|
||||
Field(FieldRef),
|
||||
@@ -37,15 +35,6 @@ impl Type {
|
||||
pub fn is_resolved(&self) -> bool {
|
||||
!matches!(self, Self::Error | Self::Placeholder | Self::Infer)
|
||||
}
|
||||
pub fn rf(self) -> Self {
|
||||
Type::Ref(Box::new(self))
|
||||
}
|
||||
pub fn arr(self, len: Len) -> Self {
|
||||
Type::Array(Box::new(self), len)
|
||||
}
|
||||
pub fn slice(self) -> Self {
|
||||
Type::Slice(Box::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl UProgram {
|
||||
|
||||
Reference in New Issue
Block a user