random spot with parser rewrite (still broken)

This commit is contained in:
2025-04-27 02:32:28 -04:00
parent a087af505e
commit d7222cc7a4
16 changed files with 240 additions and 260 deletions

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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 {