add Num.bitwiseOr and Num.shiftLeftBy

This commit is contained in:
Folkert 2021-02-21 15:15:16 +01:00
parent 89bf22598e
commit ea76578e06
6 changed files with 83 additions and 11 deletions

View file

@ -324,6 +324,24 @@ pub fn types() -> MutMap<Symbol, (SolvedType, Region)> {
), ),
); );
// bitwiseOr : Int a, Int a -> Int a
add_type(
Symbol::NUM_BITWISE_OR,
top_level_function(
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
Box::new(int_type(flex(TVAR1))),
),
);
// shiftLeftBy : Nat, Int a -> Int a
add_type(
Symbol::NUM_SHIFT_LEFT,
top_level_function(
vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))],
Box::new(int_type(flex(TVAR1))),
),
);
// rem : Int a, Int a -> Result (Int a) [ DivByZero ]* // rem : Int a, Int a -> Result (Int a) [ DivByZero ]*
add_type( add_type(
Symbol::NUM_REM, Symbol::NUM_REM,

View file

@ -151,6 +151,8 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option<Def>
NUM_MIN_INT => num_min_int, NUM_MIN_INT => num_min_int,
NUM_BITWISE_AND => num_bitwise_and, NUM_BITWISE_AND => num_bitwise_and,
NUM_BITWISE_XOR => num_bitwise_xor, NUM_BITWISE_XOR => num_bitwise_xor,
NUM_BITWISE_OR => num_bitwise_or,
NUM_SHIFT_LEFT=> num_shift_left_by,
RESULT_MAP => result_map, RESULT_MAP => result_map,
RESULT_MAP_ERR => result_map_err, RESULT_MAP_ERR => result_map_err,
RESULT_WITH_DEFAULT => result_with_default, RESULT_WITH_DEFAULT => result_with_default,
@ -273,6 +275,10 @@ pub fn builtin_defs(var_store: &mut VarStore) -> MutMap<Symbol, Def> {
Symbol::NUM_ASIN => num_asin, Symbol::NUM_ASIN => num_asin,
Symbol::NUM_MAX_INT => num_max_int, Symbol::NUM_MAX_INT => num_max_int,
Symbol::NUM_MIN_INT => num_min_int, Symbol::NUM_MIN_INT => num_min_int,
Symbol::NUM_BITWISE_AND => num_bitwise_and,
Symbol::NUM_BITWISE_XOR => num_bitwise_xor,
Symbol::NUM_BITWISE_OR => num_bitwise_or,
Symbol::NUM_SHIFT_LEFT=> num_shift_left_by,
Symbol::RESULT_MAP => result_map, Symbol::RESULT_MAP => result_map,
Symbol::RESULT_MAP_ERR => result_map_err, Symbol::RESULT_MAP_ERR => result_map_err,
Symbol::RESULT_WITH_DEFAULT => result_with_default, Symbol::RESULT_WITH_DEFAULT => result_with_default,
@ -1299,6 +1305,16 @@ fn num_bitwise_xor(symbol: Symbol, var_store: &mut VarStore) -> Def {
num_binop(symbol, var_store, LowLevel::NumBitwiseXor) num_binop(symbol, var_store, LowLevel::NumBitwiseXor)
} }
/// Num.bitwiseOr: Int, Int -> Int
fn num_bitwise_or(symbol: Symbol, var_store: &mut VarStore) -> Def {
num_binop(symbol, var_store, LowLevel::NumBitwiseOr)
}
/// Num.shiftLeftBy: Nat, Int a -> Int a
fn num_shift_left_by(symbol: Symbol, var_store: &mut VarStore) -> Def {
lowlevel_2(symbol, LowLevel::NumShiftLeftBy, var_store)
}
/// List.isEmpty : List * -> Bool /// List.isEmpty : List * -> Bool
fn list_is_empty(symbol: Symbol, var_store: &mut VarStore) -> Def { fn list_is_empty(symbol: Symbol, var_store: &mut VarStore) -> Def {
let list_var = var_store.fresh(); let list_var = var_store.fresh();

View file

@ -3943,7 +3943,23 @@ fn run_low_level<'a, 'ctx, 'env>(
build_num_binop(env, parent, lhs_arg, lhs_layout, rhs_arg, rhs_layout, op) build_num_binop(env, parent, lhs_arg, lhs_layout, rhs_arg, rhs_layout, op)
} }
NumBitwiseAnd | NumBitwiseXor => { NumBitwiseAnd | NumBitwiseOr | NumBitwiseXor => {
debug_assert_eq!(args.len(), 2);
let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]);
let (rhs_arg, rhs_layout) = load_symbol_and_layout(scope, &args[1]);
build_int_binop(
env,
parent,
lhs_arg.into_int_value(),
lhs_layout,
rhs_arg.into_int_value(),
rhs_layout,
op,
)
}
NumShiftLeftBy => {
debug_assert_eq!(args.len(), 2); debug_assert_eq!(args.len(), 2);
let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]); let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]);
@ -4585,6 +4601,14 @@ fn build_int_binop<'a, 'ctx, 'env>(
NumPowInt => call_bitcode_fn(env, &[lhs.into(), rhs.into()], &bitcode::NUM_POW_INT), NumPowInt => call_bitcode_fn(env, &[lhs.into(), rhs.into()], &bitcode::NUM_POW_INT),
NumBitwiseAnd => bd.build_and(lhs, rhs, "int_bitwise_and").into(), NumBitwiseAnd => bd.build_and(lhs, rhs, "int_bitwise_and").into(),
NumBitwiseXor => bd.build_xor(lhs, rhs, "int_bitwise_xor").into(), NumBitwiseXor => bd.build_xor(lhs, rhs, "int_bitwise_xor").into(),
NumBitwiseOr => bd.build_or(lhs, rhs, "int_bitwise_or").into(),
NumShiftLeftBy => {
// NOTE arguments are flipped;
// we write `assert_eq!(0b0000_0001 << 0, 0b0000_0001);`
// as `Num.shiftLeftBy 0 0b0000_0001
bd.build_left_shift(rhs, lhs, "int_bitwise_or").into()
}
_ => { _ => {
unreachable!("Unrecognized int binary operation: {:?}", op); unreachable!("Unrecognized int binary operation: {:?}", op);
} }

