[project @ 2000-01-05 18:05:33 by sewardj]
[ghc-hetmet.git] / ghc / interpreter / parser.y
index 0ca0fa6..783a669 100644 (file)
@@ -12,8 +12,8 @@
  * included in the distribution.
  *
  * $RCSfile: parser.y,v $
- * $Revision: 1.15 $
- * $Date: 1999/11/29 18:53:14 $
+ * $Revision: 1.21 $
+ * $Date: 2000/01/05 18:05:34 $
  * ------------------------------------------------------------------------*/
 
 %{
@@ -25,7 +25,6 @@
 #define fixdecl(l,ops,a,p)       ap(FIXDECL,\
                                     triple(l,ops,mkInt(mkSyntax(a,intOf(p)))))
 #define grded(gs)                ap(GUARDED,gs)
-#define bang(t)                  ap(BANG,t)
 #define only(t)                  ap(ONLY,t)
 #define letrec(bs,e)             (nonNull(bs) ? ap(LETREC,pair(bs,e)) : e)
 #define qualify(ps,t)            (nonNull(ps) ? ap(QUAL,pair(ps,t)) : t)
@@ -98,6 +97,7 @@ static Void   local noIP       Args((String));
 %token TMODULE    IMPORT     HIDING     QUALIFIED  ASMOD
 %token EXPORT     UUEXPORT   INTERFACE  REQUIRES   UNSAFE     
 %token INSTIMPORT DYNAMIC    CCALL      STDKALL
+%token UTL        UTR        UUUSAGE
 
 %%
 /*- Top level script/module structure -------------------------------------*/
@@ -120,75 +120,77 @@ start     : EXPR exp wherePart          {inputExpr = letrec($3,$2); sp-=2;}
  */
 
 /*- Top-level interface files -----------------------------*/
-iface     : INTERFACE ifName NUMLIT checkVersion WHERE ifDecls 
-                                        {$$ = gc6(NIL); }
+iface     : INTERFACE ifCon NUMLIT ifOrphans ifCheckVersion WHERE ifTopDecls 
+                                        {$$ = gc7(ap(I_INTERFACE, 
+                                                     zpair($2,$7))); }
           | INTERFACE error             {syntaxError("interface file");}
           ;
-ifDecls:                                {$$=gc0(NIL);}
-          | ifDecl ';' ifDecls          {$$=gc3(cons($1,$3));}
-          ;
-varid_or_conid
-          : VARID                       { $$=gc1($1); }
-          | CONID                       { $$=gc1($1); }
-          ;
-opt_bang  : '!'                         {$$=gc1(NIL);}
-          |                             {$$=gc0(NIL);}
-          ;
-ifName    : CONID                       {openGHCIface(textOf($1)); 
-                                         $$ = gc1(NIL);}
-checkVersion
-          : NUMLIT                      {$$ = gc1(NIL); }
+
+ifTopDecls:                             {$$=gc0(NIL);}
+          | ifTopDecl ';' ifTopDecls    {$$=gc3(cons($1,$3));}
           ;
-ifDecl    
-          : IMPORT CONID NUMLIT opt_bang COCO version_list_junk
-                                        { addGHCImports(intOf($3),textOf($2),
-                                                       $6);
-                                          $$ = gc6(NIL); 
-                                        }
 
