Skip to content

Commit

Permalink
Fixed issue with conditional statements requiring a resulting value e…
Browse files Browse the repository at this point in the history
…ven when just used as a statement
  • Loading branch information
IsaacShelton committed Jan 6, 2025
1 parent 375ac7d commit b639840
Show file tree
Hide file tree
Showing 19 changed files with 202 additions and 97 deletions.
2 changes: 1 addition & 1 deletion src/asg/expr/conditional.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::asg::{Block, Type};

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Conditional {
pub result_type: Type,
pub result_type: Option<Type>,
pub branches: Vec<Branch>,
pub otherwise: Option<Block>,
}
Expand Down
9 changes: 6 additions & 3 deletions src/lower/expr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,12 @@ pub fn lower_expr(
builder.use_block(resume_basicblock_id);

if conditional.otherwise.is_some() {
let ir_type =
lower_type(ir_module, &builder.unpoly(&conditional.result_type)?, asg)?;
Ok(builder.push(ir::Instr::Phi(ir::Phi { ir_type, incoming })))
if let Some(result_type) = &conditional.result_type {
let ir_type = lower_type(ir_module, &builder.unpoly(result_type)?, asg)?;
Ok(builder.push(ir::Instr::Phi(ir::Phi { ir_type, incoming })))
} else {
Ok(Value::Literal(Literal::Void))
}
} else {
Ok(Value::Literal(Literal::Void))
}
Expand Down
6 changes: 4 additions & 2 deletions src/resolve/expr/array_access.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{resolve_expr, PreferredType, ResolveExprCtx};
use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode};
use crate::{
asg::{self, TypedExpr},
ast,
Expand All @@ -23,7 +23,8 @@ pub fn resolve_array_access_expr(
ctx,
&array_access.subject,
None,
crate::resolve::Initialized::Require,
Initialized::Require,
ResolveExprMode::RequireValue,
)?,
c_integer_assumptions,
)?;
Expand All @@ -36,6 +37,7 @@ pub fn resolve_array_access_expr(
&asg::TypeKind::Integer(IntegerBits::Bits64, IntegerSign::Unsigned).at(source),
)),
Initialized::Require,
ResolveExprMode::RequireValue,
)?,
c_integer_assumptions,
)?;
Expand Down
89 changes: 46 additions & 43 deletions src/resolve/expr/basic_binary_operation.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use super::{resolve_expr, PreferredType, ResolveExprCtx};
use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode};
use crate::{
asg::{
self, Constraint, FloatOrInteger, FloatOrSignLax, NumericMode, SignOrIndeterminate,
TypedExpr,
},
ast,
resolve::{
error::{ResolveError, ResolveErrorKind},
unify_types::unify_types,
Initialized,
},
asg::{
self, Constraint, FloatOrInteger, FloatOrSignLax, NumericMode, SignOrIndeterminate,
TypedExpr,
},
source_files::Source,
};
use ast::IntegerSign;
Expand All @@ -27,13 +27,15 @@ pub fn resolve_basic_binary_operation_expr(
&binary_operation.left,
preferred_type,
Initialized::Require,
ResolveExprMode::RequireValue,
)?;

let mut right = resolve_expr(
ctx,
&binary_operation.right,
preferred_type,
Initialized::Require,
ResolveExprMode::RequireValue,
)?;

