mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Format Num, Str and fix off-by-one bug
This commit is contained in:
parent
521f1e2c6c
commit
e293a8d4fa
3 changed files with 14 additions and 53 deletions
|
@ -4,46 +4,36 @@ interface Num
|
||||||
Num,
|
Num,
|
||||||
Int,
|
Int,
|
||||||
Frac,
|
Frac,
|
||||||
|
|
||||||
Integer,
|
Integer,
|
||||||
FloatingPoint,
|
FloatingPoint,
|
||||||
|
|
||||||
I128,
|
I128,
|
||||||
I64,
|
I64,
|
||||||
I32,
|
I32,
|
||||||
I16,
|
I16,
|
||||||
I8,
|
I8,
|
||||||
|
|
||||||
U128,
|
U128,
|
||||||
U64,
|
U64,
|
||||||
U32,
|
U32,
|
||||||
U16,
|
U16,
|
||||||
U8,
|
U8,
|
||||||
|
|
||||||
Signed128,
|
Signed128,
|
||||||
Signed64,
|
Signed64,
|
||||||
Signed32,
|
Signed32,
|
||||||
Signed16,
|
Signed16,
|
||||||
Signed8,
|
Signed8,
|
||||||
|
|
||||||
Unsigned128,
|
Unsigned128,
|
||||||
Unsigned64,
|
Unsigned64,
|
||||||
Unsigned32,
|
Unsigned32,
|
||||||
Unsigned16,
|
Unsigned16,
|
||||||
Unsigned8,
|
Unsigned8,
|
||||||
|
|
||||||
Nat,
|
Nat,
|
||||||
Dec,
|
Dec,
|
||||||
|
|
||||||
F32,
|
F32,
|
||||||
F64,
|
F64,
|
||||||
|
|
||||||
Natural,
|
Natural,
|
||||||
Decimal,
|
Decimal,
|
||||||
|
|
||||||
Binary32,
|
Binary32,
|
||||||
Binary64,
|
Binary64,
|
||||||
|
|
||||||
abs,
|
abs,
|
||||||
neg,
|
neg,
|
||||||
add,
|
add,
|
||||||
|
@ -155,7 +145,7 @@ interface Num
|
||||||
]
|
]
|
||||||
imports
|
imports
|
||||||
[
|
[
|
||||||
Bool.{ Bool }
|
Bool.{ Bool },
|
||||||
]
|
]
|
||||||
|
|
||||||
## Represents a number that could be either an [Int] or a [Frac].
|
## Represents a number that could be either an [Int] or a [Frac].
|
||||||
|
@ -343,7 +333,6 @@ Num range := range
|
||||||
##
|
##
|
||||||
## As such, it's very important to design your code not to exceed these bounds!
|
## As such, it's very important to design your code not to exceed these bounds!
|
||||||
## If you need to do math outside these bounds, consider using a larger numeric size.
|
## If you need to do math outside these bounds, consider using a larger numeric size.
|
||||||
|
|
||||||
Int range : Num (Integer range)
|
Int range : Num (Integer range)
|
||||||
|
|
||||||
## A fixed-size number with a fractional component.
|
## A fixed-size number with a fractional component.
|
||||||
|
@ -501,7 +490,6 @@ F32 : Num (FloatingPoint Binary32)
|
||||||
Dec : Num (FloatingPoint Decimal)
|
Dec : Num (FloatingPoint Decimal)
|
||||||
|
|
||||||
# ------- Functions
|
# ------- Functions
|
||||||
|
|
||||||
## Convert a number to a [Str].
|
## Convert a number to a [Str].
|
||||||
##
|
##
|
||||||
## This is the same as calling `Num.format {}` - so for more details on
|
## This is the same as calling `Num.format {}` - so for more details on
|
||||||
|
@ -875,7 +863,6 @@ subChecked : Num a, Num a -> Result (Num a) [ Overflow ]*
|
||||||
|
|
||||||
mulWrap : Int range, Int range -> Int range
|
mulWrap : Int range, Int range -> Int range
|
||||||
# mulSaturated : Num a, Num a -> Num a
|
# mulSaturated : Num a, Num a -> Num a
|
||||||
|
|
||||||
## Multiply two numbers and check for overflow.
|
## Multiply two numbers and check for overflow.
|
||||||
##
|
##
|
||||||
## This is the same as [Num.mul] except if the operation overflows, instead of
|
## This is the same as [Num.mul] except if the operation overflows, instead of
|
||||||
|
@ -1086,7 +1073,6 @@ minF64 = -1.7976931348623157e308
|
||||||
maxF64 : F64
|
maxF64 : F64
|
||||||
maxF64 = 1.7976931348623157e308
|
maxF64 = 1.7976931348623157e308
|
||||||
|
|
||||||
|
|
||||||
## Converts an [Int] to an [I8]. If the given number can't be precisely represented in an [I8],
|
## Converts an [Int] to an [I8]. If the given number can't be precisely represented in an [I8],
|
||||||
## the returned number may be different from the given number.
|
## the returned number may be different from the given number.
|
||||||
toI8 : Int * -> I8
|
toI8 : Int * -> I8
|
||||||
|
@ -1142,9 +1128,7 @@ toNatChecked : Int * -> Result Nat [ OutOfBounds ]*
|
||||||
toF32Checked : Num * -> Result F32 [ OutOfBounds ]*
|
toF32Checked : Num * -> Result F32 [ OutOfBounds ]*
|
||||||
toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
||||||
|
|
||||||
|
|
||||||
# Special Floating-Point operations
|
# Special Floating-Point operations
|
||||||
|
|
||||||
## When given a [F64] or [F32] value, returns `False` if that value is
|
## When given a [F64] or [F32] value, returns `False` if that value is
|
||||||
## [*NaN*](Num.isNaN), ∞ or -∞, and `True` otherwise.
|
## [*NaN*](Num.isNaN), ∞ or -∞, and `True` otherwise.
|
||||||
##
|
##
|
||||||
|
@ -1152,8 +1136,7 @@ toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
||||||
##
|
##
|
||||||
## This is the opposite of [isInfinite], except when given [*NaN*](Num.isNaN). Both
|
## This is the opposite of [isInfinite], except when given [*NaN*](Num.isNaN). Both
|
||||||
## [isFinite] and [isInfinite] return `False` for [*NaN*](Num.isNaN).
|
## [isFinite] and [isInfinite] return `False` for [*NaN*](Num.isNaN).
|
||||||
#isFinite : Frac * -> Bool
|
# isFinite : Frac * -> Bool
|
||||||
|
|
||||||
## When given a [F64] or [F32] value, returns `True` if that value is either
|
## When given a [F64] or [F32] value, returns `True` if that value is either
|
||||||
## ∞ or -∞, and `False` otherwise.
|
## ∞ or -∞, and `False` otherwise.
|
||||||
##
|
##
|
||||||
|
@ -1161,8 +1144,7 @@ toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
||||||
##
|
##
|
||||||
## This is the opposite of [isFinite], except when given [*NaN*](Num.isNaN). Both
|
## This is the opposite of [isFinite], except when given [*NaN*](Num.isNaN). Both
|
||||||
## [isFinite] and [isInfinite] return `False` for [*NaN*](Num.isNaN).
|
## [isFinite] and [isInfinite] return `False` for [*NaN*](Num.isNaN).
|
||||||
#isInfinite : Frac * -> Bool
|
# isInfinite : Frac * -> Bool
|
||||||
|
|
||||||
## When given a [F64] or [F32] value, returns `True` if that value is
|
## When given a [F64] or [F32] value, returns `True` if that value is
|
||||||
## *NaN* ([not a number](https://en.wikipedia.org/wiki/NaN)), and `False` otherwise.
|
## *NaN* ([not a number](https://en.wikipedia.org/wiki/NaN)), and `False` otherwise.
|
||||||
##
|
##
|
||||||
|
@ -1185,21 +1167,17 @@ toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
||||||
## Note that you should never put a *NaN* into a [Set], or use it as the key in
|
## Note that you should never put a *NaN* into a [Set], or use it as the key in
|
||||||
## a [Dict]. The result is entries that can never be removed from those
|
## a [Dict]. The result is entries that can never be removed from those
|
||||||
## collections! See the documentation for [Set.add] and [Dict.insert] for details.
|
## collections! See the documentation for [Set.add] and [Dict.insert] for details.
|
||||||
#isNaN : Frac * -> Bool
|
# isNaN : Frac * -> Bool
|
||||||
|
|
||||||
|
|
||||||
## Returns the higher of two numbers.
|
## Returns the higher of two numbers.
|
||||||
##
|
##
|
||||||
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
||||||
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
||||||
#max : Num a, Num a -> Num a
|
# max : Num a, Num a -> Num a
|
||||||
|
|
||||||
## Returns the lower of two numbers.
|
## Returns the lower of two numbers.
|
||||||
##
|
##
|
||||||
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
## If either argument is [*NaN*](Num.isNaN), returns `False` no matter what. (*NaN*
|
||||||
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
## is [defined to be unordered](https://en.wikipedia.org/wiki/NaN#Comparison_with_NaN).)
|
||||||
#min : Num a, Num a -> Num a
|
# min : Num a, Num a -> Num a
|
||||||
|
|
||||||
# Branchless implementation that works for all numeric types:
|
# Branchless implementation that works for all numeric types:
|
||||||
#
|
#
|
||||||
# let is_lt = arg1 < arg2;
|
# let is_lt = arg1 < arg2;
|
||||||
|
@ -1209,57 +1187,46 @@ toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
|
||||||
# 1, 1 -> (0 - 1) + 1 == 0 # Eq
|
# 1, 1 -> (0 - 1) + 1 == 0 # Eq
|
||||||
# 5, 1 -> (0 - 0) + 1 == 1 # Gt
|
# 5, 1 -> (0 - 0) + 1 == 1 # Gt
|
||||||
# 1, 5 -> (1 - 0) + 1 == 2 # Lt
|
# 1, 5 -> (1 - 0) + 1 == 2 # Lt
|
||||||
|
|
||||||
## Returns `Lt` if the first number is less than the second, `Gt` if
|
## Returns `Lt` if the first number is less than the second, `Gt` if
|
||||||
## the first is greater than the second, and `Eq` if they're equal.
|
## the first is greater than the second, and `Eq` if they're equal.
|
||||||
##
|
##
|
||||||
## Although this can be passed to `List.sort`, you'll get better performance
|
## Although this can be passed to `List.sort`, you'll get better performance
|
||||||
## by using `List.sortAsc` or `List.sortDesc` instead.
|
## by using `List.sortAsc` or `List.sortDesc` instead.
|
||||||
#compare : Num a, Num a -> [ Lt, Eq, Gt ]
|
# compare : Num a, Num a -> [ Lt, Eq, Gt ]
|
||||||
|
|
||||||
## [Endianness](https://en.wikipedia.org/wiki/Endianness)
|
## [Endianness](https://en.wikipedia.org/wiki/Endianness)
|
||||||
# Endi : [ Big, Little, Native ]
|
# Endi : [ Big, Little, Native ]
|
||||||
|
|
||||||
## The `Endi` argument does not matter for [U8] and [I8], since they have
|
## The `Endi` argument does not matter for [U8] and [I8], since they have
|
||||||
## only one byte.
|
## only one byte.
|
||||||
# toBytes : Num *, Endi -> List U8
|
# toBytes : Num *, Endi -> List U8
|
||||||
|
|
||||||
## when Num.parseBytes bytes Big is
|
## when Num.parseBytes bytes Big is
|
||||||
## Ok { val: f64, rest } -> ...
|
## Ok { val: f64, rest } -> ...
|
||||||
## Err (ExpectedNum (Frac Binary64)) -> ...
|
## Err (ExpectedNum (Frac Binary64)) -> ...
|
||||||
# parseBytes : List U8, Endi -> Result { val : Num a, rest : List U8 } [ ExpectedNum a ]*
|
# parseBytes : List U8, Endi -> Result { val : Num a, rest : List U8 } [ ExpectedNum a ]*
|
||||||
|
|
||||||
## when Num.fromBytes bytes Big is
|
## when Num.fromBytes bytes Big is
|
||||||
## Ok f64 -> ...
|
## Ok f64 -> ...
|
||||||
## Err (ExpectedNum (Frac Binary64)) -> ...
|
## Err (ExpectedNum (Frac Binary64)) -> ...
|
||||||
# fromBytes : List U8, Endi -> Result (Num a) [ ExpectedNum a ]*
|
# fromBytes : List U8, Endi -> Result (Num a) [ ExpectedNum a ]*
|
||||||
|
|
||||||
# Bit shifts
|
# Bit shifts
|
||||||
|
|
||||||
## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) left.
|
## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) left.
|
||||||
##
|
##
|
||||||
## `a << b` is shorthand for `Num.shl a b`.
|
## `a << b` is shorthand for `Num.shl a b`.
|
||||||
#shl : Int a, Int a -> Int a
|
# shl : Int a, Int a -> Int a
|
||||||
|
|
||||||
## [Arithmetic bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift) left.
|
## [Arithmetic bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift) left.
|
||||||
##
|
##
|
||||||
## This is called `shlWrap` because any bits shifted
|
## This is called `shlWrap` because any bits shifted
|
||||||
## off the beginning of the number will be wrapped around to
|
## off the beginning of the number will be wrapped around to
|
||||||
## the end. (In contrast, [shl] replaces discarded bits with zeroes.)
|
## the end. (In contrast, [shl] replaces discarded bits with zeroes.)
|
||||||
#shlWrap : Int a, Int a -> Int a
|
# shlWrap : Int a, Int a -> Int a
|
||||||
|
|
||||||
## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) right.
|
## [Logical bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Logical_shift) right.
|
||||||
##
|
##
|
||||||
## `a >> b` is shorthand for `Num.shr a b`.
|
## `a >> b` is shorthand for `Num.shr a b`.
|
||||||
#shr : Int a, Int a -> Int a
|
# shr : Int a, Int a -> Int a
|
||||||
|
|
||||||
## [Arithmetic bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift) right.
|
## [Arithmetic bit shift](https://en.wikipedia.org/wiki/Bitwise_operation#Arithmetic_shift) right.
|
||||||
##
|
##
|
||||||
## This is called `shrWrap` because any bits shifted
|
## This is called `shrWrap` because any bits shifted
|
||||||
## off the end of the number will be wrapped around to
|
## off the end of the number will be wrapped around to
|
||||||
## the beginning. (In contrast, [shr] replaces discarded bits with zeroes.)
|
## the beginning. (In contrast, [shr] replaces discarded bits with zeroes.)
|
||||||
#shrWrap : Int a, Int a -> Int a
|
# shrWrap : Int a, Int a -> Int a
|
||||||
|
|
||||||
# ## Convert a number into a [Str], formatted with the given options.
|
# ## Convert a number into a [Str], formatted with the given options.
|
||||||
# ##
|
# ##
|
||||||
# ## Default options:
|
# ## Default options:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
interface Str
|
interface Str
|
||||||
exposes
|
exposes
|
||||||
[
|
[
|
||||||
concat,
|
concat,
|
||||||
Utf8Problem,
|
Utf8Problem,
|
||||||
Utf8ByteProblem,
|
Utf8ByteProblem,
|
||||||
|
@ -18,7 +18,6 @@ interface Str
|
||||||
trim,
|
trim,
|
||||||
trimLeft,
|
trimLeft,
|
||||||
trimRight,
|
trimRight,
|
||||||
|
|
||||||
toDec,
|
toDec,
|
||||||
toF64,
|
toF64,
|
||||||
toF32,
|
toF32,
|
||||||
|
@ -41,7 +40,6 @@ interface Str
|
||||||
## Dealing with text is a deep topic, so by design, Roc's `Str` module sticks
|
## Dealing with text is a deep topic, so by design, Roc's `Str` module sticks
|
||||||
## to the basics.
|
## to the basics.
|
||||||
##
|
##
|
||||||
|
|
||||||
## ### Unicode
|
## ### Unicode
|
||||||
##
|
##
|
||||||
## Unicode can represent text values which span multiple languages, symbols, and emoji.
|
## Unicode can represent text values which span multiple languages, symbols, and emoji.
|
||||||
|
@ -111,8 +109,6 @@ interface Str
|
||||||
## and you can use it as many times as you like inside a string. The name
|
## and you can use it as many times as you like inside a string. The name
|
||||||
## between the parentheses must refer to a `Str` value that is currently in
|
## between the parentheses must refer to a `Str` value that is currently in
|
||||||
## scope, and it must be a name - it can't be an arbitrary expression like a function call.
|
## scope, and it must be a name - it can't be an arbitrary expression like a function call.
|
||||||
|
|
||||||
|
|
||||||
Utf8ByteProblem :
|
Utf8ByteProblem :
|
||||||
[
|
[
|
||||||
InvalidStartByte,
|
InvalidStartByte,
|
||||||
|
@ -191,7 +187,6 @@ toUtf8 : Str -> List U8
|
||||||
|
|
||||||
# fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8Problem ]*
|
# fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8Problem ]*
|
||||||
# fromUtf8Range : List U8 -> Result Str [ BadUtf8 Utf8Problem Nat, OutOfBounds ]*
|
# fromUtf8Range : List U8 -> Result Str [ BadUtf8 Utf8Problem Nat, OutOfBounds ]*
|
||||||
|
|
||||||
fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8ByteProblem Nat ]*
|
fromUtf8 : List U8 -> Result Str [ BadUtf8 Utf8ByteProblem Nat ]*
|
||||||
fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [ BadUtf8 Utf8ByteProblem Nat, OutOfBounds ]*
|
fromUtf8Range : List U8, { start : Nat, count : Nat } -> Result Str [ BadUtf8 Utf8ByteProblem Nat, OutOfBounds ]*
|
||||||
|
|
||||||
|
|
|
@ -388,7 +388,6 @@ fn eat_line_comment<'a>(
|
||||||
}
|
}
|
||||||
b'\n' => {
|
b'\n' => {
|
||||||
state = state.advance_newline();
|
state = state.advance_newline();
|
||||||
index += 1;
|
|
||||||
multiline = true;
|
multiline = true;
|
||||||
comments_and_newlines.push(CommentOrNewline::Newline);
|
comments_and_newlines.push(CommentOrNewline::Newline);
|
||||||
}
|
}
|
||||||
|
@ -424,7 +423,7 @@ fn eat_line_comment<'a>(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => false,
|
Some(_) => false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue