Compare commits
No commits in common. "e79a0fe4586ff57d6986c1fb85aef2931c1a97b8" and "51c341450b4747bd66bad69e6062aa32508c888d" have entirely different histories.
e79a0fe458
...
51c341450b
@ -251,10 +251,9 @@ impl Builder {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Alloca(_, _) => Ok(()),
|
Alloca(_, _) => Ok(()),
|
||||||
Load(ptr, load_ty) => {
|
Load(ptr, _) => {
|
||||||
if let Ok(ptr_ty) = ptr.get_type(&self) {
|
if let Ok(ty) = ptr.get_type(&self) {
|
||||||
if let Type::Ptr(ptr_ty_inner) = ptr_ty {
|
if let Type::Ptr(_) = ty {
|
||||||
if *ptr_ty_inner == load_ty {
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
@ -262,9 +261,6 @@ impl Builder {
|
|||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Err(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Store(ptr, _) => {
|
Store(ptr, _) => {
|
||||||
if let Ok(ty) = ptr.get_type(&self) {
|
if let Ok(ty) = ptr.get_type(&self) {
|
||||||
@ -336,7 +332,7 @@ impl InstructionValue {
|
|||||||
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
|
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
|
||||||
Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)),
|
Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)),
|
||||||
Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
|
Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
|
||||||
Load(_, ty) => Ok(ty.clone()),
|
Load(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
|
||||||
Store(_, value) => value.get_type(builder),
|
Store(_, value) => value.get_type(builder),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,11 +6,10 @@ fn indirection() -> bool {
|
|||||||
|
|
||||||
fn main() -> u16 {
|
fn main() -> u16 {
|
||||||
let mut test = 5;
|
let mut test = 5;
|
||||||
let heehoo = 10;
|
|
||||||
|
|
||||||
if indirection() {
|
if indirection() {
|
||||||
test = 11;
|
test = 11;
|
||||||
}
|
}
|
||||||
|
|
||||||
return test + heehoo;
|
return test;
|
||||||
}
|
}
|
||||||
|
@ -40,15 +40,14 @@ type TypeIdRef = Rc<RefCell<usize>>;
|
|||||||
pub struct TypeHints {
|
pub struct TypeHints {
|
||||||
/// Simple list of types that variables can refrence
|
/// Simple list of types that variables can refrence
|
||||||
hints: RefCell<Vec<TypeKind>>,
|
hints: RefCell<Vec<TypeKind>>,
|
||||||
/// Indirect ID-references, referring to hints-vec
|
types: RefCell<Vec<TypeIdRef>>,
|
||||||
type_refs: RefCell<Vec<TypeIdRef>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeHints {
|
impl TypeHints {
|
||||||
pub fn new(&self, ty: TypeKind) -> TypeIdRef {
|
pub fn new(&self, ty: TypeKind) -> TypeIdRef {
|
||||||
let idx = self.hints.borrow().len();
|
let idx = self.hints.borrow().len();
|
||||||
let typecell = Rc::new(RefCell::new(idx));
|
let typecell = Rc::new(RefCell::new(idx));
|
||||||
self.type_refs.borrow_mut().push(typecell.clone());
|
self.types.borrow_mut().push(typecell.clone());
|
||||||
self.hints.borrow_mut().push(ty);
|
self.hints.borrow_mut().push(ty);
|
||||||
typecell
|
typecell
|
||||||
}
|
}
|
||||||
@ -71,13 +70,19 @@ impl<'outer> ScopeHints<'outer> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn retrieve_type(&self, idx: usize) -> Option<TypeKind> {
|
pub fn retrieve_type(&self, mut idx: usize) -> Option<TypeKind> {
|
||||||
let inner_idx = self
|
// Just make sure we have the correct idx
|
||||||
.types
|
let mut inner_idx = self.types.types.borrow().get(idx).map(|i| *i.borrow())?;
|
||||||
.type_refs
|
let mut limit = 50;
|
||||||
.borrow()
|
while inner_idx != idx {
|
||||||
.get(idx)
|
idx = inner_idx;
|
||||||
.map(|i| *i.borrow())?;
|
inner_idx = self.types.types.borrow().get(idx).map(|i| *i.borrow())?;
|
||||||
|
limit -= 1;
|
||||||
|
if limit < 0 {
|
||||||
|
// Should never happen, but just to avoid infinite loops
|
||||||
|
panic!("Limit reached!");
|
||||||
|
}
|
||||||
|
}
|
||||||
self.types.hints.borrow().get(inner_idx).copied()
|
self.types.hints.borrow().get(inner_idx).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +133,7 @@ impl<'outer> ScopeHints<'outer> {
|
|||||||
.get_unchecked(*hint2.0.borrow())
|
.get_unchecked(*hint2.0.borrow())
|
||||||
.clone();
|
.clone();
|
||||||
self.narrow_to_type(&hint1, &ty)?;
|
self.narrow_to_type(&hint1, &ty)?;
|
||||||
for idx in self.types.type_refs.borrow_mut().iter_mut() {
|
for idx in self.types.types.borrow_mut().iter_mut() {
|
||||||
if *idx == hint2.0 {
|
if *idx == hint2.0 {
|
||||||
*idx.borrow_mut() = *hint1.0.borrow();
|
*idx.borrow_mut() = *hint1.0.borrow();
|
||||||
}
|
}
|
||||||
@ -193,7 +198,7 @@ impl<'scope> TypeRef<'scope> {
|
|||||||
Ok(ty) => TypeRef::Literal(*ty),
|
Ok(ty) => TypeRef::Literal(*ty),
|
||||||
Err(vague) => match &vague {
|
Err(vague) => match &vague {
|
||||||
super::VagueType::Hinted(idx) => TypeRef::Hint(ScopeHint(
|
super::VagueType::Hinted(idx) => TypeRef::Hint(ScopeHint(
|
||||||
unsafe { hints.types.type_refs.borrow().get_unchecked(*idx).clone() },
|
unsafe { hints.types.types.borrow().get_unchecked(*idx).clone() },
|
||||||
hints,
|
hints,
|
||||||
)),
|
)),
|
||||||
_ => TypeRef::Hint(hints.new_vague(vague)),
|
_ => TypeRef::Hint(hints.new_vague(vague)),
|
||||||
|
@ -38,8 +38,6 @@ pub enum ErrorKind {
|
|||||||
VariableNotMutable(String),
|
VariableNotMutable(String),
|
||||||
#[error("Function {0} was given {1} parameters, but {2} were expected")]
|
#[error("Function {0} was given {1} parameters, but {2} were expected")]
|
||||||
InvalidAmountParameters(String, usize, usize),
|
InvalidAmountParameters(String, usize, usize),
|
||||||
#[error("Unable to infer type {0}")]
|
|
||||||
TypeNotInferrable(TypeKind),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Struct used to implement a type-checking pass that can be performed on the
|
/// Struct used to implement a type-checking pass that can be performed on the
|
||||||
@ -196,10 +194,6 @@ impl Block {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let res_t = if res_t.known().is_err() {
|
let res_t = if res_t.known().is_err() {
|
||||||
// state.ok::<_, Infallible>(
|
|
||||||
// Err(ErrorKind::TypeNotInferrable(res_t)),
|
|
||||||
// variable_reference.2 + expression.1,
|
|
||||||
// );
|
|
||||||
// Unable to infer variable type even from expression! Default it
|
// Unable to infer variable type even from expression! Default it
|
||||||
let res_t =
|
let res_t =
|
||||||
state.or_else(res_t.or_default(), Vague(Unknown), variable_reference.2);
|
state.or_else(res_t.or_default(), Vague(Unknown), variable_reference.2);
|
||||||
@ -558,6 +552,8 @@ impl Literal {
|
|||||||
(L::Vague(VagueL::Number(v)), U32) => L::U32(v as u32),
|
(L::Vague(VagueL::Number(v)), U32) => L::U32(v as u32),
|
||||||
(L::Vague(VagueL::Number(v)), U64) => L::U64(v as u64),
|
(L::Vague(VagueL::Number(v)), U64) => L::U64(v as u64),
|
||||||
(L::Vague(VagueL::Number(v)), U128) => L::U128(v as u128),
|
(L::Vague(VagueL::Number(v)), U128) => L::U128(v as u128),
|
||||||
|
// Default type for number literal if unable to find true type.
|
||||||
|
(L::Vague(VagueL::Number(v)), Vague(Number)) => L::I32(v as i32),
|
||||||
(_, Vague(_)) => self,
|
(_, Vague(_)) => self,
|
||||||
_ => Err(ErrorKind::LiteralIncompatible(self, hint))?,
|
_ => Err(ErrorKind::LiteralIncompatible(self, hint))?,
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user