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