diff --git a/core/prelude/operators.carbon b/core/prelude/operators.carbon index 7854c9768716..e4fe994ec49a 100644 --- a/core/prelude/operators.carbon +++ b/core/prelude/operators.carbon @@ -4,101 +4,7 @@ package Core library "prelude/operators" api; -interface Add { - fn Op[self: Self](other: Self) -> Self; -} -interface AddAssign { - fn Op[addr self: Self*](other: Self); -} - -interface BitAnd { - fn Op[self: Self](other: Self) -> Self; -} -interface BitAndAssign { - fn Op[addr self: Self*](other: Self); -} - -interface BitComplement { - fn Op[self: Self]() -> Self; -} - -interface BitOr { - fn Op[self: Self](other: Self) -> Self; -} -interface BitOrAssign { - fn Op[addr self: Self*](other: Self); -} - -interface BitXor { - fn Op[self: Self](other: Self) -> Self; -} -interface BitXorAssign { - fn Op[addr self: Self*](other: Self); -} - -interface Dec { - fn Op[addr self: Self*](); -} - -interface Div { - fn Op[self: Self](other: Self) -> Self; -} -interface DivAssign { - fn Op[addr self: Self*](other: Self); -} - -interface Eq { - fn Equal[self: Self](other: Self) -> bool; - fn NotEqual[self: Self](other: Self) -> bool; -} - -interface Inc { - fn Op[addr self: Self*](); -} - -interface LeftShift { - fn Op[self: Self](other: Self) -> Self; -} -interface LeftShiftAssign { - fn Op[addr self: Self*](other: Self); -} - -interface Mod { - fn Op[self: Self](other: Self) -> Self; -} -interface ModAssign { - fn Op[addr self: Self*](other: Self); -} - -interface Mul { - fn Op[self: Self](other: Self) -> Self; -} -interface MulAssign { - fn Op[addr self: Self*](other: Self); -} - -interface Negate { - fn Op[self: Self]() -> Self; -} - -interface Ordered { - // TODO: fn Compare - fn Less[self: Self](other: Self) -> bool; - fn LessOrEquivalent[self: Self](other: Self) -> bool; - fn Greater[self: Self](other: Self) -> bool; - fn GreaterOrEquivalent[self: Self](other: Self) -> bool; -} - -interface RightShift { - fn Op[self: Self](other: Self) -> Self; -} -interface RightShiftAssign { - fn Op[addr self: Self*](other: Self); -} - -interface Sub { - fn Op[self: Self](other: Self) -> Self; -} -interface SubAssign { - fn Op[addr self: Self*](other: Self); -} +// TODO: Add a mechanism to re-export the names declared here. +import library "prelude/operators/arithmetic"; +import library "prelude/operators/bitwise"; +import library "prelude/operators/comparison"; diff --git a/core/prelude/operators/arithmetic.carbon b/core/prelude/operators/arithmetic.carbon new file mode 100644 index 000000000000..0113229bb68d --- /dev/null +++ b/core/prelude/operators/arithmetic.carbon @@ -0,0 +1,70 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +package Core library "prelude/operators/arithmetic" api; + +// Addition: `a + b`. +interface Add { + fn Op[self: Self](other: Self) -> Self; +} + +// Addition with assignment: `a += b`. +interface AddAssign { + fn Op[addr self: Self*](other: Self); +} + +// Increment: `++a`. +interface Inc { + fn Op[addr self: Self*](); +} + +// Negation: `-a`. +interface Negate { + fn Op[self: Self]() -> Self; +} + +// Subtraction: `a - b`. +interface Sub { + fn Op[self: Self](other: Self) -> Self; +} + +// Subtraction with assignment: `a -= b`. +interface SubAssign { + fn Op[addr self: Self*](other: Self); +} + +// Decrement: `--a`. +interface Dec { + fn Op[addr self: Self*](); +} + +// Multiplication: `a * b`. +interface Mul { + fn Op[self: Self](other: Self) -> Self; +} + +// Multiplication with assignment: `a *= b`. +interface MulAssign { + fn Op[addr self: Self*](other: Self); +} + +// Division: `a / b`. +interface Div { + fn Op[self: Self](other: Self) -> Self; +} + +// Division with assignment: `a /= b`. +interface DivAssign { + fn Op[addr self: Self*](other: Self); +} + +// Modulo: `a % b`. +interface Mod { + fn Op[self: Self](other: Self) -> Self; +} + +// Modulo with assignment: `a %= b`. +interface ModAssign { + fn Op[addr self: Self*](other: Self); +} diff --git a/core/prelude/operators/bitwise.carbon b/core/prelude/operators/bitwise.carbon new file mode 100644 index 000000000000..7f6c4a7177f2 --- /dev/null +++ b/core/prelude/operators/bitwise.carbon @@ -0,0 +1,60 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +package Core library "prelude/operators/bitwise" api; + +// Bit complement: `^a`. +interface BitComplement { + fn Op[self: Self]() -> Self; +} + +// Bitwise AND: `a & b`. +interface BitAnd { + fn Op[self: Self](other: Self) -> Self; +} + +// Bitwise AND with assignment: `a &= b`. +interface BitAndAssign { + fn Op[addr self: Self*](other: Self); +} + +// Bitwise OR: `a | b`. +interface BitOr { + fn Op[self: Self](other: Self) -> Self; +} + +// Bitwise OR with assignment: `a |= b`. +interface BitOrAssign { + fn Op[addr self: Self*](other: Self); +} + +// Bitwise XOR: `a ^ b`. +interface BitXor { + fn Op[self: Self](other: Self) -> Self; +} + +// Bitwise XOR with assignment: `a ^= b`. +interface BitXorAssign { + fn Op[addr self: Self*](other: Self); +} + +// Left shift: `a << b`. +interface LeftShift { + fn Op[self: Self](other: Self) -> Self; +} + +// Left shift with assignment: `a <<= b`. +interface LeftShiftAssign { + fn Op[addr self: Self*](other: Self); +} + +// Right shift: `a >> b`. +interface RightShift { + fn Op[self: Self](other: Self) -> Self; +} + +// Right shift with assignment: `a >>= b`. +interface RightShiftAssign { + fn Op[addr self: Self*](other: Self); +} diff --git a/core/prelude/operators/comparison.carbon b/core/prelude/operators/comparison.carbon new file mode 100644 index 000000000000..11bdc65426aa --- /dev/null +++ b/core/prelude/operators/comparison.carbon @@ -0,0 +1,20 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +package Core library "prelude/operators/comparison" api; + +// Equality comparison: `a == b` and `a != b`. +interface Eq { + fn Equal[self: Self](other: Self) -> bool; + fn NotEqual[self: Self](other: Self) -> bool; +} + +// Relational comparison: `a < b`, `a <= b`, `a > b`, `a >= b`. +interface Ordered { + // TODO: fn Compare + fn Less[self: Self](other: Self) -> bool; + fn LessOrEquivalent[self: Self](other: Self) -> bool; + fn Greater[self: Self](other: Self) -> bool; + fn GreaterOrEquivalent[self: Self](other: Self) -> bool; +} diff --git a/core/prelude/i32.carbon b/core/prelude/types/i32.carbon similarity index 69% rename from core/prelude/i32.carbon rename to core/prelude/types/i32.carbon index 365e5e310131..6256563c4ca4 100644 --- a/core/prelude/i32.carbon +++ b/core/prelude/types/i32.carbon @@ -2,21 +2,29 @@ // Exceptions. See /LICENSE for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -package Core library "i32" api; +package Core library "prelude/types/i32" api; import library "prelude/operators"; +// TODO: Remove these once prelude/operators re-exports their contents. +import library "prelude/operators/arithmetic"; +import library "prelude/operators/bitwise"; +import library "prelude/operators/comparison"; + impl i32 as Add { fn Op[self: Self](other: Self) -> Self = "int.add"; } impl i32 as AddAssign { fn Op[addr self: Self*](other: Self) { - *self = *self + other; + // TODO: Once operator lookup works inside Core. + // *self = *self + other; + *self = self->(Add.Op)(other); } } impl i32 as Inc { fn Op[addr self: Self*]() { - *self += 1; + // *self += 1; + self->(AddAssign.Op)(1); } } @@ -25,7 +33,8 @@ impl i32 as BitAnd { } impl i32 as BitAndAssign { fn Op[addr self: Self*](other: Self) { - *self = *self & other; + // *self = *self & other; + *self = self->(BitAnd.Op)(other); } } @@ -38,7 +47,8 @@ impl i32 as BitOr { } impl i32 as BitOrAssign { fn Op[addr self: Self*](other: Self) { - *self = *self | other; + // *self = *self | other; + *self = self->(BitOr.Op)(other); } } @@ -47,7 +57,8 @@ impl i32 as BitXor { } impl i32 as BitXorAssign { fn Op[addr self: Self*](other: Self) { - *self = *self ^ other; + // *self = *self ^ other; + *self = self->(BitXor.Op)(other); } } @@ -56,7 +67,8 @@ impl i32 as Div { } impl i32 as DivAssign { fn Op[addr self: Self*](other: Self) { - *self = *self / other; + // *self = *self / other; + *self = self->(Div.Op)(other); } } @@ -70,7 +82,8 @@ impl i32 as LeftShift { } impl i32 as LeftShiftAssign { fn Op[addr self: Self*](other: Self) { - *self = *self << other; + // *self = *self << other; + *self = self->(LeftShift.Op)(other); } } @@ -79,7 +92,8 @@ impl i32 as Mod { } impl i32 as ModAssign { fn Op[addr self: Self*](other: Self) { - *self = *self % other; + // *self = *self % other; + *self = self->(Mod.Op)(other); } } @@ -88,7 +102,8 @@ impl i32 as Mul { } impl i32 as MulAssign { fn Op[addr self: Self*](other: Self) { - *self = *self * other; + // *self = *self * other; + *self = self->(Mul.Op)(other); } } @@ -109,7 +124,8 @@ impl i32 as RightShift { } impl i32 as RightShiftAssign { fn Op[addr self: Self*](other: Self) { - *self = *self >> other; + // *self = *self >> other; + *self = self->(RightShift.Op)(other); } } @@ -118,11 +134,13 @@ impl i32 as Sub { } impl i32 as SubAssign { fn Op[addr self: Self*](other: Self) { - *self = *self - other; + // *self = *self - other; + *self = self->(Sub.Op)(other); } } impl i32 as Dec { fn Op[addr self: Self*]() { - *self -= 1; + // *self -= 1; + self->(SubAssign.Op)(1); } } diff --git a/examples/sieve.carbon b/examples/sieve.carbon index 921961f22daa..21fc616dde3c 100644 --- a/examples/sieve.carbon +++ b/examples/sieve.carbon @@ -4,11 +4,12 @@ // Compute and return the number of primes less than 1000. -import Core library "operators"; +import Core library "prelude/operators/arithmetic"; +import Core library "prelude/operators/comparison"; -// TODO: Copied from i32.carbon. +// TODO: Copied from core/prelude/types/i32.carbon. // Remove the following, once we do cross-file impl lookup. -// import Core library "i32"; +// import Core library "prelude/types/i32"; impl i32 as Core.Add { fn Op[self: Self](other: Self) -> Self = "int.add"; @@ -24,37 +25,6 @@ impl i32 as Core.Inc { } } -impl i32 as Core.BitAnd { - fn Op[self: Self](other: Self) -> Self = "int.and"; -} -impl i32 as Core.BitAndAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self & other; - } -} - -impl i32 as Core.BitComplement { - fn Op[self: Self]() -> Self = "int.complement"; -} - -impl i32 as Core.BitOr { - fn Op[self: Self](other: Self) -> Self = "int.or"; -} -impl i32 as Core.BitOrAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self | other; - } -} - -impl i32 as Core.BitXor { - fn Op[self: Self](other: Self) -> Self = "int.xor"; -} -impl i32 as Core.BitXorAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self ^ other; - } -} - impl i32 as Core.Div { fn Op[self: Self](other: Self) -> Self = "int.div"; } @@ -69,15 +39,6 @@ impl i32 as Core.Eq { fn NotEqual[self: Self](other: Self) -> bool = "int.neq"; } -impl i32 as Core.LeftShift { - fn Op[self: Self](other: Self) -> Self = "int.left_shift"; -} -impl i32 as Core.LeftShiftAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self << other; - } -} - impl i32 as Core.Mod { fn Op[self: Self](other: Self) -> Self = "int.mod"; } @@ -108,15 +69,6 @@ impl i32 as Core.Ordered { fn GreaterOrEquivalent[self: Self](other: Self) -> bool = "int.greater_eq"; } -impl i32 as Core.RightShift { - fn Op[self: Self](other: Self) -> Self = "int.right_shift"; -} -impl i32 as Core.RightShiftAssign { - fn Op[addr self: Self*](other: Self) { - *self = *self >> other; - } -} - impl i32 as Core.Sub { fn Op[self: Self](other: Self) -> Self = "int.sub"; }