@@ -8,7 +8,7 @@ module Compiler.Parse.Number exposing
88
99import Compiler.AST.Utils.Binop as Binop
1010import Compiler.Parse.Primitives as P exposing (Col , Row )
11- import Compiler.Parse.SyntaxVersion as SyntaxVersion exposing (SyntaxVersion )
11+ import Compiler.Parse.SyntaxVersion as SV exposing (SyntaxVersion )
1212import Compiler.Parse.Variable as Var
1313import Compiler.Reporting.Error.Syntax as E
1414
@@ -49,7 +49,7 @@ number syntaxVersion toExpectation toError =
4949 word =
5050 charAtPos pos src
5151 in
52- if word == ' _' && isGuida syntaxVersion then
52+ if word == ' _' && syntaxVersion == SV . Guida then
5353 P . Cerr row col ( toError E . NumberNoLeadingOrTrailingUnderscores )
5454
5555 else if not ( isDecimalDigit word) then
@@ -102,8 +102,9 @@ number syntaxVersion toExpectation toError =
102102
103103 parsed : Maybe Float
104104 parsed =
105- if isGuida syntaxVersion then
106- String . replace " _" " " raw |> String . toFloat
105+ if syntaxVersion == SV . Guida then
106+ String . replace " _" " " raw
107+ |> String . toFloat
107108
108109 else
109110 String . toFloat raw
@@ -155,7 +156,7 @@ chompInt syntaxVersion src pos end n =
155156 else if word == ' e' || word == ' E' then
156157 chompExponent syntaxVersion src ( pos + 1 ) end
157158
158- else if isGuida syntaxVersion && word == ' _' then
159+ else if word == ' _' && syntaxVersion == SV . Guida then
159160 chompUnderscore_ syntaxVersion src pos end n
160161
161162 else if isDirtyEnd src pos end word then
@@ -255,7 +256,7 @@ chompFraction syntaxVersion src pos end n =
255256 nextWord =
256257 charAtPos pos1 src
257258 in
258- if isGuida syntaxVersion && nextWord == ' _' then
259+ if nextWord == ' _' && syntaxVersion == SV . Guida then
259260 Err_ ( pos + 1 ) E . NumberNoUnderscoresAdjacentToDecimalOrExponent
260261
261262 else if isDecimalDigit nextWord then
@@ -279,7 +280,7 @@ chompFractionHelp syntaxVersion src pos end =
279280 if isDecimalDigit word then
280281 chompFractionHelp syntaxVersion src ( pos + 1 ) end
281282
282- else if isGuida syntaxVersion && word == ' _' then
283+ else if word == ' _' && syntaxVersion == SV . Guida then
283284 if ( pos + 1 ) == end then
284285 Err_ pos E . NumberNoLeadingOrTrailingUnderscores
285286
@@ -326,7 +327,7 @@ chompExponent syntaxVersion src pos end =
326327 if isDecimalDigit word then
327328 chompExponentHelp syntaxVersion src ( pos + 1 ) end
328329
329- else if isGuida syntaxVersion && word == ' _' then
330+ else if word == ' _' && syntaxVersion == SV . Guida then
330331 Err_ pos E . NumberNoUnderscoresAdjacentToDecimalOrExponent
331332
332333 else if word == ' +' || word == ' -' then
@@ -339,7 +340,7 @@ chompExponent syntaxVersion src pos end =
339340 nextWord =
340341 charAtPos pos1 src
341342 in
342- if isGuida syntaxVersion && nextWord == ' _' then
343+ if nextWord == ' _' && syntaxVersion == SV . Guida then
343344 Err_ ( pos + 1 ) E . NumberNoUnderscoresAdjacentToDecimalOrExponent
344345
345346 else if pos1 < end && isDecimalDigit nextWord then
@@ -363,7 +364,7 @@ chompExponentHelp syntaxVersion src pos end =
363364 word =
364365 charAtPos pos src
365366 in
366- if isDecimalDigit word || ( isGuida syntaxVersion && word == ' _' ) then
367+ if isDecimalDigit word || ( word == ' _' && syntaxVersion == SV . Guida ) then
367368 chompExponentHelp syntaxVersion src ( pos + 1 ) end
368369
369370 else
@@ -386,12 +387,19 @@ chompZero syntaxVersion src pos end =
386387 charAtPos pos src
387388 in
388389 if word == ' x' then
389- if isGuida syntaxVersion && charAtPos ( pos + 1 ) src == ' _' then
390+ if charAtPos ( pos + 1 ) src == ' _' && syntaxVersion == SV . Guida then
390391 Err_ ( pos + 1 ) E . NumberNoUnderscoresAdjacentToHexadecimalPreFix
391392
392393 else
393394 chompHexInt syntaxVersion src ( pos + 1 ) end
394395
396+ else if word == ' b' && syntaxVersion == SV . Guida then
397+ if charAtPos ( pos + 1 ) src == ' _' then
398+ Err_ ( pos + 1 ) E . NumberNoUnderscoresAdjacentToBinaryPreFix
399+
400+ else
401+ chompBinInt src ( pos + 1 ) end
402+
395403 else if word == ' .' then
396404 chompFraction syntaxVersion src pos end 0
397405
@@ -424,6 +432,25 @@ chompHexInt syntaxVersion src pos end =
424432 OkInt newPos answer
425433
426434
435+ chompBinInt : String -> Int -> Int -> Outcome
436+ chompBinInt src pos end =
437+ let
438+ ( newPos, answer ) =
439+ chompBin src pos end
440+ in
441+ if answer == - 4 then
442+ Err_ ( newPos + 1 ) E . NumberNoConsecutiveUnderscores
443+
444+ else if answer == - 3 then
445+ Err_ newPos E . NumberNoLeadingOrTrailingUnderscores
446+
447+ else if answer < 0 then
448+ Err_ newPos E . NumberBinDigit
449+
450+ else
451+ OkInt newPos answer
452+
453+
427454
428455-- CHOMP HEX
429456
@@ -474,7 +501,7 @@ stepHex syntaxVersion src pos end word acc =
474501 else if ' A' <= word && word <= ' F' then
475502 16 * acc + 10 + ( Char . toCode word - Char . toCode ' A')
476503
477- else if isGuida syntaxVersion && ' _' == word then
504+ else if word == ' _' && syntaxVersion == SV . Guida then
478505 let
479506 nextWord : Char
480507 nextWord =
@@ -505,6 +532,78 @@ stepHex syntaxVersion src pos end word acc =
505532
506533
507534
535+ -- CHOMP BIN
536+
537+
538+ chompBin : String -> Int -> Int -> ( Int , Int )
539+ chompBin src pos end =
540+ chompBinHelp src pos end - 1 0
541+
542+
543+ chompBinHelp : String -> Int -> Int -> Int -> Int -> ( Int , Int )
544+ chompBinHelp src pos end answer accumulator =
545+ if pos >= end then
546+ ( pos, answer )
547+
548+ else
549+ let
550+ newAnswer : Int
551+ newAnswer =
552+ stepBin src pos end ( charAtPos pos src) accumulator
553+ in
554+ if newAnswer < 0 then
555+ ( pos
556+ , if newAnswer == - 1 then
557+ answer
558+
559+ else if newAnswer == - 3 then
560+ - 3
561+
562+ else if newAnswer == - 4 then
563+ - 4
564+
565+ else
566+ - 2
567+ )
568+
569+ else
570+ chompBinHelp src ( pos + 1 ) end newAnswer newAnswer
571+
572+
573+ stepBin : String -> Int -> Int -> Char -> Int -> Int
574+ stepBin src pos end word acc =
575+ if ' 0' <= word && word <= ' 1' then
576+ 2 * acc + ( Char . toCode word - Char . toCode ' 0')
577+
578+ else if word == ' _' then
579+ let
580+ nextWord : Char
581+ nextWord =
582+ charAtPos ( pos + 1 ) src
583+ in
584+ if nextWord == ' _' then
585+ - 4
586+
587+ else
588+ let
589+ validNextWord : Bool
590+ validNextWord =
591+ ' 0' <= nextWord && nextWord <= ' 1'
592+ in
593+ if pos + 1 == end || not validNextWord then
594+ - 3
595+
596+ else
597+ acc
598+
599+ else if isDirtyEnd src pos end word then
600+ - 2
601+
602+ else
603+ - 1
604+
605+
606+
508607-- PRECEDENCE
509608
510609
@@ -531,7 +630,7 @@ precedence toExpectation =
531630
532631
533632
534- -- helpers
633+ -- CHAR AT POSITION
535634
536635
537636charAtPos : Int -> String -> Char
@@ -540,8 +639,3 @@ charAtPos pos src =
540639 |> String . uncons
541640 |> Maybe . map Tuple . first
542641 |> Maybe . withDefault ' '
543-
544-
545- isGuida : SyntaxVersion -> Bool
546- isGuida syntaxVersion =
547- syntaxVersion == SyntaxVersion . Guida
0 commit comments