Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for operators on Core.IntLiteral. #4716

Open
wants to merge 12 commits into
base: trunk
Choose a base branch
from
3 changes: 1 addition & 2 deletions core/io.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ fn PrintChar(x: i32) -> i32 = "print.char";
fn ReadChar() -> i32 = "read.char";

// TODO: Change this to a global constant once they are fully supported.
// TODO: Use simply -1 once we support negate on an IntLiteral.
fn EOF() -> i32 { return -(1 as i32); }
fn EOF() -> i32 { return -1; }
29 changes: 29 additions & 0 deletions core/prelude/operators/arithmetic.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

package Core library "prelude/operators/arithmetic";

import library "prelude/types/int_literal";

// Addition: `a + b`.
interface Add {
fn Op[self: Self](other: Self) -> Self;
Expand Down Expand Up @@ -68,3 +70,30 @@ interface Mod {
interface ModAssign {
fn Op[addr self: Self*](other: Self);
}


// Operations for IntLiteral. These need to be here because IntLiteral has no
// associated library of its own.
impl IntLiteral() as Add {
fn Op[self: Self](other: Self) -> Self = "int.sadd";
}

impl IntLiteral() as Div {
fn Op[self: Self](other: Self) -> Self = "int.sdiv";
}

impl IntLiteral() as Mod {
fn Op[self: Self](other: Self) -> Self = "int.smod";
}

impl IntLiteral() as Mul {
fn Op[self: Self](other: Self) -> Self = "int.smul";
}

impl IntLiteral() as Negate {
fn Op[self: Self]() -> Self = "int.snegate";
}

impl IntLiteral() as Sub {
fn Op[self: Self](other: Self) -> Self = "int.ssub";
}
29 changes: 29 additions & 0 deletions core/prelude/operators/bitwise.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

package Core library "prelude/operators/bitwise";

import library "prelude/types/int_literal";

// Bit complement: `^a`.
interface BitComplement {
fn Op[self: Self]() -> Self;
Expand Down Expand Up @@ -58,3 +60,30 @@ interface RightShift {
interface RightShiftAssign {
fn Op[addr self: Self*](other: Self);
}


// Operations for IntLiteral. These need to be here because IntLiteral has no
// associated library of its own.
impl IntLiteral() as BitAnd {
fn Op[self: Self](other: Self) -> Self = "int.and";
}

impl IntLiteral() as BitComplement {
fn Op[self: Self]() -> Self = "int.complement";
}

impl IntLiteral() as BitOr {
fn Op[self: Self](other: Self) -> Self = "int.or";
}

impl IntLiteral() as BitXor {
fn Op[self: Self](other: Self) -> Self = "int.xor";
}

impl IntLiteral() as LeftShift {
fn Op[self: Self](other: Self) -> Self = "int.left_shift";
}

impl IntLiteral() as RightShift {
fn Op[self: Self](other: Self) -> Self = "int.right_shift";
}
17 changes: 17 additions & 0 deletions core/prelude/operators/comparison.carbon
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package Core library "prelude/operators/comparison";

export import library "prelude/types/bool";
import library "prelude/types/int_literal";

// Equality comparison: `a == b` and `a != b`.
interface Eq {
Expand All @@ -28,3 +29,19 @@ impl bool as Eq {
fn Equal[self: Self](other: Self) -> bool = "bool.eq";
fn NotEqual[self: Self](other: Self) -> bool = "bool.neq";
}


// Operations for IntLiteral. These need to be here because IntLiteral has no
// associated library of its own.
impl IntLiteral() as Eq {
fn Equal[self: Self](other: Self) -> bool = "int.eq";
fn NotEqual[self: Self](other: Self) -> bool = "int.neq";
}

impl IntLiteral() as Ordered {
// TODO: fn Compare
fn Less[self: Self](other: Self) -> bool = "int.less";
fn LessOrEquivalent[self: Self](other: Self) -> bool = "int.less_eq";
fn Greater[self: Self](other: Self) -> bool = "int.greater";
fn GreaterOrEquivalent[self: Self](other: Self) -> bool = "int.greater_eq";
}
11 changes: 8 additions & 3 deletions toolchain/base/int.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,14 @@ constexpr int32_t IntId::InvalidIndex = Invalid.AsIndex();
// an array of `APInt` values and represented as an index in the ID.
class IntStore {
public:
// The maximum supported bit width of an integer type.
// TODO: Pick a maximum size and document it in the design. For now
// we use 2^^23, because that's the largest size that LLVM supports.
static constexpr int MaxIntWidth = 1 << 23;

// Pick a canonical bit width for the provided number of significant bits.
static auto CanonicalBitWidth(int significant_bits) -> int;

// Accepts a signed `int64_t` and uses the mathematical signed integer value
// of it as the added integer value.
//
Expand Down Expand Up @@ -395,9 +403,6 @@ class IntStore {
return IntId::Invalid;
}

// Pick a canonical bit width for the provided number of significant bits.
static auto CanonicalBitWidth(int significant_bits) -> int;

// Canonicalize an incoming signed APInt to the correct bit width.
static auto CanonicalizeSigned(llvm::APInt value) -> llvm::APInt;

Expand Down
Loading
Loading