You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.8 KiB

4 years ago
  1. include import "./lib/parsers.ml"
  2. open import "prelude.ml"
  3. let lex = run_parser
  4. let line_comment () =
  5. let! _ = symbol "--"
  6. let rec go =
  7. let! x = map (const "\n") eof <|> char
  8. if x == "\n" then
  9. pure ()
  10. else
  11. go
  12. go
  13. let whitepiece : forall 'm. monad 'm => parser_t 'm () =
  14. (try (void @@ one_of " \n\v\t\r") <|> try (line_comment ()))
  15. <?> "white space"
  16. let whitespace : forall 'm. monad 'm => parser_t 'm () =
  17. void (many whitepiece)
  18. let lexeme p =
  19. let! _ = whitespace
  20. p
  21. let oparen : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "(")
  22. let cparen : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol ")")
  23. let comma : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol ",")
  24. let semi : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol ";")
  25. let osquare : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "[")
  26. let csquare : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "]")
  27. let obrace : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "{")
  28. let cbrace : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "}")
  29. let back : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "\\")
  30. let arrow : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "->")
  31. let darrow : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "=>")
  32. let equals : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "=")
  33. let pipe : forall 'm. monad 'm => parser_t 'm () = try @@ void @@ lexeme (symbol "|")
  34. let small : forall 'm. monad 'm => parser_t 'm string =
  35. try (satisfy (fun c -> "a" <= c && c <= "z") <|> symbol "_") <?> "small letter"
  36. let big : forall 'm. monad 'm => parser_t 'm string =
  37. try (satisfy (fun c -> "A" <= c && c <= "Z")) <?> "big letter"
  38. let iskw = function
  39. | "case"
  40. | "class"
  41. | "data"
  42. | "default"
  43. | "deriving"
  44. | "do"
  45. | "else"
  46. | "if"
  47. | "import"
  48. | "in"
  49. | "infix"
  50. | "infixl"
  51. | "infixr"
  52. | "instance"
  53. | "let"
  54. | "module"
  55. | "newtype"
  56. | "of"
  57. | "then"
  58. | "type"
  59. | "where"
  60. | "_" -> true
  61. | _ -> false
  62. let isreserved = function
  63. | "=" | "=>" | "->" | "|" -> true
  64. | _ -> false
  65. let varid : forall 'm. monad 'm => parser_t 'm string =
  66. flip (<?>) "variable name" # lexeme @@
  67. let! c = small
  68. let! cs =
  69. many_fold (^) "" (small <|> big <|> try (symbol "'"))
  70. <|> pure ""
  71. let id = c ^ cs
  72. if iskw id then
  73. unexpected id
  74. else
  75. pure id
  76. let conid : forall 'm. monad 'm => parser_t 'm string =
  77. flip (<?>) "constructor name" # lexeme @@
  78. let! c = big
  79. let! cs =
  80. many_fold (^) "" (small <|> big <|> try (symbol "'"))
  81. <|> pure ""
  82. pure (c ^ cs)
  83. let tyvar = varid
  84. let tycon = conid
  85. let tycls = conid
  86. let keyword c = lexeme (symbol c) <?> "``" ^ c ^ "''"
  87. let operator : forall 'm. monad 'm => parser_t 'm string =
  88. flip (<?>) "operator" # lexeme @@
  89. let! c = one_of "!#$%&*+./<=>?@\\^|-~"
  90. let! cs = many_fold (^) "" (one_of ":!#$%&*+./<=>?@\\^|-~")
  91. let op = c ^ cs
  92. if isreserved op then
  93. unexpected op
  94. else
  95. pure op
  96. let digit : forall 'm. monad 'm => parser_t 'm string =
  97. satisfy (fun c -> "0" <= c && c <= "9") <?> "digit"
  98. let hexit : forall 'm. monad 'm => parser_t 'm string =
  99. digit
  100. <|> satisfy (fun c -> "a" <= c && c <= "f")
  101. <|> satisfy (fun c -> "A" <= c && c <= "F")
  102. let integer : forall 'm. monad 'm => parser_t 'm int =
  103. let decimal =
  104. let! c = digit
  105. let! cs = many_fold (^) "" digit
  106. pure (c ^ cs)
  107. let hexadecimal =
  108. let! _ = symbol "0x"
  109. let! c = hexit
  110. let! cs = many_fold (^) "" hexit
  111. pure ("0x" ^ c ^ cs)
  112. let! c = (try hexadecimal <|> decimal) <?> "hex or decimal integer"
  113. match parse_int c with
  114. | None -> error "no parse"
  115. | Some x -> pure x