2 /* --------------------------------------------------------------------------
3 * Unparse expressions and types - for use in error messages, type checker
6 * Hugs 98 is Copyright (c) Mark P Jones, Alastair Reid and the Yale
7 * Haskell Group 1994-99, and is distributed as Open Source software
8 * under the Artistic License; see the file "Artistic" that is included
9 * in the distribution for details.
11 * $RCSfile: output.c,v $
13 * $Date: 1999/02/03 17:08:33 $
14 * ------------------------------------------------------------------------*/
22 /*#define DEBUG_SHOWSC*/ /* Must also be set in compiler.c */
24 #define DEPTH_LIMIT 15
26 /* --------------------------------------------------------------------------
27 * Local function prototypes:
28 * ------------------------------------------------------------------------*/
30 static Void local putChr Args((Int));
31 static Void local putStr Args((String));
32 static Void local putInt Args((Int));
34 static Void local put Args((Int,Cell));
35 static Void local putFlds Args((Cell,List));
36 static Void local putComp Args((Cell,List));
37 static Void local putQual Args((Cell));
38 static Bool local isDictVal Args((Cell));
39 static Cell local maySkipDict Args((Cell));
40 static Void local putAp Args((Int,Cell));
41 static Void local putOverInfix Args((Int,Text,Syntax,Cell));
42 static Void local putInfix Args((Int,Text,Syntax,Cell,Cell));
43 static Void local putSimpleAp Args((Cell,Int));
44 static Void local putTuple Args((Int,Cell));
45 static Int local unusedTups Args((Int,Cell));
46 static Void local unlexVar Args((Text));
47 static Void local unlexOp Args((Text));
48 static Void local unlexCharConst Args((Cell));
49 static Void local unlexStrConst Args((Text));
51 static Void local putSigType Args((Cell));
52 static Void local putContext Args((List,List,Int));
53 static Void local putPred Args((Cell,Int));
54 static Void local putType Args((Cell,Int,Int));
55 static Void local putTyVar Args((Int));
56 static Bool local putTupleType Args((Cell,Int));
57 static Void local putApType Args((Type,Int,Int));
59 static Void local putKind Args((Kind));
60 static Void local putKinds Args((Kinds));
62 /* --------------------------------------------------------------------------
63 * Basic output routines:
64 * ------------------------------------------------------------------------*/
66 static FILE *outputStream; /* current output stream */
68 static Int outColumn = 0; /* current output column number */
71 #define OPEN(b) if (b) putChr('(');
72 #define CLOSE(b) if (b) putChr(')');
74 static Void local putChr(c) /* print single character */
82 static Void local putStr(s) /* print string */
85 Putc(*s,outputStream);
92 static Void local putInt(n) /* print integer */
94 static char intBuf[16];
95 sprintf(intBuf,"%d",n);
99 /* --------------------------------------------------------------------------
100 * Precedence values (See Haskell 1.3 report, p.12):
101 * ------------------------------------------------------------------------*/
103 #define ALWAYS FUN_PREC /* Always use parens (unless atomic)*/
104 /* User defined operators have prec */
105 /* in the range MIN_PREC..MAX_PREC */
106 #define ARROW_PREC MAX_PREC /* for printing -> in type exprs */
107 #define COCO_PREC (MIN_PREC-1) /* :: is left assoc, low precedence */
108 #define COND_PREC (MIN_PREC-2) /* conditional expressions */
109 #define WHERE_PREC (MIN_PREC-3) /* where expressions */
110 #define LAM_PREC (MIN_PREC-4) /* lambda abstraction */
111 #define NEVER LAM_PREC /* Never use parentheses */
114 /* --------------------------------------------------------------------------
115 * Print an expression (used to display context of type errors):
116 * ------------------------------------------------------------------------*/
118 static Int putDepth = 0; /* limits depth of printing DBG */
120 static Void local put(d,e) /* print expression e in context of */
121 Int d; /* operator of precedence d */
125 if (putDepth>DEPTH_LIMIT) {
133 case FINLIST : putChr('[');
137 while (nonNull(xs=tl(xs))) {
145 case AP : putAp(d,e);
148 case NAME : unlexVar(name(e).text);
155 case CONOPCELL : unlexVar(textOf(e));
159 case RECSEL : putChr('#');
160 unlexVar(extText(snd(e)));
164 case FREECELL : putStr("{free!}");
167 case TUPLE : putTuple(tupleOf(e),e);
170 case WILDCARD : putChr('_');
173 case ASPAT : put(NEVER,fst(snd(e)));
175 put(ALWAYS,snd(snd(e)));
178 case LAZYPAT : putChr('~');
182 case DOCOMP : putStr("do {...}");
185 case COMP : putComp(fst(snd(e)),snd(snd(e)));
188 case MONADCOMP : putComp(fst(snd(snd(e))),snd(snd(snd(e))));
191 case CHARCELL : unlexCharConst(charOf(e));
194 case INTCELL : { Int i = intOf(e);
195 if (i<0 && d>=UMINUS_PREC) putChr('(');
197 if (i<0 && d>=UMINUS_PREC) putChr(')');
204 case POSNUM : xs = bigOut(e,NIL,d>=UMINUS_PREC);
205 for (; nonNull(xs); xs=tl(xs))
206 putChr(charOf(arg(hd(xs))));
210 case FLOATCELL : { Float f = floatOf(e);
211 if (f<0 && d>=UMINUS_PREC) putChr('(');
212 putStr(floatToString(f));
213 if (f<0 && d>=UMINUS_PREC) putChr(')');
217 case STRCELL : unlexStrConst(textOf(e));
220 case LETREC : OPEN(d>WHERE_PREC);
223 put(NEVER,fst(snd(e)));
226 putStr("let {...} in ");
228 put(WHERE_PREC+1,snd(snd(e)));
232 case COND : OPEN(d>COND_PREC);
234 put(COND_PREC+1,fst3(snd(e)));
236 put(COND_PREC+1,snd3(snd(e)));
238 put(COND_PREC+1,thd3(snd(e)));
242 case LAMBDA : xs = fst(snd(e));
243 if (whatIs(xs)==BIGLAM)
245 while (nonNull(xs) && isDictVal(hd(xs)))
248 put(d,snd(snd(snd(e))));
255 while (nonNull(xs=tl(xs))) {
261 put(LAM_PREC,snd(snd(snd(e))));
265 case ESIGN : OPEN(d>COCO_PREC);
266 put(COCO_PREC,fst(snd(e)));
268 putSigType(snd(snd(e)));
272 case BIGLAM : put(d,snd(snd(e)));
275 case CASE : putStr("case ");
276 put(NEVER,fst(snd(e)));
279 put(NEVER,snd(snd(e)));
286 case CONFLDS : putFlds(fst(snd(e)),snd(snd(e)));
289 case UPDFLDS : putFlds(fst3(snd(e)),thd3(snd(e)));
292 default : /*internal("put");*/
300 static Void local putFlds(exp,fs) /* Output exp using labelled fields*/
305 for (; nonNull(fs); fs=tl(fs)) {
312 Text t = isName(f) ? name(f).text :
313 isVar(f) ? textOf(f) : inventText();
314 Text s = isName(e) ? name(e).text :
315 isVar(e) ? textOf(e) : inventText();
318 if (haskell98 || s!=t) {
329 static Void local putComp(e,qs) /* print comprehension */
337 while (nonNull(qs=tl(qs))) {
345 static Void local putQual(q) /* print list comp qualifier */
348 case BOOLQUAL : put(NEVER,snd(q));
351 case QWHERE : putStr("let {...}");
354 case FROMQUAL : put(ALWAYS,fst(snd(q)));
356 put(NEVER,snd(snd(q)));
361 static Bool local isDictVal(e) /* Look for dictionary value */
366 case DICTVAR : return TRUE;
367 case NAME : return isDfun(h);
373 static Cell local maySkipDict(e) /* descend function application, */
374 Cell e; { /* ignoring dict aps */
375 while (isAp(e) && isDictVal(arg(e)))
380 static Void local putAp(d,e) /* print application (args>=1) */
388 for (h=e; isAp(h); h=fun(h)) /* find head of expression, looking*/
389 if (!isDictVal(arg(h))) /* for dictionary arguments */
392 if (args==0) { /* Special case when *all* args */
393 put(d,h); /* are dictionary values */
399 case ADDPAT : if (args==1)
400 putInfix(d,textPlus,syntaxOf(namePlus),
401 arg(e),mkInt(intValOf(fun(e))));
407 case TUPLE : OPEN(args>tupleOf(h) && d>=FUN_PREC);
408 putTuple(tupleOf(h),e);
409 CLOSE(args>tupleOf(h) && d>=FUN_PREC);
412 case NAME : if (args==1 &&
413 ((h==nameFromInt && isInt(arg(e))) ||
415 (h==nameFromInteger && isBignum(arg(e))) ||
417 (h==nameFromDouble && isFloat(arg(e))))) {
429 case CONOPCELL : sy = defaultSyntax(t = textOf(h));
433 case EXT : if (args==2) {
438 putStr(textToStr(extText(h)));
440 put(NEVER,extField(e));
443 for (h=e; isAp(h); h=fun(h))
444 if (!isDictVal(arg(h)))
446 } while (isExt(h) && args==2);
461 default : sy = APPLIC;
467 if (sy==APPLIC) { /* print simple application */
473 else if (args==1) { /* print section of the form (e+) */
475 put(FUN_PREC-1,arg(e));
480 else if (args==2) /* infix expr of the form e1 + e2 */
481 putInfix(d,t,sy,arg(maySkipDict(fun(e))),arg(e));
482 else { /* o/w (e1 + e2) e3 ... en (n>=3) */
484 putOverInfix(args,t,sy,e);
489 static Void local putOverInfix(args,t,sy,e)
490 Int args; /* infix applied to >= 3 arguments */
495 putOverInfix(args-1,t,sy,maySkipDict(fun(e)));
497 put(FUN_PREC,arg(e));
500 putInfix(ALWAYS,t,sy,arg(maySkipDict(fun(e))),arg(e));
503 static Void local putInfix(d,t,sy,e,f) /* print infix expression */
505 Text t; /* Infix operator symbol */
506 Syntax sy; /* with name t, syntax s */
507 Cell e, f; { /* Left and right operands */
508 Syntax a = assocOf(sy);
512 put((a==LEFT_ASS ? p : 1+p), e);
516 put((a==RIGHT_ASS ? p : 1+p), f);
520 static Void local putSimpleAp(e,n) /* print application e0 e1 ... en */
524 putSimpleAp(maySkipDict(fun(e)),n-1);
526 put(FUN_PREC,arg(e));
532 static Void local putTuple(ts,e) /* Print tuple expression, allowing*/
533 Int ts; /* for possibility of either too */
534 Cell e; { /* few or too many args to constr */
537 if ((i=unusedTups(ts,e))>0) {
544 static Int local unusedTups(ts,e) /* print first part of tuple expr */
545 Int ts; /* returning number of constructor */
546 Cell e; { /* args not yet printed ... */
548 if ((ts=unusedTups(ts,fun(e))-1)>=0) {
550 putChr(ts>0?',':')');
554 put(FUN_PREC,arg(e));
560 static Void local unlexVar(t) /* print text as a variable name */
561 Text t; { /* operator symbols must be enclosed*/
562 String s = textToStr(t); /* in parentheses... except [] ... */
564 if ((isascii(s[0]) && isalpha(s[0])) || s[0]=='_' || s[0]=='[' || s[0]=='(')
573 static Void local unlexOp(t) /* print text as operator name */
574 Text t; { /* alpha numeric symbols must be */
575 String s = textToStr(t); /* enclosed by backquotes */
577 if (isascii(s[0]) && isalpha(s[0])) {
586 static Void local unlexCharConst(c)
589 putStr(unlexChar(c,'\''));
593 static Void local unlexStrConst(t)
595 String s = textToStr(t);
596 static Char SO = 14; /* ASCII code for '\SO' */
597 Bool lastWasSO = FALSE;
598 Bool lastWasDigit = FALSE;
599 Bool lastWasEsc = FALSE;
603 String ch = unlexChar(*s,'\"');
606 if ((lastWasSO && *ch=='H') ||
607 (lastWasEsc && lastWasDigit && isascii(*ch) && isdigit(*ch)))
610 lastWasEsc = (*ch=='\\');
611 lastWasSO = (*s==SO);
612 for (; *ch; c = *ch++)
614 lastWasDigit = (isascii(c) && isdigit(c));
619 /* --------------------------------------------------------------------------
620 * Print type expression:
621 * ------------------------------------------------------------------------*/
623 static Void local putSigType(t) /* print (possibly) generic type */
627 Kinds ks = polySigOf(t);
628 for (; isAp(ks); ks=tl(ks))
633 putType(t,NEVER,fr); /* Finally, print rest of type ... */
636 static Void local putContext(ps,qs,fr) /* print context list */
640 Int len = length(ps) + length(qs);
645 for (; nonNull(ps); ps=tl(ps)) {
651 for (; nonNull(qs); qs=tl(qs)) {
662 static Void local putPred(pi,fr) /* Output predicate */
667 if (isExt(fun(pi))) {
668 putType(arg(pi),ALWAYS,fr);
670 putStr(textToStr(extText(fun(pi))));
676 putType(arg(pi),ALWAYS,fr);
678 else if (isClass(pi))
679 putStr(textToStr(cclass(pi).text));
681 putStr(textToStr(textOf(pi)));
683 putStr("<unknownPredicate>");
686 static Void local putType(t,prec,fr) /* print nongeneric type expression*/
691 case TYCON : putStr(textToStr(tycon(t).text));
694 case TUPLE : { Int n = tupleOf(t);
702 case POLYTYPE : { Kinds ks = polySigOf(t);
703 OPEN(prec>=ARROW_PREC);
705 for (; isAp(ks); ks=tl(ks)) {
711 putType(monotypeOf(t),NEVER,fr);
712 CLOSE(prec>=ARROW_PREC);
717 case QUAL : OPEN(prec>=ARROW_PREC);
718 if (whatIs(snd(snd(t)))==CDICTS) {
719 putContext(fst(snd(t)),fst(snd(snd(snd(t)))),fr);
721 putType(snd(snd(snd(snd(t)))),NEVER,fr);
723 putContext(fst(snd(t)),NIL,fr);
725 putType(snd(snd(t)),NEVER,fr);
727 CLOSE(prec>=ARROW_PREC);
731 case RANK2 : putType(snd(snd(t)),prec,fr);
734 case OFFSET : putTyVar(offsetOf(t));
738 case VAROPCELL : putChr('_');
742 case INTCELL : putChr('_');
746 case AP : { Cell typeHead = getHead(t);
747 Bool brackets = (argCount!=0 && prec>=ALWAYS);
750 if (typeHead==typeList) {
753 putType(arg(t),NEVER,fr);
758 else if (typeHead==typeArrow) {
760 OPEN(prec>=ARROW_PREC);
761 putType(arg(fun(t)),ARROW_PREC,fr);
763 putType(arg(t),NEVER,fr);
764 CLOSE(prec>=ARROW_PREC);
767 else if (argCount==1) {
769 putType(arg(t),ARROW_PREC,fr);
774 else if (isTuple(typeHead)) {
775 if (argCount==tupleOf(typeHead)) {
783 else if (isExt(typeHead)) {
789 putStr(textToStr(extText(typeHead)));
791 putType(extField(t),NEVER,fr);
793 typeHead = getHead(t);
794 } while (isExt(typeHead) && argCount==2);
809 putApType(t,args,fr);
814 default : putStr("(bad type)");
818 static Void local putTyVar(n) /* print type variable */
820 static String alphabet /* for the benefit of EBCDIC :-) */
821 ="abcdefghijklmnopqrstuvwxyz";
822 putChr(alphabet[n%26]);
823 if (n /= 26) /* just in case there are > 26 vars*/
827 static Bool local putTupleType(e,fr) /* print tuple of types, returning */
828 Cell e; /* TRUE if something was printed, */
829 Int fr; { /* FALSE otherwise; used to control*/
830 if (isAp(e)) { /* printing of intermed. commas */
831 if (putTupleType(fun(e),fr))
833 putType(arg(e),NEVER,fr);
839 static Void local putApType(t,n,fr) /* print type application */
844 putApType(fun(t),n-1,fr);
846 putType(arg(t),ALWAYS,fr);
849 putType(t,ALWAYS,fr);
852 /* --------------------------------------------------------------------------
853 * Print kind expression:
854 * ------------------------------------------------------------------------*/
856 static Void local putKind(k) /* print kind expression */
859 case AP : if (isAp(fst(k))) {
871 case ROW : putStr("row");
875 case STAR : putChr('*');
878 case OFFSET : putTyVar(offsetOf(k));
881 case INTCELL : putChr('_');
885 default : putStr("(bad kind)");
889 static Void local putKinds(ks) /* Print list of kinds */
893 else if (nonNull(tl(ks))) {
896 while (nonNull(ks=tl(ks))) {
906 /* --------------------------------------------------------------------------
908 * ------------------------------------------------------------------------*/
910 Void printExp(fp,e) /* print expr on specified stream */
918 Void printType(fp,t) /* print type on specified stream */
925 Void printContext(fp,qs) /* print context on spec. stream */
929 putContext(qs,NIL,0);
932 Void printPred(fp,pi) /* print predicate pi on stream */
939 Void printKind(fp,k) /* print kind k on stream */
946 Void printKinds(fp,ks) /* print list of kinds on stream */
953 /*-------------------------------------------------------------------------*/