1. module Parser where
    2. import Text.Parsec
    3. import Text.Parsec.String (Parser)
    4. import qualified Text.Parsec.Expr as Ex
    5. import qualified Text.Parsec.Token as Tok
    6. import Lexer
    7. import Syntax
    8. binary s f assoc = Ex.Infix (reservedOp s >> return (BinOp f)) assoc
    9. table = [[binary "*" Times Ex.AssocLeft,
    10. binary "/" Divide Ex.AssocLeft]
    11. ,[binary "+" Plus Ex.AssocLeft,
    12. binary "-" Minus Ex.AssocLeft]]
    13. int :: Parser Expr
    14. int = do
    15. n <- integer
    16. return $ Float (fromInteger n)
    17. floating :: Parser Expr
    18. floating = do
    19. return $ Float n
    20. expr :: Parser Expr
    21. variable :: Parser Expr
    22. variable = do
    23. var <- identifier
    24. return $ Var var
    25. function :: Parser Expr
    26. function = do
    27. reserved "def"
    28. name <- identifier
    29. args <- parens $ many variable
    30. body <- expr
    31. return $ Function name args body
    32. extern :: Parser Expr
    33. extern = do
    34. reserved "extern"
    35. name <- identifier
    36. args <- parens $ many variable
    37. return $ Extern name args
    38. call :: Parser Expr
    39. call = do
    40. name <- identifier
    41. args <- parens $ commaSep expr
    42. return $ Call name args
    43. factor :: Parser Expr
    44. factor = try floating
    45. <|> try extern
    46. <|> try function
    47. <|> try call
    48. <|> variable
    49. <|> parens expr
    50. defn :: Parser Expr
    51. defn = try extern
    52. <|> try function
    53. <|> expr
    54. contents :: Parser a -> Parser a
    55. contents p = do
    56. Tok.whiteSpace lexer
    57. r <- p
    58. eof
    59. return r
    60. toplevel :: Parser [Expr]
    61. toplevel = many $ do
    62. def <- defn
    63. reservedOp ";"
    64. return def
    65. parseExpr :: String -> Either ParseError Expr
    66. parseExpr s = parse (contents expr) "<stdin>" s
    67. parseToplevel s = parse (contents toplevel) "<stdin>" s