Commit a6199582 authored by simonmar's avatar simonmar
Browse files

[project @ 1999-06-17 09:51:16 by simonmar]

Comment cleanup and literisation(?) by Wolfram Kahl <kahl@DI.Unipi.IT>.
parent 07e4037d
......@@ -2,6 +2,7 @@
% (c) The GRASP/AQUA Project, Glasgow University, 1997-1998
%
% Author: Juan J. Quintela <quintela@krilin.dc.fi.udc.es>
\section{Module @Check@ in @deSugar@}
\begin{code}
......@@ -56,61 +57,69 @@ import Outputable
\end{code}
This module performs checks about if one list of equations are:
- Overlapped
- Non exhaustive
\begin{itemize}
\item Overlapped
\item Non exhaustive
\end{itemize}
To discover that we go through the list of equations in a tree-like fashion.
If you like theory, a similar algorithm is described in:
Two Techniques for Compiling Lazy Pattern Matching
Luc Maranguet
\begin{quotation}
{\em Two Techniques for Compiling Lazy Pattern Matching},
Luc Maranguet,
INRIA Rocquencourt (RR-2385, 1994)
The algorithm is based in the first Technique, but there are some differences:
- We don't generate code
- We have constructors and literals (not only literals as in the
\end{quotation}
The algorithm is based on the first technique, but there are some differences:
\begin{itemize}
\item We don't generate code
\item We have constructors and literals (not only literals as in the
article)
- We don't use directions, we must select the columns from
\item We don't use directions, we must select the columns from
left-to-right
\end{itemize}
(By the way the second technique is really similar to the one used in
Match.lhs to generate code)
@Match.lhs@ to generate code)
This function takes the equations of a pattern and returns:
- The patterns that are not recognized
- The equations that are not overlapped
It simplify the patterns and then call check' (the same semantics),and it
\begin{itemize}
\item The patterns that are not recognized
\item The equations that are not overlapped
\end{itemize}
It simplify the patterns and then call @check'@ (the same semantics), and it
needs to reconstruct the patterns again ....
The problem appear with things like:
\begin{verbatim}
f [x,y] = ....
f (x:xs) = .....
\end{verbatim}
We want to put the two patterns with the same syntax, (prefix form) and
then all the constructors are equal:
\begin{verbatim}
f (: x (: y [])) = ....
f (: x xs) = .....
\end{verbatim}
(more about that in @simplify_eqns@)
(more about that in simplify_eqns)
We would prefer to have a WarningPat of type String, but Strings and the
We would prefer to have a @WarningPat@ of type @String@, but Strings and the
Pretty Printer are not friends.
We use InPat in WarningPat instead of OutPat because we need to print the
We use @InPat@ in @WarningPat@ instead of @OutPat@
because we need to print the
warning messages in the same way they are introduced, i.e. if the user
wrote:
\begin{verbatim}
f [x,y] = ..
\end{verbatim}
He don't want a warning message written:
\begin{verbatim}
f (: x (: y [])) ........
\end{verbatim}
Then we need to use InPats.
Juan Quintela 5 JUL 1998
\begin{quotation}
Juan Quintela 5 JUL 1998\\
User-friendliness and compiler writers are no friends.
\end{quotation}
\begin{code}
type WarningPat = InPat Name
......@@ -178,11 +187,11 @@ untidy_lit lit = lit
This equation is the same that check, the only difference is that the
boring work is done, that work needs to be done only once, this is
the reason top have two functions, check is the external interface,
check' is called recursively.
@check'@ is called recursively.
There are several cases:
\begin{item}
\begin{itemize}
\item There are no equations: Everything is OK.
\item There are only one equation, that can fail, and all the patterns are
variables. Then that equation is used and the same equation is
......@@ -198,7 +207,7 @@ There are several cases:
\item In the general case, there can exist literals ,constructors or only
vars in the first column, we actuate in consequence.
\end{item}
\end{itemize}
\begin{code}
......@@ -243,7 +252,7 @@ split_by_literals qs = process_literals used_lits qs
used_lits = get_used_lits qs
\end{code}
process_explicit_literals is a function that process each literal that appears
@process_explicit_literals@ is a function that process each literal that appears
in the column of the matrix.
\begin{code}
......@@ -256,7 +265,7 @@ process_explicit_literals lits qs = (concat pats, unionManyUniqSets indexs)
\end{code}
Process_literals calls process_explicit_literals to deal with the literals
@process_literals@ calls @process_explicit_literals@ to deal with the literals
that appears in the matrix and deal also with the rest of the cases. It
must be one Variable to be complete.
......@@ -297,7 +306,7 @@ remove_first_column_lit lit qs =
\end{code}
This function splits the equations @qs@ in groups that deal with the
same constructor
same constructor.
\begin{code}
......@@ -327,7 +336,7 @@ constructor, using all the constructors that appears in the first column
of the pattern matching.
We can need a default clause or not ...., it depends if we used all the
constructors or not explicitly. The reasoning is similar to process_literals,
constructors or not explicitly. The reasoning is similar to @process_literals@,
the difference is that here the default case is not always needed.
\begin{code}
......@@ -362,15 +371,15 @@ Here remove first column is more difficult that with literals due to the fact
that constructors can have arguments.
For instance, the matrix
\begin{verbatim}
(: x xs) y
z y
\end{verbatim}
is transformed in:
\begin{verbatim}
x xs y
_ _ y
\end{verbatim}
\begin{code}
remove_first_column :: TypecheckedPat -- Constructor
......@@ -436,7 +445,8 @@ get_unused_cons used_cons = unused_cons
Just (ty_con,_) = splitTyConApp_maybe ty
all_cons = tyConDataCons ty_con
used_cons_as_id = map (\ (ConPat d _ _ _ _) -> d) used_cons
unused_cons = uniqSetToList (mkUniqSet all_cons `minusUniqSet` mkUniqSet used_cons_as_id)
unused_cons = uniqSetToList
(mkUniqSet all_cons `minusUniqSet` mkUniqSet used_cons_as_id)
all_vars :: [TypecheckedPat] -> Bool
......@@ -446,7 +456,8 @@ all_vars _ = False
remove_var :: EquationInfo -> EquationInfo
remove_var (EqnInfo n ctx (WildPat _:ps) result) = EqnInfo n ctx ps result
remove_var _ = panic "Check:remove_var: equation not begin with a variable"
remove_var _ =
panic "Check.remove_var: equation does not begin with a variable"
is_con :: EquationInfo -> Bool
is_con (EqnInfo _ _ ((ConPat _ _ _ _ _):_) _) = True
......@@ -481,39 +492,43 @@ is_var_lit lit (EqnInfo _ _ ((NPat lit' _ _):_) _) | lit == lit' = True
is_var_lit lit _ = False
\end{code}
The difference beteewn make_con and make_whole_con is that
make_wole_con creates a new constructor with all their arguments, and
make_Con takes a list of argumntes, creates the contructor geting thir
argumnts from the list. See where are used for details.
The difference beteewn @make_con@ and @make_whole_con@ is that
@make_wole_con@ creates a new constructor with all their arguments, and
@make_con@ takes a list of argumntes, creates the contructor getting their
arguments from the list. See where \fbox{\ ???\ } are used for details.
We need to reconstruct the patterns (make the constructors infix and
similar) at the same time that we create the constructors.
You can tell tuple constructors using
\begin{verbatim}
Id.isTupleCon
\end{verbatim}
You can see if one constructor is infix with this clearer code :-))))))))))
\begin{verbatim}
Lex.isLexConSym (Name.occNameString (Name.getOccName con))
\end{verbatim}
Rather clumsy but it works. (Simon Peyton Jones)
We con't mind the nilDataCon because it doesn't change the way to
print the messsage, we are searching only for things like: [1,2,3],
not x:xs ....
We don't mind the @nilDataCon@ because it doesn't change the way to
print the messsage, we are searching only for things like: @[1,2,3]@,
not @x:xs@ ....
In reconstruct_pat we want to "undo" the work that we have done in simplify_pat
In @reconstruct_pat@ we want to ``undo'' the work
that we have done in @simplify_pat@.
In particular:
((,) x y) returns to be (x, y)
((:) x xs) returns to be (x:xs)
(x:(...:[]) returns to be [x,...]
\begin{tabular}{lll}
@((,) x y)@ & returns to be & @(x, y)@
\\ @((:) x xs)@ & returns to be & @(x:xs)@
\\ @(x:(...:[])@ & returns to be & @[x,...]@
\end{tabular}
%
The difficult case is the third one becouse we need to follow all the
contructors until the [] to know taht we need to use the second case,
not the second.
contructors until the @[]@ to know that we need to use the second case,
not the second. \fbox{\ ???\ }
%
\begin{code}
isInfixCon con = isDataSymOcc (getOccName con)
......@@ -560,9 +575,9 @@ new_wild_pat :: WarningPat
new_wild_pat = WildPatIn
\end{code}
This equation makes the same thing that tidy in Match.lhs, the
This equation makes the same thing as @tidy@ in @Match.lhs@, the
difference is that here we can do all the tidy in one place and in the
Match tidy it must be done one column each time due to bookkeeping
@Match@ tidy it must be done one column each time due to bookkeeping
constraints.
\begin{code}
......@@ -584,9 +599,9 @@ simplify_pat (AsPat id p) = simplify_pat p
simplify_pat (ConPat id ty tvs dicts ps) = ConPat id ty tvs dicts (map simplify_pat ps)
simplify_pat (ListPat ty ps) = foldr (\ x -> \y -> ConPat consDataCon list_ty [] [] [x, y])
(ConPat nilDataCon list_ty [] [] [])
(map simplify_pat ps)
simplify_pat (ListPat ty ps) = foldr (\ x -> \y -> ConPat consDataCon list_ty [] [] [x, y])
(ConPat nilDataCon list_ty [] [] [])
(map simplify_pat ps)
where list_ty = mkListTy ty
......
......@@ -76,7 +76,7 @@ deSugar mod_name us (TcResults {tc_env = global_val_env,
module_and_group = (mod_name, grp_name)
grp_name = case opt_SccGroup of
Just xx -> _PK_ xx
Nothing -> _PK_ (moduleString mod_name) -- default: module name
Nothing -> _PK_ (moduleString mod_name) -- default: module name
dsProgram mod_name all_binds rules fo_decls
= dsMonoBinds auto_scc all_binds [] `thenDs` \ core_prs ->
......@@ -121,8 +121,8 @@ dsRule (RuleDecl name sig_tvs vars lhs rhs loc)
ds_lhs all_vars lhs
= let
(dict_binds, body) = case lhs of
(HsLet (MonoBind dict_binds _ _) body) -> (dict_binds, body)
other -> (EmptyMonoBinds, lhs)
(HsLet (MonoBind dict_binds _ _) body) -> (dict_binds, body)
other -> (EmptyMonoBinds, lhs)
in
ds_dict_binds dict_binds `thenDs` \ dict_binds' ->
dsExpr body `thenDs` \ body' ->
......
......@@ -89,7 +89,8 @@ dsMonoBinds auto_scc (PatMonoBind pat grhss locn) rest
-- Common case: one exported variable
-- All non-recursive bindings come through this way
dsMonoBinds auto_scc (AbsBinds all_tyvars dicts exps@[(tyvars, global, local)] inlines binds) rest
dsMonoBinds auto_scc
(AbsBinds all_tyvars dicts exps@[(tyvars, global, local)] inlines binds) rest
= ASSERT( all (`elem` tyvars) all_tyvars )
dsMonoBinds (addSccs auto_scc exps) binds [] `thenDs` \ core_prs ->
let
......@@ -207,7 +208,8 @@ worthSCC (Con _ _) = False
worthSCC core_expr = True
\end{code}
If profiling and dealing with a dict binding, wrap the dict in "_scc_ DICT <dict>":
If profiling and dealing with a dict binding,
wrap the dict in @_scc_ DICT <dict>@:
\begin{code}
addDictScc var rhs = returnDs rhs
......
......@@ -180,9 +180,10 @@ unboxArg arg
Just (arg2_tycon,_) = maybe_arg2_tycon
can'tSeeDataConsPanic thing ty
= pprPanic "ERROR: Can't see the data constructor(s) for _ccall_/_casm_/foreign declaration"
(hcat [text thing, text "; type: ", ppr ty, text "(try compiling with -fno-prune-tydecls ..)\n"])
= pprPanic
"ERROR: Can't see the data constructor(s) for _ccall_/_casm_/foreign declaration"
(hcat [ text thing, text "; type: ", ppr ty
, text "(try compiling with -fno-prune-tydecls ..)\n"])
\end{code}
......
......@@ -60,14 +60,14 @@ import Outputable
%* *
%************************************************************************
@dsLet@ is a match-result transformer, taking the MatchResult for the body
@dsLet@ is a match-result transformer, taking the @MatchResult@ for the body
and transforming it into one for the let-bindings enclosing the body.
This may seem a bit odd, but (source) let bindings can contain unboxed
binds like
\begin{verbatim}
C x# = e
\end{verbatim}
This must be transformed to a case expression and, if the type has
more than one constructor, may fail.
......@@ -83,7 +83,8 @@ dsLet (ThenBinds b1 b2) body
-- Special case for bindings which bind unlifted variables
-- Silently ignore INLINE pragmas...
dsLet (MonoBind (AbsBinds [] [] binder_triples inlines (PatMonoBind pat grhss loc)) sigs is_rec) body
dsLet (MonoBind (AbsBinds [] [] binder_triples inlines
(PatMonoBind pat grhss loc)) sigs is_rec) body
| or [isUnLiftedType (idType g) | (_, g, l) <- binder_triples]
= ASSERT (case is_rec of {NonRecursive -> True; other -> False})
putSrcLocDs loc $
......@@ -93,7 +94,8 @@ dsLet (MonoBind (AbsBinds [] [] binder_triples inlines (PatMonoBind pat grhss lo
bind (tyvars, g, l) body = ASSERT( null tyvars )
bindNonRec g (Var l) body
in
mkErrorAppDs iRREFUT_PAT_ERROR_ID result_ty (showSDoc (ppr pat)) `thenDs` \ error_expr ->
mkErrorAppDs iRREFUT_PAT_ERROR_ID result_ty (showSDoc (ppr pat))
`thenDs` \ error_expr ->
matchSimply rhs PatBindMatch pat body' error_expr
where
result_ty = coreExprType body
......@@ -124,17 +126,17 @@ dsExpr e@(HsVar var) = returnDs (Var var)
%* *
%************************************************************************
We give int/float literals type Integer and Rational, respectively.
We give int/float literals type @Integer@ and @Rational@, respectively.
The typechecker will (presumably) have put \tr{from{Integer,Rational}s}
around them.
ToDo: put in range checks for when converting "i"
ToDo: put in range checks for when converting ``@i@''
(or should that be in the typechecker?)
For numeric literals, we try to detect there use at a standard type
(Int, Float, etc.) are directly put in the right constructor.
(@Int@, @Float@, etc.) are directly put in the right constructor.
[NB: down with the @App@ conversion.]
Otherwise, we punt, putting in a "NoRep" Core literal (where the
Otherwise, we punt, putting in a @NoRep@ Core literal (where the
representation decisions are delayed)...
See also below where we look for @DictApps@ for \tr{plusInt}, etc.
......@@ -322,8 +324,8 @@ dsExpr (HsSCC cc expr)
dsExpr (HsCase discrim matches@[Match _ [TuplePat ps boxed] _ _] src_loc)
| not boxed && all var_pat ps
= putSrcLocDs src_loc $
dsExpr discrim `thenDs` \ core_discrim ->
matchWrapper CaseMatch matches "case" `thenDs` \ ([discrim_var], matching_code) ->
dsExpr discrim `thenDs` \ core_discrim ->
matchWrapper CaseMatch matches "case" `thenDs` \ ([discrim_var], matching_code) ->
case matching_code of
Case (Var x) bndr alts | x == discrim_var ->
returnDs (Case core_discrim bndr alts)
......@@ -331,8 +333,8 @@ dsExpr (HsCase discrim matches@[Match _ [TuplePat ps boxed] _ _] src_loc)
dsExpr (HsCase discrim matches src_loc)
= putSrcLocDs src_loc $
dsExpr discrim `thenDs` \ core_discrim ->
matchWrapper CaseMatch matches "case" `thenDs` \ ([discrim_var], matching_code) ->
dsExpr discrim `thenDs` \ core_discrim ->
matchWrapper CaseMatch matches "case" `thenDs` \ ([discrim_var], matching_code) ->
returnDs (bindNonRec discrim_var core_discrim matching_code)
dsExpr (HsLet binds body)
......@@ -370,8 +372,9 @@ dsExpr (HsIf guard_expr then_expr else_expr src_loc)
\end{code}
Type lambda and application
~~~~~~~~~~~~~~~~~~~~~~~~~~~
\noindent
\underline{\bf Type lambda and application}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{code}
dsExpr (TyLam tyvars expr)
= dsExpr expr `thenDs` \ core_expr ->
......@@ -383,8 +386,9 @@ dsExpr (TyApp expr tys)
\end{code}
Various data construction things
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\noindent
\underline{\bf Various data construction things}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{code}
dsExpr (ExplicitListOut ty xs)
= go xs
......@@ -443,25 +447,26 @@ dsExpr (ArithSeqOut expr (FromThenTo from thn two))
returnDs (mkApps expr2 [from2, thn2, two2])
\end{code}
Record construction and update
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\noindent
\underline{\bf Record construction and update}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For record construction we do this (assuming T has three arguments)
\begin{verbatim}
T { op2 = e }
==>
let err = /\a -> recConErr a
T (recConErr t1 "M.lhs/230/op1")
e
(recConErr t1 "M.lhs/230/op3")
recConErr then converts its arugment string into a proper message
\end{verbatim}
@recConErr@ then converts its arugment string into a proper message
before printing it as
\begin{verbatim}
M.lhs, line 230: missing field op1 was evaluated
\end{verbatim}
M.lhs, line 230: Missing field in record construction op1
We also handle C{} as valid construction syntax for an unlabelled
constructor C, setting all of C's fields to bottom.
We also handle @C{}@ as valid construction syntax for an unlabelled
constructor @C@, setting all of @C@'s fields to bottom.
\begin{code}
dsExpr (RecordConOut data_con con_expr rbinds)
......@@ -489,13 +494,13 @@ dsExpr (RecordConOut data_con con_expr rbinds)
\end{code}
Record update is a little harder. Suppose we have the decl:
\begin{verbatim}
data T = T1 {op1, op2, op3 :: Int}
| T2 {op4, op2 :: Int}
| T3
\end{verbatim}
Then we translate as follows:
\begin{verbatim}
r { op2 = e }
===>
let op2 = e in
......@@ -503,9 +508,9 @@ Then we translate as follows:
T1 op1 _ op3 -> T1 op1 op2 op3
T2 op4 _ -> T2 op4 op2
other -> recUpdError "M.lhs/230"
It's important that we use the constructor Ids for T1, T2 etc on the
RHSs, and do not generate a Core Con directly, because the constructor
\end{verbatim}
It's important that we use the constructor Ids for @T1@, @T2@ etc on the
RHSs, and do not generate a Core @Con@ directly, because the constructor
might do some argument-evaluation first; and may have to throw away some
dictionaries.
......@@ -569,8 +574,10 @@ dsExpr (RecordUpdOut record_expr record_out_ty dicts rbinds)
ok (sel_id, _, _) = recordSelectorFieldLabel sel_id `elem` con_fields
\end{code}
Dictionary lambda and application
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\noindent
\underline{\bf Dictionary lambda and application}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@DictLam@ and @DictApp@ turn into the regular old things.
(OLD:) @DictFunApp@ also becomes a curried application, albeit slightly more
complicated; reminiscent of fully-applied constructors.
......@@ -625,7 +632,7 @@ dsDo do_or_lc stmts return_id then_id fail_id result_ty
= do_expr expr locn `thenDs` \ expr2 ->
go stmts `thenDs` \ rest ->
let msg = ASSERT( isNotUsgTy b_ty )
"Pattern match failure in do expression, " ++ showSDoc (ppr locn) in
"Pattern match failure in do expression, " ++ showSDoc (ppr locn) in
returnDs (mkIfThenElse expr2
rest
(App (App (Var fail_id)
......@@ -635,7 +642,7 @@ dsDo do_or_lc stmts return_id then_id fail_id result_ty
go (ExprStmt expr locn : stmts)
= do_expr expr locn `thenDs` \ expr2 ->
let
(_, a_ty) = splitAppTy (coreExprType expr2) -- Must be of form (m a)
(_, a_ty) = splitAppTy (coreExprType expr2) -- Must be of form (m a)
in
if null stmts then
returnDs expr2
......@@ -653,13 +660,15 @@ dsDo do_or_lc stmts return_id then_id fail_id result_ty
= putSrcLocDs locn $
dsExpr expr `thenDs` \ expr2 ->
let
(_, a_ty) = splitAppTy (coreExprType expr2) -- Must be of form (m a)
fail_expr = HsApp (TyApp (HsVar fail_id) [b_ty]) (HsLitOut (HsString (_PK_ msg)) stringTy)
(_, a_ty) = splitAppTy (coreExprType expr2) -- Must be of form (m a)
fail_expr = HsApp (TyApp (HsVar fail_id) [b_ty])
(HsLitOut (HsString (_PK_ msg)) stringTy)
msg = ASSERT2( isNotUsgTy a_ty, ppr a_ty )
ASSERT2( isNotUsgTy b_ty, ppr b_ty )
"Pattern match failure in do expression, " ++ showSDoc (ppr locn)
main_match = mkSimpleMatch [pat]
(HsDoOut do_or_lc stmts return_id then_id fail_id result_ty locn)
(HsDoOut do_or_lc stmts return_id then_id
fail_id result_ty locn)
(Just result_ty) locn
the_matches
| failureFreePat pat = [main_match]
......
......@@ -47,15 +47,15 @@ import Outputable
Desugaring of @foreign@ declarations is naturally split up into
parts, an @import@ and an @export@ part. A @foreign import@
declaration
declaration
\begin{verbatim}
foreign import cc nm f :: prim_args -> IO prim_res
\end{verbatim}
is the same as
\begin{verbatim}
f :: prim_args -> IO prim_res
f a1 ... an = _ccall_ nm cc a1 ... an
\end{verbatim}
so we reuse the desugaring code in @DsCCall@ to deal with these.
\begin{code}
......@@ -63,8 +63,10 @@ dsForeigns :: Module
-> [TypecheckedForeignDecl]
-> DsM ( [CoreBind] -- desugared foreign imports
, [CoreBind] -- helper functions for foreign exports
, SDoc -- Header file prototypes for "foreign exported" functions.
, SDoc -- C stubs to use when calling "foreign exported" funs.
, SDoc -- Header file prototypes for
-- "foreign exported" functions.
, SDoc -- C stubs to use when calling
-- "foreign exported" functions.
)
dsForeigns mod_name fos = foldlDs combine ([],[],empty,empty) fos
where
......@@ -99,7 +101,7 @@ dsForeigns mod_name fos = foldlDs combine ([],[],empty,empty) fos
Desugaring foreign imports is just the matter of creating a binding
that on its RHS unboxes its arguments, performs the external call
(using the CCallOp primop), before boxing the result up and returning it.
(using the @CCallOp@ primop), before boxing the result up and returning it.
\begin{code}
dsFImport :: Id
......@@ -201,16 +203,16 @@ dsFLabel nm ext_name = returnDs (NonRec nm fo_rhs)
\end{code}
The function that does most of the work for 'foreign export' declarations.
(see below for the boilerplate code a 'foreign export' declaration expands
The function that does most of the work for `@foreign export@' declarations.
(see below for the boilerplate code a `@foreign export@' declaration expands
into.)
For each 'foreign export foo' in a module M we generate:
* a C function 'foo', which calls
* a Haskell stub 'M.$ffoo', which calls
the user-written Haskell function 'M.foo'.
For each `@foreign export foo@' in a module M we generate:
\begin{itemize}
\item a C function `@foo@', which calls
\item a Haskell stub `@M.$ffoo@', which calls
\end{itemize}
the user-written Haskell function `@M.foo@'.
\begin{code}
dsFExport :: Id
......@@ -267,7 +269,7 @@ dsFExport i ty mod_name ext_name cconv isDyn =
returnDs (i,
\ body -> body,
panic "stbl_ptr" -- should never be touched.
)) `thenDs` \ (i, getFun_wrapper, stbl_ptr) ->
)) `thenDs` \ (i, getFun_wrapper, stbl_ptr) ->
let
wrapper_args
| isDyn = stbl_ptr:fe_args
......@@ -291,7 +293,8 @@ dsFExport i ty mod_name ext_name cconv isDyn =
ExtName fs _ -> fs
Dynamic -> panic "dsFExport: Dynamic - shouldn't ever happen."
(h_stub, c_stub) = fexportEntry c_nm f_helper_glob wrapper_arg_tys the_result_ty cconv isDyn
(h_stub, c_stub) = fexportEntry c_nm f_helper_glob
wrapper_arg_tys the_result_ty cconv isDyn
in
returnDs (NonRec f_helper_glob the_body, h_stub, c_stub)
......@@ -333,7 +336,7 @@ dsFExport i ty mod_name ext_name cconv isDyn =
\end{code}
"foreign export dynamic" lets you dress up Haskell IO actions
@foreign export dynamic@ lets you dress up Haskell IO actions
of some fixed type behind an externally callable interface (i.e.,
as a C function pointer). Useful for callbacks and stuff.
......@@ -376,7 +379,8 @@ dsFExportDynamic i ty mod_name ext_name cconv =
fe_nm = toCName fe_id
fe_ext_name = ExtName (_PK_ fe_nm) Nothing
in