home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / build / batch.sml next >
Encoding:
Text File  |  1993-02-09  |  11.3 KB  |  374 lines

  1. (* Copyright 1989 by AT&T Bell Laboratories *)
  2. functor Batch(structure M: CODEGENERATOR and A:ASSEMBLER)  : sig end =
  3. struct
  4.  
  5. val pr = System.Print.say
  6. open PrintUtil CompUtil ProcessFile System.Print
  7. structure CGoptions = System.Control.CG
  8.  
  9. (* command parsing *)
  10.  
  11. fun skip_white stream =
  12.     case lookahead stream
  13.       of " " => (input(stream,1); skip_white stream)
  14.        | "\t" => (input(stream,1); skip_white stream)
  15.        | "\n" => (input(stream,1); skip_white stream)
  16.        | _ => ()
  17.  
  18. fun getword stream =
  19.     let val nextchar = input(stream,1)
  20.      in case nextchar
  21.       of "" => ""
  22.        | " " => ""
  23.        | "\t" => ""
  24.        | "\n" => ""
  25.        | _ => nextchar ^ getword stream
  26.     end
  27.  
  28. (* printDepth *)
  29.  
  30. val _  = signatures := 0
  31.  
  32. (* compilation static environment *)
  33. val compenv = ref({static = StaticEnv.empty, inverse = InverseEnv.empty})
  34.  
  35. (* The commandline interpreter *)
  36.  
  37. val srcDir = ref ""
  38. val dstDir = ref ""
  39. val globalhandle = ref true
  40. val dumpCore = ref false
  41.  
  42. fun compile env fname = 
  43.     let val file = !srcDir ^ fname
  44.         fun p(function,s) = 
  45.         let fun complain _ s = (pr(file ^ ": " ^ s ^ "\n"); raise Abort)
  46.         val code = M.generate(function,NONE,complain)
  47.         val codesize = String.size(System.Unsafe.cast code)
  48.         val outfile = open_out(!dstDir ^ s ^ ".mo")
  49.          in System.Stats.codesize := codesize + !System.Stats.codesize;
  50.         outputc outfile code;
  51.         close_out outfile
  52.         end
  53.      in pr("[Compiling " ^ file ^ "]\n");
  54.     process(env, file, SOME p)
  55.     end
  56.  
  57. fun assemble env s = 
  58.     let val file = !srcDir ^ s
  59.         fun p(function,s) = 
  60.         let fun complain _ s = (pr(file ^ ": "^s); raise Abort)
  61.         val outfile = open_out(!dstDir ^ s ^ ".s")
  62.          in A.generate ((function,NONE,complain), outfile);
  63.         close_out outfile
  64.         end
  65.      in pr("[Assembling " ^ file ^ "]\n");
  66.     process(env,file,SOME p)
  67.     end
  68.  
  69. fun load env s = 
  70.     let val file = !srcDir ^ s
  71.      in pr ("[Loading " ^ file ^ "]\n");
  72.     process(env,file,NONE)
  73.     end
  74.  
  75. fun export s =
  76.     let val file = !srcDir ^ s
  77.     val msg = System.version ^ " (batch compiler)\n"
  78.      in pr("[Exporting to " ^ file ^ "]\n"); exportML file; pr msg
  79.     end
  80.  
  81. exception Notfound_Compile of string
  82. local open System.Control 
  83.       open CG
  84.       val flags = [
  85.         ("tailrecur",tailrecur),
  86.         ("recordopt",recordopt),
  87.         ("tail",tail),
  88.         ("allocprof",allocprof),
  89.         ("closureprint",closureprint),
  90.             ("lambdaopt",lambdaopt),
  91.         ("cpsopt",cpsopt),
  92.         ("path",path),
  93.         ("betacontract",betacontract),
  94.         ("eta",eta),
  95.         ("selectopt",selectopt),
  96.         ("dropargs",dropargs),
  97.         ("deadvars",deadvars),
  98.         ("flattenargs",flattenargs),
  99.         ("switchopt",switchopt),
  100.         ("handlerfold",handlerfold),
  101.         ("branchfold",branchfold),
  102.         ("arithopt",arithopt),
  103.         ("betaexpand",betaexpand),
  104.         ("unroll",unroll),
  105.         ("unroll_recur",unroll_recur),
  106.         ("newconreps",newconreps),
  107.         ("knownfiddle",knownfiddle),
  108.         ("lambdaprop",lambdaprop),
  109.         ("invariant",invariant),
  110.         ("hoistup",hoistup),
  111.         ("hoistdown",hoistdown),
  112.         ("recordcopy",recordcopy),
  113.         ("tagopt",tagopt),
  114.         ("machdep",machdep),
  115.         ("misc1",misc1),
  116.         ("misc2",misc2),
  117.         ("hoist",hoist),
  118.         ("argrep",argrep),
  119.         ("reduce",reduce),
  120.         ("alphac",alphac),
  121.         ("comment",comment),
  122.         ("foldconst",foldconst),
  123.         ("etasplit",etasplit),
  124.         ("printit",printit),
  125.         ("printLambda",printLambda),
  126.         ("printsize",printsize),
  127.         ("scheduling",scheduling),
  128.         ("internals",internals),
  129.         ("MC.printArgs",MC.printArgs),
  130.         ("MC.printRet",MC.printRet),
  131.         ("MC.bindContainsVar",MC.bindContainsVar),
  132.         ("MC.bindExhaustive",MC.bindExhaustive),
  133.         ("MC.matchExhaustive",MC.matchExhaustive),
  134.         ("MC.matchRedundant",MC.matchRedundant),
  135.         ("MC.expandResult",MC.expandResult),
  136.         ("saveLvarNames",Access.saveLvarNames),
  137.         ("saveLambda",saveLambda),
  138.                 ("markabsyn",markabsyn),
  139.         ("debugging",debugging),
  140.         ("debugLook",debugLook),
  141.         ("debugBind",debugBind),
  142.         ("timings",timings),
  143.         ("dumpCore",dumpCore),
  144.         ("globalhandle",globalhandle),
  145.         ("indexing",System.Control.indexing),
  146.         ("ifidiom",ifidiom),
  147.         ("uncurry",uncurry),
  148.         ("cse",cse),
  149.         ("csehoist",csehoist),
  150.         ("rangeopt",rangeopt),
  151.         ("comparefold",comparefold),
  152.         ("extraflatten",extraflatten),
  153.         ("profiling",System.Unsafe.profiling),
  154.         ("floatreg_params",floatreg_params),
  155.         ("icount",icount),
  156.                 ("representations",representations)]
  157. in
  158. fun getflag f =
  159.     let fun get nil = raise Notfound_Compile f
  160.       | get ((name,flag)::tl) = if f=name then flag else get tl
  161.      in get flags
  162.     end
  163.  
  164. fun printflags () =
  165.     (pr "[Flags:\n";
  166.      app (fn(name,flag:bool ref) => (pr name; pr " = "; pr(makestring(!flag)); pr "\n"))
  167.      flags;
  168.      pr "]\n")
  169. end
  170.  
  171. fun toggle "" = printflags()
  172.   | toggle arg =
  173.     let val flag = getflag arg
  174.     val new = not(!flag)
  175.     in pr ("["^arg^" := "^makestring new^"]\n"); flag := new
  176.     end
  177.  
  178. fun lsave () = (toggle "saveLambda"; toggle "saveLvarNames")
  179.  
  180. fun atoi s =
  181.     let val dtoi = fn "0" => 0 | "1" => 1 | "2" => 2 | "3" => 3 | "4" => 4
  182.             | "5" => 5 | "6" => 6 | "7" => 7 | "8" => 8 | "9" => 9
  183.             | _ => (pr "[garbled integer input]\n"; raise Abort)
  184.     in case explode s
  185.     of "~" :: s' => ~ (revfold (fn(a,b) => b * 10 + dtoi a) s' 0)
  186.      | s' => revfold (fn(a,b) => b * 10 + dtoi a) s' 0
  187.     end
  188.  
  189. fun gcmessage() =
  190.     let val f = System.Control.Runtime.gcmessages
  191.     in f := (!f + 1) mod 4; pr "[gcmessages := "; pr(makestring(!f)); pr "]\n"
  192.     end
  193.  
  194. fun summary() =
  195.     (System.Stats.summary();
  196.      pr "Generated code for:\n";
  197.      pr(makestring(!System.Control.CG.knownGen));
  198.      pr " known functions\n";
  199.      pr(makestring(!System.Control.CG.knownClGen));
  200.      pr " known functions with closures\n";
  201.      pr(makestring(!System.Control.CG.escapeGen));
  202.      pr " escaping functions\n";
  203.      pr(makestring(!System.Control.CG.calleeGen));
  204.      pr " callee-save continuations\n";
  205.      pr(makestring(!System.Control.CG.spillGen));
  206.      pr " spills\n";
  207.      ())
  208.  
  209. val intvars = [("ratio",System.Control.Runtime.ratio),
  210.            ("maxregs",System.Control.CG.maxregs),
  211.            ("misc3",System.Control.CG.misc3),
  212.            ("misc4",System.Control.CG.misc4),
  213.            ("knownGen",System.Control.CG.knownGen),
  214.            ("knownClGen",System.Control.CG.knownClGen),
  215.            ("escapeGen",System.Control.CG.escapeGen),
  216.            ("calleeGen",System.Control.CG.calleeGen),
  217.            ("spillGen",System.Control.CG.spillGen),
  218.            ("softmax",System.Control.Runtime.softmax),
  219.            ("bodysize",System.Control.CG.bodysize),
  220.            ("rounds",System.Control.CG.rounds),
  221.            ("reducemore",System.Control.CG.reducemore),
  222.            ("targeting",System.Control.CG.targeting),
  223.            ("closureStrategy",System.Control.CG.closureStrategy),
  224.            ("calleesaves",System.Control.CG.calleesaves),
  225.            ("floatargs",System.Control.CG.floatargs),
  226.            ("floatvars",System.Control.CG.floatvars),
  227.            ("signatures",signatures)]
  228.  
  229. val otherexecs =        
  230.        [("lsave",lsave),
  231.     ("summary",summary),
  232.     ("prFun",fn () =>
  233.         prFun(atoi(skip_white std_in; getword std_in))),
  234.     ("gcmessages",gcmessage),
  235.     ("flushstdout",fn () => set_term_out(!System.Print.out,true)),
  236.     ("dumpMap",dumpMap),
  237.     ("asBoot",fn () =>
  238.        let val (env,_) = BootEnv.bootEnv assemble
  239.         in compenv := env
  240.        end),
  241.     ("mBoot",fn () =>
  242.        let val (senv,_) = BootEnv.bootEnv compile
  243.         in compenv := senv
  244.        end),
  245.     ("primeEnv",fn () => (compenv := {static=Prim.primEnv,
  246.                                           inverse=InverseEnv.empty})),
  247.     ("allocReport",AllocProf.print_profile_info),
  248.     ("allocReset",AllocProf.reset) (* ,
  249.     ("clear",System.Control.Profile.clear),
  250.     ("reset",System.Control.Profile.reset),
  251.     ("report",fn () => System.Control.Profile.report (!System.Print.out)),
  252.     ("profileOff",System.Control.Profile.profileOff),
  253.     ("profileOn",System.Control.Profile.profileOn) *)]
  254.  
  255. val execs = otherexecs
  256.        @ map (fn (s,r) => ("set"^s, fn()=>
  257.         let val i = atoi(skip_white std_in; getword std_in)
  258.         in  pr "["; pr s; pr " := "; pr(makestring i); pr "]\n";
  259.             r := i
  260.         end)) intvars
  261.  
  262.  
  263. fun getexec f =
  264.     let fun get nil = raise Notfound_Compile f
  265.       | get ((name,exec)::tl) = if f=name then exec else get tl
  266.      in get execs
  267.     end
  268.  
  269. fun printexecs () =
  270.     (pr "[Available execs:\n";
  271.      app (fn ("prFun",_) => pr "prFun <lvar>\n"
  272.        | ("printslots",_) => pr "printslots <structure>\n"
  273.        | (name,_) => (pr name; pr "\n"))
  274.      otherexecs;
  275.      app (fn (s,r) => (pr "set"; pr s; pr " <int>  (currently ";
  276.                pr(makestring(!r)); pr ")\n"))
  277.          intvars;
  278.      pr "]\n")
  279.  
  280. fun execute "" = printexecs()
  281.   | execute arg =
  282.     let val exec = getexec arg
  283.     in  pr("["^arg^"()]\n");
  284.     exec()
  285.     end
  286.  
  287. fun help() = pr "\
  288. \!file      => compile the file.\n\
  289. \*file      => assemble the file.\n\
  290. \<file      => parse the file.\n\
  291. \>file      => export to a file.\n\
  292. \%          => print the last generated lambda.\n\
  293. \#word      => comment; ignored.\n\
  294. \@directory => look for files in a directory (directory should end in /).\n\
  295. \&directory => put mo files in a directory (directory should end in /).\n\
  296. \~function  => execute a function.\n\
  297. \^flag      => toggle a flag.\n\
  298. \?          => print this help message.\n"
  299.  
  300. fun interp "" = ()
  301.   | interp word =
  302.     let val arg = substring(word,1,size word - 1) handle Substring => ""
  303.     in  (case substring(word,0,1) of
  304.            "!" => compenv := compile (!compenv) arg
  305.         | "*" => compenv := assemble (!compenv) arg
  306.         | "<" => compenv := load (!compenv) arg
  307.         | ">" => export arg
  308.         | "%" => ProcessFile.prLambda()
  309.         | "#" => ()            (* comment *)
  310.         | "@" => srcDir := arg    (* change load directory *)
  311.         | "&" => dstDir := arg    (* change load directory *)
  312.         | "~" => execute arg    (* execute function *)
  313.         | "^" => toggle arg        (* toggle flag *)
  314.         | "?" => help()        
  315.         |  _  => pr ("[What is \""^word^"\"?]\n")
  316.     ) handle e as Notfound_Compile f =>
  317.            (pr("[flag \""^f^"\" not recognized]\n");
  318.             raise e)
  319.     end
  320.  
  321. exception INTERRUPT
  322. fun setcont () = (
  323.       System.Unsafe.toplevelcont := callcc(fn k => (
  324.       callcc(fn k' => (throw k k'));
  325.       raise INTERRUPT)))
  326. fun interp1 word = if !globalhandle
  327.       then (setcont(); interp word)
  328.       handle Abort => (
  329.               pr "[Failed on "; pr_mlstr word; pr "]\n"; System.Print.flush())
  330.            | INTERRUPT => (pr "\n[Interrupt]\n"; System.Print.flush())
  331.            | e => (
  332.               pr "[Failed on "; pr_mlstr word; pr " with ";
  333.               pr(System.exn_name e); pr "]\n"; System.Print.flush())
  334.       else (setcont(); interp word)
  335.       handle e => (
  336.           case e
  337.            of INTERRUPT => (pr "\n[Interrupt]\n")
  338.             | _ => (pr "[Failed on "; pr_mlstr word; pr " with ";
  339.                     pr(System.exn_name e); pr "]\n");
  340.         System.Print.flush();
  341.         if !dumpCore
  342.         then (toggle "globalhandle";
  343.           toggle "dumpCore";
  344.                   pr "[Saving state]\n[Exporting to sml.save]\n";
  345.           System.Print.flush();
  346.                   if exportML "sml.save"
  347.                     then pr "hello there\n"
  348.                     else (summary(); raise e))
  349.             else raise e)
  350.          
  351. (* command-line interpreter top-level loop *)
  352. fun toplevel () =
  353.     if end_of_stream std_in
  354.     then ()
  355.     else (skip_white std_in;
  356.       if (end_of_stream std_in)
  357.       then () 
  358.       else (interp1(getword std_in); 
  359.         compenv := Environment.consolidateStatic(!compenv);
  360.         toplevel ()))
  361.  
  362.  
  363. (* load the pervasives into top-level env (no .mo files generated) *)
  364. val _ = 
  365.   let val (env,_) = BootEnv.bootEnv load      
  366.    in compenv := Environment.consolidateStatic(env)
  367.   end
  368.  
  369. (* start up command interpreter *)
  370. val _ = (pr "Batch Interpreter\n";
  371.      toplevel ())
  372.  
  373. end
  374.