add binary literals

Written via "0b" in the manner of other literals. e.g. 0b111001 = 57
This commit is contained in:
MarcelineVQ 2020-08-30 12:21:47 -07:00 committed by G. Allais
parent 7de26e7d75
commit 57e7f14bca
4 changed files with 37 additions and 1 deletions

View File

@ -203,6 +203,20 @@ reservedSymbols
["%", "\\", ":", "=", "|", "|||", "<-", "->", "=>", "?", "!",
"&", "**", "..", "~"]
fromBinLit : String -> Integer
fromBinLit str
= if length str <= 2
then 0
else let num = assert_total (strTail (strTail str)) in
fromBin . reverse . map castBin . unpack $ num
where
castBin : Char -> Integer
castBin '1' = 1; castBin _ = 0 -- This can only be '1' and '0' once lexed
fromBin : List Integer -> Integer
fromBin [] = 0
fromBin (0 :: xs) = 2 * fromBin xs
fromBin (1 :: xs) = 1 + (2 * fromBin xs)
fromHexLit : String -> Integer
fromHexLit str
= if length str <= 2
@ -230,6 +244,7 @@ rawTokens =
(holeIdent, \x => HoleIdent (assert_total (strTail x)))] ++
map (\x => (exact x, Symbol)) symbols ++
[(doubleLit, \x => DoubleLit (cast x)),
(binLit, \x => IntegerLit (fromBinLit x)),
(hexLit, \x => IntegerLit (fromHexLit x)),
(octLit, \x => IntegerLit (fromOctLit x)),
(digits, \x => IntegerLit (cast x)),

View File

@ -166,6 +166,18 @@ export
digits : Lexer
digits = some digit
||| Recognise a single binary digit
||| /[0-1]/
export
binDigit : Lexer
binDigit = pred (\c => c == '0' || c == '1')
||| Recognise one or more binary digits
||| /[0-1]+/
export
binDigits : Lexer
binDigits = some binDigit
||| Recognise a single hexidecimal digit
||| /[0-9A-Fa-f]/
export
@ -332,6 +344,7 @@ charLit = let q = '\'' in
"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB",
"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US",
"SP", "DEL"]
<|> (is 'b' <+> binDigits)
<|> (is 'x' <+> hexDigits)
<|> (is 'o' <+> octDigits)
<|> digits
@ -342,6 +355,12 @@ export
intLit : Lexer
intLit = opt (is '-') <+> digits
||| Recognise a binary literal, prefixed by "0b"
||| /0b[0-1]+/
export
binLit : Lexer
binLit = exact "0b" <+> binDigits
||| Recognise a hexidecimal literal, prefixed by "0x" or "0X"
||| /0[Xx][0-9A-Fa-f]+/
export
@ -349,7 +368,7 @@ hexLit : Lexer
hexLit = approx "0x" <+> hexDigits
||| Recognise an octal literal, prefixed by "0o"
||| /0[Xx][0-9A-Fa-f]+/
||| /0o[0-9A-Fa-f]+/
export
octLit : Lexer
octLit = exact "0o" <+> octDigits

View File

@ -1,5 +1,6 @@
1/1: Building matchlits (matchlits.idr)
Main> Main.test1 : Int -> Int
test1 5 = 5
test1 256 = 42
test1 64 = 43
test1 1234567890 = 44

View File

@ -1,4 +1,5 @@
test1 : Int -> Int
test1 0b101 = 5
test1 0x100 = 42
test1 0o100 = 43
test1 1234567890 = 44