| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- // 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 Carbon api;
- // ----------------------
- // Conversion interfaces.
- // ----------------------
- // Explicitly convert `Self` to `T`.
- interface As(T:! Type) {
- fn Convert[me: Self]() -> T;
- }
- // Implicitly convert `Self` to `T`.
- interface ImplicitAs(T:! Type) {
- fn Convert[me: Self]() -> T;
- }
- // TODO: ImplicitAs(T) should extend As(T).
- impl forall [T:! Type, U:! ImplicitAs(T)] U as As(T) {
- fn Convert[me: Self]() -> T { return me.Convert(); }
- }
- // Every type implicitly converts to itself.
- impl forall [T:! Type] T as ImplicitAs(T) {
- fn Convert[me: Self]() -> T { return me; }
- }
- // TODO: Simplify this once we have variadics.
- // TODO: Should these be final?
- impl forall [U1:! Type, T1:! ImplicitAs(U1)]
- (T1,) as ImplicitAs((U1,)) {
- fn Convert[me: Self]() -> (U1,) {
- let (v1: T1,) = me;
- return (v1.Convert(),);
- }
- }
- impl forall [U1:! Type, U2:! Type, T1:! ImplicitAs(U1), T2:! ImplicitAs(U2)]
- (T1, T2) as ImplicitAs((U1, U2)) {
- fn Convert[me: Self]() -> (U1, U2) {
- let (v1: T1, v2: T2) = me;
- return (v1.Convert(), v2.Convert());
- }
- }
- impl forall [U1:! Type, U2:! Type, U3:! Type,
- T1:! ImplicitAs(U1), T2:! ImplicitAs(U2), T3:! ImplicitAs(U3)]
- (T1, T2, T3) as ImplicitAs((U1, U2, U3)) {
- fn Convert[me: Self]() -> (U1, U2, U3) {
- let (v1: T1, v2: T2, v3: T3) = me;
- return (v1.Convert(), v2.Convert(), v3.Convert());
- }
- }
- // ----------------------
- // Comparison interfaces.
- // ----------------------
- interface EqWith(U:! Type) {
- fn Equal[me: Self](other: U) -> bool;
- // TODO: NotEqual with default impl
- }
- // TODO: constraint Eq { ... }
- // TODO: Simplify this once we have variadics
- impl forall [T2:! Type, U2:! Type, T1:! EqWith(T2), U1:! EqWith(U2)]
- (T1, U1) as EqWith((T2, U2)) {
- fn Equal[me: Self](other: (T2, U2)) -> bool {
- let (l1: T1, l2: U1) = me;
- let (r1: T2, r2: U2) = other;
- return l1 == r1 and l2 == r2;
- }
- }
- impl i32 as EqWith(Self) {
- fn Equal[me: Self](other: Self) -> bool {
- return __intrinsic_int_eq(me, other);
- }
- }
- impl String as EqWith(Self) {
- fn Equal[me: Self](other: Self) -> bool {
- return __intrinsic_str_eq(me, other);
- }
- }
- // ----------------------
- // Arithmetic interfaces.
- // ----------------------
- interface Negate {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self]() -> Result;
- }
- interface AddWith(U:! Type) {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self](other: U) -> Result;
- }
- // TODO: constraint Add { ... }
- interface SubWith(U:! Type) {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self](other: U) -> Result;
- }
- // TODO: constraint Sub { ... }
- interface MulWith(U:! Type) {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self](other: U) -> Result;
- }
- // TODO: constraint Mul { ... }
- interface ModWith(U:! Type) {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self](other: U) -> Result;
- }
- // TODO: constraint Mod { ... }
- // Note, these impls use the builtin addition for i32.
- external impl i32 as Negate where .Result == i32 {
- fn Op[me: i32]() -> i32 { return -me; }
- }
- external impl i32 as AddWith(i32) where .Result == i32 {
- fn Op[me: i32](other: i32) -> i32 { return me + other; }
- }
- external impl i32 as SubWith(i32) where .Result == i32 {
- fn Op[me: i32](other: i32) -> i32 { return me - other; }
- }
- external impl i32 as MulWith(i32) where .Result == i32 {
- fn Op[me: i32](other: i32) -> i32 { return me * other; }
- }
- external impl i32 as ModWith(i32) where .Result == i32 {
- fn Op[me: i32](other: i32) -> i32 { return me % other; }
- }
- // ---------------------------------
- // Bitwise and bit-shift interfaces.
- // ---------------------------------
- // Unary `^`.
- interface BitComplement {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self]() -> Result;
- }
- // Binary `&`.
- interface BitAndWith(U:! Type) {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self](other: U) -> Result;
- }
- // TODO:
- // constraint BitAnd {
- // extends BitAndWith(Self) where .Result == Self;
- // }
- // Binary `|`.
- interface BitOrWith(U:! Type) {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self](other: U) -> Result;
- }
- // TODO:
- // constraint BitOr {
- // extends BitOrWith(Self) where .Result == Self;
- // }
- // Binary `^`.
- interface BitXorWith(U:! Type) {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self](other: U) -> Result;
- }
- // TODO:
- // constraint BitXor {
- // extends BitXorWith(Self) where .Result == Self;
- // }
- // Binary `<<`.
- interface LeftShiftWith(U:! Type) {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self](other: U) -> Result;
- }
- // TODO:
- // constraint LeftShift {
- // extends LeftShiftWith(Self) where .Result == Self;
- // }
- // Binary `>>`.
- interface RightShiftWith(U:! Type) {
- // TODO: = Self
- let Result:! Type;
- fn Op[me: Self](other: U) -> Result;
- }
- // TODO:
- // constraint RightShift {
- // extends RightShiftWith(Self) where .Result == Self;
- // }
- external impl i32 as BitComplement where .Result == i32 {
- fn Op[me: i32]() -> i32 {
- return __intrinsic_int_bit_complement(me);
- }
- }
- external impl i32 as BitAndWith(i32) where .Result == i32 {
- fn Op[me: i32](other: i32) -> i32 {
- return __intrinsic_int_bit_and(me, other);
- }
- }
- external impl i32 as BitOrWith(i32) where .Result == i32 {
- fn Op[me: i32](other: i32) -> i32 {
- return __intrinsic_int_bit_or(me, other);
- }
- }
- external impl i32 as BitXorWith(i32) where .Result == i32 {
- fn Op[me: i32](other: i32) -> i32 {
- return __intrinsic_int_bit_xor(me, other);
- }
- }
- external impl i32 as LeftShiftWith(i32) where .Result == i32 {
- fn Op[me: i32](other: i32) -> i32 {
- return __intrinsic_int_left_shift(me, other);
- }
- }
- external impl i32 as RightShiftWith(i32) where .Result == i32 {
- fn Op[me: i32](other: i32) -> i32 {
- return __intrinsic_int_right_shift(me, other);
- }
- }
- // ------------------------
- // Miscellaneous utilities.
- // ------------------------
- // Note that Print is experimental, and not part of an accepted proposal, but
- // is included here for printing state in tests.
- // TODO: Remove Print special casing once we have variadics or overloads.
- // fn Print(format_str: String) {
- // __intrinsic_print(format_str);
- // }
- fn Rand(low: i32, high: i32) -> i32{
- return __intrinsic_rand(low,high);
- }
- class Heap {
- fn New[T:! Type, me: Self](x : T) -> T* {
- return __intrinsic_new(x);
- }
- fn Delete[T:! Type, me: Self](p : T*) {
- __intrinsic_delete(p);
- }
- }
- var heap: Heap = {};
|