99900bf4a1a1415267a9b64c5fc0e06ab29c7cde
[ghc-hetmet.git] / ghc / interpreter / parser.y
1
2 /* --------------------------------------------------------------------------
3  * Hugs parser (included as part of input.c)
4  *
5  * Expect 6 shift/reduce conflicts when passing this grammar through yacc,
6  * but don't worry; they should all be resolved in an appropriate manner.
7  *
8  * The Hugs 98 system is Copyright (c) Mark P Jones, Alastair Reid, the
9  * Yale Haskell Group, and the Oregon Graduate Institute of Science and
10  * Technology, 1994-1999, All rights reserved.  It is distributed as
11  * free software under the license in the file "License", which is
12  * included in the distribution.
13  *
14  * $RCSfile: parser.y,v $
15  * $Revision: 1.27 $
16  * $Date: 2000/04/04 17:35:04 $
17  * ------------------------------------------------------------------------*/
18
19 %{
20 #ifndef lint
21 #define lint
22 #endif
23 #define sigdecl(l,vs,t)          ap(SIGDECL,triple(l,vs,t))
24 #define fixdecl(l,ops,a,p)       ap(FIXDECL,\
25                                     triple(l,ops,mkInt(mkSyntax(a,intOf(p)))))
26 #define grded(gs)                ap(GUARDED,gs)
27 #define only(t)                  ap(ONLY,t)
28 #define letrec(bs,e)             (nonNull(bs) ? ap(LETREC,pair(bs,e)) : e)
29 #define qualify(ps,t)            (nonNull(ps) ? ap(QUAL,pair(ps,t)) : t)
30 #define yyerror(s)               /* errors handled elsewhere */
31 #define YYSTYPE                  Cell
32
33 static Cell   local gcShadow     ( Int,Cell );
34 static Void   local syntaxError  ( String );
35 static String local unexpected   ( Void );
36 static Cell   local checkPrec    ( Cell );
37 static Void   local fixDefn      ( Syntax,Cell,Cell,List );
38 static Cell   local buildTuple   ( List );
39 static List   local checkCtxt    ( List );
40 static Cell   local checkPred    ( Cell );
41 static Pair   local checkDo      ( List );
42 static Cell   local checkTyLhs   ( Cell );
43 #if !TREX
44 static Void   local noTREX       ( String );
45 #endif
46 #if !IPARAM
47 static Void   local noIP         ( String );
48 #endif
49
50 /* For the purposes of reasonably portable garbage collection, it is
51  * necessary to simulate the YACC stack on the Hugs stack to keep
52  * track of all intermediate constructs.  The lexical analyser
53  * pushes a token onto the stack for each token that is found, with
54  * these elements being removed as reduce actions are performed,
55  * taking account of look-ahead tokens as described by gcShadow()
56  * below.
57  *
58  * Of the non-terminals used below, only start, topDecl & begin
59  * do not leave any values on the Hugs stack.  The same is true for the
60  * terminals EXPR and SCRIPT.  At the end of a successful parse, there
61  * should only be one element left on the stack, containing the result
62  * of the parse.
63  */
64
65 #define gc0(e)                  gcShadow(0,e)
66 #define gc1(e)                  gcShadow(1,e)
67 #define gc2(e)                  gcShadow(2,e)
68 #define gc3(e)                  gcShadow(3,e)
69 #define gc4(e)                  gcShadow(4,e)
70 #define gc5(e)                  gcShadow(5,e)
71 #define gc6(e)                  gcShadow(6,e)
72 #define gc7(e)                  gcShadow(7,e)
73 #define gc8(e)                  gcShadow(8,e)
74 #define gc9(e)                  gcShadow(9,e)
75
76 %}
77
78 %token EXPR       CONTEXT    SCRIPT
79 %token CASEXP     OF         DATA       TYPE       IF
80 %token THEN       ELSE       WHERE      LET        IN
81 %token INFIXN     INFIXL     INFIXR     FOREIGN    TNEWTYPE
82 %token DEFAULT    DERIVING   DO         TCLASS     TINSTANCE
83 /*#if IPARAM*/
84 %token WITH DLET
85 /*#endif*/
86 %token REPEAT     ALL        NUMLIT     CHARLIT    STRINGLIT
87 %token VAROP      VARID      CONOP      CONID
88 %token QVAROP     QVARID     QCONOP     QCONID
89 /*#if TREX*/
90 %token RECSELID   IPVARID
91 /*#endif*/
92 %token COCO       '='        UPTO       '@'        '\\'
93 %token '|'        '-'        FROM       ARROW      '~'
94 %token '!'        IMPLIES    '('        ','        ')'
95 %token '['        ';'        ']'        '`'        '.'
96 %token TMODULE    IMPORT     HIDING     QUALIFIED  ASMOD
97 %token EXPORT     UUEXPORT   INTERFACE  REQUIRES   UNSAFE     
98 %token INSTIMPORT DYNAMIC    CCALL      STDKALL
99 %token UTL        UTR        UUUSAGE
100 %token PRIVILEGED
101
102 %%
103 /*- Top level script/module structure -------------------------------------*/
104
105 start     : EXPR exp wherePart      {inputExpr    = letrec($3,$2); sp-=2;}
106           | CONTEXT context         {inputContext = $2;            sp-=1;}
107           | SCRIPT topModule        {drop(); push($2);}
108           | INTERFACE iface         {sp-=1;}
109           | error                   {syntaxError("input");}
110           ;
111
112
113 /*- GHC interface file parsing: -------------------------------------------*/
114
115 /* Reading in an interface file is surprisingly like reading
116  * a normal Haskell module: we read in a bunch of declarations,
117  * construct symbol table entries, etc.  The "only" differences
118  * are that there's no syntactic sugar to deal with and we don't
119  * have to read in expressions.
120  */
121
122 /*- Top-level interface files -----------------------------*/
123 iface     : INTERFACE ifCon NUMLIT ifOrphans ifCheckVersion WHERE ifTopDecls 
124                                         {$$ = gc7(ap(I_INTERFACE, 
125                                                      zpair($2,$7))); }
126           | INTERFACE error             {syntaxError("interface file");}
127           ;
128
129 ifTopDecls:                             {$$=gc0(NIL);}
130           | ifTopDecl ';' ifTopDecls    {$$=gc3(cons($1,$3));}
131           ;
132
133 ifTopDecl    
134           : IMPORT CONID NUMLIT ifOrphans ifIsBoot ifOptCOCO ifVersionList
135                                         {$$=gc7(ap(I_IMPORT,zpair($2,$7))); }
136
137           | INSTIMPORT CONID            {$$=gc2(ap(I_INSTIMPORT,NIL));}
138
139           | UUEXPORT CONID ifEntities   {$$=gc3(ap(I_EXPORT,zpair($2,$3)));}
140
141           | NUMLIT INFIXL optDigit ifVarCon
142                                         {$$=gc4(ap(I_FIXDECL,
143                                             ztriple($3,mkInt(LEFT_ASS),$4)));}
144           | NUMLIT INFIXR optDigit ifVarCon
145                                         {$$=gc4(ap(I_FIXDECL,
146                                             ztriple($3,mkInt(RIGHT_ASS),$4)));}
147           | NUMLIT INFIXN optDigit ifVarCon
148                                         {$$=gc4(ap(I_FIXDECL,
149                                             ztriple($3,mkInt(NON_ASS),$4)));}
150
151           | TINSTANCE ifCtxInst ifInstHdL '=' ifVar
152                                         {$$=gc5(ap(I_INSTANCE,
153                                                    z5ble($1,$2,$3,$5,NIL)));}
154
155           | NUMLIT TYPE ifCon ifKindedTyvarL '=' ifType
156                                         {$$=gc6(ap(I_TYPE,
157                                                    z4ble($2,$3,$4,$6)));}
158
159           | NUMLIT DATA ifCtxDecl ifConData ifKindedTyvarL ifConstrs
160                                         {$$=gc6(ap(I_DATA,
161                                                    z5ble($2,$3,$4,$5,$6)));}
162
163           | NUMLIT TNEWTYPE ifCtxDecl ifConData ifKindedTyvarL ifNewTypeConstr
164                                         {$$=gc6(ap(I_NEWTYPE,
165                                                    z5ble($2,$3,$4,$5,$6)));}
166
167           | NUMLIT TCLASS ifCtxDecl ifCon ifKindedTyvar ifCmeths
168                                         {$$=gc6(ap(I_CLASS,
169                                                    z5ble($2,$3,$4,
170                                                          singleton($5),$6)));}
171
172           | NUMLIT ifVar COCO ifType
173                                         {$$=gc4(ap(I_VALUE,
174                                                    ztriple($3,$2,$4)));}
175
176           | error                       { syntaxError(
177                                              "interface declaration"); }
178           ;
179
180
181 /*- Top-level misc interface stuff ------------------------*/
182 ifOrphans : '!'                         {$$=gc1(NIL);}
183           |                             {$$=gc0(NIL);}
184 ifIsBoot  : '@'                         {$$=gc1(NIL);}
185           |                             {$$=gc0(NIL);}
186           ;
187 ifOptCOCO : COCO                        {$$=gc1(NIL);}
188           |                             {$$=gc0(NIL);}
189           ;
190 ifCheckVersion
191           : NUMLIT                      {$$ = gc1(NIL); }
192           ;
193
194
195
196 /*- Interface variable and constructor ids ----------------*/
197 ifTyvar   : VARID                       {$$ = $1;}
198           ;
199 ifVar     : VARID                       {$$ = gc1($1);}
200           ;
201 ifCon     : CONID                       {$$ = gc1($1);}
202           ;
203
204 ifVarCon  : VARID                       {$$ = gc1($1);}
205           | CONID                       {$$ = gc1($1);}
206           ;
207
208 ifQCon    : CONID                       {$$ = gc1($1);}
209           | QCONID                      {$$ = gc1($1);}
210           ;
211 ifConData : ifCon                       {$$ = gc1($1);}
212           | '(' ')'                     {$$ = gc2(typeUnit);}
213           | '[' ']'                     {$$ = gc2(typeList);}
214           | '(' ARROW ')'               {$$ = gc3(typeArrow);}
215           ;
216 ifTCName  : CONID                       { $$ = gc1($1); }
217           | CONOP                       { $$ = gc1($1); }
218           | '(' ARROW ')'               { $$ = gc3(typeArrow); }
219           | '[' ']'                     { $$ = gc1(typeList);  }
220           ; 
221 ifQTCName : ifTCName                    { $$ = gc1($1); }
222           | QCONID                      { $$ = gc1($1); }
223           | QCONOP                      { $$ = gc1($1); }
224           ; 
225
226
227 /*- Interface contexts ------------------------------------*/
228 ifCtxInst /* __forall [a b] =>     :: [((VarId,Kind))] */
229           : ALL ifForall IMPLIES        {$$=gc3($2);}
230           |                             {$$=gc0(NIL);}
231           ;
232 ifInstHd /* { Class aType }    :: ((ConId, Type)) */
233           : '{' ifQCon ifAType '}'      {$$=gc4(ap(DICTAP,
234                                                 zpair($2,$3)));}
235           ;
236
237 ifInstHdL /* { C a1 } -> { C2 a2 } -> ... -> { Cn an } :: Type */
238           : ifInstHd ARROW ifInstHdL    {$$=gc3(ap($1,$3));}
239           | ifInstHd                    {$$=gc1($1);}
240           ;
241
242 ifCtxDecl /* {M.C1 a, C2 b} =>  :: [(QConId, VarId)] */ 
243           : ifCtxDeclT IMPLIES          { $$ = gc2($1);  }
244           |                             { $$ = gc0(NIL); }
245           ;                                     
246 ifCtxDeclT /* {M.C1 a, C2 b} :: [(QConId, VarId)] */ 
247           :                             { $$ = gc0(NIL); }
248           | '{' ifCtxDeclL '}'          { $$ = gc3($2);  }
249           ;                                     
250
251 ifCtxDeclL /* M.C1 a, C2 b :: [(QConId, VarId)] */
252           : ifCtxDeclLE ',' ifCtxDeclL  {$$=gc3(cons($1,$3));}
253           | ifCtxDeclLE                 {$$=gc1(cons($1,NIL));}
254           |                             {$$=gc0(NIL);}
255           ;
256 ifCtxDeclLE /* M.C1 a   :: (QConId,VarId) */
257           : ifQCon ifTyvar              {$$=gc2(zpair($1,$2));}
258           ;
259
260
261 /*- Interface data declarations - constructor lists -------*/
262 /* The (Type,VarId,Int) are (field type, name (or NIL), strictness).
263    Strictness is a number: mkInt(0) indicates lazy, mkInt(1)
264    indicates a strict field (!type) as in standard H98, and 
265    mkInt(2) indicates unpacked -- a GHC extension.
266 */
267
268 ifConstrs /* = Con1 | ... | ConN  :: [((ConId,[((Type,VarId,Int))]))] */
269           :                             {$$ = gc0(NIL);}
270           | '=' ifConstrL               {$$ = gc2($2);}
271           ;
272 ifConstrL /* [((ConId,[((Type,VarId,Int))]))] */
273           : ifConstr                    {$$ = gc1(singleton($1));}
274           | ifConstr '|' ifConstrL      {$$ = gc3(cons($1,$3));}
275           ;
276 ifConstr /* ((ConId,[((Type,VarId,Int))])) */
277           : ifConData ifDataAnonFieldL  {$$ = gc2(zpair($1,$2));}
278           | ifConData '{' ifDataNamedFieldL '}' 
279                                         {$$ = gc4(zpair($1,$3));}
280           ;
281 ifDataAnonFieldL /* [((Type,VarId,Int))] */
282           :                             {$$=gc0(NIL);}
283           | ifDataAnonField ifDataAnonFieldL
284                                         {$$=gc2(cons($1,$2));}
285           ;
286 ifDataNamedFieldL /* [((Type,VarId,Int))] */
287           :                             {$$=gc0(NIL);}
288           | ifDataNamedField            {$$=gc1(cons($1,NIL));}
289           | ifDataNamedField ',' ifDataNamedFieldL 
290                                         {$$=gc3(cons($1,$3));}
291           ;
292 ifDataAnonField /* ((Type,VarId,Int)) */
293           : ifAType                     {$$=gc1(ztriple($1,NIL,mkInt(0)));}
294           | '!' ifAType                 {$$=gc2(ztriple($2,NIL,mkInt(1)));}
295           | '!' '!' ifAType             {$$=gc3(ztriple($3,NIL,mkInt(2)));}
296           ;
297 ifDataNamedField  /* ((Type,VarId,Int)) */
298           : ifVar COCO ifAType          {$$=gc3(ztriple($3,$1,mkInt(0)));}
299           | ifVar COCO '!' ifAType      {$$=gc4(ztriple($4,$1,mkInt(1)));}
300           | ifVar COCO '!' '!' ifAType  {$$=gc5(ztriple($5,$1,mkInt(2)));}
301           ;
302
303
304 /*- Interface class declarations - methods ----------------*/
305 ifCmeths /* [((VarId,Type))] */
306           :                             { $$ = gc0(NIL); }
307           | WHERE '{' ifCmethL '}'      { $$ = gc4($3); }
308           ;
309 ifCmethL /* [((VarId,Type))] */
310           : ifCmeth                     { $$ = gc1(singleton($1)); }
311           | ifCmeth ';' ifCmethL        { $$ = gc3(cons($1,$3));    }
312           ;
313 ifCmeth /* ((VarId,Type)) */
314           : ifVar     COCO ifType       { $$ = gc3(zpair($1,$3)); }
315           | ifVar '=' COCO ifType       { $$ = gc4(zpair($1,$4)); } 
316                                               /* has default method */
317           ;
318
319
320 /*- Interface newtype declararions ------------------------*/
321 ifNewTypeConstr /* ((ConId,Type)) */
322           : '=' ifCon ifAType           { $$ = gc3(zpair($2,$3)); }
323           ;
324
325
326 /*- Interface type expressions ----------------------------*/
327 ifType    : ALL ifForall ifCtxDeclT IMPLIES ifType 
328                                         { if ($3 == NIL)
329                                            $$=gc5($5); else
330                                            $$=gc5(pair(QUAL,pair($3,$5)));
331                                         }
332           | ifBType ARROW ifType        { $$ = gc3(fn($1,$3)); }
333           | ifBType                     { $$ = gc1($1); }
334           ;                                     
335 ifForall  /* [((VarId,Kind))] */
336           : '[' ifKindedTyvarL ']'      { $$ = gc3($2); }
337           ;
338
339 ifTypeL2  /* [Type], 2 or more */
340           : ifType ',' ifType           { $$ = gc3(doubleton($1,$3)); }
341           | ifType ',' ifTypeL2         { $$ = gc3(cons($1,$3));      }
342           ;
343
344 ifTypeL   /* [Type], 0 or more */
345           : ifType ',' ifTypeL          { $$ = gc3(cons($1,$3)); }
346           | ifType                      { $$ = gc1(singleton($1)); }
347           |                             { $$ = gc0(NIL); }
348           ;
349
350 ifBType   : ifAType                     { $$ = gc1($1);        } 
351           | ifBType ifAType             { $$ = gc2(ap($1,$2)); }
352           | UUUSAGE ifUsage ifAType     { $$ = gc3($3); }
353           ;
354
355 ifAType   : ifQTCName                   { $$ = gc1($1); }
356           | ifTyvar                     { $$ = gc1($1); }
357           | '(' ')'                     { $$ = gc2(typeUnit); }
358           | '(' ifTypeL2 ')'            { $$ = gc3(buildTuple(reverse($2))); }
359           | '[' ifType ']'              { $$ = gc3(ap(mkCon(tycon(typeList).text),
360                                                       $2));}
361           | '{' ifQTCName ifAType '}'   { $$ = gc4(ap(DICTAP,
362                                                       pair($2,$3))); }
363           | '(' ifType ')'              { $$ = gc3($2); }
364           | UTL ifTypeL UTR             { $$ = gc3(ap(UNBOXEDTUP,$2)); }
365           ;
366
367
368 /*- KW's usage stuff --------------------------------------*/
369 ifUsage   : '-'                         { $$ = gc1(NIL); }
370           | '!'                         { $$ = gc1(NIL); }
371           | ifVar                       { $$ = gc1(NIL); }
372           ;
373
374
375 /*- Interface kinds ---------------------------------------*/
376 ifKindedTyvarL /* [((VarId,Kind))] */
377           :                              { $$ = gc0(NIL);         }
378           | ifKindedTyvar ifKindedTyvarL { $$ = gc2(cons($1,$2)); }
379           ;
380 ifKindedTyvar /* ((VarId,Kind)) */
381           : ifTyvar                     { $$ = gc1(zpair($1,STAR)); }
382           | ifTyvar COCO ifAKind        { $$ = gc3(zpair($1,$3));   }
383           ; 
384 ifKind    : ifAKind                     { $$ = gc1($1);        }
385           | ifAKind ARROW ifKind        { $$ = gc3(ap($1,$3)); }
386           ;
387 ifAKind   : VAROP                       { $$ = gc1(STAR); } 
388                                             /* should be '*' */
389           | '(' ifKind ')'              { $$ = gc3($2);   }
390           ;
391
392
393 /*- Interface version/export/import stuff -----------------*/
394 ifEntities                                      
395           :                             { $$ = gc0(NIL);         }
396           | ifEntity ifEntities         { $$ = gc2(cons($1,$2)); }
397           ;
398 ifEntity
399           : ifEntityOcc                 {$$=gc1($1);}
400           | ifEntityOcc ifStuffInside   {$$=gc2(zpair($1,$2));}
401           ;
402 ifEntityOcc
403           : ifVar                       { $$ = gc1($1); }
404           | ifCon                       { $$ = gc1($1); }
405           | ARROW                       { $$ = gc1(typeArrow); }
406           | '(' ARROW ')'               { $$ = gc3(typeArrow); }  
407                                         /* why allow both? */
408           ;
409 ifStuffInside
410           : '{' ifValOccs '}'           { $$ = gc3($2); }
411           ;
412 ifValOccs
413           :                             { $$ = gc0(NIL); }
414           | ifVar ifValOccs             { $$ = gc2(cons($1,$2));   }
415           | ifCon ifValOccs             { $$ = gc2(cons($1,$2));   }
416           ;
417
418 ifVersionList
419           :                             {$$=gc0(NIL);}
420           | VARID NUMLIT ifVersionList  {$$=gc3(cons($1,$3));} 
421           | CONID NUMLIT ifVersionList  {$$=gc3(cons($1,$3));}
422           ;
423
424
425 /*- Haskell module header/import parsing: -----------------------------------
426  * Module chasing is now totally different from Classic Hugs98.  We parse
427  * the entire syntax tree.  Subsequent passes over the tree collect and
428  * chase imports; we no longer attempt to do so whilst parsing.
429  *-------------------------------------------------------------------------*/
430
431 /* In Haskell 1.2, the default module header was "module Main where"
432  * In 1.3, this changed to "module Main(main) where".
433  * We use the 1.2 header because it breaks much less pre-module code.
434  * STG Hugs, 15 March 00: disallow default headers (pro tem).
435  */
436 topModule : TMODULE modname expspec WHERE '{' modBody end
437                                         {$$=gc7(ap(M_MODULE,
438                                                    ztriple($2,$3,$6)));}
439           | TMODULE modname WHERE '{' modBody end
440                                         {$$=gc6(ap(M_MODULE,
441                                             ztriple(
442                                               $2,
443                                               singleton(ap(MODULEENT,$2)),
444                                               $5)));}
445
446           | begin modBody end           {ConId fakeNm = mkCon(module(
447                                             moduleBeingParsed).text);
448                                          $$ = gc2(ap(M_MODULE,
449                                                   ztriple(fakeNm,
450                                                   singleton(ap(MODULEENT,fakeNm)), 
451                                                   $2)));}
452
453           | TMODULE error               {syntaxError("module definition");}
454           ;
455
456 modname   : CONID                       {$$ = gc1($1);}
457           ;
458 modid     : CONID                       {$$ = gc1($1);}
459           ;
460 modBody   : topDecls                    {$$ = gc1($1);}
461           | impDecls                    {$$ = gc1($1);}
462           | impDecls ';' topDecls       {$$ = gc3(appendOnto($1,$3));}
463           ;
464
465 /*- Exports: --------------------------------------------------------------*/
466
467 expspec   : '(' ')'                     {$$ = gc2(NIL);}
468           | '(' exports ')'             {$$ = gc3($2);}
469           | '(' exports ',' ')'         {$$ = gc4($2);}
470           ;
471 exports   : exports ',' export          {$$ = gc3(cons($3,$1));}
472           | export                      {$$ = gc1(singleton($1));}
473           ;
474 /* The qcon should be qconid.  
475  * Relaxing the rule lets us explicitly export (:) from the Prelude.
476  */
477 export    : qvar                        {$$ = $1;}
478           | qcon                        {$$ = $1;}
479           | qconid '(' UPTO ')'         {$$ = gc4(pair($1,DOTDOT));}
480           | qconid '(' qnames ')'       {$$ = gc4(pair($1,$3));}
481           | TMODULE modid               {$$ = gc2(ap(MODULEENT,$2));}
482           ;
483 qnames    : /* empty */                 {$$ = gc0(NIL);}
484           | ','                         {$$ = gc1(NIL);}
485           | qnames1                     {$$ = $1;}
486           | qnames1 ','                 {$$ = gc2($1);}
487           ;
488 qnames1   : qnames1 ',' qname           {$$ = gc3(cons($3,$1));}
489           | qname                       {$$ = gc1(singleton($1));}
490           ;
491 qname     : qvar                        {$$ = $1;}
492           | qcon                        {$$ = $1;}
493           ;
494
495 /*- Import declarations: --------------------------------------------------*/
496
497 impDecls  : impDecls ';' impDecl        {$$ = gc3(appendOnto($3,$1));}
498           | impDecl                     {$$ = gc1($1);}
499           ;
500
501 /* Note that qualified import ignores the import list. */
502 impDecl   : IMPORT modid impspec        {$$=gc3(doubleton(
503                                               ap(M_IMPORT_Q,zpair($2,$2)),
504                                               ap(M_IMPORT_UNQ,zpair($2,$3))
505                                             ));}
506           | IMPORT modid ASMOD modid impspec
507                                         {$$=gc5(doubleton(
508                                               ap(M_IMPORT_Q,zpair($2,$4)),
509                                               ap(M_IMPORT_UNQ,zpair($2,$5))
510                                          ));}
511           | IMPORT QUALIFIED modid ASMOD modid impspec
512                                         {$$=gc6(singleton(
513                                                ap(M_IMPORT_Q,zpair($3,$5))
514                                             ));}
515           | IMPORT QUALIFIED modid impspec
516                                         {$$=gc4(singleton(
517                                                ap(M_IMPORT_Q,zpair($3,$3))
518                                             ));}
519           | IMPORT PRIVILEGED modid '(' imports ')'
520                                         {$$=gc6(singleton(
521                                                ap(M_IMPORT_UNQ,
522                                                   zpair($3,ap(STAR,$5)))));}
523           | IMPORT error                {syntaxError("import declaration");}
524           ;
525 impspec   : /* empty */                 {$$ = gc0(DOTDOT);}
526           | HIDING '(' imports ')'      {$$ = gc4(ap(HIDDEN,$3));}
527           | '(' imports ')'             {$$ = gc3($2);}
528           ;
529 imports   : /* empty */                 {$$ = gc0(NIL);}
530           | ','                         {$$ = gc1(NIL);}
531           | imports1                    {$$ = $1;}
532           | imports1 ','                {$$ = gc2($1);}
533           ;
534 imports1  : imports1 ',' import         {$$ = gc3(cons($3,$1));}
535           | import                      {$$ = gc1(singleton($1));}
536           ;
537 import    : var                         {$$ = $1;}
538           | CONID                       {$$ = $1;}
539           | CONID '(' UPTO ')'          {$$ = gc4(pair($1,DOTDOT));}
540           | CONID '(' names ')'         {$$ = gc4(pair($1,$3));}
541           ;
542 names     : /* empty */                 {$$ = gc0(NIL);}
543           | ','                         {$$ = gc1(NIL);}
544           | names1                      {$$ = $1;}
545           | names1 ','                  {$$ = gc2($1);}
546           ;
547 names1    : names1 ',' name             {$$ = gc3(cons($3,$1));}
548           | name                        {$$ = gc1(singleton($1));}
549           ;
550 name      : var                         {$$ = $1;}
551           | con                         {$$ = $1;}
552           ;
553
554 /*- Top-level declarations: -----------------------------------------------*/
555
556 topDecls : /* empty */                  {$$=gc0(NIL);}
557          | topDecl ';' topDecls         {$$=gc3(cons($1,$3));}
558          | decl    ';' topDecls         {$$=gc3(cons(ap(M_VALUE,$1),$3));}
559          | topDecl                      {$$=gc1(cons($1,NIL));}
560          | decl                         {$$=gc1(cons(ap(M_VALUE,$1),NIL));}
561          ;
562
563 /*- Type declarations: ----------------------------------------------------*/
564
565 topDecl   : TYPE tyLhs '=' type         {$$=gc4(ap(M_TYCON,
566                                                    z4ble($3,$2,$4,
567                                                          SYNONYM)));}
568           | TYPE tyLhs '=' type IN invars
569                                         {$$=gc6(ap(M_TYCON,
570                                                    z4ble($3,$2,ap($4,$6),
571                                                          RESTRICTSYN)));}
572           | TYPE error                  {syntaxError("type definition");}
573           | DATA btype2 '=' constrs deriving
574                                         {$$=gc5(ap(M_TYCON,
575                                                 z4ble($3,checkTyLhs($2),
576                                                       ap(rev($4),$5),
577                                                       DATATYPE)));}
578           | DATA context IMPLIES tyLhs '=' constrs deriving
579                                         {$$=gc7(ap(M_TYCON,
580                                                    z4ble($5,$4,
581                                                       ap(qualify($2,rev($6)),$7),
582                                                       DATATYPE)));}
583           | DATA btype2                 {$$=gc2(ap(M_TYCON,
584                                                    z4ble($1,checkTyLhs($2),
585                                                       ap(NIL,NIL),DATATYPE)));}
586           | DATA context IMPLIES tyLhs  {$$=gc4(ap(M_TYCON,
587                                                   z4ble($1,$4,
588                                                         ap(qualify($2,NIL),NIL),
589                                                         DATATYPE)));}
590           | DATA error                  {syntaxError("data definition");}
591           | TNEWTYPE btype2 '=' nconstr deriving
592                                         {$$=gc5(ap(M_TYCON,
593                                                    z4ble($3,checkTyLhs($2),
594                                                          ap($4,$5),NEWTYPE)));}
595           | TNEWTYPE context IMPLIES tyLhs '=' nconstr deriving
596                                         {$$=gc7(ap(M_TYCON,
597                                                    z4ble($5,$4,
598                                                          ap(qualify($2,$6),$7),
599                                                          NEWTYPE)));}
600           | TNEWTYPE error              {syntaxError("newtype definition");}
601           ;
602 tyLhs     : tyLhs varid                 {$$ = gc2(ap($1,$2));}
603           | CONID                       {$$ = $1;}
604           | error                       {syntaxError("type defn lhs");}
605           ;
606 invars    : invars ',' invar            {$$ = gc3(cons($3,$1));}
607           | invar                       {$$ = gc1(cons($1,NIL));}
608           ;
609 invar     : var COCO topType            {$$ = gc3(sigdecl($2,singleton($1),
610                                                                        $3));}
611           | var                         {$$ = $1;}
612           ;
613 constrs   : constrs '|' pconstr         {$$ = gc3(cons($3,$1));}
614           | pconstr                     {$$ = gc1(cons($1,NIL));}
615           ;
616 pconstr   : ALL varids '.' qconstr      {$$ = gc4(ap(POLYTYPE,
617                                                      pair(rev($2),$4)));}
618           | qconstr                     {$$ = $1;}
619           ;
620 qconstr   : context IMPLIES constr      {$$ = gc3(qualify($1,$3));}
621           | constr                      {$$ = $1;}
622           ;
623 constr    : '!' btype conop bbtype      {$$ = gc4(ap(ap($3,bang($2)),$4));}
624           | btype1    conop bbtype      {$$ = gc3(ap(ap($2,$1),$3));}
625           | btype2    conop bbtype      {$$ = gc3(ap(ap($2,$1),$3));}
626           | bpolyType conop bbtype      {$$ = gc3(ap(ap($2,$1),$3));}
627           | btype2                      {$$ = $1;}
628           | btype3                      {$$ = $1;}
629           | btype4                      {$$ = $1;}
630           | con '{' fieldspecs '}'      {$$ = gc4(ap(LABC,pair($1,rev($3))));}
631           | con '{' '}'                 {$$ = gc3(ap(LABC,pair($1,NIL)));}
632           | error                       {syntaxError("data type definition");}
633           ;
634 btype3    : btype2 '!' atype            {$$ = gc3(ap($1,bang($3)));}
635           | btype3 '!' atype            {$$ = gc3(ap($1,bang($3)));}
636           | btype3 atype                {$$ = gc2(ap($1,$2));}
637           ;
638 btype4    : btype2 bpolyType            {$$ = gc2(ap($1,$2));}
639           | btype3 bpolyType            {$$ = gc2(ap($1,$2));}
640           | btype4 bpolyType            {$$ = gc2(ap($1,$2));}
641           | btype4 atype                {$$ = gc2(ap($1,$2));}
642           | btype4 '!' atype            {$$ = gc3(ap($1,bang($3)));}
643           ;
644 bbtype    : '!' btype                   {$$ = gc2(bang($2));}
645           | btype                       {$$ = $1;}
646           | bpolyType                   {$$ = $1;}
647           ;
648 nconstr   : pconstr                     {$$ = gc1(singleton($1));}
649           ;
650 fieldspecs: fieldspecs ',' fieldspec    {$$ = gc3(cons($3,$1));}
651           | fieldspec                   {$$ = gc1(cons($1,NIL));}
652           ;
653 fieldspec : vars COCO polyType          {$$ = gc3(pair(rev($1),$3));}
654           | vars COCO type              {$$ = gc3(pair(rev($1),$3));}
655           | vars COCO '!' type          {$$ = gc4(pair(rev($1),bang($4)));}
656           ;
657 deriving  : /* empty */                 {$$ = gc0(NIL);}
658           | DERIVING qconid             {$$ = gc2(singleton($2));}
659           | DERIVING '(' derivs0 ')'    {$$ = gc4($3);}
660           ;
661 derivs0   : /* empty */                 {$$ = gc0(NIL);}
662           | derivs                      {$$ = gc1(rev($1));}
663           ;
664 derivs    : derivs ',' qconid           {$$ = gc3(cons($3,$1));}
665           | qconid                      {$$ = gc1(singleton($1));}
666           ;
667
668 /*- Processing definitions of primitives ----------------------------------*/
669
670 topDecl   : FOREIGN IMPORT callconv DYNAMIC unsafe_flag var COCO type 
671                {$$=gc8(ap(M_FOREIGN_IM,z5ble($1,$3,NIL,$6,$8)));}
672           | FOREIGN IMPORT callconv ext_loc ext_name unsafe_flag var COCO type 
673                {$$=gc9(ap(M_FOREIGN_IM,z5ble($1,$3,pair($4,$5),$7,$9)));}
674           | FOREIGN EXPORT callconv DYNAMIC qvarid COCO type 
675                {$$=gc7(ap(M_FOREIGN_EX,z5ble($1,$3,$4,$5,$7)));}
676           ;
677
678 callconv  : CCALL                {$$ = gc1(textCcall);}
679           | STDKALL              {$$ = gc1(textStdcall);}
680           | /* empty */          {$$ = gc0(NIL);}
681           ;
682 ext_loc   : STRINGLIT            {$$ = $1;}
683           ;
684 ext_name  : STRINGLIT            {$$ = $1;}
685           ;
686 unsafe_flag: /* empty */         {$$ = gc0(NIL);}
687           | UNSAFE               {$$ = gc1(NIL); /* ignored */ }
688           ;
689
690
691 /*- Class declarations: ---------------------------------------------------*/
692
693 topDecl   : TCLASS crule fds wherePart  {$$=gc4(ap(M_CLASS,z4ble($1,$2,$4,$3)));}
694           | TINSTANCE irule wherePart   {$$=gc3(ap(M_INST,ztriple($1,$2,$3)));}
695           | DEFAULT '(' dtypes ')'      {$$=gc4(ap(M_DEFAULT,zpair($1,$3)));}
696           | TCLASS error                {syntaxError("class declaration");}
697           | TINSTANCE error             {syntaxError("instance declaration");}
698           | DEFAULT error               {syntaxError("default declaration");}
699           ;
700 crule     : context IMPLIES btype2      {$$ = gc3(pair($1,checkPred($3)));}
701           | btype2                      {$$ = gc1(pair(NIL,checkPred($1)));}
702           ;
703 irule     : context IMPLIES btype2      {$$ = gc3(pair($1,checkPred($3)));}
704           | btype2                      {$$ = gc1(pair(NIL,checkPred($1)));}
705           ;
706 dtypes    : /* empty */                 {$$ = gc0(NIL);}
707           | dtypes1                     {$$ = gc1(rev($1));}
708           ;
709 dtypes1   : dtypes1 ',' type            {$$ = gc3(cons($3,$1));}
710           | type                        {$$ = gc1(cons($1,NIL));}
711           ;
712
713 fds       : /* empty */                 {$$ = gc0(NIL);}
714           | '|' fds1                    {h98DoesntSupport(row,"dependent parameters");
715                                          $$ = gc2(rev($2));}
716           ;
717 fds1      : fds1 ',' fd                 {$$ = gc3(cons($3,$1));}
718           | fd                          {$$ = gc1(cons($1,NIL));}
719           | 
720           ;
721 fd        : varids0 ARROW varids0       {$$ = gc3(pair(rev($1),rev($3)));}
722           ;
723 varids0   : /* empty */                 {$$ = gc0(NIL);}
724           | varids0 varid               {$$ = gc2(cons($2,$1));}
725           ;
726   
727   /*- Type expressions: -----------------------------------------------------*/
728   
729 topType   : ALL varids '.' topType0     {$$ = gc4(ap(POLYTYPE,
730                                                      pair(rev($2),$4)));}
731           | topType0                    {$$ = $1;}
732           ;
733 topType0  : context IMPLIES topType1    {$$ = gc3(qualify($1,$3));}
734           | topType1                    {$$ = $1;}
735           ;
736 topType1  : bpolyType ARROW topType1    {$$ = gc3(fn($1,$3));}
737           | btype1    ARROW topType1    {$$ = gc3(fn($1,$3));}
738           | btype2    ARROW topType1    {$$ = gc3(fn($1,$3));}
739           | btype                       {$$ = $1;}
740           ;
741 polyType  : ALL varids '.' sigType      {$$ = gc4(ap(POLYTYPE,
742                                                      pair(rev($2),$4)));}
743           | context IMPLIES type        {$$ = gc3(qualify($1,$3));}
744           | bpolyType                   {$$ = $1;}
745           ;
746 bpolyType : '(' polyType ')'            {$$ = gc3($2);}
747           ;
748 varids    : varids varid                {$$ = gc2(cons($2,$1));}
749           | varid                       {$$ = gc1(singleton($1));}
750           ;
751 sigType   : context IMPLIES type        {$$ = gc3(qualify($1,$3));}
752           | type                        {$$ = $1;}
753           ;
754 context   : '(' ')'                     {$$ = gc2(NIL);}
755           | btype2                      {$$ = gc1(singleton(checkPred($1)));}
756           | '(' btype2 ')'              {$$ = gc3(singleton(checkPred($2)));}
757           | '(' btypes2 ')'             {$$ = gc3(checkCtxt(rev($2)));}
758 /*#if TREX*/
759           | lacks                       {$$ = gc1(singleton($1));}
760           | '(' lacks1 ')'              {$$ = gc3(checkCtxt(rev($2)));}
761           ;
762 lacks     : varid '\\' varid            {
763 #if TREX
764                                          $$ = gc3(ap(mkExt(textOf($3)),$1));
765 #else
766                                          noTREX("a type context");
767 #endif
768                                         }
769           | IPVARID COCO type           {
770 #if IPARAM
771                                          $$ = gc3(pair(mkIParam($1),$3));
772 #else
773                                          noIP("a type context");
774 #endif
775                                         }
776           ;
777 lacks1    : btypes2 ',' lacks           {$$ = gc3(cons($3,$1));}
778           | lacks1  ',' btype2          {$$ = gc3(cons($3,$1));}
779           | lacks1  ',' lacks           {$$ = gc3(cons($3,$1));}
780           | btype2  ',' lacks           {$$ = gc3(cons($3,cons($1,NIL)));}
781           | lacks                       {$$ = gc1(singleton($1));}
782           ;
783 /*#endif*/
784
785 type      : type1                       {$$ = $1;}
786           | btype2                      {$$ = $1;}
787           ;
788 type1     : btype1                      {$$ = $1;}
789           | btype1 ARROW type           {$$ = gc3(fn($1,$3));}
790           | btype2 ARROW type           {$$ = gc3(fn($1,$3));}
791           | error                       {syntaxError("type expression");}
792           ;
793 btype     : btype1                      {$$ = $1;}
794           | btype2                      {$$ = $1;}
795           ;
796 btype1    : btype1 atype                {$$ = gc2(ap($1,$2));}
797           | atype1                      {$$ = $1;}
798           ;
799 btype2    : btype2 atype                {$$ = gc2(ap($1,$2));}
800           | qconid                      {$$ = $1;}
801           ;
802 atype     : atype1                      {$$ = $1;}
803           | qconid                      {$$ = $1;}
804           ;
805 atype1    : varid                       {$$ = $1;}
806           | '(' ')'                     {$$ = gc2(typeUnit);}
807           | '(' ARROW ')'               {$$ = gc3(typeArrow);}
808           | '(' type1 ')'               {$$ = gc3($2);}
809           | '(' btype2 ')'              {$$ = gc3($2);}
810           | '(' tupCommas ')'           {$$ = gc3($2);}
811           | '(' btypes2 ')'             {$$ = gc3(buildTuple($2));}
812           | '(' typeTuple ')'           {$$ = gc3(buildTuple($2));}
813           | '(' tfields ')'             {
814 #if TREX
815                                          $$ = gc3(revOnto($2,typeNoRow));
816 #else
817                                          noTREX("a type");
818 #endif
819                                         }
820           | '(' tfields '|' type ')'    {
821 #if TREX
822                                          $$ = gc5(revOnto($2,$4));
823 #else
824                                          noTREX("a type");
825 #endif
826                                         }
827           | '[' type ']'                {$$ = gc3(ap(typeList,$2));}
828           | '[' ']'                     {$$ = gc2(typeList);}
829           | '_'                         {h98DoesntSupport(row,"anonymous type variables");
830                                          $$ = gc1(inventVar());}
831           ;
832 btypes2   : btypes2 ',' btype2          {$$ = gc3(cons($3,$1));}
833           | btype2  ',' btype2          {$$ = gc3(cons($3,cons($1,NIL)));}
834           ;
835 typeTuple : type1     ',' type          {$$ = gc3(cons($3,cons($1,NIL)));}
836           | btype2    ',' type1         {$$ = gc3(cons($3,cons($1,NIL)));}
837           | btypes2   ',' type1         {$$ = gc3(cons($3,$1));}
838           | typeTuple ',' type          {$$ = gc3(cons($3,$1));}
839           ;
840 /*#if TREX*/
841 tfields   : tfields ',' tfield          {$$ = gc3(cons($3,$1));}
842           | tfield                      {$$ = gc1(singleton($1));}
843           ;
844 tfield    : varid COCO type             {h98DoesntSupport(row,"extensible records");
845                                          $$ = gc3(ap(mkExt(textOf($1)),$3));}
846           ;
847 /*#endif*/
848
849 /*- Value declarations: ---------------------------------------------------*/
850
851 gendecl   : INFIXN optDigit ops         {$$ = gc3(fixdecl($1,$3,NON_ASS,$2));}
852           | INFIXN error                {syntaxError("fixity decl");}
853           | INFIXL optDigit ops         {$$ = gc3(fixdecl($1,$3,LEFT_ASS,$2));}
854           | INFIXL error                {syntaxError("fixity decl");}
855           | INFIXR optDigit ops         {$$ = gc3(fixdecl($1,$3,RIGHT_ASS,$2));}
856           | INFIXR error                {syntaxError("fixity decl");}
857           | vars COCO topType           {$$ = gc3(sigdecl($2,$1,$3));}
858           | vars COCO error             {syntaxError("type signature");}
859           ;
860 optDigit  : NUMLIT                      {$$ = gc1(checkPrec($1));}
861           | /* empty */                 {$$ = gc0(mkInt(DEF_PREC));}
862           ;
863 ops       : ops ',' op                  {$$ = gc3(cons($3,$1));}
864           | op                          {$$ = gc1(singleton($1));}
865           ;
866 vars      : vars ',' var                {$$ = gc3(cons($3,$1));}
867           | var                         {$$ = gc1(singleton($1));}
868           ;
869 decls     : '{' decls0 end              {$$ = gc3($2);}
870           | '{' decls1 end              {$$ = gc3($2);}
871           ;
872 decls0    : /* empty */                 {$$ = gc0(NIL);}
873           | decls0 ';'                  {$$ = gc2($1);}
874           | decls1 ';'                  {$$ = gc2($1);}
875           ;
876 decls1    : decls0 decl                 {$$ = gc2(cons($2,$1));}
877           ;
878 decl      : gendecl                     {$$ = $1;}
879           | funlhs rhs                  {$$ = gc2(ap(FUNBIND,pair($1,$2)));}
880           | funlhs COCO type rhs        {$$ = gc4(ap(FUNBIND,
881                                                      pair($1,ap(RSIGN,
882                                                                 ap($4,$3)))));}
883           | pat0 rhs                    {$$ = gc2(ap(PATBIND,pair($1,$2)));}
884           ;
885 funlhs    : funlhs0                     {$$ = $1;}
886           | funlhs1                     {$$ = $1;}
887           | npk                         {$$ = $1;}
888           ;
889 funlhs0   : pat10_vI varop    pat0      {$$ = gc3(ap2($2,$1,$3));}
890           | infixPat varop    pat0      {$$ = gc3(ap2($2,$1,$3));}
891           | NUMLIT   varop    pat0      {$$ = gc3(ap2($2,$1,$3));}
892           | var      varop_pl pat0      {$$ = gc3(ap2($2,$1,$3));}
893           | var      '+'      pat0_INT  {$$ = gc3(ap2(varPlus,$1,$3));}
894           ;
895 funlhs1   : '(' funlhs0 ')' apat        {$$ = gc4(ap($2,$4));}
896           | '(' funlhs1 ')' apat        {$$ = gc4(ap($2,$4));}
897           | '(' npk     ')' apat        {$$ = gc4(ap($2,$4));}
898           | var     apat                {$$ = gc2(ap($1,$2));}
899           | funlhs1 apat                {$$ = gc2(ap($1,$2));}
900           ;
901 rhs       : rhs1 wherePart              {$$ = gc2(letrec($2,$1));}
902           | error                       {syntaxError("declaration");}
903           ;
904 rhs1      : '=' exp                     {$$ = gc2(pair($1,$2));}
905           | gdrhs                       {$$ = gc1(grded(rev($1)));}
906           ;
907 gdrhs     : gdrhs gddef                 {$$ = gc2(cons($2,$1));}
908           | gddef                       {$$ = gc1(singleton($1));}
909           ;
910 gddef     : '|' exp0 '=' exp            {$$ = gc4(pair($3,pair($2,$4)));}
911           ;
912 wherePart : /* empty */                 {$$ = gc0(NIL);}
913           | WHERE decls                 {$$ = gc2($2);}
914           ;
915
916 /*- Patterns: -------------------------------------------------------------*/
917
918 pat       : npk                         {$$ = $1;}
919           | pat_npk                     {$$ = $1;}
920           ;
921 pat_npk   : pat0 COCO type              {$$ = gc3(ap(ESIGN,pair($1,$3)));}
922           | pat0                        {$$ = $1;}
923           ;
924 npk       : var '+' NUMLIT              {$$ = gc3(ap2(varPlus,$1,$3));}
925           ;
926 pat0      : var                         {$$ = $1;}
927           | NUMLIT                      {$$ = $1;}
928           | pat0_vI                     {$$ = $1;}
929           ;
930 pat0_INT  : var                         {$$ = $1;}
931           | pat0_vI                     {$$ = $1;}
932           ;
933 pat0_vI   : pat10_vI                    {$$ = $1;}
934           | infixPat                    {$$ = gc1(ap(INFIX,$1));}
935           ;
936 infixPat  : '-' pat10                   {$$ = gc2(ap(NEG,only($2)));}
937           | '-' error                   {syntaxError("pattern");}
938           | var qconop pat10            {$$ = gc3(ap(ap($2,only($1)),$3));}
939           | var qconop '-' pat10        {$$ = gc4(ap(NEG,ap2($2,only($1),$4)));}
940           | NUMLIT qconop pat10         {$$ = gc3(ap(ap($2,only($1)),$3));}
941           | NUMLIT qconop '-' pat10     {$$ = gc4(ap(NEG,ap2($2,only($1),$4)));}
942           | pat10_vI qconop pat10       {$$ = gc3(ap(ap($2,only($1)),$3));}
943           | pat10_vI qconop '-' pat10   {$$ = gc4(ap(NEG,ap2($2,only($1),$4)));}
944           | infixPat qconop pat10       {$$ = gc3(ap(ap($2,$1),$3));}
945           | infixPat qconop '-' pat10   {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
946           ;
947 pat10     : fpat                        {$$ = $1;}
948           | apat                        {$$ = $1;}
949           ;
950 pat10_vI  : fpat                        {$$ = $1;}
951           | apat_vI                     {$$ = $1;}
952           ;
953 fpat      : fpat apat                   {$$ = gc2(ap($1,$2));}
954           | gcon apat                   {$$ = gc2(ap($1,$2));}
955           ;
956 apat      : NUMLIT                      {$$ = $1;}
957           | var                         {$$ = $1;}
958           | apat_vI                     {$$ = $1;}
959           ;
960 apat_vI   : var '@' apat                {$$ = gc3(ap(ASPAT,pair($1,$3)));}
961           | gcon                        {$$ = $1;}
962           | qcon '{' patbinds '}'       {$$ = gc4(ap(CONFLDS,pair($1,$3)));}
963           | CHARLIT                     {$$ = $1;}
964           | STRINGLIT                   {$$ = $1;}
965           | '_'                         {$$ = gc1(WILDCARD);}
966           | '(' pat_npk ')'             {$$ = gc3($2);}
967           | '(' npk ')'                 {$$ = gc3($2);}
968           | '(' pats2 ')'               {$$ = gc3(buildTuple($2));}
969           | '[' pats1 ']'               {$$ = gc3(ap(FINLIST,rev($2)));}
970           | '~' apat                    {$$ = gc2(ap(LAZYPAT,$2));}
971 /*#if TREX*/
972           | '(' patfields ')'           {
973 #if TREX
974                                          $$ = gc3(revOnto($2,nameNoRec));
975 #else
976                                          $$ = gc3(NIL);
977 #endif
978                                         }
979           | '(' patfields '|' pat ')'   {$$ = gc5(revOnto($2,$4));}
980 /*#endif TREX*/
981           ;
982 pats2     : pats2 ',' pat               {$$ = gc3(cons($3,$1));}
983           | pat ',' pat                 {$$ = gc3(cons($3,singleton($1)));}
984           ;
985 pats1     : pats1 ',' pat               {$$ = gc3(cons($3,$1));}
986           | pat                         {$$ = gc1(singleton($1));}
987           ;
988 patbinds  : /* empty */                 {$$ = gc0(NIL);}
989           | patbinds1                   {$$ = gc1(rev($1));}
990           ;
991 patbinds1 : patbinds1 ',' patbind       {$$ = gc3(cons($3,$1));}
992           | patbind                     {$$ = gc1(singleton($1));}
993           ;
994 patbind   : qvar '=' pat                {$$ = gc3(pair($1,$3));}
995           | var                         {$$ = $1;}
996           ;
997 /*#if TREX*/
998 patfields : patfields ',' patfield      {$$ = gc3(cons($3,$1));}
999           | patfield                    {$$ = gc1(singleton($1));}
1000           ;
1001 patfield  : varid '=' pat               {
1002 #if TREX
1003                                          $$ = gc3(ap(mkExt(textOf($1)),$3));
1004 #else
1005                                          noTREX("a pattern");
1006 #endif
1007                                         }
1008           ;
1009 /*#endif TREX*/
1010
1011 /*- Expressions: ----------------------------------------------------------*/
1012
1013 exp       : exp_err                     {$$ = $1;}
1014           | error                       {syntaxError("expression");}
1015           ;
1016 exp_err   : exp0a COCO sigType          {$$ = gc3(ap(ESIGN,pair($1,$3)));}
1017           | exp0a WITH dbinds           {
1018 #if IPARAM
1019                                          $$ = gc3(ap(WITHEXP,pair($1,$3)));
1020 #else
1021                                          noIP("an expression");
1022 #endif
1023                                         }
1024           | exp0                        {$$ = $1;}
1025           ;
1026 exp0      : exp0a                       {$$ = $1;}
1027           | exp0b                       {$$ = $1;}
1028           ;
1029 exp0a     : infixExpa                   {$$ = gc1(ap(INFIX,$1));}
1030           | exp10a                      {$$ = $1;}
1031           ;
1032 exp0b     : infixExpb                   {$$ = gc1(ap(INFIX,$1));}
1033           | exp10b                      {$$ = $1;}
1034           ;
1035 infixExpa : infixExpa qop '-' exp10a    {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
1036           | infixExpa qop exp10a        {$$ = gc3(ap(ap($2,$1),$3));}
1037           | '-' exp10a                  {$$ = gc2(ap(NEG,only($2)));}
1038           | exp10a qop '-' exp10a       {$$ = gc4(ap(NEG,
1039                                                      ap(ap($2,only($1)),$4)));}
1040           | exp10a qop exp10a           {$$ = gc3(ap(ap($2,only($1)),$3));}
1041           ;
1042 infixExpb : infixExpa qop '-' exp10b    {$$ = gc4(ap(NEG,ap(ap($2,$1),$4)));}
1043           | infixExpa qop exp10b        {$$ = gc3(ap(ap($2,$1),$3));}
1044           | '-' exp10b                  {$$ = gc2(ap(NEG,only($2)));}
1045           | exp10a qop '-' exp10b       {$$ = gc4(ap(NEG,
1046                                                      ap(ap($2,only($1)),$4)));}
1047           | exp10a qop exp10b           {$$ = gc3(ap(ap($2,only($1)),$3));}
1048           ;
1049 exp10a    : CASEXP exp OF '{' alts end  {$$ = gc6(ap(CASE,pair($2,rev($5))));}
1050           | DO '{' stmts end            {$$ = gc4(ap(DOCOMP,checkDo($3)));}
1051           | appExp                      {$$ = $1;}
1052           ;
1053 exp10b    : '\\' pats ARROW exp         {$$ = gc4(ap(LAMBDA,      
1054                                                      pair(rev($2),
1055                                                           pair($3,$4))));}
1056           | LET decls IN exp            {$$ = gc4(letrec($2,$4));}
1057           | IF exp THEN exp ELSE exp    {$$ = gc6(ap(COND,triple($2,$4,$6)));}
1058           | DLET dbinds IN exp          {
1059 #if IPARAM
1060                                          $$ = gc4(ap(WITHEXP,pair($4,$2)));
1061 #else
1062                                          noIP("an expression");
1063 #endif
1064                                         }
1065           ;
1066 pats      : pats apat                   {$$ = gc2(cons($2,$1));}
1067           | apat                        {$$ = gc1(cons($1,NIL));}
1068           ;
1069 appExp    : appExp aexp                 {$$ = gc2(ap($1,$2));}
1070           | aexp                        {$$ = $1;}
1071           ;
1072 aexp      : qvar                        {$$ = $1;}
1073           | qvar '@' aexp               {$$ = gc3(ap(ASPAT,pair($1,$3)));}
1074           | '~' aexp                    {$$ = gc2(ap(LAZYPAT,$2));}
1075           | IPVARID                     {$$ = $1;}
1076           | '_'                         {$$ = gc1(WILDCARD);}
1077           | gcon                        {$$ = $1;}
1078           | qcon '{' fbinds '}'         {$$ = gc4(ap(CONFLDS,pair($1,$3)));}
1079           | aexp '{' fbinds '}'         {$$ = gc4(ap(UPDFLDS,
1080                                                      triple($1,NIL,$3)));}
1081           | NUMLIT                      {$$ = $1;}
1082           | CHARLIT                     {$$ = $1;}
1083           | STRINGLIT                   {$$ = $1;}
1084           | REPEAT                      {$$ = $1;}
1085           | '(' exp ')'                 {$$ = gc3($2);}
1086           | '(' exps2 ')'               {$$ = gc3(buildTuple($2));}
1087 /*#if TREX*/
1088           | '(' vfields ')'             {
1089 #if TREX
1090                                          $$ = gc3(revOnto($2,nameNoRec));
1091 #else
1092                                          $$ = gc3(NIL);
1093 #endif
1094                                         }
1095           | '(' vfields '|' exp ')'     {$$ = gc5(revOnto($2,$4));}
1096           | RECSELID                    {$$ = $1;}
1097 /*#endif*/
1098           | '[' list ']'                {$$ = gc3($2);}
1099           | '(' exp10a qop ')'          {$$ = gc4(ap($3,$2));}
1100           | '(' qvarop_mi exp0 ')'      {$$ = gc4(ap(ap(nameFlip,$2),$3));}
1101           | '(' qconop exp0 ')'         {$$ = gc4(ap(ap(nameFlip,$2),$3));}
1102           ;
1103 exps2     : exps2 ',' exp               {$$ = gc3(cons($3,$1));}
1104           | exp ',' exp                 {$$ = gc3(cons($3,cons($1,NIL)));}
1105           ;
1106 /*#if TREX*/
1107 vfields   : vfields ',' vfield          {$$ = gc3(cons($3,$1));}
1108           | vfield                      {$$ = gc1(singleton($1));}
1109           ;
1110 vfield    : varid '=' exp               {
1111 #if TREX
1112                                          $$ = gc3(ap(mkExt(textOf($1)),$3));
1113 #else
1114                                          noTREX("an expression");
1115 #endif
1116                                         }
1117           ;
1118 /*#endif*/
1119 alts      : alts1                       {$$ = $1;}
1120           | alts1 ';'                   {$$ = gc2($1);}
1121           ;
1122 alts1     : alts1 ';' alt               {$$ = gc3(cons($3,$1));}
1123           | alt                         {$$ = gc1(cons($1,NIL));}
1124           ;
1125 alt       : pat altRhs wherePart        {$$ = gc3(pair($1,letrec($3,$2)));}
1126           ;
1127 altRhs    : guardAlts                   {$$ = gc1(grded(rev($1)));}
1128           | ARROW exp                   {$$ = gc2(pair($1,$2));}
1129           | error                       {syntaxError("case expression");}
1130           ;
1131 guardAlts : guardAlts guardAlt          {$$ = gc2(cons($2,$1));}
1132           | guardAlt                    {$$ = gc1(cons($1,NIL));}
1133           ;
1134 guardAlt  : '|' exp0 ARROW exp          {$$ = gc4(pair($3,pair($2,$4)));}
1135           ;
1136 stmts     : stmts1 ';'                  {$$ = gc2($1);}
1137           | stmts1                      {$$ = $1;}
1138           ;
1139 stmts1    : stmts1 ';' stmt             {$$ = gc3(cons($3,$1));}
1140           | stmt                        {$$ = gc1(cons($1,NIL));}
1141           ;
1142 stmt      : exp_err FROM exp            {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
1143           | LET decls                   {$$ = gc2(ap(QWHERE,$2));}
1144 /*        | IF exp                      {$$ = gc2(ap(BOOLQUAL,$2));}*/
1145           | exp_err                     {$$ = gc1(ap(DOQUAL,$1));}
1146           ;
1147 fbinds    : /* empty */                 {$$ = gc0(NIL);}
1148           | fbinds1                     {$$ = gc1(rev($1));}
1149           ;
1150 fbinds1   : fbinds1 ',' fbind           {$$ = gc3(cons($3,$1));}
1151           | fbind                       {$$ = gc1(singleton($1));}
1152           ;
1153 fbind     : var                         {$$ = $1;}
1154           | qvar '=' exp                {$$ = gc3(pair($1,$3));}
1155           ;
1156
1157 dbinds    : '{' dbs0 end                {$$ = gc3($2);}
1158           | '{' dbs1 end                {$$ = gc3($2);}
1159           ;
1160 dbs0      : /* empty */                 {$$ = gc0(NIL);}
1161           | dbs0 ';'                    {$$ = gc2($1);}
1162           | dbs1 ';'                    {$$ = gc2($1);}
1163           ;
1164 dbs1      : dbs0 dbind                  {$$ = gc2(cons($2,$1));}
1165           ;
1166 dbind     : IPVARID '=' exp             {$$ = gc3(pair($1,$3));}
1167           ;
1168
1169 /*- List Expressions: -------------------------------------------------------*/
1170
1171 list      : exp                         {$$ = gc1(ap(FINLIST,cons($1,NIL)));}
1172           | exps2                       {$$ = gc1(ap(FINLIST,rev($1)));}
1173           | exp '|' quals               {$$ = gc3(ap(COMP,pair($1,rev($3))));}
1174           | exp         UPTO exp        {$$ = gc3(ap(ap(nameFromTo,$1),$3));}
1175           | exp ',' exp UPTO            {$$ = gc4(ap(ap(nameFromThen,$1),$3));}
1176           | exp         UPTO            {$$ = gc2(ap(nameFrom,$1));}
1177           | exp ',' exp UPTO exp        {$$ = gc5(ap(ap(ap(nameFromThenTo,
1178                                                                 $1),$3),$5));}
1179           ;
1180 quals     : quals ',' qual              {$$ = gc3(cons($3,$1));}
1181           | qual                        {$$ = gc1(cons($1,NIL));}
1182           ;
1183 qual      : exp FROM exp                {$$ = gc3(ap(FROMQUAL,pair($1,$3)));}
1184           | exp                         {$$ = gc1(ap(BOOLQUAL,$1));}
1185           | LET decls                   {$$ = gc2(ap(QWHERE,$2));}
1186           ;
1187
1188 /*- Identifiers and symbols: ----------------------------------------------*/
1189
1190 gcon      : qcon                        {$$ = $1;}
1191           | '(' ')'                     {$$ = gc2(nameUnit);}
1192           | '[' ']'                     {$$ = gc2(nameNil);}
1193           | '(' tupCommas ')'           {$$ = gc3($2);}
1194           ;
1195 tupCommas : tupCommas ','               {$$ = gc2(mkTuple(tupleOf($1)+1));}
1196           | ','                         {$$ = gc1(mkTuple(2));}
1197           ;
1198 varid     : VARID                       {$$ = $1;}
1199           | HIDING                      {$$ = gc1(varHiding);}
1200           | QUALIFIED                   {$$ = gc1(varQualified);}
1201           | ASMOD                       {$$ = gc1(varAsMod);}
1202           | PRIVILEGED                  {$$ = gc1(varPrivileged);}
1203           ;
1204 qconid    : QCONID                      {$$ = $1;}
1205           | CONID                       {$$ = $1;}
1206           ;
1207 var       : varid                       {$$ = $1;}
1208           | '(' VAROP ')'               {$$ = gc3($2);}
1209           | '(' '+' ')'                 {$$ = gc3(varPlus);}
1210           | '(' '-' ')'                 {$$ = gc3(varMinus);}
1211           | '(' '!' ')'                 {$$ = gc3(varBang);}
1212           | '(' '.' ')'                 {$$ = gc3(varDot);}
1213           ;
1214 qvar      : QVARID                      {$$ = $1;}
1215           | '(' QVAROP ')'              {$$ = gc3($2);}
1216           | var                         {$$ = $1;}
1217           ;
1218 con       : CONID                       {$$ = $1;}
1219           | '(' CONOP ')'               {$$ = gc3($2);}
1220           ;
1221 qcon      : QCONID                      {$$ = $1;}
1222           | '(' QCONOP ')'              {$$ = gc3($2);}
1223           | con                         {$$ = $1;}
1224           ;
1225 varop     : '+'                         {$$ = gc1(varPlus);}
1226           | '-'                         {$$ = gc1(varMinus);}
1227           | varop_mipl                  {$$ = $1;}
1228           ;
1229 varop_mi  : '+'                         {$$ = gc1(varPlus);}
1230           | varop_mipl                  {$$ = $1;}
1231           ;
1232 varop_pl  : '-'                         {$$ = gc1(varMinus);}
1233           | varop_mipl                  {$$ = $1;}
1234           ;
1235 varop_mipl: VAROP                       {$$ = $1;}
1236           | '`' varid '`'               {$$ = gc3($2);}
1237           | '!'                         {$$ = gc1(varBang);}
1238           | '.'                         {$$ = gc1(varDot);}
1239           ;
1240 qvarop    : '-'                         {$$ = gc1(varMinus);}
1241           | qvarop_mi                   {$$ = $1;}
1242           ;
1243 qvarop_mi : QVAROP                      {$$ = $1;}
1244           | '`' QVARID '`'              {$$ = gc3($2);}
1245           | varop_mi                    {$$ = $1;}
1246           ;
1247
1248 conop     : CONOP                       {$$ = $1;}
1249           | '`' CONID  '`'              {$$ = gc3($2);}
1250           ;
1251 qconop    : QCONOP                      {$$ = $1;}
1252           | '`' QCONID '`'              {$$ = gc3($2);}
1253           | conop                       {$$ = $1;}
1254           ;
1255 op        : varop                       {$$ = $1;}
1256           | conop                       {$$ = $1;}
1257           ;
1258 qop       : qvarop                      {$$ = $1;}
1259           | qconop                      {$$ = $1;}
1260           ;
1261
1262 /*- Stuff from STG hugs ---------------------------------------------------*/
1263
1264 qvarid    : varid1                      {$$ = gc1($1);}
1265           | QVARID                      {$$ = gc1($1);}
1266
1267 varid1    : VARID                       {$$ = gc1($1);}
1268           | HIDING                      {$$ = gc1(varHiding);}
1269           | QUALIFIED                   {$$ = gc1(varQualified);}
1270           | ASMOD                       {$$ = gc1(varAsMod);}
1271           | PRIVILEGED                  {$$ = gc1(varPrivileged);}
1272           ;
1273
1274 /*- Tricks to force insertion of leading and closing braces ---------------*/
1275
1276 begin     : error                       {yyerrok; 
1277                                          if (offsideON) goOffside(startColumn);}
1278           ;
1279
1280 end       : '}'                         {$$ = $1;}
1281           | error                       {yyerrok; 
1282                                          if (offsideON && canUnOffside()) {
1283                                              unOffside();
1284                                              /* insert extra token on stack*/
1285                                              push(NIL);
1286                                              pushed(0) = pushed(1);
1287                                              pushed(1) = mkInt(column);
1288                                          }
1289                                          else
1290                                              syntaxError("definition");
1291                                         }
1292           ;
1293
1294 /*-------------------------------------------------------------------------*/
1295
1296 %%
1297
1298 static Cell local gcShadow(n,e)         /* keep parsed fragments on stack  */
1299 Int  n;
1300 Cell e; {
1301     /* If a look ahead token is held then the required stack transformation
1302      * is:
1303      *   pushed: n               1     0          1     0
1304      *           x1  |  ...  |  xn  |  la   ===>  e  |  la
1305      *                                top()            top()
1306      *
1307      * Otherwise, the transformation is:
1308      *   pushed: n-1             0        0
1309      *           x1  |  ...  |  xn  ===>  e
1310      *                         top()     top()
1311      */
1312     if (yychar>=0) {
1313         pushed(n-1) = top();
1314         pushed(n)   = e;
1315     }
1316     else
1317         pushed(n-1) = e;
1318     sp -= (n-1);
1319     return e;
1320 }
1321
1322 static Void local syntaxError(s)        /* report on syntax error          */
1323 String s; {
1324     ERRMSG(row) "Syntax error in %s (unexpected %s)", s, unexpected()
1325     EEND;
1326 }
1327
1328 static String local unexpected() {     /* find name for unexpected token   */
1329     static char buffer[100];
1330     static char *fmt = "%s \"%s\"";
1331     static char *kwd = "keyword";
1332
1333     switch (yychar) {
1334         case 0         : return "end of input";
1335
1336 #define keyword(kw) sprintf(buffer,fmt,kwd,kw); return buffer;
1337         case INFIXL    : keyword("infixl");
1338         case INFIXR    : keyword("infixr");
1339         case INFIXN    : keyword("infix");
1340         case FOREIGN   : keyword("foreign");
1341         case UNSAFE    : keyword("unsafe");
1342         case TINSTANCE : keyword("instance");
1343         case TCLASS    : keyword("class");
1344         case CASEXP    : keyword("case");
1345         case OF        : keyword("of");
1346         case IF        : keyword("if");
1347         case THEN      : keyword("then");
1348         case ELSE      : keyword("else");
1349         case WHERE     : keyword("where");
1350         case TYPE      : keyword("type");
1351         case DATA      : keyword("data");
1352         case TNEWTYPE  : keyword("newtype");
1353         case LET       : keyword("let");
1354         case IN        : keyword("in");
1355         case DERIVING  : keyword("deriving");
1356         case DEFAULT   : keyword("default");
1357         case IMPORT    : keyword("import");
1358         case TMODULE   : keyword("module");
1359           /* AJG: Hugs98/Classic use the keyword forall
1360                   rather than __forall.
1361                   Agree on one or the other
1362           */
1363         case ALL       : keyword("__forall");
1364 #if IPARAM
1365         case DLET      : keyword("dlet");
1366         case WITH      : keyword("with");
1367 #endif
1368 #undef keyword
1369
1370         case ARROW     : return "`->'";
1371         case '='       : return "`='";
1372         case COCO      : return "`::'";
1373         case '-'       : return "`-'";
1374         case '!'       : return "`!'";
1375         case ','       : return "comma";
1376         case '@'       : return "`@'";
1377         case '('       : return "`('";
1378         case ')'       : return "`)'";
1379         case '{'       : return "`{', possibly due to bad layout";
1380         case '}'       : return "`}', possibly due to bad layout";
1381         case '_'       : return "`_'";
1382         case '|'       : return "`|'";
1383         case '.'       : return "`.'";
1384         case ';'       : return "`;', possibly due to bad layout";
1385         case UPTO      : return "`..'";
1386         case '['       : return "`['";
1387         case ']'       : return "`]'";
1388         case FROM      : return "`<-'";
1389         case '\\'      : return "backslash (lambda)";
1390         case '~'       : return "tilde";
1391         case '`'       : return "backquote";
1392 #if TREX
1393         case RECSELID  : sprintf(buffer,"selector \"#%s\"",
1394                                  textToStr(extText(snd(yylval))));
1395                          return buffer;
1396 #endif
1397 #if IPARAM
1398         case IPVARID   : sprintf(buffer,"implicit parameter \"?%s\"",
1399                                  textToStr(textOf(yylval)));
1400                          return buffer;
1401 #endif
1402         case VAROP     :
1403         case VARID     :
1404         case CONOP     :
1405         case CONID     : sprintf(buffer,"symbol \"%s\"",
1406                                  textToStr(textOf(yylval)));
1407                          return buffer;
1408         case QVAROP    :
1409         case QVARID    :
1410         case QCONOP    : 
1411         case QCONID    : sprintf(buffer,"symbol \"%s\"",
1412                                  identToStr(yylval));
1413                          return buffer;
1414         case HIDING    : return "symbol \"hiding\"";
1415         case QUALIFIED : return "symbol \"qualified\"";
1416         case PRIVILEGED : return "symbol \"privileged\"";
1417         case ASMOD     : return "symbol \"as\"";
1418         case NUMLIT    : return "numeric literal";
1419         case CHARLIT   : return "character literal";
1420         case STRINGLIT : return "string literal";
1421         case IMPLIES   : return "`=>'";
1422         default        : return "token";
1423     }
1424 }
1425
1426 static Cell local checkPrec(p)          /* Check for valid precedence value*/
1427 Cell p; {
1428     if (!isInt(p) || intOf(p)<MIN_PREC || intOf(p)>MAX_PREC) {
1429         ERRMSG(row) "Precedence value must be an integer in the range [%d..%d]",
1430                     MIN_PREC, MAX_PREC
1431         EEND;
1432     }
1433     return p;
1434 }
1435
1436 static Cell local buildTuple(tup)       /* build tuple (x1,...,xn) from    */
1437 List tup; {                             /* list [xn,...,x1]                */
1438     Int  n = 0;
1439     Cell t = tup;
1440     Cell x;
1441
1442     do {                                /*    .                    .       */
1443         x      = fst(t);                /*   / \                  / \      */
1444         fst(t) = snd(t);                /*  xn  .                .   xn    */
1445         snd(t) = x;                     /*       .    ===>      .          */
1446         x      = t;                     /*        .            .           */
1447         t      = fun(x);                /*         .          .            */
1448         n++;                            /*        / \        / \           */
1449     } while (nonNull(t));               /*       x1  NIL   (n)  x1         */
1450     fst(x) = mkTuple(n);
1451     return tup;
1452 }
1453
1454 static List local checkCtxt(con)     /* validate context                */
1455 Type con; {
1456     mapOver(checkPred, con);
1457     return con;
1458 }
1459
1460 static Cell local checkPred(c)          /* check that type expr is a valid */
1461 Cell c; {                               /* constraint                      */
1462     Cell cn = getHead(c);
1463 #if TREX
1464     if (isExt(cn) && argCount==1)
1465         return c;
1466 #endif
1467 #if IPARAM
1468     if (isIP(cn))
1469         return c;
1470 #endif
1471     if (!isQCon(cn) /*|| argCount==0*/)
1472         syntaxError("class expression");
1473     return c;
1474 }
1475
1476 static Pair local checkDo(dqs)          /* convert reversed list of dquals */
1477 List dqs; {                             /* to an (expr,quals) pair         */
1478     if (isNull(dqs) || whatIs(hd(dqs))!=DOQUAL) {
1479         ERRMSG(row) "Last generator in do {...} must be an expression"
1480         EEND;
1481     }
1482     fst(dqs) = snd(fst(dqs));           /* put expression in fst of pair   */
1483     snd(dqs) = rev(snd(dqs));           /* & reversed list of quals in snd */
1484     return dqs;
1485 }
1486
1487 static Cell local checkTyLhs(c)         /* check that lhs is of the form   */
1488 Cell c; {                               /* T a1 ... a                      */
1489     Cell tlhs = c;
1490     while (isAp(tlhs) && whatIs(arg(tlhs))==VARIDCELL) {
1491         tlhs = fun(tlhs);
1492     }
1493     if (whatIs(tlhs)!=CONIDCELL) {
1494         ERRMSG(row) "Illegal left hand side in datatype definition"
1495         EEND;
1496     }
1497     return c;
1498 }
1499
1500
1501 #if !TREX
1502 static Void local noTREX(where)
1503 String where; {
1504     ERRMSG(row) "Attempt to use TREX records while parsing %s.\n", where ETHEN
1505     ERRTEXT     "(TREX is disabled in this build of Hugs)"
1506     EEND;
1507 }
1508 #endif
1509 #if !IPARAM
1510 static Void local noIP(where)
1511 String where; {
1512     ERRMSG(row) "Attempt to use Implicit Parameters while parsing %s.\n", where ETHEN
1513     ERRTEXT     "(Implicit Parameters are disabled in this build of Hugs)"
1514     EEND;
1515 }
1516 #endif
1517
1518 /*-------------------------------------------------------------------------*/