Advertisement
Guest User

Untitled

a guest
Jan 17th, 2015
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.75 KB | None | 0 0
  1. #include "share/atspre_staload.hats"
  2. #include "share/HATS/atspre_staload_libats_ML.hats"
  3.  
  4. typedef cfun1 (a:t@ype, b:t@ype) = a -<cloref1> b
  5. typedef cfun2 (a:t@ype, b:t@ype, c:t@ype) = (a,b) -<cloref1> c
  6.  
  7. // ----------------------------------------------------------------------
  8. // ----------------------- INPUT ----------------------------------------
  9. // ----------------------------------------------------------------------
  10.  
  11. abstype input_type = ptr
  12. stadef input_t = input_type
  13.  
  14. extern fun create_input(content: string): input_t
  15. extern fun avail_input(input: input_t, pos: size_t, nchars: size_t): bool
  16. extern fun get_input(input: input_t, pos: size_t, nchars: size_t): string
  17.  
  18. local
  19. extern castfn string_2_input(content: string):<> input_t
  20. extern castfn input_2_string(input: input_t):<> string
  21. in
  22. implement create_input(content) = string_2_input(content)
  23.  
  24. implement avail_input(input, pos, nchars) = let
  25. val len = length(input_2_string(input))
  26. in nchars <= (len-pos) end
  27.  
  28. implement get_input(input, pos, nchars) = let
  29. val ins = input_2_string(input)
  30. in string_make_substring(ins, pos, nchars) end
  31. end
  32.  
  33. // -----------------------------------------------------------------------
  34. // ----------------------- STATUS ----------------------------------------
  35. // -----------------------------------------------------------------------
  36.  
  37. abstype status_type(a: t@ype) = ptr
  38. stadef status_t = status_type
  39.  
  40. extern fun{a: t@ype} success_status(index: size_t, value: a): status_t(a)
  41. extern fun{a: t@ype} value_status(status: status_t(a)): Option(a)
  42. extern fun{a: t@ype} expected_status(status: status_t(a)): string
  43. extern fun{a: t@ype} index_status(status: status_t(a)): size_t
  44. extern fun{a: t@ype} flag_status(status: status_t(a)): bool
  45. extern fun{a: t@ype} failure_status(index: size_t, expected: string): status_t(a)
  46. extern fun{a: t@ype} print_status(status: status_t(a)): void
  47. extern fun{a: t@ype} print_error_status(status: status_t(a)): void
  48.  
  49. local
  50. datatype status_dt(a: t@ype) =
  51. | Success of (size_t, a)
  52. | Failure of (size_t, string)
  53.  
  54. assume status_type = status_dt
  55. in
  56. implement{a} success_status(index, value) = Success{a}(index, value)
  57. implement{a} failure_status(index, expected) = Failure{a}(index, expected)
  58.  
  59. implement{a} index_status(status) = case+ status of
  60. | Failure(index, _) => index
  61. | Success(index, _) => index
  62.  
  63. implement{a} value_status(status) = case+ status of
  64. | Success(_, value) => option_some<a>(value)
  65. | Failure(_, _) => option_none<a>()
  66.  
  67. implement{a} expected_status(status) = case+ status of
  68. | Failure(_, expected) => expected
  69. | Success(_, _) => ""
  70.  
  71. implement{a} flag_status(status) = case+ status of
  72. | Failure(_, _) => false
  73. | Success(_, _) => true
  74.  
  75. implement{a} print_error_status(status) = let
  76. val expected = expected_status<a>(status)
  77. val index = index_status<a>(status)
  78. in fprintln! (stderr_ref, "KO : ", index, " -> \"", expected, "\" expected") end
  79. end
  80.  
  81. // -----------------------------------------------------------------------
  82. // ----------------------- PARSER ----------------------------------------
  83. // -----------------------------------------------------------------------
  84.  
  85. abstype parser_type(a: t@ype) = ptr
  86. stadef parser_t = parser_type
  87.  
  88. extern fun{a: t@ype} create_parser(f: cfun2(input_t, size_t, status_t(a))): parser_t(a)
  89. extern fun{a: t@ype} exec_parser(input: input_t, pos: size_t, parser: parser_t(a)): status_t(a)
  90. extern fun{a: t@ype} parse(input: input_t, parser: parser_t(a)): status_t(a)
  91. extern fun string_parser(value: string): parser_t(string)
  92. extern fun{a: t@ype} seq_parser(parsers: list0(parser_t(a))): parser_t(list0(a))
  93. extern fun{a, b: t@ype} fmap_parser(parser: parser_t(a), f: cfun1(a, b)): parser_t(b)
  94.  
  95. local
  96. datatype parser_dt(a: t@ype) =
  97. Parser of (cfun2(input_t, size_t, status_t(a)))
  98. assume parser_type = parser_dt
  99.  
  100. datatype pair_dt(a: t@ype, b: t@ype) =
  101. Pair of (a, b)
  102.  
  103. datatype either_dt (a: t@ype, b: t@ype) =
  104. | Left(a,b) of (a)
  105. | Right(a,b) of (b)
  106.  
  107. typedef seq_success_t(a: t@ype) = pair_dt(list0(a), size_t)
  108. typedef seq_fail_t(a: t@ype) = status_t(a)
  109.  
  110. extern fun{a: t@ype} seq_ok(list: list0(a), index: size_t):
  111. either_dt(seq_success_t(a), seq_fail_t(a))
  112. extern fun{a: t@ype} seq_ko(status: status_t(a)):
  113. either_dt(seq_success_t(a), seq_fail_t(a))
  114.  
  115. in
  116. implement{a} create_parser(f) = Parser{a}(f)
  117. implement{a} exec_parser(input, pos, parser) = let
  118. val+Parser(f) = parser
  119. in f(input, pos) end
  120. implement{a} parse(input, parser) = exec_parser(input, i2sz(0), parser)
  121.  
  122. implement string_parser(value) =
  123. create_parser<string>(lam(input, pos) =<cloref1> let
  124. val l = length(value)
  125. in if ~avail_input(input, pos, l) then
  126. failure_status<string>(pos, value)
  127. else let
  128. val s = get_input(input, pos, l)
  129. in
  130. if s = value then
  131. success_status<string>(pos+l, s)
  132. else
  133. failure_status<string>(pos, value)
  134. end
  135. end)
  136.  
  137. implement{a} seq_ok(list, index) = Left{seq_success_t(a),seq_fail_t(a)}(Pair{list0(a), size_t}(list, index))
  138. implement{a} seq_ko(status) = Right{seq_success_t(a),seq_fail_t(a)}(status)
  139.  
  140. implement{a} seq_parser(parsers) =
  141. create_parser<list0(a)>(lam(input, pos) =<cloref1> let
  142. fun{a: t@ype} loop(list: list0(parser_t(a)), index: size_t):
  143. either_dt(seq_success_t(a), seq_fail_t(a)) = case+ list of
  144. | list0_nil() => seq_ok<a>(list0_nil{a}(), index)
  145. | list0_cons(parser, tail) => let
  146. val status = exec_parser<a>(input, index, parser)
  147. val value = value_status<a>(status)
  148. val new_index = index_status<a>(status)
  149. in if option_is_some(value) then let
  150. val loop_rest = loop(tail, new_index)
  151. in case+ loop_rest of
  152. | Left(Pair(list, _)) => seq_ok<a>(list0_cons{a}(option_unsome<a>(value), list), new_index)
  153. | Right(status) => seq_ko<a>(status)
  154. end
  155. else seq_ko<a>(status)
  156. end
  157. val result = loop<a>(parsers, pos)
  158. in case+ result of
  159. | Left(Pair(list, index)) => success_status<list0(a)>(index, list)
  160. | Right(status) => let
  161. val index = index_status(status)
  162. val expected = expected_status(status)
  163. in failure_status<list0(a)>(index, expected) end
  164. end)
  165.  
  166. implement{a,b} fmap_parser(parser, f) =
  167. create_parser<b>(lam(input, pos) =<cloref1> let
  168. val status = exec_parser<a>(input, pos, parser)
  169. val index = index_status<a>(status)
  170. val value = value_status<a>(status)
  171. in if option_is_some(value) then
  172. success_status<b>(index, f(option_unsome(value)))
  173. else failure_status<b>(index, expected_status<a>(status)) end)
  174. end
  175.  
  176. // -----------------------------------------------------------------------
  177. // ----------------------- TEST ------------------------------------------
  178. // -----------------------------------------------------------------------
  179.  
  180. extern fun test_ok(): void
  181. extern fun test_ko(): void
  182.  
  183. local
  184. in
  185. implement print_status<list0(string)>(status) = let
  186. implement fprint_val<string>(out, str) = let
  187. val () = fprint(out, "\"")
  188. val () = fprint(out, str)
  189. in fprint(out, "\"") end
  190.  
  191. val value = value_status(status)
  192. in if option_is_some(value) then let
  193. val () = fprint_list0_sep(stdout_ref, option_unsome<list0(string)>(value), ", ")
  194. in fprint_newline(stdout_ref) end
  195. else print_error_status<list0(string)>(status) end
  196.  
  197. implement test_ok() = let
  198. val s = create_input("hello hello !")
  199. val hello = string_parser("hello")
  200. val space = string_parser(" ")
  201. val l = list0_of_list($list{parser_t(string)}(hello, space, hello))
  202. val a = seq_parser<string>(l)
  203.  
  204. val status = parse(s, a)
  205. in print_status(status) end
  206.  
  207. implement test_ko() = let
  208. val s = create_input("hello world !")
  209. val hello = string_parser("hello")
  210. val space = string_parser(" ")
  211. val l = list0_of_list($list{parser_t(string)}(hello, space, hello))
  212. val a = seq_parser<string>(l)
  213. val status = parse(s, a)
  214. in print_status(status) end
  215. end
  216.  
  217. extern fun test_ast(): void
  218.  
  219. local
  220. datatype ast_t =
  221. | String of (string)
  222. | Seq of (list0(ast_t))
  223. extern fun fprint_ast(out: FILEref, ast: ast_t): void
  224. extern fun fprint_list_ast(out: FILEref, ast_list: list0(ast_t)): void
  225. in
  226. implement fprint_ast(out, ast) = case+ ast of
  227. | String(a_string) => fprint! (out, "String{\"", a_string, "\"}")
  228. | Seq(list) => let
  229. val () = fprint! (out, "Seq{")
  230. val () = fprint_list_ast(out, list)
  231. in fprint! (out, "}") end
  232.  
  233. implement fprint_list_ast(out, ast_list) = let
  234. implement fprint_val<ast_t>(out, list) = fprint_ast(out, list)
  235. in fprint_list0_sep(out, ast_list, ", ") end
  236.  
  237. implement print_status<ast_t>(status) = let
  238. val value = value_status(status)
  239. in if option_is_some(value) then let
  240. val () = fprint_ast(stdout_ref, option_unsome<ast_t>(value))
  241. in fprint_newline(stdout_ref) end
  242. else
  243. print_error_status<ast_t>(status)
  244. end
  245.  
  246. implement test_ast() = let
  247. val input = create_input("hello hello !")
  248. val hello = fmap_parser<string, ast_t>(string_parser("hello"),
  249. lam(str) =<cloref1> String(str))
  250. val space = fmap_parser<string, ast_t>(string_parser(" "),
  251. lam(str) =<cloref1> String(str))
  252. val seq = fmap_parser<list0(ast_t), ast_t>(
  253. seq_parser<ast_t>(list0_of_list($list{parser_t(ast_t)}(hello, space, hello))),
  254. lam(seq) =<cloref1> Seq(seq))
  255. val status = parse(input, seq)
  256. in print_status(status) end
  257. end
  258.  
  259. implement main0() = let
  260. val () = test_ok()
  261. val () = test_ko()
  262. val () = test_ast()
  263. in () end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement