Advertisement
Guest User

Untitled

a guest
Dec 13th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.36 KB | None | 0 0
  1. #use "reader.ml";;
  2.  
  3. type constant =
  4. | Sexpr of sexpr
  5. | Void
  6.  
  7. type expr =
  8. | Const of constant
  9. | Var of string
  10. | If of expr * expr * expr
  11. | Seq of expr list
  12. | Set of expr * expr
  13. | Def of expr * expr
  14. | Or of expr list
  15. | LambdaSimple of string list * expr
  16. | LambdaOpt of string list * string * expr
  17. | Applic of expr * (expr list);;
  18.  
  19. let rec expr_eq e1 e2 =
  20. match e1, e2 with
  21. | Const Void, Const Void -> true
  22. | Const(Sexpr s1), Const(Sexpr s2) -> sexpr_eq s1 s2
  23. | Var(v1), Var(v2) -> String.equal v1 v2
  24. | If(t1, th1, el1), If(t2, th2, el2) -> (expr_eq t1 t2) &&
  25. (expr_eq th1 th2) &&
  26. (expr_eq el1 el2)
  27. | (Seq(l1), Seq(l2)
  28. | Or(l1), Or(l2)) -> List.for_all2 expr_eq l1 l2
  29. | (Set(var1, val1), Set(var2, val2)
  30. | Def(var1, val1), Def(var2, val2)) -> (expr_eq var1 var2) &&
  31. (expr_eq val1 val2)
  32. | LambdaSimple(vars1, body1), LambdaSimple(vars2, body2) ->
  33. (List.for_all2 String.equal vars1 vars2) &&
  34. (expr_eq body1 body2)
  35. | LambdaOpt(vars1, var1, body1), LambdaOpt(vars2, var2, body2) ->
  36. (String.equal var1 var2) &&
  37. (List.for_all2 String.equal vars1 vars2) &&
  38. (expr_eq body1 body2)
  39. | Applic(e1, args1), Applic(e2, args2) ->
  40. (expr_eq e1 e2) &&
  41. (List.for_all2 expr_eq args1 args2)
  42. | _ -> false;;
  43.  
  44.  
  45. exception X_syntax_error;;
  46.  
  47. module type TAG_PARSER = sig
  48. val tag_parse_expression : sexpr -> expr
  49. val tag_parse_expressions : sexpr list -> expr list
  50. end;; (* signature TAG_PARSER *)
  51.  
  52. module Tag_Parser : TAG_PARSER = struct
  53.  
  54. let reserved_word_list =
  55. ["and"; "begin"; "cond"; "define"; "else";
  56. "if"; "lambda"; "let"; "let*"; "letrec"; "or";
  57. "quasiquote"; "quote"; "set!"; "unquote";
  58. "unquote-splicing"];;
  59.  
  60. (* work on the tag parser starts here *)
  61. let rec pairsToList=(function
  62. | Pair(Symbol(x),y) -> x::(pairsToList y)
  63. | Nil -> [];
  64. | _ -> raise X_no_match
  65. );;
  66.  
  67. let rec pairsToListDotted=(function
  68. | Pair(Symbol(x),y) -> x::(pairsToListDotted y)
  69. | Symbol(x) -> [];
  70. | _ -> raise X_no_match
  71. );;
  72. let rec lastOneInListDotted=(function
  73. | Pair(Symbol(x),y) -> lastOneInListDotted y
  74. | Symbol(x) -> x;
  75. | _ -> raise X_no_match
  76. );;
  77. let rec hasLastOneInListDotted=(function
  78. | Pair(Symbol(x),y) -> hasLastOneInListDotted y
  79. | Symbol(x) -> true
  80. | _ -> false
  81. );;
  82.  
  83. (* let lastElementInList =function *)
  84.  
  85. let rec tag_parse s= (function
  86. | Number(x) -> Const(Sexpr(Number(x)))
  87. | Bool(x) -> Const(Sexpr(Bool(x)))
  88. | Char(x) -> Const(Sexpr(Char(x)))
  89. | String(x) -> Const(Sexpr(String(x)))
  90. | TagRef(x) -> Const(Sexpr(TagRef(x)))
  91. | TaggedSexpr(name, Pair(x,Pair(y, Nil))) -> Const(Sexpr(TaggedSexpr (name, y)))
  92. | Pair(Symbol("if"), Pair(test, Pair(dit, Pair(dif, Nil))))-> If(tag_parse test, tag_parse dit, tag_parse dif)
  93. | Pair(Symbol("if"), Pair(test, Pair(dit, Nil)))-> If(tag_parse test, tag_parse dit, Const(Void))
  94. | Pair(Symbol("quote"), Pair(x, Nil)) -> Const(Sexpr(x))
  95. | Pair(Symbol("lambda"), Pair(Symbol(arg), Pair(body,Nil)))-> LambdaOpt([], arg, tag_parse body)
  96. | Pair(Symbol("lambda"), Pair(Symbol(arg), body))-> LambdaOpt([], arg, tag_parse (Pair(Symbol "begin", body)))
  97. | Pair(Symbol("lambda"), Pair(args, Pair(body,Nil)))-> if(hasLastOneInListDotted args)
  98. then LambdaOpt(pairsToListDotted args, lastOneInListDotted args, tag_parse body)
  99. else LambdaSimple(pairsToList args, tag_parse body)
  100. | Pair(Symbol("lambda"), Pair(args, body))-> if(hasLastOneInListDotted args)
  101. then LambdaOpt(pairsToListDotted args, lastOneInListDotted args, tag_parse (Pair(Symbol "begin", body)))
  102. else LambdaSimple(pairsToList args, tag_parse (Pair(Symbol "begin", body)))
  103. | Pair(Symbol("define"), Pair(Pair(Symbol(name), args), body))-> Def (Var(name),tag_parse (Pair(Symbol("lambda"), Pair(args, body))))
  104. | Pair(Symbol("define"), Pair(Symbol(name), Pair(body, Nil)))-> Def (Var(name),tag_parse body)
  105. | Pair(Symbol("set!"), Pair(Symbol(name), Pair(body, Nil)))-> Set (Var(name),tag_parse body)
  106. | Pair(Symbol("begin"), Nil)-> Const(Void)
  107. | Pair(Symbol("begin"), Pair(name,Nil))-> tag_parse name
  108. | Pair(Symbol("begin"), args)-> Seq(taggedList args)
  109. | Pair(Symbol("or"), Nil)-> Const(Sexpr(Bool(false)))
  110. | Pair(Symbol("or"), Pair(arg,Nil))-> tag_parse arg
  111. | Pair(Symbol("or"), args)-> Or(taggedList args)
  112. | Pair(Symbol("cond"), Pair(rib1, ribs))-> tag_parse(condMaker (rib1,ribs))
  113. | Pair(Symbol("let"), Pair(args, Pair(body,Nil)))-> tag_parse (Pair(Pair(Symbol "lambda", Pair(leftSideLet args, body)), rightSideLet args))
  114. | Pair(Symbol("let*"), Pair(Nil, body))-> tag_parse (Pair(Symbol("let"), Pair(Nil, Pair(body,Nil))))
  115. | Pair(Symbol("let*"), Pair(Pair(arg,Nil) , Pair(body,Nil))) -> tag_parse (Pair(Symbol("let"), Pair(Pair(arg,Nil), Pair(body,Nil))))
  116. | Pair(Symbol("let*"), Pair(Pair(arg,args), body)) -> tag_parse (Pair(Symbol "let",Pair(Pair(arg,Nil),Pair(Pair(Symbol "let*",Pair (args,Pair(body,Nil))),Nil))))
  117. | Pair(Symbol("and"), Nil)-> Const(Sexpr(Bool(true)))
  118. | Pair(Symbol("and"), Pair(arg,Nil))-> tag_parse arg
  119. | Pair(Symbol("and"), Pair(arg,args))-> If(tag_parse arg, tag_parse(Pair (Symbol("and"),args)), Const(Sexpr(Bool(false))))
  120. (* | Pair(Symbol("letrec"), Pair(args, Pair(body,Nil)))-> tag_parse (Pair(Symbol("let"),Pair(letrecLeft (leftSideLet args), setMaker(leftSideLet args,rightSideLetrec args,body)))) *)
  121. | Pair(Symbol("quasiquote"), Pair(arg,Nil))-> tag_parse(quasiMaker(arg))
  122.  
  123.  
  124. (* (Tag_Parser. tag_parse_expression (Pair (Symbol "lambda",Pair (Pair (Symbol "x", Pair (Symbol "y", Nil)),Pair (Pair (Symbol "+", Pair (Symbol "x", Pair (Symbol "y", Nil))),Pair (Pair (Symbol "*", Pair (Symbol "x", Pair (Symbol "y", Nil))), Nil)))))); *)
  125. | Pair(x,y) -> Applic((tag_parse x),taggedList y)
  126. | Symbol(x) -> Var(x)
  127. | _ -> raise X_no_match
  128. ) s
  129. and taggedList s=(function
  130. | Pair(x,y) -> (tag_parse x)::(taggedList y)
  131. | Nil -> [];
  132. | _ -> raise X_no_match
  133. ) s
  134.  
  135. and quasiMaker s = (function
  136. | Pair(Symbol "unquote",Pair(arg, Nil)) -> arg
  137. | Pair(Symbol "unquote-splicing",Pair(arg, Nil)) -> raise X_no_match
  138. | Pair(Pair(Symbol "unquote-splicing",arg), args) -> Pair(Symbol "append",Pair(Pair(Symbol "begin", arg), Pair(quasiMaker args,Nil)))
  139. | Pair(arg, Pair(Symbol "unquote-splicing",args)) -> Pair(Symbol "cons",Pair(quasiMaker arg, args))
  140. | Pair(arg,args) ->Pair(Symbol "cons",Pair(quasiMaker arg, Pair(quasiMaker args,Nil)))
  141. | Nil -> Pair(Symbol "quote", Pair(Nil,Nil))
  142. | (Symbol arg) -> Pair(Symbol "quote", Pair(Symbol arg,Nil))
  143. | arg -> arg
  144. ) s
  145. and condMaker s= (function
  146. | (Pair(value,Pair(Symbol("=>"),body)),Pair(rest1,rest2)) ->
  147. Pair (Symbol "let",Pair(
  148. Pair (Pair (Symbol "value", Pair(value,Nil)),
  149. Pair(Pair (Symbol "f",Pair (Pair (Symbol "lambda", Pair (Nil,body)),Nil)),
  150. Pair(Pair (Symbol "rest",Pair(Pair (Symbol "lambda", Pair(Nil, Pair(condMaker(rest1,rest2),Nil))), Nil)),Nil))),
  151. Pair (Symbol "if",Pair (Symbol "value",Pair (Pair (Pair (Symbol "f", Nil), Pair (Symbol "value", Nil)),Pair (Pair (Symbol "rest", Nil), Nil))))))
  152.  
  153. | (Pair(value,Pair(Symbol("=>"),body)),Nil) ->
  154. (Pair (Symbol "let",Pair(
  155. Pair (Pair (Symbol "value",Pair (value, Nil)),
  156. Pair(Pair (Symbol "f", Pair(Pair(Symbol "lambda", Pair (Nil, body)), Nil)),Nil)),
  157. Pair (Symbol "if",Pair (Symbol "value",Pair (Pair (Pair (Symbol "f", Nil), Pair(Symbol "value", Nil)), Nil))))))
  158. | (Pair(Symbol "else",body),rest)-> Pair(Symbol "begin",body)
  159. | (Pair(test,body),Pair(rest1,rest2)) -> Pair(Symbol("if"), Pair(test, Pair(Pair(Symbol "begin",body), Pair(condMaker (rest1,rest2), Nil))))
  160. | (Pair(test,body),Nil) -> Pair(Symbol("if"), Pair(test, Pair(Pair(Symbol "begin",body), Nil)))
  161. | _ -> raise X_no_match
  162. ) s
  163. and leftSideLet s=(function
  164. | Nil -> Nil
  165. | Pair(Pair(x,y),Nil) -> Pair(x, Nil)
  166. | Pair(Pair(x,y),z) -> Pair(x, (leftSideLet z))
  167. | _ -> raise X_no_match
  168. ) s
  169. and rightSideLet s=(function
  170. | Nil -> Nil
  171. | Pair(Pair(x,y),Nil) -> y
  172. | Pair(Pair(x,y),z) -> Pair(y ,(rightSideLet z))
  173. | _ -> raise X_no_match
  174. )s
  175. and rightSideLetrec s=(function
  176. | Pair(Pair(x,Pair(y,Nil)),Nil) -> [y]
  177. | Pair(Pair(x,Pair(y,Nil)),z) -> y:: (rightSideLetrec z)
  178. | _ -> raise X_no_match
  179. )s
  180. and letrecLeft s =(function
  181. | [] -> Nil
  182. | a :: b -> Pair (Pair(Symbol a, Pair(Symbol "'whatever",Nil)), letrecLeft b)
  183. )s
  184. and setMaker s =(function
  185. | ([],[],body) -> Pair(Pair(Symbol("let"), Pair(Nil, body)),Nil)
  186. | (a :: b,c::d,body) -> Pair (Pair (Symbol "set!", Pair (Symbol a, Pair (c, Nil))), setMaker (b,d,body))
  187. | _ -> Nil
  188. )s
  189. ;;
  190.  
  191. let tag_parse_expression sexpr = tag_parse sexpr;;
  192.  
  193. let tag_parse_expressions sexpr = List.map tag_parse_expression sexpr;;
  194.  
  195.  
  196. end;; (* struct Tag_Parser *)
  197.  
  198.  
  199. (* Pair (Symbol "cond", Pair(Pair (Symbol "t",Pair (Number (Int 1), Pair (Number (Int 2), Pair (Number (Int 3), Nil)))),Nil)) *)
  200.  
  201. (* Pair (Symbol "cond",Pair(Pair (Symbol "t",Pair(Pair (Number (Int 1), Pair (Number (Int 2), Pair (Number (Int 3), Nil))),Nil)),Nil)) *)
  202. (* Pair (Symbol "cond", Pair(Pair (Symbol "t",Pair (Pair (Number (Int 1), Nil), Pair (Pair (Number (Int 2), Nil), Pair (Pair (Number (Int 3), Nil), Nil)))),Nil)) *)
  203.  
  204. (* Pair (Symbol "cond", Pair (Pair (Bool true, Pair (Number (Int 1), Pair (Number (Int 2), Pair (Number (Int 3), Nil)))),Nil)) *)
  205.  
  206. let rec is_proper_list sexpr =
  207. match sexpr with
  208. | Pair(a,Nil) -> true
  209. | Pair(a,b) -> is_proper_list b
  210. | _-> raise X_syntax_error
  211.  
  212. and pair_to_string sexpr =
  213. let rec proper_list list =
  214. match list with
  215. | Pair(a,Nil) -> sexpr_to_string_literal a
  216. | Pair(a,b) -> (sexpr_to_string_literal a)^" "^(proper_list b) in
  217. let rec improper_list list =
  218. match list with
  219. | Pair(a,b) -> " "^(sexpr_to_string_literal a)^(proper_list b)
  220. | _-> " . "^(sexpr_to_string_literal list) in
  221. if(is_proper_list sexpr) then "("^(proper_list sexpr)^")"
  222. else "("^(improper_list sexpr)^")"
  223.  
  224. and sexpr_to_string_literal sexpr =
  225. match sexpr with
  226. | Bool(b) -> string_of_bool b
  227. | Number(Int(n)) -> string_of_int n
  228. | Number(Float(f)) -> string_of_float f
  229. | Nil -> "()"
  230. | Char(c) -> list_to_string [c]
  231. | String(s) -> s
  232. | Symbol(s) -> s
  233. | Pair(a,b) -> pair_to_string sexpr
  234. | TaggedSexpr(a,b) -> "#{"^a^"}="^sexpr_to_string_literal b
  235. | TagRef(s) -> s;;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement