Skip to content

Commit

Permalink
Apply rules from discussion in crystal-lang#8373
Browse files Browse the repository at this point in the history
  • Loading branch information
BlobCodes committed Dec 12, 2021
1 parent 7e7e172 commit e25b754
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 35 deletions.
41 changes: 21 additions & 20 deletions spec/compiler/lexer/lexer_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -302,32 +302,33 @@ describe "Lexer" do
assert_syntax_error "18446744073709551616_i32", "18446744073709551616 doesn't fit in an Int32"
assert_syntax_error "9999999999999999999_i32", "9999999999999999999 doesn't fit in an Int32"

assert_syntax_error "-9999999999999999999_i64", "-9999999999999999999 doesn't fit in an Int64"
assert_syntax_error "-99999999999999999999_i64", "-99999999999999999999 doesn't fit in an Int64"
assert_syntax_error "-11111111111111111111_i64", "-11111111111111111111 doesn't fit in an Int64"
assert_syntax_error "-9223372036854775809_i64", "-9223372036854775809 doesn't fit in an Int64"
assert_syntax_error "18446744073709551616_u64", "18446744073709551616 doesn't fit in an UInt64"
assert_syntax_error "-9999999999999999999", "-9999999999999999999 doesn't fit in an Int64, try using the suffix i128"
assert_syntax_error "-99999999999999999999", "-99999999999999999999 doesn't fit in an Int64, try using the suffix i128"
assert_syntax_error "-11111111111111111111", "-11111111111111111111 doesn't fit in an Int64, try using the suffix i128"
assert_syntax_error "-9223372036854775809", "-9223372036854775809 doesn't fit in an Int64, try using the suffix i128"
assert_syntax_error "118446744073709551616", "118446744073709551616 doesn't fit in an UInt64, try using the suffix i128"
assert_syntax_error "18446744073709551616", "18446744073709551616 doesn't fit in an UInt64, try using the suffix i128"

assert_syntax_error "340282366920938463463374607431768211456", "340282366920938463463374607431768211456 doesn't fit in an UInt128"
assert_syntax_error "-170141183460469231731687303715884105729", "-170141183460469231731687303715884105729 doesn't fit in an Int128"
assert_syntax_error "-999999999999999999999999999999999999999", "-999999999999999999999999999999999999999 doesn't fit in an Int128"
assert_syntax_error "340282366920938463463374607431768211456", "340282366920938463463374607431768211456 doesn't fit in an UInt64"
assert_syntax_error "-170141183460469231731687303715884105729", "-170141183460469231731687303715884105729 doesn't fit in an Int64"
assert_syntax_error "-999999999999999999999999999999999999999", "-999999999999999999999999999999999999999 doesn't fit in an Int64"

assert_syntax_error "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF doesn't fit in an UInt128"
assert_syntax_error "0o7777777777777777777777777777777777777777777777777", "0o7777777777777777777777777777777777777777777777777 doesn't fit in an UInt128"
assert_syntax_error "-0o7777777777777777777777777777777777777777777777777", "-0o7777777777777777777777777777777777777777777777777 doesn't fit in an Int128"
assert_syntax_error "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF doesn't fit in an UInt64"
assert_syntax_error "0o7777777777777777777777777777777777777777777777777", "0o7777777777777777777777777777777777777777777777777 doesn't fit in an UInt64"
assert_syntax_error "-0o7777777777777777777777777777777777777777777777777", "-0o7777777777777777777777777777777777777777777777777 doesn't fit in an Int64"