if let asg::TypeKind::IntegerLiteral(left) = &left.ty.kind {
Expand Down Expand Up @@ -105,51 +107,54 @@ pub fn resolve_basic_binary_operator(
ast::BasicBinaryOperator::Multiply => {
NumericMode::try_new(ty).map(asg::BasicBinaryOperator::Multiply)
}
ast::BasicBinaryOperator::Divide => float_or_sign_lax_from_type(ty, false)
.map(asg::BasicBinaryOperator::Divide),
ast::BasicBinaryOperator::Modulus => float_or_sign_lax_from_type(ty, false)
.map(asg::BasicBinaryOperator::Modulus),
ast::BasicBinaryOperator::Equals => float_or_integer_from_type(ty, true)
.map(asg::BasicBinaryOperator::Equals),
ast::BasicBinaryOperator::NotEquals => float_or_integer_from_type(ty, true)
.map(asg::BasicBinaryOperator::NotEquals),
ast::BasicBinaryOperator::LessThan => float_or_sign_lax_from_type(ty, false)
.map(asg::BasicBinaryOperator::LessThan),
ast::BasicBinaryOperator::LessThanEq => float_or_sign_lax_from_type(ty, false)
.map(asg::BasicBinaryOperator::LessThanEq),
ast::BasicBinaryOperator::GreaterThan => float_or_sign_lax_from_type(ty, false)
.map(asg::BasicBinaryOperator::GreaterThan),
ast::BasicBinaryOperator::Divide => {
float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::Divide)
}
ast::BasicBinaryOperator::Modulus => {
float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::Modulus)
}
ast::BasicBinaryOperator::Equals => {
float_or_integer_from_type(ty, true).map(asg::BasicBinaryOperator::Equals)
}
ast::BasicBinaryOperator::NotEquals => {
float_or_integer_from_type(ty, true).map(asg::BasicBinaryOperator::NotEquals)
}
ast::BasicBinaryOperator::LessThan => {
float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::LessThan)
}
ast::BasicBinaryOperator::LessThanEq => {
float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::LessThanEq)
}
ast::BasicBinaryOperator::GreaterThan => {
float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::GreaterThan)
}
ast::BasicBinaryOperator::GreaterThanEq => {
float_or_sign_lax_from_type(ty, false)
.map(asg::BasicBinaryOperator::GreaterThanEq)
float_or_sign_lax_from_type(ty, false).map(asg::BasicBinaryOperator::GreaterThanEq)
}
ast::BasicBinaryOperator::BitwiseAnd => (ty.kind.is_integer()
|| ty.kind.is_c_integer()
|| ty.kind.is_boolean())
.then_some(asg::BasicBinaryOperator::BitwiseAnd),
ast::BasicBinaryOperator::BitwiseOr => (ty.kind.is_integer()
|| ty.kind.is_c_integer()
|| ty.kind.is_boolean())
.then_some(asg::BasicBinaryOperator::BitwiseOr),
ast::BasicBinaryOperator::BitwiseXor => (ty.kind.is_integer()
|| ty.kind.is_c_integer())
.then_some(asg::BasicBinaryOperator::BitwiseXor),
ast::BasicBinaryOperator::BitwiseAnd => {
(ty.kind.is_integer() || ty.kind.is_c_integer() || ty.kind.is_boolean())
.then_some(asg::BasicBinaryOperator::BitwiseAnd)
}
ast::BasicBinaryOperator::BitwiseOr => {
(ty.kind.is_integer() || ty.kind.is_c_integer() || ty.kind.is_boolean())
.then_some(asg::BasicBinaryOperator::BitwiseOr)
}
ast::BasicBinaryOperator::BitwiseXor => (ty.kind.is_integer() || ty.kind.is_c_integer())
.then_some(asg::BasicBinaryOperator::BitwiseXor),
ast::BasicBinaryOperator::LeftShift | ast::BasicBinaryOperator::LogicalLeftShift => {
(ty.kind.is_integer() || ty.kind.is_c_integer())
.then_some(asg::BasicBinaryOperator::LogicalLeftShift)
}
ast::BasicBinaryOperator::RightShift => match ty.kind {
asg::TypeKind::Integer(_, sign) => {
Some(asg::BasicBinaryOperator::ArithmeticRightShift(
SignOrIndeterminate::Sign(sign),
))
}
asg::TypeKind::Integer(_, sign) => Some(
asg::BasicBinaryOperator::ArithmeticRightShift(SignOrIndeterminate::Sign(sign)),
),
asg::TypeKind::CInteger(c_integer, sign) => Some(if let Some(sign) = sign {
asg::BasicBinaryOperator::ArithmeticRightShift(SignOrIndeterminate::Sign(sign))
} else {
asg::BasicBinaryOperator::ArithmeticRightShift(
SignOrIndeterminate::Indeterminate(c_integer),
)
asg::BasicBinaryOperator::ArithmeticRightShift(SignOrIndeterminate::Indeterminate(
c_integer,
))
}),
_ => None,
},
Expand All @@ -173,9 +178,7 @@ fn float_or_integer_from_type(
) -> Option<FloatOrInteger> {
match &unified_type.kind {
asg::TypeKind::Boolean if allow_on_bools => Some(FloatOrInteger::Integer),
asg::TypeKind::Integer(..) | asg::TypeKind::CInteger(..) => {
Some(FloatOrInteger::Integer)
}
asg::TypeKind::Integer(..) | asg::TypeKind::CInteger(..) => Some(FloatOrInteger::Integer),
asg::TypeKind::Floating(_) => Some(FloatOrInteger::Float),
_ => None,
}
Expand Down
10 changes: 8 additions & 2 deletions src/resolve/expr/call.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{resolve_expr, PreferredType, ResolveExprCtx};
use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode};
use crate::{
asg::{self, Callee, Cast, CastFrom, TypedExpr},
ast::{self, CInteger, FloatSize},
Expand Down Expand Up @@ -28,7 +28,13 @@ pub fn resolve_call_expr(

let mut args = Vec::with_capacity(call.args.len());
for arg in call.args.iter() {
args.push(resolve_expr(ctx, arg, None, Initialized::Require)?);
args.push(resolve_expr(
ctx,
arg,
None,
Initialized::Require,
ResolveExprMode::RequireValue,
)?);
}

let args = match cast(ctx, call, args, source)? {
Expand Down
59 changes: 37 additions & 22 deletions src/resolve/expr/conditional.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{resolve_expr, PreferredType, ResolveExprCtx};
use super::{resolve_expr, PreferredType, ResolveExprCtx, ResolveExprMode};
use crate::{
asg::{self, Branch, TypedExpr},
ast,
resolve::{
conform::{conform_expr_or_error, ConformMode},
Expand All @@ -8,7 +9,6 @@ use crate::{
unify_types::unify_types,
Initialized,
},
asg::{self, Branch, TypedExpr},
source_files::Source,
};
use itertools::Itertools;
Expand All @@ -17,6 +17,7 @@ pub fn resolve_conditional_expr(
ctx: &mut ResolveExprCtx<'_, '_>,
conditional: &ast::Conditional,
preferred_type: Option<PreferredType>,
mode: ResolveExprMode,
source: Source,
) -> Result<TypedExpr, ResolveError> {
let ast::Conditional {
Expand All @@ -28,9 +29,15 @@ pub fn resolve_conditional_expr(

for (expr, block) in conditions.iter() {
ctx.variable_haystack.begin_scope();
let condition = resolve_expr(ctx, expr, preferred_type, Initialized::Require)?;
let condition = resolve_expr(
ctx,
expr,
preferred_type,
Initialized::Require,
ResolveExprMode::RequireValue,
)?;

let stmts = resolve_stmts(ctx, &block.stmts)?;
let stmts = resolve_stmts(ctx, &block.stmts, mode)?;

let condition = conform_expr_or_error(
ctx,
Expand All @@ -53,7 +60,7 @@ pub fn resolve_conditional_expr(
.as_ref()
.map(|otherwise| {
ctx.variable_haystack.begin_scope();
let maybe_block = resolve_stmts(ctx, &otherwise.stmts).map(asg::Block::new);
let maybe_block = resolve_stmts(ctx, &otherwise.stmts, mode).map(asg::Block::new);
ctx.variable_haystack.end_scope();
maybe_block
})
Expand All @@ -66,23 +73,27 @@ pub fn resolve_conditional_expr(
.map(|block| block.get_result_type(source))
.collect_vec();

let result_type = if block_results
let result_type: Option<asg::Type> = if mode == ResolveExprMode::NeglectValue {
None
} else if block_results
.iter()
.any(|result| result.kind == asg::TypeKind::Void)
{
block_results
.iter()
.all_equal()
.then_some(asg::TypeKind::Void.at(source))
.ok_or_else(|| {
ResolveErrorKind::MismatchingYieldedTypes {
got: block_results
.iter()
.map(|ty| ty.kind.to_string())
.collect_vec(),
}
.at(source)
})
Some(
block_results
.iter()
.all_equal()
.then_some(asg::TypeKind::Void.at(source))
.ok_or_else(|| {
ResolveErrorKind::MismatchingYieldedTypes {
got: block_results
.iter()
.map(|ty| ty.kind.to_string())
.collect_vec(),
}
.at(source)
})?,
)
} else {
let mut last_exprs = branches_without_else
.chunks_exact_mut(1)
Expand Down Expand Up @@ -110,6 +121,7 @@ pub fn resolve_conditional_expr(
ctx.adept_conform_behavior(),
source,
)
.map(Some)
.ok_or_else(|| {
ResolveErrorKind::MismatchingYieldedTypes {
got: block_results
Expand All @@ -118,8 +130,8 @@ pub fn resolve_conditional_expr(
.collect_vec(),
}
.at(source)
})
}?;
})?
};

let expr = asg::Expr::new(
asg::ExprKind::Conditional(Box::new(asg::Conditional {
Expand All @@ -130,5 +142,8 @@ pub fn resolve_conditional_expr(
source,
);

Ok(TypedExpr::new(result_type, expr))
Ok(TypedExpr::new(
result_type.unwrap_or_else(|| asg::TypeKind::Void.at(source)),
expr,
))
}
10 changes: 8 additions & 2 deletions src/resolve/expr/declare_assign.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{resolve_expr, ResolveExprCtx};
use super::{resolve_expr, ResolveExprCtx, ResolveExprMode};
use crate::{
asg::{self, TypedExpr},
ast::{self},
Expand All @@ -18,7 +18,13 @@ pub fn resolve_declare_assign_expr(
let c_integer_assumptions = ctx.c_integer_assumptions();

let value = conform_expr_to_default_or_error(
resolve_expr(ctx, &declare_assign.value, None, Initialized::Require)?,
resolve_expr(
ctx,
&declare_assign.value,
None,
Initialized::Require,
ResolveExprMode::RequireValue,
)?,
c_integer_assumptions,
)?;

Expand Down
9 changes: 8 additions & 1 deletion src/resolve/expr/member_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
core_struct_info::{get_core_struct_info, CoreStructInfo},
destination::resolve_expr_to_destination,
error::{ResolveError, ResolveErrorKind},
expr::ResolveExprMode,
Initialized, PolyCatalog,
},
source_files::Source,
Expand All @@ -18,7 +19,13 @@ pub fn resolve_member_expr(
min_privacy: Privacy,
source: Source,
) -> Result<TypedExpr, ResolveError> {
let resolved_subject = resolve_expr(ctx, subject, None, Initialized::Require)?;
let resolved_subject = resolve_expr(
ctx,
subject,
None,
Initialized::Require,
ResolveExprMode::RequireValue,
)?;

let CoreStructInfo {
struct_ref,
Expand Down
Loading

0 comments on commit b639840

Please sign in to comment.