-          | INSTIMPORT CONID            {$$=gc2(NIL);}
-
-          | UUEXPORT CONID ifEntities   { addGHCExports($2,$3);
-                                          $$=gc3(NIL);}
-
-          | NUMLIT INFIXL optDigit varid_or_conid   
-                                        {$$ = gc4(fixdecl($2,singleton($4),
-                                                          LEFT_ASS,$3)); }
-          | NUMLIT INFIXR optDigit varid_or_conid   
-                                        {$$ = gc4(fixdecl($2,singleton($4),
-                                                          RIGHT_ASS,$3)); }
-          | NUMLIT INFIXN optDigit varid_or_conid   
-                                        {$$ = gc4(fixdecl($2,singleton($4),
-                                                          NON_ASS,$3)); }
-
-          | TINSTANCE ifCtxInst ifInstHd '=' ifVar
-                                        { addGHCInstance(intOf($1),$2,$3,
-                                          textOf($5)); 
-                                          $$ = gc5(NIL); }
+ifTopDecl    
+          : IMPORT CONID NUMLIT ifOrphans ifOptCOCO ifVersionList
+                                        {$$=gc6(ap(I_IMPORT,zpair($2,$6))); }
+
+          | INSTIMPORT CONID            {$$=gc2(ap(I_INSTIMPORT,NIL));}
+
+          | UUEXPORT CONID ifEntities   {$$=gc3(ap(I_EXPORT,zpair($2,$3)));}
+
+          | NUMLIT INFIXL optDigit ifVarCon
+                                        {$$=gc4(ap(I_FIXDECL,
+                                            ztriple($3,mkInt(LEFT_ASS),$4)));}
+          | NUMLIT INFIXR optDigit ifVarCon
+                                        {$$=gc4(ap(I_FIXDECL,
+                                            ztriple($3,mkInt(RIGHT_ASS),$4)));}
+          | NUMLIT INFIXN optDigit ifVarCon
+                                        {$$=gc4(ap(I_FIXDECL,
+                                            ztriple($3,mkInt(NON_ASS),$4)));}
+
+          | TINSTANCE ifCtxInst ifInstHdL '=' ifVar
+                                        {$$=gc5(ap(I_INSTANCE,
+                                                   z5ble($1,$2,$3,$5,NIL)));}
+
           | NUMLIT TYPE ifCon ifKindedTyvarL '=' ifType
-                                        { addGHCSynonym(intOf($2),$3,$4,$6);
-                                          $$ = gc6(NIL); }
+                                        {$$=gc6(ap(I_TYPE,
+                                                   z4ble($2,$3,$4,$6)));}
 
           | NUMLIT DATA ifCtxDecl ifConData ifKindedTyvarL ifConstrs
-                                        { addGHCDataDecl(intOf($2),
-                                                         $3,$4,$5,$6);
-                                          $$ = gc6(NIL); }
+                                        {$$=gc6(ap(I_DATA,
+                                                   z5ble($2,$3,$4,$5,$6)));}
 
           | NUMLIT TNEWTYPE ifCtxDecl ifConData ifKindedTyvarL ifNewTypeConstr
-                                        { addGHCNewType(intOf($2),
-                                                        $3,$4,$5,$6);
-                                          $$ = gc6(NIL); }
-          | NUMLIT TCLASS ifCtxDecl ifCon ifTyvar ifCmeths
-                                        { addGHCClass(intOf($2),$3,$4,$5,$6);
-                                          $$ = gc6(NIL); }
+                                        {$$=gc6(ap(I_NEWTYPE,
+                                                   z5ble($2,$3,$4,$5,$6)));}
+
+          | NUMLIT TCLASS ifCtxDecl ifCon ifKindedTyvar ifCmeths
+                                        {$$=gc6(ap(I_CLASS,
+                                                   z5ble($2,$3,$4,
+                                                         singleton($5),$6)));}
+
           | NUMLIT ifVar COCO ifType
-                                        { addGHCVar(intOf($3),textOf($2),$4);
-                                          $$ = gc4(NIL); }
+                                        {$$=gc4(ap(I_VALUE,
+                                                  ztriple($3,$2,$4)));}
+
           | error                       { syntaxError(
                                              "interface declaration"); }
           ;
 
 
+/*- Top-level misc interface stuff ------------------------*/
+ifOrphans : '!'                         {$$=gc1(NIL);}
+          |                             {$$=gc0(NIL);}
+          ;
+ifOptCOCO : COCO                        {$$=gc1(NIL);}
+          |                             {$$=gc0(NIL);}
+          ;
+ifCheckVersion
+          : NUMLIT                      {$$ = gc1(NIL); }
+          ;
+
+
+
 /*- Interface variable and constructor ids ----------------*/
 ifTyvar   : VARID                       {$$ = $1;}
           ;
@@ -196,6 +198,11 @@ ifVar     : VARID                       {$$ = gc1($1);}
           ;
 ifCon     : CONID                       {$$ = gc1($1);}
           ;
+
+ifVarCon  : VARID                       {$$ = gc1($1);}
+          | CONID                       {$$ = gc1($1);}
+          ;
+
 ifQCon    : CONID                       {$$ = gc1($1);}
           | QCONID                      {$$ = gc1($1);}
           ;
