@@ -132,6 +132,37 @@ data JS = JSRaw String
133data FFI = FFICode Char | FFIArg Int | FFIError String
133data FFI = FFICode Char | FFIArg Int | FFIError String
135+ffi :: String -> [String] -> String
136+ffi code args = let parsed = ffiParse code in
137+ case ffiError parsed of
138+ Just err -> error err
139+ Nothing -> renderFFI parsed args
141+ ffiParse :: String -> [FFI]
143+ ffiParse ['%'] = [FFIError $ "FFI - Invalid positional argument"]
144+ ffiParse ('%':'%':ss) = FFICode '%' : ffiParse ss
147+ FFIArg (read $ s : takeWhile isDigit ss) : ffiParse (dropWhile isDigit ss)
149+ [FFIError $ "FFI - Invalid positional argument"]
150+ ffiParse (s:ss) = FFICode s : ffiParse ss
153+ ffiError :: [FFI] -> Maybe String
154+ ffiError [] = Nothing
155+ ffiError ((FFIError s):xs) = Just s
156+ ffiError (x:xs) = ffiError xs
159+ renderFFI :: [FFI] -> [String] -> String
161+ renderFFI ((FFICode c) : fs) args = c : renderFFI fs args
162+ renderFFI ((FFIArg i) : fs) args
163+ | i < length args && i >= 0 = args !! i ++ renderFFI fs args
164+ | otherwise = error "FFI - Argument index out of bounds"
135compileJS :: JS -> String
166compileJS :: JS -> String
136compileJS = compileJS' 0
167compileJS = compileJS' 0
@@ -141,8 +172,8 @@ compileJS' indent JSNoop = ""
141compileJS' indent (JSAnnotation annotation js) =
172compileJS' indent (JSAnnotation annotation js) =
142 "/** @" ++ show annotation ++ " */\n" ++ compileJS' indent js
173 "/** @" ++ show annotation ++ " */\n" ++ compileJS' indent js
144−{-compileJS' indent (JSFFI raw args) =-}
175+compileJS' indent (JSFFI raw args) =
145− {-ffi raw (map compileJS' indent args)-}
176+ ffi raw (map (compileJS' indent) args)
147compileJS' indent (JSRaw code) =
178compileJS' indent (JSRaw code) =
@@ -601,6 +632,28 @@ jsFOREIGN _ reg n args
602 JSBinOp "==" (translateReg lhs) (translateReg rhs)
633 JSBinOp "==" (translateReg lhs) (translateReg rhs)
639+ JSFFI n (map generateWrapper args)
642+ generateWrapper :: (FType, Reg) -> JS
643+ generateWrapper (ty, reg)
645+ JSApp (JSIdent "i$ffiWrap") [ translateReg reg
647+ , JSIdent "myoldbase"
649+ | FFunctionIO <- ty =
650+ JSApp (JSIdent "i$ffiWrap") [ translateReg reg
652+ , JSIdent "myoldbase"
655+ generateWrapper (_, reg) =
605jsREBASE :: CompileInfo -> JS
658jsREBASE :: CompileInfo -> JS
606jsREBASE _ = JSAssign jsSTACKBASE jsOLDBASE
659jsREBASE _ = JSAssign jsSTACKBASE jsOLDBASE