core: Extract codegen portion of gen_binop_expr
This allows binops to be generated internally using LLVM values as input. Required in a future change.
This commit is contained in:
parent
aa84cc425f
commit
deb325de4f
|
@ -1089,34 +1089,22 @@ pub fn gen_comprehension<'ctx, G: CodeGenerator>(
|
||||||
Ok(Some(list.as_ptr_value().into()))
|
Ok(Some(list.as_ptr_value().into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates LLVM IR for a [binary operator expression][expr].
|
/// Generates LLVM IR for a binary operator expression using the [`Type`] and
|
||||||
///
|
/// [LLVM value][`BasicValueEnum`] of the operands.
|
||||||
/// * `left` - The left-hand side of the binary operator.
|
pub fn gen_binop_expr_with_values<'ctx, G: CodeGenerator>(
|
||||||
/// * `op` - The operator applied on the operands.
|
|
||||||
/// * `right` - The right-hand side of the binary operator.
|
|
||||||
/// * `loc` - The location of the full expression.
|
|
||||||
/// * `is_aug_assign` - Whether the binary operator expression is also an assignment operator.
|
|
||||||
pub fn gen_binop_expr<'ctx, G: CodeGenerator>(
|
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
left: &Expr<Option<Type>>,
|
left: (&Option<Type>, BasicValueEnum<'ctx>),
|
||||||
op: &Operator,
|
op: &Operator,
|
||||||
right: &Expr<Option<Type>>,
|
right: (&Option<Type>, BasicValueEnum<'ctx>),
|
||||||
loc: Location,
|
loc: Location,
|
||||||
is_aug_assign: bool,
|
is_aug_assign: bool,
|
||||||
) -> Result<Option<ValueEnum<'ctx>>, String> {
|
) -> Result<Option<ValueEnum<'ctx>>, String> {
|
||||||
let ty1 = ctx.unifier.get_representative(left.custom.unwrap());
|
let (left_ty, left_val) = left;
|
||||||
let ty2 = ctx.unifier.get_representative(right.custom.unwrap());
|
let (right_ty, right_val) = right;
|
||||||
let left_val = if let Some(v) = generator.gen_expr(ctx, left)? {
|
|
||||||
v.to_basic_value_enum(ctx, generator, left.custom.unwrap())?
|
let ty1 = ctx.unifier.get_representative(left_ty.unwrap());
|
||||||
} else {
|
let ty2 = ctx.unifier.get_representative(right_ty.unwrap());
|
||||||
return Ok(None)
|
|
||||||
};
|
|
||||||
let right_val = if let Some(v) = generator.gen_expr(ctx, right)? {
|
|
||||||
v.to_basic_value_enum(ctx, generator, right.custom.unwrap())?
|
|
||||||
} else {
|
|
||||||
return Ok(None)
|
|
||||||
};
|
|
||||||
|
|
||||||
// we can directly compare the types, because we've got their representatives
|
// we can directly compare the types, because we've got their representatives
|
||||||
// which would be unchanged until further unification, which we would never do
|
// which would be unchanged until further unification, which we would never do
|
||||||
|
@ -1141,7 +1129,7 @@ pub fn gen_binop_expr<'ctx, G: CodeGenerator>(
|
||||||
);
|
);
|
||||||
Ok(Some(res.into()))
|
Ok(Some(res.into()))
|
||||||
} else {
|
} else {
|
||||||
let left_ty_enum = ctx.unifier.get_ty_immutable(left.custom.unwrap());
|
let left_ty_enum = ctx.unifier.get_ty_immutable(left_ty.unwrap());
|
||||||
let TypeEnum::TObj { fields, obj_id, .. } = left_ty_enum.as_ref() else {
|
let TypeEnum::TObj { fields, obj_id, .. } = left_ty_enum.as_ref() else {
|
||||||
unreachable!("must be tobj")
|
unreachable!("must be tobj")
|
||||||
};
|
};
|
||||||
|
@ -1161,7 +1149,7 @@ pub fn gen_binop_expr<'ctx, G: CodeGenerator>(
|
||||||
let signature = if let Some(call) = ctx.calls.get(&loc.into()) {
|
let signature = if let Some(call) = ctx.calls.get(&loc.into()) {
|
||||||
ctx.unifier.get_call_signature(*call).unwrap()
|
ctx.unifier.get_call_signature(*call).unwrap()
|
||||||
} else {
|
} else {
|
||||||
let left_enum_ty = ctx.unifier.get_ty_immutable(left.custom.unwrap());
|
let left_enum_ty = ctx.unifier.get_ty_immutable(left_ty.unwrap());
|
||||||
let TypeEnum::TObj { fields, .. } = left_enum_ty.as_ref() else {
|
let TypeEnum::TObj { fields, .. } = left_enum_ty.as_ref() else {
|
||||||
unreachable!("must be tobj")
|
unreachable!("must be tobj")
|
||||||
};
|
};
|
||||||
|
@ -1186,13 +1174,51 @@ pub fn gen_binop_expr<'ctx, G: CodeGenerator>(
|
||||||
generator
|
generator
|
||||||
.gen_call(
|
.gen_call(
|
||||||
ctx,
|
ctx,
|
||||||
Some((left.custom.unwrap(), left_val.into())),
|
Some((left_ty.unwrap(), left_val.into())),
|
||||||
(&signature, fun_id),
|
(&signature, fun_id),
|
||||||
vec![(None, right_val.into())],
|
vec![(None, right_val.into())],
|
||||||
).map(|f| f.map(Into::into))
|
).map(|f| f.map(Into::into))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generates LLVM IR for a [binary operator expression][expr].
|
||||||
|
///
|
||||||
|
/// * `left` - The left-hand side of the binary operator.
|
||||||
|
/// * `op` - The operator applied on the operands.
|
||||||
|
/// * `right` - The right-hand side of the binary operator.
|
||||||
|
/// * `loc` - The location of the full expression.
|
||||||
|
/// * `is_aug_assign` - Whether the binary operator expression is also an assignment operator.
|
||||||
|
pub fn gen_binop_expr<'ctx, G: CodeGenerator>(
|
||||||
|
generator: &mut G,
|
||||||
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
left: &Expr<Option<Type>>,
|
||||||
|
op: &Operator,
|
||||||
|
right: &Expr<Option<Type>>,
|
||||||
|
loc: Location,
|
||||||
|
is_aug_assign: bool,
|
||||||
|
) -> Result<Option<ValueEnum<'ctx>>, String> {
|
||||||
|
let left_val = if let Some(v) = generator.gen_expr(ctx, left)? {
|
||||||
|
v.to_basic_value_enum(ctx, generator, left.custom.unwrap())?
|
||||||
|
} else {
|
||||||
|
return Ok(None)
|
||||||
|
};
|
||||||
|
let right_val = if let Some(v) = generator.gen_expr(ctx, right)? {
|
||||||
|
v.to_basic_value_enum(ctx, generator, right.custom.unwrap())?
|
||||||
|
} else {
|
||||||
|
return Ok(None)
|
||||||
|
};
|
||||||
|
|
||||||
|
gen_binop_expr_with_values(
|
||||||
|
generator,
|
||||||
|
ctx,
|
||||||
|
(&left.custom, left_val),
|
||||||
|
op,
|
||||||
|
(&right.custom, right_val),
|
||||||
|
loc,
|
||||||
|
is_aug_assign,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// Generates code for a subscript expression on an `ndarray`.
|
/// Generates code for a subscript expression on an `ndarray`.
|
||||||
///
|
///
|
||||||
/// * `ty` - The `Type` of the `NDArray` elements.
|
/// * `ty` - The `Type` of the `NDArray` elements.
|
||||||
|
|
Loading…
Reference in New Issue