Advertisement
Guest User

Untitled

a guest
Nov 26th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #use "pc.ml";;
  2. open PC;;
  3.  
  4. exception X_not_yet_implemented;;
  5. exception X_this_should_not_happen;;
  6.  
  7. type number =
  8.   | Int of int
  9.   | Float of float;;
  10.  
  11. type sexpr =
  12.   | Bool of bool
  13.   | Nil
  14.   | Number of number
  15.   | Char of char
  16.   | String of string
  17.   | Symbol of string
  18.   | Pair of sexpr * sexpr
  19.   | TaggedSexpr of string * sexpr
  20.   | TagRef of string
  21.  
  22. let rec sexpr_eq s1 s2 =
  23.   match s1, s2 with
  24.   | Bool(b1), Bool(b2) -> b1 = b2
  25.   | Nil, Nil -> true
  26.   | Number(Float f1), Number(Float f2) -> abs_float(f1 -. f2) < 0.001
  27.   | Number(Int n1), Number(Int n2) -> n1 = n2
  28.   | Char(c1), Char(c2) -> c1 = c2
  29.   | String(s1), String(s2) -> s1 = s2
  30.   | Symbol(s1), Symbol(s2) -> s1 = s2
  31.   | Pair(car1, cdr1), Pair(car2, cdr2) -> (sexpr_eq car1 car2) && (sexpr_eq cdr1 cdr2)
  32.   | TaggedSexpr(name1, expr1), TaggedSexpr(name2, expr2) -> (name1 = name2) && (sexpr_eq expr1 expr2)
  33.   | TagRef(name1), TagRef(name2) -> name1 = name2
  34.   | _ -> false;;
  35.  
  36. module Reader: sig
  37.   val read_sexpr : string -> sexpr
  38.   val read_sexprs : string -> sexpr list
  39. end
  40. = struct
  41. let normalize_scheme_symbol str =
  42.   let s = string_to_list str in
  43.   if (andmap
  44.     (fun ch -> (ch = (lowercase_ascii ch)))
  45.     s) then str
  46.   else Printf.sprintf "|%s|" str;;
  47.  
  48. let read_sexpr string = raise X_not_yet_implemented ;;
  49.  
  50. let read_sexprs string = raise X_not_yet_implemented;;
  51. end;; (* struct Reader *)
  52.  
  53.  
  54. let all_letters_no_space = (range (char_of_int 33) (char_of_int 127));;
  55.  
  56. let bool_parser = pack (disj (word_ci "#t") (word_ci "#f"))  (
  57.   function
  58.   | ['#';'t'] -> Bool true
  59.   | ['#';'T'] -> Bool true
  60.   | ['#';'f'] -> Bool false
  61.   | ['#';'F'] -> Bool false
  62.   | _ -> raise X_no_match
  63. );;
  64.  
  65. let digit = range '0' '9';;
  66.  
  67. let tok_num=
  68.   (let digits= (plus digit) in
  69.   pack digits (fun (ds) -> Int (int_of_string(list_to_string ds))));;
  70.  
  71. let string_literal_char = diff nt_any (disj (char '"') (char '\\')) ;;
  72.  
  73. let string_meta_char = disj_list[
  74. (pack (word_ci "\\n")(fun (x)-> '\n'));
  75. (pack (word_ci "\\t")(fun (x)-> '\t'));
  76. (pack (word_ci "\\f")(fun (x)->'\012'));
  77. (pack (word_ci "\\r")(fun (x)->'\r'));
  78. (pack (word_ci "\\\\")(fun (x)->'\\'));
  79. (pack (word_ci "\\\"")(fun (x)->'\"'));
  80. ];;
  81.  
  82. let letters = disj string_meta_char string_literal_char;;
  83.  
  84. let string_parser = pack (caten (caten (char '"') (star letters)) (char '"'))(
  85. function
  86. | (('"',s),'"') -> String (list_to_string s)
  87. | _ -> raise X_no_match
  88. );;
  89.  
  90. let char_prefix = word "#\\";;
  91. let visible_simple_char = range (char_of_int 33) (char_of_int 127);;
  92. let named_char = disj_list[
  93. (pack (word_ci "newline")(fun (x)-> char_of_int 10));
  94. (pack (word_ci "nul")(fun (x)-> char_of_int 0));
  95. (pack (word_ci "page")(fun (x)-> char_of_int 12));
  96. (pack (word_ci "return")(fun (x)-> char_of_int 13));
  97. (pack (word_ci "space")(fun (x)-> char_of_int 32));
  98. (pack (word_ci "tab")(fun (x)-> char_of_int 9));
  99. ];;
  100. let char_profix = disj named_char visible_simple_char;;
  101.  
  102. let char_parser = pack (caten char_prefix char_profix)(
  103. function
  104. | (['#';'\\'],s) -> Char s
  105. | _ -> raise X_no_match
  106. );;
  107.  
  108. let natural = plus digit;;
  109.  
  110. let integer = caten (maybe (disj (char '+') (char '-'))) natural;;
  111.  
  112. let float_parser = pack (caten (caten integer (char '.')) natural)(
  113. function
  114. | (((Some '+',s1),'.'),s2) -> Float (float_of_string ((list_to_string s1) ^ "." ^ (list_to_string s2)))
  115. | (((Some '-',s1),'.'),s2) -> Float ((-1.0) *. float_of_string ((list_to_string s1) ^ "." ^ (list_to_string s2)))
  116. | (((None,s1),'.'),s2) -> Float (float_of_string ((list_to_string s1) ^ "." ^ (list_to_string s2)))
  117. | _ -> raise X_no_match
  118. );;
  119.  
  120. let integer_parser = pack integer(
  121. function
  122. | (Some '+',s1) -> Int (int_of_string (list_to_string s1))
  123. | (Some '-',s1) -> Int ((-1) * int_of_string (list_to_string s1))
  124. | (None , s1) -> Int (int_of_string (list_to_string s1))
  125. | _ -> raise X_no_match
  126. );;
  127.  
  128. let float_scientific = pack (caten (disj float_parser integer_parser) (caten (char_ci 'e') (diff integer_parser float_parser)))(
  129. function
  130. | (Int(s1),('e',Int(s2))) -> Float ((float_of_int s1) *. (10.0 ** (float_of_int s2)))
  131. | (Float(s1),('e',Int(s2))) -> Float (s1 *. (10.0 ** (float_of_int s2)))
  132. | (Int(s1),('E',Int(s2))) ->  Float ((float_of_int s1) *. (10.0 ** (float_of_int s2)))
  133. | (Float(s1),('E',Int(s2))) -> Float (s1 *. (10.0 ** (float_of_int s2)))
  134. | _ -> raise X_no_match
  135. );;
  136.  
  137. let radix_r = pack (char_ci 'r')(
  138. function
  139. | ('R') -> 'r'
  140. | ('r') -> 'r'
  141. | _ -> raise X_no_match
  142. );;
  143.  
  144. let radix_converter = pack (all_letters_no_space)(
  145. function
  146. | (s) -> (lowercase_ascii s)
  147. );;
  148.  
  149. let char_converter2 c =
  150. if (c >= '0' && c <= '9') then float_of_int ((int_of_char c) - 48) else
  151. float_of_int((int_of_char c) - 87);;
  152.  
  153. let rest base s = List.fold_right
  154. (fun a b -> ((a /. base) +. (b /. base)))
  155. (List.map char_converter2 (string_to_list s))
  156. 0.;;
  157.  
  158. let char_converter c =
  159. if (c >= '0' && c <= '9') then (int_of_char c) - 48 else
  160. (int_of_char c) - 87;;
  161. (* ((String.index nt '.') - length + 1) *)
  162. let radix_to_dec length base nt=
  163.  let first_num = ref 0. in
  164.  let pow = ref 1 in
  165.  let s  = (String.sub nt ((String.index nt '.')) ((String.length nt)-(String.index nt '.')))in
  166.  let n = (String.sub s 1 ((String.length s)-1)) in
  167.  for i = (String.index nt '.') downto 0 do
  168.    if (char_converter (String.get nt i)) >= base then raise X_no_match;
  169.    if (String.get nt i) != '.' then(
  170.      first_num := !first_num +. (float_of_int ((char_converter (String.get nt i)) * !pow));
  171.    pow := !pow * base)
  172. done;
  173. !first_num +. (rest (float_of_int base) n);;
  174.  
  175. let radix_to_int length base nt=
  176.  let first_num = ref 0 in
  177.  let pow = ref 1 in
  178.  for i = length - 1 downto 0 do
  179.    if (char_converter (String.get nt i)) >= base then raise X_no_match;
  180.    if (String.get nt i) != '.' then(
  181.      first_num := !first_num + ((char_converter (String.get nt i)) * !pow);
  182.    pow := !pow * base)
  183. done;
  184. !first_num;;
  185.    
  186.    
  187.    
  188.      
  189.  
  190. let radix_parser = pack (caten integer_parser (caten radix_r (plus radix_converter)))(
  191. function
  192. | (Int(s1),('r',s2)) -> if (String.contains (list_to_string s2) '.') then Float(radix_to_dec (String.length (list_to_string s2)) s1 (list_to_string s2))
  193.                        else Int(radix_to_int (String.length (list_to_string s2)) s1 (list_to_string s2))
  194. | _ -> raise X_no_match
  195. );;
  196.  
  197. let nt_whitespaces = star (char ' ');;
  198.  
  199. let number_parser = pack (disj_list[
  200. radix_parser;
  201. float_scientific;
  202. float_parser;
  203. integer_parser;
  204. ])(
  205. function
  206. | s -> Number(s)
  207. );;
  208.  
  209. let line_comment_parser = pack (caten (caten (char ';') (star (diff letters (char '\n')))) (disj (word "\n") nt_end_of_input))
  210. (
  211. function
  212. | ((';',s),['\n']) -> Nil
  213. | _ -> raise X_no_match
  214. );;
  215. let symbol_char = disj_list[
  216.  range '0' '9';
  217.  range 'a' 'z';
  218.  range 'A' 'Z';
  219.  char ':';
  220.  char '!';
  221.  char '=';
  222.  char '<';
  223.  char '>';
  224.  char '$';
  225.  char '*';
  226.  char '+';
  227.  char '^';
  228.  char '-';
  229.  char '_';
  230.  char '/';
  231.  char '?';
  232.  ];;
  233.  
  234. let symbol_parser = pack (plus symbol_char)(
  235.  function
  236.  | s -> Symbol (list_to_string s)
  237. );;
  238.  
  239. let make_paired nt_left nt_right nt =
  240. let nt = caten nt_left nt in
  241. let nt = pack nt (function (_, e) -> e) in
  242. let nt = caten nt nt_right in
  243. let nt = pack nt (function (e, _) -> e) in
  244.  nt;;
  245.  
  246. let make_spaced nt = make_paired nt_whitespaces nt_whitespaces nt;;
  247.  
  248. let tok_lparen = make_spaced ( char '(');;
  249.  
  250. let tok_rparen = make_spaced ( char ')');;
  251.  
  252. let tok_dotted = make_spaced ( char '.');;
  253.  
  254. let tok_comment = make_spaced ( word "#;");;
  255.  
  256.  
  257.  
  258.  
  259. let rec list_parser s = (disj dottted_list_parser undottted_list_parser) s
  260. and undottted_list_parser s=
  261.  pack (caten (caten tok_lparen (star sexp)) tok_rparen)(
  262.    function
  263.    | ((l, e), r) -> pairfunc_undotted e
  264.  ) s
  265. and pairfunc_undotted s= (
  266.  function
  267.  | [] -> Nil
  268.  | a :: b -> Pair (a, pairfunc_undotted b)
  269. ) s
  270. and dottted_list_parser s=
  271. pack (caten (caten (caten (caten tok_lparen (plus sexp)) tok_dotted) sexp) tok_rparen)(
  272.  function
  273.  | ((((l, e1),'.'),e2), r) ->  pairfunc_dotted (e1,e2)
  274.  | _ -> raise X_no_match
  275. ) s
  276.  
  277. and pairfunc_dotted s= (
  278. function
  279. | ([] , b) -> b
  280. | ((a::c) , b) -> Pair (a, pairfunc_dotted (c,b))
  281. ) s
  282. and sexp s = make_spaced (disj (disj (disj (disj (disj bool_parser number_parser) string_parser) char_parser) list_parser) symbol_parser) s;;
  283.  
  284. let sexp =(disj (disj (disj (disj (disj bool_parser number_parser) string_parser) char_parser) list_parser) symbol_parser);;
  285.  
  286. let quote_maker = pack(disj (disj (disj (word "`") (word "'")) (word ",@")) (word ","))(
  287.  fun (x) -> match x with
  288.  | ['`'] -> "Quoted"
  289.  | ['\''] -> "QQuoted"
  290.  | [',';'@'] -> "UnquotedSpliced"
  291.  | [','] -> "Unquoted"
  292.  | _ -> raise X_no_match
  293. );;
  294.  
  295. let quote_parser = pack (caten quote_maker sexp)(
  296.  function
  297.  (x,y) -> Pair (Symbol x, Pair (y, Nil))
  298. );;
  299.  
  300. (* let rec sexp_comment = pack (caten (caten (caten tok_comment (star tok_comment)) sexp) (star nt_any))
  301. (function
  302. | (((a,[]), c),d) -> " "
  303. | (((a, [b]), c),d) -> sexp_comment ((list_to_string b) ^ (list_to_string d))
  304. | _ -> raise X_no_match
  305. );; *)
  306.  
  307. (* let rec sexp_comment = pack (caten (caten tok_comment (star tok_comment)) (plus sexp))
  308. (function
  309. | ((a,[]), c) -> " "
  310. | ((a, [b::d]), c) -> sexp_comment ()
  311. | _ -> raise X_no_match
  312. );; *)
  313.  
  314. (* let sexp_comment' =
  315.  let rec make_comment () =
  316.    let nt = caten (caten (make_spaced (word "#;"))
  317.               (delayed make_comment))
  318.            (make_spaced sexp) in
  319.    let nt = pack nt (fun _ -> ' ') in
  320.    let nt' = star nt_whitespace in
  321.    let nt' = pack nt' (fun _ -> ' ') in
  322.    let nt = disj nt nt' in
  323.    nt in
  324.  make_comment ();; *)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement