Skip to content

Commit efb36a9

Browse files
committed
cleanup
1 parent e3a1686 commit efb36a9

File tree

2 files changed

+27
-34
lines changed

2 files changed

+27
-34
lines changed

src/codegen/generators/expression_generator.rs

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -647,84 +647,77 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
647647

648648
fn generate_output_assignment_with_direct_access(
649649
&self,
650+
left_statement: &AstNode,
650651
left_pointer: PointerValue,
651-
lvalue_rhs: PointerValue,
652-
statement_lhs: &AstNode,
653-
type_rhs: &DataType,
652+
right_pointer: PointerValue,
653+
right_type: &DataType,
654654
) -> Result<(), Diagnostic> {
655655
let left_value = self.llvm.builder.build_load(left_pointer, "").into_int_value();
656656

657657
//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, "");
659659
self.generate_assignment_with_direct_access(
660-
statement_lhs,
660+
left_statement,
661661
left_value,
662662
left_pointer,
663-
type_rhs,
663+
right_type,
664664
right,
665665
)?;
666666

667667
Ok(())
668668
}
669669

670670
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;
672672
let builder = &self.llvm.builder;
673673

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() {
681676
return Ok(());
682677
}
683678

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() => {
688683
// TODO: Can we this be simplified?
689-
let dt = {
684+
let rhs_type = {
690685
let pou = self.index.find_pou(function_name).unwrap();
691686
let pou_struct = &pou.find_instance_struct_type(self.index).unwrap().information;
692687
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
694688

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()
696690
};
697691

698692
let AstStatement::ReferenceExpr(ReferenceExpr {
699693
access: ReferenceAccess::Member(member),
700694
base,
701-
}) = &assignment.get_stmt()
695+
}) = &expr.get_stmt()
702696
else {
703697
unreachable!("must be a bitaccess, will return early for all other cases")
704698
};
705699

706700
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`
707702
let (Some(base), _) = (base, ..) else { panic!() };
708-
// Given `foo.bar.baz.%W1.%B1.%X3`, we want to grab the lvalue of `foo.bar.baz`
709703
let (base, _) = collect_base_and_direct_access_for_assignment(base).unwrap();
710704

711705
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();
713707

714708
self.generate_output_assignment_with_direct_access(
709+
expr,
715710
lhs.into_pointer_value(),
716711
rhs,
717-
assignment,
718-
dt,
712+
rhs_type,
719713
)?;
720714
};
721715
}
722716

723717
_ => {
724-
let assigned_output = self.generate_lvalue(assignment)?;
725-
718+
let assigned_output = self.generate_lvalue(expr)?;
726719
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();
728721

729722
let output = builder.build_struct_gep(parameter_struct, index, "").map_err(|_| {
730723
Diagnostic::codegen_error(
@@ -735,15 +728,15 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
735728

736729
let output_value_type = self.index.get_type_information_or_void(parameter.get_type_name());
737730

738-
//Special string handling
731+
// Special string handling
739732
if (assigned_output_type.is_string() && output_value_type.is_string())
740733
|| (assigned_output_type.is_struct() && output_value_type.is_struct())
741734
|| (assigned_output_type.is_array() && output_value_type.is_array())
742735
{
743736
self.generate_string_store(
744737
assigned_output,
745738
assigned_output_type,
746-
assignment.get_location(),
739+
expr.get_location(),
747740
output,
748741
output_value_type,
749742
parameter.source_location.clone(),
@@ -758,8 +751,6 @@ impl<'ink, 'b> ExpressionCodeGenerator<'ink, 'b> {
758751
Ok(())
759752
}
760753

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.
763754
fn generate_explicit_output_assignment(
764755
&self,
765756
parameter_struct: PointerValue<'ink>,

tests/correctness/bitaccess.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) 2020 Ghaith Hachem and Mathias Rieder
22

3-
// TODO: Update tests, variable initialization into program body
3+
// TODO: Some of these tests are incorrect, because a `default()` call will override the values defined in the
4+
// VAR block. Thus any tests relying on data initialized in the VAR block needs to be updated such that
5+
// the initialization happens in the POU body. However, this won't be any issue once we convert to LIT.
46

57
use crate::*;
68
use pretty_assertions::assert_eq;

0 commit comments

Comments
 (0)