Implement GEP instead of the weird thing before
This commit is contained in:
		
							parent
							
								
									312a777203
								
							
						
					
					
						commit
						cbb1be1161
					
				@ -270,6 +270,7 @@ impl Builder {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                Store(ptr, _) => {
 | 
					                Store(ptr, _) => {
 | 
				
			||||||
                    if let Ok(ty) = ptr.get_type(&self) {
 | 
					                    if let Ok(ty) = ptr.get_type(&self) {
 | 
				
			||||||
 | 
					                        dbg!(&ty);
 | 
				
			||||||
                        if let Type::Ptr(_) = ty {
 | 
					                        if let Type::Ptr(_) = ty {
 | 
				
			||||||
                            Ok(())
 | 
					                            Ok(())
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
@ -279,27 +280,14 @@ impl Builder {
 | 
				
			|||||||
                        Err(())
 | 
					                        Err(())
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                Extract(arr, idx) => {
 | 
					 | 
				
			||||||
                    let arr_ty = arr.get_type(&self)?;
 | 
					 | 
				
			||||||
                    if let Type::Array(_, len) = arr_ty {
 | 
					 | 
				
			||||||
                        if len > idx { Ok(()) } else { Err(()) }
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        Err(())
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                ArrayAlloca(_, _) => Ok(()),
 | 
					                ArrayAlloca(_, _) => Ok(()),
 | 
				
			||||||
                Insert(arr, idx, val) => {
 | 
					                ArrayGEP(arr, _) => {
 | 
				
			||||||
                    let arr_ty = arr.get_type(&self)?;
 | 
					                    let arr_ty = arr.get_type(&self)?;
 | 
				
			||||||
                    let val_ty = val.get_type(&self)?;
 | 
					                    if let Type::ArrayPtr(_, _) = arr_ty {
 | 
				
			||||||
                    if let Type::Array(elem_ty, len) = arr_ty {
 | 
					 | 
				
			||||||
                        if val_ty == *elem_ty && len > idx {
 | 
					 | 
				
			||||||
                        Ok(())
 | 
					                        Ok(())
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        Err(())
 | 
					                        Err(())
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        Err(())
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -362,15 +350,14 @@ impl InstructionValue {
 | 
				
			|||||||
                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(ty.clone()),
 | 
				
			||||||
                Store(_, value) => value.get_type(builder),
 | 
					                Store(_, value) => value.get_type(builder),
 | 
				
			||||||
                Extract(arr, _) => match arr.get_type(builder) {
 | 
					                ArrayAlloca(ty, len_value) => {
 | 
				
			||||||
                    Ok(Type::Array(elem_t, _)) => Ok(*elem_t),
 | 
					                    Ok(Type::ArrayPtr(Box::new(ty.clone()), len_value.clone()))
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                ArrayGEP(arr, _) => match arr.get_type(builder) {
 | 
				
			||||||
 | 
					                    Ok(Type::ArrayPtr(elem_t, _)) => Ok(Type::Ptr(Box::new(*elem_t))),
 | 
				
			||||||
                    Ok(_) => Err(()),
 | 
					                    Ok(_) => Err(()),
 | 
				
			||||||
                    Err(_) => Err(()),
 | 
					                    Err(_) => Err(()),
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                ArrayAlloca(ty, len_value) => {
 | 
					 | 
				
			||||||
                    Ok(Type::Array(Box::new(ty.clone()), len_value.clone()))
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Insert(_, _, val) => val.get_type(builder),
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -391,15 +378,6 @@ impl ConstValue {
 | 
				
			|||||||
            ConstValue::U64(_) => U64,
 | 
					            ConstValue::U64(_) => U64,
 | 
				
			||||||
            ConstValue::U128(_) => U128,
 | 
					            ConstValue::U128(_) => U128,
 | 
				
			||||||
            ConstValue::Bool(_) => Bool,
 | 
					            ConstValue::Bool(_) => Bool,
 | 
				
			||||||
            // ConstValue::Array(arr) => Array(
 | 
					 | 
				
			||||||
            //     Box::new(
 | 
					 | 
				
			||||||
            //         arr.iter()
 | 
					 | 
				
			||||||
            //             .map(|a| a.get_type(builder).unwrap())
 | 
					 | 
				
			||||||
            //             .next()
 | 
					 | 
				
			||||||
            //             .unwrap_or(Void),
 | 
					 | 
				
			||||||
            //     ),
 | 
					 | 
				
			||||||
            //     arr.len() as u32,
 | 
					 | 
				
			||||||
            // ),
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -420,7 +398,7 @@ impl Type {
 | 
				
			|||||||
            Type::Bool => true,
 | 
					            Type::Bool => true,
 | 
				
			||||||
            Type::Void => false,
 | 
					            Type::Void => false,
 | 
				
			||||||
            Type::Ptr(_) => false,
 | 
					            Type::Ptr(_) => false,
 | 
				
			||||||
            Type::Array(_, _) => false,
 | 
					            Type::ArrayPtr(_, _) => false,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -439,7 +417,7 @@ impl Type {
 | 
				
			|||||||
            Type::Bool => false,
 | 
					            Type::Bool => false,
 | 
				
			||||||
            Type::Void => false,
 | 
					            Type::Void => false,
 | 
				
			||||||
            Type::Ptr(_) => false,
 | 
					            Type::Ptr(_) => false,
 | 
				
			||||||
            Type::Array(_, _) => false,
 | 
					            Type::ArrayPtr(_, _) => false,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -349,29 +349,9 @@ impl InstructionHolder {
 | 
				
			|||||||
                    module.values.get(&val).unwrap().value_ref,
 | 
					                    module.values.get(&val).unwrap().value_ref,
 | 
				
			||||||
                    module.values.get(&ptr).unwrap().value_ref,
 | 
					                    module.values.get(&ptr).unwrap().value_ref,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Extract(arr, idx) => {
 | 
					 | 
				
			||||||
                    let t = arr.get_type(module.builder).unwrap();
 | 
					 | 
				
			||||||
                    let Type::Array(elem_t, _) = t else { panic!() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    let indices = &mut [ConstValue::I32(*idx as i32).as_llvm(module.context_ref)];
 | 
					 | 
				
			||||||
                    let ptr = LLVMBuildGEP2(
 | 
					 | 
				
			||||||
                        module.builder_ref,
 | 
					 | 
				
			||||||
                        elem_t.as_llvm(module.context_ref),
 | 
					 | 
				
			||||||
                        module.values.get(arr).unwrap().value_ref,
 | 
					 | 
				
			||||||
                        indices.as_mut_ptr(),
 | 
					 | 
				
			||||||
                        1,
 | 
					 | 
				
			||||||
                        c"insert_gep".as_ptr(),
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
                    LLVMBuildLoad2(
 | 
					 | 
				
			||||||
                        module.builder_ref,
 | 
					 | 
				
			||||||
                        elem_t.as_llvm(module.context_ref),
 | 
					 | 
				
			||||||
                        ptr,
 | 
					 | 
				
			||||||
                        c"load".as_ptr(),
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                ArrayAlloca(ty, len) => {
 | 
					                ArrayAlloca(ty, len) => {
 | 
				
			||||||
                    let array_len = ConstValue::U16(*len as u16).as_llvm(module.context_ref);
 | 
					                    let array_len = ConstValue::U16(*len as u16).as_llvm(module.context_ref);
 | 
				
			||||||
                    let array_ty = Type::Array(Box::new(ty.clone()), *len);
 | 
					                    let array_ty = Type::ArrayPtr(Box::new(ty.clone()), *len);
 | 
				
			||||||
                    dbg!(
 | 
					                    dbg!(
 | 
				
			||||||
                        &ty.as_llvm(module.context_ref),
 | 
					                        &ty.as_llvm(module.context_ref),
 | 
				
			||||||
                        &array_ty.as_llvm(module.context_ref)
 | 
					                        &array_ty.as_llvm(module.context_ref)
 | 
				
			||||||
@ -383,31 +363,24 @@ impl InstructionHolder {
 | 
				
			|||||||
                        c"array_alloca".as_ptr(),
 | 
					                        c"array_alloca".as_ptr(),
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                Insert(arr, idx, val) => {
 | 
					                ArrayGEP(arr, indices) => {
 | 
				
			||||||
                    let indices = &mut [ConstValue::I32(*idx as i32).as_llvm(module.context_ref)];
 | 
					                    let t = arr.get_type(module.builder).unwrap();
 | 
				
			||||||
                    let ptr = LLVMBuildGEP2(
 | 
					                    let Type::ArrayPtr(elem_t, _) = t else {
 | 
				
			||||||
 | 
					                        panic!()
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    let mut indices: Vec<_> = indices
 | 
				
			||||||
 | 
					                        .iter()
 | 
				
			||||||
 | 
					                        .map(|idx| ConstValue::U32(*idx).as_llvm(module.context_ref))
 | 
				
			||||||
 | 
					                        .collect();
 | 
				
			||||||
 | 
					                    LLVMBuildGEP2(
 | 
				
			||||||
                        module.builder_ref,
 | 
					                        module.builder_ref,
 | 
				
			||||||
                        val.get_type(module.builder)
 | 
					                        elem_t.as_llvm(module.context_ref),
 | 
				
			||||||
                            .unwrap()
 | 
					 | 
				
			||||||
                            .as_llvm(module.context_ref),
 | 
					 | 
				
			||||||
                        module.values.get(arr).unwrap().value_ref,
 | 
					                        module.values.get(arr).unwrap().value_ref,
 | 
				
			||||||
                        indices.as_mut_ptr(),
 | 
					                        indices.as_mut_ptr(),
 | 
				
			||||||
                        1,
 | 
					                        1,
 | 
				
			||||||
                        c"insert_gep".as_ptr(),
 | 
					                        c"array_gep".as_ptr(),
 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
                    LLVMBuildStore(
 | 
					 | 
				
			||||||
                        module.builder_ref,
 | 
					 | 
				
			||||||
                        module.values.get(val).unwrap().value_ref,
 | 
					 | 
				
			||||||
                        ptr,
 | 
					 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    // LLVMBuildInsertValue(
 | 
					 | 
				
			||||||
                    //     module.builder_ref,
 | 
					 | 
				
			||||||
                    //     ptr,
 | 
					 | 
				
			||||||
                    //     module.values.get(val).unwrap().value_ref,
 | 
					 | 
				
			||||||
                    //     *idx,
 | 
					 | 
				
			||||||
                    //     c"insert".as_ptr(),
 | 
					 | 
				
			||||||
                    // )
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
@ -505,7 +478,7 @@ impl Type {
 | 
				
			|||||||
                Bool => LLVMInt1TypeInContext(context),
 | 
					                Bool => LLVMInt1TypeInContext(context),
 | 
				
			||||||
                Void => LLVMVoidType(),
 | 
					                Void => LLVMVoidType(),
 | 
				
			||||||
                Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0),
 | 
					                Ptr(ty) => LLVMPointerType(ty.as_llvm(context), 0),
 | 
				
			||||||
                Array(elem_t, _) => LLVMPointerType(elem_t.as_llvm(context), 0),
 | 
					                ArrayPtr(elem_t, _) => LLVMPointerType(elem_t.as_llvm(context), 0),
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -100,11 +100,18 @@ impl Debug for Instr {
 | 
				
			|||||||
            Instr::Alloca(name, ty) => write!(f, "alloca<{:?}>({})", ty, name),
 | 
					            Instr::Alloca(name, ty) => write!(f, "alloca<{:?}>({})", ty, name),
 | 
				
			||||||
            Instr::Load(val, ty) => write!(f, "load<{:?}>({:?})", ty, val),
 | 
					            Instr::Load(val, ty) => write!(f, "load<{:?}>({:?})", ty, val),
 | 
				
			||||||
            Instr::Store(ptr, val) => write!(f, "store({:?} = {:?})", ptr, val),
 | 
					            Instr::Store(ptr, val) => write!(f, "store({:?} = {:?})", ptr, val),
 | 
				
			||||||
            Instr::Extract(instruction_value, idx) => fmt_index(f, instruction_value, idx),
 | 
					 | 
				
			||||||
            Instr::ArrayAlloca(ty, instruction_value) => {
 | 
					            Instr::ArrayAlloca(ty, instruction_value) => {
 | 
				
			||||||
                write!(f, "array_alloca<{:?}>({:?})", ty, instruction_value)
 | 
					                write!(f, "array_alloca<{:?}>({:?})", ty, instruction_value)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Instr::Insert(arr, idx, val) => write!(f, "{:?}[{}] = {:?}", arr, idx, val),
 | 
					            Instr::ArrayGEP(instruction_value, items) => fmt_index(
 | 
				
			||||||
 | 
					                f,
 | 
				
			||||||
 | 
					                instruction_value,
 | 
				
			||||||
 | 
					                &items
 | 
				
			||||||
 | 
					                    .iter()
 | 
				
			||||||
 | 
					                    .map(|i| i.to_string())
 | 
				
			||||||
 | 
					                    .collect::<Vec<_>>()
 | 
				
			||||||
 | 
					                    .join(", "),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -178,8 +178,7 @@ pub enum Instr {
 | 
				
			|||||||
    Load(InstructionValue, Type),
 | 
					    Load(InstructionValue, Type),
 | 
				
			||||||
    Store(InstructionValue, InstructionValue),
 | 
					    Store(InstructionValue, InstructionValue),
 | 
				
			||||||
    ArrayAlloca(Type, u32),
 | 
					    ArrayAlloca(Type, u32),
 | 
				
			||||||
    Insert(InstructionValue, u32, InstructionValue),
 | 
					    ArrayGEP(InstructionValue, Vec<u32>),
 | 
				
			||||||
    Extract(InstructionValue, u32),
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Integer Comparison
 | 
					    /// Integer Comparison
 | 
				
			||||||
    ICmp(CmpPredicate, InstructionValue, InstructionValue),
 | 
					    ICmp(CmpPredicate, InstructionValue, InstructionValue),
 | 
				
			||||||
@ -202,7 +201,7 @@ pub enum Type {
 | 
				
			|||||||
    Bool,
 | 
					    Bool,
 | 
				
			||||||
    Void,
 | 
					    Void,
 | 
				
			||||||
    Ptr(Box<Type>),
 | 
					    Ptr(Box<Type>),
 | 
				
			||||||
    Array(Box<Type>, u32),
 | 
					    ArrayPtr(Box<Type>, u32),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Hash)]
 | 
					#[derive(Debug, Clone, Hash)]
 | 
				
			||||||
 | 
				
			|||||||
@ -171,9 +171,11 @@ impl ast::Expression {
 | 
				
			|||||||
            ast::ExpressionKind::Array(expressions) => {
 | 
					            ast::ExpressionKind::Array(expressions) => {
 | 
				
			||||||
                mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect())
 | 
					                mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect())
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ast::ExpressionKind::Index(expression, idx) => {
 | 
					            ast::ExpressionKind::Index(expression, idx) => mir::ExprKind::Index(
 | 
				
			||||||
                mir::ExprKind::Index(Box::new(expression.process()), *idx)
 | 
					                Box::new(expression.process()),
 | 
				
			||||||
            }
 | 
					                mir::TypeKind::Vague(mir::VagueType::Unknown),
 | 
				
			||||||
 | 
					                *idx,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mir::Expression(kind, self.1.into())
 | 
					        mir::Expression(kind, self.1.into())
 | 
				
			||||||
 | 
				
			|||||||
@ -334,12 +334,17 @@ impl mir::Expression {
 | 
				
			|||||||
                    None
 | 
					                    None
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            mir::ExprKind::Index(expression, idx) => {
 | 
					            mir::ExprKind::Index(expression, val_t, idx) => {
 | 
				
			||||||
                let expr = expression.codegen(scope)?;
 | 
					                let array = expression.codegen(scope)?;
 | 
				
			||||||
 | 
					                let ptr = scope
 | 
				
			||||||
 | 
					                    .block
 | 
				
			||||||
 | 
					                    .build(Instr::ArrayGEP(array, vec![*idx as u32]))
 | 
				
			||||||
 | 
					                    .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Some(
 | 
					                Some(
 | 
				
			||||||
                    scope
 | 
					                    scope
 | 
				
			||||||
                        .block
 | 
					                        .block
 | 
				
			||||||
                        .build(Instr::Extract(expr, *idx as u32))
 | 
					                        .build(Instr::Load(ptr, val_t.get_type()))
 | 
				
			||||||
                        .unwrap(),
 | 
					                        .unwrap(),
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -354,7 +359,6 @@ impl mir::Expression {
 | 
				
			|||||||
                    .next()
 | 
					                    .next()
 | 
				
			||||||
                    .unwrap_or(TypeKind::Void);
 | 
					                    .unwrap_or(TypeKind::Void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                dbg!(&instr_t);
 | 
					 | 
				
			||||||
                let array = scope
 | 
					                let array = scope
 | 
				
			||||||
                    .block
 | 
					                    .block
 | 
				
			||||||
                    .build(Instr::ArrayAlloca(
 | 
					                    .build(Instr::ArrayAlloca(
 | 
				
			||||||
@ -364,10 +368,11 @@ impl mir::Expression {
 | 
				
			|||||||
                    .unwrap();
 | 
					                    .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for (i, instr) in instr_list.iter().enumerate() {
 | 
					                for (i, instr) in instr_list.iter().enumerate() {
 | 
				
			||||||
                    scope
 | 
					                    let ptr = scope
 | 
				
			||||||
                        .block
 | 
					                        .block
 | 
				
			||||||
                        .build(Instr::Insert(array, i as u32, *instr))
 | 
					                        .build(Instr::ArrayGEP(array, vec![i as u32]))
 | 
				
			||||||
                        .unwrap();
 | 
					                        .unwrap();
 | 
				
			||||||
 | 
					                    scope.block.build(Instr::Store(ptr, *instr)).unwrap();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Some(array)
 | 
					                Some(array)
 | 
				
			||||||
@ -450,7 +455,9 @@ impl TypeKind {
 | 
				
			|||||||
            TypeKind::U64 => Type::U64,
 | 
					            TypeKind::U64 => Type::U64,
 | 
				
			||||||
            TypeKind::U128 => Type::U128,
 | 
					            TypeKind::U128 => Type::U128,
 | 
				
			||||||
            TypeKind::Bool => Type::Bool,
 | 
					            TypeKind::Bool => Type::Bool,
 | 
				
			||||||
            TypeKind::Array(elem_t, len) => Type::Array(Box::new(elem_t.get_type()), *len as u32),
 | 
					            TypeKind::Array(elem_t, len) => {
 | 
				
			||||||
 | 
					                Type::ArrayPtr(Box::new(elem_t.get_type()), *len as u32)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            TypeKind::Void => panic!("Void not a supported type"),
 | 
					            TypeKind::Void => panic!("Void not a supported type"),
 | 
				
			||||||
            TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
 | 
					            TypeKind::Vague(_) => panic!("Tried to compile a vague type!"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -128,8 +128,9 @@ impl Display for ExprKind {
 | 
				
			|||||||
            ExprKind::FunctionCall(fc) => Display::fmt(fc, f),
 | 
					            ExprKind::FunctionCall(fc) => Display::fmt(fc, f),
 | 
				
			||||||
            ExprKind::If(if_exp) => Display::fmt(&if_exp, f),
 | 
					            ExprKind::If(if_exp) => Display::fmt(&if_exp, f),
 | 
				
			||||||
            ExprKind::Block(block) => Display::fmt(block, f),
 | 
					            ExprKind::Block(block) => Display::fmt(block, f),
 | 
				
			||||||
            ExprKind::Index(expression, idx) => {
 | 
					            ExprKind::Index(expression, elem_ty, idx) => {
 | 
				
			||||||
                Display::fmt(&expression, f)?;
 | 
					                Display::fmt(&expression, f)?;
 | 
				
			||||||
 | 
					                write!(f, "<{}>", elem_ty)?;
 | 
				
			||||||
                write_index(f, *idx)
 | 
					                write_index(f, *idx)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ExprKind::Array(expressions) => {
 | 
					            ExprKind::Array(expressions) => {
 | 
				
			||||||
 | 
				
			|||||||
@ -208,7 +208,7 @@ pub struct Import(pub String, pub Metadata);
 | 
				
			|||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub enum ExprKind {
 | 
					pub enum ExprKind {
 | 
				
			||||||
    Variable(NamedVariableRef),
 | 
					    Variable(NamedVariableRef),
 | 
				
			||||||
    Index(Box<Expression>, u64),
 | 
					    Index(Box<Expression>, TypeKind, u64),
 | 
				
			||||||
    Array(Vec<Expression>),
 | 
					    Array(Vec<Expression>),
 | 
				
			||||||
    Literal(Literal),
 | 
					    Literal(Literal),
 | 
				
			||||||
    BinOp(BinaryOperator, Box<Expression>, Box<Expression>),
 | 
					    BinOp(BinaryOperator, Box<Expression>, Box<Expression>),
 | 
				
			||||||
 | 
				
			|||||||
@ -380,7 +380,7 @@ impl Expression {
 | 
				
			|||||||
                Ok(collapsed)
 | 
					                Ok(collapsed)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ExprKind::Block(block) => block.typecheck(state, &hints, hint_t),
 | 
					            ExprKind::Block(block) => block.typecheck(state, &hints, hint_t),
 | 
				
			||||||
            ExprKind::Index(expression, idx) => {
 | 
					            ExprKind::Index(expression, elem_ty, idx) => {
 | 
				
			||||||
                // Try to unwrap hint type from array if possible
 | 
					                // Try to unwrap hint type from array if possible
 | 
				
			||||||
                let hint_t = hint_t.map(|t| match t {
 | 
					                let hint_t = hint_t.map(|t| match t {
 | 
				
			||||||
                    Array(type_kind, _) => &type_kind,
 | 
					                    Array(type_kind, _) => &type_kind,
 | 
				
			||||||
@ -388,11 +388,17 @@ impl Expression {
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let expr_t = expression.typecheck(state, hints, hint_t)?;
 | 
					                let expr_t = expression.typecheck(state, hints, hint_t)?;
 | 
				
			||||||
                if let TypeKind::Array(elem_t, len) = expr_t {
 | 
					                if let TypeKind::Array(inferred_ty, len) = expr_t {
 | 
				
			||||||
                    if len < *idx {
 | 
					                    if len < *idx {
 | 
				
			||||||
                        return Err(ErrorKind::IndexOutOfBounds(*idx, len));
 | 
					                        return Err(ErrorKind::IndexOutOfBounds(*idx, len));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Ok(*elem_t)
 | 
					                    let ty = state.or_else(
 | 
				
			||||||
 | 
					                        elem_ty.resolve_hinted(hints).collapse_into(&inferred_ty),
 | 
				
			||||||
 | 
					                        TypeKind::Vague(Unknown),
 | 
				
			||||||
 | 
					                        self.1,
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                    *elem_ty = ty.clone();
 | 
				
			||||||
 | 
					                    Ok(ty)
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    Err(ErrorKind::TriedIndexingNonArray(expr_t))
 | 
					                    Err(ErrorKind::TriedIndexingNonArray(expr_t))
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
				
			|||||||
@ -263,11 +263,16 @@ impl Expression {
 | 
				
			|||||||
                    ReturnKind::Soft => Ok(block_ref.1),
 | 
					                    ReturnKind::Soft => Ok(block_ref.1),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ExprKind::Index(expression, _) => {
 | 
					            ExprKind::Index(expression, index_ty, _) => {
 | 
				
			||||||
                let expr_ty = expression.infer_types(state, type_refs)?;
 | 
					                let expr_ty = expression.infer_types(state, type_refs)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let kind = unsafe { expr_ty.resolve_type() };
 | 
					                let kind = unsafe { expr_ty.resolve_type() };
 | 
				
			||||||
                match kind {
 | 
					                match kind {
 | 
				
			||||||
                    Array(type_kind, _) => Ok(type_refs.from_type(&type_kind).unwrap()),
 | 
					                    Array(type_kind, _) => {
 | 
				
			||||||
 | 
					                        let elem_ty = type_refs.from_type(&type_kind).unwrap();
 | 
				
			||||||
 | 
					                        *index_ty = elem_ty.as_type().clone();
 | 
				
			||||||
 | 
					                        Ok(elem_ty)
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    _ => Err(ErrorKind::TriedIndexingNonArray(kind)),
 | 
					                    _ => Err(ErrorKind::TriedIndexingNonArray(kind)),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -89,7 +89,7 @@ impl ReturnType for Expression {
 | 
				
			|||||||
            Block(block) => block.return_type(),
 | 
					            Block(block) => block.return_type(),
 | 
				
			||||||
            FunctionCall(fcall) => fcall.return_type(),
 | 
					            FunctionCall(fcall) => fcall.return_type(),
 | 
				
			||||||
            If(expr) => expr.return_type(),
 | 
					            If(expr) => expr.return_type(),
 | 
				
			||||||
            Index(expression, _) => {
 | 
					            Index(expression, _, _) => {
 | 
				
			||||||
                let expr_type = expression.return_type()?;
 | 
					                let expr_type = expression.return_type()?;
 | 
				
			||||||
                if let (_, TypeKind::Array(elem_ty, _)) = expr_type {
 | 
					                if let (_, TypeKind::Array(elem_ty, _)) = expr_type {
 | 
				
			||||||
                    Ok((ReturnKind::Soft, *elem_ty))
 | 
					                    Ok((ReturnKind::Soft, *elem_ty))
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user