Format Num, Str and fix off-by-one bug

This commit is contained in:
Ayaz Hafiz 2022-05-18 15:26:21 -04:00
parent 521f1e2c6c
commit e293a8d4fa
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
3 changed files with 14 additions and 53 deletions

View file

@ -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.
## ##
@ -1153,7 +1137,6 @@ 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.
## ##
@ -1162,7 +1145,6 @@ 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.
## ##
@ -1186,20 +1168,16 @@ toF64Checked : Num * -> Result F64 [ OutOfBounds ]*
## 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:

View file

@ -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 ]*

View file

@ -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