summaryrefslogtreecommitdiff
path: root/parser.hs
diff options
context:
space:
mode:
Diffstat (limited to 'parser.hs')
-rw-r--r--parser.hs36
1 files changed, 27 insertions, 9 deletions
diff --git a/parser.hs b/parser.hs
index 46bd3d0..615f6e7 100644
--- a/parser.hs
+++ b/parser.hs
@@ -29,9 +29,11 @@ pProgram = pWhiteComment >> (Program <$> many1 pDeclaration)
pDeclaration :: Parser Declaration
pDeclaration = pDecTypedef <|> do
- t <- pType
+ t <- pTypeVoid <|> pType
n <- pName
- pDecFunction' t n <|> pDecVariable' t n
+ if t == TypeVoid
+ then pDecFunction' t n
+ else pDecFunction' t n <|> pDecVariable' t n
pDecTypedef :: Parser Declaration
pDecTypedef = do
@@ -158,9 +160,10 @@ pStWhile = do
pStReturn :: Parser Statement
pStReturn = do
symbol "return"
- e <- pExpression
- symbol ";"
- return $ StReturn e
+ (symbol ";" >> return (StReturn Nothing)) <|> do
+ e <- pExpression
+ symbol ";"
+ return $ StReturn (Just e)
primitiveTypes :: Map.Map String Type
@@ -173,7 +176,7 @@ findPrimType :: String -> Type
findPrimType s = fromJust $ Map.lookup s primitiveTypes
pType :: Parser Type
-pType = pPrimType <|> pPtrType <|> pTypeName
+pType = pPrimType <|> pTypePtr <|> pTypeFunc <|> pTypeName
pPrimType :: Parser Type
pPrimType = findPrimType <$> choice (map typeParser $ Map.keys primitiveTypes)
@@ -183,14 +186,26 @@ pPrimType = findPrimType <$> choice (map typeParser $ Map.keys primitiveTypes)
pWhiteComment
return t
-pPtrType :: Parser Type
-pPtrType = do
+pTypeVoid :: Parser Type
+pTypeVoid = symbol "void" >> return TypeVoid
+
+pTypePtr :: Parser Type
+pTypePtr = do
symbol "ptr"
symbol "("
t <- pType
symbol ")"
return $ TypePtr t
+pTypeFunc :: Parser Type
+pTypeFunc = do
+ symbol "func"
+ r <- pTypeVoid <|> pType
+ symbol "("
+ a <- sepBy pType (symbol ",")
+ symbol ")"
+ return $ TypeFunc r a
+
pTypeName :: Parser Type
pTypeName = TypeName <$> pName
@@ -232,7 +247,10 @@ pString = do
<|> (liftM (\c -> ord c - ord 'A' + 10) (oneOf "ABCDEF"))
symbol :: String -> Parser ()
-symbol s = try (string s) >> pWhiteComment
+symbol s = do
+ void $ try (string s)
+ when (isAlphaNum (last s)) $ notFollowedBy alphaNum
+ pWhiteComment
pWhiteComment :: Parser ()
pWhiteComment = sepBy pWhitespace pComment >> return ()