it_lexes_number :i128, ["9223372036854775808_i128", "9223372036854775808"]
it_lexes_number :i128, ["-9223372036854775809_i128", "-9223372036854775809"]
it_lexes_number :u128, ["118446744073709551616_u128", "118446744073709551616"]
it_lexes_number :u128, ["18446744073709551616_u128", "18446744073709551616"]
it_lexes_number :i128, "-9223372036854775809"
it_lexes_number :i128, "118446744073709551616"
it_lexes_number :i128, "18446744073709551616"
it_lexes_number :i128, "170141183460469231731687303715884105727"
it_lexes_number :u128, "170141183460469231731687303715884105728"
it_lexes_number :u128, "340282366920938463463374607431768211455"
it_lexes_number :u128, ["0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "340282366920938463463374607431768211455"]
it_lexes_number :i128, ["-0x80000000000000000000000000000000", "-170141183460469231731687303715884105728"]
it_lexes_number :i128, ["170141183460469231731687303715884105727_i128", "170141183460469231731687303715884105727"]
it_lexes_number :u128, ["170141183460469231731687303715884105728_u128", "170141183460469231731687303715884105728"]
it_lexes_number :u128, ["340282366920938463463374607431768211455_u128", "340282366920938463463374607431768211455"]
it_lexes_number :u128, ["0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u128", "340282366920938463463374607431768211455"]
it_lexes_number :i128, ["-0x80000000000000000000000000000000_i128", "-170141183460469231731687303715884105728"]
assert_syntax_error "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF doesn't fit in an UInt64, try using the suffix u128"
assert_syntax_error "-0x80000000000000000000000000000000", "-0x80000000000000000000000000000000 doesn't fit in an Int64, try using the suffix i128"
assert_syntax_error "-0x80000000000000000000000000000001", "-0x80000000000000000000000000000001 doesn't fit in an Int64"
assert_syntax_error "-1_u128", "Invalid negative value -1 for UInt128"

assert_syntax_error "1__1", "consecutive underscores in numbers aren't allowed"
Expand Down Expand Up @@ -367,7 +368,7 @@ describe "Lexer" do
it_lexes_u64 [["0xffff_ffff_ffff_ffff", "18446744073709551615"], ["0o177777_77777777_77777777", "18446744073709551615"], ["0b11111111_11111111_11111111_11111111_11111111_11111111_11111111_11111111", "18446744073709551615"]]
it_lexes_u64 [["0x00ffffffffffffffff", "18446744073709551615"], ["0o001777777777777777777777", "18446744073709551615"], ["0b001111111111111111111111111111111111111111111111111111111111111111", "18446744073709551615"]]
# 2**64
it_lexes_number :i128, ["0x10000_0000_0000_0000", "18446744073709551616"]
it_lexes_number :i128, ["0x10000_0000_0000_0000_i128", "18446744073709551616"]
assert_syntax_error "0x10000_0000_0000_0000_u64", "0x10000_0000_0000_0000 doesn't fit in an UInt64"
assert_syntax_error "0xfffffffffffffffff_u64", "0xfffffffffffffffff doesn't fit in an UInt64"
assert_syntax_error "0o200000_00000000_00000000_u64", "0o200000_00000000_00000000 doesn't fit in an UInt64"
Expand Down
30 changes: 15 additions & 15 deletions src/compiler/crystal/syntax/lexer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,10 @@ module Crystal
raise "#{string_range(start, pos_before_suffix)} doesn't fit in an #{type}", @token, (current_pos - start)
end

def raise_value_doesnt_fit_in(type, start, pos_before_suffix, alternative)
raise "#{string_range(start, pos_before_suffix)} doesn't fit in an #{type}, try using the suffix #{alternative}", @token, (current_pos - start)
end

private def scan_number(start, negative = false)
@token.type = :NUMBER
base = 10
Expand Down Expand Up @@ -1562,7 +1566,7 @@ module Crystal

# Check or determine suffix
if suffix_size == 0
raise_value_doesnt_fit_in(negative ? Int128 : UInt128, start, pos_before_suffix) unless @token.value
raise_value_doesnt_fit_in(negative ? Int64 : UInt64, start, pos_before_suffix) unless @token.value
@token.number_kind = case number_size
when 0..9 then :i32
when 10 then raw_number_string.to_i32? ? :i32 : :i64
Expand All @@ -1571,30 +1575,26 @@ module Crystal
if raw_number_string.to_i64?
:i64
elsif negative
:i128
raise_value_doesnt_fit_in(Int64, start, pos_before_suffix, "i128")
else
:u64
end
when 20
if !negative && raw_number_string.to_u64?
:u64
else
:i128
end
when 21..38 then :i128
raise_value_doesnt_fit_in(Int64, start, pos_before_suffix, "i128") if negative
raise_value_doesnt_fit_in(UInt64, start, pos_before_suffix, "i128") unless raw_number_string.to_u64?
:u64
when 21..38
raise_value_doesnt_fit_in(negative ? Int64 : UInt64, start, pos_before_suffix, "i128")
when 39
if raw_number_string.to_i128?
:i128
elsif negative
raise_value_doesnt_fit_in(Int128, start, pos_before_suffix)
raise_value_doesnt_fit_in(negative ? Int64 : UInt64, start, pos_before_suffix, "i128")
elsif raw_number_string.to_u128?
:u128
raise_value_doesnt_fit_in(UInt64, start, pos_before_suffix, "u128")
else
raise_value_doesnt_fit_in(UInt128, start, pos_before_suffix)
raise_value_doesnt_fit_in(negative ? Int64 : UInt64, start, pos_before_suffix)
end
else
raise_value_doesnt_fit_in(Int128, start, pos_before_suffix) if negative
raise_value_doesnt_fit_in(UInt128, start, pos_before_suffix)
raise_value_doesnt_fit_in(negative ? Int64 : UInt64, start, pos_before_suffix)
end
else
case @token.number_kind
Expand Down

0 comments on commit e25b754

Please sign in to comment.