Refactor stuff into codegen-module
This commit is contained in:
		
							parent
							
								
									d79d396814
								
							
						
					
					
						commit
						6ee43d4012
					
				| @ -7,6 +7,6 @@ edition = "2024" | |||||||
| 
 | 
 | ||||||
| [dependencies] | [dependencies] | ||||||
| ## LLVM Bindings | ## LLVM Bindings | ||||||
| llvm-sys = {version ="201.0.1", features=["force-static"] } | llvm-sys = {version ="201.0.1", features=["prefer-dynamic"] } | ||||||
| ## Make it easier to generate errors | ## Make it easier to generate errors | ||||||
| thiserror = "1.0.44" | thiserror = "1.0.44" | ||||||
| @ -1,10 +1,12 @@ | |||||||
| use reid_lib::{builder::InstructionValue, Instr}; | use reid_lib::{builder::InstructionValue, Instr}; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     codegen::{ErrorKind, Scope, StackValue, StackValueKind}, |     codegen::{ErrorKind, StackValueKind}, | ||||||
|     mir::{BinopDefinition, FunctionDefinition, TypeKind}, |     mir::{BinopDefinition, FunctionDefinition, TypeKind}, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | use super::scope::{Scope, StackValue}; | ||||||
|  | 
 | ||||||
| pub fn form_intrinsics() -> Vec<FunctionDefinition> { | pub fn form_intrinsics() -> Vec<FunctionDefinition> { | ||||||
|     let intrinsics = Vec::new(); |     let intrinsics = Vec::new(); | ||||||
| 
 | 
 | ||||||
| @ -1,31 +1,33 @@ | |||||||
| use std::{cell::RefCell, collections::HashMap, mem, rc::Rc}; | use std::{cell::RefCell, collections::HashMap, rc::Rc}; | ||||||
| 
 | 
 | ||||||
|  | use allocator::{Allocator, AllocatorScope}; | ||||||
|  | use intrinsics::*; | ||||||
| use reid_lib::{ | use reid_lib::{ | ||||||
|     builder::{InstructionValue, TypeValue}, |  | ||||||
|     compile::CompiledModule, |     compile::CompiledModule, | ||||||
|     debug_information::{ |     debug_information::{ | ||||||
|         DebugArrayType, DebugBasicType, DebugFieldType, DebugFileData, DebugInformation, |         DebugFileData, DebugLocalVariable, DebugLocation, DebugMetadata, DebugRecordKind, | ||||||
|         DebugLocalVariable, DebugLocation, DebugMetadata, DebugPointerType, DebugPosition, |         DebugSubprogramData, DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, | ||||||
|         DebugProgramValue, DebugRecordKind, DebugStructType, DebugSubprogramData, |         DwarfFlags, InstructionDebugRecordData, | ||||||
|         DebugSubprogramOptionals, DebugSubprogramType, DebugTypeData, DebugTypeValue, |  | ||||||
|         DwarfEncoding, DwarfFlags, InstructionDebugRecordData, |  | ||||||
|     }, |     }, | ||||||
|     Block, CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, |     CmpPredicate, ConstValue, Context, CustomTypeKind, Function, FunctionFlags, Instr, Module, | ||||||
|     Module, NamedStruct, TerminatorKind as Term, Type, |     NamedStruct, TerminatorKind as Term, Type, | ||||||
| }; | }; | ||||||
|  | use scope::*; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     allocator::{Allocator, AllocatorScope}, |  | ||||||
|     intrinsics::IntrinsicFunction, |  | ||||||
|     lexer::{FullToken, Position}, |  | ||||||
|     mir::{ |     mir::{ | ||||||
|         self, implement::TypeCategory, pass::ScopeBinopKey, CustomTypeKey, FunctionDefinitionKind, |         self, implement::TypeCategory, pass::ScopeBinopKey, CustomTypeKey, FunctionDefinitionKind, | ||||||
|         Metadata, NamedVariableRef, SourceModuleId, StructField, StructType, TypeDefinition, |         NamedVariableRef, SourceModuleId, StructField, StructType, TypeDefinitionKind, TypeKind, | ||||||
|         TypeDefinitionKind, TypeKind, VagueLiteral, WhileStatement, |         WhileStatement, | ||||||
|     }, |     }, | ||||||
|     util::try_all, |     util::try_all, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | mod allocator; | ||||||
|  | pub mod intrinsics; | ||||||
|  | pub(super) mod scope; | ||||||
|  | pub(super) mod util; | ||||||
|  | 
 | ||||||
| #[derive(thiserror::Error, Debug, Clone, PartialEq, PartialOrd)] | #[derive(thiserror::Error, Debug, Clone, PartialEq, PartialOrd)] | ||||||
| pub enum ErrorKind { | pub enum ErrorKind { | ||||||
|     #[error("NULL error, should never occur!")] |     #[error("NULL error, should never occur!")] | ||||||
| @ -73,160 +75,6 @@ impl<'ctx> std::fmt::Debug for ModuleCodegen<'ctx> { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct Scope<'ctx, 'scope> { |  | ||||||
|     context: &'ctx Context, |  | ||||||
|     modules: &'scope HashMap<SourceModuleId, ModuleCodegen<'ctx>>, |  | ||||||
|     tokens: &'ctx Vec<FullToken>, |  | ||||||
|     module: &'ctx Module<'ctx>, |  | ||||||
|     module_id: SourceModuleId, |  | ||||||
|     function: &'ctx Function<'ctx>, |  | ||||||
|     pub(super) block: Block<'ctx>, |  | ||||||
|     types: &'scope HashMap<TypeValue, TypeDefinition>, |  | ||||||
|     type_values: &'scope HashMap<CustomTypeKey, TypeValue>, |  | ||||||
|     functions: &'scope HashMap<String, Function<'ctx>>, |  | ||||||
|     binops: &'scope HashMap<ScopeBinopKey, StackBinopDefinition<'ctx>>, |  | ||||||
|     stack_values: HashMap<String, StackValue>, |  | ||||||
|     debug: Option<Debug<'ctx>>, |  | ||||||
|     allocator: Rc<RefCell<Allocator>>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl<'ctx, 'a> Scope<'ctx, 'a> { |  | ||||||
|     fn with_block(&self, block: Block<'ctx>) -> Scope<'ctx, 'a> { |  | ||||||
|         Scope { |  | ||||||
|             block, |  | ||||||
|             modules: self.modules, |  | ||||||
|             tokens: self.tokens, |  | ||||||
|             function: self.function, |  | ||||||
|             context: self.context, |  | ||||||
|             module: self.module, |  | ||||||
|             module_id: self.module_id, |  | ||||||
|             functions: self.functions, |  | ||||||
|             types: self.types, |  | ||||||
|             type_values: self.type_values, |  | ||||||
|             stack_values: self.stack_values.clone(), |  | ||||||
|             debug: self.debug.clone(), |  | ||||||
|             allocator: self.allocator.clone(), |  | ||||||
|             binops: self.binops, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /// Takes the block out from this scope, swaps the given block in it's place
 |  | ||||||
|     /// and returns the old block.
 |  | ||||||
|     fn swap_block(&mut self, block: Block<'ctx>) -> Block<'ctx> { |  | ||||||
|         let mut old_block = block; |  | ||||||
|         mem::swap(&mut self.block, &mut old_block); |  | ||||||
|         old_block |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn get_typedef(&self, key: &CustomTypeKey) -> Option<&TypeDefinition> { |  | ||||||
|         self.type_values.get(key).and_then(|v| self.types.get(v)) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn allocate(&self, name: &String, ty: &TypeKind) -> Option<InstructionValue> { |  | ||||||
|         self.allocator.borrow_mut().allocate(name, ty) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, Clone)] |  | ||||||
| pub struct Debug<'ctx> { |  | ||||||
|     info: &'ctx DebugInformation, |  | ||||||
|     scope: DebugProgramValue, |  | ||||||
|     types: &'ctx HashMap<TypeKind, DebugTypeValue>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, Clone, PartialEq, Eq)] |  | ||||||
| pub struct StackValue(pub(super) StackValueKind, pub(super) TypeKind); |  | ||||||
| 
 |  | ||||||
| impl StackValue { |  | ||||||
|     fn instr(&self) -> InstructionValue { |  | ||||||
|         self.0.instr() |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] |  | ||||||
| pub enum StackValueKind { |  | ||||||
|     Immutable(InstructionValue), |  | ||||||
|     Mutable(InstructionValue), |  | ||||||
|     Literal(InstructionValue), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl StackValueKind { |  | ||||||
|     fn mutable(mutable: bool, instr: InstructionValue) -> StackValueKind { |  | ||||||
|         match mutable { |  | ||||||
|             true => StackValueKind::Mutable(instr), |  | ||||||
|             false => StackValueKind::Immutable(instr), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn instr(&self) -> InstructionValue { |  | ||||||
|         match &self { |  | ||||||
|             StackValueKind::Immutable(val) => *val, |  | ||||||
|             StackValueKind::Mutable(val) => *val, |  | ||||||
|             StackValueKind::Literal(val) => *val, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn derive(&self, instr: InstructionValue) -> StackValueKind { |  | ||||||
|         match &self { |  | ||||||
|             StackValueKind::Immutable(_) => StackValueKind::Immutable(instr), |  | ||||||
|             StackValueKind::Mutable(_) => StackValueKind::Mutable(instr), |  | ||||||
|             StackValueKind::Literal(_) => StackValueKind::Literal(instr), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     #[allow(dead_code)] |  | ||||||
|     fn map<F>(&self, lambda: F) -> StackValueKind |  | ||||||
|     where |  | ||||||
|         F: FnOnce(InstructionValue) -> InstructionValue, |  | ||||||
|     { |  | ||||||
|         self.derive(lambda(self.instr())) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub struct StackBinopDefinition<'ctx> { |  | ||||||
|     parameters: ((String, TypeKind), (String, TypeKind)), |  | ||||||
|     return_ty: TypeKind, |  | ||||||
|     kind: StackBinopFunctionKind<'ctx>, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub enum StackBinopFunctionKind<'ctx> { |  | ||||||
|     UserGenerated(Function<'ctx>), |  | ||||||
|     Intrinsic(&'ctx Box<dyn IntrinsicFunction>), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl<'ctx> StackBinopDefinition<'ctx> { |  | ||||||
|     fn codegen<'a>( |  | ||||||
|         &self, |  | ||||||
|         lhs: &StackValue, |  | ||||||
|         rhs: &StackValue, |  | ||||||
|         scope: &mut Scope<'ctx, 'a>, |  | ||||||
|     ) -> Result<StackValue, ErrorKind> { |  | ||||||
|         let (lhs, rhs) = if lhs.1 == self.parameters.0 .1 && rhs.1 == self.parameters.1 .1 { |  | ||||||
|             (lhs, rhs) |  | ||||||
|         } else { |  | ||||||
|             (rhs, lhs) |  | ||||||
|         }; |  | ||||||
|         match &self.kind { |  | ||||||
|             StackBinopFunctionKind::UserGenerated(ir) => { |  | ||||||
|                 let instr = scope |  | ||||||
|                     .block |  | ||||||
|                     .build(Instr::FunctionCall( |  | ||||||
|                         ir.value(), |  | ||||||
|                         vec![lhs.instr(), rhs.instr()], |  | ||||||
|                     )) |  | ||||||
|                     .unwrap(); |  | ||||||
|                 Ok(StackValue( |  | ||||||
|                     StackValueKind::Immutable(instr), |  | ||||||
|                     self.return_ty.clone(), |  | ||||||
|                 )) |  | ||||||
|             } |  | ||||||
|             StackBinopFunctionKind::Intrinsic(fun) => { |  | ||||||
|                 fun.codegen(scope, &[lhs.instr(), rhs.instr()]) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] | #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] | ||||||
| struct State { | struct State { | ||||||
|     should_load: bool, |     should_load: bool, | ||||||
| @ -1567,262 +1415,3 @@ impl mir::IfExpression { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| impl mir::CmpOperator { |  | ||||||
|     fn predicate(&self) -> CmpPredicate { |  | ||||||
|         match self { |  | ||||||
|             mir::CmpOperator::LT => CmpPredicate::LT, |  | ||||||
|             mir::CmpOperator::GT => CmpPredicate::GT, |  | ||||||
|             mir::CmpOperator::LE => CmpPredicate::LE, |  | ||||||
|             mir::CmpOperator::GE => CmpPredicate::GE, |  | ||||||
|             mir::CmpOperator::EQ => CmpPredicate::EQ, |  | ||||||
|             mir::CmpOperator::NE => CmpPredicate::NE, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl mir::Literal { |  | ||||||
|     fn as_const(&self, block: &mut Block) -> InstructionValue { |  | ||||||
|         block |  | ||||||
|             .build_named(format!("{}", self), self.as_const_kind()) |  | ||||||
|             .unwrap() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn as_const_kind(&self) -> Instr { |  | ||||||
|         Instr::Constant(match self.clone() { |  | ||||||
|             mir::Literal::I8(val) => ConstValue::I8(val), |  | ||||||
|             mir::Literal::I16(val) => ConstValue::I16(val), |  | ||||||
|             mir::Literal::I32(val) => ConstValue::I32(val), |  | ||||||
|             mir::Literal::I64(val) => ConstValue::I64(val), |  | ||||||
|             mir::Literal::I128(val) => ConstValue::I128(val), |  | ||||||
|             mir::Literal::U8(val) => ConstValue::U8(val), |  | ||||||
|             mir::Literal::U16(val) => ConstValue::U16(val), |  | ||||||
|             mir::Literal::U32(val) => ConstValue::U32(val), |  | ||||||
|             mir::Literal::U64(val) => ConstValue::U64(val), |  | ||||||
|             mir::Literal::U128(val) => ConstValue::U128(val), |  | ||||||
|             mir::Literal::Bool(val) => ConstValue::Bool(val), |  | ||||||
|             mir::Literal::String(val) => ConstValue::Str(val.clone()), |  | ||||||
|             mir::Literal::Vague(VagueLiteral::Number(val)) => ConstValue::I32(val as i32), |  | ||||||
|             mir::Literal::Vague(VagueLiteral::Decimal(val)) => ConstValue::F32(val as f32), |  | ||||||
|             mir::Literal::F16(val) => ConstValue::F16(val), |  | ||||||
|             mir::Literal::F32B(val) => ConstValue::F32B(val), |  | ||||||
|             mir::Literal::F32(val) => ConstValue::F32(val), |  | ||||||
|             mir::Literal::F64(val) => ConstValue::F64(val), |  | ||||||
|             mir::Literal::F80(val) => ConstValue::F80(val), |  | ||||||
|             mir::Literal::F128(val) => ConstValue::F128(val), |  | ||||||
|             mir::Literal::F128PPC(val) => ConstValue::F128PPC(val), |  | ||||||
|             mir::Literal::Char(c) => ConstValue::U8(c as u8), |  | ||||||
|         }) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl TypeKind { |  | ||||||
|     pub(super) fn get_type(&self, type_vals: &HashMap<CustomTypeKey, TypeValue>) -> Type { |  | ||||||
|         match &self { |  | ||||||
|             TypeKind::I8 => Type::I8, |  | ||||||
|             TypeKind::I16 => Type::I16, |  | ||||||
|             TypeKind::I32 => Type::I32, |  | ||||||
|             TypeKind::I64 => Type::I64, |  | ||||||
|             TypeKind::I128 => Type::I128, |  | ||||||
|             TypeKind::U8 => Type::U8, |  | ||||||
|             TypeKind::U16 => Type::U16, |  | ||||||
|             TypeKind::U32 => Type::U32, |  | ||||||
|             TypeKind::U64 => Type::U64, |  | ||||||
|             TypeKind::U128 => Type::U128, |  | ||||||
|             TypeKind::Bool => Type::Bool, |  | ||||||
|             TypeKind::F16 => Type::F16, |  | ||||||
|             TypeKind::F32B => Type::F32B, |  | ||||||
|             TypeKind::F32 => Type::F32, |  | ||||||
|             TypeKind::F64 => Type::F64, |  | ||||||
|             TypeKind::F128 => Type::F128, |  | ||||||
|             TypeKind::F80 => Type::F80, |  | ||||||
|             TypeKind::F128PPC => Type::F128PPC, |  | ||||||
|             TypeKind::Char => Type::U8, |  | ||||||
|             TypeKind::Array(elem_t, len) => Type::Array(Box::new(elem_t.get_type(type_vals)), *len), |  | ||||||
|             TypeKind::Void => Type::Void, |  | ||||||
|             TypeKind::Vague(_) => panic!("Tried to compile a vague type!"), |  | ||||||
|             TypeKind::CustomType(n) => { |  | ||||||
|                 let type_val = type_vals.get(n).unwrap().clone(); |  | ||||||
|                 Type::CustomType(type_val) |  | ||||||
|             } |  | ||||||
|             TypeKind::UserPtr(type_kind) => Type::Ptr(Box::new(type_kind.get_type(type_vals))), |  | ||||||
|             TypeKind::CodegenPtr(type_kind) => Type::Ptr(Box::new(type_kind.get_type(type_vals))), |  | ||||||
|             TypeKind::Borrow(type_kind, _) => Type::Ptr(Box::new(type_kind.get_type(type_vals))), |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl TypeKind { |  | ||||||
|     fn get_debug_type(&self, debug: &Debug, scope: &Scope) -> DebugTypeValue { |  | ||||||
|         self.get_debug_type_hard( |  | ||||||
|             debug.scope, |  | ||||||
|             debug.info, |  | ||||||
|             debug.types, |  | ||||||
|             scope.type_values, |  | ||||||
|             scope.types, |  | ||||||
|             scope.module_id, |  | ||||||
|             scope.tokens, |  | ||||||
|             scope.modules, |  | ||||||
|         ) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn get_debug_type_hard( |  | ||||||
|         &self, |  | ||||||
|         scope: DebugProgramValue, |  | ||||||
|         debug_info: &DebugInformation, |  | ||||||
|         debug_types: &HashMap<TypeKind, DebugTypeValue>, |  | ||||||
|         type_values: &HashMap<CustomTypeKey, TypeValue>, |  | ||||||
|         types: &HashMap<TypeValue, TypeDefinition>, |  | ||||||
|         local_mod: SourceModuleId, |  | ||||||
|         tokens: &Vec<FullToken>, |  | ||||||
|         modules: &HashMap<SourceModuleId, ModuleCodegen>, |  | ||||||
|     ) -> DebugTypeValue { |  | ||||||
|         if let Some(ty) = debug_types.get(self) { |  | ||||||
|             return *ty; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         let name = format!("{}", self); |  | ||||||
| 
 |  | ||||||
|         let data = match self { |  | ||||||
|             TypeKind::CodegenPtr(inner) | TypeKind::UserPtr(inner) | TypeKind::Borrow(inner, _) => { |  | ||||||
|                 DebugTypeData::Pointer(DebugPointerType { |  | ||||||
|                     name, |  | ||||||
|                     pointee: inner.get_debug_type_hard( |  | ||||||
|                         scope, |  | ||||||
|                         debug_info, |  | ||||||
|                         debug_types, |  | ||||||
|                         type_values, |  | ||||||
|                         types, |  | ||||||
|                         local_mod, |  | ||||||
|                         tokens, |  | ||||||
|                         modules, |  | ||||||
|                     ), |  | ||||||
|                     size_bits: self.size_of(), |  | ||||||
|                 }) |  | ||||||
|             } |  | ||||||
|             TypeKind::Array(elem_ty, len) => { |  | ||||||
|                 let elem_ty = elem_ty.clone().get_debug_type_hard( |  | ||||||
|                     scope, |  | ||||||
|                     debug_info, |  | ||||||
|                     debug_types, |  | ||||||
|                     type_values, |  | ||||||
|                     types, |  | ||||||
|                     local_mod, |  | ||||||
|                     tokens, |  | ||||||
|                     modules, |  | ||||||
|                 ); |  | ||||||
|                 DebugTypeData::Array(DebugArrayType { |  | ||||||
|                     size_bits: self.size_of(), |  | ||||||
|                     align_bits: self.alignment(), |  | ||||||
|                     element_type: elem_ty, |  | ||||||
|                     length: *len, |  | ||||||
|                 }) |  | ||||||
|             } |  | ||||||
|             TypeKind::CustomType(key) => { |  | ||||||
|                 let typedef = types.get(type_values.get(key).unwrap()).unwrap(); |  | ||||||
|                 match &typedef.kind { |  | ||||||
|                     TypeDefinitionKind::Struct(struct_type) => { |  | ||||||
|                         let mut fields = Vec::new(); |  | ||||||
|                         let mut size_bits = 0; |  | ||||||
| 
 |  | ||||||
|                         for field in &struct_type.0 { |  | ||||||
|                             let location = if typedef.source_module != local_mod { |  | ||||||
|                                 None |  | ||||||
|                             } else { |  | ||||||
|                                 field.2.into_debug(&tokens, scope) |  | ||||||
|                             }; |  | ||||||
|                             fields.push(DebugFieldType { |  | ||||||
|                                 name: field.0.clone(), |  | ||||||
|                                 scope, |  | ||||||
|                                 pos: location.map(|l| l.pos), |  | ||||||
|                                 size_bits: field.1.size_of(), |  | ||||||
|                                 offset: size_bits, |  | ||||||
|                                 flags: DwarfFlags, |  | ||||||
|                                 ty: field.1.get_debug_type_hard( |  | ||||||
|                                     scope, |  | ||||||
|                                     debug_info, |  | ||||||
|                                     debug_types, |  | ||||||
|                                     type_values, |  | ||||||
|                                     types, |  | ||||||
|                                     local_mod, |  | ||||||
|                                     tokens, |  | ||||||
|                                     modules, |  | ||||||
|                                 ), |  | ||||||
|                             }); |  | ||||||
|                             size_bits += field.1.size_of(); |  | ||||||
|                         } |  | ||||||
|                         { |  | ||||||
|                             let location = if typedef.source_module != local_mod { |  | ||||||
|                                 None |  | ||||||
|                             } else { |  | ||||||
|                                 typedef.meta.into_debug(&tokens, scope) |  | ||||||
|                             }; |  | ||||||
|                             DebugTypeData::Struct(DebugStructType { |  | ||||||
|                                 name: key.0.clone(), |  | ||||||
|                                 scope, |  | ||||||
|                                 pos: location.map(|l| l.pos), |  | ||||||
|                                 size_bits, |  | ||||||
|                                 flags: DwarfFlags, |  | ||||||
|                                 fields, |  | ||||||
|                             }) |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             _ => DebugTypeData::Basic(DebugBasicType { |  | ||||||
|                 name, |  | ||||||
|                 size_bits: self.size_of(), |  | ||||||
|                 encoding: match self { |  | ||||||
|                     TypeKind::Bool => DwarfEncoding::Boolean, |  | ||||||
|                     TypeKind::I8 => DwarfEncoding::SignedChar, |  | ||||||
|                     TypeKind::U8 => DwarfEncoding::UnsignedChar, |  | ||||||
|                     TypeKind::I16 | TypeKind::I32 | TypeKind::I64 | TypeKind::I128 => { |  | ||||||
|                         DwarfEncoding::Signed |  | ||||||
|                     } |  | ||||||
|                     TypeKind::U16 | TypeKind::U32 | TypeKind::U64 | TypeKind::U128 => { |  | ||||||
|                         DwarfEncoding::Unsigned |  | ||||||
|                     } |  | ||||||
|                     TypeKind::F16 |  | ||||||
|                     | TypeKind::F32 |  | ||||||
|                     | TypeKind::F32B |  | ||||||
|                     | TypeKind::F64 |  | ||||||
|                     | TypeKind::F80 |  | ||||||
|                     | TypeKind::F128 |  | ||||||
|                     | TypeKind::F128PPC => DwarfEncoding::Float, |  | ||||||
|                     TypeKind::Void => DwarfEncoding::Address, |  | ||||||
|                     TypeKind::Char => DwarfEncoding::UnsignedChar, |  | ||||||
|                     TypeKind::Array(_, _) => DwarfEncoding::Address, |  | ||||||
|                     TypeKind::CustomType(_) => DwarfEncoding::Address, |  | ||||||
|                     _ => panic!("tried fetching debug-type for non-supported type!"), |  | ||||||
|                 }, |  | ||||||
|                 flags: DwarfFlags, |  | ||||||
|             }), |  | ||||||
|         }; |  | ||||||
|         debug_info.debug_type(data) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Metadata { |  | ||||||
|     pub fn into_debug( |  | ||||||
|         &self, |  | ||||||
|         tokens: &Vec<FullToken>, |  | ||||||
|         scope: DebugProgramValue, |  | ||||||
|     ) -> Option<DebugLocation> { |  | ||||||
|         if let Some((start, _)) = self.into_positions(tokens) { |  | ||||||
|             Some(start.debug(scope)) |  | ||||||
|         } else { |  | ||||||
|             None |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl Position { |  | ||||||
|     fn debug(self, scope: DebugProgramValue) -> DebugLocation { |  | ||||||
|         DebugLocation { |  | ||||||
|             pos: DebugPosition { |  | ||||||
|                 line: self.1, |  | ||||||
|                 column: self.0, |  | ||||||
|             }, |  | ||||||
|             scope, |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										168
									
								
								reid/src/codegen/scope.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								reid/src/codegen/scope.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,168 @@ | |||||||
|  | use std::{cell::RefCell, collections::HashMap, mem, rc::Rc}; | ||||||
|  | 
 | ||||||
|  | use reid_lib::{ | ||||||
|  |     builder::{InstructionValue, TypeValue}, | ||||||
|  |     debug_information::{DebugInformation, DebugProgramValue, DebugTypeValue}, | ||||||
|  |     Block, Context, Function, Instr, Module, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | use crate::{ | ||||||
|  |     lexer::FullToken, | ||||||
|  |     mir::{pass::ScopeBinopKey, CustomTypeKey, SourceModuleId, TypeDefinition, TypeKind}, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | use super::{allocator::Allocator, ErrorKind, IntrinsicFunction, ModuleCodegen}; | ||||||
|  | 
 | ||||||
|  | pub struct Scope<'ctx, 'scope> { | ||||||
|  |     pub(super) context: &'ctx Context, | ||||||
|  |     pub(super) modules: &'scope HashMap<SourceModuleId, ModuleCodegen<'ctx>>, | ||||||
|  |     pub(super) tokens: &'ctx Vec<FullToken>, | ||||||
|  |     pub(super) module: &'ctx Module<'ctx>, | ||||||
|  |     pub(super) module_id: SourceModuleId, | ||||||
|  |     pub(super) function: &'ctx Function<'ctx>, | ||||||
|  |     pub(super) block: Block<'ctx>, | ||||||
|  |     pub(super) types: &'scope HashMap<TypeValue, TypeDefinition>, | ||||||
|  |     pub(super) type_values: &'scope HashMap<CustomTypeKey, TypeValue>, | ||||||
|  |     pub(super) functions: &'scope HashMap<String, Function<'ctx>>, | ||||||
|  |     pub(super) binops: &'scope HashMap<ScopeBinopKey, StackBinopDefinition<'ctx>>, | ||||||
|  |     pub(super) stack_values: HashMap<String, StackValue>, | ||||||
|  |     pub(super) debug: Option<Debug<'ctx>>, | ||||||
|  |     pub(super) allocator: Rc<RefCell<Allocator>>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'ctx, 'a> Scope<'ctx, 'a> { | ||||||
|  |     pub fn with_block(&self, block: Block<'ctx>) -> Scope<'ctx, 'a> { | ||||||
|  |         Scope { | ||||||
|  |             block, | ||||||
|  |             modules: self.modules, | ||||||
|  |             tokens: self.tokens, | ||||||
|  |             function: self.function, | ||||||
|  |             context: self.context, | ||||||
|  |             module: self.module, | ||||||
|  |             module_id: self.module_id, | ||||||
|  |             functions: self.functions, | ||||||
|  |             types: self.types, | ||||||
|  |             type_values: self.type_values, | ||||||
|  |             stack_values: self.stack_values.clone(), | ||||||
|  |             debug: self.debug.clone(), | ||||||
|  |             allocator: self.allocator.clone(), | ||||||
|  |             binops: self.binops, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// Takes the block out from this scope, swaps the given block in it's place
 | ||||||
|  |     /// and returns the old block.
 | ||||||
|  |     pub fn swap_block(&mut self, block: Block<'ctx>) -> Block<'ctx> { | ||||||
|  |         let mut old_block = block; | ||||||
|  |         mem::swap(&mut self.block, &mut old_block); | ||||||
|  |         old_block | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn get_typedef(&self, key: &CustomTypeKey) -> Option<&TypeDefinition> { | ||||||
|  |         self.type_values.get(key).and_then(|v| self.types.get(v)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn allocate(&self, name: &String, ty: &TypeKind) -> Option<InstructionValue> { | ||||||
|  |         self.allocator.borrow_mut().allocate(name, ty) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone)] | ||||||
|  | pub struct Debug<'ctx> { | ||||||
|  |     pub(super) info: &'ctx DebugInformation, | ||||||
|  |     pub(super) scope: DebugProgramValue, | ||||||
|  |     pub(super) types: &'ctx HashMap<TypeKind, DebugTypeValue>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, PartialEq, Eq)] | ||||||
|  | pub struct StackValue(pub(super) StackValueKind, pub(super) TypeKind); | ||||||
|  | 
 | ||||||
|  | impl StackValue { | ||||||
|  |     pub fn instr(&self) -> InstructionValue { | ||||||
|  |         self.0.instr() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||||||
|  | pub enum StackValueKind { | ||||||
|  |     Immutable(InstructionValue), | ||||||
|  |     Mutable(InstructionValue), | ||||||
|  |     Literal(InstructionValue), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl StackValueKind { | ||||||
|  |     pub fn mutable(mutable: bool, instr: InstructionValue) -> StackValueKind { | ||||||
|  |         match mutable { | ||||||
|  |             true => StackValueKind::Mutable(instr), | ||||||
|  |             false => StackValueKind::Immutable(instr), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn instr(&self) -> InstructionValue { | ||||||
|  |         match &self { | ||||||
|  |             StackValueKind::Immutable(val) => *val, | ||||||
|  |             StackValueKind::Mutable(val) => *val, | ||||||
|  |             StackValueKind::Literal(val) => *val, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn derive(&self, instr: InstructionValue) -> StackValueKind { | ||||||
|  |         match &self { | ||||||
|  |             StackValueKind::Immutable(_) => StackValueKind::Immutable(instr), | ||||||
|  |             StackValueKind::Mutable(_) => StackValueKind::Mutable(instr), | ||||||
|  |             StackValueKind::Literal(_) => StackValueKind::Literal(instr), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[allow(dead_code)] | ||||||
|  |     fn map<F>(&self, lambda: F) -> StackValueKind | ||||||
|  |     where | ||||||
|  |         F: FnOnce(InstructionValue) -> InstructionValue, | ||||||
|  |     { | ||||||
|  |         self.derive(lambda(self.instr())) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub struct StackBinopDefinition<'ctx> { | ||||||
|  |     pub(super) parameters: ((String, TypeKind), (String, TypeKind)), | ||||||
|  |     pub(super) return_ty: TypeKind, | ||||||
|  |     pub(super) kind: StackBinopFunctionKind<'ctx>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub enum StackBinopFunctionKind<'ctx> { | ||||||
|  |     UserGenerated(Function<'ctx>), | ||||||
|  |     Intrinsic(&'ctx Box<dyn IntrinsicFunction>), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'ctx> StackBinopDefinition<'ctx> { | ||||||
|  |     pub fn codegen<'a>( | ||||||
|  |         &self, | ||||||
|  |         lhs: &StackValue, | ||||||
|  |         rhs: &StackValue, | ||||||
|  |         scope: &mut Scope<'ctx, 'a>, | ||||||
|  |     ) -> Result<StackValue, ErrorKind> { | ||||||
|  |         let (lhs, rhs) = if lhs.1 == self.parameters.0 .1 && rhs.1 == self.parameters.1 .1 { | ||||||
|  |             (lhs, rhs) | ||||||
|  |         } else { | ||||||
|  |             (rhs, lhs) | ||||||
|  |         }; | ||||||
|  |         match &self.kind { | ||||||
|  |             StackBinopFunctionKind::UserGenerated(ir) => { | ||||||
|  |                 let instr = scope | ||||||
|  |                     .block | ||||||
|  |                     .build(Instr::FunctionCall( | ||||||
|  |                         ir.value(), | ||||||
|  |                         vec![lhs.instr(), rhs.instr()], | ||||||
|  |                     )) | ||||||
|  |                     .unwrap(); | ||||||
|  |                 Ok(StackValue( | ||||||
|  |                     StackValueKind::Immutable(instr), | ||||||
|  |                     self.return_ty.clone(), | ||||||
|  |                 )) | ||||||
|  |             } | ||||||
|  |             StackBinopFunctionKind::Intrinsic(fun) => { | ||||||
|  |                 fun.codegen(scope, &[lhs.instr(), rhs.instr()]) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										284
									
								
								reid/src/codegen/util.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										284
									
								
								reid/src/codegen/util.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,284 @@ | |||||||
|  | use std::collections::HashMap; | ||||||
|  | 
 | ||||||
|  | use reid_lib::{ | ||||||
|  |     builder::{InstructionValue, TypeValue}, | ||||||
|  |     debug_information::{ | ||||||
|  |         DebugArrayType, DebugBasicType, DebugFieldType, DebugInformation, DebugLocation, | ||||||
|  |         DebugPointerType, DebugPosition, DebugProgramValue, DebugStructType, DebugTypeData, | ||||||
|  |         DebugTypeValue, DwarfEncoding, DwarfFlags, | ||||||
|  |     }, | ||||||
|  |     Block, CmpPredicate, ConstValue, Instr, Type, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | use crate::{ | ||||||
|  |     lexer::{FullToken, Position}, | ||||||
|  |     mir::{ | ||||||
|  |         self, CustomTypeKey, Metadata, SourceModuleId, TypeDefinition, TypeDefinitionKind, | ||||||
|  |         TypeKind, VagueLiteral, | ||||||
|  |     }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | use super::{ | ||||||
|  |     scope::{Debug, Scope}, | ||||||
|  |     ModuleCodegen, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | impl mir::CmpOperator { | ||||||
|  |     pub(super) fn predicate(&self) -> CmpPredicate { | ||||||
|  |         match self { | ||||||
|  |             mir::CmpOperator::LT => CmpPredicate::LT, | ||||||
|  |             mir::CmpOperator::GT => CmpPredicate::GT, | ||||||
|  |             mir::CmpOperator::LE => CmpPredicate::LE, | ||||||
|  |             mir::CmpOperator::GE => CmpPredicate::GE, | ||||||
|  |             mir::CmpOperator::EQ => CmpPredicate::EQ, | ||||||
|  |             mir::CmpOperator::NE => CmpPredicate::NE, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl mir::Literal { | ||||||
|  |     pub(super) fn as_const(&self, block: &mut Block) -> InstructionValue { | ||||||
|  |         block | ||||||
|  |             .build_named(format!("{}", self), self.as_const_kind()) | ||||||
|  |             .unwrap() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub(super) fn as_const_kind(&self) -> Instr { | ||||||
|  |         Instr::Constant(match self.clone() { | ||||||
|  |             mir::Literal::I8(val) => ConstValue::I8(val), | ||||||
|  |             mir::Literal::I16(val) => ConstValue::I16(val), | ||||||
|  |             mir::Literal::I32(val) => ConstValue::I32(val), | ||||||
|  |             mir::Literal::I64(val) => ConstValue::I64(val), | ||||||
|  |             mir::Literal::I128(val) => ConstValue::I128(val), | ||||||
|  |             mir::Literal::U8(val) => ConstValue::U8(val), | ||||||
|  |             mir::Literal::U16(val) => ConstValue::U16(val), | ||||||
|  |             mir::Literal::U32(val) => ConstValue::U32(val), | ||||||
|  |             mir::Literal::U64(val) => ConstValue::U64(val), | ||||||
|  |             mir::Literal::U128(val) => ConstValue::U128(val), | ||||||
|  |             mir::Literal::Bool(val) => ConstValue::Bool(val), | ||||||
|  |             mir::Literal::String(val) => ConstValue::Str(val.clone()), | ||||||
|  |             mir::Literal::Vague(VagueLiteral::Number(val)) => ConstValue::I32(val as i32), | ||||||
|  |             mir::Literal::Vague(VagueLiteral::Decimal(val)) => ConstValue::F32(val as f32), | ||||||
|  |             mir::Literal::F16(val) => ConstValue::F16(val), | ||||||
|  |             mir::Literal::F32B(val) => ConstValue::F32B(val), | ||||||
|  |             mir::Literal::F32(val) => ConstValue::F32(val), | ||||||
|  |             mir::Literal::F64(val) => ConstValue::F64(val), | ||||||
|  |             mir::Literal::F80(val) => ConstValue::F80(val), | ||||||
|  |             mir::Literal::F128(val) => ConstValue::F128(val), | ||||||
|  |             mir::Literal::F128PPC(val) => ConstValue::F128PPC(val), | ||||||
|  |             mir::Literal::Char(c) => ConstValue::U8(c as u8), | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl TypeKind { | ||||||
|  |     pub(super) fn get_type(&self, type_vals: &HashMap<CustomTypeKey, TypeValue>) -> Type { | ||||||
|  |         match &self { | ||||||
|  |             TypeKind::I8 => Type::I8, | ||||||
|  |             TypeKind::I16 => Type::I16, | ||||||
|  |             TypeKind::I32 => Type::I32, | ||||||
|  |             TypeKind::I64 => Type::I64, | ||||||
|  |             TypeKind::I128 => Type::I128, | ||||||
|  |             TypeKind::U8 => Type::U8, | ||||||
|  |             TypeKind::U16 => Type::U16, | ||||||
|  |             TypeKind::U32 => Type::U32, | ||||||
|  |             TypeKind::U64 => Type::U64, | ||||||
|  |             TypeKind::U128 => Type::U128, | ||||||
|  |             TypeKind::Bool => Type::Bool, | ||||||
|  |             TypeKind::F16 => Type::F16, | ||||||
|  |             TypeKind::F32B => Type::F32B, | ||||||
|  |             TypeKind::F32 => Type::F32, | ||||||
|  |             TypeKind::F64 => Type::F64, | ||||||
|  |             TypeKind::F128 => Type::F128, | ||||||
|  |             TypeKind::F80 => Type::F80, | ||||||
|  |             TypeKind::F128PPC => Type::F128PPC, | ||||||
|  |             TypeKind::Char => Type::U8, | ||||||
|  |             TypeKind::Array(elem_t, len) => Type::Array(Box::new(elem_t.get_type(type_vals)), *len), | ||||||
|  |             TypeKind::Void => Type::Void, | ||||||
|  |             TypeKind::Vague(_) => panic!("Tried to compile a vague type!"), | ||||||
|  |             TypeKind::CustomType(n) => { | ||||||
|  |                 let type_val = type_vals.get(n).unwrap().clone(); | ||||||
|  |                 Type::CustomType(type_val) | ||||||
|  |             } | ||||||
|  |             TypeKind::UserPtr(type_kind) => Type::Ptr(Box::new(type_kind.get_type(type_vals))), | ||||||
|  |             TypeKind::CodegenPtr(type_kind) => Type::Ptr(Box::new(type_kind.get_type(type_vals))), | ||||||
|  |             TypeKind::Borrow(type_kind, _) => Type::Ptr(Box::new(type_kind.get_type(type_vals))), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl TypeKind { | ||||||
|  |     pub(super) fn get_debug_type(&self, debug: &Debug, scope: &Scope) -> DebugTypeValue { | ||||||
|  |         self.get_debug_type_hard( | ||||||
|  |             debug.scope, | ||||||
|  |             debug.info, | ||||||
|  |             debug.types, | ||||||
|  |             scope.type_values, | ||||||
|  |             scope.types, | ||||||
|  |             scope.module_id, | ||||||
|  |             scope.tokens, | ||||||
|  |             scope.modules, | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub(super) fn get_debug_type_hard( | ||||||
|  |         &self, | ||||||
|  |         scope: DebugProgramValue, | ||||||
|  |         debug_info: &DebugInformation, | ||||||
|  |         debug_types: &HashMap<TypeKind, DebugTypeValue>, | ||||||
|  |         type_values: &HashMap<CustomTypeKey, TypeValue>, | ||||||
|  |         types: &HashMap<TypeValue, TypeDefinition>, | ||||||
|  |         local_mod: SourceModuleId, | ||||||
|  |         tokens: &Vec<FullToken>, | ||||||
|  |         modules: &HashMap<SourceModuleId, ModuleCodegen>, | ||||||
|  |     ) -> DebugTypeValue { | ||||||
|  |         if let Some(ty) = debug_types.get(self) { | ||||||
|  |             return *ty; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let name = format!("{}", self); | ||||||
|  | 
 | ||||||
|  |         let data = match self { | ||||||
|  |             TypeKind::CodegenPtr(inner) | TypeKind::UserPtr(inner) | TypeKind::Borrow(inner, _) => { | ||||||
|  |                 DebugTypeData::Pointer(DebugPointerType { | ||||||
|  |                     name, | ||||||
|  |                     pointee: inner.get_debug_type_hard( | ||||||
|  |                         scope, | ||||||
|  |                         debug_info, | ||||||
|  |                         debug_types, | ||||||
|  |                         type_values, | ||||||
|  |                         types, | ||||||
|  |                         local_mod, | ||||||
|  |                         tokens, | ||||||
|  |                         modules, | ||||||
|  |                     ), | ||||||
|  |                     size_bits: self.size_of(), | ||||||
|  |                 }) | ||||||
|  |             } | ||||||
|  |             TypeKind::Array(elem_ty, len) => { | ||||||
|  |                 let elem_ty = elem_ty.clone().get_debug_type_hard( | ||||||
|  |                     scope, | ||||||
|  |                     debug_info, | ||||||
|  |                     debug_types, | ||||||
|  |                     type_values, | ||||||
|  |                     types, | ||||||
|  |                     local_mod, | ||||||
|  |                     tokens, | ||||||
|  |                     modules, | ||||||
|  |                 ); | ||||||
|  |                 DebugTypeData::Array(DebugArrayType { | ||||||
|  |                     size_bits: self.size_of(), | ||||||
|  |                     align_bits: self.alignment(), | ||||||
|  |                     element_type: elem_ty, | ||||||
|  |                     length: *len, | ||||||
|  |                 }) | ||||||
|  |             } | ||||||
|  |             TypeKind::CustomType(key) => { | ||||||
|  |                 let typedef = types.get(type_values.get(key).unwrap()).unwrap(); | ||||||
|  |                 match &typedef.kind { | ||||||
|  |                     TypeDefinitionKind::Struct(struct_type) => { | ||||||
|  |                         let mut fields = Vec::new(); | ||||||
|  |                         let mut size_bits = 0; | ||||||
|  | 
 | ||||||
|  |                         for field in &struct_type.0 { | ||||||
|  |                             let location = if typedef.source_module != local_mod { | ||||||
|  |                                 None | ||||||
|  |                             } else { | ||||||
|  |                                 field.2.into_debug(&tokens, scope) | ||||||
|  |                             }; | ||||||
|  |                             fields.push(DebugFieldType { | ||||||
|  |                                 name: field.0.clone(), | ||||||
|  |                                 scope, | ||||||
|  |                                 pos: location.map(|l| l.pos), | ||||||
|  |                                 size_bits: field.1.size_of(), | ||||||
|  |                                 offset: size_bits, | ||||||
|  |                                 flags: DwarfFlags, | ||||||
|  |                                 ty: field.1.get_debug_type_hard( | ||||||
|  |                                     scope, | ||||||
|  |                                     debug_info, | ||||||
|  |                                     debug_types, | ||||||
|  |                                     type_values, | ||||||
|  |                                     types, | ||||||
|  |                                     local_mod, | ||||||
|  |                                     tokens, | ||||||
|  |                                     modules, | ||||||
|  |                                 ), | ||||||
|  |                             }); | ||||||
|  |                             size_bits += field.1.size_of(); | ||||||
|  |                         } | ||||||
|  |                         { | ||||||
|  |                             let location = if typedef.source_module != local_mod { | ||||||
|  |                                 None | ||||||
|  |                             } else { | ||||||
|  |                                 typedef.meta.into_debug(&tokens, scope) | ||||||
|  |                             }; | ||||||
|  |                             DebugTypeData::Struct(DebugStructType { | ||||||
|  |                                 name: key.0.clone(), | ||||||
|  |                                 scope, | ||||||
|  |                                 pos: location.map(|l| l.pos), | ||||||
|  |                                 size_bits, | ||||||
|  |                                 flags: DwarfFlags, | ||||||
|  |                                 fields, | ||||||
|  |                             }) | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             _ => DebugTypeData::Basic(DebugBasicType { | ||||||
|  |                 name, | ||||||
|  |                 size_bits: self.size_of(), | ||||||
|  |                 encoding: match self { | ||||||
|  |                     TypeKind::Bool => DwarfEncoding::Boolean, | ||||||
|  |                     TypeKind::I8 => DwarfEncoding::SignedChar, | ||||||
|  |                     TypeKind::U8 => DwarfEncoding::UnsignedChar, | ||||||
|  |                     TypeKind::I16 | TypeKind::I32 | TypeKind::I64 | TypeKind::I128 => { | ||||||
|  |                         DwarfEncoding::Signed | ||||||
|  |                     } | ||||||
|  |                     TypeKind::U16 | TypeKind::U32 | TypeKind::U64 | TypeKind::U128 => { | ||||||
|  |                         DwarfEncoding::Unsigned | ||||||
|  |                     } | ||||||
|  |                     TypeKind::F16 | ||||||
|  |                     | TypeKind::F32 | ||||||
|  |                     | TypeKind::F32B | ||||||
|  |                     | TypeKind::F64 | ||||||
|  |                     | TypeKind::F80 | ||||||
|  |                     | TypeKind::F128 | ||||||
|  |                     | TypeKind::F128PPC => DwarfEncoding::Float, | ||||||
|  |                     TypeKind::Void => DwarfEncoding::Address, | ||||||
|  |                     TypeKind::Char => DwarfEncoding::UnsignedChar, | ||||||
|  |                     TypeKind::Array(_, _) => DwarfEncoding::Address, | ||||||
|  |                     TypeKind::CustomType(_) => DwarfEncoding::Address, | ||||||
|  |                     _ => panic!("tried fetching debug-type for non-supported type!"), | ||||||
|  |                 }, | ||||||
|  |                 flags: DwarfFlags, | ||||||
|  |             }), | ||||||
|  |         }; | ||||||
|  |         debug_info.debug_type(data) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Metadata { | ||||||
|  |     pub(super) fn into_debug( | ||||||
|  |         &self, | ||||||
|  |         tokens: &Vec<FullToken>, | ||||||
|  |         scope: DebugProgramValue, | ||||||
|  |     ) -> Option<DebugLocation> { | ||||||
|  |         if let Some((start, _)) = self.into_positions(tokens) { | ||||||
|  |             Some(start.debug(scope)) | ||||||
|  |         } else { | ||||||
|  |             None | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Position { | ||||||
|  |     pub(super) fn debug(self, scope: DebugProgramValue) -> DebugLocation { | ||||||
|  |         DebugLocation { | ||||||
|  |             pos: DebugPosition { | ||||||
|  |                 line: self.1, | ||||||
|  |                 column: self.0, | ||||||
|  |             }, | ||||||
|  |             scope, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -43,8 +43,8 @@ | |||||||
| 
 | 
 | ||||||
| use std::path::PathBuf; | use std::path::PathBuf; | ||||||
| 
 | 
 | ||||||
|  | use codegen::intrinsics::{form_intrinsic_binops, form_intrinsics}; | ||||||
| use error_raporting::{ErrorKind as ErrorRapKind, ErrorModules, ReidError}; | use error_raporting::{ErrorKind as ErrorRapKind, ErrorModules, ReidError}; | ||||||
| use intrinsics::{form_intrinsic_binops, form_intrinsics}; |  | ||||||
| use lexer::FullToken; | use lexer::FullToken; | ||||||
| use mir::{ | use mir::{ | ||||||
|     linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs, |     linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs, | ||||||
| @ -53,11 +53,9 @@ use reid_lib::{compile::CompileOutput, Context}; | |||||||
| 
 | 
 | ||||||
| use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream}; | use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream}; | ||||||
| 
 | 
 | ||||||
| mod allocator; |  | ||||||
| mod ast; | mod ast; | ||||||
| mod codegen; | mod codegen; | ||||||
| pub mod error_raporting; | pub mod error_raporting; | ||||||
| pub mod intrinsics; |  | ||||||
| pub mod ld; | pub mod ld; | ||||||
| mod lexer; | mod lexer; | ||||||
| pub mod mir; | pub mod mir; | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ | |||||||
| use std::{collections::HashMap, path::PathBuf}; | use std::{collections::HashMap, path::PathBuf}; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     intrinsics::IntrinsicFunction, |     codegen::intrinsics::IntrinsicFunction, | ||||||
|     lexer::{FullToken, Position}, |     lexer::{FullToken, Position}, | ||||||
|     token_stream::TokenRange, |     token_stream::TokenRange, | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user