alga-0.2.0: src/Alga/Interaction/Base.hs
--
-- This module describes monad for interactive REPL and some basic
-- functions.
--
-- Copyright © 2015–2016 Mark Karpov
--
-- ALGA is free software: you can redistribute it and/or modify it under the
-- terms of the GNU General Public License as published by the Free Software
-- Foundation, either version 3 of the License, or (at your option) any
-- later version.
--
-- ALGA is distributed in the hope that it will be useful, but WITHOUT ANY
-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-- details.
--
-- You should have received a copy of the GNU General Public License along
-- with this program. If not, see <http://www.gnu.org/licenses/>.
module Alga.Interaction.Base
( AlgaSt (..)
, AlgaCfg (..)
, Alga
, runAlga
, defaultSeed
, defaultBeats
, processDef
, showRatio )
where
import Alga.Language
import Alga.Representation
import Alga.Translation
import Control.Monad.Reader
import Control.Monad.State.Strict
import Data.Ratio (numerator, denominator, Ratio)
import Formatting
import Numeric.Natural
import Path
-- | ALGA REPL state.
data AlgaSt = AlgaSt
{ stBackend :: AlgaBackend -- ^ Selected backend (DAW dependent)
, stPrevLen :: Natural -- ^ Length of preview principles
, stSrcFile :: Path Abs File -- ^ Name of current source file
}
-- | ALGA REPL configuration.
data AlgaCfg = AlgaCfg
{ cfgPrecision :: Double -- ^ Precision for some REPL utilities
, cfgPrompt :: String -- ^ REPL prompt
, cfgVerbose :: Bool -- ^ Verbose mode?
}
-- | A synonym for MIDA monad stack.
type Alga = StateT AlgaSt (ReaderT AlgaCfg (AlgaEnv IO))
-- | Run ALGA monad stack.
runAlga
:: Alga a -- ^ ALGA monad stack
-> AlgaSt -- ^ Initial state
-> AlgaCfg -- ^ Configuration
-> IO a
runAlga m st cfg = runAlgaEnv (runReaderT (evalStateT m st) cfg)
-- | Default seed for random number generator.
defaultSeed :: Natural
defaultSeed = 0
-- | Default duration of automation to calculate in whole notes, note that
-- this is actually floating point value.
defaultBeats :: Double
defaultBeats = 4
-- | Process a principle definition.
processDef :: (HasEnv m, MonadIO m)
=> String -- ^ Definition name
-> SyntaxTree -- ^ AST for that definition
-> m ()
processDef n t = do
recursive <- checkRecur n t
if recursive
then liftIO $
fprint ("Rejected recursive definition for ‘" % string % "’\n") n
else do addDef n t
liftIO $ fprint ("• ‘" % string % "’\n") n
-- | Render a ratio.
showRatio :: (Integral a, Show a) => Ratio a -> String
showRatio x =
let n = numerator x
d = denominator x
in if d == 1
then show n
else show n ++ divisionOp ++ show d