diff options
Diffstat (limited to 'parser.hs')
-rw-r--r-- | parser.hs | 41 |
1 files changed, 28 insertions, 13 deletions
@@ -28,7 +28,7 @@ pProgram :: Parser Program pProgram = pWhiteComment >> (Program <$> many1 pDeclaration) pDeclaration :: Parser Declaration -pDeclaration = pDecTypedef <|> do +pDeclaration = pDecTypedef <|> pDecExtern <|> do t <- pTypeVoid <|> pType n <- pName if t == TypeVoid @@ -44,6 +44,14 @@ pDecTypedef = do symbol ";" return $ DecTypedef t n +pDecExtern :: Parser Declaration +pDecExtern = do + symbol "extern" + t <- pType + n <- pName + symbol ";" + return $ DecExtern t n + pDecFunction' :: Type -> Name -> Parser Declaration pDecFunction' t n = do symbol "(" @@ -97,7 +105,7 @@ pExLit :: Parser Expression pExLit = exLit_ <$> pLiteral pLiteral :: Parser Literal -pLiteral = (LitInt <$> pInteger) <|> (LitString <$> pString) +pLiteral = (LitInt <$> pInteger) <|> (LitInt <$> pCharStr) <|> (LitString <$> pString) <|> try pLitCall <|> (LitVar <$> pName) pLitCall :: Parser Literal @@ -224,23 +232,30 @@ pString = do s <- many (pEscape <|> satisfy (/='"')) symbol "\"" return s - where - pEscape :: Parser Char - pEscape = char '\\' >> (pEscapeQuote <|> pEscapeN <|> pEscapeR <|> pEscapeT <|> pEscapeHex) +pCharStr :: Parser Integer +pCharStr = do + void $ char '\'' + c <- pEscape <|> satisfy (/='\'') + symbol "'" + return $ fromIntegral (ord c) + +pEscape :: Parser Char +pEscape = char '\\' >> (pEscapeQuote <|> pEscapeN <|> pEscapeR <|> pEscapeT <|> pEscapeHex) + where pEscapeQuote, pEscapeN, pEscapeR, pEscapeT :: Parser Char - pEscapeQuote = '"' <$ char '"' + pEscapeQuote = ('"' <$ char '"') <|> ('\'' <$ char '\'') pEscapeN = '\n' <$ char 'n' pEscapeR = '\r' <$ char 'r' pEscapeT = '\t' <$ char 't' - pEscapeHex :: Parser Char - pEscapeHex = do - void $ char 'x' - c1 <- pHexChar - c2 <- pHexChar - return $ chr $ 16 * c1 + c2 - +pEscapeHex :: Parser Char +pEscapeHex = do + void $ char 'x' + c1 <- pHexChar + c2 <- pHexChar + return $ chr $ 16 * c1 + c2 + where pHexChar :: Parser Int pHexChar = (liftM (\c -> ord c - ord '0') (satisfy isDigit)) <|> (liftM (\c -> ord c - ord 'a' + 10) (oneOf "abcdef")) |