Add scaffolding to return some errors from codegen
This commit is contained in:
		
							parent
							
								
									bd356f11db
								
							
						
					
					
						commit
						efeefe0bfe
					
				| @ -4,8 +4,8 @@ | |||||||
| use std::{cell::RefCell, rc::Rc}; | use std::{cell::RefCell, rc::Rc}; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     Block, BlockData, CustomTypeKind, FunctionData, Instr, InstructionData, ModuleData, |     Block, BlockData, CompileResult, CustomTypeKind, ErrorKind, FunctionData, Instr, | ||||||
|     NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, |     InstructionData, ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, | ||||||
|     debug_information::{ |     debug_information::{ | ||||||
|         DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, |         DebugInformation, DebugLocationValue, DebugMetadataValue, DebugProgramValue, | ||||||
|         InstructionDebugRecordData, |         InstructionDebugRecordData, | ||||||
| @ -151,7 +151,7 @@ impl Builder { | |||||||
|         block_val: &BlockValue, |         block_val: &BlockValue, | ||||||
|         data: InstructionData, |         data: InstructionData, | ||||||
|         name: String, |         name: String, | ||||||
|     ) -> Result<InstructionValue, ()> { |     ) -> CompileResult<InstructionValue> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let mut modules = self.modules.borrow_mut(); |             let mut modules = self.modules.borrow_mut(); | ||||||
|             let module = modules.get_unchecked_mut(block_val.0.0.0); |             let module = modules.get_unchecked_mut(block_val.0.0.0); | ||||||
| @ -236,14 +236,14 @@ impl Builder { | |||||||
|         &self, |         &self, | ||||||
|         block: &BlockValue, |         block: &BlockValue, | ||||||
|         value: TerminatorKind, |         value: TerminatorKind, | ||||||
|     ) -> Result<(), ()> { |     ) -> CompileResult<()> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let mut modules = self.modules.borrow_mut(); |             let mut modules = self.modules.borrow_mut(); | ||||||
|             let module = modules.get_unchecked_mut(block.0.0.0); |             let module = modules.get_unchecked_mut(block.0.0.0); | ||||||
|             let function = module.functions.get_unchecked_mut(block.0.1); |             let function = module.functions.get_unchecked_mut(block.0.1); | ||||||
|             let block = function.blocks.get_unchecked_mut(block.1); |             let block = function.blocks.get_unchecked_mut(block.1); | ||||||
|             if let Some(_) = &block.data.terminator { |             if let Some(_) = &block.data.terminator { | ||||||
|                 Err(()) |                 Err(ErrorKind::Null) | ||||||
|             } else { |             } else { | ||||||
|                 block.data.terminator = Some(value); |                 block.data.terminator = Some(value); | ||||||
|                 Ok(()) |                 Ok(()) | ||||||
| @ -255,14 +255,14 @@ impl Builder { | |||||||
|         &self, |         &self, | ||||||
|         block: &BlockValue, |         block: &BlockValue, | ||||||
|         location: DebugLocationValue, |         location: DebugLocationValue, | ||||||
|     ) -> Result<(), ()> { |     ) -> CompileResult<()> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let mut modules = self.modules.borrow_mut(); |             let mut modules = self.modules.borrow_mut(); | ||||||
|             let module = modules.get_unchecked_mut(block.0.0.0); |             let module = modules.get_unchecked_mut(block.0.0.0); | ||||||
|             let function = module.functions.get_unchecked_mut(block.0.1); |             let function = module.functions.get_unchecked_mut(block.0.1); | ||||||
|             let block = function.blocks.get_unchecked_mut(block.1); |             let block = function.blocks.get_unchecked_mut(block.1); | ||||||
|             if let Some(_) = &block.data.terminator_location { |             if let Some(_) = &block.data.terminator_location { | ||||||
|                 Err(()) |                 Err(ErrorKind::Null) | ||||||
|             } else { |             } else { | ||||||
|                 block.data.terminator_location = Some(location); |                 block.data.terminator_location = Some(location); | ||||||
|                 Ok(()) |                 Ok(()) | ||||||
| @ -270,7 +270,7 @@ impl Builder { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub(crate) unsafe fn delete_block(&self, block: &BlockValue) -> Result<(), ()> { |     pub(crate) unsafe fn delete_block(&self, block: &BlockValue) -> CompileResult<()> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let mut modules = self.modules.borrow_mut(); |             let mut modules = self.modules.borrow_mut(); | ||||||
|             let module = modules.get_unchecked_mut(block.0.0.0); |             let module = modules.get_unchecked_mut(block.0.0.0); | ||||||
| @ -349,7 +349,7 @@ impl Builder { | |||||||
|         self.modules.clone() |         self.modules.clone() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn check_instruction(&self, instruction: &InstructionValue) -> Result<(), ()> { |     pub fn check_instruction(&self, instruction: &InstructionValue) -> CompileResult<()> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             match self.instr_data(&instruction).kind { |             match self.instr_data(&instruction).kind { | ||||||
|                 Instr::Param(_) => Ok(()), |                 Instr::Param(_) => Ok(()), | ||||||
| @ -372,7 +372,7 @@ impl Builder { | |||||||
|                     if t.comparable() || t.category() != TypeCategory::Integer { |                     if t.comparable() || t.category() != TypeCategory::Integer { | ||||||
|                         Ok(()) |                         Ok(()) | ||||||
|                     } else { |                     } else { | ||||||
|                         Err(()) // TODO error: Types not comparable
 |                         Err(ErrorKind::Null) // TODO error: Types not comparable
 | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Instr::FCmp(_, lhs, rhs) => { |                 Instr::FCmp(_, lhs, rhs) => { | ||||||
| @ -380,17 +380,17 @@ impl Builder { | |||||||
|                     if t.comparable() || t.category() != TypeCategory::Real { |                     if t.comparable() || t.category() != TypeCategory::Real { | ||||||
|                         Ok(()) |                         Ok(()) | ||||||
|                     } else { |                     } else { | ||||||
|                         Err(()) // TODO error: Types not comparable
 |                         Err(ErrorKind::Null) // TODO error: Types not comparable
 | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Instr::FunctionCall(fun, params) => { |                 Instr::FunctionCall(fun, params) => { | ||||||
|                     let param_types = self.function_data(&fun).params; |                     let param_types = self.function_data(&fun).params; | ||||||
|                     if param_types.len() != params.len() { |                     if param_types.len() != params.len() { | ||||||
|                         return Err(()); // TODO error: invalid amount of params
 |                         return Err(ErrorKind::Null); // TODO error: invalid amount of params
 | ||||||
|                     } |                     } | ||||||
|                     for (a, b) in param_types.iter().zip(params) { |                     for (a, b) in param_types.iter().zip(params) { | ||||||
|                         if *a != b.get_type(&self)? { |                         if *a != b.get_type(&self)? { | ||||||
|                             return Err(()); // TODO error: params do not match
 |                             return Err(ErrorKind::Null); // TODO error: params do not match
 | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     Ok(()) |                     Ok(()) | ||||||
| @ -403,7 +403,7 @@ impl Builder { | |||||||
|                     // incoming values come from blocks that are added later
 |                     // incoming values come from blocks that are added later
 | ||||||
|                     // than the one where this one exists.
 |                     // than the one where this one exists.
 | ||||||
| 
 | 
 | ||||||
|                     let first = iter.next().ok_or(())?; |                     let first = iter.next().ok_or(ErrorKind::Null)?; | ||||||
|                     for item in iter { |                     for item in iter { | ||||||
|                         match_types(first, item, &self)?; |                         match_types(first, item, &self)?; | ||||||
|                     } |                     } | ||||||
| @ -416,10 +416,10 @@ impl Builder { | |||||||
|                         if *ptr_ty_inner == load_ty { |                         if *ptr_ty_inner == load_ty { | ||||||
|                             Ok(()) |                             Ok(()) | ||||||
|                         } else { |                         } else { | ||||||
|                             Err(()) // TODO error: inner type mismatch
 |                             Err(ErrorKind::Null) // TODO error: inner type mismatch
 | ||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         Err(()) // TODO error: not a pointer
 |                         Err(ErrorKind::Null) // TODO error: not a pointer
 | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Instr::Store(ptr, _) => { |                 Instr::Store(ptr, _) => { | ||||||
| @ -427,7 +427,7 @@ impl Builder { | |||||||
|                     if let Type::Ptr(_) = ty { |                     if let Type::Ptr(_) = ty { | ||||||
|                         Ok(()) |                         Ok(()) | ||||||
|                     } else { |                     } else { | ||||||
|                         Err(()) // TODO error: not a pointer
 |                         Err(ErrorKind::Null) // TODO error: not a pointer
 | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Instr::ArrayAlloca(_, _) => Ok(()), |                 Instr::ArrayAlloca(_, _) => Ok(()), | ||||||
| @ -435,7 +435,7 @@ impl Builder { | |||||||
|                     let ptr_ty = ptr_val.get_type(&self)?; |                     let ptr_ty = ptr_val.get_type(&self)?; | ||||||
|                     match ptr_ty { |                     match ptr_ty { | ||||||
|                         Type::Ptr(_) => Ok(()), |                         Type::Ptr(_) => Ok(()), | ||||||
|                         _ => Err(()), |                         _ => Err(ErrorKind::Null), | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Instr::GetStructElemPtr(ptr_val, idx) => { |                 Instr::GetStructElemPtr(ptr_val, idx) => { | ||||||
| @ -445,16 +445,16 @@ impl Builder { | |||||||
|                             match self.type_data(&val).kind { |                             match self.type_data(&val).kind { | ||||||
|                                 CustomTypeKind::NamedStruct(NamedStruct(_, fields)) => { |                                 CustomTypeKind::NamedStruct(NamedStruct(_, fields)) => { | ||||||
|                                     if fields.len() <= idx as usize { |                                     if fields.len() <= idx as usize { | ||||||
|                                         return Err(()); // TODO error: no such field
 |                                         return Err(ErrorKind::Null); // TODO error: no such field
 | ||||||
|                                     } |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                             Ok(()) |                             Ok(()) | ||||||
|                         } else { |                         } else { | ||||||
|                             Err(()) // TODO error: not a struct
 |                             Err(ErrorKind::Null) // TODO error: not a struct
 | ||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         Err(()) // TODO error: not a pointer
 |                         Err(ErrorKind::Null) // TODO error: not a pointer
 | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Instr::ExtractValue(val, _) => { |                 Instr::ExtractValue(val, _) => { | ||||||
| @ -464,7 +464,7 @@ impl Builder { | |||||||
|                             CustomTypeKind::NamedStruct(_) => Ok(()), |                             CustomTypeKind::NamedStruct(_) => Ok(()), | ||||||
|                         }, |                         }, | ||||||
|                         Type::Array(_, _) => Ok(()), |                         Type::Array(_, _) => Ok(()), | ||||||
|                         _ => Err(()), |                         _ => Err(ErrorKind::Null), | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Instr::Trunc(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), |                 Instr::Trunc(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), | ||||||
| @ -545,7 +545,7 @@ impl InstructionValue { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub(crate) fn get_type(&self, builder: &Builder) -> Result<Type, ()> { |     pub(crate) fn get_type(&self, builder: &Builder) -> CompileResult<Type> { | ||||||
|         use Instr::*; |         use Instr::*; | ||||||
|         unsafe { |         unsafe { | ||||||
|             match &builder.instr_data(self).kind { |             match &builder.instr_data(self).kind { | ||||||
| @ -554,7 +554,7 @@ impl InstructionValue { | |||||||
|                     .params |                     .params | ||||||
|                     .get(*nth) |                     .get(*nth) | ||||||
|                     .cloned() |                     .cloned() | ||||||
|                     .ok_or(()), |                     .ok_or(ErrorKind::Null), | ||||||
|                 Constant(c) => Ok(c.get_type()), |                 Constant(c) => Ok(c.get_type()), | ||||||
|                 Add(lhs, rhs) => match_types(lhs, rhs, &builder), |                 Add(lhs, rhs) => match_types(lhs, rhs, &builder), | ||||||
|                 FAdd(lhs, rhs) => match_types(lhs, rhs, &builder), |                 FAdd(lhs, rhs) => match_types(lhs, rhs, &builder), | ||||||
| @ -572,7 +572,10 @@ impl InstructionValue { | |||||||
|                 ICmp(_, _, _) => Ok(Type::Bool), |                 ICmp(_, _, _) => Ok(Type::Bool), | ||||||
|                 FCmp(_, _, _) => Ok(Type::Bool), |                 FCmp(_, _, _) => Ok(Type::Bool), | ||||||
|                 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(ErrorKind::Null) | ||||||
|  |                     .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(ty.clone()), | ||||||
|                 Store(_, value) => value.get_type(builder), |                 Store(_, value) => value.get_type(builder), | ||||||
| @ -614,7 +617,7 @@ impl InstructionValue { | |||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         Type::Array(elem_ty, _) => *elem_ty.clone(), |                         Type::Array(elem_ty, _) => *elem_ty.clone(), | ||||||
|                         _ => return Err(()), |                         _ => return Err(ErrorKind::Null), | ||||||
|                     }) |                     }) | ||||||
|                 } |                 } | ||||||
|                 Trunc(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), |                 Trunc(instr, ty) => instr.cast_to(builder, ty).map(|_| ty.clone()), | ||||||
| @ -633,9 +636,9 @@ impl InstructionValue { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn cast_to(&self, builder: &Builder, ty: &Type) -> Result<Instr, ()> { |     fn cast_to(&self, builder: &Builder, ty: &Type) -> CompileResult<Instr> { | ||||||
|         self.get_type(builder)? |         self.get_type(builder)? | ||||||
|             .cast_instruction(*self, &ty) |             .cast_instruction(*self, &ty) | ||||||
|             .ok_or(()) |             .ok_or(ErrorKind::Null) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -17,6 +17,14 @@ mod fmt; | |||||||
| mod pad_adapter; | mod pad_adapter; | ||||||
| mod util; | mod util; | ||||||
| 
 | 
 | ||||||
|  | #[derive(thiserror::Error, Debug, Clone, PartialEq, PartialOrd)] | ||||||
|  | pub enum ErrorKind { | ||||||
|  |     #[error("NULL error, should never occur!")] | ||||||
|  |     Null, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub type CompileResult<T> = Result<T, ErrorKind>; | ||||||
|  | 
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| pub struct Context { | pub struct Context { | ||||||
|     builder: Builder, |     builder: Builder, | ||||||
| @ -254,7 +262,7 @@ impl<'builder> Block<'builder> { | |||||||
|         &mut self, |         &mut self, | ||||||
|         name: T, |         name: T, | ||||||
|         instruction: Instr, |         instruction: Instr, | ||||||
|     ) -> Result<InstructionValue, ()> { |     ) -> CompileResult<InstructionValue> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             self.builder.add_instruction( |             self.builder.add_instruction( | ||||||
|                 &self.value, |                 &self.value, | ||||||
| @ -268,7 +276,7 @@ impl<'builder> Block<'builder> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn build(&mut self, instruction: Instr) -> Result<InstructionValue, ()> { |     pub fn build(&mut self, instruction: Instr) -> CompileResult<InstructionValue> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             let name = instruction.default_name().to_owned(); |             let name = instruction.default_name().to_owned(); | ||||||
|             self.builder.add_instruction( |             self.builder.add_instruction( | ||||||
| @ -297,16 +305,16 @@ impl<'builder> Block<'builder> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn terminate(&mut self, instruction: TerminatorKind) -> Result<(), ()> { |     pub fn terminate(&mut self, instruction: TerminatorKind) -> CompileResult<()> { | ||||||
|         unsafe { self.builder.terminate(&self.value, instruction) } |         unsafe { self.builder.terminate(&self.value, instruction) } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn set_terminator_location(&mut self, location: DebugLocationValue) -> Result<(), ()> { |     pub fn set_terminator_location(&mut self, location: DebugLocationValue) -> CompileResult<()> { | ||||||
|         unsafe { self.builder.set_terminator_location(&self.value, location) } |         unsafe { self.builder.set_terminator_location(&self.value, location) } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Delete block if it is unused. Return true if deleted, false if not.
 |     /// Delete block if it is unused. Return true if deleted, false if not.
 | ||||||
|     pub fn delete_if_unused(&mut self) -> Result<bool, ()> { |     pub fn delete_if_unused(&mut self) -> CompileResult<bool> { | ||||||
|         unsafe { |         unsafe { | ||||||
|             if !self.builder.is_block_used(self.value()) { |             if !self.builder.is_block_used(self.value()) { | ||||||
|                 self.builder.delete_block(&self.value)?; |                 self.builder.delete_block(&self.value)?; | ||||||
| @ -682,7 +690,7 @@ pub enum TypeCategory { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl TerminatorKind { | impl TerminatorKind { | ||||||
|     pub(crate) fn get_type(&self, builder: &Builder) -> Result<Type, ()> { |     pub(crate) fn get_type(&self, builder: &Builder) -> CompileResult<Type> { | ||||||
|         use TerminatorKind::*; |         use TerminatorKind::*; | ||||||
|         match self { |         match self { | ||||||
|             Ret(instr_val) => instr_val.get_type(builder), |             Ret(instr_val) => instr_val.get_type(builder), | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ use llvm_sys::{ | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     Type, |     CompileResult, ErrorKind, Type, | ||||||
|     builder::{Builder, InstructionValue}, |     builder::{Builder, InstructionValue}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -117,12 +117,16 @@ pub fn match_types( | |||||||
|     lhs: &InstructionValue, |     lhs: &InstructionValue, | ||||||
|     rhs: &InstructionValue, |     rhs: &InstructionValue, | ||||||
|     builder: &Builder, |     builder: &Builder, | ||||||
| ) -> Result<Type, ()> { | ) -> CompileResult<Type> { | ||||||
|     let lhs_type = lhs.get_type(&builder); |     let lhs_type = lhs.get_type(&builder); | ||||||
|     let rhs_type = rhs.get_type(&builder); |     let rhs_type = rhs.get_type(&builder); | ||||||
|     if let (Ok(lhs_t), Ok(rhs_t)) = (lhs_type, rhs_type) { |     if let (Ok(lhs_t), Ok(rhs_t)) = (lhs_type, rhs_type) { | ||||||
|         if lhs_t == rhs_t { Ok(lhs_t) } else { Err(()) } |         if lhs_t == rhs_t { | ||||||
|  |             Ok(lhs_t) | ||||||
|  |         } else { | ||||||
|  |             Err(ErrorKind::Null) | ||||||
|  |         } | ||||||
|     } else { |     } else { | ||||||
|         Err(()) |         Err(ErrorKind::Null) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -20,8 +20,15 @@ use crate::{ | |||||||
|         self, implement::TypeCategory, CustomTypeKey, Metadata, NamedVariableRef, SourceModuleId, |         self, implement::TypeCategory, CustomTypeKey, Metadata, NamedVariableRef, SourceModuleId, | ||||||
|         StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, VagueLiteral, |         StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, VagueLiteral, | ||||||
|     }, |     }, | ||||||
|  |     util::try_all, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | #[derive(thiserror::Error, Debug, Clone, PartialEq, PartialOrd)] | ||||||
|  | pub enum ErrorKind { | ||||||
|  |     #[error("NULL error, should never occur!")] | ||||||
|  |     Null, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /// Context that contains all of the given modules as complete codegenerated
 | /// Context that contains all of the given modules as complete codegenerated
 | ||||||
| /// LLIR that can then be finally compiled into LLVM IR.
 | /// LLIR that can then be finally compiled into LLVM IR.
 | ||||||
| #[derive(Debug)] | #[derive(Debug)] | ||||||
| @ -39,16 +46,16 @@ impl<'ctx> CodegenContext<'ctx> { | |||||||
| 
 | 
 | ||||||
| impl mir::Context { | impl mir::Context { | ||||||
|     /// Compile MIR [`Context`] into [`CodegenContext`] containing LLIR.
 |     /// Compile MIR [`Context`] into [`CodegenContext`] containing LLIR.
 | ||||||
|     pub fn codegen<'ctx>(&self, context: &'ctx Context) -> CodegenContext<'ctx> { |     pub fn codegen<'ctx>(&self, context: &'ctx Context) -> Result<CodegenContext<'ctx>, ErrorKind> { | ||||||
|         let mut modules = HashMap::new(); |         let mut modules = HashMap::new(); | ||||||
|         let mut modules_sorted = self.modules.iter().map(|(_, m)| m).collect::<Vec<_>>(); |         let mut modules_sorted = self.modules.iter().map(|(_, m)| m).collect::<Vec<_>>(); | ||||||
|         modules_sorted.sort_by(|m1, m2| m2.module_id.cmp(&m1.module_id)); |         modules_sorted.sort_by(|m1, m2| m2.module_id.cmp(&m1.module_id)); | ||||||
| 
 | 
 | ||||||
|         for module in &modules_sorted { |         for module in &modules_sorted { | ||||||
|             let codegen = module.codegen(context, modules.clone()); |             let codegen = module.codegen(context, modules.clone())?; | ||||||
|             modules.insert(module.module_id, codegen); |             modules.insert(module.module_id, codegen); | ||||||
|         } |         } | ||||||
|         CodegenContext { context } |         Ok(CodegenContext { context }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -194,7 +201,7 @@ impl mir::Module { | |||||||
|         &'ctx self, |         &'ctx self, | ||||||
|         context: &'ctx Context, |         context: &'ctx Context, | ||||||
|         modules: HashMap<SourceModuleId, ModuleCodegen<'ctx>>, |         modules: HashMap<SourceModuleId, ModuleCodegen<'ctx>>, | ||||||
|     ) -> ModuleCodegen<'ctx> { |     ) -> Result<ModuleCodegen<'ctx>, ErrorKind> { | ||||||
|         let mut module = context.module(&self.name, self.is_main); |         let mut module = context.module(&self.name, self.is_main); | ||||||
|         let tokens = &self.tokens; |         let tokens = &self.tokens; | ||||||
| 
 | 
 | ||||||
| @ -430,7 +437,7 @@ impl mir::Module { | |||||||
|                     }; |                     }; | ||||||
| 
 | 
 | ||||||
|                     let state = State::default(); |                     let state = State::default(); | ||||||
|                     if let Some(ret) = block.codegen(&mut scope, &state) { |                     if let Some(ret) = block.codegen(&mut scope, &state)? { | ||||||
|                         scope.block.terminate(Term::Ret(ret.instr())).unwrap(); |                         scope.block.terminate(Term::Ret(ret.instr())).unwrap(); | ||||||
|                     } else { |                     } else { | ||||||
|                         if !scope.block.delete_if_unused().unwrap() { |                         if !scope.block.delete_if_unused().unwrap() { | ||||||
| @ -451,7 +458,7 @@ impl mir::Module { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         ModuleCodegen { module } |         Ok(ModuleCodegen { module }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -460,9 +467,9 @@ impl mir::Block { | |||||||
|         &self, |         &self, | ||||||
|         mut scope: &mut Scope<'ctx, 'a>, |         mut scope: &mut Scope<'ctx, 'a>, | ||||||
|         state: &State, |         state: &State, | ||||||
|     ) -> Option<StackValue> { |     ) -> Result<Option<StackValue>, ErrorKind> { | ||||||
|         for stmt in &self.statements { |         for stmt in &self.statements { | ||||||
|             stmt.codegen(&mut scope, state).map(|s| { |             stmt.codegen(&mut scope, state)?.map(|s| { | ||||||
|                 if let Some(debug) = &scope.debug { |                 if let Some(debug) = &scope.debug { | ||||||
|                     let location = stmt.1.into_debug(scope.tokens, debug.scope).unwrap(); |                     let location = stmt.1.into_debug(scope.tokens, debug.scope).unwrap(); | ||||||
|                     let loc_val = debug.info.location(&debug.scope, location); |                     let loc_val = debug.info.location(&debug.scope, location); | ||||||
| @ -472,22 +479,30 @@ impl mir::Block { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if let Some((kind, expr)) = &self.return_expression { |         if let Some((kind, expr)) = &self.return_expression { | ||||||
|             let ret = expr.codegen(&mut scope, &mut state.load(true)); |             let ret = expr.codegen(&mut scope, &mut state.load(true))?; | ||||||
|             match kind { |             match kind { | ||||||
|                 mir::ReturnKind::Hard => { |                 mir::ReturnKind::Hard => { | ||||||
|                     scope.block.terminate(Term::Ret(ret?.instr())).unwrap(); |                     if let Some(ret) = ret { | ||||||
|                     None |                         scope.block.terminate(Term::Ret(ret.instr())).unwrap(); | ||||||
|  |                     } else { | ||||||
|  |                         scope.block.terminate(Term::RetVoid).unwrap(); | ||||||
|  |                     } | ||||||
|  |                     Ok(None) | ||||||
|                 } |                 } | ||||||
|                 mir::ReturnKind::Soft => ret, |                 mir::ReturnKind::Soft => Ok(ret), | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             None |             Ok(None) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl mir::Statement { | impl mir::Statement { | ||||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option<StackValue> { |     fn codegen<'ctx, 'a>( | ||||||
|  |         &self, | ||||||
|  |         scope: &mut Scope<'ctx, 'a>, | ||||||
|  |         state: &State, | ||||||
|  |     ) -> Result<Option<StackValue>, ErrorKind> { | ||||||
|         let location = scope.debug.clone().map(|d| { |         let location = scope.debug.clone().map(|d| { | ||||||
|             let location = self.1.into_debug(scope.tokens, d.scope).unwrap(); |             let location = self.1.into_debug(scope.tokens, d.scope).unwrap(); | ||||||
|             d.info.location(&d.scope, location) |             d.info.location(&d.scope, location) | ||||||
| @ -495,7 +510,7 @@ impl mir::Statement { | |||||||
| 
 | 
 | ||||||
|         match &self.0 { |         match &self.0 { | ||||||
|             mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => { |             mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => { | ||||||
|                 let value = expression.codegen(scope, &state).unwrap(); |                 let value = expression.codegen(scope, &state)?.unwrap(); | ||||||
| 
 | 
 | ||||||
|                 let alloca = scope |                 let alloca = scope | ||||||
|                     .block |                     .block | ||||||
| @ -545,14 +560,17 @@ impl mir::Statement { | |||||||
|                         }, |                         }, | ||||||
|                     ); |                     ); | ||||||
|                 } |                 } | ||||||
|                 None |                 Ok(None) | ||||||
|             } |             } | ||||||
|             mir::StmtKind::Set(lhs, rhs) => { |             mir::StmtKind::Set(lhs, rhs) => { | ||||||
|                 let lhs_value = lhs |                 let lhs_value = lhs | ||||||
|                     .codegen(scope, &state.load(false)) |                     .codegen(scope, &state.load(false))? | ||||||
|                     .expect("non-returning LHS snuck into codegen!"); |                     .expect("non-returning LHS snuck into codegen!"); | ||||||
| 
 | 
 | ||||||
|                 let rhs_value = rhs.codegen(scope, state)?; |                 let rhs_value = rhs.codegen(scope, state)?; | ||||||
|  |                 let Some(rhs_value) = rhs_value else { | ||||||
|  |                     return Ok(None); | ||||||
|  |                 }; | ||||||
| 
 | 
 | ||||||
|                 let backing_var = if let Some(var) = lhs.backing_var() { |                 let backing_var = if let Some(var) = lhs.backing_var() { | ||||||
|                     &format!("store.{}", var.1) |                     &format!("store.{}", var.1) | ||||||
| @ -576,7 +594,7 @@ impl mir::Statement { | |||||||
|                     } |                     } | ||||||
|                 }; |                 }; | ||||||
| 
 | 
 | ||||||
|                 None |                 Ok(None) | ||||||
|             } |             } | ||||||
|             mir::StmtKind::Import(_) => todo!(), |             mir::StmtKind::Import(_) => todo!(), | ||||||
|             mir::StmtKind::Expression(expression) => expression.codegen(scope, state), |             mir::StmtKind::Expression(expression) => expression.codegen(scope, state), | ||||||
| @ -585,7 +603,11 @@ impl mir::Statement { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl mir::Expression { | impl mir::Expression { | ||||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option<StackValue> { |     fn codegen<'ctx, 'a>( | ||||||
|  |         &self, | ||||||
|  |         scope: &mut Scope<'ctx, 'a>, | ||||||
|  |         state: &State, | ||||||
|  |     ) -> Result<Option<StackValue>, ErrorKind> { | ||||||
|         let location = if let Some(debug) = &scope.debug { |         let location = if let Some(debug) = &scope.debug { | ||||||
|             Some(debug.info.location( |             Some(debug.info.location( | ||||||
|                 &debug.scope, |                 &debug.scope, | ||||||
| @ -634,11 +656,11 @@ impl mir::Expression { | |||||||
|             )), |             )), | ||||||
|             mir::ExprKind::BinOp(binop, lhs_exp, rhs_exp) => { |             mir::ExprKind::BinOp(binop, lhs_exp, rhs_exp) => { | ||||||
|                 let lhs = lhs_exp |                 let lhs = lhs_exp | ||||||
|                     .codegen(scope, state) |                     .codegen(scope, state)? | ||||||
|                     .expect("lhs has no return value") |                     .expect("lhs has no return value") | ||||||
|                     .instr(); |                     .instr(); | ||||||
|                 let rhs = rhs_exp |                 let rhs = rhs_exp | ||||||
|                     .codegen(scope, state) |                     .codegen(scope, state)? | ||||||
|                     .expect("rhs has no return value") |                     .expect("rhs has no return value") | ||||||
|                     .instr(); |                     .instr(); | ||||||
|                 let lhs_type = lhs_exp |                 let lhs_type = lhs_exp | ||||||
| @ -721,11 +743,17 @@ impl mir::Expression { | |||||||
| 
 | 
 | ||||||
|                 let ret_type = ret_type_kind.get_type(scope.type_values, scope.types); |                 let ret_type = ret_type_kind.get_type(scope.type_values, scope.types); | ||||||
| 
 | 
 | ||||||
|                 let params = call |                 let params = try_all( | ||||||
|                     .parameters |                     call.parameters | ||||||
|                     .iter() |                         .iter() | ||||||
|                     .map(|e| e.codegen(scope, state).unwrap()) |                         .map(|e| e.codegen(scope, state)) | ||||||
|                     .collect::<Vec<_>>(); |                         .collect::<Vec<_>>(), | ||||||
|  |                 ) | ||||||
|  |                 .map_err(|e| e.first().cloned().unwrap())? | ||||||
|  |                 .into_iter() | ||||||
|  |                 .map(|v| v.unwrap()) | ||||||
|  |                 .collect::<Vec<_>>(); | ||||||
|  | 
 | ||||||
|                 let param_instrs = params.iter().map(|e| e.instr()).collect(); |                 let param_instrs = params.iter().map(|e| e.instr()).collect(); | ||||||
|                 let callee = scope |                 let callee = scope | ||||||
|                     .functions |                     .functions | ||||||
| @ -782,13 +810,13 @@ impl mir::Expression { | |||||||
|                     None |                     None | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             mir::ExprKind::If(if_expression) => if_expression.codegen(scope, state), |             mir::ExprKind::If(if_expression) => if_expression.codegen(scope, state)?, | ||||||
|             mir::ExprKind::Block(block) => { |             mir::ExprKind::Block(block) => { | ||||||
|                 let inner = scope.function.ir.block("inner"); |                 let inner = scope.function.ir.block("inner"); | ||||||
|                 scope.block.terminate(Term::Br(inner.value())).unwrap(); |                 scope.block.terminate(Term::Br(inner.value())).unwrap(); | ||||||
| 
 | 
 | ||||||
|                 let mut inner_scope = scope.with_block(inner); |                 let mut inner_scope = scope.with_block(inner); | ||||||
|                 let ret = if let Some(ret) = block.codegen(&mut inner_scope, state) { |                 let ret = if let Some(ret) = block.codegen(&mut inner_scope, state)? { | ||||||
|                     Some(ret) |                     Some(ret) | ||||||
|                 } else { |                 } else { | ||||||
|                     None |                     None | ||||||
| @ -800,10 +828,10 @@ impl mir::Expression { | |||||||
|             } |             } | ||||||
|             mir::ExprKind::Indexed(expression, val_t, idx_expr) => { |             mir::ExprKind::Indexed(expression, val_t, idx_expr) => { | ||||||
|                 let StackValue(kind, ty) = expression |                 let StackValue(kind, ty) = expression | ||||||
|                     .codegen(scope, &state.load(false)) |                     .codegen(scope, &state.load(false))? | ||||||
|                     .expect("array returned none!"); |                     .expect("array returned none!"); | ||||||
|                 let idx = idx_expr |                 let idx = idx_expr | ||||||
|                     .codegen(scope, &state.load(true)) |                     .codegen(scope, &state.load(true))? | ||||||
|                     .expect("index returned none!") |                     .expect("index returned none!") | ||||||
|                     .instr(); |                     .instr(); | ||||||
| 
 | 
 | ||||||
| @ -877,10 +905,17 @@ impl mir::Expression { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             mir::ExprKind::Array(expressions) => { |             mir::ExprKind::Array(expressions) => { | ||||||
|                 let stack_value_list = expressions |                 let stack_value_list: Vec<_> = try_all( | ||||||
|                     .iter() |                     expressions | ||||||
|                     .map(|e| e.codegen(scope, state).unwrap()) |                         .iter() | ||||||
|                     .collect::<Vec<_>>(); |                         .map(|e| e.codegen(scope, state)) | ||||||
|  |                         .collect::<Vec<_>>(), | ||||||
|  |                 ) | ||||||
|  |                 .map_err(|e| e.first().cloned().unwrap())? | ||||||
|  |                 .into_iter() | ||||||
|  |                 .map(|v| v.unwrap()) | ||||||
|  |                 .collect(); | ||||||
|  | 
 | ||||||
|                 let instr_list = stack_value_list |                 let instr_list = stack_value_list | ||||||
|                     .iter() |                     .iter() | ||||||
|                     .map(|s| s.instr()) |                     .map(|s| s.instr()) | ||||||
| @ -944,7 +979,7 @@ impl mir::Expression { | |||||||
|                 )) |                 )) | ||||||
|             } |             } | ||||||
|             mir::ExprKind::Accessed(expression, type_kind, field) => { |             mir::ExprKind::Accessed(expression, type_kind, field) => { | ||||||
|                 let struct_val = expression.codegen(scope, &state.load(false)).unwrap(); |                 let struct_val = expression.codegen(scope, &state.load(false))?.unwrap(); | ||||||
| 
 | 
 | ||||||
|                 let TypeKind::CodegenPtr(inner) = &struct_val.1 else { |                 let TypeKind::CodegenPtr(inner) = &struct_val.1 else { | ||||||
|                     panic!("tried accessing non-pointer"); |                     panic!("tried accessing non-pointer"); | ||||||
| @ -996,7 +1031,12 @@ impl mir::Expression { | |||||||
|             } |             } | ||||||
|             mir::ExprKind::Struct(name, items) => { |             mir::ExprKind::Struct(name, items) => { | ||||||
|                 let type_key = CustomTypeKey(name.clone(), scope.module_id); |                 let type_key = CustomTypeKey(name.clone(), scope.module_id); | ||||||
|                 let struct_ty = Type::CustomType(*scope.type_values.get(&type_key)?); |                 let struct_ty = Type::CustomType({ | ||||||
|  |                     let Some(a) = scope.type_values.get(&type_key) else { | ||||||
|  |                         return Ok(None); | ||||||
|  |                     }; | ||||||
|  |                     *a | ||||||
|  |                 }); | ||||||
| 
 | 
 | ||||||
|                 let load_n = format!("{}.load", name); |                 let load_n = format!("{}.load", name); | ||||||
| 
 | 
 | ||||||
| @ -1015,7 +1055,7 @@ impl mir::Expression { | |||||||
|                         .build_named(gep_n, Instr::GetStructElemPtr(struct_ptr, i as u32)) |                         .build_named(gep_n, Instr::GetStructElemPtr(struct_ptr, i as u32)) | ||||||
|                         .unwrap() |                         .unwrap() | ||||||
|                         .maybe_location(&mut scope.block, location); |                         .maybe_location(&mut scope.block, location); | ||||||
|                     if let Some(val) = exp.codegen(scope, state) { |                     if let Some(val) = exp.codegen(scope, state)? { | ||||||
|                         scope |                         scope | ||||||
|                             .block |                             .block | ||||||
|                             .build_named(store_n, Instr::Store(elem_ptr, val.instr())) |                             .build_named(store_n, Instr::Store(elem_ptr, val.instr())) | ||||||
| @ -1101,6 +1141,7 @@ impl mir::Expression { | |||||||
|             } |             } | ||||||
|             mir::ExprKind::CastTo(expression, type_kind) => { |             mir::ExprKind::CastTo(expression, type_kind) => { | ||||||
|                 let val = expression.codegen(scope, state)?; |                 let val = expression.codegen(scope, state)?; | ||||||
|  |                 let Some(val) = val else { return Ok(None) }; | ||||||
| 
 | 
 | ||||||
|                 if val.1 == *type_kind { |                 if val.1 == *type_kind { | ||||||
|                     Some(val) |                     Some(val) | ||||||
| @ -1161,13 +1202,17 @@ impl mir::Expression { | |||||||
|         if let Some(value) = &value { |         if let Some(value) = &value { | ||||||
|             value.instr().maybe_location(&mut scope.block, location); |             value.instr().maybe_location(&mut scope.block, location); | ||||||
|         } |         } | ||||||
|         value |         Ok(value) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl mir::IfExpression { | impl mir::IfExpression { | ||||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, state: &State) -> Option<StackValue> { |     fn codegen<'ctx, 'a>( | ||||||
|         let condition = self.0.codegen(scope, state).unwrap(); |         &self, | ||||||
|  |         scope: &mut Scope<'ctx, 'a>, | ||||||
|  |         state: &State, | ||||||
|  |     ) -> Result<Option<StackValue>, ErrorKind> { | ||||||
|  |         let condition = self.0.codegen(scope, state)?.unwrap(); | ||||||
| 
 | 
 | ||||||
|         // Create blocks
 |         // Create blocks
 | ||||||
|         let mut then_b = scope.function.ir.block("then"); |         let mut then_b = scope.function.ir.block("then"); | ||||||
| @ -1199,7 +1244,7 @@ impl mir::IfExpression { | |||||||
| 
 | 
 | ||||||
|         // Generate then-block content
 |         // Generate then-block content
 | ||||||
|         let mut then_scope = scope.with_block(then_b); |         let mut then_scope = scope.with_block(then_b); | ||||||
|         let then_res = self.1.codegen(&mut then_scope, state); |         let then_res = self.1.codegen(&mut then_scope, state)?; | ||||||
|         then_scope.block.terminate(Term::Br(after_bb)).ok(); |         then_scope.block.terminate(Term::Br(after_bb)).ok(); | ||||||
| 
 | 
 | ||||||
|         let else_res = if let Some(else_expr) = self.2.as_ref() { |         let else_res = if let Some(else_expr) = self.2.as_ref() { | ||||||
| @ -1210,7 +1255,7 @@ impl mir::IfExpression { | |||||||
|                 .terminate(Term::CondBr(condition.instr(), then_bb, else_bb)) |                 .terminate(Term::CondBr(condition.instr(), then_bb, else_bb)) | ||||||
|                 .unwrap(); |                 .unwrap(); | ||||||
| 
 | 
 | ||||||
|             let opt = else_expr.codegen(&mut else_scope, state); |             let opt = else_expr.codegen(&mut else_scope, state)?; | ||||||
| 
 | 
 | ||||||
|             else_scope.block.terminate(Term::Br(after_bb)).ok(); |             else_scope.block.terminate(Term::Br(after_bb)).ok(); | ||||||
| 
 | 
 | ||||||
| @ -1232,7 +1277,7 @@ impl mir::IfExpression { | |||||||
|         scope.swap_block(after_b); |         scope.swap_block(after_b); | ||||||
| 
 | 
 | ||||||
|         if then_res.is_none() && else_res.is_none() { |         if then_res.is_none() && else_res.is_none() { | ||||||
|             None |             Ok(None) | ||||||
|         } else { |         } else { | ||||||
|             let mut incoming = Vec::from(then_res.as_slice()); |             let mut incoming = Vec::from(then_res.as_slice()); | ||||||
|             incoming.extend(else_res.clone()); |             incoming.extend(else_res.clone()); | ||||||
| @ -1260,7 +1305,7 @@ impl mir::IfExpression { | |||||||
|                     (Mutable(_), Mutable(_)) => StackValue(Mutable(instr), lhs_val.1), |                     (Mutable(_), Mutable(_)) => StackValue(Mutable(instr), lhs_val.1), | ||||||
|                 }, |                 }, | ||||||
|             }; |             }; | ||||||
|             Some(value) |             Ok(Some(value)) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -4,6 +4,7 @@ use std::{ | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|  |     codegen, | ||||||
|     lexer::{self, Cursor, FullToken, Position}, |     lexer::{self, Cursor, FullToken, Position}, | ||||||
|     mir::{self, pass, Metadata, SourceModuleId}, |     mir::{self, pass, Metadata, SourceModuleId}, | ||||||
|     token_stream::{self, TokenRange}, |     token_stream::{self, TokenRange}, | ||||||
| @ -30,6 +31,8 @@ pub enum ErrorKind { | |||||||
|     TypeInferenceError(#[source] mir::pass::Error<mir::typecheck::ErrorKind>), |     TypeInferenceError(#[source] mir::pass::Error<mir::typecheck::ErrorKind>), | ||||||
|     #[error("{}{}", label("(Linker) "), .0.kind)] |     #[error("{}{}", label("(Linker) "), .0.kind)] | ||||||
|     LinkerError(#[from] mir::pass::Error<mir::linker::ErrorKind>), |     LinkerError(#[from] mir::pass::Error<mir::linker::ErrorKind>), | ||||||
|  |     #[error("{}{}", label("(Codegen) "), .0)] | ||||||
|  |     CodegenError(#[from] codegen::ErrorKind), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl ErrorKind { | impl ErrorKind { | ||||||
| @ -50,6 +53,9 @@ impl ErrorKind { | |||||||
|             ErrorKind::TypeCheckError(error) => error.metadata, |             ErrorKind::TypeCheckError(error) => error.metadata, | ||||||
|             ErrorKind::TypeInferenceError(error) => error.metadata, |             ErrorKind::TypeInferenceError(error) => error.metadata, | ||||||
|             ErrorKind::LinkerError(error) => error.metadata, |             ErrorKind::LinkerError(error) => error.metadata, | ||||||
|  |             ErrorKind::CodegenError(error) => match error { | ||||||
|  |                 codegen::ErrorKind::Null => Default::default(), | ||||||
|  |             }, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -155,7 +161,7 @@ impl ReidError { | |||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     pub fn from_kind<U>(errors: Vec<ErrorKind>, map: ErrorModules) -> ReidError { |     pub fn from_kind(errors: Vec<ErrorKind>, map: ErrorModules) -> ReidError { | ||||||
|         ReidError { map, errors } |         ReidError { map, errors } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -137,7 +137,7 @@ pub fn perform_all_passes<'map>( | |||||||
|     dbg!(&state); |     dbg!(&state); | ||||||
| 
 | 
 | ||||||
|     if !state.errors.is_empty() { |     if !state.errors.is_empty() { | ||||||
|         return Err(ReidError::from_kind::<()>( |         return Err(ReidError::from_kind( | ||||||
|             state.errors.iter().map(|e| e.clone().into()).collect(), |             state.errors.iter().map(|e| e.clone().into()).collect(), | ||||||
|             module_map.clone(), |             module_map.clone(), | ||||||
|         )); |         )); | ||||||
| @ -157,7 +157,7 @@ pub fn perform_all_passes<'map>( | |||||||
|     dbg!(&state); |     dbg!(&state); | ||||||
| 
 | 
 | ||||||
|     if !state.errors.is_empty() { |     if !state.errors.is_empty() { | ||||||
|         return Err(ReidError::from_kind::<()>( |         return Err(ReidError::from_kind( | ||||||
|             state |             state | ||||||
|                 .errors |                 .errors | ||||||
|                 .iter() |                 .iter() | ||||||
| @ -177,7 +177,7 @@ pub fn perform_all_passes<'map>( | |||||||
|     dbg!(&state); |     dbg!(&state); | ||||||
| 
 | 
 | ||||||
|     if !state.errors.is_empty() { |     if !state.errors.is_empty() { | ||||||
|         return Err(ReidError::from_kind::<()>( |         return Err(ReidError::from_kind( | ||||||
|             state |             state | ||||||
|                 .errors |                 .errors | ||||||
|                 .iter() |                 .iter() | ||||||
| @ -214,7 +214,10 @@ pub fn compile_and_pass<'map>( | |||||||
|     println!("{}", &mir_context); |     println!("{}", &mir_context); | ||||||
| 
 | 
 | ||||||
|     let mut context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION"))); |     let mut context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION"))); | ||||||
|     let codegen_modules = mir_context.codegen(&mut context); |     let codegen_modules = match mir_context.codegen(&mut context) { | ||||||
|  |         Ok(modules) => modules, | ||||||
|  |         Err(e) => Err(ReidError::from_kind(vec![e.into()], module_map.clone()))?, | ||||||
|  |     }; | ||||||
| 
 | 
 | ||||||
|     #[cfg(debug_assertions)] |     #[cfg(debug_assertions)] | ||||||
|     println!("{}", &codegen_modules.context); |     println!("{}", &codegen_modules.context); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user