extern list reverse_list();
extern tree root;
-/* For FN, PREVPATT and SAMEFN macros */
+/* For FN, SAMEFN macros */
extern qid fns[];
extern BOOLEAN samefn[];
-extern tree prevpatt[];
extern short icontexts;
/* Line Numbers */
char *ineg PROTO((char *));
long source_version = 0;
+BOOLEAN pat_check=TRUE;
-BOOLEAN inpat;
%}
%union {
ttype uttype;
constr uconstr;
binding ubinding;
- pbinding upbinding;
+ match umatch;
+ gdexp ugdexp;
+ grhsb ugrhsb;
entidt uentid;
id uid;
qid uqid;
%token OCURLY CCURLY VCCURLY
%token COMMA SEMI OBRACK CBRACK
-%token WILDCARD BQUOTE OPAREN CPAREN
+%token BQUOTE OPAREN CPAREN
+%token OUNBOXPAREN CUNBOXPAREN
/**********************************************************************
%token SCC
%token CCALL CCALL_GC CASM CASM_GC
+%token DOT FORALL
+%token EXPORT UNSAFE STDCALL C_CALL LABEL
+%token PASCAL FASTCALL FOREIGN DYNAMIC
/**********************************************************************
* *
**********************************************************************/
%token INTERFACE_UPRAGMA SPECIALISE_UPRAGMA
-%token INLINE_UPRAGMA MAGIC_UNFOLDING_UPRAGMA
+%token INLINE_UPRAGMA NOINLINE_UPRAGMA MAGIC_UNFOLDING_UPRAGMA
%token END_UPRAGMA
%token SOURCE_UPRAGMA
**********************************************************************/
-%type <ulist> caserest alts alt quals
+%type <ulist> caserest alts quals
dorest stmts stmt
rbinds rbinds1 rpats rpats1 list_exps list_rest
qvarsk qvars_list
- constrs constr1 fields
- types atypes batypes
+ constrs fields conargatypes
+ tautypes atypes
types_and_maybe_ids
- pats simple_context simple_context_list
+ pats simple_context simple_context_list
export_list enames
import_list inames
impdecls maybeimpdecls impdecl
- maybefixes fixes fix ops
dtyclses dtycls_list
- gdrhs gdpat valrhs
- lampats cexps gd
+ gdrhs gdpat
+ lampats cexps gd texps
+ tyvars1 constr_context forall
-%type <umaybe> maybeexports impspec deriving
+%type <umatch> alt
+
+%type <ugrhsb> valrhs altrhs
+
+%type <umaybe> maybeexports impspec deriving
+ ext_name opt_sig opt_asig
%type <uliteral> lit_constant
-%type <utree> exp oexp dexp kexp fexp aexp rbind texps
+%type <utree> exp oexp dexp kexp fexp aexp rbind
expL oexpL kexpL expLno oexpLno dexpLno kexpLno
- vallhs funlhs qual leftexp
- pat cpat bpat apat apatc conpat rpat
- patk bpatk apatck conpatk
+ funlhs funlhs1 funlhs2 funlhs3 qual leftexp
+ pat dpat cpat bpat apat apatc conpat rpat
+ patk bpatk apatck conpatk
%type <uid> MINUS PLUS DARROW AS LAZY
VARID CONID VARSYM CONSYM
var con varop conop op
vark varid varsym varsym_nominus
- tycon modid ccallid
+ tycon modid ccallid tyvar
+ varid_noforall
%type <uqid> QVARID QCONID QVARSYM QCONSYM
qvarid qconid qvarsym qconsym
qvar qcon qvarop qconop qop
qvark qconk qtycon qtycls
gcon gconk gtycon itycon qop1 qvarop1
- ename iname
-
-%type <ubinding> topdecl topdecls letdecls
- typed datad newtd classd instd defaultd
- decl decls valdef instdef instdefs
- maybe_where cbody rinst type_and_maybe_id
+ ename iname
-%type <upbinding> valrhs1 altrest
+%type <ubinding> topdecl topdecls topdecls1 letdecls
+ typed datad newtd classd instd defaultd foreignd
+ decl decls decls1 fixdecl fix_op fix_ops valdef
+ maybe_where type_and_maybe_id
-%type <uttype> ctype sigtype sigarrowtype type atype bigatype btype
- bbtype batype bxtype wierd_atype
- simple_con_app simple_con_app1 tyvar contype inst_type
+%type <uttype> polytype
+ conargatype conapptype
+ tautype
+ apptype
+ atype polyatype
+ simple_con_app simple_con_app1 inst_type
-%type <uconstr> constr constr_after_context field
+%type <uconstr> constr constr_after_context field constr1
%type <ustring> FLOAT INTEGER INTPRIM
FLOATPRIM DOUBLEPRIM CLITLIT
%type <uentid> export import
%type <ulong> commas importkey get_line_no
+ unsafe_flag callconv
/**********************************************************************
* *
body
;
-body : ocurly { setstartlineno(); } interface_pragma orestm
- | vocurly interface_pragma vrestm
+body : ocurly { setstartlineno(); } main_body ccurly
+ | vocurly main_body vccurly
;
-interface_pragma : /* empty */
- | INTERFACE_UPRAGMA INTEGER END_UPRAGMA SEMI
- {
- source_version = atoi($2);
- }
- ;
-
-orestm : maybeimpdecls maybefixes topdecls ccurly
+main_body : interface_pragma maybeimpdecls topdecls
{
- root = mkhmodule(the_module_name,$1,module_exports,
- $2,$3,source_version,modulelineno);
+ root = mkhmodule(the_module_name, $2, module_exports,
+ $3, source_version,modulelineno);
}
- | impdecls ccurly
+ | interface_pragma impdecls
{
- root = mkhmodule(the_module_name,$1,module_exports,
- Lnil,mknullbind(),source_version,modulelineno);
+ root = mkhmodule(the_module_name, $2, module_exports,
+ mknullbind(), source_version, modulelineno);
}
-vrestm : maybeimpdecls maybefixes topdecls vccurly
- {
- root = mkhmodule(the_module_name,$1,module_exports,
- $2,$3,source_version,modulelineno);
- }
- | impdecls vccurly
+interface_pragma : /* empty */
+ | INTERFACE_UPRAGMA INTEGER END_UPRAGMA SEMI
{
- root = mkhmodule(the_module_name,$1,module_exports,
- Lnil,mknullbind(),source_version,modulelineno);
+ source_version = atoi($2);
}
+ ;
maybeexports : /* empty */ { $$ = mknothing(); }
| OPAREN export_list CPAREN { $$ = mkjust($2); }
| enames COMMA ename { $$ = lapp($1,$3); }
;
ename : qvar
- | qcon
+ | gcon
;
{ $$ = lsing(mkimport($3,1,mknothing(),$4,$1,startlineno)); }
| importkey QUALIFIED modid AS modid impspec
{ $$ = lsing(mkimport($3,1,mkjust($5),$6,$1,startlineno)); }
+ | importkey modid AS modid impspec
+ { $$ = lsing(mkimport($3,1,mkjust($4),$5,$1,startlineno)); }
;
impspec : /* empty */ { $$ = mknothing(); }
- | OPAREN CPAREN { $$ = mkjust(mkleft(Lnil)); }
- | OPAREN import_list CPAREN { $$ = mkjust(mkleft($2)); }
- | OPAREN import_list COMMA CPAREN { $$ = mkjust(mkleft($2)); }
- | HIDING OPAREN import_list CPAREN { $$ = mkjust(mkright($3)); }
- | HIDING OPAREN import_list COMMA CPAREN { $$ = mkjust(mkright($3)); }
+ | OPAREN CPAREN { $$ = mkjust(mkleft(Lnil)); }
+ | OPAREN import_list CPAREN { $$ = mkjust(mkleft($2)); }
+ | OPAREN import_list COMMA CPAREN { $$ = mkjust(mkleft($2)); }
+ | HIDING OPAREN CPAREN { $$ = mkjust(mkright(Lnil)); }
+ | HIDING OPAREN import_list CPAREN { $$ = mkjust(mkright($3)); }
+ | HIDING OPAREN import_list COMMA CPAREN { $$ = mkjust(mkright($3)); }
;
import_list:
* *
**********************************************************************/
-maybefixes: /* empty */ { $$ = Lnil; }
- | fixes SEMI { $$ = $1; }
- ;
-
-fixes : fix { $$ = $1; }
- | fixes SEMI fix { $$ = lconc($1,$3); }
- ;
-
-fix : INFIXL INTEGER { Precedence = checkfixity($2); Fixity = INFIXL; }
- ops { $$ = $4; }
- | INFIXR INTEGER { Precedence = checkfixity($2); Fixity = INFIXR; }
- ops { $$ = $4; }
- | INFIX INTEGER { Precedence = checkfixity($2); Fixity = INFIX; }
- ops { $$ = $4; }
- | INFIXL { Fixity = INFIXL; Precedence = 9; }
- ops { $$ = $3; }
- | INFIXR { Fixity = INFIXR; Precedence = 9; }
- ops { $$ = $3; }
- | INFIX { Fixity = INFIX; Precedence = 9; }
- ops { $$ = $3; }
- ;
-
-ops : op { $$ = lsing(mkfixop(mknoqual($1),infixint(Fixity),Precedence,startlineno)); }
- | ops COMMA op { $$ = lapp($1,mkfixop(mknoqual($3),infixint(Fixity),Precedence,startlineno)); }
- ;
+topdecls: topdecls1 opt_semi { $$ = $1; }
-topdecls: topdecl
- | topdecls SEMI topdecl
+topdecls1: topdecl
+ | topdecls1 SEMI topdecl
{
if($1 != NULL)
if($3 != NULL)
| classd { $$ = $1; FN = NULL; SAMEFN = 0; }
| instd { $$ = $1; FN = NULL; SAMEFN = 0; }
| defaultd { $$ = $1; FN = NULL; SAMEFN = 0; }
+ | foreignd { $$ = $1; FN = NULL; SAMEFN = 0; }
| decl { $$ = $1; }
;
-typed : typekey simple_con_app EQUAL type { $$ = mknbind($2,$4,startlineno); }
+typed : typekey simple_con_app EQUAL tautype { $$ = mknbind($2,$4,startlineno); }
;
;
newtd : newtypekey simple_con_app EQUAL constr1 deriving
- { $$ = mkntbind(Lnil,$2,$4,$5,startlineno); }
+ { $$ = mkntbind(Lnil,$2,lsing($4),$5,startlineno); }
| newtypekey simple_context DARROW simple_con_app EQUAL constr1 deriving
- { $$ = mkntbind($2,$4,$6,$7,startlineno); }
+ { $$ = mkntbind($2,$4,lsing($6),$7,startlineno); }
;
deriving: /* empty */ { $$ = mknothing(); }
| DERIVING dtyclses { $$ = mkjust($2); }
;
-classd : classkey simple_context DARROW simple_con_app1 cbody
- { $$ = mkcbind($2,$4,$5,startlineno); }
- | classkey simple_con_app1 cbody
- { $$ = mkcbind(Lnil,$2,$3,startlineno); }
- ;
-
-cbody : /* empty */ { $$ = mknullbind(); }
- | WHERE ocurly decls ccurly { checkorder($3); $$ = $3; }
- | WHERE vocurly decls vccurly { checkorder($3); $$ = $3; }
+classd : classkey apptype DARROW simple_con_app1 maybe_where
+ /* Context can now be more than simple_context */
+ { $$ = mkcbind(type2context($2),$4,$5,startlineno); }
+ | classkey apptype maybe_where
+ /* We have to say apptype rather than simple_con_app1, else
+ we get reduce/reduce errs */
+ { check_class_decl_head($2);
+ $$ = mkcbind(Lnil,$2,$3,startlineno); }
;
-instd : instkey inst_type rinst { $$ = mkibind($2,$3,startlineno); }
+instd : instkey inst_type maybe_where { $$ = mkibind($2,$3,startlineno); }
;
-/* Compare ctype */
-inst_type : type DARROW type { is_context_format( $3, 0 ); /* Check the instance head */
- $$ = mkcontext(type2context($1),$3); }
- | type { is_context_format( $1, 0 ); /* Check the instance head */
+/* Compare polytype */
+/* [July 98: first production was tautype DARROW tautype, but I can't see why.] */
+inst_type : apptype DARROW apptype { is_context_format( $3, 0 ); /* Check the instance head */
+ $$ = mkforall(Lnil,type2context($1),$3); }
+ | apptype { is_context_format( $1, 0 ); /* Check the instance head */
$$ = $1; }
;
-rinst : /* empty */ { $$ = mknullbind(); }
- | WHERE ocurly instdefs ccurly { $$ = $3; }
- | WHERE vocurly instdefs vccurly { $$ = $3; }
+defaultd: defaultkey OPAREN tautypes CPAREN { $$ = mkdbind($3,startlineno); }
+ | defaultkey OPAREN CPAREN { $$ = mkdbind(Lnil,startlineno); }
;
-defaultd: defaultkey OPAREN types CPAREN { $$ = mkdbind($3,startlineno); }
- | defaultkey OPAREN CPAREN { $$ = mkdbind(Lnil,startlineno); }
+/* FFI primitive declarations - GHC/Hugs specific */
+foreignd: foreignkey IMPORT callconv ext_name unsafe_flag qvarid DCOLON tautype
+ { $$ = mkfobind($6,$8,$4,$5,$3,FOREIGN_IMPORT,startlineno); }
+ | foreignkey EXPORT callconv ext_name qvarid DCOLON tautype
+ { $$ = mkfobind($5,$7,$4,0,$3,FOREIGN_EXPORT,startlineno); }
+ | foreignkey LABEL ext_name qvarid DCOLON tautype
+ { $$ = mkfobind($4,$6,$3,0,-1,FOREIGN_LABEL,startlineno); }
;
-decls : decl
- | decls SEMI decl
+callconv: STDCALL { $$ = CALLCONV_STDCALL; }
+ | C_CALL { $$ = CALLCONV_CCALL; }
+ | PASCAL { $$ = CALLCONV_PASCAL; }
+ | FASTCALL { $$ = CALLCONV_FASTCALL; }
+/* If you leave out the specification of a calling convention, you'll (probably) get C's. */
+ | /*empty*/ { $$ = CALLCONV_NONE; }
+ ;
+
+ext_name: STRING { $$ = mkjust(lsing($1)); }
+ | STRING STRING { $$ = mkjust(mklcons ($1,lsing($2))); }
+ | DYNAMIC { $$ = mknothing(); }
+
+unsafe_flag: UNSAFE { $$ = 1; }
+ | /*empty*/ { $$ = 0; }
+ ;
+
+decls : decls1 opt_semi { $$ = $1; }
+
+decls1 : decl
+ | decls1 SEMI decl
{
if(SAMEFN)
{
}
;
+opt_semi : /*empty*/
+ | SEMI
+ ;
+
/*
Note: if there is an iclasop_pragma here, then we must be
doing a class-op in an interface -- unless the user is up
to real mischief (ugly, but likely to work).
*/
-decl : qvarsk DCOLON sigtype
+decl : fixdecl
+
+ | qvarsk DCOLON polytype
{ $$ = mksbind($1,$3,startlineno);
- PREVPATT = NULL; FN = NULL; SAMEFN = 0;
+ FN = NULL; SAMEFN = 0;
+ }
+
+ | qvark DCOLON polytype
+ { $$ = mksbind(lsing($1),$3,startlineno);
+ FN = NULL; SAMEFN = 0;
}
/* User-specified pragmas come in as "signatures"...
| SPECIALISE_UPRAGMA qvark DCOLON types_and_maybe_ids END_UPRAGMA
{
$$ = mkvspec_uprag($2, $4, startlineno);
- PREVPATT = NULL; FN = NULL; SAMEFN = 0;
+ FN = NULL; SAMEFN = 0;
}
| SPECIALISE_UPRAGMA INSTANCE gtycon atype END_UPRAGMA
{
$$ = mkispec_uprag($3, $4, startlineno);
- PREVPATT = NULL; FN = NULL; SAMEFN = 0;
+ FN = NULL; SAMEFN = 0;
}
| SPECIALISE_UPRAGMA DATA gtycon atypes END_UPRAGMA
{
$$ = mkdspec_uprag($3, $4, startlineno);
- PREVPATT = NULL; FN = NULL; SAMEFN = 0;
+ FN = NULL; SAMEFN = 0;
}
| INLINE_UPRAGMA qvark END_UPRAGMA
{
$$ = mkinline_uprag($2, startlineno);
- PREVPATT = NULL; FN = NULL; SAMEFN = 0;
+ FN = NULL; SAMEFN = 0;
+ }
+
+ | NOINLINE_UPRAGMA qvark END_UPRAGMA
+ {
+ $$ = mknoinline_uprag($2, startlineno);
+ FN = NULL; SAMEFN = 0;
}
| MAGIC_UNFOLDING_UPRAGMA qvark vark END_UPRAGMA
{
$$ = mkmagicuf_uprag($2, $3, startlineno);
- PREVPATT = NULL; FN = NULL; SAMEFN = 0;
+ FN = NULL; SAMEFN = 0;
}
/* end of user-specified pragmas */
| valdef
- | /* empty */ { $$ = mknullbind(); PREVPATT = NULL; FN = NULL; SAMEFN = 0; }
;
+fixdecl : INFIXL INTEGER { Precedence = checkfixity($2); Fixity = INFIXL; }
+ fix_ops { $$ = $4; }
+ | INFIXR INTEGER { Precedence = checkfixity($2); Fixity = INFIXR; }
+ fix_ops { $$ = $4; }
+ | INFIX INTEGER { Precedence = checkfixity($2); Fixity = INFIX; }
+ fix_ops { $$ = $4; }
+ | INFIXL { Fixity = INFIXL; Precedence = 9; }
+ fix_ops { $$ = $3; }
+ | INFIXR { Fixity = INFIXR; Precedence = 9; }
+ fix_ops { $$ = $3; }
+ | INFIX { Fixity = INFIX; Precedence = 9; }
+ fix_ops { $$ = $3; }
+ ;
+
+/* Grotesque global-variable hack to
+ make a separate fixity decl for each op */
+fix_ops : fix_op
+ | fix_ops COMMA fix_op { $$ = mkabind($1,$3); }
+ ;
+
+fix_op : op { $$ = mkfixd(mknoqual($1),infixint(Fixity),Precedence,startlineno); }
+ ;
+
qvarsk : qvark COMMA qvars_list { $$ = mklcons($1,$3); }
- | qvark { $$ = lsing($1); }
;
qvars_list: qvar { $$ = lsing($1); }
;
type_and_maybe_id :
- type { $$ = mkvspec_ty_and_id($1,mknothing()); }
- | type EQUAL qvark { $$ = mkvspec_ty_and_id($1,mkjust($3)); }
+ tautype { $$ = mkvspec_ty_and_id($1,mknothing()); }
+ | tautype EQUAL qvark { $$ = mkvspec_ty_and_id($1,mkjust($3)); }
/**********************************************************************
* *
**********************************************************************/
-/* "DCOLON context => type" vs "DCOLON type" is a problem,
+/* "DCOLON context => tautype" vs "DCOLON tautype" is a problem,
because you can't distinguish between
foo :: (Baz a, Baz a)
bar :: (Baz a, Baz a) => [a] -> [a] -> [a]
- with one token of lookahead. The HACK is to have "DCOLON ttype"
- [tuple type] in the first case, then check that it has the right
+ with one token of lookahead. The HACK is to have "DCOLON apptype"
+ in the first case, then check that it has the right
form C a, or (C1 a, C2 b, ... Cn z) and convert it into a
context. Blaach!
*/
-/* A sigtype is a rank 2 type; it can have for-alls as function args:
- f :: All a => (All b => ...) -> Int
-*/
-sigtype : type DARROW sigarrowtype { $$ = mkcontext(type2context($1),$3); }
- | sigarrowtype
- ;
+/* --------------------------- */
-sigarrowtype : bigatype RARROW sigarrowtype { $$ = mktfun($1,$3); }
- | btype RARROW sigarrowtype { $$ = mktfun($1,$3); }
- | btype
- ;
+polyatype : atype
+ ;
-/* A "big" atype can be a forall-type in brackets. */
-bigatype: OPAREN type DARROW type CPAREN { $$ = mkcontext(type2context($2),$4); }
- ;
+polytype : FORALL tyvars1 DOT
+ apptype DARROW tautype { $$ = mkforall($2, type2context($4), $6); }
+ | FORALL tyvars1 DOT tautype { $$ = mkforall($2, Lnil, $4); }
+ | apptype DARROW tautype { $$ = mkforall(Lnil, type2context($1), $3); }
+ | tautype
+ ;
- /* 1 S/R conflict at DARROW -> shift */
-ctype : type DARROW type { $$ = mkcontext(type2context($1),$3); }
- | type
- ;
+/* --------------------------- */
+/* tautype is just a monomorphic type.
+ But it may have nested for-alls if we're in a rank-2 type */
- /* 1 S/R conflict at RARROW -> shift */
-type : btype RARROW type { $$ = mktfun($1,$3); }
- | btype { $$ = $1; }
+tautype : apptype RARROW tautype { $$ = mktfun($1,$3); }
+ | apptype { $$ = $1; }
;
-btype : btype atype { $$ = mktapp($1,$2); }
+tautypes : tautype { $$ = lsing($1); }
+ | tautypes COMMA tautype { $$ = lapp($1,$3); }
+ ;
+
+/* --------------------------- */
+/* apptype: type application */
+
+apptype : apptype atype { $$ = mktapp($1,$2); }
| atype { $$ = $1; }
;
-atype : gtycon { $$ = mktname($1); }
- | tyvar { $$ = $1; }
- | OPAREN type COMMA types CPAREN { $$ = mkttuple(mklcons($2,$4)); }
- | OBRACK type CBRACK { $$ = mktllist($2); }
- | OPAREN type CPAREN { $$ = $2; }
- ;
+/* --------------------------- */
+/* atype: an atomic or bracketed type: T, x, [ty], tuple ty */
+
+atypes : atype { $$ = lsing($1); }
+ | atype atypes { $$ = mklcons($1,$2); }
+ ;
+
+atype : gtycon { $$ = mktname($1); }
+ | tyvar { $$ = mknamedtvar($1); }
+
+ | OPAREN tautype COMMA
+ tautypes CPAREN { $$ = mkttuple(mklcons($2,$4)); }
+
+ | OUNBOXPAREN tautype COMMA
+ tautypes CUNBOXPAREN { $$ = mktutuple(mklcons($2,$4)); }
+
+ | OBRACK tautype CBRACK { $$ = mktllist($2); }
+ | OPAREN polytype CPAREN { $$ = $2; }
+ ;
+/* --------------------------- */
gtycon : qtycon
| OPAREN RARROW CPAREN { $$ = creategid(ARROWGID); }
| OBRACK CBRACK { $$ = creategid(NILGID); }
| OPAREN commas CPAREN { $$ = creategid($2); }
;
-atypes : atype { $$ = lsing($1); }
- | atypes atype { $$ = lapp($1,$2); }
- ;
-
-types : type { $$ = lsing($1); }
- | types COMMA type { $$ = lapp($1,$3); }
- ;
-
commas : COMMA { $$ = 1; }
| commas COMMA { $$ = $1 + 1; }
;
/* C a b c, where a,b,c are type variables */
/* C can be a class or tycon */
+
+/* simple_con_app can have no args; simple_con_app1 must have at least one */
simple_con_app: gtycon { $$ = mktname($1); }
| simple_con_app1 { $$ = $1; }
;
-simple_con_app1: gtycon tyvar { $$ = mktapp(mktname($1),$2); }
- | simple_con_app tyvar { $$ = mktapp($1, $2); }
+simple_con_app1: gtycon tyvar { $$ = mktapp(mktname($1),mknamedtvar($2)); }
+ | simple_con_app1 tyvar { $$ = mktapp($1, mknamedtvar($2)); }
;
simple_context : OPAREN simple_context_list CPAREN { $$ = $2; }
+ | OPAREN CPAREN { $$ = Lnil; }
| simple_con_app1 { $$ = lsing($1); }
;
-simple_context_list: simple_con_app1 { $$ = lsing($1); }
+simple_context_list : simple_con_app1 { $$ = lsing($1); }
| simple_context_list COMMA simple_con_app1 { $$ = lapp($1,$3); }
;
| constrs VBAR constr { $$ = lapp($1,$3); }
;
-constr : constr_after_context
- | type DARROW constr_after_context { $$ = mkconstrcxt ( type2context($1), $3 ); }
+constr : forall constr_context DARROW constr_after_context { $$ = mkconstrex ( $1, $2, $4 ); }
+ | forall constr_after_context { $$ = mkconstrex ( $1, Lnil, $2 ); }
+ ;
+
+forall : { $$ = Lnil }
+ | FORALL tyvars1 DOT { $$ = $2; }
+ ;
+
+constr_context
+ : conapptype conargatype { $$ = type2context( mktapp($1,$2) ); }
+ | conargatype { $$ = type2context( $1 ); }
;
constr_after_context :
*/
/* Con !Int (Tree a) */
- contype { qid tyc; list tys;
+ conapptype { qid tyc; list tys;
splittyconapp($1, &tyc, &tys);
$$ = mkconstrpre(tyc,tys,hsplineno); }
-/* !Int `Con` Tree a */
- | bbtype qconop bbtype { $$ = mkconstrinf($1,$2,$3,hsplineno); }
-
/* (::) (Tree a) Int */
- | OPAREN qconsym CPAREN batypes { $$ = mkconstrpre($2,$4,hsplineno); }
+ | OPAREN qconsym CPAREN conargatypes { $$ = mkconstrpre($2,$4,hsplineno); }
+
+/* !Int `Con` Tree a */
+ | conargatype qconop conargatype { $$ = mkconstrinf($1,$2,$3,hsplineno); }
/* Con { op1 :: Int } */
- | gtycon OCURLY fields CCURLY { $$ = mkconstrrec($1,$3,hsplineno); }
+ | qtycon OCURLY CCURLY { $$ = mkconstrrec($1,Lnil,hsplineno); }
+ | qtycon OCURLY fields CCURLY { $$ = mkconstrrec($1,$3,hsplineno); }
+ | OPAREN qconsym CPAREN OCURLY fields CCURLY { $$ = mkconstrrec($2,$5,hsplineno); }
;
/* 1 S/R conflict on OCURLY -> shift */
-/* contype has to reduce to a btype unless there are !'s, so that
- we don't get reduce/reduce conflicts with the second production of constr.
- But as soon as we see a ! we must switch to using bxtype. */
+conapptype : gtycon { $$ = mktname($1); }
+ | conapptype conargatype { $$ = mktapp($1, $2); }
+ ;
-contype : btype { $$ = $1; }
- | bxtype { $$ = $1; }
- ;
-
-/* S !Int Bool; at least one ! */
-bxtype : btype wierd_atype { $$ = mktapp($1, $2); }
- | bxtype batype { $$ = mktapp($1, $2); }
- ;
-
-bbtype : btype { $$ = $1; }
- | wierd_atype { $$ = $1; }
- ;
-
-batype : atype { $$ = $1; }
- | wierd_atype { $$ = $1; }
- ;
-
-/* A wierd atype is one that isn't a regular atype;
- it starts with a "!", or with a forall. */
-wierd_atype : BANG bigatype { $$ = mktbang( $2 ); }
- | BANG atype { $$ = mktbang( $2 ); }
- | bigatype
+conargatype : polyatype { $$ = $1; }
+ | BANG polyatype { $$ = mktbang( $2 ); }
;
-batypes : { $$ = Lnil; }
- | batypes batype { $$ = lapp($1,$2); }
- ;
-
+conargatypes : { $$ = Lnil; }
+ | conargatype conargatypes { $$ = mklcons($1,$2); }
+ ;
fields : field { $$ = lsing($1); }
| fields COMMA field { $$ = lapp($1,$3); }
;
-field : qvars_list DCOLON ctype { $$ = mkfield($1,$3); }
- | qvars_list DCOLON BANG atype { $$ = mkfield($1,mktbang($4)); }
- | qvars_list DCOLON BANG bigatype { $$ = mkfield($1,mktbang($4)); }
+field : qvars_list DCOLON polytype { $$ = mkfield($1,$3); }
+ | qvars_list DCOLON BANG polyatype { $$ = mkfield($1,mktbang($4)); }
;
-constr1 : gtycon atype { $$ = lsing(mkconstrnew($1,$2,hsplineno)); }
+constr1 : gtycon conargatype { $$ = mkconstrnew($1,$2,mknothing(),hsplineno); }
+ | gtycon OCURLY qvar DCOLON polytype CCURLY { $$ = mkconstrnew($1,$5,mkjust($3),hsplineno); }
;
| dtycls_list COMMA qtycls { $$ = lapp($1,$3); }
;
-instdefs : /* empty */ { $$ = mknullbind(); }
- | instdef { $$ = $1; }
- | instdefs SEMI instdef
- {
- if(SAMEFN)
- {
- extendfn($1,$3);
- $$ = $1;
- }
- else
- $$ = mkabind($1,$3);
- }
- ;
-
-/* instdef: same as valdef, except certain user-pragmas may appear */
-instdef :
- SPECIALISE_UPRAGMA qvark DCOLON types_and_maybe_ids END_UPRAGMA
- {
- $$ = mkvspec_uprag($2, $4, startlineno);
- PREVPATT = NULL; FN = NULL; SAMEFN = 0;
- }
-
- | INLINE_UPRAGMA qvark END_UPRAGMA
- {
- $$ = mkinline_uprag($2, startlineno);
- PREVPATT = NULL; FN = NULL; SAMEFN = 0;
- }
-
- | MAGIC_UNFOLDING_UPRAGMA qvark vark END_UPRAGMA
- {
- $$ = mkmagicuf_uprag($2, $3, startlineno);
- PREVPATT = NULL; FN = NULL; SAMEFN = 0;
- }
-
- | valdef
- ;
-
-
-valdef : vallhs
+valdef : funlhs opt_sig { checksamefn($1); }
+ get_line_no valrhs { $$ = mkfbind( lsing(mkpmatch( lsing($1), $2, $5 )), $4); }
- {
- tree fn = function($1);
- PREVPATT = $1;
-
- if(ttree(fn) == ident)
- {
- qid fun_id = gident((struct Sident *) fn);
- checksamefn(fun_id);
- FN = fun_id;
- }
+/* Special case for f :: type = e
+ We treat it as a special kind of pattern binding */
+ | qvark DCOLON tautype
+ get_line_no valrhs { $$ = mkpbind( mkrestr( mkident($1), $3 ), $5, $4 );
+ FN = NULL; SAMEFN = 0; }
- else if (ttree(fn) == infixap)
- {
- qid fun_id = ginffun((struct Sinfixap *) fn);
- checksamefn(fun_id);
- FN = fun_id;
- }
-
- else if(etags)
-#if 1/*etags*/
- printf("%u\n",startlineno);
-#else
- fprintf(stderr,"%u\tvaldef\n",startlineno);
-#endif
- }
-
- get_line_no
- valrhs
- {
- if ( lhs_is_patt($1) )
- {
- $$ = mkpbind($4, $3);
- FN = NULL;
- SAMEFN = 0;
- }
- else
- $$ = mkfbind($4, $3);
-
- PREVPATT = NULL;
- }
- ;
+ | patk
+ get_line_no valrhs { $$ = mkpbind($1, $3, $2);
+ FN = NULL; SAMEFN = 0; }
-get_line_no : { $$ = startlineno }
+get_line_no : { $$ = hsplineno; /* startlineno; */ }
;
+/* This grammar still isn't quite right
+ If you say
+ (x + 2) y = e
+ you should get a function binding, but actually the (x+3) will
+ parse as a pattern, and you'll get a parse error. */
+
+funlhs : patk qvarop cpat { $$ = mkinfixap($2,$1,$3); }
+ | funlhs1 apat { $$ = mkap( $1, $2 ); }
+
+funlhs1 : oparenkey funlhs2 CPAREN { $$ = mkpar($2); }
+ | funlhs1 apat { $$ = mkap( $1, $2 ); }
+ | qvark { $$ = mkident($1); }
+ ;
-vallhs : patk { $$ = $1; }
- | patk qvarop pat { $$ = mkinfixap($2,$1,$3); }
- | funlhs { $$ = $1; }
- ;
+funlhs2 : cpat qvarop cpat { $$ = mkinfixap($2,$1,$3); }
+ | funlhs3 apat { $$ = mkap( $1, $2 ); }
-funlhs : qvark apat { $$ = mkap(mkident($1),$2); }
- | funlhs apat { $$ = mkap($1,$2); }
- ;
+funlhs3 : OPAREN funlhs2 CPAREN { $$ = mkpar($2); }
+ | funlhs3 apat { $$ = mkap( $1, $2 ); }
+ | qvar { $$ = mkident($1); }
+ ;
+opt_sig : { $$ = mknothing(); }
+ | DCOLON tautype { $$ = mkjust($2); }
+ ;
-valrhs : valrhs1 maybe_where { $$ = lsing(createpat($1, $2)); }
- ;
+/* opt_asig is the same, but with a parenthesised type */
+opt_asig : { $$ = mknothing(); }
+ | DCOLON atype { $$ = mkjust($2); }
+ ;
-valrhs1 : gdrhs { $$ = mkpguards($1); }
- | EQUAL exp { $$ = mkpnoguards($2); }
+valrhs : EQUAL get_line_no exp maybe_where { $$ = mkpnoguards($2, $3, $4); }
+ | gdrhs maybe_where { $$ = mkpguards($1, $2); }
;
-gdrhs : gd EQUAL exp { $$ = lsing(mkpgdexp($1,$3)); }
- | gd EQUAL exp gdrhs { $$ = mklcons(mkpgdexp($1,$3),$4); }
+gdrhs : gd EQUAL get_line_no exp { $$ = lsing(mkpgdexp($1,$3,$4)); }
+ | gd EQUAL get_line_no exp gdrhs { $$ = mklcons(mkpgdexp($1,$3,$4),$5); }
;
maybe_where:
WHERE ocurly decls ccurly { $$ = $3; }
| WHERE vocurly decls vccurly { $$ = $3; }
/* A where containing no decls is OK */
- | WHERE SEMI { $$ = mknullbind(); }
+ | WHERE { $$ = mknullbind(); }
| /* empty */ { $$ = mknullbind(); }
;
* *
**********************************************************************/
-exp : oexp DCOLON ctype { $$ = mkrestr($1,$3); }
+exp : oexp DCOLON polytype { $$ = mkrestr($1,$3); }
| oexp
;
Operators must be left-associative at the same precedence for
precedence parsing to work.
*/
- /* 8 S/R conflicts on qop -> shift */
-oexp : oexp qop oexp %prec MINUS { $$ = mkinfixap($2,$1,$3); }
+ /* 10 S/R conflicts on qop -> shift */
+oexp : oexp qop dexp %prec MINUS { $$ = mkinfixap($2,$1,$3); }
| dexp
;
/*
We need to factor out a leading let expression so we can set
- inpat=TRUE when parsing (non let) expressions inside stmts and quals
+ pat_check=FALSE when parsing (non let) expressions inside stmts and quals
*/
-expLno : oexpLno DCOLON ctype { $$ = mkrestr($1,$3); }
- | oexpLno
+expLno : oexpLno DCOLON polytype { $$ = mkrestr($1,$3); }
+ | oexpLno
;
oexpLno : oexpLno qop oexp %prec MINUS { $$ = mkinfixap($2,$1,$3); }
| dexpLno
| kexpLno
;
-expL : oexpL DCOLON ctype { $$ = mkrestr($1,$3); }
+expL : oexpL DCOLON polytype { $$ = mkrestr($1,$3); }
| oexpL
;
oexpL : oexpL qop oexp %prec MINUS { $$ = mkinfixap($2,$1,$3); }
kexpLno : LAMBDA
{ hsincindent(); /* push new context for FN = NULL; */
FN = NULL; /* not actually concerned about indenting */
- $<ulong>$ = hsplineno; /* remember current line number */
- }
- lampats
- { hsendindent();
- }
- RARROW exp /* lambda abstraction */
- {
- $$ = mklambda($3, $6, $<ulong>2);
}
+ lampats opt_asig
+ { hsendindent(); }
+
+ RARROW get_line_no exp /* lambda abstraction */
+ { $$ = mklambda( mkpmatch( $3, $4, mkpnoguards( $7, $8, mknullbind() ) ) ); }
/* If Expression */
| IF {$<ulong>$ = hsplineno;}
| OPAREN exp CPAREN { $$ = mkpar($2); } /* mkpar: stop infix parsing at ()'s */
| qcon OCURLY rbinds CCURLY { $$ = mkrecord($1,$3); } /* 1 S/R conflict on OCURLY -> shift */
| OBRACK list_exps CBRACK { $$ = mkllist($2); }
- | OPAREN exp COMMA texps CPAREN { if (ttree($4) == tuple)
- $$ = mktuple(mklcons($2, gtuplelist((struct Stuple *) $4)));
- else
- $$ = mktuple(ldub($2, $4)); }
+ | OPAREN exp COMMA texps CPAREN { $$ = mktuple(mklcons($2,$4)); }
+ /* unboxed tuples */
+ | OUNBOXPAREN exp COMMA texps CUNBOXPAREN
+ { $$ = mkutuple(mklcons($2,$4)); }
/* only in expressions ... */
| aexp OCURLY rbinds1 CCURLY { $$ = mkrupdate($1,$3); }
/* these add 2 S/R conflict with with aexp . OCURLY rbinds CCURLY */
| qvar AT aexp { checkinpat(); $$ = mkas($1,$3); }
| LAZY aexp { checkinpat(); $$ = mklazyp($2); }
- | WILDCARD { checkinpat(); $$ = mkwildp(); }
;
/* ccall arguments */
caserest: ocurly alts ccurly { $$ = $2; }
| vocurly alts vccurly { $$ = $2; }
-dorest : ocurly stmts ccurly { checkdostmts($2); $$ = $2; }
+dorest : ocurly stmts ccurly { checkdostmts($2); $$ = $2; }
| vocurly stmts vccurly { checkdostmts($2); $$ = $2; }
;
| rbinds1 COMMA rbind { $$ = lapp($1,$3); }
;
-rbind : qvar { $$ = mkrbind($1,mknothing()); }
- | qvar EQUAL exp { $$ = mkrbind($1,mkjust($3)); }
- ;
+rbind : qvar EQUAL exp { $$ = mkrbind($1,mkjust($3)); }
+;
-texps : exp { $$ = mkpar($1); } /* mkpar: so we don't flatten last element in tuple */
- | exp COMMA texps
- { if (ttree($3) == tuple)
- $$ = mktuple(mklcons($1, gtuplelist((struct Stuple *) $3)));
- else if (ttree($3) == par)
- $$ = mktuple(ldub($1, gpare((struct Spar *) $3)));
- else
- hsperror("hsparser:texps: panic");
- }
+texps : exp { $$ = lsing($1); }
+ | exp COMMA texps { $$ = mklcons($1, $3) }
/* right recursion? WDP */
;
at it, it *will* do the wrong thing [WDP 94/06])
*/
-letdecls: LET ocurly decls ccurly { $$ = $3; }
- | LET vocurly decls vccurly { $$ = $3; }
+letdecls: LET { pat_check = TRUE; } ocurly decls ccurly { $$ = $4; }
+ | LET { pat_check = TRUE; } vocurly decls vccurly { $$ = $4; }
;
-quals : qual { $$ = lsing($1); }
- | quals COMMA qual { $$ = lapp($1,$3); }
- ;
+/*
+ When parsing patterns inside do stmt blocks or quals, we have
+ to tentatively parse them as expressions, since we don't know at
+ the time of parsing `p' whether it will be part of "p <- e" (pat)
+ or "p" (expr). When we eventually can tell the difference, the parse
+ of `p' is examined to see if it consitutes a syntactically legal pattern
+ or expression.
+
+ The expr rule used to parse the pattern/expression do contain
+ pattern-special productions (e.g., _ , a@pat, etc.), which are
+ illegal in expressions. Since we don't know whether what
+ we're parsing is an expression rather than a pattern, we turn off
+ the check and instead do it later.
+
+ The rather clumsy way that this check is turned on/off is there
+ to work around a Bison feature/shortcoming. Turning the flag
+ on/off just around the relevant nonterminal by decorating it
+ with simple semantic actions, e.g.,
+
+ {pat_check = FALSE; } expLNo { pat_check = TRUE; }
+
+ causes Bison to generate a parser where in one state it either
+ has to reduce/perform a semantic action ( { pat_check = FALSE; })
+ or reduce an error (the error production used to implement
+ vccurly.) Bison picks the semantic action, which it ideally shouldn't.
+ The work around is to lift out the setting of { pat_check = FALSE; }
+ and then later reset pat_check. Not pretty.
-qual : letdecls { $$ = mkseqlet($1); }
- | expL { $$ = $1; }
- | {inpat=TRUE;} expLno
- {inpat=FALSE;} leftexp
- { if ($4 == NULL) {
- expORpat(LEGIT_EXPR,$2);
- $$ = mkguard($2);
- } else {
- expORpat(LEGIT_PATT,$2);
- $$ = mkqual($2,$4);
- }
- }
+*/
+
+
+quals : { pat_check = FALSE;} qual { pat_check = TRUE; $$ = lsing($2); }
+ | quals COMMA { pat_check = FALSE; } qual { pat_check = TRUE; $$ = lapp($1,$4); }
;
-alts : alt { $$ = $1; }
- | alts SEMI alt { $$ = lconc($1,$3); }
+qual : letdecls { $$ = mkseqlet($1); }
+ | expL { expORpat(LEGIT_EXPR,$1); $$ = $1; }
+ | expLno { pat_check = TRUE; } leftexp
+ { if ($3 == NULL) {
+ expORpat(LEGIT_EXPR,$1);
+ $$ = mkguard($1);
+ } else {
+ expORpat(LEGIT_PATT,$1);
+ $$ = mkqual($1,$3);
+ }
+ }
;
-alt : pat { PREVPATT = $1; } altrest { $$ = lsing($3); PREVPATT = NULL; }
- | /* empty */ { $$ = Lnil; }
+alts : /* empty */ { $$ = Lnil; }
+ | alt { $$ = lsing($1); }
+ | alt SEMI alts { $$ = mklcons($1,$3); }
+ | SEMI alts { $$ = $2; }
;
-altrest : gdpat maybe_where { $$ = createpat(mkpguards($1), $2); }
- | RARROW exp maybe_where { $$ = createpat(mkpnoguards($2),$3); }
+alt : dpat opt_sig altrhs { $$ = mkpmatch( lsing($1), $2, $3 ); }
;
-gdpat : gd RARROW exp { $$ = lsing(mkpgdexp($1,$3)); }
- | gd RARROW exp gdpat { $$ = mklcons(mkpgdexp($1,$3),$4); }
+altrhs : RARROW get_line_no exp maybe_where { $$ = mkpnoguards($2, $3, $4); }
+ | gdpat maybe_where { $$ = mkpguards($1, $2); }
+ ;
+
+gdpat : gd RARROW get_line_no exp { $$ = lsing(mkpgdexp($1,$3,$4)); }
+ | gd RARROW get_line_no exp gdpat { $$ = mklcons(mkpgdexp($1,$3,$4),$5); }
;
-stmts : stmt { $$ = $1; }
- | stmts SEMI stmt { $$ = lconc($1,$3); }
+stmts : {pat_check = FALSE;} stmt {pat_check=TRUE; $$ = $2; }
+ | stmts SEMI {pat_check=FALSE;} stmt {pat_check=TRUE; $$ = lconc($1,$4); }
;
-stmt : /* empty */ { $$ = Lnil; }
- | letdecls { $$ = lsing(mkseqlet($1)); }
- | expL { $$ = lsing(mkdoexp($1,hsplineno)); }
- | {inpat=TRUE;} expLno {inpat=FALSE;} leftexp
- { if ($4 == NULL) {
- expORpat(LEGIT_EXPR,$2);
- $$ = lsing(mkdoexp($2,endlineno));
- } else {
- expORpat(LEGIT_PATT,$2);
- $$ = lsing(mkdobind($2,$4,endlineno));
- }
- }
+stmt : /* empty */ { $$ = Lnil; }
+ | letdecls { $$ = lsing(mkseqlet($1)); }
+ | expL { expORpat(LEGIT_EXPR,$1); $$ = lsing(mkdoexp($1,hsplineno)); }
+ | expLno {pat_check=TRUE;} leftexp
+ { if ($3 == NULL) {
+ expORpat(LEGIT_EXPR,$1);
+ $$ = lsing(mkdoexp($1,endlineno));
+ } else {
+ expORpat(LEGIT_PATT,$1);
+ $$ = lsing(mkdobind($1,$3,endlineno));
+ }
+ }
;
+
leftexp : LARROW exp { $$ = $2; }
| /* empty */ { $$ = NULL; }
;
* *
**********************************************************************/
-pat : qvar PLUS INTEGER { $$ = mkplusp($1, mkinteger($3)); }
+pat : dpat DCOLON tautype { $$ = mkrestr($1,$3); }
+ | dpat
+ ;
+
+dpat : qvar PLUS INTEGER { $$ = mkplusp($1, mkinteger($3)); }
| cpat
;
apatc : qvar { $$ = mkident($1); }
| qvar AT apat { $$ = mkas($1,$3); }
| lit_constant { $$ = mklit($1); }
- | WILDCARD { $$ = mkwildp(); }
| OPAREN pat CPAREN { $$ = mkpar($2); }
| OPAREN pat COMMA pats CPAREN { $$ = mktuple(mklcons($2,$4)); }
+ | OUNBOXPAREN pat COMMA pats CUNBOXPAREN { $$ = mkutuple(mklcons($2,$4)); }
| OBRACK pats CBRACK { $$ = mkllist($2); }
| LAZY apat { $$ = mklazyp($2); }
;
| CLITLIT /* yurble yurble */ { $$ = mkclitlit($1); }
;
+/* Sequence of apats for a lambda abstraction */
lampats : apat lampats { $$ = mklcons($1,$2); }
| apat { $$ = lsing($1); }
/* right recursion? (WDP) */
;
+/* Comma-separated sequence of pats */
pats : pat COMMA pats { $$ = mklcons($1, $3); }
| pat { $$ = lsing($1); }
/* right recursion? (WDP) */
;
+/* Comma separated sequence of record patterns, each of form 'field=pat' */
rpats : /* empty */ { $$ = Lnil; }
| rpats1
;
| rpats1 COMMA rpat { $$ = lapp($1,$3); }
;
-rpat : qvar { $$ = mkrbind($1,mknothing()); }
- | qvar EQUAL pat { $$ = mkrbind($1,mkjust($3)); }
+rpat : qvar EQUAL pat { $$ = mkrbind($1,mkjust($3)); }
;
+/* I can't figure out just what these ...k patterns are for.
+ It seems to have something to do with recording the line number */
+
+/* Corresponds to a cpat */
patk : patk qconop bpat { $$ = mkinfixap($2,$1,$3); }
| bpatk
;
apatck : qvark { $$ = mkident($1); }
| qvark AT apat { $$ = mkas($1,$3); }
| lit_constant { $$ = mklit($1); setstartlineno(); }
- | WILDCARD { $$ = mkwildp(); setstartlineno(); }
| oparenkey pat CPAREN { $$ = mkpar($2); }
| oparenkey pat COMMA pats CPAREN { $$ = mktuple(mklcons($2,$4)); }
+ | ounboxparenkey pat COMMA pats CUNBOXPAREN
+ { $$ = mkutuple(mklcons($2,$4)); }
| obrackkey pats CBRACK { $$ = mkllist($2); }
| lazykey apat { $$ = mklazyp($2); }
;
defaultkey: DEFAULT { setstartlineno(); }
;
+foreignkey: FOREIGN { setstartlineno(); }
+ ;
+
classkey: CLASS { setstartlineno();
if(etags)
#if 1/*etags*/
oparenkey: OPAREN { setstartlineno(); }
;
+ounboxparenkey: OUNBOXPAREN { setstartlineno(); }
+ ;
+
obrackkey: OBRACK { setstartlineno(); }
;
varsym_nominus : VARSYM
| PLUS { $$ = install_literal("+"); }
| BANG { $$ = install_literal("!"); }
+ | DOT { $$ = install_literal("."); }
;
/* AS HIDING QUALIFIED are valid varids */
-varid : VARID
+varid : varid_noforall
+ | FORALL { $$ = install_literal("forall"); }
+ ;
+
+varid_noforall
+ : VARID
| AS { $$ = install_literal("as"); }
| HIDING { $$ = install_literal("hiding"); }
| QUALIFIED { $$ = install_literal("qualified"); }
+/* The rest of these guys are used by the FFI decls, a ghc (and hugs) extension. */
+ | EXPORT { $$ = install_literal("export"); }
+ | UNSAFE { $$ = install_literal("unsafe"); }
+ | DYNAMIC { $$ = install_literal("dynamic"); }
+ | LABEL { $$ = install_literal("label"); }
+ | C_CALL { $$ = install_literal("ccall"); }
+ | STDCALL { $$ = install_literal("stdcall"); }
+ | PASCAL { $$ = install_literal("pascal"); }
;
-
ccallid : VARID
| CONID
;
-tyvar : varid { $$ = mknamedtvar(mknoqual($1)); }
- ;
tycon : CONID
;
modid : CONID
;
-/*
-tyvar_list: tyvar { $$ = lsing($1); }
- | tyvar_list COMMA tyvar { $$ = lapp($1,$3); }
+/* ---------------------------------------------- */
+tyvar : varid_noforall { $$ = $1; }
+ ;
+
+/* tyvars1: At least one tyvar */
+tyvars1 : tyvar { $$ = lsing($1); }
+ | tyvar tyvars1 { $$ = mklcons($1,$2); }
;
-*/
/**********************************************************************
* *
ccurly :
CCURLY
{
- FN = NULL; SAMEFN = 0; PREVPATT = NULL;
+ FN = NULL; SAMEFN = 0;
hsendindent();
}
;
vccurly1:
VCCURLY
{
- FN = NULL; SAMEFN = 0; PREVPATT = NULL;
+ FN = NULL; SAMEFN = 0;
hsendindent();
}
| error
{
yyerrok;
- FN = NULL; SAMEFN = 0; PREVPATT = NULL;
+ FN = NULL; SAMEFN = 0;
hsendindent();
}
- ;
+ ;
%%
* *
**********************************************************************/
+
void
checkinpat()
{
- if(!inpat)
+ if(pat_check)
hsperror("pattern syntax used in expression");
}
-
/* The parser calls "hsperror" when it sees a
`report this and die' error. It sets the stage
and calls "yyerror".
/* We want to be able to distinguish 'error'-raised yyerrors
from yyerrors explicitly coded by the parser hacker.
*/
- if (expect_ccurly && ! error_and_I_mean_it ) {
+ if ( expect_ccurly && ! error_and_I_mean_it ) {
/*NOTHING*/;
} else {