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