arithmetic.carbon 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. package Core library "prelude/operators/arithmetic";
  5. import library "prelude/types/int_literal";
  6. // TODO: Per the design, the associated type `Result` in each of these
  7. // interfaces should have a default value of `Self`:
  8. //
  9. // default let Result:! type = Self;
  10. // TODO: Per the design, for each *With interface there should also be a
  11. // non-With named constraint, such as:
  12. //
  13. // constraint Add {
  14. // extend require impls AddWith(Self) where .Result = Self;
  15. // }
  16. // Addition: `a + b`.
  17. interface AddWith(Other:! type) {
  18. let Result:! type;
  19. fn Op[self: Self](other: Other) -> Result;
  20. }
  21. // Addition with assignment: `a += b`.
  22. interface AddAssignWith(Other:! type) {
  23. fn Op[ref self: Self](other: Other);
  24. }
  25. // Increment: `++a`.
  26. interface Inc {
  27. fn Op[ref self: Self]();
  28. }
  29. // Negation: `-a`.
  30. interface Negate {
  31. let Result:! type;
  32. fn Op[self: Self]() -> Result;
  33. }
  34. // Subtraction: `a - b`.
  35. interface SubWith(Other:! type) {
  36. let Result:! type;
  37. fn Op[self: Self](other: Other) -> Result;
  38. }
  39. // Subtraction with assignment: `a -= b`.
  40. interface SubAssignWith(Other:! type) {
  41. fn Op[ref self: Self](other: Other);
  42. }
  43. // Decrement: `--a`.
  44. interface Dec {
  45. fn Op[ref self: Self]();
  46. }
  47. // Multiplication: `a * b`.
  48. interface MulWith(Other:! type) {
  49. let Result:! type;
  50. fn Op[self: Self](other: Other) -> Result;
  51. }
  52. // Multiplication with assignment: `a *= b`.
  53. interface MulAssignWith(Other:! type) {
  54. fn Op[ref self: Self](other: Other);
  55. }
  56. // Division: `a / b`.
  57. interface DivWith(Other:! type) {
  58. let Result:! type;
  59. fn Op[self: Self](other: Other) -> Result;
  60. }
  61. // Division with assignment: `a /= b`.
  62. interface DivAssignWith(Other:! type) {
  63. fn Op[ref self: Self](other: Other);
  64. }
  65. // Modulo: `a % b`.
  66. interface ModWith(Other:! type) {
  67. let Result:! type;
  68. fn Op[self: Self](other: Other) -> Result;
  69. }
  70. // Modulo with assignment: `a %= b`.
  71. interface ModAssignWith(Other:! type) {
  72. fn Op[ref self: Self](other: Other);
  73. }
  74. // Operations for IntLiteral. These need to be here because IntLiteral has no
  75. // associated library of its own.
  76. impl IntLiteral() as AddWith(Self) where .Result = Self {
  77. fn Op[self: Self](other: Self) -> Self = "int.sadd";
  78. }
  79. impl IntLiteral() as DivWith(Self) where .Result = Self {
  80. fn Op[self: Self](other: Self) -> Self = "int.sdiv";
  81. }
  82. impl IntLiteral() as ModWith(Self) where .Result = Self {
  83. fn Op[self: Self](other: Self) -> Self = "int.smod";
  84. }
  85. impl IntLiteral() as MulWith(Self) where .Result = Self {
  86. fn Op[self: Self](other: Self) -> Self = "int.smul";
  87. }
  88. impl IntLiteral() as Negate where .Result = Self {
  89. fn Op[self: Self]() -> Self = "int.snegate";
  90. }
  91. impl IntLiteral() as SubWith(Self) where .Result = Self {
  92. fn Op[self: Self](other: Self) -> Self = "int.ssub";
  93. }