Add support for bitwise operators. (#1809)

Following #1191, add initial support for bitwise operators. Support for both
integer operations and for operator overloading via the interfaces specified in
#1191 is provided.

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
Richard Smith
2022-07-31 15:25:10 -07:00
committed by GitHub
co-authored by Jon Ross-Perkins
parent 52f80c25ab
commit ef96f60425
22 changed files with 770 additions and 266 deletions
+47 -28
View File
@@ -32,6 +32,12 @@ auto IntrinsicExpression::FindIntrinsic(std::string_view name,
{"delete", Intrinsic::Dealloc},
{"rand", Intrinsic::Rand},
{"int_eq", Intrinsic::IntEq},
{"int_bit_complement", Intrinsic::IntBitComplement},
{"int_bit_and", Intrinsic::IntBitAnd},
{"int_bit_or", Intrinsic::IntBitOr},
{"int_bit_xor", Intrinsic::IntBitXor},
{"int_left_shift", Intrinsic::IntLeftShift},
{"int_right_shift", Intrinsic::IntRightShift},
{"str_eq", Intrinsic::StrEq}});
name.remove_prefix(std::strlen("__intrinsic_"));
auto it = intrinsic_map.find(name);
@@ -41,6 +47,36 @@ auto IntrinsicExpression::FindIntrinsic(std::string_view name,
return it->second;
}
auto IntrinsicExpression::name() const -> std::string_view {
switch (intrinsic()) {
case IntrinsicExpression::Intrinsic::Print:
// TODO: Remove Print special casing once we have variadics or overloads.
return "Print";
case IntrinsicExpression::Intrinsic::Alloc:
return "__intrinsic_new";
case IntrinsicExpression::Intrinsic::Dealloc:
return "__intrinsic_delete";
case IntrinsicExpression::Intrinsic::Rand:
return "__intrinsic_rand";
case IntrinsicExpression::Intrinsic::IntEq:
return "__intrinsic_int_eq";
case IntrinsicExpression::Intrinsic::IntBitComplement:
return "__intrinsic_int_bit_complement";
case IntrinsicExpression::Intrinsic::IntBitAnd:
return "__intrinsic_int_bit_and";
case IntrinsicExpression::Intrinsic::IntBitOr:
return "__intrinsic_int_bit_or";
case IntrinsicExpression::Intrinsic::IntBitXor:
return "__intrinsic_int_bit_xor";
case IntrinsicExpression::Intrinsic::IntLeftShift:
return "__intrinsic_int_left_shift";
case IntrinsicExpression::Intrinsic::IntRightShift:
return "__intrinsic_int_right_shift";
case IntrinsicExpression::Intrinsic::StrEq:
return "__intrinsic_str_eq";
}
}
auto ExpressionFromParenContents(
Nonnull<Arena*> arena, SourceLocation source_loc,
const ParenContents<Expression>& paren_contents) -> Nonnull<Expression*> {
@@ -67,8 +103,17 @@ auto ToString(Operator op) -> std::string_view {
case Operator::As:
return "as";
case Operator::AddressOf:
case Operator::Combine:
case Operator::BitwiseAnd:
return "&";
case Operator::BitwiseOr:
return "|";
case Operator::BitwiseXor:
case Operator::Complement:
return "^";
case Operator::BitShiftLeft:
return "<<";
case Operator::BitShiftRight:
return ">>";
case Operator::Neg:
case Operator::Sub:
return "-";
@@ -173,33 +218,7 @@ void Expression::Print(llvm::raw_ostream& out) const {
}
case ExpressionKind::IntrinsicExpression: {
const auto& iexp = cast<IntrinsicExpression>(*this);
// TODO: Remove Print special casing once we have variadics or overloads.
if (iexp.intrinsic() == IntrinsicExpression::Intrinsic::Print) {
out << "Print" << iexp.args();
break;
}
out << "intrinsic_";
switch (iexp.intrinsic()) {
case IntrinsicExpression::Intrinsic::Print:
out << "print";
break;
case IntrinsicExpression::Intrinsic::Alloc:
out << "new";
break;
case IntrinsicExpression::Intrinsic::Dealloc:
out << "delete";
break;
case IntrinsicExpression::Intrinsic::Rand:
out << "rand";
break;
case IntrinsicExpression::Intrinsic::IntEq:
out << "int_eq";
break;
case IntrinsicExpression::Intrinsic::StrEq:
out << "str_eq";
}
out << iexp.args();
out << iexp.name() << iexp.args();
break;
}
case ExpressionKind::IfExpression: {