Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /branches/vis15/src/compiler/cxx-util/print-as-cxx.sml
ViewVC logotype

Annotation of /branches/vis15/src/compiler/cxx-util/print-as-cxx.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3999 - (view) (download)

1 : jhr 3871 (* print-as-cxx.sml
2 :     *
3 :     * Print CLang syntax trees using C++ syntax.
4 :     *
5 :     * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
6 :     *
7 :     * COPYRIGHT (c) 2016 The University of Chicago
8 :     * All rights reserved.
9 :     *)
10 :    
11 :     structure PrintAsCxx : sig
12 :    
13 : jhr 3994 val rawTyName : RawTypes.t -> string
14 :    
15 : jhr 3905 val output : TextIOPP.stream * CLang.decl -> unit
16 : jhr 3871
17 :     end = struct
18 :    
19 :     structure CL = CLang
20 :     structure PP = TextIOPP
21 :    
22 :     val indent0 = (PP.Abs 0)
23 :     val indent = (PP.Abs 4) (* standard indentation amount *)
24 :    
25 : jhr 3994 fun rawTyName rty = (case rty
26 :     of RawTypes.RT_Int8 => "int8_t"
27 :     | RawTypes.RT_UInt8 => "uint8_t"
28 :     | RawTypes.RT_Int16 => "int16_t"
29 :     | RawTypes.RT_UInt16 => "uint16_t"
30 :     | RawTypes.RT_Int32 => "int32_t"
31 :     | RawTypes.RT_UInt32 => "uint32_t"
32 :     | RawTypes.RT_Int64 => "int64_t"
33 :     | RawTypes.RT_UInt64 => "uint64_t"
34 :     | RawTypes.RT_Float => "float"
35 :     | RawTypes.RT_Double => "double"
36 :     (* end case *))
37 :    
38 : jhr 3999 fun output (_, CL.D_Verbatim[]) = ()
39 :     | output (strm, decl) = let
40 : jhr 3871 val str = PP.string strm
41 :     fun sp () = PP.space strm 1
42 :     fun inHBox f = (PP.openHBox strm; f(); PP.closeBox strm)
43 :     fun ppCom s = inHBox (fn () => (str "// "; str s))
44 :     fun ppComLn s = (ppCom s; PP.newline strm)
45 :     fun ppList {pp, sep, l} = let
46 :     fun ppList' [] = ()
47 :     | ppList' [x] = pp x
48 :     | ppList' (x::xs) = (pp x; sep(); ppList' xs)
49 :     in
50 :     ppList' l
51 :     end
52 : jhr 3994 fun ppCommaList {pp, l} = ppList {pp = pp, sep = fn () => (str ","; sp()), l = l}
53 : jhr 3871 fun ppTy (ty, optVar) = let
54 : jhr 3994 fun getBaseTy (CL.T_Num rty) = rawTyName rty
55 :     | getBaseTy (CL.T_Const(CL.T_Num rty)) = "const " ^ rawTyName rty
56 : jhr 3955 | getBaseTy (CL.T_Const(CL.T_Named ty)) = "const " ^ ty
57 :     | getBaseTy (CL.T_Const ty) = getBaseTy ty
58 : jhr 3871 | getBaseTy (CL.T_Ptr ty) = getBaseTy ty
59 :     | getBaseTy (CL.T_RestrictPtr ty) = getBaseTy ty
60 :     | getBaseTy (CL.T_Array(ty, _)) = getBaseTy ty
61 :     | getBaseTy (CL.T_Named ty) = ty
62 :     (* FIXME: this isn't right *)
63 :     | getBaseTy (CL.T_Template(name, tys)) = concat[
64 :     name, "< ", String.concatWith ", " (List.map getBaseTy tys), " >"
65 :     ]
66 :     | getBaseTy (CL.T_Qual(attr, ty)) =
67 :     concat[attr, " ", getBaseTy ty]
68 : jhr 3955 fun ppVar (isFirst, SOME x) = (
69 : jhr 3871 if isFirst then sp() else ();
70 : jhr 3955 str x)
71 :     | ppVar _ = ()
72 :     fun pp (isFirst, CL.T_Const(CL.T_Num _), optVar) = ppVar (isFirst, optVar)
73 :     | pp (isFirst, CL.T_Const(CL.T_Named _), optVar) = ppVar (isFirst, optVar)
74 :     | pp (isFirst, CL.T_Const ty, optVar) = raise Fail "FIXME"
75 :     | pp (isFirst, CL.T_Ptr ty, optVar) = (
76 :     if isFirst then sp() else ();
77 : jhr 3871 case ty
78 :     of CL.T_Array _ => (
79 :     str "(*"; pp(false, ty, optVar); str ")")
80 :     | _ => (str "*"; pp(false, ty, optVar))
81 :     (* end case *))
82 :     | pp (isFirst, CL.T_RestrictPtr ty, optVar) = (
83 :     if isFirst then sp() else ();
84 :     case ty
85 :     of CL.T_Array _ => (
86 :     str "(*"; sp(); str "__restrict__"; sp(); pp(false, ty, optVar); str ")")
87 :     | _ => (str "*"; sp(); str "__restrict__"; sp(); pp(false, ty, optVar))
88 :     (* end case *))
89 :     | pp (isFirst, CL.T_Array(ty, optN), optVar) = (
90 :     pp (isFirst, ty, optVar);
91 :     case optN
92 :     of NONE => str "[]"
93 :     | SOME n => (str "["; str(Int.toString n); str "]")
94 :     (* end case *))
95 :     | pp (isFirst, CL.T_Qual(_, ty), optVar) =
96 :     pp (isFirst, ty, optVar)
97 : jhr 3955 | pp (isFirst, _, optVar) = ppVar (isFirst, optVar)
98 : jhr 3871 in
99 :     str (getBaseTy ty);
100 :     pp (true, ty, optVar)
101 :     end
102 :     fun ppAttrs [] = ()
103 :     | ppAttrs attrs = (
104 :     ppList {pp=str, sep=sp, l = attrs};
105 :     sp())
106 :     fun ppDecl (inClass, dcl) = (case dcl
107 :     of CL.D_Pragma l => (
108 : jhr 3999 if inClass then PP.newline strm else ();
109 : jhr 3871 inHBox (fn () => (
110 :     str "#pragma";
111 : jhr 3999 List.app (fn s => (sp(); str s)) l)))
112 : jhr 3871 | CL.D_Comment l => List.app ppComLn l
113 : jhr 3999 | CL.D_Verbatim [] => ()
114 :     | CL.D_Verbatim l => (if inClass then PP.newline strm else (); List.app str l)
115 : jhr 3871 | CL.D_Var(attrs, ty, x, optInit) => (
116 : jhr 3999 if inClass then PP.newline strm else ();
117 : jhr 3871 inHBox (fn () => (
118 :     ppAttrs attrs;
119 :     ppTy (ty, SOME x);
120 :     case optInit
121 :     of SOME init => (sp(); str "="; sp(); ppInit init)
122 :     | NONE => ()
123 :     (* end case *);
124 : jhr 3999 str ";")))
125 : jhr 3871 | CL.D_Proto(attrs, ty, f, params) => (
126 : jhr 3999 if inClass then PP.newline strm else ();
127 : jhr 3871 inHBox (fn () => (
128 :     ppAttrs attrs;
129 :     ppTy(ty, SOME f);
130 :     sp(); str "(";
131 : jhr 3994 ppCommaList {pp=ppParam, l=params};
132 : jhr 3999 str ");")))
133 : jhr 3871 | CL.D_Func(attrs, ty, f, params, body) => (
134 : jhr 3999 if inClass then PP.newline strm else ();
135 : jhr 3871 PP.openVBox strm indent0;
136 :     inHBox (fn () => (
137 :     ppAttrs attrs;
138 :     ppTy(ty, SOME f);
139 :     sp(); str "(";
140 : jhr 3994 ppCommaList {pp=ppParam, l=params};
141 : jhr 3871 str ")"));
142 : jhr 3999 if inClass then PP.newline strm else ();
143 : jhr 3994 ppBody body;
144 : jhr 3999 PP.closeBox strm)
145 : jhr 3871 | CL.D_Constr(attrs, namespace, cls, params, inits, body) => (
146 : jhr 3999 if inClass then PP.newline strm else ();
147 : jhr 3871 PP.openVBox strm indent0;
148 : jhr 3994 PP.openHBox strm;
149 : jhr 3871 ppAttrs attrs;
150 :     if inClass
151 :     then str cls
152 :     else (
153 :     Option.app (fn ns => (str ns; str "::")) namespace;
154 :     str cls; str "::"; str cls);
155 :     sp(); str "(";
156 : jhr 3994 ppCommaList {pp=ppParam, l=params};
157 :     if Option.isNone body then str ");" else str ")";
158 :     case body
159 :     of SOME(CL.S_Block[]) => (
160 :     if List.null inits
161 :     then (sp(); str "{ }"; PP.closeBox strm)
162 :     else (
163 :     PP.closeBox strm;
164 :     PP.newline strm;
165 :     (* FIXME: inits *)
166 :     str"{ }"))
167 :     | SOME body => (
168 :     PP.closeBox strm;
169 :     PP.newline strm;
170 :     (* FIXME inits *)
171 :     ppBody body)
172 :     | NONE => ()
173 :     (* end case *);
174 :     (* NOTE: HBox has been closed *)
175 : jhr 3999 PP.closeBox strm)
176 : jhr 3871 | CL.D_Destr(attrs, namespace, cls, body) => (
177 : jhr 3999 if inClass then PP.newline strm else ();
178 : jhr 3871 PP.openVBox strm indent0;
179 : jhr 3994 PP.openHBox strm;
180 : jhr 3871 ppAttrs attrs;
181 :     if inClass
182 :     then (str "~"; str cls)
183 :     else (
184 :     Option.app (fn ns => (str ns; str "::")) namespace;
185 : jhr 3999 str cls; str "::"; str "~"; str cls);
186 : jhr 3871 sp();
187 : jhr 3994 case body
188 :     of NONE => (str "();"; PP.closeBox strm)
189 :     | SOME(CL.S_Block[]) => (str "() { }"; PP.closeBox strm)
190 :     | SOME body => (
191 :     str "()"; PP.closeBox strm; PP.newline strm; ppBody body)
192 :     (* end case *);
193 :     (* NOTE: HBox has been closed *)
194 : jhr 3999 PP.closeBox strm)
195 : jhr 3871 | CL.D_StructDef(SOME name, fields, NONE) => (
196 : jhr 3999 if inClass then PP.newline strm else ();
197 : jhr 3871 PP.openVBox strm indent0;
198 :     inHBox (fn () => (str "struct"; sp(); str name; sp(); str "{"));
199 :     PP.openVBox strm indent;
200 :     List.app (fn (ty, x) => (
201 :     PP.newline strm;
202 :     inHBox (fn () => (ppTy(ty, SOME x); str ";"))))
203 :     fields;
204 :     PP.closeBox strm;
205 :     PP.newline strm;
206 :     str "};";
207 : jhr 3999 PP.closeBox strm)
208 : jhr 3871 | CL.D_StructDef(optStruct, fields, SOME tyName) => (
209 : jhr 3999 if inClass then PP.newline strm else ();
210 : jhr 3871 PP.openVBox strm indent0;
211 :     str "typedef struct {";
212 :     PP.openVBox strm indent;
213 :     List.app (fn (ty, x) => (
214 :     PP.newline strm;
215 :     inHBox (fn () => (ppTy(ty, SOME x); str ";"))))
216 :     fields;
217 :     PP.closeBox strm;
218 :     PP.newline strm;
219 :     inHBox (fn () => (str "}"; sp(); str tyName; str ";"));
220 : jhr 3999 PP.closeBox strm)
221 : jhr 3871 | CL.D_StructDef(NONE, _, NONE) => raise Fail "unamed struct"
222 : jhr 3994 | CL.D_ClassDef{name, args, from, public, protected=[], private=[]} => (
223 : jhr 3999 if inClass then PP.newline strm else ();
224 : jhr 3871 PP.openVBox strm indent0;
225 :     inHBox (fn () => (
226 :     str "struct"; sp(); str name;
227 : jhr 3994 Option.map (fn tys => (str "<"; str ">")) args;
228 : jhr 3871 Option.map (fn base => (sp(); str ":"; sp(); str base)) from;
229 :     sp(); str "{"));
230 :     PP.openVBox strm indent;
231 :     List.app (fn dcl => ppDecl (true, dcl)) public;
232 :     PP.closeBox strm;
233 :     PP.newline strm;
234 :     str "};";
235 : jhr 3999 PP.closeBox strm)
236 : jhr 3994 | CL.D_ClassDef{name, args, from, public, protected, private} =>
237 : jhr 3871 raise Fail "FIXME: ClassDef"
238 : jhr 3989 | CL.D_Template(params, dcl) => let
239 :     fun ppParam (CL.TypeParam name) = (str "typename"; sp(); str name)
240 :     | ppParam (CL.ConstParam(ty, name)) = (
241 :     str "const"; sp(); ppTy (ty, NONE); sp(); str name)
242 :     in
243 : jhr 3999 if inClass then PP.newline strm else ();
244 : jhr 3989 PP.openVBox strm indent0;
245 :     inHBox (fn () => (
246 :     str "template"; sp(); str "<";
247 : jhr 3994 ppCommaList {pp = ppParam, l = params};
248 : jhr 3989 str ">"));
249 :     ppDecl (inClass, dcl);
250 :     PP.closeBox strm
251 :     end
252 : jhr 3994 | CL.D_Typedef(name, ty) => (
253 : jhr 3999 if inClass then PP.newline strm else ();
254 : jhr 3994 inHBox (fn () => (
255 : jhr 3999 str "using"; sp(); str name; sp(); str"="; sp(); ppTy(ty, NONE); str ";")))
256 : jhr 3996 | CL.D_Namespace(name, dcls) => (
257 :     if inClass then raise Fail "unexpected namespace inside class decl" else ();
258 :     PP.openVBox strm indent0;
259 :     inHBox (fn () => (str "namespace"; sp(); str name; sp(); str "{"));
260 :     PP.openVBox strm indent;
261 : jhr 3999 List.app
262 :     (fn CL.D_Verbatim[] => ()
263 :     | dcl => (PP.newline strm; ppDecl(false, dcl))
264 :     ) dcls;
265 : jhr 3996 PP.closeBox strm;
266 :     PP.newline strm;
267 :     inHBox (fn () => (str "}"; sp(); str("// namespace " ^ name)));
268 : jhr 3999 PP.closeBox strm)
269 : jhr 3871 (* end case *))
270 : jhr 3994 and ppBody (CL.S_Block stms) = ppBlock stms
271 :     | ppBody stm = ppBlock [stm]
272 : jhr 3871 and ppParam (CL.PARAM(attrs, ty, x)) = (
273 :     ppAttrs attrs;
274 :     ppTy(ty, SOME(CL.varToString x)))
275 :     and ppInit init = (case init
276 :     of CL.I_Exp e => ppExp e
277 :     | CL.I_Exps fields => (
278 :     str "{";
279 :     PP.openHVBox strm indent;
280 :     List.app (fn init => (
281 :     PP.break strm;
282 :     inHBox (fn () => (ppInit init; str ","))))
283 :     fields;
284 :     PP.closeBox strm;
285 :     str "}")
286 :     | CL.I_Struct fields => (
287 :     str "{";
288 :     PP.openHVBox strm indent;
289 :     List.app (fn (lab, init) => (
290 :     PP.break strm;
291 :     inHBox (fn () => (
292 :     str("." ^ lab); sp(); str "="; sp(); ppInit init; str ","))))
293 :     fields;
294 :     PP.closeBox strm;
295 :     str "}")
296 :     | CL.I_Array elems => (
297 :     str "{";
298 :     PP.openHVBox strm indent;
299 :     List.app (fn (i, init) => (
300 :     PP.break strm;
301 :     inHBox (fn () => (
302 :     str(concat["[", Int.toString i, "]"]); sp(); str "="; sp();
303 :     ppInit init; str ","))))
304 :     elems;
305 :     PP.closeBox strm;
306 :     str "}")
307 :     | CL.I_Cons(ty, args) => (
308 :     PP.openHVBox strm indent;
309 :     ppTy(ty, NONE); ppArgs args; str ";";
310 :     PP.closeBox strm)
311 :     (* end case *))
312 :     and ppBlock stms = (
313 :     str "{";
314 :     PP.openVBox strm indent;
315 :     List.app (fn stm => (PP.newline strm; ppStm stm)) stms;
316 :     PP.closeBox strm;
317 :     PP.newline strm;
318 :     str "}")
319 :     and ppStm stm = (case stm
320 :     of CL.S_Block stms => ppBlock stms
321 :     | CL.S_Comment l => List.app ppCom l
322 :     | CL.S_Verbatim [] => ()
323 :     | CL.S_Verbatim (stm::stms) => (
324 :     str stm;
325 :     List.app (fn stm => (PP.newline strm; str stm)) stms)
326 :     | CL.S_Decl(attrs, ty, x, NONE) => inHBox (fn () => (
327 :     ppAttrs attrs;
328 :     ppTy(ty, SOME x); str ";"))
329 :     | CL.S_Decl(attrs, ty, x, SOME e) => inHBox (fn () => (
330 :     ppAttrs attrs;
331 :     ppTy(ty, SOME x); sp(); str "="; sp(); ppInit e; str ";"))
332 :     | CL.S_Exp e => inHBox (fn () => (ppExp e; str ";"))
333 :     | CL.S_If(e, blk, CL.S_Block[]) =>
334 :     inHBox (fn () => (str "if"; sp(); ppExp e; ppStmAsBlock blk))
335 :     | CL.S_If(e, blk1, stm as CL.S_If _) => (
336 :     PP.openVBox strm indent0;
337 :     inHBox (fn () => (str "if"; sp(); ppExp e; ppStmAsBlock blk1));
338 :     PP.newline strm;
339 :     PP.closeBox strm;
340 :     inHBox (fn () => (str "else"; sp(); ppStm stm)))
341 :     | CL.S_If(e, blk1, blk2) => (
342 :     PP.openVBox strm indent0;
343 :     inHBox (fn () => (str "if"; sp(); ppExp e; ppStmAsBlock blk1));
344 :     PP.newline strm;
345 :     inHBox (fn () => (str "else"; ppStmAsBlock blk2));
346 :     PP.closeBox strm)
347 :     | CL.S_While(e, blk) =>
348 :     inHBox (fn () => (str "while"; sp(); ppExp e; ppStmAsBlock blk))
349 :     | CL.S_DoWhile(blk, e) =>
350 :     inHBox (fn () => (
351 :     str "do"; ppStmAsBlock blk; sp(); str "while"; sp(); ppExp e))
352 : jhr 3996 | CL.S_For(ty, dcls, cond, incrs, blk) => inHBox (fn () => (
353 :     str "for"; sp(); str "(";
354 :     case dcls
355 :     of (x, e)::rest => (
356 :     ppTy(ty, SOME x); sp(); str "="; sp(); ppExp e;
357 :     List.app
358 :     (fn (x, e) => (str ","; sp(); str x; sp(); str "="; sp(); ppExp e))
359 :     rest)
360 :     | [] => ()
361 :     (* end case *);
362 :     str ";"; sp();
363 :     ppExp cond; str ";"; sp();
364 :     ppList {pp = ppExp, sep = fn () => str ",", l = incrs};
365 :     str ")";
366 :     ppStmAsBlock blk))
367 : jhr 3871 | CL.S_Return(SOME e) => inHBox (fn () => (str "return"; sp(); ppExp e; str ";"))
368 :     | CL.S_Return _ => str "return;"
369 :     | CL.S_Break => str "break;"
370 :     | CL.S_Continue => str "continue;"
371 : jhr 3897 | CL.S_KernCall _ => raise Fail "unexpected KernCall in C++ code"
372 : jhr 3871 (* end case *))
373 :     (* force printing "{" "}" around a statement *)
374 :     and ppStmAsBlock (CL.S_Block stms) = (sp(); ppBlock stms)
375 :     | ppStmAsBlock stm = (sp(); ppBlock [stm])
376 :     and ppExp e = (case e
377 :     of CL.E_Grp e => (str "("; ppExp e; str ")")
378 :     | CL.E_AssignOp(lhs, rator, rhs) => (
379 :     ppExp lhs; sp(); str(CL.assignopToString rator); sp(); ppExp rhs)
380 :     | CL.E_Cond(e1, e2, e3) => (
381 :     ppExp e1; sp(); str "?"; sp(); ppExp e2; sp(); str ":"; sp(); ppExp e3)
382 :     | CL.E_BinOp(e1, rator, e2) => (ppExp e1; str(CL.binopToString rator); ppExp e2)
383 :     | CL.E_UnOp(rator, e) => (str(CL.unopToString rator); ppExp e)
384 :     | CL.E_PostOp(e, rator) => (ppExp e; str(CL.postopToString rator))
385 :     | CL.E_Apply(e, args) => (ppExp e; ppArgs args)
386 : jhr 3897 | CL.E_TApply(f, tys, args) => (
387 :     str f; str "<";
388 : jhr 3994 ppCommaList {
389 : jhr 3897 pp = fn ty => (PP.openHBox strm; ppTy(ty, NONE); PP.closeBox strm),
390 :     l = tys
391 :     };
392 :     str ">"; ppArgs args)
393 : jhr 3871 | CL.E_Cons(ty, args) => (ppTy(ty, NONE); ppArgs args)
394 :     | CL.E_New(ty, args) => (
395 :     str "new"; sp(); ppTy(ty, NONE);
396 :     case (ty, args)
397 :     of (CL.T_Named ty, []) => str ty
398 :     | (CL.T_Template _, []) => ppTy(ty, NONE)
399 :     | (CL.T_Named ty, args) => (str ty; ppArgs args)
400 :     | (CL.T_Template _, args) => (ppTy(ty, NONE); ppArgs args)
401 :     | (ty, []) => ppTy(ty, NONE)
402 :     | _ => raise Fail "bogus new"
403 :     (* end case *))
404 :     | CL.E_Subscript(e1, e2) => (ppExp e1; str "["; ppExp e2; str "]")
405 :     | CL.E_Select(e, f) => (ppExp e; str "."; str f)
406 :     | CL.E_Indirect(e, f) => (ppExp e; str "->"; str f)
407 : jhr 3893 | CL.E_Cast(ty, e) => (str "("; ppTy(ty, NONE); str ")"; ppExp e)
408 : jhr 3924 | CL.E_XCast(c, ty, e) => (
409 :     str c; str "<"; ppTy(ty, NONE); str ">("; ppExp e; str ")")
410 : jhr 3871 | CL.E_Vec(ty, args) => (
411 :     (* GCC vector syntax: "__extension__ (ty){a, b, ...}" *)
412 :     str "__extension__"; sp(); str "("; ppTy(ty, NONE); str ")";
413 :     str "{";
414 :     PP.openHOVBox strm indent;
415 :     PP.cut strm;
416 : jhr 3994 ppCommaList {
417 : jhr 3871 pp = fn e => (PP.openHBox strm; ppExp e; PP.closeBox strm),
418 :     l = args
419 :     };
420 :     str "}";
421 :     PP.closeBox strm)
422 :     | CL.E_Var x => str(CL.varToString x)
423 :     | CL.E_Int(n, CL.T_Num(RawTypes.RT_Int64)) =>
424 :     str(IntLit.toString n ^ "l")
425 :     | CL.E_Int(n, _) => str(IntLit.toString n)
426 :     | CL.E_Flt(f, ty) => let
427 :     val isDouble = (case ty
428 :     of CL.T_Num(RawTypes.RT_Float) => false
429 :     | _ => true
430 :     (* end case *))
431 :     (* NOTE: the CLang.mkFlt function guarantees that f is non-negative *)
432 :     val f = if RealLit.same(RealLit.posInf, f)
433 :     then if isDouble
434 :     then "HUGE_VAL"
435 :     else "HUGE_VALF"
436 :     else if RealLit.same(RealLit.nan, f)
437 :     then if isDouble
438 :     then "std::nan(\"\")"
439 :     else "std::nanf(\"\")"
440 :     else if isDouble
441 :     then RealLit.toString f
442 :     else RealLit.toString f ^ "f"
443 :     in
444 :     str f
445 :     end
446 :     | CL.E_Bool b => str(Bool.toString b)
447 :     | CL.E_Str s => str(concat["\"", String.toCString s, "\""])
448 :     | CL.E_Char c => str(concat["'", Char.toCString c, "'"])
449 :     | CL.E_Sizeof ty => (str "sizeof("; ppTy(ty, NONE); str ")")
450 :     (* end case *))
451 :     and ppArgs args = (
452 :     str "(";
453 :     PP.openHOVBox strm indent;
454 :     PP.cut strm;
455 : jhr 3994 ppCommaList {
456 : jhr 3871 pp = fn e => (PP.openHBox strm; ppExp e; PP.closeBox strm),
457 :     l = args
458 :     };
459 :     str ")";
460 :     PP.closeBox strm)
461 :     in
462 : jhr 3999 PP.openVBox strm indent0;
463 :     ppDecl (false, decl);
464 :     PP.newline strm;
465 :     PP.closeBox strm
466 : jhr 3871 end
467 :    
468 :     end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0