Skip to content

Commit 858a582

Browse files
authored
Merge pull request #1784 from cryspen/lean-floats
[Lean] Add basic support for floats
2 parents ef7848a + 27f35fa commit 858a582

File tree

7 files changed

+77
-9
lines changed

7 files changed

+77
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Changes to the Lean backend:
3232
- Rename `Result` monad to `RustM` to avoid confusion with Rust `Result` type (#1768)
3333
- Add support for shift-left (#1785)
3434
- Add support for default methods of traits (#1777)
35+
- Add support for floats (#1784)
3536
- Add support for pattern matching on constant literals (#1789)
3637
- Add support for binding subpatterns in match constructs (#1790)
3738

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Hax.Lib
2+
import Hax.Integers.Ops
3+
4+
abbrev f32 := Float32
5+
abbrev f64 := Float
6+
7+
macro "declare_float_ops" typeName:ident : command =>
8+
`(
9+
namespace $typeName
10+
11+
instance : HaxAdd $typeName where
12+
add := fun x y => x + y
13+
14+
instance : HaxSub $typeName where
15+
sub := fun x y => x - y
16+
17+
instance : HaxMul $typeName where
18+
mul := fun x y => x * y
19+
20+
instance : HaxDiv $typeName where
21+
div := fun x y => x / y
22+
23+
end $typeName
24+
)
25+
26+
declare_float_ops f32
27+
declare_float_ops f64
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
import Hax.Integers.Ops
22
import Hax.Integers.Spec
3+
import Hax.Float

rust-engine/src/backends/lean.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,6 @@ set_option linter.unusedVariables false
431431

432432
fn expr(&self, Expr { kind, ty, meta: _ }: &Expr) -> DocBuilder<A> {
433433
match &**kind {
434-
ExprKind::Literal(int_lit @ Literal::Int { .. }) => {
435-
docs![int_lit, reflow!(" : "), ty].parens().group()
436-
}
437434
ExprKind::If {
438435
condition,
439436
then,
@@ -478,6 +475,9 @@ set_option linter.unusedVariables false
478475
}
479476
}
480477
}
478+
ExprKind::Literal(numeric_lit @ (Literal::Float { .. } | Literal::Int { .. })) => {
479+
docs![numeric_lit, reflow!(" : "), ty].parens().group()
480+
}
481481
ExprKind::Literal(literal) => docs![literal],
482482
ExprKind::Array(exprs) => docs![
483483
"#v[",
@@ -788,7 +788,11 @@ set_option linter.unusedVariables false
788788
negative,
789789
kind: _,
790790
} => format!("{}{value}", if *negative { "-" } else { "" }),
791-
Literal::Float { .. } => emit_error!(issue 1715, "Unsupported Float literal"),
791+
Literal::Float {
792+
value,
793+
negative,
794+
kind: _,
795+
} => format!("{}{value}", if *negative { "-" } else { "" }),
792796
}]
793797
}
794798

@@ -805,7 +809,7 @@ set_option linter.unusedVariables false
805809
match primitive_ty {
806810
PrimitiveTy::Bool => docs!["Bool"],
807811
PrimitiveTy::Int(int_kind) => docs![int_kind],
808-
PrimitiveTy::Float(_) => emit_error!(issue 1715, "Unsupported Float type"),
812+
PrimitiveTy::Float(float_kind) => docs![float_kind],
809813
PrimitiveTy::Char => docs!["Char"],
810814
PrimitiveTy::Str => docs!["String"],
811815
}
@@ -828,6 +832,14 @@ set_option linter.unusedVariables false
828832
}]
829833
}
830834

835+
fn float_kind(&self, float_kind: &FloatKind) -> DocBuilder<A> {
836+
docs![match float_kind {
837+
FloatKind::F32 => "f32",
838+
FloatKind::F64 => "f64",
839+
_ => emit_error!(issue 1787, "The only supported float types are `f32` and `f64`."),
840+
}]
841+
}
842+
831843
fn generic_value(&self, generic_value: &GenericValue) -> DocBuilder<A> {
832844
match generic_value {
833845
GenericValue::Ty(ty) => docs![ty],
@@ -1248,10 +1260,6 @@ set_option linter.unusedVariables false
12481260
unreachable_by_invariant!(Drop_references)
12491261
}
12501262

1251-
fn float_kind(&self, _float_kind: &FloatKind) -> DocBuilder<A> {
1252-
emit_error!(issue 1715, "floats are unsupported")
1253-
}
1254-
12551263
fn dyn_trait_goal(&self, _dyn_trait_goal: &DynTraitGoal) -> DocBuilder<A> {
12561264
emit_error!(issue 1708, "`dyn` traits are unsupported")
12571265
}

test-harness/src/snapshots/toolchain__lean-tests into-lean.snap

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,20 @@ def Lean_tests.Loops.Errors.loop4
654654
| (Core.Ops.Control_flow.ControlFlow.Continue e)
655655
=> (pure (Core.Result.Result.Ok (Rust_primitives.Hax.Tuple2.mk e e)))
656656

657+
def Lean_tests.Floats.N : f32 := RustM.of_isOk (do (pure (1.0 : f32))) (by rfl)
658+
659+
def Lean_tests.Floats.test
660+
(_ : Rust_primitives.Hax.Tuple0)
661+
: RustM Rust_primitives.Hax.Tuple0
662+
:= do
663+
let l0 : f64 := (1.0 : f64);
664+
let l1 : f64 := (0.9 : f64);
665+
let l2 : f32 := (5.0 : f32);
666+
let l5 : f32 := Lean_tests.Floats.N;
667+
(pure Rust_primitives.Hax.Tuple0.mk)
668+
669+
def Lean_tests.Floats.f (x : f64) (y : f32) : RustM f32 := do (pure y)
670+
657671
inductive Lean_tests.Enums.E : Type
658672
| V1 : Lean_tests.Enums.E
659673
| V2 : Lean_tests.Enums.E

tests/lean-tests/src/floats.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Tests on floats
2+
#![allow(dead_code)]
3+
#![allow(unused_variables)]
4+
5+
const N: f32 = 1.0;
6+
7+
fn test() {
8+
let l0 = 1.0;
9+
let l1 = 0.9;
10+
let l2 = 5.0f32;
11+
let l5 = N;
12+
}
13+
14+
fn f(x: f64, y: f32) -> f32 {
15+
y
16+
}

tests/lean-tests/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
pub mod comments;
55
pub mod constants;
66
pub mod enums;
7+
pub mod floats;
78
pub mod ite;
89
pub mod loops;
910
pub mod matching;

0 commit comments

Comments
 (0)