@@ -216,86 +223,101 @@ ifQTCName : ifTCName                    { $$ = gc1($1); }
 
 
 /*- Interface contexts ------------------------------------*/
-ifCtxInst /* __forall [a b] {M.C1 a, M.C2 b} =>  */
-          /* :: [(QConId, VarId)]                */
-          : ALL ifForall ifCtxDecl      {$$=gc3($3);}
-          | ALL ifForall IMPLIES        {$$=gc3(NIL);}
+ifCtxInst /* __forall [a b] =>     :: [((VarId,Kind))] */
+          : ALL ifForall IMPLIES        {$$=gc3($2);}
           |                             {$$=gc0(NIL);}
           ;
-ifInstHd  /* { Class aType }    :: (ConId, Type) */
-          : '{' ifCon ifAType '}'       {$$=gc4(pair($2,$3));}
+ifInstHd /* { Class aType }    :: ((ConId, Type)) */
+          : '{' ifQCon ifAType '}'      {$$=gc4(ap(DICTAP,
+                                                zpair($2,$3)));}
           ;
 
-ifCtxDecl /* {M.C1 a, C2 b} :: [(QConId, VarId)] */ 
-          :                             { $$ = gc0(NIL); }
-          | '{' ifCtxDeclL '}' IMPLIES  { $$ = gc4($2);  }
+ifInstHdL /* { C a1 } -> { C2 a2 } -> ... -> { Cn an } :: Type */
+          : ifInstHd ARROW ifInstHdL    {$$=gc3(ap($1,$3));}
+          | ifInstHd                    {$$=gc1($1);}
+          ;
+
+ifCtxDecl /* {M.C1 a, C2 b} =>  :: [(QConId, VarId)] */ 
+          : ifCtxDeclT IMPLIES          { $$ = gc2($1);  }
+          |                             { $$ = gc0(NIL); }
           ;                                    
 ifCtxDeclT /* {M.C1 a, C2 b} :: [(QConId, VarId)] */ 
           :                             { $$ = gc0(NIL); }
           | '{' ifCtxDeclL '}'          { $$ = gc3($2);  }
           ;                                    
+
 ifCtxDeclL /* M.C1 a, C2 b :: [(QConId, VarId)] */
           : ifCtxDeclLE ',' ifCtxDeclL  {$$=gc3(cons($1,$3));}
           | ifCtxDeclLE                 {$$=gc1(cons($1,NIL));}
           |                             {$$=gc0(NIL);}
           ;
 ifCtxDeclLE /* M.C1 a   :: (QConId,VarId) */
-          : ifQCon ifTyvar              {$$=gc2(pair($1,$2));}
+          : ifQCon ifTyvar              {$$=gc2(zpair($1,$2));}
           ;
 
 
 /*- Interface data declarations - constructor lists -------*/
-ifConstrs /* = Con1 | ... | ConN  :: [(ConId,[(Type,Text)],NIL)] */
+/* The (Type,VarId,Int) are (field type, name (or NIL), strictness).
+   Strictness is a number: mkInt(0) indicates lazy, mkInt(1)
+   indicates a strict field (!type) as in standard H98, and 
+   mkInt(2) indicates unpacked -- a GHC extension.
+*/
+
+ifConstrs /* = Con1 | ... | ConN  :: [((ConId,[((Type,VarId,Int))]))] */
           :                             {$$ = gc0(NIL);}
           | '=' ifConstrL               {$$ = gc2($2);}
           ;
-ifConstrL /* [(ConId,[(Type,Text)],NIL)] */
+ifConstrL /* [((ConId,[((Type,VarId,Int))]))] */
           : ifConstr                    {$$ = gc1(singleton($1));}
           | ifConstr '|' ifConstrL      {$$ = gc3(cons($1,$3));}
           ;
-ifConstr /* (ConId,[(Type,Text)],NIL) */
-          : ifConData ifDataAnonFieldL  {$$ = gc2(triple($1,$2,NIL));}
+ifConstr /* ((ConId,[((Type,VarId,Int))])) */
+          : ifConData ifDataAnonFieldL  {$$ = gc2(zpair($1,$2));}
           | ifConData '{' ifDataNamedFieldL '}' 
-                                        {$$ = gc4(triple($1,$3,NIL));}
+                                        {$$ = gc4(zpair($1,$3));}
           ;
