core/codegen/expr: WIP - Split unaryop
parent
1f0ac6341d
commit
0537e816a5
|
@ -1291,6 +1291,67 @@ pub fn gen_binop_expr<'ctx, G: CodeGenerator>(
|
|||
)
|
||||
}
|
||||
|
||||
pub fn gen_unaryop_expr_with_values<'ctx, G: CodeGenerator>(
|
||||
_generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
op: &ast::Unaryop,
|
||||
operand: (&Option<Type>, BasicValueEnum<'ctx>),
|
||||
) -> Result<Option<ValueEnum<'ctx>>, String> {
|
||||
let (ty, val) = operand;
|
||||
let ty = ctx.unifier.get_representative(ty.unwrap());
|
||||
|
||||
Ok(Some(if ty == ctx.primitives.bool {
|
||||
let val = val.into_int_value();
|
||||
match op {
|
||||
ast::Unaryop::Invert | ast::Unaryop::Not => {
|
||||
ctx.builder.build_not(val, "not").map(Into::into).unwrap()
|
||||
}
|
||||
_ => val.into(),
|
||||
}
|
||||
} else if [ctx.primitives.int32, ctx.primitives.int64, ctx.primitives.uint32, ctx.primitives.uint64].contains(&ty) {
|
||||
let val = val.into_int_value();
|
||||
match op {
|
||||
ast::Unaryop::USub => ctx.builder.build_int_neg(val, "neg").map(Into::into).unwrap(),
|
||||
ast::Unaryop::Invert => ctx.builder.build_not(val, "not").map(Into::into).unwrap(),
|
||||
ast::Unaryop::Not => ctx.builder.build_xor(val, val.get_type().const_all_ones(), "not").map(Into::into).unwrap(),
|
||||
ast::Unaryop::UAdd => val.into(),
|
||||
}
|
||||
} else if ty == ctx.primitives.float {
|
||||
let val = val.into_float_value();
|
||||
match op {
|
||||
ast::Unaryop::USub => ctx.builder.build_float_neg(val, "neg").map(Into::into).unwrap(),
|
||||
ast::Unaryop::Not => ctx
|
||||
.builder
|
||||
.build_float_compare(
|
||||
inkwell::FloatPredicate::OEQ,
|
||||
val,
|
||||
val.get_type().const_zero(),
|
||||
"not",
|
||||
)
|
||||
.map(Into::into)
|
||||
.unwrap(),
|
||||
_ => val.into(),
|
||||
}
|
||||
} else {
|
||||
unimplemented!()
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn gen_unaryop_expr<'ctx, G: CodeGenerator>(
|
||||
generator: &mut G,
|
||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||
op: &ast::Unaryop,
|
||||
operand: &Expr<Option<Type>>,
|
||||
) -> Result<Option<ValueEnum<'ctx>>, String> {
|
||||
let val = if let Some(v) = generator.gen_expr(ctx, operand)? {
|
||||
v.to_basic_value_enum(ctx, generator, operand.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
|
||||
gen_unaryop_expr_with_values(generator, ctx, op, (&operand.custom, val))
|
||||
}
|
||||
|
||||
/// Generates code for a subscript expression on an `ndarray`.
|
||||
///
|
||||
/// * `ty` - The `Type` of the `NDArray` elements.
|
||||
|
@ -1667,47 +1728,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
|
|||
return gen_binop_expr(generator, ctx, left, op, right, expr.location, false);
|
||||
}
|
||||
ExprKind::UnaryOp { op, operand } => {
|
||||
let ty = ctx.unifier.get_representative(operand.custom.unwrap());
|
||||
let val = if let Some(v) = generator.gen_expr(ctx, operand)? {
|
||||
v.to_basic_value_enum(ctx, generator, operand.custom.unwrap())?
|
||||
} else {
|
||||
return Ok(None)
|
||||
};
|
||||
if ty == ctx.primitives.bool {
|
||||
let val = val.into_int_value();
|
||||
match op {
|
||||
ast::Unaryop::Invert | ast::Unaryop::Not => {
|
||||
ctx.builder.build_not(val, "not").map(Into::into).unwrap()
|
||||
}
|
||||
_ => val.into(),
|
||||
}
|
||||
} else if [ctx.primitives.int32, ctx.primitives.int64, ctx.primitives.uint32, ctx.primitives.uint64].contains(&ty) {
|
||||
let val = val.into_int_value();
|
||||
match op {
|
||||
ast::Unaryop::USub => ctx.builder.build_int_neg(val, "neg").map(Into::into).unwrap(),
|
||||
ast::Unaryop::Invert => ctx.builder.build_not(val, "not").map(Into::into).unwrap(),
|
||||
ast::Unaryop::Not => ctx.builder.build_xor(val, val.get_type().const_all_ones(), "not").map(Into::into).unwrap(),
|
||||
ast::Unaryop::UAdd => val.into(),
|
||||
}
|
||||
} else if ty == ctx.primitives.float {
|
||||
let val = val.into_float_value();
|
||||
match op {
|
||||
ast::Unaryop::USub => ctx.builder.build_float_neg(val, "neg").map(Into::into).unwrap(),
|
||||
ast::Unaryop::Not => ctx
|
||||
.builder
|
||||
.build_float_compare(
|
||||
inkwell::FloatPredicate::OEQ,
|
||||
val,
|
||||
val.get_type().const_zero(),
|
||||
"not",
|
||||
)
|
||||
.map(Into::into)
|
||||
.unwrap(),
|
||||
_ => val.into(),
|
||||
}
|
||||
} else {
|
||||
unimplemented!()
|
||||
}
|
||||
return gen_unaryop_expr(generator, ctx, op, operand)
|
||||
}
|
||||
ExprKind::Compare { left, ops, comparators } => {
|
||||
let cmp_val = izip!(chain(once(left.as_ref()), comparators.iter()), comparators.iter(), ops.iter(),)
|
||||
|
|
Loading…
Reference in New Issue