@@ -325,11 +325,16 @@ translateName NErased = ""
326translateSpecialName :: SpecialName -> String
326translateSpecialName :: SpecialName -> String
327translateSpecialName name
327translateSpecialName name
328− | WhereN i m n <- name = translateName m ++ translateName n ++ show i
328+ | WhereN i m n <- name =
329+ "_where" ++ show i ++ "_" ++ translateName m ++ translateName n
330+ | InstanceN n s <- name =
329− | InstanceN n s <- name = translateName n ++ concatMap translateIdentifier s
331+ "_inst_" ++ translateName n ++ concatMap translateIdentifier s
332+ | ParentN n s <- name =
330− | ParentN n s <- name = translateName n ++ translateIdentifier s
333+ "_parent_" ++ translateName n ++ translateIdentifier s
331− | MethodN n <- name = translateName n
334+ | MethodN n <- name =
335+ "_meth_" ++ translateName n
332− | CaseN n <- name = translateName n
337+ "_case_" ++ translateName n
334translateConstant :: Const -> JS
339translateConstant :: Const -> JS
335translateConstant (I i) = JSNum (JSInt i)
340translateConstant (I i) = JSNum (JSInt i)
@@ -626,59 +631,9 @@ translateExpression (SError msg) =
626translateExpression (SForeign _ _ "putStr" [(FString, var)]) =
631translateExpression (SForeign _ _ "putStr" [(FString, var)]) =
627 jsCall (idrRTNamespace ++ "print") [JSVar var]
632 jsCall (idrRTNamespace ++ "print") [JSVar var]
629−translateExpression (SForeign _ _ fun args)
634+translateExpression (SForeign _ _ fun args) =
630− | "[]=" `isSuffixOf` fun
635+ ffi fun (map generateWrapper args)
631− , (obj:idx:val:[]) <- args =
632− JSRaw $ concat [object obj, index idx, assign val]
634− | "[]" `isSuffixOf` fun
635− , (obj:idx:[]) <- args =
636− JSRaw $ object obj ++ index idx
638− | "[" `isPrefixOf` fun && "]=" `isSuffixOf` fun
639− , (obj:val:[]) <- args =
640− JSRaw $ concat [object obj, '[' : name ++ "]", assign val]
642− | "[" `isPrefixOf` fun && "]" `isSuffixOf` fun
643− , (obj:[]) <- args =
644− JSRaw $ object obj ++ '[' : name ++ "]"
646− | "." `isPrefixOf` fun, "=" `isSuffixOf` fun
647− , (obj:val:[]) <- args =
648− JSRaw $ concat [object obj, field, assign val]
650− | "." `isPrefixOf` fun
651− , (obj:[]) <- args =
652− JSRaw $ object obj ++ field
654− | "." `isPrefixOf` fun
655− , (obj:[(FUnit, _)]) <- args =
656− JSRaw $ concat [object obj, method, "()"]
658− | "." `isPrefixOf` fun
659− , (obj:as) <- args =
660− JSRaw $ concat [object obj, method, arguments as]
662− | "[]=" `isSuffixOf` fun
663− , (idx:val:[]) <- args =
664− JSRaw $ concat [array, index idx, assign val]
666− | "[]" `isSuffixOf` fun
667− , (idx:[]) <- args =
668− JSRaw $ array ++ index idx
670− | otherwise = JSRaw $ fun ++ arguments args
672− name = filter (`notElem` "[]=") fun
676− object o = translateVariableName (snd o)
677− index i = "[" ++ translateVariableName (snd i) ++ "]"
678− assign v = '=' : generateWrapper v
680− '(' : intercalate "," (map generateWrapper as) ++ ")"
682 generateWrapper (ffunc, name)
637 generateWrapper (ffunc, name)
683 | FFunction <- ffunc =
638 | FFunction <- ffunc =
684 idrRTNamespace ++ "ffiWrap(" ++ translateVariableName name ++ ")"
639 idrRTNamespace ++ "ffiWrap(" ++ translateVariableName name ++ ")"
@@ -727,6 +682,37 @@ translateExpression SNothing = JSNull
727translateExpression e =
682translateExpression e =
728 JSError $ "Not yet implemented: " ++ filter (/= '\'') (show e)
683 JSError $ "Not yet implemented: " ++ filter (/= '\'') (show e)
685+data FFI = FFICode Char | FFIArg Int | FFIError String
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
693+ ffiParse :: String -> [FFI]
695+ ffiParse ['%'] = [FFIError "Invalid positional argument"]
696+ ffiParse ('%':'%':ss) = FFICode '%' : ffiParse ss
699+ FFIArg (read $ s : takeWhile isDigit ss) : ffiParse (dropWhile isDigit ss)
701+ [FFIError "Invalid positional argument"]
702+ ffiParse (s:ss) = FFICode s : ffiParse ss
704+ ffiError :: [FFI] -> Maybe String
705+ ffiError [] = Nothing
706+ ffiError ((FFIError s):xs) = Just s
707+ ffiError (x:xs) = ffiError xs
709+ renderFFI :: [FFI] -> [String] -> String
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"
730data CaseType = ConCase Int
716data CaseType = ConCase Int
731 | TypeCase JSType
717 | TypeCase JSType
732 | DefaultCase
718 | DefaultCase