@@ -647,84 +647,77 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
647
647
648
648
fn generate_output_assignment_with_direct_access (
649
649
& self ,
650
+ left_statement : & AstNode ,
650
651
left_pointer : PointerValue ,
651
- lvalue_rhs : PointerValue ,
652
- statement_lhs : & AstNode ,
653
- type_rhs : & DataType ,
652
+ right_pointer : PointerValue ,
653
+ right_type : & DataType ,
654
654
) -> Result < ( ) , Diagnostic > {
655
655
let left_value = self . llvm . builder . build_load ( left_pointer, "" ) . into_int_value ( ) ;
656
656
657
657
//Generate an expression for the right size
658
- let right = self . llvm . builder . build_load ( lvalue_rhs , "" ) ;
658
+ let right = self . llvm . builder . build_load ( right_pointer , "" ) ;
659
659
self . generate_assignment_with_direct_access (
660
- statement_lhs ,
660
+ left_statement ,
661
661
left_value,
662
662
left_pointer,
663
- type_rhs ,
663
+ right_type ,
664
664
right,
665
665
) ?;
666
666
667
667
Ok ( ( ) )
668
668
}
669
669
670
670
fn generate_output_assignment ( & self , context : & CallParameterAssignment ) -> Result < ( ) , Diagnostic > {
671
- let & CallParameterAssignment { assignment, function_name, index, parameter_struct } = context;
671
+ let & CallParameterAssignment { assignment : expr , function_name, index, parameter_struct } = context;
672
672
let builder = & self . llvm . builder ;
673
673
674
- let Some ( parameter) = self . index . get_declared_parameter ( function_name, index) else {
675
- panic ! ( "or return?" ) ;
676
- } ;
677
- assert ! ( parameter. get_variable_type( ) . is_output( ) ) ;
678
-
679
- // Don't generate code if right-hand side of an assignment is an empty statement (e.g. `foo(out => )`)
680
- if assignment. is_empty_statement ( ) {
674
+ // We don't want to generate any code if the right side of an assignment is empty, e.g. `foo(out =>)`
675
+ if expr. is_empty_statement ( ) {
681
676
return Ok ( ( ) ) ;
682
677
}
683
678
684
- // FOO(x => y)
685
- // FOO(x => y.0)
686
- match assignment . get_stmt ( ) {
687
- AstStatement :: ReferenceExpr ( _) if assignment . has_direct_access ( ) => {
679
+ let parameter = self . index . get_declared_parameter ( function_name , index ) . expect ( "must exist" ) ;
680
+
681
+ match expr . get_stmt ( ) {
682
+ AstStatement :: ReferenceExpr ( _) if expr . has_direct_access ( ) => {
688
683
// TODO: Can we this be simplified?
689
- let dt = {
684
+ let rhs_type = {
690
685
let pou = self . index . find_pou ( function_name) . unwrap ( ) ;
691
686
let pou_struct = & pou. find_instance_struct_type ( self . index ) . unwrap ( ) . information ;
692
687
let DataTypeInformation :: Struct { members, .. } = pou_struct else { panic ! ( ) } ;
693
- let param = & members[ index as usize ] ; // TODO: Create a test for this; this fucks up if populating the members is not in order
694
688
695
- self . index . find_effective_type_by_name ( & param . data_type_name ) . unwrap ( )
689
+ self . index . find_effective_type_by_name ( & members [ index as usize ] . data_type_name ) . unwrap ( )
696
690
} ;
697
691
698
692
let AstStatement :: ReferenceExpr ( ReferenceExpr {
699
693
access : ReferenceAccess :: Member ( member) ,
700
694
base,
701
- } ) = & assignment . get_stmt ( )
695
+ } ) = & expr . get_stmt ( )
702
696
else {
703
697
unreachable ! ( "must be a bitaccess, will return early for all other cases" )
704
698
} ;
705
699
706
700
if let AstStatement :: DirectAccess ( _) = member. as_ref ( ) . get_stmt ( ) {
701
+ // Given `foo.bar.baz.%W1.%B1.%X3`, we want to grab the base i.e. `foo.bar.baz`
707
702
let ( Some ( base) , _) = ( base, ..) else { panic ! ( ) } ;
708
- // Given `foo.bar.baz.%W1.%B1.%X3`, we want to grab the lvalue of `foo.bar.baz`
709
703
let ( base, _) = collect_base_and_direct_access_for_assignment ( base) . unwrap ( ) ;
710
704
711
705
let lhs = self . generate_expression_value ( base) ?. get_basic_value_enum ( ) ;
712
- let rhs = self . llvm . builder . build_struct_gep ( parameter_struct, index, "" ) . unwrap ( ) ; // TODO(volsa): Is a `impl From<...>` possible for inkwell results?
706
+ let rhs = self . llvm . builder . build_struct_gep ( parameter_struct, index, "" ) . unwrap ( ) ;
713
707
714
708
self . generate_output_assignment_with_direct_access (
709
+ expr,
715
710
lhs. into_pointer_value ( ) ,
716
711
rhs,
717
- assignment,
718
- dt,
712
+ rhs_type,
719
713
) ?;
720
714
} ;
721
715
}
722
716
723
717
_ => {
724
- let assigned_output = self . generate_lvalue ( assignment) ?;
725
-
718
+ let assigned_output = self . generate_lvalue ( expr) ?;
726
719
let assigned_output_type =
727
- self . annotations . get_type_or_void ( assignment , self . index ) . get_type_information ( ) ;
720
+ self . annotations . get_type_or_void ( expr , self . index ) . get_type_information ( ) ;
728
721
729
722
let output = builder. build_struct_gep ( parameter_struct, index, "" ) . map_err ( |_| {
730
723
Diagnostic :: codegen_error (
@@ -735,15 +728,15 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
735
728
736
729
let output_value_type = self . index . get_type_information_or_void ( parameter. get_type_name ( ) ) ;
737
730
738
- //Special string handling
731
+ // Special string handling
739
732
if ( assigned_output_type. is_string ( ) && output_value_type. is_string ( ) )
740
733
|| ( assigned_output_type. is_struct ( ) && output_value_type. is_struct ( ) )
741
734
|| ( assigned_output_type. is_array ( ) && output_value_type. is_array ( ) )
742
735
{
743
736
self . generate_string_store (
744
737
assigned_output,
745
738
assigned_output_type,
746
- assignment . get_location ( ) ,
739
+ expr . get_location ( ) ,
747
740
output,
748
741
output_value_type,
749
742
parameter. source_location . clone ( ) ,
@@ -758,8 +751,6 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
758
751
Ok ( ( ) )
759
752
}
760
753
761
- /// Given an output assignment such as `foo => bar`, the right-hand side of the assignment (i.e. `bar`)
762
- /// will be extracted and fed into [`generate_output_assignment`] in a subsequent call.
763
754
fn generate_explicit_output_assignment (
764
755
& self ,
765
756
parameter_struct : PointerValue < ' ink > ,
0 commit comments