Просмотр исходного кода

Add core library with operator interface definitions and an example program. (#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.
Richard Smith 2 лет назад
Родитель
Сommit
2b2f27a9ce
3 измененных файлов с 393 добавлено и 0 удалено
  1. 128 0
      core/prelude/i32.carbon
  2. 104 0
      core/prelude/operators.carbon
  3. 161 0
      examples/sieve.carbon

+ 128 - 0
core/prelude/i32.carbon

@@ -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 - 0
core/prelude/operators.carbon

@@ -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 - 0
examples/sieve.carbon

@@ -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;
+}