Skip to content

Commit 783644c

Browse files
committed
flow-control: Some cleanup.
commit-id:29416fcc
1 parent d499daa commit 783644c

File tree

2 files changed

+29
-238
lines changed

2 files changed

+29
-238
lines changed

crates/cairo-lang-lowering/src/lower/lower_if.rs

Lines changed: 2 additions & 170 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,14 @@
1-
use cairo_lang_debug::DebugWithDb;
21
use cairo_lang_diagnostics::Maybe;
32
use cairo_lang_semantic as semantic;
4-
use cairo_lang_semantic::corelib;
53
use cairo_lang_syntax::node::TypedStablePtr;
6-
use semantic::{Condition, MatchArmSelector};
74

85
use super::block_builder::{BlockBuilder, SealedBlockBuilder};
9-
use super::context::{LoweredExpr, LoweringContext, LoweringFlowError, LoweringResult};
6+
use super::context::{LoweredExpr, LoweringContext, LoweringResult};
107
use super::flow_control::create_graph::create_graph_expr_if;
118
use super::flow_control::lower_graph::lower_graph;
129
use super::lowered_expr_to_block_scope_end;
13-
use crate::diagnostic::LoweringDiagnosticKind::{self};
14-
use crate::diagnostic::{LoweringDiagnosticsBuilder, MatchDiagnostic, MatchError, MatchKind};
1510
use crate::ids::LocationId;
16-
use crate::lower::context::VarRequest;
17-
use crate::lower::lower_match::{self, MatchArmWrapper};
18-
use crate::lower::{create_subscope, lower_block, lower_expr, lower_expr_to_var_usage};
19-
use crate::{MatchArm, MatchEnumInfo, MatchInfo};
20-
21-
/// Represents an expression of the form:
22-
///
23-
/// `if conditions[0] && conditions[1] && ... && conditions[n] { expr } else { else_block }`
24-
///
25-
/// where `n` is `conditions.len() - 1`.
26-
///
27-
/// In particular, note that if `conditions` is empty, there are no conditions and the
28-
/// expression is simply [Self::expr].
29-
pub struct ConditionedExpr<'db, 'a> {
30-
pub expr: semantic::ExprId,
31-
pub conditions: &'a [Condition],
32-
pub else_block: Option<semantic::ExprId>,
33-
/// The location of the `if` expression.
34-
pub if_expr_location: LocationId<'db>,
35-
}
36-
37-
impl ConditionedExpr<'_, '_> {
38-
/// Returns a copy of self, without the first condition.
39-
pub fn remove_first(&self) -> Self {
40-
Self { conditions: &self.conditions[1..], ..*self }
41-
}
42-
}
11+
use crate::lower::lower_block;
4312

4413
/// Lowers an expression of type [semantic::ExprIf].
4514
pub fn lower_expr_if<'db>(
@@ -51,143 +20,6 @@ pub fn lower_expr_if<'db>(
5120
lower_graph(ctx, builder, &graph, ctx.get_location(expr.stable_ptr.untyped()))
5221
}
5322