-ifDataAnonFieldL /* [(Type,Text)] */
+ifDataAnonFieldL /* [((Type,VarId,Int))] */
           :                             {$$=gc0(NIL);}
           | ifDataAnonField ifDataAnonFieldL
                                         {$$=gc2(cons($1,$2));}
           ;
-ifDataNamedFieldL /* [(Type,Text)] */
+ifDataNamedFieldL /* [((Type,VarId,Int))] */
           :                             {$$=gc0(NIL);}
           | ifDataNamedField            {$$=gc1(cons($1,NIL));}
           | ifDataNamedField ',' ifDataNamedFieldL 
                                         {$$=gc3(cons($1,$3));}
           ;
-ifDataAnonField /* (Type,Text) */
-          : ifAType                     {$$=gc1(pair($1,NIL));}
+ifDataAnonField /* ((Type,VarId,Int)) */
+          : ifAType                     {$$=gc1(ztriple($1,NIL,mkInt(0)));}
+          | '!' ifAType                 {$$=gc2(ztriple($2,NIL,mkInt(1)));}
+          | '!' '!' ifAType             {$$=gc3(ztriple($3,NIL,mkInt(2)));}
           ;
-ifDataNamedField  /* (Type,Text) */
-          : VARID COCO ifAType          {$$=gc3(pair($3,$1));}
+ifDataNamedField  /* ((Type,VarId,Int)) */
+          : ifVar COCO ifAType          {$$=gc3(ztriple($3,$1,mkInt(0)));}
+          | ifVar COCO '!' ifAType      {$$=gc4(ztriple($4,$1,mkInt(1)));}
+          | ifVar COCO '!' '!' ifAType  {$$=gc5(ztriple($5,$1,mkInt(2)));}
           ;
 
 
 /*- Interface class declarations - methods ----------------*/
-ifCmeths /* [(VarId,Type)] */
+ifCmeths /* [((VarId,Type))] */
           :                             { $$ = gc0(NIL); }
           | WHERE '{' ifCmethL '}'      { $$ = gc4($3); }
           ;
-ifCmethL /* [(VarId,Type)] */
+ifCmethL /* [((VarId,Type))] */
           : ifCmeth                     { $$ = gc1(singleton($1)); }
           | ifCmeth ';' ifCmethL        { $$ = gc3(cons($1,$3));    }
           ;
-ifCmeth /* (VarId,Type) */
-          : ifVar     COCO ifType       { $$ = gc3(pair($1,$3)); }
-          | ifVar '=' COCO ifType       { $$ = gc4(pair($1,$4)); } 
+ifCmeth /* ((VarId,Type)) */
+          : ifVar     COCO ifType       { $$ = gc3(zpair($1,$3)); }
+          | ifVar '=' COCO ifType       { $$ = gc4(zpair($1,$4)); } 
                                               /* has default method */
           ;
 
 
 /*- Interface newtype declararions ------------------------*/
-ifNewTypeConstr /* (ConId,Type) */
-          : '=' ifCon ifAType           { $$ = gc3(pair($2,$3)); }
+ifNewTypeConstr /* ((ConId,Type)) */
+          : '=' ifCon ifAType           { $$ = gc3(zpair($2,$3)); }
           ;
 
 
@@ -308,37 +330,54 @@ ifType    : ALL ifForall ifCtxDeclT IMPLIES ifType
           | ifBType ARROW ifType        { $$ = gc3(fn($1,$3)); }
           | ifBType                     { $$ = gc1($1); }
           ;                                    
-ifForall /* [(VarId,Kind)] */
+ifForall  /* [((VarId,Kind))] */
           : '[' ifKindedTyvarL ']'      { $$ = gc3($2); }
-          ;                                    
-ifTypes2  : ifType ',' ifType           { $$ = gc3(doubleton($1,$3)); }
-          | ifType ',' ifTypes2         { $$ = gc3(cons($1,$3));      }
           ;
+
+ifTypeL2  /* [Type], 2 or more */
+          : ifType ',' ifType           { $$ = gc3(doubleton($1,$3)); }
+          | ifType ',' ifTypeL2         { $$ = gc3(cons($1,$3));      }
+          ;
+
+ifTypeL   /* [Type], 0 or more */
+          : ifType ',' ifTypeL          { $$ = gc3(cons($1,$3)); }
+          | ifType                      { $$ = gc1(singleton($1)); }
+          |                             { $$ = gc0(NIL); }
+          ;
+
 ifBType   : ifAType                     { $$ = gc1($1);        } 
           | ifBType ifAType             { $$ = gc2(ap($1,$2)); }
