*/
#include <stdio.h>
+/* Included so as to bring the right prototypes into scope */
+#include "rtsdefs.h"
+
#define W_ unsigned long int
#define I_ long int
+#if __GLASGOW_HASKELL__ >= 303
+void
+ErrorHdrHook (long fd)
+{
+ char msg[]="\n";
+ write(fd,msg,1);
+}
+#else
void
ErrorHdrHook (FILE *where)
{
fprintf(where, "\n"); /* no "Fail: " */
}
-
+#endif
void
OutOfHeapHook (W_ request_size, W_ heap_size) /* both in bytes */
fprintf(stderr, "GHC stack-space overflow: current size %ld bytes.\nUse the `-K<size>' option to increase it.\n", stack_size);
}
+#if __GLASGOW_HASKELL__ >= 303
+void
+PatErrorHdrHook (long fd)
+{
+ const char msg[]="\n*** Pattern-matching error within GHC!\n\nThis is a compiler bug; please report it to glasgow-haskell-bugs@dcs.gla.ac.uk.\n\nFail:";
+ write(fd,msg,sizeof(msg)-1);
+}
+
+void
+PreTraceHook (long fd)
+{
+ const char msg[]="\n";
+ write(fd,msg,sizeof(msg)-1);
+}
+
+void
+PostTraceHook (long fd)
+{
+#if 0
+ const char msg[]="\n";
+ write(fd,msg,sizeof(msg)-1);
+#endif
+}
+
+#else
void
PatErrorHdrHook (FILE *where)
{
{
fprintf(where, "\n"); /* not "Trace Off" */
}
+#endif
<GlaExt>"_ccall_GC_" { RETURN(CCALL_GC); }
<GlaExt>"_casm_" { RETURN(CASM); }
<GlaExt>"_casm_GC_" { RETURN(CASM_GC); }
+<GlaExt>"foreign" { RETURN(FOREIGN); }
+<GlaExt>"export" { RETURN(EXPORT); }
+<GlaExt>"unsafe" { RETURN(UNSAFE); }
+<GlaExt>"_stdcall" { RETURN(STDCALL); }
+<GlaExt>"_ccall" { RETURN(C_CALL); }
+<GlaExt>"_pascal" { RETURN(PASCAL); }
+<GlaExt>"_fastcall" { RETURN(FASTCALL); }
+<GlaExt>"dynamic" { RETURN(DYNAMIC); }
%{
/*
%token SCC
%token CCALL CCALL_GC CASM CASM_GC
-
+%token EXPORT UNSAFE STDCALL C_CALL
+%token PASCAL FASTCALL FOREIGN DYNAMIC
/**********************************************************************
* *
gdrhs gdpat valrhs
lampats cexps gd
-%type <umaybe> maybeexports impspec deriving
+%type <umaybe> maybeexports impspec deriving
+ ext_name
%type <uliteral> lit_constant
qvar qcon qvarop qconop qop
qvark qconk qtycon qtycls
gcon gconk gtycon itycon qop1 qvarop1
- ename iname
+ ename iname
%type <ubinding> topdecl topdecls letdecls
- typed datad newtd classd instd defaultd
+ typed datad newtd classd instd defaultd foreignd
decl decls valdef instdef instdefs
maybe_where cbody rinst type_and_maybe_id
%type <uentid> export import
%type <ulong> commas importkey get_line_no
+ unsafe_flag callconv
/**********************************************************************
* *
| 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; }
;
| defaultkey OPAREN CPAREN { $$ = mkdbind(Lnil,startlineno); }
;
+/* FFI primitive declarations - GHC/Hugs specific */
+foreignd: foreignkey IMPORT callconv ext_name unsafe_flag qvarid DCOLON sigtype { $$ = mkfobind($6,$8,$4,$5,$3,FOREIGN_IMPORT,startlineno); }
+ | foreignkey EXPORT callconv ext_name qvarid DCOLON sigtype { $$ = mkfobind($5,$7,$4,0,$3,FOREIGN_EXPORT,startlineno); }
+ ;
+
+callconv: STDCALL { $$ = CALLCONV_STDCALL; }
+ | C_CALL { $$ = CALLCONV_CCALL; }
+ | PASCAL { $$ = CALLCONV_PASCAL; }
+ | FASTCALL { $$ = CALLCONV_FASTCALL; }
+ ;
+
+ext_name: STRING { $$ = mkjust(lsing($1)); }
+ | STRING STRING { $$ = mkjust(mklcons ($1,lsing($2))); }
+ | DYNAMIC { $$ = mknothing(); }
+
+unsafe_flag: UNSAFE { $$ = 1; }
+ | /*empty*/ { $$ = 0; }
+ ;
+
+
+
decls : decl
| decls SEMI decl
{
defaultkey: DEFAULT { setstartlineno(); }
;
+foreignkey: FOREIGN { setstartlineno(); }
+ ;
+
classkey: CLASS { setstartlineno();
if(etags)
#if 1/*etags*/
void checkprec PROTO((tree, qid, BOOLEAN));
*/
+/* FFI predefines */
+#define CALLCONV_STDCALL 0
+#define CALLCONV_CCALL 1
+#define CALLCONV_PASCAL 2
+#define CALLCONV_FASTCALL 3
+
+#define FOREIGN_IMPORT 0
+#define FOREIGN_EXPORT 1
+
BOOLEAN isconstr PROTO((char *));
void setstartlineno PROTO((void));