View file

@ -78,6 +78,8 @@ pub enum LowLevel {
NumAsin, NumAsin,
NumBitwiseAnd, NumBitwiseAnd,
NumBitwiseXor, NumBitwiseXor,
NumBitwiseOr,
NumShiftLeftBy,
Eq, Eq,
NotEq, NotEq,
And, And,

View file

@ -841,15 +841,17 @@ define_builtins! {
80 NUM_BINARY32: "Binary32" imported 80 NUM_BINARY32: "Binary32" imported
81 NUM_BITWISE_AND: "bitwiseAnd" 81 NUM_BITWISE_AND: "bitwiseAnd"
82 NUM_BITWISE_XOR: "bitwiseXor" 82 NUM_BITWISE_XOR: "bitwiseXor"
83 NUM_SUB_WRAP: "subWrap" 83 NUM_BITWISE_OR: "bitwiseOr"
84 NUM_SUB_CHECKED: "subChecked" 84 NUM_SHIFT_LEFT: "shiftLeftBy"
85 NUM_MUL_WRAP: "mulWrap" 85 NUM_SUB_WRAP: "subWrap"
86 NUM_MUL_CHECKED: "mulChecked" 86 NUM_SUB_CHECKED: "subChecked"
87 NUM_INT: "Int" imported 87 NUM_MUL_WRAP: "mulWrap"
88 NUM_FLOAT: "Float" imported 88 NUM_MUL_CHECKED: "mulChecked"
89 NUM_AT_NATURAL: "@Natural" 89 NUM_INT: "Int" imported
90 NUM_NATURAL: "Natural" imported 90 NUM_FLOAT: "Float" imported
91 NUM_NAT: "Nat" imported 91 NUM_AT_NATURAL: "@Natural"
92 NUM_NATURAL: "Natural" imported
93 NUM_NAT: "Nat" imported
} }
2 BOOL: "Bool" => { 2 BOOL: "Bool" => {
0 BOOL_BOOL: "Bool" imported // the Bool.Bool type alias 0 BOOL_BOOL: "Bool" imported // the Bool.Bool type alias

View file

@ -373,6 +373,14 @@ impl<'a> BorrowInfState<'a> {
self.own_var(z); self.own_var(z);
// if the function exects an owned argument (ps), the argument must be owned (args) // if the function exects an owned argument (ps), the argument must be owned (args)
debug_assert_eq!(
arguments.len(),
ps.len(),
"{:?} has {} parameters, but was applied to {} arguments",
name,
ps.len(),
arguments.len()
);
self.own_args_using_params(arguments, ps); self.own_args_using_params(arguments, ps);
} }
None => { None => {
@ -658,7 +666,9 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
And | Or | NumAdd | NumAddWrap | NumAddChecked | NumSub | NumSubWrap | NumSubChecked And | Or | NumAdd | NumAddWrap | NumAddChecked | NumSub | NumSubWrap | NumSubChecked
| NumMul | NumMulWrap | NumMulChecked | NumGt | NumGte | NumLt | NumLte | NumCompare | NumMul | NumMulWrap | NumMulChecked | NumGt | NumGte | NumLt | NumLte | NumCompare
| NumDivUnchecked | NumRemUnchecked | NumPow | NumPowInt | NumBitwiseAnd | NumDivUnchecked | NumRemUnchecked | NumPow | NumPowInt | NumBitwiseAnd
| NumBitwiseXor => arena.alloc_slice_copy(&[irrelevant, irrelevant]), | NumBitwiseXor | NumBitwiseOr | NumShiftLeftBy => {
arena.alloc_slice_copy(&[irrelevant, irrelevant])
}
NumAbs | NumNeg | NumSin | NumCos | NumSqrtUnchecked | NumRound | NumCeiling | NumFloor NumAbs | NumNeg | NumSin | NumCos | NumSqrtUnchecked | NumRound | NumCeiling | NumFloor
| NumToFloat | Not | NumIsFinite | NumAtan | NumAcos | NumAsin => { | NumToFloat | Not | NumIsFinite | NumAtan | NumAcos | NumAsin => {