|
|
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 *)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.