use crate::{ patio::{ compilation_unit::{ PatioCompilationUnit, PatioCompilationUnitElement, PatioDataElementImmutableDefinition, PatioDataElementMutableDeclaration, PatioDataElementMutableDefinition, PatioFunctionDeclaration, PatioFunctionDefinition, PatioLocal, PatioLocalType, PatioVisibility, }, instructions::{ PatioBlock, PatioBoolToInt, PatioCall, PatioCallPointer, PatioDataPtrToInt, PatioIf, PatioInstruction, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, PatioIntToBool, PatioIntToDataPtr, PatioLocalStore, PatioLoop, PatioLoopBreak, PatioLoopContinue, PatioMemoryLoad, PatioMemoryStore, PatioReturn, PatioSwitch, PatioSwitchCase, PatioUnreachable, PatioVarLoad, PatioVarStore, }, operands::{PatioLocalRef, PatioOperand}, types::{PatioDataLayout, PatioType}, values::{PatioDataPtrValue, PatioDataValue, PatioIntValue}, }, patio_generated::{ self, patio::{PatioDataLayoutValue, PatioDataValueValue, PatioIntValueValue, PatioTypeValue}, }, }; // == Compilation unit == impl From> for PatioCompilationUnit { fn from(value: patio_generated::patio::PatioCompilationUnit<'_>) -> Self { Self { elements: value.elements().iter().map(Into::into).collect(), } } } // == Compilation unit elements == impl From> for PatioCompilationUnitElement { fn from(value: patio_generated::patio::PatioCompilationUnitElement<'_>) -> Self { match value.value_type() { patio_generated::patio::PatioCompilationUnitElementValue::PatioDataElementImmutableDefinition => { let data_element_immutable_definition = value.value_as_patio_data_element_immutable_definition().unwrap(); Self::DataElementImmutableDefinition(PatioDataElementImmutableDefinition { name: data_element_immutable_definition.name().to_string(), visibility: data_element_immutable_definition.visibility().into(), value: data_element_immutable_definition.value().into(), }) } patio_generated::patio::PatioCompilationUnitElementValue::PatioDataElementMutableDeclaration => { let data_element_mutable_declaration = value.value_as_patio_data_element_mutable_declaration().unwrap(); Self::DataElementMutableDeclaration(PatioDataElementMutableDeclaration { name: data_element_mutable_declaration.name().to_string(), layout: data_element_mutable_declaration.layout().into(), }) } patio_generated::patio::PatioCompilationUnitElementValue::PatioDataElementMutableDefinition => { let data_element_mutable_definition = value.value_as_patio_data_element_mutable_definition().unwrap(); Self::DataElementMutableDefinition(PatioDataElementMutableDefinition { name: data_element_mutable_definition.name().to_string(), visibility: data_element_mutable_definition.visibility().into(), initial_value: data_element_mutable_definition.initial_value().into(), }) } patio_generated::patio::PatioCompilationUnitElementValue::PatioFunctionDeclaration => { let function_declaration = value.value_as_patio_function_declaration().unwrap(); Self::FunctionDeclaration(PatioFunctionDeclaration { name: function_declaration.name().to_string(), params: function_declaration .params() .iter() .map(Into::into) .collect(), return_types: function_declaration.return_types().iter().map(Into::into).collect(), }) } patio_generated::patio::PatioCompilationUnitElementValue::PatioFunctionDefinition => { let function_definition = value.value_as_patio_function_definition().unwrap(); Self::FunctionDefinition(PatioFunctionDefinition { name: function_definition.name().to_string(), visibility: function_definition.visibility().into(), locals: function_definition .locals() .iter() .map(Into::into) .collect(), return_types: function_definition.return_types().iter().map(Into::into).collect(), body: function_definition.body().iter().map(Into::into).collect(), }) } element_type => todo!( "Unhandled compilation unit element type: {:?} {}", element_type.variant_name(), element_type.0 ), } } } impl From> for PatioLocal { fn from(value: patio_generated::patio::PatioLocal<'_>) -> Self { Self { name: value.name().to_string(), type_: value.type_().into(), local_type: value.local_type().into(), } } } impl From for PatioLocalType { fn from(value: patio_generated::patio::PatioLocalType) -> Self { match value { patio_generated::patio::PatioLocalType::PARAM => Self::Param, patio_generated::patio::PatioLocalType::VAL => Self::Val, patio_generated::patio::PatioLocalType::VAR => Self::Var, local_type_type => todo!( "Unhandled local type type: {:?} {}", local_type_type.variant_name(), local_type_type.0 ), } } } impl From for PatioVisibility { fn from(value: patio_generated::patio::PatioVisibility) -> Self { match value { patio_generated::patio::PatioVisibility::PRIVATE => Self::Private, patio_generated::patio::PatioVisibility::PUBLIC => Self::Public, visibility_type => todo!( "Unhandled visibility type: {:?} {}", visibility_type.variant_name(), visibility_type.0 ), } } } // == Instructions == impl From> for PatioInstruction { fn from(value: patio_generated::patio::PatioInstruction<'_>) -> Self { match value.value_type() { patio_generated::patio::PatioInstructionValue::PatioBlock => { let block = value.value_as_patio_block().unwrap(); Self::Block(block.into()) } patio_generated::patio::PatioInstructionValue::PatioBoolToInt => { let bool_to_int = value.value_as_patio_bool_to_int().unwrap(); Self::BoolToInt(PatioBoolToInt { destination: bool_to_int.destination().into(), value: bool_to_int.value().into(), }) } patio_generated::patio::PatioInstructionValue::PatioCall => { let call = value.value_as_patio_call().unwrap(); Self::Call(PatioCall { destinations: call.destinations().iter().map(Into::into).collect(), function_name: call.function_name().into(), args: call.args().iter().map(Into::into).collect(), }) } patio_generated::patio::PatioInstructionValue::PatioCallPointer => { let call_pointer = value.value_as_patio_call_pointer().unwrap(); Self::CallPointer(PatioCallPointer { destinations: call_pointer.destinations().iter().map(Into::into).collect(), function_pointer: call_pointer.function_pointer().into(), args: call_pointer.args().iter().map(Into::into).collect(), }) } patio_generated::patio::PatioInstructionValue::PatioDataPtrToInt => { let data_ptr_to_int = value.value_as_patio_data_ptr_to_int().unwrap(); Self::DataPtrToInt(PatioDataPtrToInt { destination: data_ptr_to_int.destination().into(), value: data_ptr_to_int.value().into(), }) } patio_generated::patio::PatioInstructionValue::PatioIf => { let if_ = value.value_as_patio_if().unwrap(); Self::If(PatioIf { destinations: if_.destinations().iter().map(Into::into).collect(), condition: if_.condition().into(), true_body: if_.true_body().into(), false_body: if_.false_body().into(), }) } patio_generated::patio::PatioInstructionValue::PatioIntAdd => { let int_add = value.value_as_patio_int_add().unwrap(); Self::IntAdd(PatioIntAdd { destination: int_add.destination().into(), left: int_add.left().into(), right: int_add.right().into(), }) } patio_generated::patio::PatioInstructionValue::PatioIntEquals => { let int_add = value.value_as_patio_int_equals().unwrap(); Self::IntEquals(PatioIntEquals { destination: int_add.destination().into(), left: int_add.left().into(), right: int_add.right().into(), }) } patio_generated::patio::PatioInstructionValue::PatioIntNotEqual => { let int_not_equal = value.value_as_patio_int_not_equal().unwrap(); Self::IntNotEqual(PatioIntNotEqual { destination: int_not_equal.destination().into(), left: int_not_equal.left().into(), right: int_not_equal.right().into(), }) } patio_generated::patio::PatioInstructionValue::PatioIntSub => { let int_sub = value.value_as_patio_int_sub().unwrap(); Self::IntSub(PatioIntSub { destination: int_sub.destination().into(), left: int_sub.left().into(), right: int_sub.right().into(), }) } patio_generated::patio::PatioInstructionValue::PatioIntToBool => { let int_to_bool = value.value_as_patio_int_to_bool().unwrap(); Self::IntToBool(PatioIntToBool { destination: int_to_bool.destination().into(), value: int_to_bool.value().into(), }) } patio_generated::patio::PatioInstructionValue::PatioIntToDataPtr => { let int_to_data_ptr = value.value_as_patio_int_to_data_ptr().unwrap(); Self::IntToDataPtr(PatioIntToDataPtr { destination: int_to_data_ptr.destination().into(), value: int_to_data_ptr.value().into(), }) } patio_generated::patio::PatioInstructionValue::PatioLocalStore => { let local_store = value.value_as_patio_local_store().unwrap(); Self::LocalStore(PatioLocalStore { destination: local_store.destination().into(), value: local_store.value().into(), }) } patio_generated::patio::PatioInstructionValue::PatioLoop => { let loop_ = value.value_as_patio_loop().unwrap(); Self::Loop(PatioLoop { body: loop_.body().iter().map(Into::into).collect(), }) } patio_generated::patio::PatioInstructionValue::PatioLoopBreak => { Self::LoopBreak(PatioLoopBreak) } patio_generated::patio::PatioInstructionValue::PatioLoopContinue => { Self::LoopContinue(PatioLoopContinue) } patio_generated::patio::PatioInstructionValue::PatioMemoryLoad => { let memory_load = value.value_as_patio_memory_load().unwrap(); Self::MemoryLoad(PatioMemoryLoad { destination: memory_load.destination().into(), pointer: memory_load.pointer().into(), layout: memory_load.layout().into(), element_offsets: memory_load.element_offsets().iter().collect(), }) } patio_generated::patio::PatioInstructionValue::PatioMemoryStore => { let memory_store = value.value_as_patio_memory_store().unwrap(); Self::MemoryStore(PatioMemoryStore { pointer: memory_store.pointer().into(), layout: memory_store.layout().into(), element_offsets: memory_store.element_offsets().iter().collect(), value: memory_store.value().into(), }) } patio_generated::patio::PatioInstructionValue::PatioReturn => { let return_ = value.value_as_patio_return().unwrap(); Self::Return(PatioReturn { values: return_.values().iter().map(Into::into).collect(), }) } patio_generated::patio::PatioInstructionValue::PatioSwitch => { let switch = value.value_as_patio_switch().unwrap(); Self::Switch(PatioSwitch { destinations: switch.destinations().iter().map(Into::into).collect(), value: switch.value().into(), cases: switch.cases().iter().map(Into::into).collect(), default_body: switch.default_body().into(), }) } patio_generated::patio::PatioInstructionValue::PatioUnreachable => { Self::Unreachable(PatioUnreachable) } patio_generated::patio::PatioInstructionValue::PatioVarLoad => { let var_load = value.value_as_patio_var_load().unwrap(); Self::VarLoad(PatioVarLoad { destination: var_load.destination().into(), var: var_load.var().into(), }) } patio_generated::patio::PatioInstructionValue::PatioVarStore => { let var_store = value.value_as_patio_var_store().unwrap(); Self::VarStore(PatioVarStore { var: var_store.var().into(), value: var_store.value().into(), }) } instruction_type => todo!( "Unhandled instruction type: {:?} {}", instruction_type.variant_name(), instruction_type.0 ), } } } impl From> for PatioBlock { fn from(value: patio_generated::patio::PatioBlock<'_>) -> Self { Self { body: value.body().iter().map(Into::into).collect(), results: value.results().iter().map(Into::into).collect(), } } } impl From> for PatioSwitchCase { fn from(value: patio_generated::patio::PatioSwitchCase<'_>) -> Self { Self { value: value.value(), body: value.body().into(), } } } // == Operands == impl From> for PatioOperand { fn from(value: patio_generated::patio::PatioOperand<'_>) -> Self { match value.value_type() { patio_generated::patio::PatioOperandValue::PatioBoolConst => { let bool_const = value.value_as_patio_bool_const().unwrap(); Self::BoolConst(bool_const.value()) } patio_generated::patio::PatioOperandValue::PatioByteConst => { let byte_const = value.value_as_patio_byte_const().unwrap(); Self::ByteConst(byte_const.value().try_into().unwrap()) } patio_generated::patio::PatioOperandValue::PatioDataPtrConst => { let data_ptr_const = value.value_as_patio_data_ptr_const().unwrap(); Self::DataPtrConst(data_ptr_const.value().into()) } patio_generated::patio::PatioOperandValue::PatioFunctionPtrConst => { let function_ptr_const = value.value_as_patio_function_ptr_const().unwrap(); Self::FunctionPtrConst(function_ptr_const.name().to_string()) } patio_generated::patio::PatioOperandValue::PatioIntConst => { let int_const = value.value_as_patio_int_const().unwrap(); Self::IntConst(int_const.value().into()) } patio_generated::patio::PatioOperandValue::PatioInt32Const => { let int32_const = value.value_as_patio_int_32_const().unwrap(); Self::Int32Const(int32_const.value().into()) } patio_generated::patio::PatioOperandValue::PatioLocalRef => { let local_ref = value.value_as_patio_local_ref().unwrap(); Self::LocalRef(local_ref.into()) } operand_type => todo!( "Unhandled operand type: {:?} {}", operand_type.variant_name(), operand_type.0 ), } } } impl From> for PatioLocalRef { fn from(value: patio_generated::patio::PatioLocalRef<'_>) -> Self { Self { name: value.name().to_string(), } } } // == Data ptr values == impl From> for PatioDataPtrValue { fn from(value: patio_generated::patio::PatioDataPtrValue<'_>) -> Self { match value.value_type() { patio_generated::patio::PatioDataPtrValueValue::PatioDataPtrValueDataElement => { let data_element = value.value_as_patio_data_ptr_value_data_element().unwrap(); Self::DataElement { name: data_element.name().to_string(), } } patio_generated::patio::PatioDataPtrValueValue::PatioDataPtrValueNull => Self::Null, data_ptr_value_type => todo!( "Unhandled data ptr value type: {:?} {}", data_ptr_value_type.variant_name(), data_ptr_value_type.0 ), } } } // == Int values == impl From> for PatioIntValue { fn from(value: patio_generated::patio::PatioIntValue<'_>) -> Self { match value.value_type() { PatioIntValueValue::PatioIntValueByteOffsetOf => { let byte_offset_of = value.value_as_patio_int_value_byte_offset_of().unwrap(); Self::ByteOffsetOf { layout: byte_offset_of.layout().into(), element_offsets: byte_offset_of.element_offsets().iter().collect(), } } PatioIntValueValue::PatioIntValueByteSizeOf => { let byte_size_of = value.value_as_patio_int_value_byte_size_of().unwrap(); Self::ByteSizeOf { layout: byte_size_of.layout().into(), } } PatioIntValueValue::PatioIntValueLiteral => { let literal = value.value_as_patio_int_value_literal().unwrap(); Self::Literal { value: literal.value(), } } int_value_type => todo!( "Unhandled int value type: {:?} {}", int_value_type.variant_name(), int_value_type.0 ), } } } // == Types == impl From> for PatioType { fn from(value: patio_generated::patio::PatioType<'_>) -> Self { match value.value_type() { PatioTypeValue::PatioBoolType => Self::Bool, PatioTypeValue::PatioByteType => Self::Byte, PatioTypeValue::PatioDataPtrType => Self::DataPtr, PatioTypeValue::PatioFunctionPtrType => Self::FunctionPtr, PatioTypeValue::PatioIntType => Self::Int, PatioTypeValue::PatioInt32Type => Self::Int32, type_type => { todo!( "Unhandled type type: {:?} {}", type_type.variant_name(), type_type.0 ) } } } } // == Data layouts == impl From> for PatioDataLayout { fn from(value: patio_generated::patio::PatioDataLayout<'_>) -> Self { match value.value_type() { PatioDataLayoutValue::PatioDataLayoutArray => { let array = value.value_as_patio_data_layout_array().unwrap(); PatioDataLayout::array(array.element().into(), array.size()) } PatioDataLayoutValue::PatioDataLayoutBool => PatioDataLayout::Bool, PatioDataLayoutValue::PatioDataLayoutByte => PatioDataLayout::Byte, PatioDataLayoutValue::PatioDataLayoutDataPtr => PatioDataLayout::DataPtr, PatioDataLayoutValue::PatioDataLayoutFunctionPtr => PatioDataLayout::FunctionPtr, PatioDataLayoutValue::PatioDataLayoutInt => PatioDataLayout::Int, PatioDataLayoutValue::PatioDataLayoutInt32 => PatioDataLayout::Int32, PatioDataLayoutValue::PatioDataLayoutStruct => { let struct_ = value.value_as_patio_data_layout_struct().unwrap(); PatioDataLayout::struct_( struct_ .elements() .iter() .map(|element| element.into()) .collect(), ) } layout_type => { todo!( "Unhandled data layout type: {:?} {}", layout_type.variant_name(), layout_type.0 ) } } } } // == Data values == impl From> for PatioDataValue { fn from(value: patio_generated::patio::PatioDataValue<'_>) -> Self { match value.value_type() { PatioDataValueValue::PatioDataValueArray => { let array = value.value_as_patio_data_value_array().unwrap(); Self::Array { element_layout: array.element_layout().into(), elements: array.elements().iter().map(Into::into).collect(), } } PatioDataValueValue::PatioDataValueBool => { let bool = value.value_as_patio_data_value_bool().unwrap(); Self::Bool(bool.value()) } PatioDataValueValue::PatioDataValueByte => { let byte = value.value_as_patio_data_value_byte().unwrap(); Self::Byte(byte.value().try_into().unwrap()) } PatioDataValueValue::PatioDataValueDataPtr => { let data_ptr = value.value_as_patio_data_value_data_ptr().unwrap(); Self::DataPtr(data_ptr.value().into()) } PatioDataValueValue::PatioDataValueInt => { let int = value.value_as_patio_data_value_int().unwrap(); Self::Int(int.value().into()) } PatioDataValueValue::PatioDataValueInt32 => { let int32 = value.value_as_patio_data_value_int_32().unwrap(); Self::Int32(int32.value().into()) } PatioDataValueValue::PatioDataValueStruct => { let struct_ = value.value_as_patio_data_value_struct().unwrap(); Self::Struct { elements: struct_.elements().iter().map(Into::into).collect(), } } value_type => { todo!( "Unhandled data value type: {:?} {}", value_type.variant_name(), value_type.0 ) } } } }