diff --git a/src/Char/Extra.elm b/src/Char/Extra.elm index 0ab12342..3975d466 100644 --- a/src/Char/Extra.elm +++ b/src/Char/Extra.elm @@ -25,41 +25,45 @@ unicodeIsLowerFast c = code : Int code = Char.toCode c - - cString : String - cString = - String.fromChar c in charCodeIsLower code - || (if String.toLower cString == cString ++ "" && String.toUpper cString /= cString ++ "" then - code <= 0x0344 || 0x0346 <= code && code <= 0x216F || 0x2180 <= code && code <= 0x24CF || 0x24EA <= code && code <= 0x000F0000 - - else if code < 0xA7F9 then - if code < 0x2109 then - if code < 0x024E then - 0x0137 <= code && code <= 0x0138 || 0x018C <= code && code <= 0x018D || 0x0199 <= code && code <= 0x019B || 0x01AA <= code && code <= 0x01AB || 0x01B9 <= code && code <= 0x01BA || 0x01BD <= code && code <= 0x01BF || code == 0x0221 || 0x0233 <= code && code <= 0x0239 + || (code + > 0x7F + && (let + cString : String + cString = + String.fromChar c + in + if String.toLower cString == cString ++ "" && String.toUpper cString /= cString ++ "" then + code <= 0x0344 || 0x0346 <= code && code <= 0x216F || 0x2180 <= code && code <= 0x24CF || 0x24EA <= code && code <= 0x000F0000 + + else if code < 0xA7F9 then + if code < 0x2109 then + if code < 0x024E then + 0x0137 <= code && code <= 0x0138 || 0x018C <= code && code <= 0x018D || 0x0199 <= code && code <= 0x019B || 0x01AA <= code && code <= 0x01AB || 0x01B9 <= code && code <= 0x01BA || 0x01BD <= code && code <= 0x01BF || code == 0x0221 || 0x0233 <= code && code <= 0x0239 - else - 0x024F <= code && code <= 0x0293 || 0x0295 <= code && code <= 0x02AF || 0x03FB <= code && code <= 0x03FC || 0x0560 <= code && code <= 0x0588 || 0x1D00 <= code && code <= 0x1D2B || 0x1D6B <= code && code <= 0x1D77 || 0x1D79 <= code && code <= 0x1D9A || 0x1E95 <= code && code <= 0x1E9D || code == 0x1E9F + else + 0x024F <= code && code <= 0x0293 || 0x0295 <= code && code <= 0x02AF || 0x03FB <= code && code <= 0x03FC || 0x0560 <= code && code <= 0x0588 || 0x1D00 <= code && code <= 0x1D2B || 0x1D6B <= code && code <= 0x1D77 || 0x1D79 <= code && code <= 0x1D9A || 0x1E95 <= code && code <= 0x1E9D || code == 0x1E9F - else if code < 0x2C70 then - code == 0x210A || 0x210E <= code && code <= 0x210F || code == 0x2113 || code == 0x212F || code == 0x2134 || code == 0x2139 || 0x213C <= code && code <= 0x213D || 0x2146 <= code && code <= 0x2149 + else if code < 0x2C70 then + code == 0x210A || 0x210E <= code && code <= 0x210F || code == 0x2113 || code == 0x212F || code == 0x2134 || code == 0x2139 || 0x213C <= code && code <= 0x213D || 0x2146 <= code && code <= 0x2149 - else - code == 0x2C71 || 0x2C73 <= code && code <= 0x2C74 || 0x2C76 <= code && code <= 0x2C7B || 0x2CE3 <= code && code <= 0x2CE4 || 0xA72F <= code && code <= 0xA731 || 0xA771 <= code && code <= 0xA778 || code == 0xA78E || 0xA793 <= code && code <= 0xA795 || code == 0xA7AF || modBy 2 code == 1 && 0xA7D3 <= code && code <= 0xA7D5 + else + code == 0x2C71 || 0x2C73 <= code && code <= 0x2C74 || 0x2C76 <= code && code <= 0x2C7B || 0x2CE3 <= code && code <= 0x2CE4 || 0xA72F <= code && code <= 0xA731 || 0xA771 <= code && code <= 0xA778 || code == 0xA78E || 0xA793 <= code && code <= 0xA795 || code == 0xA7AF || modBy 2 code == 1 && 0xA7D3 <= code && code <= 0xA7D5 - else if code < 0x0001D621 then - if code < 0x0001D4BA then - code == 0xA7FA || 0xAB30 <= code && code <= 0xAB5A || 0xAB60 <= code && code <= 0xAB68 || 0x0001D41A <= code && code <= 0x0001D433 || 0x0001D44E <= code && code <= 0x0001D454 || 0x0001D456 <= code && code <= 0x0001D467 || 0x0001D482 <= code && code <= 0x0001D49B || 0x0001D4B6 <= code && code <= 0x0001D4B9 + else if code < 0x0001D621 then + if code < 0x0001D4BA then + code == 0xA7FA || 0xAB30 <= code && code <= 0xAB5A || 0xAB60 <= code && code <= 0xAB68 || 0x0001D41A <= code && code <= 0x0001D433 || 0x0001D44E <= code && code <= 0x0001D454 || 0x0001D456 <= code && code <= 0x0001D467 || 0x0001D482 <= code && code <= 0x0001D49B || 0x0001D4B6 <= code && code <= 0x0001D4B9 - else - code == 0x0001D4BB || 0x0001D4BD <= code && code <= 0x0001D4C3 || 0x0001D4C5 <= code && code <= 0x0001D4CF || 0x0001D4EA <= code && code <= 0x0001D503 || 0x0001D51E <= code && code <= 0x0001D537 || 0x0001D552 <= code && code <= 0x0001D56B || 0x0001D586 <= code && code <= 0x0001D59F || 0x0001D5BA <= code && code <= 0x0001D5D3 || 0x0001D5EE <= code && code <= 0x0001D607 + else + code == 0x0001D4BB || 0x0001D4BD <= code && code <= 0x0001D4C3 || 0x0001D4C5 <= code && code <= 0x0001D4CF || 0x0001D4EA <= code && code <= 0x0001D503 || 0x0001D51E <= code && code <= 0x0001D537 || 0x0001D552 <= code && code <= 0x0001D56B || 0x0001D586 <= code && code <= 0x0001D59F || 0x0001D5BA <= code && code <= 0x0001D5D3 || 0x0001D5EE <= code && code <= 0x0001D607 - else if code < 0x0001D74F then - 0x0001D622 <= code && code <= 0x0001D63B || 0x0001D656 <= code && code <= 0x0001D66F || 0x0001D68A <= code && code <= 0x0001D6A5 || 0x0001D6C2 <= code && code <= 0x0001D6DA || 0x0001D6DC <= code && code <= 0x0001D6E1 || 0x0001D6FC <= code && code <= 0x0001D714 || 0x0001D716 <= code && code <= 0x0001D71B || 0x0001D736 <= code && code <= 0x0001D74E + else if code < 0x0001D74F then + 0x0001D622 <= code && code <= 0x0001D63B || 0x0001D656 <= code && code <= 0x0001D66F || 0x0001D68A <= code && code <= 0x0001D6A5 || 0x0001D6C2 <= code && code <= 0x0001D6DA || 0x0001D6DC <= code && code <= 0x0001D6E1 || 0x0001D6FC <= code && code <= 0x0001D714 || 0x0001D716 <= code && code <= 0x0001D71B || 0x0001D736 <= code && code <= 0x0001D74E - else - 0x0001D750 <= code && code <= 0x0001D755 || 0x0001D770 <= code && code <= 0x0001D788 || 0x0001D78A <= code && code <= 0x0001D78F || 0x0001D7AA <= code && code <= 0x0001D7C2 || 0x0001D7C4 <= code && code <= 0x0001D7C9 || code == 0x0001D7CB || 0x0001DF00 <= code && code <= 0x0001DF09 || 0x0001DF0B <= code && code <= 0x0001DF1E || 0x0001DF25 <= code && code <= 0x0001DF2A + else + 0x0001D750 <= code && code <= 0x0001D755 || 0x0001D770 <= code && code <= 0x0001D788 || 0x0001D78A <= code && code <= 0x0001D78F || 0x0001D7AA <= code && code <= 0x0001D7C2 || 0x0001D7C4 <= code && code <= 0x0001D7C9 || code == 0x0001D7CB || 0x0001DF00 <= code && code <= 0x0001DF09 || 0x0001DF0B <= code && code <= 0x0001DF1E || 0x0001DF25 <= code && code <= 0x0001DF2A + ) ) @@ -71,26 +75,29 @@ unicodeIsUpperFast c = Char.toCode c in charCodeIsUpper code - || (let - cString : String - cString = - String.fromChar c - in - if String.toUpper cString == cString ++ "" && String.toLower cString /= cString ++ "" then - code <= 0x215F || 0x2170 <= code && code <= 0x24B5 || 0x24D0 <= code && code <= 0x000F0000 - - else if code < 0x0001D4CF then - if code < 0x213D then - 0x03D2 <= code && code <= 0x03D4 || code == 0x2102 || code == 0x2107 || 0x210B <= code && code <= 0x210D || 0x2110 <= code && code <= 0x2112 || code == 0x2115 || 0x2119 <= code && code <= 0x211D || code == 0x2124 || code == 0x2128 || 0x212A <= code && code <= 0x212D || 0x2130 <= code && code <= 0x2133 + || (code + > 0x7F + && (let + cString : String + cString = + String.fromChar c + in + if String.toUpper cString == cString ++ "" && String.toLower cString /= cString ++ "" then + code <= 0x215F || 0x2170 <= code && code <= 0x24B5 || 0x24D0 <= code && code <= 0x000F0000 + + else if code < 0x0001D4CF then + if code < 0x213D then + 0x03D2 <= code && code <= 0x03D4 || code == 0x2102 || code == 0x2107 || 0x210B <= code && code <= 0x210D || 0x2110 <= code && code <= 0x2112 || code == 0x2115 || 0x2119 <= code && code <= 0x211D || code == 0x2124 || code == 0x2128 || 0x212A <= code && code <= 0x212D || 0x2130 <= code && code <= 0x2133 - else - 0x213E <= code && code <= 0x213F || code == 0x2145 || 0x0001D400 <= code && code <= 0x0001D419 || 0x0001D434 <= code && code <= 0x0001D44D || 0x0001D468 <= code && code <= 0x0001D481 || code == 0x0001D49C || 0x0001D49E <= code && code <= 0x0001D49F || code == 0x0001D4A2 || 0x0001D4A5 <= code && code <= 0x0001D4A6 || 0x0001D4A9 <= code && code <= 0x0001D4AC || 0x0001D4AE <= code && code <= 0x0001D4B5 + else + 0x213E <= code && code <= 0x213F || code == 0x2145 || 0x0001D400 <= code && code <= 0x0001D419 || 0x0001D434 <= code && code <= 0x0001D44D || 0x0001D468 <= code && code <= 0x0001D481 || code == 0x0001D49C || 0x0001D49E <= code && code <= 0x0001D49F || code == 0x0001D4A2 || 0x0001D4A5 <= code && code <= 0x0001D4A6 || 0x0001D4A9 <= code && code <= 0x0001D4AC || 0x0001D4AE <= code && code <= 0x0001D4B5 - else if code < 0x0001D59F then - 0x0001D4D0 <= code && code <= 0x0001D4E9 || 0x0001D504 <= code && code <= 0x0001D505 || 0x0001D507 <= code && code <= 0x0001D50A || 0x0001D50D <= code && code <= 0x0001D514 || 0x0001D516 <= code && code <= 0x0001D51C || 0x0001D538 <= code && code <= 0x0001D539 || 0x0001D53B <= code && code <= 0x0001D53E || 0x0001D540 <= code && code <= 0x0001D544 || code == 0x0001D546 || 0x0001D54A <= code && code <= 0x0001D550 || 0x0001D56C <= code && code <= 0x0001D585 + else if code < 0x0001D59F then + 0x0001D4D0 <= code && code <= 0x0001D4E9 || 0x0001D504 <= code && code <= 0x0001D505 || 0x0001D507 <= code && code <= 0x0001D50A || 0x0001D50D <= code && code <= 0x0001D514 || 0x0001D516 <= code && code <= 0x0001D51C || 0x0001D538 <= code && code <= 0x0001D539 || 0x0001D53B <= code && code <= 0x0001D53E || 0x0001D540 <= code && code <= 0x0001D544 || code == 0x0001D546 || 0x0001D54A <= code && code <= 0x0001D550 || 0x0001D56C <= code && code <= 0x0001D585 - else - 0x0001D5A0 <= code && code <= 0x0001D5B9 || 0x0001D5D4 <= code && code <= 0x0001D5ED || 0x0001D608 <= code && code <= 0x0001D621 || 0x0001D63C <= code && code <= 0x0001D655 || 0x0001D670 <= code && code <= 0x0001D689 || 0x0001D6A8 <= code && code <= 0x0001D6C0 || 0x0001D6E2 <= code && code <= 0x0001D6FA || 0x0001D71C <= code && code <= 0x0001D734 || 0x0001D756 <= code && code <= 0x0001D76E || 0x0001D790 <= code && code <= 0x0001D7A8 || code == 0x0001D7CA + else + 0x0001D5A0 <= code && code <= 0x0001D5B9 || 0x0001D5D4 <= code && code <= 0x0001D5ED || 0x0001D608 <= code && code <= 0x0001D621 || 0x0001D63C <= code && code <= 0x0001D655 || 0x0001D670 <= code && code <= 0x0001D689 || 0x0001D6A8 <= code && code <= 0x0001D6C0 || 0x0001D6E2 <= code && code <= 0x0001D6FA || 0x0001D71C <= code && code <= 0x0001D734 || 0x0001D756 <= code && code <= 0x0001D76E || 0x0001D790 <= code && code <= 0x0001D7A8 || code == 0x0001D7CA + ) ) @@ -115,17 +122,16 @@ unicodeIsAlphaNumOrUnderscoreFast c = code = Char.toCode c in - charCodeIsLower code - || charCodeIsUpper code - || charCodeIsDigit code + (97 <= code && code <= 122) + || (65 <= code && code <= 90) + || (48 <= code && code <= 57) || -- (c == '_') (code == 95) - || -- if it's not obviously alphanum, - -- check if it's not some common end character and shortcut to False if possible - -- ((c /= ' ') && (c /= '\n')) - ((code /= 32) && (code /= 10)) + || -- For ASCII chars (0x00-0x7F), the above checks already catch all valid + -- identifier characters. Only enter the unicode table for non-ASCII. + (code > 0x7F) && (if code < 0x0100 then - 0x30 <= code && code <= 0x39 || 0x41 <= code && code <= 0x5A || 0x61 <= code && code <= 0x7A || code == 0xAA || 0xB2 <= code && code <= 0xB3 || code == 0xB5 || 0xB9 <= code && code <= 0xBA || 0xBC <= code && code <= 0xBE || 0xC0 <= code && code <= 0xD6 || 0xD8 <= code && code <= 0xF6 || 0xF8 <= code && code <= 0xFF + code == 0xAA || 0xB2 <= code && code <= 0xB3 || code == 0xB5 || 0xB9 <= code && code <= 0xBA || 0xBC <= code && code <= 0xBE || 0xC0 <= code && code <= 0xD6 || 0xD8 <= code && code <= 0xF6 || 0xF8 <= code && code <= 0xFF else if code < 0xAAB4 then if code < 0x10FB then diff --git a/src/Elm/Parser/Expression.elm b/src/Elm/Parser/Expression.elm index 2e3fd8cc..0302b600 100644 --- a/src/Elm/Parser/Expression.elm +++ b/src/Elm/Parser/Expression.elm @@ -56,8 +56,38 @@ subExpression = "'" -> charLiteralExpression + "0" -> + numberExpression + + "1" -> + numberExpression + + "2" -> + numberExpression + + "3" -> + numberExpression + + "4" -> + numberExpression + + "5" -> + numberExpression + + "6" -> + numberExpression + + "7" -> + numberExpression + + "8" -> + numberExpression + + "9" -> + numberExpression + _ -> - referenceOrNumberExpression + referenceExpression ) @@ -82,12 +112,11 @@ ifOrUnqualifiedReferenceExpression = unqualifiedFunctionReferenceExpressionFollowedByRecordAccess -referenceOrNumberExpression : Parser (WithComments (Node Expression)) -referenceOrNumberExpression = - ParserFast.oneOf3 +referenceExpression : Parser (WithComments (Node Expression)) +referenceExpression = + ParserFast.oneOf2 qualifiedOrVariantOrRecordConstructorReferenceExpressionFollowedByRecordAccess unqualifiedFunctionReferenceExpressionFollowedByRecordAccess - numberExpression multiRecordAccess : ParserFast.Parser (List (Node String)) diff --git a/src/ParserFast.elm b/src/ParserFast.elm index e2bf9c4b..5886f537 100644 --- a/src/ParserFast.elm +++ b/src/ParserFast.elm @@ -1606,7 +1606,7 @@ integerDecimalMapWithRange rangeAndIntToRes = s1 = convertIntegerDecimal s0.offset s0.src in - if s1.offset == -1 then + if s1.offset < 0 then Bad False (ExpectingNumber s0.row s0.col) else @@ -1659,7 +1659,7 @@ integerDecimalOrHexadecimalMapWithRange rangeAndIntDecimalToRes rangeAndIntHexad s1 = convertIntegerDecimalOrHexadecimal s0.offset s0.src in - if s1.offsetAndInt.offset == -1 then + if s1.offsetAndInt.offset < 0 then Bad False (ExpectingNumber s0.row s0.col) else @@ -1719,7 +1719,7 @@ floatOrIntegerDecimalOrHexadecimalMapWithRange rangeAndFloatToRes rangeAndIntDec s1 = convertIntegerDecimalOrHexadecimal s0.offset s0.src in - if s1.offsetAndInt.offset == -1 then + if s1.offsetAndInt.offset < 0 then Bad False (ExpectingNumber s0.row s0.col) else @@ -1728,7 +1728,7 @@ floatOrIntegerDecimalOrHexadecimalMapWithRange rangeAndFloatToRes rangeAndIntDec offsetAfterFloat = skipFloatAfterIntegerDecimal s1.offsetAndInt.offset s0.src in - if offsetAfterFloat == -1 then + if offsetAfterFloat < 0 then let newColumn : Int newColumn = @@ -1791,7 +1791,7 @@ skipFloatAfterIntegerDecimal offset src = offsetAfterDigits = skip1OrMoreDigits0To9 (offset + 1) src in - if offsetAfterDigits == -1 then + if offsetAfterDigits < 0 then -1 else @@ -2211,7 +2211,7 @@ symbol str res = newOffset = s.offset + strLength in - if String.slice s.offset newOffset s.src == str ++ "" then + if String.slice s.offset newOffset s.src == str then Good res { src = s.src , offset = newOffset @@ -2241,7 +2241,7 @@ followedBySymbol str (Parser parsePrevious) = newOffset = s1.offset + strLength in - if String.slice s1.offset newOffset s1.src == str ++ "" then + if String.slice s1.offset newOffset s1.src == str then Good res { src = s1.src , offset = newOffset @@ -2272,7 +2272,7 @@ symbolWithEndLocation str endLocationToRes = newOffset = s.offset + strLength in - if String.slice s.offset newOffset s.src == str ++ "" then + if String.slice s.offset newOffset s.src == str then let newCol : Int newCol = @@ -2306,7 +2306,7 @@ symbolWithRange str startAndEndLocationToRes = newOffset = s.offset + strLength in - if String.slice s.offset newOffset s.src == str ++ "" then + if String.slice s.offset newOffset s.src == str then let newCol : Int newCol = @@ -2343,7 +2343,7 @@ symbolFollowedBy str (Parser parseNext) = newOffset = s.offset + strLength in - if String.slice s.offset newOffset s.src == str ++ "" then + if String.slice s.offset newOffset s.src == str then parseNext { src = s.src , offset = newOffset @@ -2375,7 +2375,7 @@ symbolBacktrackableFollowedBy str (Parser parseNext) = newOffset = s.offset + strLength in - if String.slice s.offset newOffset s.src == str ++ "" then + if String.slice s.offset newOffset s.src == str then parseNext { src = s.src , offset = newOffset @@ -2428,7 +2428,7 @@ keyword kwd res = s.offset + kwdLength in if - (String.slice s.offset newOffset s.src == kwd ++ "") + (String.slice s.offset newOffset s.src == kwd) && not (isSubCharAlphaNumOrUnderscore newOffset s.src) then Good res @@ -2468,7 +2468,7 @@ keywordFollowedBy kwd (Parser parseNext) = s.offset + kwdLength in if - (String.slice s.offset newOffset s.src == kwd ++ "") + (String.slice s.offset newOffset s.src == kwd) && not (isSubCharAlphaNumOrUnderscore newOffset s.src) then parseNext @@ -2778,7 +2778,7 @@ ifFollowedByWhileValidateWithoutLinebreak firstIsOkay afterFirstIsOkay resultIsO firstOffset = isSubCharWithoutLinebreak firstIsOkay s.offset s.src in - if firstOffset == -1 then + if firstOffset < 0 then Bad False (ExpectingCharSatisfyingPredicate s.row s.col) else @@ -2862,7 +2862,7 @@ whileWithoutLinebreakAnd2PartUtf16ValidateMapWithRangeBacktrackableFollowedBySym in if (String.slice s1Offset (s1Offset + mandatoryFinalSymbolLength) s0.src - == (mandatoryFinalSymbol ++ "") + == mandatoryFinalSymbol ) && whileResultIsOkay whileContent then @@ -2904,7 +2904,7 @@ ifFollowedByWhileValidateMapWithRangeWithoutLinebreak toResult firstIsOkay after firstOffset = isSubCharWithoutLinebreak firstIsOkay s0.offset s0.src in - if firstOffset == -1 then + if firstOffset < 0 then Bad False (ExpectingCharSatisfyingPredicate s0.row s0.col) else @@ -2937,7 +2937,7 @@ ifFollowedByWhileWithoutLinebreak firstIsOkay afterFirstIsOkay = firstOffset = isSubCharWithoutLinebreak firstIsOkay s.offset s.src in - if firstOffset == -1 then + if firstOffset < 0 then Bad False (ExpectingCharSatisfyingPredicate s.row s.col) else @@ -2963,7 +2963,7 @@ ifFollowedByWhileMapWithRangeWithoutLinebreak rangeAndConsumedStringToRes firstI firstOffset = isSubCharWithoutLinebreak firstIsOkay s0.offset s0.src in - if firstOffset == -1 then + if firstOffset < 0 then Bad False (ExpectingCharSatisfyingPredicate s0.row s0.col) else @@ -2996,7 +2996,7 @@ ifFollowedByWhileMapWithoutLinebreak consumedStringToRes firstIsOkay afterFirstI firstOffset = isSubCharWithoutLinebreak firstIsOkay s0.offset s0.src in - if firstOffset == -1 then + if firstOffset < 0 then Bad False (ExpectingCharSatisfyingPredicate s0.row s0.col) else @@ -3024,9 +3024,22 @@ nestableMultiCommentMapWithRange rangeContentToRes ( openChar, openTail ) ( clos close = String.cons closeChar closeTail + openCharCode : Int + openCharCode = + Char.toCode openChar + + closeCharCode : Int + closeCharCode = + Char.toCode closeChar + isNotRelevant : Char -> Bool isNotRelevant char = - char /= openChar && char /= closeChar && not (Char.Extra.isUtf16Surrogate char) + let + charCode : Int + charCode = + Char.toCode char + in + charCode /= openCharCode && charCode /= closeCharCode && not (Char.Extra.isUtf16Surrogate char) in map2WithRange (\range afterOpen contentAfterAfterOpen -> @@ -3246,6 +3259,13 @@ The `newOffset` value can be a few different things: depending on whether the UTF16 character is one or two words wide. +Callers check failure with `< 0` rather than `== -1` because +the Elm compiler does not optimize `== -1` to `===`. Negative +numbers are compiled as a prefix negate expression, not a literal, +so `isLiteral` returns False and `==` falls back to `_Utils_eq` +which allocates on every call. +See https://github.com/elm/compiler/blob/0.19.1/compiler/src/Generate/JavaScript/Expression.hs#L549-L592 + -} isSubCharWithoutLinebreak : (Char -> Bool) -> Int -> String -> Int isSubCharWithoutLinebreak predicate offset string =