Skip to content

Commit

Permalink
Add core library with operator interface definitions and an example p…
Browse files Browse the repository at this point in the history
…rogram. (carbon-language#3856)

This is almost certainly not how we'll want these to be organized, and
if the examples/ directory is kept it should have BUILD files. But this
at least lets me park these files somewhere that's more global than my
own checkout.
  • Loading branch information
zygoloid authored Apr 4, 2024
1 parent 36c05bd commit 2b2f27a
Show file tree
Hide file tree
Showing 3 changed files with 393 additions and 0 deletions.
128 changes: 128 additions & 0 deletions core/prelude/i32.carbon
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// 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 "i32" api;

import library "prelude/operators";

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;
}
}
impl i32 as Inc {
fn Op[addr self: Self*]() {
*self += 1;
}
}

impl i32 as BitAnd {
fn Op[self: Self](other: Self) -> Self = "int.and";
}
impl i32 as BitAndAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self + other;
}
}

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

impl i32 as BitOr {
fn Op[self: Self](other: Self) -> Self = "int.or";
}
impl i32 as BitOrAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self + other;
}
}

impl i32 as BitXor {
fn Op[self: Self](other: Self) -> Self = "int.xor";
}
impl i32 as BitXorAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self ^ other;
}
}

impl i32 as Div {
fn Op[self: Self](other: Self) -> Self = "int.div";
}
impl i32 as DivAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self / other;
}
}

impl i32 as Eq {
fn Equal[self: Self](other: Self) -> bool = "int.eq";
fn NotEqual[self: Self](other: Self) -> bool = "int.neq";
}

impl i32 as LeftShift {
fn Op[self: Self](other: Self) -> Self = "int.left_shift";
}
impl i32 as LeftShiftAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self << other;
}
}

impl i32 as Mod {
fn Op[self: Self](other: Self) -> Self = "int.mod";
}
impl i32 as ModAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self % other;
}
}

impl i32 as Mul {
fn Op[self: Self](other: Self) -> Self = "int.mul";
}
impl i32 as MulAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self * other;
}
}

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

impl i32 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";
}

impl i32 as RightShift {
fn Op[self: Self](other: Self) -> Self = "int.right_shift";
}
impl i32 as RightShiftAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self >> other;
}
}

impl i32 as Sub {
fn Op[self: Self](other: Self) -> Self = "int.sub";
}
impl i32 as SubAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self - other;
}
}
impl i32 as Dec {
fn Op[addr self: Self*]() {
*self -= 1;
}
}
104 changes: 104 additions & 0 deletions core/prelude/operators.carbon
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// 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" 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);
}
161 changes: 161 additions & 0 deletions examples/sieve.carbon
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// 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

// Compute and return the number of primes less than 1000.

import Core library "operators";

// TODO: Copied from i32.carbon.
// Remove the following, once we do cross-file impl lookup.
// import Core library "i32";

impl i32 as Core.Add {
fn Op[self: Self](other: Self) -> Self = "int.add";
}
impl i32 as Core.AddAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self + other;
}
}
impl i32 as Core.Inc {
fn Op[addr self: Self*]() {
*self += 1;
}
}

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";
}
impl i32 as Core.DivAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self / other;
}
}

impl i32 as Core.Eq {
fn Equal[self: Self](other: Self) -> bool = "int.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";
}
impl i32 as Core.ModAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self % other;
}
}

impl i32 as Core.Mul {
fn Op[self: Self](other: Self) -> Self = "int.mul";
}
impl i32 as Core.MulAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self * other;
}
}

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

impl i32 as Core.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";
}

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";
}
impl i32 as Core.SubAssign {
fn Op[addr self: Self*](other: Self) {
*self = *self - other;
}
}
impl i32 as Core.Dec {
fn Op[addr self: Self*]() {
*self -= 1;
}
}

// ---

fn Run() -> i32 {
var is_prime: [bool; 1000];

// TODO: `for` loop.
var n: i32 = 0;
while (n < 1000) {
is_prime[n] = true;
++n;
}

var number_of_primes: i32 = 0;
n = 2;
while (n < 1000) {
if (is_prime[n]) {
++number_of_primes;
var k: i32 = 2 * n;
while (k < 1000) {
is_prime[k] = false;
k += n;
}
}
++n;
}

return number_of_primes;
}

0 comments on commit 2b2f27a

Please sign in to comment.