54-
/// Lowers an expression of type [semantic::ExprIf].
55-
pub fn lower_if_bool_condition<'db>(
56-
ctx: &mut LoweringContext<'db, '_>,
57-
builder: &mut BlockBuilder<'db>,
58-
condition: semantic::ExprId,
59-
inner_expr: ConditionedExpr<'db, '_>,
60-
) -> LoweringResult<'db, LoweredExpr<'db>> {
61-
// The condition cannot be unit.
62-
let condition_var = lower_expr_to_var_usage(ctx, builder, condition)?;
63-
let db = ctx.db;
64-
let unit_ty = corelib::unit_ty(db);
65-
66-
let if_expr_location = inner_expr.if_expr_location;
67-
68-
// Main block.
69-
let subscope_main = create_subscope(ctx, builder);
70-
let block_main_id = subscope_main.block_id;
71-
let main_block_var_id = ctx.new_var(VarRequest { ty: unit_ty, location: if_expr_location });
72-
let else_block_input_var_id =
73-
ctx.new_var(VarRequest { ty: unit_ty, location: if_expr_location });
74-
75-
let block_main = lower_conditioned_expr_and_seal(ctx, subscope_main, &inner_expr)
76-
.map_err(LoweringFlowError::Failed)?;
77-
78-
// Else block.
79-
let subscope_else = create_subscope(ctx, builder);
80-
let block_else_id = subscope_else.block_id;
81-
82-
let block_else =
83-
lower_optional_else_block(ctx, subscope_else, inner_expr.else_block, if_expr_location)
84-
.map_err(LoweringFlowError::Failed)?;
85-
86-
let match_info = MatchInfo::Enum(MatchEnumInfo {
87-
concrete_enum_id: corelib::core_bool_enum(db),
88-
input: condition_var,
89-
arms: vec![
90-
MatchArm {
91-
arm_selector: MatchArmSelector::VariantId(corelib::false_variant(db)),
92-
block_id: block_else_id,
93-
var_ids: vec![else_block_input_var_id],
94-
},
95-
MatchArm {
96-
arm_selector: MatchArmSelector::VariantId(corelib::true_variant(db)),
97-
block_id: block_main_id,
98-
var_ids: vec![main_block_var_id],
99-
},
100-
],
101-
location: if_expr_location,
102-
});
103-
builder.merge_and_end_with_match(
104-
ctx,
105-
match_info,
106-
vec![block_main, block_else],
107-
if_expr_location,
108-
)
109-
}
110-
111-
/// Lowers an expression of type if where the condition is of type [semantic::Condition::Let].
112-
pub fn lower_if_let_condition<'db>(
113-
ctx: &mut LoweringContext<'db, '_>,
114-
builder: &mut BlockBuilder<'db>,
115-
matched_expr_id: semantic::ExprId,
116-
patterns: &[semantic::PatternId],
117-
inner_expr: ConditionedExpr<'db, '_>,
118-
) -> LoweringResult<'db, LoweredExpr<'db>> {
119-
let matched_expr = &ctx.function_body.arenas.exprs[matched_expr_id];
120-
let stable_ptr = matched_expr.stable_ptr().untyped();
121-
let ty = matched_expr.ty();
122-
let location = ctx.get_location(stable_ptr);
123-
124-
let lowered_expr = lower_expr(ctx, builder, matched_expr_id)?;
125-
126-
if corelib::numeric_upcastable_to_felt252(ctx.db, ty) {
127-
return Err(LoweringFlowError::Failed(ctx.diagnostics.report(
128-
stable_ptr,
129-
LoweringDiagnosticKind::MatchError(MatchError {
130-
kind: MatchKind::IfLet,
131-
error: MatchDiagnostic::UnsupportedNumericInLetCondition,
132-
}),
133-
)));
134-
}
135-
136-
let else_arm = inner_expr
137-
.else_block
138-
.map(MatchArmWrapper::ElseClause)
139-
.unwrap_or(MatchArmWrapper::DefaultClause);
140-
let arms = vec![MatchArmWrapper::ConditionedArm(patterns, inner_expr), else_arm];
141-
142-
lower_match::lower_match_arms(
143-
ctx,
144-
builder,
145-
matched_expr_id,
146-
lowered_expr,
147-
arms,
148-
location,
149-
MatchKind::IfLet,
150-
)
151-
}
152-
153-
/// Lowers a [ConditionedExpr] recursively by iterating over the conditions and calling
154-
/// [lower_if_let_condition] or [lower_if_bool_condition].
155-
fn lower_conditioned_expr<'db>(
156-
ctx: &mut LoweringContext<'db, '_>,
157-
builder: &mut BlockBuilder<'db>,
158-
expr: &ConditionedExpr<'db, '_>,
159-
) -> LoweringResult<'db, LoweredExpr<'db>> {
160-
log::trace!(
161-
"Lowering a conditioned expression: {:?} (# of conditions: {})",
162-
expr.expr.debug(&ctx.expr_formatter),
163-
expr.conditions.len()
164-
);
165-
166-
// If there are no more conditions, we can simply lower the expression.
167-
if expr.conditions.is_empty() {
168-
return lower_expr(ctx, builder, expr.expr);
169-
}
170-
171-
match &expr.conditions[0] {
172-
Condition::Let(matched_expr_id, patterns) => {
173-
lower_if_let_condition(ctx, builder, *matched_expr_id, patterns, expr.remove_first())
174-
}
175-
Condition::BoolExpr(condition) => {
176-
lower_if_bool_condition(ctx, builder, *condition, expr.remove_first())
177-
}
178-
}
179-
}
180-
181-
/// Lowers a [ConditionedExpr] and seals the block. See [lower_conditioned_expr].
182-
pub fn lower_conditioned_expr_and_seal<'db>(
183-
ctx: &mut LoweringContext<'db, '_>,
184-
mut builder: BlockBuilder<'db>,
185-
expr: &ConditionedExpr<'db, '_>,
186-
) -> Maybe<SealedBlockBuilder<'db>> {
187-
let lowered_expr = lower_conditioned_expr(ctx, &mut builder, expr);
188-
lowered_expr_to_block_scope_end(ctx, builder, lowered_expr)
189-
}
190-
19123
/// Lowers an optional else block. If the else block is missing it is replaced with a block
19224
/// returning a unit.
19325
/// Returns the sealed block builder of the else block.

0 commit comments

Comments
 (0)