| 1 |
{-# OPTIONS_GHC -fglasgow-exts -cpp -fallow-overlapping-instances #-} |
|---|
| 2 |
|
|---|
| 3 |
{-| |
|---|
| 4 |
External call utilities. |
|---|
| 5 |
|
|---|
| 6 |
> To the Sea, to the Sea! The white gulls are crying, |
|---|
| 7 |
> The wind is blowing, and the white foam is flying. |
|---|
| 8 |
> West, west away, the round sun is falling. |
|---|
| 9 |
> Grey ship, grey ship, do you hear them calling? |
|---|
| 10 |
-} |
|---|
| 11 |
|
|---|
| 12 |
module Pugs.External where |
|---|
| 13 |
import Pugs.Internals |
|---|
| 14 |
import Pugs.AST |
|---|
| 15 |
import Pugs.External.Haskell (externalizeHaskell, loadHaskell) |
|---|
| 16 |
|
|---|
| 17 |
externalize :: String -> Exp -> IO String |
|---|
| 18 |
externalize mod stmts = externExternalize backend mod code |
|---|
| 19 |
where |
|---|
| 20 |
(backend, code) |
|---|
| 21 |
| null things = error "no inline found" |
|---|
| 22 |
| [_] <- things = head things |
|---|
| 23 |
| otherwise = error "multiple inline found" |
|---|
| 24 |
things = [ (backend, code) |
|---|
| 25 |
| (Syn "inline" [Val (VStr backend), Val (VStr code)]) <- flatten stmts |
|---|
| 26 |
] |
|---|
| 27 |
flatten (Stmts cur rest) = (cur:flatten rest) |
|---|
| 28 |
flatten exp = [exp] |
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
externExternalize :: String -> String -> String -> IO String |
|---|
| 32 |
externExternalize "Haskell" = externalizeHaskell |
|---|
| 33 |
externExternalize backend = error $ "Unrecognized inline backend: " ++ backend |
|---|
| 34 |
|
|---|
| 35 |
externLoad :: String -> FilePath -> IO [(String, [Val] -> Eval Val)] |
|---|
| 36 |
externLoad "Haskell" = loadHaskell |
|---|
| 37 |
externLoad backend = error $ "Unrecognized inline backend: " ++ backend |
|---|
| 38 |
|
|---|
| 39 |
externRequire :: String -> FilePath -> Eval () |
|---|
| 40 |
externRequire lang name = do |
|---|
| 41 |
glob <- asks envGlobal |
|---|
| 42 |
bindings <- io $ externLoad lang name |
|---|
| 43 |
stm $ do |
|---|
| 44 |
newSyms <- mapM gen bindings |
|---|
| 45 |
modifyMPad glob (\pad -> combine newSyms pad) |
|---|
| 46 |
where |
|---|
| 47 |
gen (name, fun) = genSym (cast ('&':name)) . codeRef $ mkPrim |
|---|
| 48 |
{ subName = cast name |
|---|
| 49 |
, subParams = [buildParam "List" "" "*@?1" (Val VUndef)] |
|---|
| 50 |
, subBody = (Prim fun) |
|---|
| 51 |
} |
|---|
| 52 |
|
|---|