fay 0.2.0.0 → 0.2.1.0
raw patch · 6 files changed
+80/−18 lines, 6 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Language.Fay.FFI: foreignMethod :: Foreign a => String -> FayReturnType -> a
- Language.Fay.FFI: foreignMethodFay :: Foreign a => String -> FayReturnType -> a
+ Language.Fay: compileFFISetProp :: Type -> Name -> (String, String, FayReturnType) -> Compile [JsStmt]
+ Language.Fay.FFI: foreignProp :: Foreign a => String -> FayReturnType -> a
+ Language.Fay.FFI: foreignPropFay :: Foreign a => String -> FayReturnType -> a
+ Language.Fay.FFI: foreignSetProp :: (Foreign object, Foreign value) => String -> object -> value -> Fay ()
+ Language.Fay.Types: JsUpdateProp :: JsExp -> JsName -> JsExp -> JsExp
+ Language.Fay.Types: instance Eq FayReturnType
Files
- docs/snippets/ffi.hs +9/−0
- fay.cabal +13/−4
- src/Language/Fay.hs +41/−8
- src/Language/Fay/FFI.hs +13/−4
- src/Language/Fay/Print.hs +2/−0
- src/Language/Fay/Types.hs +2/−2
docs/snippets/ffi.hs view
@@ -3,3 +3,12 @@ alert :: Foreign a => a -> Fay () alert = foreignFay "window.alert" ""++thebody :: Element+thebody = foreignPure "document.body" FayNone++getInnerHtml :: Element -> Fay String+getInnerHtml = foreignPropFay "innerHTML" FayString++setInnerHtml :: Element -> String -> Fay ()+setInnerHtml = foreignSetProp "innerHTML"
fay.cabal view
@@ -1,5 +1,5 @@ name: fay-version: 0.2.0.0+version: 0.2.1.0 synopsis: A compiler for Fay, a Haskell subset that compiles to JavaScript. description: Fay is a proper subset of Haskell which can be compiled (type-checked) with GHC, and compiled to JavaScript. It is lazy, pure, with a Fay monad,@@ -10,7 +10,9 @@ . See documentation at <http://fay-lang.org/> or build your own documentation with: .- > $ cabal build+ > $ cabal unpack fay+ > $ cd fay-*+ > $ cabal install > $ dist/build/fay-docs/fay-docs . . @@ -20,8 +22,15 @@ . /Release Notes/ .- * Changed the return type specification of the FFI, breaking change. You will have- to change your code.+ Support setting properties.+ .+ * Support assigning props (closes #10).+ .+ * Support zero-arg functions i.e. values.+ .+ * Add node example (closes #15).+ .+ * Add warning in the build script. . See full history at: <https://github.com/chrisdone/fay/commits> homepage: http://fay-lang.org/
src/Language/Fay.hs view
@@ -150,25 +150,34 @@ compilePatBind sig pat = do case pat of PatBind _ (PVar ident) Nothing (UnGuardedRhs rhs) (BDecls []) ->- case ffiExp rhs of+ case ffiExp rhs <|> ffiProp rhs of Just detail@(binding,_,_) -> case sig of Nothing -> compileNormalPatBind ident rhs Just sig -> case () of () | func binding -> compileFFIFunc sig ident detail | method binding -> compileFFIMethod sig ident detail+ | setprop binding -> compileFFISetProp sig ident detail+-- | value binding -> compileFFIValue sig ident detail | otherwise -> throwError (FfiNeedsTypeSig pat) _ -> compileNormalPatBind ident rhs _ -> throwError (UnsupportedDeclaration pat) where func = flip elem ["foreignFay","foreignPure"]- method = flip elem ["foreignMethodFay","foreignMethod"]+ method = flip elem ["foreignPropFay","foreignProp"]+ setprop = flip elem ["foreignSetProp"]+ ffiExp (App (App (Var (UnQual (Ident ident))) (Lit (String name))) (Con (UnQual (Ident (reads -> [(typ,"")]))))) = Just (ident,name,typ) ffiExp _ = Nothing + ffiProp (App (Var (UnQual (Ident ident)))+ (Lit (String name)))+ = Just (ident,name,FayNone)+ ffiProp _ = Nothing+ -- | Compile a normal simple pattern binding. compileNormalPatBind :: Name -> Exp -> Compile [JsStmt] compileNormalPatBind ident rhs = do@@ -190,6 +199,24 @@ obj = head args compileFFI sig ident detail (JsGetProp (force (JsName obj)) (fromString name)) args jsargs +-- | Compile a foreign method.+compileFFISetProp :: Type -> Name -> (String,String,FayReturnType) -> Compile [JsStmt]+compileFFISetProp sig ident detail@(_,name,_) = do+ let args = zipWith const uniqueNames [1..typeArity sig]+ jsargs = drop 1 args+ obj = head args+ compileFFI sig+ ident+ detail+ (JsUpdateProp (force (JsName obj))+ (fromString name)+ (serialize (head (tail funcTypes))+ (JsName (head jsargs))))+ args+ []+ + where funcTypes = functionTypeArgs sig+ -- | Compile an FFI call. compileFFI :: Type -> Name@@ -199,20 +226,26 @@ -> [JsName] -> Compile [JsStmt] compileFFI sig ident (binding,_,typ) exp params args = do+ let innerexp+ | length args == 0 = exp+ | binding == "foreignSetProp" = exp+ | otherwise = JsApp exp+ (map (\(typ,name) -> serialize typ (JsName name))+ (zip types args)) bind <- bindToplevel (UnQual ident) (foldr (\name inner -> JsFun [name] [] (Just inner)) (thunk (maybeMonad- (unserialize typ- (JsApp exp- (map (\(typ,name) -> serialize typ (JsName name))- (zip types args))))))+ (if binding == "foreignSetProp"+ then innerexp+ else unserialize typ innerexp))) params) return [bind] where (maybeMonad,types) | binding == "foreignFay" = (monad,funcTypes)- | binding == "foreignMethodFay" = (monad,drop 1 funcTypes)- | binding == "foreignMethod" = (id,drop 1 funcTypes)+ | binding == "foreignPropFay" = (monad,drop 1 funcTypes)+ | binding == "foreignProp" = (id,drop 1 funcTypes)+ | binding == "foreignSetProp" = (monad,[]) | otherwise = (id,funcTypes) funcTypes = functionTypeArgs sig
src/Language/Fay/FFI.hs view
@@ -53,17 +53,26 @@ foreignPure = error "Language.Fay.FFI.foreign: Used foreign function not in a JS engine context." -- | Declare a foreign action.-foreignMethodFay+foreignPropFay :: Foreign a => String -- ^ The foreign function name. -> FayReturnType -- ^ JS return type. -> a -- ^ Bottom.-foreignMethodFay = error "Language.Fay.FFI.foreignMethodFay: Used foreign function not in a JS engine context."+foreignPropFay = error "Language.Fay.FFI.foreignPropFay: Used foreign function not in a JS engine context." -- | Declare a foreign function.-foreignMethod+foreignProp :: Foreign a => String -- ^ The foreign function name. -> FayReturnType -- ^ JS return type. -> a -- ^ Bottom.-foreignMethod = error "Language.Fay.FFI.foreignMethod: Used foreign function not in a JS engine context."+foreignProp = error "Language.Fay.FFI.foreignProp: Used foreign function not in a JS engine context."++-- | Declare a foreign action.+foreignSetProp+ :: (Foreign object,Foreign value)+ => String -- ^ The property.+ -> object -- ^ The object.+ -> value -- ^ The value.+ -> Fay () -- ^ Bottom.+foreignSetProp = error "Language.Fay.FFI.foreignSetProp: Used foreign function not in a JS engine context."
src/Language/Fay/Print.hs view
@@ -149,6 +149,8 @@ printJS exp1 ++ " === " ++ printJS exp2 printJS (JsGetProp exp prop) = printJS exp ++ "." ++ printJS prop+ printJS (JsUpdateProp name prop expr) =+ (concat ["(",printJS name,".",printJS prop," = ",printJS expr,")"]) printJS (JsInfix op x y) = printJS x ++ " " ++ op ++ " " ++ printJS y
src/Language/Fay/Types.hs view
@@ -130,6 +130,7 @@ | JsSequence [JsExp] | JsParen JsExp | JsGetProp JsExp JsName+ | JsUpdateProp JsExp JsName JsExp | JsList [JsExp] | JsNew JsName [JsExp] | JsThrowExp JsExp@@ -149,5 +150,4 @@ deriving (Show,Eq) data FayReturnType = FayArray | FayList | FayString | FayNone- deriving (Read,Show)-+ deriving (Read,Show,Eq)