+          | UUUSAGE ifUsage ifAType     { $$ = gc3($3); }
           ;
+
 ifAType   : ifQTCName                   { $$ = gc1($1); }
           | ifTyvar                     { $$ = gc1($1); }
           | '(' ')'                     { $$ = gc2(typeUnit); }
-          | '(' ifTypes2 ')'            { $$ = gc3(buildTuple($2)); }
-          | '[' ifType ']'              { $$ = gc3(ap(typeList,$2));}
-          | '{' ifQTCName ifATypes '}'  { $$ = gc4(ap(DICTAP,
+          | '(' ifTypeL2 ')'            { $$ = gc3(buildTuple(reverse($2))); }
+          | '[' ifType ']'              { $$ = gc3(ap(mkCon(tycon(typeList).text),
+                                                      $2));}
+          | '{' ifQTCName ifAType '}'   { $$ = gc4(ap(DICTAP,
                                                       pair($2,$3))); }
           | '(' ifType ')'              { $$ = gc3($2); }
+          | UTL ifTypeL UTR             { $$ = gc3(ap(UNBOXEDTUP,$2)); }
           ;
-ifATypes  :                             { $$ = gc0(NIL);         }
-          | ifAType ifATypes            { $$ = gc2(cons($1,$2)); }
+
+
+/*- KW's usage stuff --------------------------------------*/
+ifUsage   : '-'                         { $$ = gc1(NIL); }
+          | '!'                         { $$ = gc1(NIL); }
+          | ifVar                       { $$ = gc1(NIL); }
           ;
 
 
 /*- Interface kinds ---------------------------------------*/
-ifKindedTyvarL /* [(VarId,Kind)] */
+ifKindedTyvarL /* [((VarId,Kind))] */
           :                              { $$ = gc0(NIL);         }
           | ifKindedTyvar ifKindedTyvarL { $$ = gc2(cons($1,$2)); }
           ;
-ifKindedTyvar /* (VarId,Kind) */
-          : ifTyvar                     { $$ = gc1(pair($1,STAR)); }
-          | ifTyvar COCO ifAKind        { $$ = gc3(pair($1,$3));   }
+ifKindedTyvar /* ((VarId,Kind)) */
+          : ifTyvar                     { $$ = gc1(zpair($1,STAR)); }
+          | ifTyvar COCO ifAKind        { $$ = gc3(zpair($1,$3));   }
           ; 
 ifKind    : ifAKind                     { $$ = gc1($1);        }
           | ifAKind ARROW ifKind        { $$ = gc3(fn($1,$3)); }
@@ -356,7 +395,7 @@ ifEntities
           ;
 ifEntity
           : ifEntityOcc                 {$$=gc1($1);}
-          | ifEntityOcc ifStuffInside   {$$=gc2(pair($1,$2));}
+          | ifEntityOcc ifStuffInside   {$$=gc2(zpair($1,$2));}
           ;
 ifEntityOcc
           : ifVar                       { $$ = gc1($1); }
@@ -373,15 +412,15 @@ ifValOccs
           | ifVar ifValOccs             { $$ = gc2(cons($1,$2));   }
           | ifCon ifValOccs             { $$ = gc2(cons($1,$2));   }
           ;
-version_list_junk
-          :                                {$$=gc0(NIL);}
-          | VARID NUMLIT version_list_junk {$$=gc3(cons($1,$3));} 
-          | CONID NUMLIT version_list_junk {$$=gc3(cons($1,$3));}
+
+ifVersionList
+          :                             {$$=gc0(NIL);}
+          | VARID NUMLIT ifVersionList  {$$=gc3(cons($1,$3));} 
+          | CONID NUMLIT ifVersionList  {$$=gc3(cons($1,$3));}
           ;
 
 
 /*- Haskell module header/import parsing: -----------------------------------
-
  * Syntax for Haskell modules (module headers and imports) is parsed but
  * most of it is ignored.  However, module names in import declarations
  * are used, of course, if import chasing is turned on.