on master help sign in
javascript: positional arguments
commit3e693f7f7b351491acca577755ac6d381f6a5ecd authorraichoo <raichoo@googlemail.com> dateFri 13 Sep 2013, 17:16 (13 years ago) parent6086376
2 files changed+59−70
javascript/JavaScript.idr+16−13 src/IRTS/CodegenJavaScript.hs+43−57
javascript/JavaScript.idr+16−13
@@ -2,12 +2,11 @@ module JavaScript
22
33%access public
44
5−-- TODO: Get rid of this hack, and find a better way.
65private
76isUndefined : Ptr -> IO Bool
87isUndefined p = do
98 res <- mkForeign (
10− FFun "(function(arg) { return arg === undefined;})" [FPtr] FString) p
9+ FFun "%0 === undefined" [FPtr] FString) p
1110 if res == "false"
1211 then (return False)
1312 else (return True)
@@ -28,15 +27,15 @@ data Element : Type where
2827
2928setText : Element -> String -> IO ()
3029setText (MkElem p) s =
31− mkForeign (FFun ".textContent=" [FPtr, FString] FUnit) p s
30+ mkForeign (FFun "%0.textContent=%1" [FPtr, FString] FUnit) p s
3231
3332
3433setOnClick : Element -> (Event -> IO Bool) -> IO ()
3534setOnClick (MkElem e) f =
3635 mkForeign (
37− FFun "['onclick']=" [ FPtr
38− , FFunction (FAny Event) (FAny (IO Bool))
39− ] FUnit) e f
36+ FFun "%0['onclick']=%1" [ FPtr
37+ , FFunction (FAny Event) (FAny (IO Bool))
38+ ] FUnit) e f
4039--------------------------------------------------------------------------------
4140-- Nodelists
4241--------------------------------------------------------------------------------
@@ -46,7 +45,9 @@ data NodeList : Type where
4645
4746elemAt : NodeList -> Nat -> IO (Maybe Element)
4847elemAt (MkNodeList p) i = do
49− e <- mkForeign (FFun ".item" [FPtr, FInt] FPtr) p (prim__truncBigInt_Int (cast i))
48+ e <- mkForeign (FFun "%0.item(%1)" [FPtr, FInt] FPtr) p (
49+ prim__truncBigInt_Int (cast i)
50+ )
5051 d <- isUndefined e
5152 if d
5253 then return $ Just (MkElem e)
@@ -62,12 +63,13 @@ data Interval : Type where
6263setInterval : (() -> IO ()) -> Float -> IO Interval
6364setInterval f t = do
6465 e <- mkForeign (
65− FFun "setInterval" [FFunction FUnit (FAny (IO ())), FFloat] FPtr) f t
66+ FFun "setInterval(%0,%1)" [FFunction FUnit (FAny (IO ())), FFloat] FPtr
67+ ) f t
6668 return (MkInterval e)
6769
6870clearInterval : Interval -> IO ()
6971clearInterval (MkInterval p) =
70− mkForeign (FFun "clearInterval" [FPtr] FUnit) p
72+ mkForeign (FFun "clearInterval(%0)" [FPtr] FUnit) p
7173
7274--------------------------------------------------------------------------------
7375-- Timeouts
@@ -78,24 +80,25 @@ data Timeout : Type where
7880setTimeout : (() -> IO ()) -> Float -> IO Timeout
7981setTimeout f t = do
8082 e <- mkForeign (
81− FFun "setTimeout" [FFunction FUnit (FAny (IO ())), FFloat] FPtr) f t
83+ FFun "setTimeout(%0,%1)" [FFunction FUnit (FAny (IO ())), FFloat] FPtr
84+ ) f t
8285 return (MkTimeout e)
8386
8487clearTimeout : Timeout -> IO ()
8588clearTimeout (MkTimeout p) =
86− mkForeign (FFun "clearTimeout" [FPtr] FUnit) p
89+ mkForeign (FFun "clearTimeout(%0)" [FPtr] FUnit) p
8790
8891--------------------------------------------------------------------------------
8992-- Basic IO
9093--------------------------------------------------------------------------------
9194alert : String -> IO ()
9295alert msg =
93− mkForeign (FFun "alert" [FString] FUnit) msg
96+ mkForeign (FFun "alert(%0)" [FString] FUnit) msg
9497
9598--------------------------------------------------------------------------------
9699-- DOM
97100--------------------------------------------------------------------------------
98101query : String -> IO NodeList
99102query q = do
100− e <- mkForeign (FFun "document.querySelectorAll" [FString] FPtr) q
103+ e <- mkForeign (FFun "document.querySelectorAll(%0)" [FString] FPtr) q
101104 return (MkNodeList e)
src/IRTS/CodegenJavaScript.hs+43−57
@@ -325,11 +325,16 @@ translateName NErased = ""
325325
326326translateSpecialName :: SpecialName -> String
327327translateSpecialName name
328− | WhereN i m n <- name = translateName m ++ translateName n ++ show i
329− | InstanceN n s <- name = translateName n ++ concatMap translateIdentifier s
330− | ParentN n s <- name = translateName n ++ translateIdentifier s
331− | MethodN n <- name = translateName n
332− | CaseN n <- name = translateName n
328+ | WhereN i m n <- name =
329+ "_where" ++ show i ++ "_" ++ translateName m ++ translateName n
330+ | InstanceN n s <- name =
331+ "_inst_" ++ translateName n ++ concatMap translateIdentifier s
332+ | ParentN n s <- name =
333+ "_parent_" ++ translateName n ++ translateIdentifier s
334+ | MethodN n <- name =
335+ "_meth_" ++ translateName n
336+ | CaseN n <- name =
337+ "_case_" ++ translateName n
333338
334339translateConstant :: Const -> JS
335340translateConstant (I i) = JSNum (JSInt i)
@@ -626,59 +631,9 @@ translateExpression (SError msg) =
626631translateExpression (SForeign _ _ "putStr" [(FString, var)]) =
627632 jsCall (idrRTNamespace ++ "print") [JSVar var]
628633
629−translateExpression (SForeign _ _ fun args)
630− | "[]=" `isSuffixOf` fun
631− , (obj:idx:val:[]) <- args =
632− JSRaw $ concat [object obj, index idx, assign val]
633−
634− | "[]" `isSuffixOf` fun
635− , (obj:idx:[]) <- args =
636− JSRaw $ object obj ++ index idx
637−
638− | "[" `isPrefixOf` fun && "]=" `isSuffixOf` fun
639− , (obj:val:[]) <- args =
640− JSRaw $ concat [object obj, '[' : name ++ "]", assign val]
641−
642− | "[" `isPrefixOf` fun && "]" `isSuffixOf` fun
643− , (obj:[]) <- args =
644− JSRaw $ object obj ++ '[' : name ++ "]"
645−
646− | "." `isPrefixOf` fun, "=" `isSuffixOf` fun
647− , (obj:val:[]) <- args =
648− JSRaw $ concat [object obj, field, assign val]
649−
650− | "." `isPrefixOf` fun
651− , (obj:[]) <- args =
652− JSRaw $ object obj ++ field
653−
654− | "." `isPrefixOf` fun
655− , (obj:[(FUnit, _)]) <- args =
656− JSRaw $ concat [object obj, method, "()"]
657−
658− | "." `isPrefixOf` fun
659− , (obj:as) <- args =
660− JSRaw $ concat [object obj, method, arguments as]
661−
662− | "[]=" `isSuffixOf` fun
663− , (idx:val:[]) <- args =
664− JSRaw $ concat [array, index idx, assign val]
665−
666− | "[]" `isSuffixOf` fun
667− , (idx:[]) <- args =
668− JSRaw $ array ++ index idx
669−
670− | otherwise = JSRaw $ fun ++ arguments args
634+translateExpression (SForeign _ _ fun args) =
635+ ffi fun (map generateWrapper args)
671636 where
672− name = filter (`notElem` "[]=") fun
673− method = name
674− field = name
675− array = name
676− object o = translateVariableName (snd o)
677− index i = "[" ++ translateVariableName (snd i) ++ "]"
678− assign v = '=' : generateWrapper v
679− arguments as =
680− '(' : intercalate "," (map generateWrapper as) ++ ")"
681−
682637 generateWrapper (ffunc, name)
683638 | FFunction <- ffunc =
684639 idrRTNamespace ++ "ffiWrap(" ++ translateVariableName name ++ ")"
@@ -727,6 +682,37 @@ translateExpression SNothing = JSNull
727682translateExpression e =
728683 JSError $ "Not yet implemented: " ++ filter (/= '\'') (show e)
729684
685+data FFI = FFICode Char | FFIArg Int | FFIError String
686+
687+ffi :: String -> [String] -> JS
688+ffi code args = let parsed = ffiParse code in
689+ case ffiError parsed of
690+ Just err -> JSError err
691+ Nothing -> JSRaw $ renderFFI parsed args
692+ where
693+ ffiParse :: String -> [FFI]
694+ ffiParse "" = []
695+ ffiParse ['%'] = [FFIError "Invalid positional argument"]
696+ ffiParse ('%':'%':ss) = FFICode '%' : ffiParse ss
697+ ffiParse ('%':s:ss)
698+ | isDigit s =
699+ FFIArg (read $ s : takeWhile isDigit ss) : ffiParse (dropWhile isDigit ss)
700+ | otherwise =
701+ [FFIError "Invalid positional argument"]
702+ ffiParse (s:ss) = FFICode s : ffiParse ss
703+
704+ ffiError :: [FFI] -> Maybe String
705+ ffiError [] = Nothing
706+ ffiError ((FFIError s):xs) = Just s
707+ ffiError (x:xs) = ffiError xs
708+
709+ renderFFI :: [FFI] -> [String] -> String
710+ renderFFI [] _ = ""
711+ renderFFI ((FFICode c) : fs) args = c : renderFFI fs args
712+ renderFFI ((FFIArg i) : fs) args
713+ | i < length args && i >= 0 = args !! i ++ renderFFI fs args
714+ | otherwise = "Argument index out of bounds"
715+
730716data CaseType = ConCase Int
731717 | TypeCase JSType
732718 | DefaultCase