@@ -8,7 +8,7 @@ module Compiler.Parse.Number exposing
8
8
9
9
import Compiler.AST.Utils.Binop as Binop
10
10
import 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 )
12
12
import Compiler.Parse.Variable as Var
13
13
import Compiler.Reporting.Error.Syntax as E
14
14
@@ -49,7 +49,7 @@ number syntaxVersion toExpectation toError =
49
49
word =
50
50
charAtPos pos src
51
51
in
52
- if word == ' _' && isGuida syntaxVersion then
52
+ if word == ' _' && syntaxVersion == SV . Guida then
53
53
P . Cerr row col ( toError E . NumberNoLeadingOrTrailingUnderscores )
54
54
55
55
else if not ( isDecimalDigit word) then
@@ -102,8 +102,9 @@ number syntaxVersion toExpectation toError =
102
102
103
103
parsed : Maybe Float
104
104
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
107
108
108
109
else
109
110
String . toFloat raw
@@ -155,7 +156,7 @@ chompInt syntaxVersion src pos end n =
155
156
else if word == ' e' || word == ' E' then
156
157
chompExponent syntaxVersion src ( pos + 1 ) end
157
158
158
- else if isGuida syntaxVersion && word == ' _' then
159
+ else if word == ' _' && syntaxVersion == SV . Guida then
159
160
chompUnderscore_ syntaxVersion src pos end n
160
161
161
162
else if isDirtyEnd src pos end word then
@@ -255,7 +256,7 @@ chompFraction syntaxVersion src pos end n =
255
256
nextWord =
256
257
charAtPos pos1 src
257
258
in
258
- if isGuida syntaxVersion && nextWord == ' _' then
259
+ if nextWord == ' _' && syntaxVersion == SV . Guida then
259
260
Err_ ( pos + 1 ) E . NumberNoUnderscoresAdjacentToDecimalOrExponent
260
261
261
262
else if isDecimalDigit nextWord then
@@ -279,7 +280,7 @@ chompFractionHelp syntaxVersion src pos end =
279
280
if isDecimalDigit word then
280
281
chompFractionHelp syntaxVersion src ( pos + 1 ) end
281
282
282
- else if isGuida syntaxVersion && word == ' _' then
283
+ else if word == ' _' && syntaxVersion == SV . Guida then
283
284
if ( pos + 1 ) == end then
284
285
Err_ pos E . NumberNoLeadingOrTrailingUnderscores
285
286
@@ -326,7 +327,7 @@ chompExponent syntaxVersion src pos end =
326
327
if isDecimalDigit word then
327
328
chompExponentHelp syntaxVersion src ( pos + 1 ) end
328
329
329
- else if isGuida syntaxVersion && word == ' _' then
330
+ else if word == ' _' && syntaxVersion == SV . Guida then
330
331
Err_ pos E . NumberNoUnderscoresAdjacentToDecimalOrExponent
331
332
332
333
else if word == ' +' || word == ' -' then
@@ -339,7 +340,7 @@ chompExponent syntaxVersion src pos end =
339
340
nextWord =
340
341
charAtPos pos1 src
341
342
in
342
- if isGuida syntaxVersion && nextWord == ' _' then
343
+ if nextWord == ' _' && syntaxVersion == SV . Guida then
343
344
Err_ ( pos + 1 ) E . NumberNoUnderscoresAdjacentToDecimalOrExponent
344
345
345
346
else if pos1 < end && isDecimalDigit nextWord then
@@ -363,7 +364,7 @@ chompExponentHelp syntaxVersion src pos end =
363
364
word =
364
365
charAtPos pos src
365
366
in
366
- if isDecimalDigit word || ( isGuida syntaxVersion && word == ' _' ) then
367
+ if isDecimalDigit word || ( word == ' _' && syntaxVersion == SV . Guida ) then
367
368
chompExponentHelp syntaxVersion src ( pos + 1 ) end
368
369
369
370
else
@@ -386,12 +387,19 @@ chompZero syntaxVersion src pos end =
386
387
charAtPos pos src
387
388
in
388
389
if word == ' x' then
389
- if isGuida syntaxVersion && charAtPos ( pos + 1 ) src == ' _' then
390
+ if charAtPos ( pos + 1 ) src == ' _' && syntaxVersion == SV . Guida then
390
391
Err_ ( pos + 1 ) E . NumberNoUnderscoresAdjacentToHexadecimalPreFix
391
392
392
393
else
393
394
chompHexInt syntaxVersion src ( pos + 1 ) end
394
395
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
+
395
403
else if word == ' .' then
396
404
chompFraction syntaxVersion src pos end 0
397
405
@@ -424,6 +432,25 @@ chompHexInt syntaxVersion src pos end =
424
432
OkInt newPos answer
425
433
426
434
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
+
427
454
428
455
-- CHOMP HEX
429
456
@@ -474,7 +501,7 @@ stepHex syntaxVersion src pos end word acc =
474
501
else if ' A' <= word && word <= ' F' then
475
502
16 * acc + 10 + ( Char . toCode word - Char . toCode ' A')
476
503
477
- else if isGuida syntaxVersion && ' _' == word then
504
+ else if word == ' _' && syntaxVersion == SV . Guida then
478
505
let
479
506
nextWord : Char
480
507
nextWord =
@@ -505,6 +532,78 @@ stepHex syntaxVersion src pos end word acc =
505
532
506
533
507
534
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
+
508
607
-- PRECEDENCE
509
608
510
609
@@ -531,7 +630,7 @@ precedence toExpectation =
531
630
532
631
533
632
534
- -- helpers
633
+ -- CHAR AT POSITION
535
634
536
635
537
636
charAtPos : Int -> String -> Char
@@ -540,8 +639,3 @@ charAtPos pos src =
540
639
|> String . uncons
541
640
|> Maybe . map Tuple . first
542
641
|> Maybe . withDefault ' '
543
-
544
-
545
- isGuida : SyntaxVersion -> Bool
546
- isGuida syntaxVersion =
547
- syntaxVersion == SyntaxVersion . Guida
0 commit comments