mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:00:11 +01:00
Addresses part of issue raised in https://github.com/carbon-language/carbon-lang/issues/7159 by implementing float.add & float.sub builtin for FloatLiteralValues The following code now compiles: ``` let a: f64 = 1.0 + 1.0; ``` Code handles case where operands are both decadic (base 10) and dyadic (base 2) real literals, with the result being whichever format results in smaller mantisssa. File tests assert equality by converting to f128, this can possibly be improved once CompareWith is implemented for FloatLiteral too. Assisted-By: Gemini
154 lines
3.9 KiB
Plaintext
154 lines
3.9 KiB
Plaintext
// 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";
|
|
|
|
import library "prelude/types/char_literal";
|
|
import library "prelude/types/int_literal";
|
|
import library "prelude/types/float_literal";
|
|
|
|
// TODO: Per the design, the associated type `Result` in each of these
|
|
// interfaces should have a default value of `Self`:
|
|
//
|
|
// default let Result: type = Self;
|
|
|
|
// TODO: Per the design, for each *With interface there should also be a
|
|
// non-With named constraint, such as:
|
|
//
|
|
// constraint Add {
|
|
// extend require impls AddWith(Self) where .Result = Self;
|
|
// }
|
|
|
|
// Addition: `a + b`.
|
|
interface AddWith(Other: type) {
|
|
let Result: type;
|
|
fn Op(self, other: Other) -> Result;
|
|
}
|
|
|
|
// Addition with assignment: `a += b`.
|
|
interface AddAssignWith(Other: type) {
|
|
fn Op(ref self, other: Other);
|
|
}
|
|
|
|
// Increment: `++a`.
|
|
interface Inc {
|
|
fn Op(ref self);
|
|
}
|
|
|
|
// Negation: `-a`.
|
|
interface Negate {
|
|
let Result: type;
|
|
fn Op(self) -> Result;
|
|
}
|
|
|
|
// Subtraction: `a - b`.
|
|
interface SubWith(Other: type) {
|
|
let Result: type;
|
|
fn Op(self, other: Other) -> Result;
|
|
}
|
|
|
|
// Subtraction with assignment: `a -= b`.
|
|
interface SubAssignWith(Other: type) {
|
|
fn Op(ref self, other: Other);
|
|
}
|
|
|
|
// Decrement: `--a`.
|
|
interface Dec {
|
|
fn Op(ref self);
|
|
}
|
|
|
|
// Multiplication: `a * b`.
|
|
interface MulWith(Other: type) {
|
|
let Result: type;
|
|
fn Op(self, other: Other) -> Result;
|
|
}
|
|
|
|
// Multiplication with assignment: `a *= b`.
|
|
interface MulAssignWith(Other: type) {
|
|
fn Op(ref self, other: Other);
|
|
}
|
|
|
|
// Division: `a / b`.
|
|
interface DivWith(Other: type) {
|
|
let Result: type;
|
|
fn Op(self, other: Other) -> Result;
|
|
}
|
|
|
|
// Division with assignment: `a /= b`.
|
|
interface DivAssignWith(Other: type) {
|
|
fn Op(ref self, other: Other);
|
|
}
|
|
|
|
// Modulo: `a % b`.
|
|
interface ModWith(Other: type) {
|
|
let Result: type;
|
|
fn Op(self, other: Other) -> Result;
|
|
}
|
|
|
|
// Modulo with assignment: `a %= b`.
|
|
interface ModAssignWith(Other: type) {
|
|
fn Op(ref self, other: Other);
|
|
}
|
|
|
|
|
|
// Operations for IntLiteral. These need to be here because IntLiteral has no
|
|
// associated library of its own.
|
|
impl IntLiteral as AddWith(Self) where .Result = Self {
|
|
fn Op(self, other: Self) -> Self = "int.sadd";
|
|
}
|
|
|
|
impl IntLiteral as DivWith(Self) where .Result = Self {
|
|
fn Op(self, other: Self) -> Self = "int.sdiv";
|
|
}
|
|
|
|
impl IntLiteral as ModWith(Self) where .Result = Self {
|
|
fn Op(self, other: Self) -> Self = "int.smod";
|
|
}
|
|
|
|
impl IntLiteral as MulWith(Self) where .Result = Self {
|
|
fn Op(self, other: Self) -> Self = "int.smul";
|
|
}
|
|
|
|
impl IntLiteral as Negate where .Result = Self {
|
|
fn Op(self) -> Self = "int.snegate";
|
|
}
|
|
|
|
impl IntLiteral as SubWith(Self) where .Result = Self {
|
|
fn Op(self, other: Self) -> Self = "int.ssub";
|
|
}
|
|
|
|
|
|
// Operations for CharLiteral. These need to be here because CharLiteral has no
|
|
// associated library of its own.
|
|
impl CharLiteral as AddWith(IntLiteral) where .Result = CharLiteral {
|
|
fn Op(self, other: IntLiteral) -> CharLiteral = "char_literal.add";
|
|
}
|
|
|
|
impl IntLiteral as AddWith(CharLiteral) where .Result = CharLiteral {
|
|
fn Op(self, other: CharLiteral) -> CharLiteral = "int.add_char_literal";
|
|
}
|
|
|
|
impl CharLiteral as SubWith(IntLiteral) where .Result = CharLiteral {
|
|
fn Op(self, other: IntLiteral) -> CharLiteral = "char_literal.sub_int";
|
|
}
|
|
|
|
impl CharLiteral as SubWith(Self) where .Result = IntLiteral {
|
|
fn Op(self, other: Self) -> IntLiteral = "char_literal.sub_char";
|
|
}
|
|
|
|
|
|
// Operations for FloatLiteral. These need to be here because FloatLiteral has no
|
|
// associated library of its own.
|
|
impl FloatLiteral as AddWith(Self) where .Result = Self {
|
|
fn Op(self, other: Self) -> Self = "float.add";
|
|
}
|
|
|
|
impl FloatLiteral as Negate where .Result = Self {
|
|
fn Op(self) -> Self = "float.negate";
|
|
}
|
|
|
|
impl FloatLiteral as SubWith(Self) where .Result = Self {
|
|
fn Op(self, other: Self) -> Self = "float.sub";
|
|
}
|