Annotation of researchv10no/cmd/sml/src/build/interact.sml, revision 1.1

1.1     ! root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
        !             2: functor Interact(structure Machm : CODEGENERATOR
        !             3:                 structure Importer: IMPORTER
        !             4:                ) : sig end =
        !             5: struct
        !             6: (* structure Reopener = Reopen(struct structure C=Machine and Machm=Machm end) *)
        !             7: 
        !             8:   open ErrorMsg Access Basics BareAbsyn Lambda PrintUtil ProcessFile
        !             9: 
        !            10:   exception Stop
        !            11:   val printDepth = System.Control.Print.printDepth
        !            12:   val saveLambda = System.Control.saveLambda
        !            13:   val bucket = ref (Lambda.RECORD [])
        !            14:   val _ = System.Control.prLambda :=
        !            15:      fn () => (MCprint.printLexp (!bucket); newline())
        !            16:   fun spoolLambda l = if !saveLambda then bucket := l else ()
        !            17:   val lambda = ref (Lambda.RECORD [])
        !            18:   val vars = ref (nil : int list)
        !            19:   fun prLambda () = (MCprint.printLexp(!lambda); newline())
        !            20:   fun prFun lv = (MCprint.printFun(!lambda) lv; newline())
        !            21:   fun timemsg (s : string) =
        !            22:       let val printit = !System.Control.timings
        !            23:        in if printit then (print s; newline()) else ();
        !            24:          printit
        !            25:       end
        !            26: 
        !            27:  (* functions for retrieving new bound lvars from declaration abstract syntax *)
        !            28: 
        !            29:   fun smash f l = fold (fn (a,c) => f a @ c) l []
        !            30: 
        !            31:   fun patvars (VARpat(VALvar{access=LVAR v,...})) = [v]
        !            32:     | patvars (VARpat(VALvar{access=INLINE _,...})) = []
        !            33:     | patvars (VARpat _ ) = impossible "non-LVAR in translate.patvars"
        !            34:     | patvars (RECORDpat{fields,...}) = smash (fn (_,p) => patvars p) fields
        !            35:     | patvars (APPpat(_,p)) = patvars p
        !            36:     | patvars (CONSTRAINTpat(p,_)) = patvars p
        !            37:     | patvars (LAYEREDpat(p,q)) = patvars p @ patvars q
        !            38:     | patvars _ = []
        !            39: 
        !            40:   fun getvars (VALdec vbl) = smash (fn VB{pat,...} => patvars pat) vbl
        !            41:     | getvars (a as VALRECdec rvbl) =
        !            42:        smash (fn RVB{var=VALvar{access=LVAR(var),...},exp,...} => [var]
        !            43:                | _ => impossible "#738 in translate")
        !            44:              rvbl
        !            45:     | getvars (LOCALdec (localdec,visibledec)) = getvars visibledec
        !            46:     | getvars (EXCEPTIONdec ebl) =
        !            47:        map (fn EBgen{exn=DATACON{rep=VARIABLE(LVAR v),...},...} => v
        !            48:              | EBdef{exn=DATACON{rep=VARIABLE(LVAR v),...},...} => v
        !            49:              | _ => impossible "in getvars EXCEPTIONdec")
        !            50:            ebl
        !            51:     | getvars (SEQdec decl) = smash getvars decl
        !            52:     | getvars (DATATYPEdec _) = []
        !            53:     | getvars (ABSTYPEdec{body,...}) = getvars body
        !            54:     | getvars (TYPEdec _) = []
        !            55:     | getvars (STRdec sbl) =
        !            56:        map (fn STRB{strvar=STRvar{access=LVAR(v),...},...} => v
        !            57:              | _ => impossible "getvars(STRdec)/fn"
        !            58:            ) sbl
        !            59:     | getvars (ABSdec sbl) =
        !            60:        map (fn STRB{strvar=STRvar{access=LVAR(v),...},...} => v
        !            61:              | _ => impossible "getvars(ABSdec)/fn"
        !            62:            ) sbl
        !            63:     | getvars (FCTdec fbl) =
        !            64:        map (fn FCTB{fctvar=FCTvar{name,access=LVAR(v),...},...} => v
        !            65:              | _ => impossible "getvars(FCTdec)/fn"
        !            66:            ) fbl
        !            67:     | getvars (OPENdec _) = []
        !            68:     | getvars (SIGdec _) = []
        !            69:     | getvars (IMPORTdec _) = impossible "getvars(IMPORTdec)"
        !            70:     | getvars (MARKdec (dec,_,_)) = getvars dec
        !            71: 
        !            72:     open System.Timer
        !            73:     val update = System.Stats.update
        !            74: 
        !            75:     (* set up top-level runtime environment, represented as intmap *)
        !            76:     exception Runbind
        !            77:     val t = Intmap.new(32, Runbind) : System.Unsafe.object Intmap.intmap
        !            78:     val bind = Intmap.add t   (* add runtime binding *)
        !            79:     val unbind = Intmap.rem t (* remove runtime binding *)
        !            80:     val _ = System.Unsafe.lookup_r := Intmap.map t
        !            81:     val lookup = System.Unsafe.lookup
        !            82: 
        !            83:     fun parse(lex : Lex.lexer) =
        !            84:        let val ref linenum = ErrorMsg.lineNum
        !            85:            val timer = start_timer()
        !            86:            fun moretops() = case !(#nextToken lex)
        !            87:                                         of Token.SEMICOLON => nil
        !            88:                                          | Token.EOF => nil
        !            89:                                           | Token.IMPORT => nil
        !            90:                                           | _ => tops()
        !            91:             and tops() = 
        !            92:                let val e0 = Env.current()
        !            93:                 in while !(#nextToken lex) = Token.SEMICOLON 
        !            94:                            do (#advance lex)();
        !            95:                    case Parse.interdec lex
        !            96:                      of x as BareAbsyn.IMPORTdec _ => [x]
        !            97:                      | OPENdec strvars =>
        !            98:                                (Env.resetEnv e0;
        !            99:                                 SEQdec(map Misc.dumpStructure strvars) ::
        !           100:                                                moretops())
        !           101:                      | y => y :: moretops()
        !           102:                end
        !           103:            val absyn = (ErrorMsg.anyErrors := false; 
        !           104:                         case tops() of [dec] => dec 
        !           105:                                      | seq => Absyn.SEQdec seq)
        !           106:            val time = check_timer timer
        !           107:            val lines = !ErrorMsg.lineNum - linenum
        !           108:        in  update(System.Stats.parse,time);
        !           109:            System.Stats.lines := !System.Stats.lines + lines;
        !           110:            timemsg ("parse, " ^ Integer.makestring lines
        !           111:                     ^ " lines, " ^ makestring time ^ "s")
        !           112:                orelse debugmsg "parse";
        !           113:            if !System.Control.debugging
        !           114:            then (PrintAbsyn.printDec(absyn,0,!printDepth); newline())
        !           115:            else ();
        !           116:            if !anyErrors then raise Stop else ();
        !           117:            absyn
        !           118:        end
        !           119: 
        !           120:     fun translate absyn =
        !           121:        let val timer = start_timer()
        !           122:            val newlvars = getvars absyn
        !           123:            val (absyn', profileList) = Prof.instrumDec(absyn)
        !           124:            val lambda' = FN(mkLvar(), Translate.transDec absyn' 
        !           125:                            (Lambda.RECORD (map Lambda.VAR newlvars)))
        !           126:            val lambda = Prof.bindLambda(lambda',profileList)
        !           127:            val time = check_timer timer
        !           128:         in update(System.Stats.translate,time);
        !           129:            timemsg ("translate, " ^ makestring time ^ "s")
        !           130:                orelse debugmsg "translate";
        !           131:            if !anyErrors then raise Stop else ();
        !           132:            (newlvars, lambda)
        !           133:        end
        !           134: 
        !           135:     fun opt lambda =
        !           136:        let val timer = start_timer()
        !           137:            val lambda = if !CGoptions.reduce then Opt.reduce lambda else lambda
        !           138:            val _ = if !anyErrors then raise Stop else ()
        !           139:            val lambda = if !CGoptions.hoist then Opt.hoist lambda else lambda
        !           140:            val time = check_timer timer
        !           141:        in  update(System.Stats.codeopt,time);
        !           142:            timemsg ("codeopt, " ^ makestring time ^ "s")
        !           143:                orelse debugmsg "codeopt";
        !           144:            lambda
        !           145:        end
        !           146: 
        !           147:     fun codegen lambda =
        !           148:        let val timer = start_timer()
        !           149:            val executable =
        !           150:                  (if !anyErrors then raise Stop else ();
        !           151:                   debugmsg "about to boot";
        !           152:                   (System.Unsafe.boot : 
        !           153:                      string -> ((int->System.Unsafe.object) ->
        !           154:                                  ((unit -> System.Unsafe.object Array.array) *
        !           155:                                   ByteArray.bytearray Array.array)))
        !           156:                   (Machm.generate lambda))
        !           157:            val time = check_timer timer
        !           158:        in  update(System.Stats.codegen,time);
        !           159:            timemsg ("codegen, " ^ makestring time ^ "s")
        !           160:                orelse debugmsg "codegen";
        !           161:            if !anyErrors then raise Stop else ();
        !           162:            executable
        !           163:        end
        !           164: 
        !           165:     fun exec executable =
        !           166:        let val timer = start_timer()
        !           167:            val result = executable lookup
        !           168:            val time = check_timer timer
        !           169:        in  update(System.Stats.execution,time);
        !           170:            timemsg ("execution, " ^ makestring time ^ "s")
        !           171:                orelse debugmsg "execution";
        !           172:            result
        !           173:        end
        !           174: 
        !           175: 
        !           176:     (* toplevel loop *)
        !           177:     (* initialize static environment *)
        !           178:     val (vCore,vInitial,vMath) = bootEnv load
        !           179:     val pervasiveEnv = Env.closeCurrentNewEnv()
        !           180:     val _ =  Env.resetEnv pervasiveEnv
        !           181:     val _ =  Env.commit()
        !           182: 
        !           183:    (* Build an environment (record) of the interactive compilation functions
        !           184:       to pass to the Importer, so that it can compile and run things. *)
        !           185: 
        !           186:     val toplevelFns =
        !           187:        Importer.TOPLEVEL_FNS{bind=bind, lookup=lookup,
        !           188:                             parse=parse, getvars=getvars, opt=opt
        !           189:                            }
        !           190: 
        !           191:     fun toploop(lex : Lex.lexer) =
        !           192:        let val _ = #prompt lex := !System.Control.primaryPrompt
        !           193:            val absyn = parse lex
        !           194:          in (case absyn
        !           195:                of IMPORTdec fnames =>
        !           196:                     let fun doit f = Importer.getAndExecModule(
        !           197:                                         f, pervasiveEnv, toplevelFns
        !           198:                                      )
        !           199:                     in app doit fnames
        !           200:                        handle Importer.Import verdict =>
        !           201:                           (print("IMPORT failed (" ^ verdict ^ ")\n"); raise Stop)
        !           202:                     end
        !           203:                 | _ => (* normal program *)
        !           204:                   let val (newlvars,lambda) = translate absyn
        !           205:                       val oldlvars =
        !           206:                             EnvAccess.staleLvars(Env.current(),Env.previous())
        !           207:                       val lambda = opt(Opt.closetop(lambda, ProcessFile.getCore()))
        !           208:                       val executable =
        !           209:                            if !System.Control.interp then Interp.interp lambda
        !           210:                                else codegen lambda
        !           211:                       val (result',profile) = exec executable
        !           212:                       val result = 
        !           213:                         (System.Control.ProfileInternals.add profile;
        !           214:                          System.Control.ProfileInternals.setOther ();
        !           215:                          System.Unsafe.isolate result' before
        !           216:                          System.Control.ProfileInternals.setToplevel ())
        !           217:                       fun bindlvars (i,v::r) = (bind(v,result sub i);
        !           218:                                                 bindlvars (i+1,r))
        !           219:                         | bindlvars (_,nil) = ()
        !           220:                   in  bindlvars(0,newlvars);   (* add new runtime bindings *)
        !           221:                       app unbind oldlvars;     (* remove stale runtime bindings *)
        !           222:                       spoolLambda lambda;           (* save lambda code *)
        !           223:                       PrintDec.printDec lookup absyn;  (* print result *)
        !           224:                       Env.consolidate();            (* consolidate static environment *)
        !           225:                       Env.commit()                  (* accept static bindings *)
        !           226:                   end);
        !           227:             toploop lex
        !           228:         end
        !           229: 
        !           230:     fun use_source(fname,stream) =
        !           231:        let   val _ = print("[opening " ^ fname ^ "]\n")
        !           232:               val interactive = is_term_in stream
        !           233:              val lex = Lex.mkLex{stream=stream, interactive=interactive}
        !           234:               val oldinteractive = !System.interactive
        !           235:              val oldfile = !ErrorMsg.fileName
        !           236:               val oldlinenum = !ErrorMsg.lineNum
        !           237:          in  ErrorMsg.fileName := fname; ErrorMsg.lineNum := 1;
        !           238:              System.interactive := interactive;
        !           239:               toploop lex
        !           240:              handle exn =>
        !           241:                (print("[closing " ^ fname ^ "]\n");
        !           242:                 close_in stream handle Io _ => ();
        !           243:                 ErrorMsg.fileName := oldfile;
        !           244:                 ErrorMsg.lineNum := oldlinenum;
        !           245:                 System.interactive := oldinteractive;
        !           246:                 case exn
        !           247:                   of Parse.Eof => ()
        !           248:                    | Stop => (Env.restore(); Env.openScope(); raise Syntax)
        !           249:                    | _ => (Env.restore(); Env.openScope(); raise exn))
        !           250:          end
        !           251: 
        !           252:     fun use_file fname =
        !           253:          use_source(fname,(open_in fname handle e as Io _ =>
        !           254:                           (print("[cannot open " ^ fname ^ "]\n"); raise e)))
        !           255: 
        !           256:     fun use_stream s = use_source("<instream>",s)
        !           257: 
        !           258:     (* outer interactive loop, with error handling *)
        !           259:     fun interact() =
        !           260:       let val lex = Lex.mkLex{stream=std_in, interactive=true}
        !           261:           fun restart() = (Env.restore(); Env.openScope();
        !           262:                           input std_in (can_input std_in);
        !           263:                           interact())
        !           264:        in ErrorMsg.fileName := "std_in"; ErrorMsg.lineNum := 1;
        !           265:           toploop lex
        !           266:          handle Parse.Eof => ()
        !           267:             | f => if !System.interactive
        !           268:                    then case f
        !           269:                           of  Stop => restart()
        !           270:                            | Syntax => restart()
        !           271:                            | Io s => (print("uncaught exception Io \""
        !           272:                                        ^ s ^ "\"\n");
        !           273:                                    restart())
        !           274:                            | _ => (print("uncaught exception "
        !           275:                                        ^ System.exn_name f ^ "\n");
        !           276:                                    restart())
        !           277:                    else (print("uncaught exception "
        !           278:                                ^ System.exn_name f ^ "\n");())
        !           279:       end
        !           280: 
        !           281:     (* bind runtime boot structures:  Core, Math, and Initial *)
        !           282:     val {core,math,initial} = !System.Unsafe.pstruct
        !           283:     val _ = (bind(vCore,core); bind(vInitial,initial); bind(vMath,math))
        !           284: 
        !           285:     val _ =
        !           286:       (IO.use_f := use_file;
        !           287:        IO.use_s := use_stream;
        !           288:        System.Control.ProfileInternals.setToplevel ();
        !           289:        print "Go for it\n";
        !           290:        interact())
        !           291: 
        !           292: end (* functor Interact *)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.