Skip to content
Snippets Groups Projects
Commit ffbb263d authored by Russel Arbore's avatar Russel Arbore
Browse files

Cast node

parent e7b1e790
No related branches found
No related tags found
1 merge request!14Cast node
......@@ -614,6 +614,7 @@ fn emit_llvm_for_node(
todo!()
}
}
UnaryOperator::Cast(_) => todo!(),
},
Node::Binary { left, right, op } => {
let opcode = match op {
......
......@@ -225,6 +225,7 @@ pub enum Node {
pub enum UnaryOperator {
Not,
Neg,
Cast(TypeID),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
......@@ -1005,6 +1006,7 @@ impl UnaryOperator {
match self {
UnaryOperator::Not => "Not",
UnaryOperator::Neg => "Neg",
UnaryOperator::Cast(_) => "Cast",
}
}
......@@ -1012,6 +1014,7 @@ impl UnaryOperator {
match self {
UnaryOperator::Not => "not",
UnaryOperator::Neg => "neg",
UnaryOperator::Cast(_) => "cast",
}
}
}
......
......@@ -625,6 +625,17 @@ fn typeflow(
));
}
}
UnaryOperator::Cast(dst_id) => {
let src_ty = &types[id.idx()];
let dst_ty = &types[dst_id.idx()];
if cast_compatible(src_ty, dst_ty) {
return Concrete(*dst_id);
} else {
return Error(String::from(
"Cast unary node has incompatible input and output types.",
));
}
}
}
}
......@@ -940,3 +951,12 @@ pub fn fork_join_map(
}
fork_join_map
}
/*
* Determine if a given cast conversion is valid.
*/
pub fn cast_compatible(src_ty: &Type, dst_ty: &Type) -> bool {
// Can convert between any pair of primitive types, as long as the cast is
// not from a floating point type to a boolean type.
src_ty.is_primitive() && dst_ty.is_primitive() && !(src_ty.is_float() && dst_ty.is_bool())
}
......@@ -444,22 +444,22 @@ fn ccp_flow_function(
} = inputs[input.idx()];
let new_constant = if let ConstantLattice::Constant(cons) = constant {
let new_cons = match (op, cons) {
(UnaryOperator::Not, Constant::Boolean(val)) => Constant::Boolean(!val),
(UnaryOperator::Not, Constant::Integer8(val)) => Constant::Integer8(!val),
(UnaryOperator::Not, Constant::Integer16(val)) => Constant::Integer16(!val),
(UnaryOperator::Not, Constant::Integer32(val)) => Constant::Integer32(!val),
(UnaryOperator::Not, Constant::Integer64(val)) => Constant::Integer64(!val),
(UnaryOperator::Neg, Constant::Integer8(val)) => Constant::Integer8(-val),
(UnaryOperator::Neg, Constant::Integer16(val)) => Constant::Integer16(-val),
(UnaryOperator::Neg, Constant::Integer32(val)) => Constant::Integer32(-val),
(UnaryOperator::Neg, Constant::Integer64(val)) => Constant::Integer64(-val),
(UnaryOperator::Neg, Constant::Float32(val)) => Constant::Float32(-val),
(UnaryOperator::Neg, Constant::Float64(val)) => Constant::Float64(-val),
(UnaryOperator::Neg, Constant::Zero(id)) => Constant::Zero(*id),
match (op, cons) {
(UnaryOperator::Not, Constant::Boolean(val)) => ConstantLattice::Constant(Constant::Boolean(!val)),
(UnaryOperator::Not, Constant::Integer8(val)) => ConstantLattice::Constant(Constant::Integer8(!val)),
(UnaryOperator::Not, Constant::Integer16(val)) => ConstantLattice::Constant(Constant::Integer16(!val)),
(UnaryOperator::Not, Constant::Integer32(val)) => ConstantLattice::Constant(Constant::Integer32(!val)),
(UnaryOperator::Not, Constant::Integer64(val)) => ConstantLattice::Constant(Constant::Integer64(!val)),
(UnaryOperator::Neg, Constant::Integer8(val)) => ConstantLattice::Constant(Constant::Integer8(-val)),
(UnaryOperator::Neg, Constant::Integer16(val)) => ConstantLattice::Constant(Constant::Integer16(-val)),
(UnaryOperator::Neg, Constant::Integer32(val)) => ConstantLattice::Constant(Constant::Integer32(-val)),
(UnaryOperator::Neg, Constant::Integer64(val)) => ConstantLattice::Constant(Constant::Integer64(-val)),
(UnaryOperator::Neg, Constant::Float32(val)) => ConstantLattice::Constant(Constant::Float32(-val)),
(UnaryOperator::Neg, Constant::Float64(val)) => ConstantLattice::Constant(Constant::Float64(-val)),
(UnaryOperator::Neg, Constant::Zero(id)) => ConstantLattice::Constant(Constant::Zero(*id)),
(UnaryOperator::Cast(_), _) => ConstantLattice::Bottom,
_ => panic!("Unsupported combination of unary operation and constant value. Did typechecking succeed?")
};
ConstantLattice::Constant(new_cons)
}
} else {
constant.clone()
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment