home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Moscow ML 1.31 / source code / mosml / src / compiler / Mixture.sml < prev    next >
Encoding:
Text File  |  1996-07-03  |  6.1 KB  |  248 lines  |  [TEXT/R*ch]

  1. open BasicIO Nonstdio Fnlib Config PP;
  2.  
  3. exception Toplevel;
  4. exception EndOfFile;
  5. exception LexicalError of string * int * int;
  6.  
  7. val toplevel = ref false;
  8.  
  9. val pp_out = mk_ppstream
  10. {
  11.   linewidth = 79,
  12.   flush     = fn() => flush_out std_out,
  13.   consumer  = outputc std_out
  14. };
  15.  
  16. fun msgCBlock offset = begin_block pp_out CONSISTENT offset;
  17. fun msgIBlock offset = begin_block pp_out INCONSISTENT offset;
  18. fun msgEBlock() = end_block pp_out;
  19. fun msgBreak size_offset = add_break pp_out size_offset;
  20. fun msgClear() = clear_ppstream pp_out;
  21. fun msgFlush() = flush_ppstream pp_out;
  22.  
  23. val msgString = add_string pp_out;
  24.  
  25. fun msgChar (i : char) = msgString (String.str i);
  26. fun msgInt  (i : int)  = msgString (makestring i);
  27. fun msgReal (r : real) = msgString (makestring r);
  28.  
  29. fun msgEOL() = add_newline pp_out;
  30.  
  31. fun msgPrompt s =
  32.   (if !toplevel then msgString toplevel_output_prompt
  33.                 else msgString batch_output_prompt;
  34.   msgString s)
  35. ;
  36.  
  37. fun msgContPrompt s =
  38.   (if !toplevel then msgString toplevel_output_cont_prompt
  39.                 else msgString batch_output_cont_prompt;
  40.   msgString s)
  41. ;
  42.  
  43. fun errPrompt s =
  44.   (if !toplevel then msgString toplevel_error_prompt
  45.                 else msgString batch_error_prompt;
  46.   msgString s)
  47. ;
  48.  
  49. (* Handling files and directories *)
  50.  
  51. val path_library = ref "";
  52. val load_path = ref ([] : string list);
  53.  
  54. fun cannot_find filename =
  55.   raise (Fail ("Cannot find file "^filename))
  56. ;
  57.  
  58. fun find_in_path filename =
  59.   if file_exists filename then
  60.     filename
  61.   else if Filename.is_absolute filename then
  62.     cannot_find filename
  63.   else
  64.     let fun h [] =
  65.               cannot_find filename
  66.           | h (a::rest) =
  67.               let val b = Filename.concat a filename in
  68.                 if file_exists b then b else h rest
  69.               end
  70.     in h (!load_path) end
  71. ;
  72.  
  73. fun remove_file f =
  74.   Miscsys.remove f
  75.     handle Io _ => ()
  76. ;
  77.  
  78. (* ---------- *)
  79.  
  80. datatype Lab =
  81.     INTlab of int
  82.   | STRINGlab of string
  83. ;
  84.  
  85. type 'a Row = (Lab * 'a) list;
  86.  
  87. fun printLab (STRINGlab s) = msgString s
  88.   | printLab (INTlab i) = msgInt i
  89. ;
  90.  
  91. val labOne = INTlab 1
  92. and labTwo = INTlab 2
  93. ;
  94.  
  95. fun isPairRow [(INTlab 1, _), (INTlab 2, _)] = true
  96.   | isPairRow [(INTlab 2, _), (INTlab 1, _)] = true
  97.   | isPairRow _ = false
  98. ;
  99.  
  100. fun isTupleRow' n [] = true
  101.   | isTupleRow' n (((INTlab i), _) :: fs) =
  102.       if n = i then isTupleRow' (n+1) fs else false
  103.   | isTupleRow' n _ = false
  104.  
  105. fun isTupleRow fs =
  106.   (List.length fs <> 1) andalso (isTupleRow' 1 fs)
  107. ;
  108.  
  109. fun mkPairRow x1 x2 = [(labOne, x1), (labTwo, x2)];
  110.  
  111. fun mkTupleRow' n [] = []
  112.   | mkTupleRow' n (x :: xs) =
  113.       (INTlab n, x) :: mkTupleRow' (n+1) xs
  114. ;
  115.  
  116. fun mkTupleRow xs = mkTupleRow' 1 xs;
  117.  
  118. fun lt_lab (STRINGlab s1) (STRINGlab s2)  = s1 < s2
  119.   | lt_lab (STRINGlab _)  (INTlab _)      = true
  120.   | lt_lab (INTlab _)     (STRINGlab _)   = false
  121.   | lt_lab (INTlab i1)    (INTlab i2)     = i1 < i2
  122. ;
  123.  
  124. fun insertField (lab, x) fields =
  125.   case fields of
  126.       [] => [(lab, x)]
  127.     | (lab', x') :: rest =>
  128.         if lt_lab lab lab' then
  129.           (lab, x) :: fields
  130.         else if lt_lab lab' lab then
  131.           (lab', x') :: insertField (lab, x) rest
  132.         else
  133.           fatalError "insertField"
  134. ;
  135.  
  136. fun sortRow row = foldL insertField [] row;
  137.  
  138. (* --- Local environments --- *)
  139.  
  140. datatype ('a, 'b) Env
  141.   = NILenv
  142.   | BNDenv of 'a * 'b * ('a, 'b) Env
  143.   | TOPenv of ('a, 'b) Hasht.t * ('a, 'b) Env
  144.   | COMPenv of ('a, 'b) Env * ('a, 'b) Env
  145. ;
  146.  
  147. fun plusEnv NILenv env2   = env2
  148.   | plusEnv env1   NILenv = env1
  149.   | plusEnv env1   env2   = COMPenv(env2, env1)
  150. ;
  151.  
  152. fun lookupEnv env key =
  153.   let val rec search = fn
  154.        NILenv => raise Subscript
  155.      | BNDenv(k, v, env) =>
  156.          if key = k then v else search env
  157.      | TOPenv(x, env) =>
  158.          (Hasht.find x key handle Subscript => search env)
  159.      | COMPenv(env1, env2) =>
  160.          (search env1 handle Subscript => search env2)
  161.   in search env end
  162. ;
  163.  
  164. fun bindInEnv env k v = BNDenv(k, v, env);
  165. fun bindTopInEnv env x = TOPenv(x, env);
  166.  
  167. fun mk1Env k v = BNDenv(k, v, NILenv);
  168. fun mk1TopEnv x = TOPenv(x, NILenv);
  169.  
  170. fun revEnvAcc NILenv acc = acc
  171.   | revEnvAcc (BNDenv(k, v, env)) acc =
  172.       revEnvAcc env (BNDenv(k, v, acc))
  173.   | revEnvAcc (TOPenv(x, env)) acc =
  174.       revEnvAcc env (TOPenv(x, acc))
  175.   | revEnvAcc (COMPenv(env1, env2)) acc =
  176.       revEnvAcc env2 (revEnvAcc env1 acc)
  177. ;
  178.  
  179. fun revEnv env = revEnvAcc env NILenv;
  180.  
  181. fun domHashTbl tbl =
  182.   let val dom = ref [] in
  183.     Hasht.apply (fn key => fn v =>
  184.       if member key (!dom) then () else dom := key :: !dom)
  185.       tbl;
  186.     !dom
  187.   end;
  188.  
  189. fun traverseEnv action env =
  190.   let fun traverse NILenv = ()
  191.         | traverse (BNDenv(k, v, env)) =
  192.             (action k v; traverse env)
  193.         | traverse (TOPenv(x, env)) =
  194.             let val dom = domHashTbl x in
  195.               List.app (fn k => action k (Hasht.find x k)) dom;
  196.               traverse env
  197.             end
  198.         | traverse (COMPenv(env1, env2)) =
  199.             (traverse env1; traverse env2)
  200.   in traverse env end
  201. ;
  202.  
  203. fun mapEnv f env0 =
  204.   case env0 of
  205.       NILenv => NILenv
  206.     | BNDenv(k, v, env) =>
  207.         bindInEnv (mapEnv f env) k (f k v)
  208.     | TOPenv(x, env) =>
  209.         let val dom = domHashTbl x in
  210.           foldL (fn k => fn env => bindInEnv env k (f k (Hasht.find x k)))
  211.                 (mapEnv f env) dom
  212.         end
  213.     | COMPenv(env1, env2) =>
  214.         COMPenv(mapEnv f env1, mapEnv f env2)
  215. ;
  216.  
  217. fun foldEnv f u env0 =
  218.   case env0 of
  219.       NILenv => u
  220.     | BNDenv(k, v, env) =>
  221.         f k v (foldEnv f u env)
  222.     | TOPenv(x, env) =>
  223.         let val dom = domHashTbl x in
  224.           foldL (fn k => f k (Hasht.find x k)) (foldEnv f u env) dom
  225.         end
  226.     | COMPenv(env1, env2) =>
  227.         foldEnv f (foldEnv f u env2) env1
  228. ;
  229.  
  230. (* --- Stamps of compiled signatures --- *)
  231.  
  232. type SigStamp = string;
  233.  
  234. val char_star = Char.chr 42;
  235. val dummySigStamp = CharVector.tabulate(20, fn _ => char_star);
  236.  
  237. (* This table is used by `load' to prevent mismatching *)
  238. (* versions of compiled units from being loaded, and also *)
  239. (* to prevent the same unit from being loaded twice. *)
  240.  
  241. val watchDog = ref (Hasht.new 17 : (string, SigStamp) Hasht.t);
  242.  
  243. (* The list of automatically preloaded units. *)
  244. (* Some of them are also preopened. *)
  245.  
  246. val preloadedUnits = ref ([] : string list);
  247. val preopenedPreloadedUnits = ref ([] : string list);
  248.