@@ -15,7 +15,7 @@ import qualified SourceSyntax.Declaration as D
17declaration :: IParser (D.Declaration t v)
17declaration :: IParser (D.Declaration t v)
18−declaration = alias <|> datatype <|> infixDecl <|> foreignDef <|> definition
18+declaration = alias <|> datatype <|> infixDecl <|> port <|> definition
20definition :: IParser (D.Declaration t v)
20definition :: IParser (D.Declaration t v)
21definition = D.Definition <$> Expr.def
21definition = D.Definition <$> Expr.def
@@ -56,67 +56,23 @@ infixDecl = do
56 D.Fixity assoc (read [n]) <$> anyOp
56 D.Fixity assoc (read [n]) <$> anyOp
59−foreignDef :: IParser (D.Declaration t v)
59+port :: IParser (D.Declaration t v)
60−foreignDef = do
60+port =
61− try (reserved "foreign")
63− importEvent <|> exportEvent
65−exportEvent :: IParser (D.Declaration t v)
67− try (reserved "export") >> padded (reserved "jsevent")
61+ do try (reserved "port")
69− whitespace
62+ whitespace
70− elmVar <- lowVar
63+ name <- lowVar
71− padded hasType
64+ padded hasType
72− tipe <- Type.expr
65+ tipe <- Type.expr
73− case tipe of
66+ expr <- choice [ do try (outPort name)
74− T.Data "Signal" [t] ->
75− case isExportable t of
76− Nothing -> return (D.ExportEvent eventName elmVar tipe)
78− _ -> fail "When importing foreign events, the imported value must have type Signal."
80−importEvent :: IParser (D.Declaration t v)
82− try (reserved "import") >> padded (reserved "jsevent")
84− baseValue <- padded Expr.term
85− <?> "Base case for imported signal (signals cannot be undefined)"
86− elmVar <- lowVar <?> "Name of imported signal"
87− padded hasType
67+ padded equals
88− tipe <- Type.expr
68+ Just <$> Expr.expr
89− case tipe of
69+ , return Nothing
90− T.Data "Signal" [t] ->
70+ ]
91− case isExportable t of
71+ return $ D.Port name tipe expr
92− Nothing -> return (D.ImportEvent eventName baseValue elmVar tipe)
94− _ -> fail "When importing foreign events, the imported value must have type Signal."
96−jsVar :: IParser String
97−jsVar = betwixt '"' '"' $ do
98− v <- (:) <$> (letter <|> char '_') <*> many (alphaNum <|> char '_')
99− if Set.notMember v jsReserveds then return v else
101− "' is not a good name for a importing or exporting JS values."
106− Just $ "Elm's JavaScript event interface does not yet handle functions. " ++
107− "Only simple values can be imported and exported in this release."
109− T.Data "JSArray" [t] -> isExportable t
112− | any (`List.isSuffixOf` name) jsTypes -> Nothing
113− | otherwise -> Just $ "'" ++ name ++ "' is not an exportable type." ++ msg
116− Just $ "'" ++ name ++ "' is not an exportable type " ++
117− "constructor. Only 'JSArray' is an exportable container."
119− T.Var _ -> Just $ "Cannot export type variables." ++ msg
121− msg = " The following types are exportable: " ++ List.intercalate ", " jsTypes
73+ outPort name = do
122− jsTypes = ["JSString","JSNumber","JSDomNode","JSBool","JSObject"]
74+ freshLine
78+ if name == name' then return () else fail "different port"