diff --git a/lib/Base/Int.fram b/lib/Base/Int.fram index 27afad2..a9a176c 100644 --- a/lib/Base/Int.fram +++ b/lib/Base/Int.fram @@ -21,11 +21,11 @@ pub method sub = (extern dbl_subInt : Int -> Int -> Int) self pub method mul = (extern dbl_mulInt : Int -> Int -> Int) self pub method div (n : Int) = - assert {msg="Division by zero"} (n.neq 0); + assert {msg="Division by zero"} (n != 0); (extern dbl_divInt : Int -> Int -> Int) self n pub method mod (n : Int) = - assert {msg="Division by zero"} (n.neq 0); + assert {msg="Division by zero"} (n != 0); (extern dbl_modInt : Int -> Int -> Int) self n pub method neg {self : Int} = 0 - self diff --git a/lib/Base/Int64.fram b/lib/Base/Int64.fram index 621ef03..b83fd95 100644 --- a/lib/Base/Int64.fram +++ b/lib/Base/Int64.fram @@ -48,14 +48,12 @@ pub method toString {self : Int64} = (extern dbl_int64ToString : Int64 -> String) self pub method toIntErr { ~onError, self : Int64 } = if self <= 0x3fffffffffffffffL && self >= 0xc000000000000000L then - (extern dbl_intToInt64 : Int64 -> Int) self + (extern dbl_int64ToInt : Int64 -> Int) self else ~onError () -pub method toIntOpt {self : Int64} = +pub method toInt {self : Int64} = if self <= 0x3fffffffffffffffL && self >= 0x7fffffffffffffffL then Some ((extern dbl_int64ToInt : Int64 -> Int) self) else None -pub method toInt {self : Int64} = - self.toIntErr { ~onError = fn () => runtimeError "Conversion overflow" } pub method abs {self : Int64} = if self < 0L then self.neg else self diff --git a/lib/Base/Option.fram b/lib/Base/Option.fram new file mode 100644 index 0000000..abd4de3 --- /dev/null +++ b/lib/Base/Option.fram @@ -0,0 +1,25 @@ +{# This file is part of DBL, released under MIT license. + # See LICENSE for details. + #} + +import open /Base/Types +import open /Base/Assert + +{## For `Some x` returns `x`, otherwise the provided argument is returned. + #} +pub method unwrapOr default = + match self with + | None => default + | Some x => x + end + +{## This method should only be called on `Some x` values, in which case it + returns `x`. When applied to `None` the entire program crashes irrecoverably + with a runtime error. The resulting error message can be optionally specified + with `?msg`. + #} +pub method unwrap {?msg} = + match self with + | None => runtimeError (msg.unwrapOr "Called `unwrap` on `None`") + | Some x => x + end diff --git a/lib/Prelude.fram b/lib/Prelude.fram index eb17828..77618c8 100644 --- a/lib/Prelude.fram +++ b/lib/Prelude.fram @@ -6,6 +6,7 @@ import /Base/Types import /Base/Operators import /Base/Assert import /Base/Bool +import /Base/Option import /Base/Int import /Base/Int64 import /Base/Char diff --git a/src/Eval/External.ml b/src/Eval/External.ml index 4614441..bf3fbe2 100644 --- a/src/Eval/External.ml +++ b/src/Eval/External.ml @@ -50,7 +50,7 @@ let int_cmpop op = int_fun2 (fun x y -> of_bool (op x y)) let int64_fun f = VFn (fun v cont -> match v with | VNum64 n -> cont (f n) - | _ -> failwith "Not a 64-bit integer") + | _ -> runtime_error "Not a 64-bit integer") let int64_fun2 f = int64_fun (fun x -> int64_fun (f x))