2012-06-25 12:08:48 +00:00
|
|
|
|
2012-11-23 04:15:59 +00:00
|
|
|
module Parse.Foreign (foreignDef) where
|
2012-06-25 12:08:48 +00:00
|
|
|
|
|
|
|
import Control.Applicative ((<$>), (<*>))
|
|
|
|
import Data.Either (partitionEithers)
|
|
|
|
import Text.Parsec hiding (newline,spaces)
|
|
|
|
|
|
|
|
import Ast
|
2012-11-23 04:15:59 +00:00
|
|
|
import Parse.Library
|
|
|
|
import Parse.Expr (term)
|
2012-11-23 04:24:20 +00:00
|
|
|
import Parse.Types
|
2012-11-23 04:30:37 +00:00
|
|
|
import Types.Types (signalOf)
|
2012-06-25 12:08:48 +00:00
|
|
|
|
|
|
|
|
2012-08-01 23:37:37 +00:00
|
|
|
foreignDef = do try (reserved "foreign") ; whitespace
|
|
|
|
importEvent <|> exportEvent
|
2012-06-25 12:08:48 +00:00
|
|
|
|
|
|
|
exportEvent = do
|
2012-06-28 08:52:47 +00:00
|
|
|
try (reserved "export" >> whitespace >> reserved "jsevent" >> whitespace)
|
2012-06-25 12:08:48 +00:00
|
|
|
js <- jsVar ; whitespace
|
|
|
|
elm <- lowVar ; whitespace
|
2013-02-04 10:56:22 +00:00
|
|
|
hasType ; whitespace
|
2012-06-25 12:08:48 +00:00
|
|
|
tipe <- typeExpr
|
|
|
|
case tipe of
|
|
|
|
ADTPT "Signal" [pt] ->
|
2012-08-01 23:37:37 +00:00
|
|
|
either fail (return . ExportEvent js elm . signalOf) (toForeignType pt)
|
2012-06-25 12:08:48 +00:00
|
|
|
_ -> fail "When exporting events, the exported value must be a Signal."
|
|
|
|
|
|
|
|
importEvent = do
|
2012-06-28 08:52:47 +00:00
|
|
|
try (reserved "import" >> whitespace >> reserved "jsevent" >> whitespace)
|
|
|
|
js <- jsVar ; whitespace
|
|
|
|
base <- term <?> "Base case for imported signal (signals cannot be undefined)"
|
|
|
|
whitespace
|
|
|
|
elm <- lowVar <?> "Name of imported signal"
|
2013-02-04 10:56:22 +00:00
|
|
|
whitespace ; hasType ; whitespace
|
2012-06-25 12:08:48 +00:00
|
|
|
tipe <- typeExpr
|
|
|
|
case tipe of
|
|
|
|
ADTPT "Signal" [pt] ->
|
2012-08-01 23:37:37 +00:00
|
|
|
either fail (return . ImportEvent js base elm . signalOf) (toForeignType pt)
|
2012-06-25 12:08:48 +00:00
|
|
|
_ -> fail "When importing events, the imported value must be a Signal."
|
|
|
|
|
|
|
|
|
|
|
|
jsVar :: (Monad m) => ParsecT [Char] u m String
|
|
|
|
jsVar = betwixt '"' '"' $ do
|
|
|
|
v <- (:) <$> (letter <|> char '_') <*> many (alphaNum <|> char '_')
|
|
|
|
if v `notElem` jsReserveds then return v else
|
|
|
|
fail $ "'" ++ v ++
|
|
|
|
"' is not a good name for a importing or exporting JS values."
|
|
|
|
|
|
|
|
jsReserveds =
|
|
|
|
[ "null", "undefined", "Nan", "Infinity", "true", "false", "eval"
|
|
|
|
, "arguments", "int", "byte", "char", "goto", "long", "final", "float"
|
|
|
|
, "short", "double", "native", "throws", "boolean", "abstract", "volatile"
|
|
|
|
, "transient", "synchronized", "function", "break", "case", "catch"
|
|
|
|
, "continue", "debugger", "default", "delete", "do", "else", "finally"
|
|
|
|
, "for", "function", "if", "in", "instanceof", "new", "return", "switch"
|
|
|
|
, "this", "throw", "try", "typeof", "var", "void", "while", "with", "class"
|
|
|
|
, "const", "enum", "export", "extends", "import", "super", "implements"
|
|
|
|
, "interface", "let", "package", "private", "protected", "public"
|
|
|
|
, "static", "yield"
|
|
|
|
]
|