From 5a7b74cfd8db401a30707fc9dd4c519a97585099 Mon Sep 17 00:00:00 2001 From: Jasper Woudenberg Date: Mon, 1 Apr 2024 15:10:12 +0200 Subject: [PATCH] Add StructuralSort skeleton This is modeling Compare after Eq/NotEq, which I'm not entirely sure makes sense. Do we want to implement Sort for arbitrary types like records and lists? I'm going to get folks' thoughts on Zulip. --- crates/compiler/builtins/roc/List.roc | 4 ++++ crates/compiler/can/src/builtins.rs | 1 + crates/compiler/gen_llvm/src/llvm/lowlevel.rs | 3 +++ crates/compiler/gen_wasm/src/low_level.rs | 4 ++++ crates/compiler/module/src/low_level.rs | 2 ++ crates/compiler/module/src/symbol.rs | 3 ++- crates/compiler/mono/src/drop_specialization.rs | 2 +- crates/compiler/mono/src/inc_dec.rs | 2 +- 8 files changed, 18 insertions(+), 3 deletions(-) diff --git a/crates/compiler/builtins/roc/List.roc b/crates/compiler/builtins/roc/List.roc index 781a1c183b9..6e7f52fd420 100644 --- a/crates/compiler/builtins/roc/List.roc +++ b/crates/compiler/builtins/roc/List.roc @@ -1329,3 +1329,7 @@ iterBackwardsHelp = \list, state, f, prevIndex -> Sort implements compare : a, a -> [LessThan, Equal, GreaterThan] where a implements Sort + +# INTERNAL COMPILER USE ONLY: used to lower calls to `compare` to structural +# compare via the `Sort` low-level for derived types. +structuralCompare : a, a -> [LessThan, Equal, GreaterThan] diff --git a/crates/compiler/can/src/builtins.rs b/crates/compiler/can/src/builtins.rs index 8191eea3996..652d1763c65 100644 --- a/crates/compiler/can/src/builtins.rs +++ b/crates/compiler/can/src/builtins.rs @@ -216,6 +216,7 @@ map_symbol_to_lowlevel_and_arity! { And; BOOL_AND; 2, Or; BOOL_OR; 2, Not; BOOL_NOT; 1, + Compare; LIST_STRUCTURAL_COMPARE; 2, BoxExpr; BOX_BOX_FUNCTION; 1, UnboxExpr; BOX_UNBOX; 1, Unreachable; LIST_UNREACHABLE; 1, diff --git a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs index 8a4de54ee97..5015206f917 100644 --- a/crates/compiler/gen_llvm/src/llvm/lowlevel.rs +++ b/crates/compiler/gen_llvm/src/llvm/lowlevel.rs @@ -1269,6 +1269,9 @@ pub(crate) fn run_low_level<'a, 'ctx>( let bool_val = env.builder.new_build_not(arg.into_int_value(), "bool_not"); BasicValueEnum::IntValue(bool_val) } + Compare => { + panic!("TODO: implement this") + } Hash => { unimplemented!() } diff --git a/crates/compiler/gen_wasm/src/low_level.rs b/crates/compiler/gen_wasm/src/low_level.rs index 0bab4cdbc95..5836e01f6b9 100644 --- a/crates/compiler/gen_wasm/src/low_level.rs +++ b/crates/compiler/gen_wasm/src/low_level.rs @@ -2087,6 +2087,10 @@ impl<'a> LowLevelCall<'a> { Eq | NotEq => self.eq_or_neq(backend), + Compare => { + panic!("TODO: implement this") + } + BoxExpr | UnboxExpr => { unreachable!("The {:?} operation is turned into mono Expr", self.lowlevel) } diff --git a/crates/compiler/module/src/low_level.rs b/crates/compiler/module/src/low_level.rs index ccc706d6d35..7bd92ffb3dd 100644 --- a/crates/compiler/module/src/low_level.rs +++ b/crates/compiler/module/src/low_level.rs @@ -113,6 +113,7 @@ pub enum LowLevel { And, Or, Not, + Compare, Hash, PtrCast, PtrStore, @@ -352,6 +353,7 @@ map_symbol_to_lowlevel! { And <= BOOL_AND; Or <= BOOL_OR; Not <= BOOL_NOT; + Compare <= LIST_STRUCTURAL_COMPARE; Unreachable <= LIST_UNREACHABLE; DictPseudoSeed <= DICT_PSEUDO_SEED; } diff --git a/crates/compiler/module/src/symbol.rs b/crates/compiler/module/src/symbol.rs index 7c1486f484a..79b52586609 100644 --- a/crates/compiler/module/src/symbol.rs +++ b/crates/compiler/module/src/symbol.rs @@ -112,7 +112,7 @@ impl Symbol { self, // The `structuralEq` call used deriving structural equality, which will wrap the `Eq` // low-level implementation. - &Self::BOOL_STRUCTURAL_EQ + &Self::BOOL_STRUCTURAL_EQ | &Self::LIST_STRUCTURAL_COMPARE ) } @@ -1739,6 +1739,7 @@ define_builtins! { 16 SORT: "Sort" => { 0 LIST_SORT: "Sort" 1 LIST_COMPARE: "compare" + unexposed 2 LIST_STRUCTURAL_COMPARE: "structuralCompare" } num_modules: 17 // Keep this count up to date by hand! (TODO: see the mut_map! macro for how we could determine this count correctly in the macro) diff --git a/crates/compiler/mono/src/drop_specialization.rs b/crates/compiler/mono/src/drop_specialization.rs index a7b9fbfa074..da5c89cf2c6 100644 --- a/crates/compiler/mono/src/drop_specialization.rs +++ b/crates/compiler/mono/src/drop_specialization.rs @@ -1558,7 +1558,7 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC { | ListReleaseExcessCapacity | StrReleaseExcessCapacity => RC::Rc, - Eq | NotEq => RC::NoRc, + Eq | NotEq | Compare => RC::NoRc, And | Or | NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap | NumSubChecked | NumSubSaturated | NumMul | NumMulWrap | NumMulSaturated diff --git a/crates/compiler/mono/src/inc_dec.rs b/crates/compiler/mono/src/inc_dec.rs index fe3a9c9b001..34ec7ec9dba 100644 --- a/crates/compiler/mono/src/inc_dec.rs +++ b/crates/compiler/mono/src/inc_dec.rs @@ -1310,7 +1310,7 @@ pub(crate) fn lowlevel_borrow_signature(op: LowLevel) -> &'static [Ownership] { ListReleaseExcessCapacity => &[OWNED], StrReleaseExcessCapacity => &[OWNED], - Eq | NotEq => &[BORROWED, BORROWED], + Eq | NotEq | Compare => &[BORROWED, BORROWED], And | Or | NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap | NumSubChecked | NumSubSaturated | NumMul | NumMulWrap | NumMulSaturated