Advertisement
Guest User

Untitled

a guest
Nov 12th, 2018
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 13.11 KB | None | 0 0
  1.  
  2. (* reader.ml
  3.  * A compiler from Scheme to x86/64
  4.  *
  5.  * Programmer: Mayer Goldberg, 2018
  6. *)
  7.  
  8. #use "pc.ml";;
  9. open PC;;
  10.  
  11.  
  12. exception X_not_yet_implemented;;
  13. exception X_this_should_not_happen;;
  14. type number =
  15.     | Int of int
  16.     | Float of float;;
  17.  
  18. type sexpr =
  19.     | Bool of bool
  20.     | Nil
  21.     | Number of number
  22.     | Char of char
  23.     | String of string
  24.     | Symbol of string
  25.     | Some of char
  26.     | Pair of sexpr * sexpr
  27.     | Vector of sexpr list;;
  28.  
  29. let rec sexpr_eq s1 s2 =
  30.   match s1, s2 with
  31.     | Bool(b1), Bool(b2) -> b1 = b2
  32.     | Nil, Nil -> true
  33.     | Number(Float f1), Number(Float f2) -> abs_float(f1 -. f2) < 0.001
  34.     | Number(Int n1), Number(Int n2) -> n1 = n2
  35.     | Char(c1), Char(c2) -> c1 = c2
  36.     | String(s1), String(s2) -> s1 = s2
  37.     | Symbol(s1), Symbol(s2) -> s1 = s2
  38.     | Pair(car1, cdr1), Pair(car2, cdr2) -> (sexpr_eq car1 car2) && (sexpr_eq cdr1 cdr2)
  39.     | Vector(l1), Vector(l2) -> List.for_all2 sexpr_eq l1 l2
  40.     | _ -> false;;
  41.  
  42.  
  43. let nt_digit_0_to_9 =
  44.   pack (const (fun ch -> '0' <= ch && ch <= '9'))
  45.     (fun ch -> (int_of_char ch) - 48);;
  46.  
  47. let nt_natural =
  48.   let rec make_nt_natural () =
  49.     pack (caten nt_digit_0_to_9
  50.             (disj (delayed make_nt_natural)
  51.                nt_epsilon))
  52.       (function (a, s) -> a :: s) in
  53.     pack (make_nt_natural())
  54.       (fun s ->
  55.          (List.fold_left
  56.             (fun a b -> 10 * a + b)
  57.             0
  58.             s));;
  59.  
  60. let nt_digit_a_to_f =
  61.   pack (const (fun ch -> 'a' <= ch && ch <= 'f'))
  62.     (fun ch -> (int_of_char ch) - 87);;
  63.  
  64. let nt_digit_A_to_F =
  65.   pack (const (fun ch -> 'A' <= ch && ch <= 'F'))
  66.     (fun ch -> (int_of_char ch) - 55);;
  67.  
  68. let nt_hex =
  69.   let rec make_nt_hex () =
  70.     pack (caten (disj (disj nt_digit_0_to_9 nt_digit_a_to_f) nt_digit_A_to_F)
  71.             (disj (delayed make_nt_hex)
  72.                nt_epsilon))
  73.       (function (a, s) -> a :: s) in
  74.     pack (pack (caten  (caten (caten (char '#') (char_ci 'x')) (pack (maybe (disj (char '+') (char '-'))) (fun l -> match l with
  75.       | None -> 1
  76.       | (Some('+')) -> 1
  77.       | (Some('-')) -> -1
  78.       | l -> 8))) (make_nt_hex())) (function (((a,b),c),d) -> List.map (fun (x) -> c*x) d))
  79.       (fun s ->
  80.          (List.fold_left
  81.             (fun a b -> 16 * a + b)
  82.             0
  83.             s));;
  84. let nt_little_float =
  85.   let rec make_nt_natural () =
  86.     pack (caten nt_digit_0_to_9
  87.             (disj (delayed make_nt_natural)
  88.                nt_epsilon))
  89.       (function (a, s) -> a :: s) in
  90.     pack (pack (make_nt_natural()) (fun (x) -> List.map float_of_int x))
  91.       (fun (s) ->
  92.          (List.fold_right
  93.             (fun a b -> b /. 10.  +. a /. 10.)
  94.             s
  95.             0.));;
  96. let nt_hexdigit = disj (disj nt_digit_0_to_9 nt_digit_a_to_f) nt_digit_A_to_F;;
  97. let nt_hex_natural = pack (pack (plus nt_hexdigit) (fun (a) -> List.map float_of_int a)) (fun (s) ->
  98.       (List.fold_right
  99.         (fun a b -> b /. 16.  +. a /. 16.)
  100.         s
  101.         0.));;
  102.  
  103.  
  104. let nt_hex_for_float =
  105.   let rec make_nt_hex () =
  106.     pack (caten (disj (disj nt_digit_0_to_9 nt_digit_a_to_f) nt_digit_A_to_F)
  107.             (disj (delayed make_nt_hex)
  108.                 nt_epsilon))
  109.       (function (a, s) -> a :: s) in
  110.     pack (make_nt_hex())
  111.       (fun s ->
  112.           (List.fold_left
  113.             (fun a b -> 16 * a + b)
  114.             0
  115.             s));;
  116.            
  117. let nt_hexfloat =
  118.   pack (caten (caten (caten  (caten (caten (char '#') (char_ci 'x')) (pack (maybe (disj (char '+') (char '-'))) (fun l -> match l with
  119.               | None -> 1.
  120.               | (Some('+')) -> 1.
  121.               | (Some('-')) -> -1.
  122.               | l -> 8.))) (pack nt_hex_for_float  (fun (a) ->  float_of_int a))) (char '.')) nt_hex_natural) (fun (((((a,b),c),d),e),f) -> c*.(d+.f));;
  123.  
  124.  
  125. let nt_float =
  126.   let rec make_nt_natural () =
  127.     pack (caten nt_digit_0_to_9
  128.             (disj (delayed make_nt_natural)
  129.                nt_epsilon))
  130.       (function (a, s) -> a :: s) in
  131.     pack (pack (caten (caten (pack (maybe (disj (char '+') (char '-'))) (fun l -> match l with
  132.           | None -> 1.
  133.           | (Some('+')) -> 1.
  134.           | (Some('-')) -> -1.
  135.           | l -> 8.)) (caten (pack (make_nt_natural()) (fun (x) -> List.map float_of_int x)) (char '.'))) (nt_little_float)) (fun ((a,(b,c)),d) -> ((List.map (fun (x) -> a*.x) b),a*.d)))
  136.       (fun (s,d) ->
  137.          (List.fold_left
  138.             (fun a b -> 10. *. a +. b)
  139.             0.
  140.             s)+.d);;
  141.  
  142.  
  143.  
  144. let nt_plusminusinteger num =
  145.   let m= disj (caten (char '-')   (pack nt_natural (fun s -> -1*s))) (caten  (pack (maybe (char '+')) (fun l -> match l with
  146.       | None -> '+'
  147.       | (Some('+')) -> '+'
  148.       | l -> 'f' )) nt_natural) num in
  149.     (fun ((e,s),c) -> (s,c)) m;;
  150.  
  151. let nt_integer num =
  152.   nt_plusminusinteger num;;
  153.  
  154. let nt_scientific_int =  pack (caten (pack (caten (pack (maybe (disj (char '+') (char '-'))) (fun l -> match l with
  155.             | None -> '0'
  156.             | (Some('+')) -> '0'
  157.             | (Some('-')) -> '-'
  158.             | l -> '8')) (plus (range_ci '0' '9'))) (fun (a,b) -> List.append (a::[]) b)) (pack (caten (char_ci 'e') (pack (caten (pack (maybe (disj (char '+') (char '-'))) (fun l -> match l with
  159.             | None -> '0'
  160.             | (Some('+')) -> '0'
  161.             | (Some('-')) -> '-'
  162.             | l -> '8')) (plus (range_ci '0' '9'))) (fun (a,b) -> List.append (a::[]) b))) (fun (a,b) -> List.append (a::[]) b)))
  163.                            (fun (a,b) -> float_of_string (list_to_string (List.append a b)));;
  164.  
  165. let nt_scientific_float =  pack (caten (pack (caten (pack (caten (pack (maybe (disj (char '+') (char '-'))) (fun l -> match l with
  166.                   | None -> '0'
  167.                   | (Some('+')) -> '0'
  168.                   | (Some('-')) -> '-'
  169.                   | l -> '8')) (plus (range_ci '0' '9'))) (fun (a,b) -> List.append (a::[]) b)) (pack (caten (char '.') (plus (range_ci '0' '9'))) (fun (a,b) -> List.append (a::[]) b))) (fun (a,b) -> List.append a b)) (pack (caten (char_ci 'e') (pack (caten (pack (maybe (disj (char '+') (char '-'))) (fun l -> match l with
  170.                                             | None -> '0'
  171.                                             | (Some('+')) -> '0'
  172.                                             | (Some('-')) -> '-'
  173.                                             | l -> '8')) (plus (range_ci '0' '9'))) (fun (a,b) -> List.append (a::[]) b) )) (fun (a,b) -> List.append (a::[]) b)))
  174.                              (fun (a,b) -> float_of_string (list_to_string (List.append a b)));;
  175.  
  176. let nt_charprefix = (word "#\\");;
  177. let nt_visiblechar = const (fun ch -> (int_of_char ch)>32 && (int_of_char ch)<=127);;
  178. let nt_namedchar = disj_list [(pack (word_ci "newline") (fun (a) -> '\010'));(pack (word_ci "page") (fun (a) -> '\012'));(pack (word_ci "space") (fun (a) -> ' '));(pack (word_ci "nul") (fun (a) -> '\000'));(pack (word_ci "return") (fun (a) -> '\013'));(pack (word_ci "tab") (fun (a) -> '\009'))];;
  179. let nt_hexchar = pack (caten (char_ci 'x') (plus nt_hexdigit)) (fun (d,c) -> char_of_int
  180.           (List.fold_left
  181.             (fun a b -> 16 * a + b)
  182.             0
  183.             c));;
  184.  
  185.  
  186.  
  187. let nt_stringlitteralchar = pack (diff nt_any (one_of "\\\"")) (fun (a) -> a::[]);;  
  188.  
  189. let nt_string_meta_f = pack (word "\\f") (fun _ -> '\012'::[]);;
  190. let nt_string_meta_bkslsh = pack (word "\\\\") (fun _ -> '\\'::[]);;
  191. let nt_string_meta_quote = pack (word "\\\"") (fun _ -> '\"'::[]);;
  192. let nt_string_meta_t = pack (word "\\t") (fun _ -> '\t'::[]);;
  193. let nt_string_meta_n = pack (word "\\n") (fun _ -> '\n'::[]);;
  194. let nt_string_meta_r = pack (word "\\r") (fun _ -> '\r'::[]);;
  195.  
  196. let nt_stringmetachar = disj_list [nt_string_meta_f ; nt_string_meta_bkslsh ; nt_string_meta_quote ; nt_string_meta_t ; nt_string_meta_n ; nt_string_meta_r];;
  197. let nt_stringhexchar = pack (caten (caten (word_ci "\\x") (pack (plus nt_hexdigit)
  198.      (fun (c) -> (char_of_int
  199.                    (List.fold_left
  200.                        (fun a b -> 16 * a + b)
  201.                        0
  202.                        c))))) (char ';')) (fun ((a,b),c) -> b::[]);;
  203.  
  204. let nt_string_char = disj_list [nt_stringmetachar;nt_stringlitteralchar;nt_stringhexchar];;
  205.  
  206. let nt_symbolchar = disj_list [(range '0' '9');(range_ci 'a' 'z'); (const (fun ch -> ch=='!' ||ch=='$' ||ch=='^' ||ch=='*' ||ch=='-' ||ch=='_' ||ch=='=' ||ch=='+' ||ch=='<' ||ch=='>' ||ch=='?' ||ch=='/' ||ch==':' ))];;
  207. let which_quote x = match x with
  208.  | "\'" -> "quote"
  209.  | "`" -> "quasiquote"
  210.  | "," -> "unquote"
  211.  | ",@" -> "unquote-splicing"
  212.  | x -> "no"
  213.  
  214.  
  215. let nt_symbol = pack (plus nt_symbolchar) (fun (a) -> ( list_to_string (List.map lowercase_ascii a)));;
  216. let nt_string = pack (caten (caten (char '\"') (star nt_string_char)) (char '\"')) (fun ((a,b),c) -> list_to_string (List.flatten b));;
  217. let nt_number = disj (pack (disj_list [nt_scientific_int;nt_scientific_float;nt_float;nt_hexfloat]) (fun (a) -> Float(a))) (pack (disj nt_plusminusinteger nt_hex) (fun (a) -> Int(a)));;
  218. let nt_char = pack (caten nt_charprefix (disj_list [nt_hexchar;nt_namedchar;nt_visiblechar])) (fun (a,b) -> b);;
  219. (*let nt_char = not_followed_by (nt_char) (disj_list [nt_symbol]);;*)
  220.  
  221. (* line comment impl *)
  222. let nt_smcol = char ';';;
  223. let nt_nwln = char '\n';;
  224. let nt_end_inp = pack nt_end_of_input (fun _ -> ' ');;
  225.  
  226. let nt_notend = const (fun ch -> ch != '\n');;
  227. let nt_skip = pack (star nt_notend) (fun l -> ' ');;
  228. let nt_line_comm = pack (caten_list [nt_smcol;nt_skip;(disj nt_nwln nt_end_inp)]) (fun a -> ' ');;
  229.  
  230. (* let nt_comment = pack nt_line_comm (fun _ -> Nil);;*) (* disj sexpr_comment *)
  231.  
  232. (* Parsers without spaces from right & left   AND   sexp conversion *)
  233. let _whitespaces_ = star (disj nt_whitespace nt_line_comm);;
  234. let nts_symbol = pack (caten (caten _whitespaces_ nt_symbol) _whitespaces_) (fun ((l,p),r) -> Symbol p);;
  235. let nts_string = pack (caten (caten _whitespaces_ nt_string) _whitespaces_) (fun ((l,p),r) -> String p);;
  236. let nts_char = pack (caten (caten _whitespaces_ nt_char) _whitespaces_) (fun ((l,p),r) -> Char p);;
  237. let nts_number = pack (caten (caten _whitespaces_ nt_number) _whitespaces_)  (fun ((l,p),r) -> Number p);;
  238.  
  239. let nt_bool =
  240.  let istrue = pack (word_ci "#t") (fun _ -> Bool true) in
  241.  let isfalse = pack (word_ci "#f") (fun _ -> Bool false) in
  242.    not_followed_by (disj istrue isfalse) (disj_list [nts_symbol;nts_string]);;
  243. let nts_bool = pack (caten (caten _whitespaces_ nt_bool) _whitespaces_)  (fun ((l,p),r) -> p);;
  244.  
  245. let lp = char '(';;
  246. let rp = char ')';;
  247. let lbp = char '[';;
  248. let rbp = char ']';;
  249. (* sexprs disjoint impl *)
  250. let rec nts_sexpr = fun a -> (disj_list [nts_vector;nts_dot_list;nts_list;nts_bracket;(*nt_sexpr_comment;nt_comment;*)nts_bool;nts_nil;nts_quote;nts_number;nts_symbol;nts_string;nts_char]) a
  251. and nts_sexprs = fun a -> (star nts_sexpr) a
  252. (*and nt_comment = fun a -> (disj nt_line_comm nt_sexpr_comment) a *)
  253.  
  254. and shortened_sexpr s =
  255.  let x = star (const (fun ch -> ch > ' ')) in
  256.  let x = caten x nts_sexpr in
  257.  x s
  258. and nt_sexpr_comment s =
  259.  let x = pack (caten (word "#;") shortened_sexpr) (fun (a,b) -> Nil) in
  260.  x s
  261. and nt_dot_list s =
  262.  let nt_dotted_list = (caten (plus nts_sexpr) (caten (char '.') nts_sexpr)) in
  263.  let nt_dotted_list = pack (caten (caten lp nt_dotted_list) rp) (fun ((l,p),r) -> p) in
  264.  let nt_dotted_list = pack nt_dotted_list (fun (l,(c,r)) -> List.fold_right (fun a b -> Pair(a,b)) l r) in
  265.    nt_dotted_list s
  266. and nts_dot_list = fun b -> (pack (caten (caten _whitespaces_ nt_dot_list) _whitespaces_) (fun ((l,p),r) -> p)) b
  267. and nt_list s =
  268.  let x = pack (caten (caten lp (star nts_sexpr)) rp) (fun ((l,p),r) -> p) in
  269.  let x = pack x (fun l -> List.fold_right (fun a b -> Pair(a,b)) l Nil) in
  270.    x s
  271. and nts_list = fun b -> (pack (caten (caten _whitespaces_ nt_list) _whitespaces_) (fun ((l,p),r) -> p)) b
  272. and nt_bracket s =
  273.  let x = pack (caten (caten lbp (star nts_sexpr)) rbp) (fun ((l,p),r) -> p) in
  274.  let x = pack x (fun l -> List.fold_right (fun a b -> Pair(a,b)) l Nil) in
  275.    x s
  276. and nts_bracket = fun b -> (pack (caten (caten _whitespaces_ nt_bracket) _whitespaces_) (fun ((l,p),r) -> p)) b
  277. and nt_vector s =
  278.  let x = pack (caten (caten lp (star nts_sexpr)) rp) (fun ((l,p),r) -> p) in
  279.  let x = pack (caten (char '#') x) (fun (a, l) -> Vector l) in
  280.    x s
  281. and nts_vector = fun c -> (pack (caten (caten _whitespaces_ nt_vector) _whitespaces_) (fun ((l,p),r) -> p)) c  
  282. and nts_nil = fun d -> (pack (caten (caten lp _whitespaces_) rp) (fun _ -> Nil)) d
  283. and nts_quote = fun a -> (pack (caten (disj_list [(word "\'");(word "`");(word ",@");(word ",")]) (nts_sexpr))
  284.                            (fun (a,b) -> Pair(Symbol((which_quote (list_to_string a))), Pair(b,Nil)))) a;;
  285.  
  286.  
  287. let pack_final nt s =
  288.  let (e, s) = (nt s) in
  289.    e;;
  290.  
  291. module Reader: sig
  292.  val read_sexpr : string -> sexpr
  293.  val read_sexprs : string -> sexpr list
  294. end
  295.  
  296. = struct
  297.  let normalize_scheme_symbol str =
  298.    let s = string_to_list str in
  299.      if (andmap
  300.            (fun ch -> (ch = (lowercase_ascii ch)))
  301.            s) then str
  302.      else Printf.sprintf "|%s|" str;;
  303.  
  304.  
  305.  
  306.  let read_sexpr string =
  307.    pack_final nts_sexpr (string_to_list string);;
  308.  
  309.  let read_sexprs string = pack_final nts_sexprs (string_to_list string);;
  310. end;; (* struct Reader *)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement