hsc3-rw-0.15: Sound/SC3/RW/HA.hs
-- | Hash at-sign. A simple minded haskell pre-processor that extends
-- the haskell syntax by rewriting @#\@@ sequences with a string
-- indicating the line and column number of the occurence. The basic
-- pre-processor is 'ha_rewrite'.
module Sound.SC3.RW.HA where
import System.Environment {- base -}
-- * Hash At-Sign
-- | Find next /hash-at/, if there is one.
--
-- > ha_split 0 "let o = sinOsc AR (rand #@ 220 440) 0 * 0.1"
ha_split :: Integer -> String -> (Integer, String, String)
ha_split =
let recur r n s =
case s of
[] -> (n,reverse r,[])
'#' : '@' : s' -> (n + 2,reverse r,s')
c : s' -> recur (c : r) (n + 1) s'
in recur []
-- | Generate replacement for /hash-at/ given line and column numbers.
--
-- > ha_insert 14 23 == "(hash \"14:21\")"
ha_insert :: Integer -> Integer -> String
ha_insert ln cn = concat ["(hash \"",show ln,":",show (cn - 2),"\")"]
-- | Process line given line number.
--
-- > putStrLn$ha_process_ln 1 "let o = sinOsc AR (rand #@ 220 440) (rand2 #@ pi) * 0.1"
ha_process_ln :: Integer -> String -> String
ha_process_ln ln =
let recur cn s =
case ha_split cn s of
(_,_,[]) -> s
(cn',pre,post) -> pre ++ ha_insert ln cn' ++ recur cn' post
in recur 0
-- | Re-write lines, starting at @1@.
ha_rewrite :: [String] -> [String]
ha_rewrite = zipWith ha_process_ln [1..]
-- | Arguments as required by @ghc -F -pgmF@.
ha_rewrite_ghcF :: IO ()
ha_rewrite_ghcF = do
a <- getArgs
case a of
[_,i_fn,o_fn] -> do
i <- readFile i_fn
let f = unlines . ha_rewrite . lines
writeFile o_fn (f i)
_ -> error "initial-file input-file output-file"