From 43e71f2ee933e25f5a1f45243af8be6c8290724c Mon Sep 17 00:00:00 2001 From: Folkert Date: Sun, 21 Feb 2021 16:07:35 +0100 Subject: [PATCH] int cast --- compiler/builtins/src/std.rs | 6 ++++++ compiler/can/src/builtins.rs | 7 +++++++ compiler/gen/src/llvm/build.rs | 10 ++++++++++ compiler/module/src/low_level.rs | 1 + compiler/module/src/symbol.rs | 2 ++ compiler/mono/src/borrow.rs | 2 +- 6 files changed, 27 insertions(+), 1 deletion(-) diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index 084edc1cd4..5a3b499dd7 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -360,6 +360,12 @@ pub fn types() -> MutMap { ), ); + // intCast : Int a -> Int b + add_type( + Symbol::NUM_INT_CAST, + top_level_function(vec![int_type(flex(TVAR1))], Box::new(int_type(flex(TVAR2)))), + ); + // rem : Int a, Int a -> Result (Int a) [ DivByZero ]* add_type( Symbol::NUM_REM, diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index c8516d26ca..af38527fcc 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -156,6 +156,7 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option NUM_SHIFT_LEFT=> num_shift_left_by, NUM_SHIFT_RIGHT => num_shift_right_by, NUM_SHIFT_RIGHT_ZERO_FILL => num_shift_right_zf_by, + NUM_INT_CAST=> num_int_cast, RESULT_MAP => result_map, RESULT_MAP_ERR => result_map_err, RESULT_WITH_DEFAULT => result_with_default, @@ -285,6 +286,7 @@ pub fn builtin_defs(var_store: &mut VarStore) -> MutMap { Symbol::NUM_SHIFT_LEFT => num_shift_left_by, Symbol::NUM_SHIFT_RIGHT => num_shift_right_by, Symbol::NUM_SHIFT_RIGHT_ZERO_FILL => num_shift_right_zf_by, + Symbol::NUM_INT_CAST=> num_int_cast, Symbol::RESULT_MAP => result_map, Symbol::RESULT_MAP_ERR => result_map_err, Symbol::RESULT_WITH_DEFAULT => result_with_default, @@ -1331,6 +1333,11 @@ fn num_shift_right_zf_by(symbol: Symbol, var_store: &mut VarStore) -> Def { lowlevel_2(symbol, LowLevel::NumShiftRightZfBy, var_store) } +/// Num.intCast: Int a -> Int b +fn num_int_cast(symbol: Symbol, var_store: &mut VarStore) -> Def { + lowlevel_1(symbol, LowLevel::NumIntCast, var_store) +} + /// List.isEmpty : List * -> Bool fn list_is_empty(symbol: Symbol, var_store: &mut VarStore) -> Def { let list_var = var_store.fresh(); diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index ed149b77a4..9ba362841f 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -3983,6 +3983,16 @@ fn run_low_level<'a, 'ctx, 'env>( op, ) } + NumIntCast => { + debug_assert_eq!(args.len(), 1); + + let arg = load_symbol(scope, &args[0]).into_int_value(); + + let to = basic_type_from_layout(env.arena, env.context, layout, env.ptr_bytes) + .into_int_type(); + + env.builder.build_int_cast(arg, to, "inc_cast").into() + } Eq => { debug_assert_eq!(args.len(), 2); diff --git a/compiler/module/src/low_level.rs b/compiler/module/src/low_level.rs index 7279a4ae76..640b8c8bca 100644 --- a/compiler/module/src/low_level.rs +++ b/compiler/module/src/low_level.rs @@ -83,6 +83,7 @@ pub enum LowLevel { NumShiftLeftBy, NumShiftRightBy, NumShiftRightZfBy, + NumIntCast, Eq, NotEq, And, diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index a7d19116dc..62f5a9d457 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -854,6 +854,8 @@ define_builtins! { 93 NUM_AT_NATURAL: "@Natural" 94 NUM_NATURAL: "Natural" imported 95 NUM_NAT: "Nat" imported + 96 NUM_INT_CAST: "intCast" + } 2 BOOL: "Bool" => { 0 BOOL_BOOL: "Bool" imported // the Bool.Bool type alias diff --git a/compiler/mono/src/borrow.rs b/compiler/mono/src/borrow.rs index 294e2582c0..c0d4f1e091 100644 --- a/compiler/mono/src/borrow.rs +++ b/compiler/mono/src/borrow.rs @@ -671,7 +671,7 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] { } NumAbs | NumNeg | NumSin | NumCos | NumSqrtUnchecked | NumRound | NumCeiling | NumFloor - | NumToFloat | Not | NumIsFinite | NumAtan | NumAcos | NumAsin => { + | NumToFloat | Not | NumIsFinite | NumAtan | NumAcos | NumAsin | NumIntCast => { arena.alloc_slice_copy(&[irrelevant]) } StrStartsWith | StrEndsWith => arena.alloc_slice_copy(&[owned, borrowed]),