use signed integer for TSeq

This commit is contained in:
pca006132 2021-07-19 13:34:45 +08:00
parent f51603f6da
commit c913fb28bd

View File

@ -81,7 +81,7 @@ pub enum TypeEnum {
id: u32, id: u32,
}, },
TSeq { TSeq {
map: VarMap, map: Mapping<i32>,
}, },
TTuple { TTuple {
ty: Vec<Type>, ty: Vec<Type>,
@ -274,16 +274,18 @@ impl Unifier {
self.set_a_to_b(a, b); self.set_a_to_b(a, b);
} }
TypeEnum::TTuple { ty: types } => { TypeEnum::TTuple { ty: types } => {
let len = types.len() as u32; let len = types.len() as i32;
for (k, v) in map1.iter() { for (k, v) in map1.iter() {
if *k >= len { // handle negative index
let ind = if *k < 0 { len + *k } else { *k };
if ind >= len || ind < 0 {
return Err(format!( return Err(format!(
"Tuple index out of range. (Length: {}, Index: {})", "Tuple index out of range. (Length: {}, Index: {})",
types.len(), types.len(),
k k
)); ));
} }
self.unify(*v, types[*k as usize])?; self.unify(*v, types[ind as usize])?;
} }
self.set_a_to_b(a, b); self.set_a_to_b(a, b);
} }
@ -516,7 +518,7 @@ impl Unifier {
TypeEnum::TVar { .. } => { TypeEnum::TVar { .. } => {
// TODO: occur check for bounds... // TODO: occur check for bounds...
} }
TypeEnum::TSeq { map } | TypeEnum::TObj { params: map, .. } => { TypeEnum::TSeq { map } => {
for t in map.values() { for t in map.values() {
self.occur_check(a, *t)?; self.occur_check(a, *t)?;
} }
@ -534,6 +536,11 @@ impl Unifier {
self.occur_check(a, *t)?; self.occur_check(a, *t)?;
} }
} }
TypeEnum::TObj { params: map, .. } => {
for t in map.values() {
self.occur_check(a, *t)?;
}
}
TypeEnum::TCall { calls } => { TypeEnum::TCall { calls } => {
for t in calls for t in calls
.iter() .iter()