module Ivory.Language.Syntax.Concrete.Lexeme where
import Numeric (readInt)
import Data.Char (digitToInt)
import Ivory.Language.Syntax.Concrete.Location
type Lexeme = Located Token
data Token =
TokInteger Integer
| TokFloat Double
| TokString String
| TokHex Integer
| TokBitLit (Integer, Integer)
| TokIdent String
| TokTyIdent String
| TokReserved String
| TokSym String
| TokBrack String
| TokSep String
| TokEOF
| TokError String
deriving (Show, Read, Eq)
readBitLit :: String -> Token
readBitLit s =
let (width, val) = break (== 'b') s in
let w = case reads width of
[(i,"")] -> i
_ -> error $ "Lex error on bitWidth " ++ width
in
TokBitLit (w, readBin (tail val))
readBin :: (Show a, Eq a, Num a) => String -> a
readBin s =
case readInt 2 (`elem` "01") digitToInt s of
[(v,"")] -> v
ls -> error $ "Impossible lex error on binary integer " ++ show ls
readInteger :: String -> Token
readInteger s = case reads s of
[(i,"")] -> TokInteger i
_ -> error $ "Lex error on integer " ++ s
readFloat :: String -> Token
readFloat s = case reads s of
[(f,"")] -> TokFloat f
_ -> error $ "Lex error on float " ++ s
readStringLit :: String -> Token
readStringLit s = case reads s of
[(s',"")] -> TokString s'
_ -> error $ "Lex error on string " ++ s