Update passes

This commit is contained in:
Pranav Gaddamadugu 2023-10-10 08:57:54 -04:00 committed by Pranav Gaddamadugu
parent d3209dae9c
commit 4b9a96ee50
5 changed files with 33 additions and 27 deletions

View File

@ -554,7 +554,7 @@ impl<'a> CodeGenerator<'a> {
let return_type = &self.symbol_table.lookup_fn_symbol(function_name).unwrap().output_type;
match return_type {
Type::Unit => {} // Do nothing
Type::Tuple(tuple) => match tuple.len() {
Type::Tuple(tuple) => match tuple.length() {
0 | 1 => unreachable!("Parsing guarantees that a tuple type has at least two elements"),
len => {
for _ in 0..len {

View File

@ -99,7 +99,7 @@ impl StatementReconstructor for Unroller<'_> {
"Type checking guarantees that if the lhs is a tuple, its associated type is also a tuple."
),
};
tuple_expression.elements.iter().zip_eq(tuple_type.0.iter()).for_each(|(expression, _type_)| {
tuple_expression.elements.iter().zip_eq(tuple_type.elements().iter()).for_each(|(expression, _type_)| {
let identifier = match expression {
Expression::Identifier(identifier) => identifier,
_ => unreachable!("Type checking guarantees that if the lhs is a tuple, all of its elements are identifiers.")

View File

@ -101,11 +101,15 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
Type::Tuple(tuple) => {
// Check out of range access.
let index = access.index.value();
if index > tuple.len() - 1 {
self.emit_err(TypeCheckerError::tuple_out_of_range(index, tuple.len(), access.span()));
if index > tuple.length() - 1 {
self.emit_err(TypeCheckerError::tuple_out_of_range(
index,
tuple.length(),
access.span(),
));
} else {
// Lookup type of tuple index.
let actual = tuple.get(index).expect("failed to get tuple index").clone();
let actual = tuple.elements().get(index).expect("failed to get tuple index").clone();
if let Some(expected) = expected {
// Emit error for mismatched types.
if !actual.eq_flat(expected) {
@ -744,15 +748,15 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
// Check the expected tuple types if they are known.
if let Some(Type::Tuple(expected_types)) = expected {
// Check actual length is equal to expected length.
if expected_types.len() != input.elements.len() {
if expected_types.length() != input.elements.len() {
self.emit_err(TypeCheckerError::incorrect_tuple_length(
expected_types.len(),
expected_types.length(),
input.elements.len(),
input.span(),
));
}
expected_types.iter().zip(input.elements.iter()).for_each(|(expected, expr)| {
expected_types.elements().iter().zip(input.elements.iter()).for_each(|(expected, expr)| {
// Check that the component expression is not a tuple.
if matches!(expr, Expression::Tuple(_)) {
self.emit_err(TypeCheckerError::nested_tuple_expression(expr.span()))

View File

@ -157,10 +157,10 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
// If the type is an empty tuple, return an error.
Type::Unit => self.emit_err(TypeCheckerError::lhs_must_be_identifier_or_tuple(input.span)),
// If the type is a singleton tuple, return an error.
Type::Tuple(tuple) => match tuple.len() {
Type::Tuple(tuple) => match tuple.length() {
0 | 1 => unreachable!("Parsing guarantees that tuple types have at least two elements."),
_ => {
if tuple.iter().any(|type_| matches!(type_, Type::Tuple(_))) {
if tuple.elements().iter().any(|type_| matches!(type_, Type::Tuple(_))) {
self.emit_err(TypeCheckerError::nested_tuple_type(input.span))
}
}
@ -210,10 +210,10 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
// If the type is an empty tuple, return an error.
Type::Unit => self.emit_err(TypeCheckerError::lhs_must_be_identifier_or_tuple(input.span)),
// If the type is a singleton tuple, return an error.
Type::Tuple(tuple) => match tuple.len() {
Type::Tuple(tuple) => match tuple.length() {
0 | 1 => unreachable!("Parsing guarantees that tuple types have at least two elements."),
_ => {
if tuple.iter().any(|type_| matches!(type_, Type::Tuple(_))) {
if tuple.elements().iter().any(|type_| matches!(type_, Type::Tuple(_))) {
self.emit_err(TypeCheckerError::nested_tuple_type(input.span))
}
}
@ -252,25 +252,27 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
"Type checking guarantees that if the lhs is a tuple, its associated type is also a tuple."
),
};
if tuple_expression.elements.len() != tuple_type.len() {
if tuple_expression.elements.len() != tuple_type.length() {
return self.emit_err(TypeCheckerError::incorrect_num_tuple_elements(
tuple_expression.elements.len(),
tuple_type.len(),
tuple_type.length(),
input.place.span(),
));
}
tuple_expression.elements.iter().zip_eq(tuple_type.0.iter()).for_each(|(expression, type_)| {
let identifier = match expression {
Expression::Identifier(identifier) => identifier,
_ => {
return self.emit_err(TypeCheckerError::lhs_tuple_element_must_be_an_identifier(
expression.span(),
));
}
};
insert_variable(identifier.name, type_.clone(), identifier.span)
});
tuple_expression.elements.iter().zip_eq(tuple_type.elements().iter()).for_each(
|(expression, type_)| {
let identifier = match expression {
Expression::Identifier(identifier) => identifier,
_ => {
return self.emit_err(TypeCheckerError::lhs_tuple_element_must_be_an_identifier(
expression.span(),
));
}
};
insert_variable(identifier.name, type_.clone(), identifier.span)
},
);
}
_ => self.emit_err(TypeCheckerError::lhs_must_be_identifier_or_tuple(input.place.span())),
}

View File

@ -1047,7 +1047,7 @@ impl<'a> TypeChecker<'a> {
self.emit_err(TypeCheckerError::struct_or_record_cannot_contain_record(parent, identifier.name, span))
}
Type::Tuple(tuple_type) => {
for type_ in tuple_type.iter() {
for type_ in tuple_type.elements().iter() {
self.assert_member_is_not_record(span, parent, type_)
}
}
@ -1071,7 +1071,7 @@ impl<'a> TypeChecker<'a> {
}
// Check that the constituent types of the tuple are valid.
Type::Tuple(tuple_type) => {
for type_ in tuple_type.iter() {
for type_ in tuple_type.elements().iter() {
is_defined &= self.assert_type_is_valid(type_, span)
}
}